diff options
1464 files changed, 18873 insertions, 7095 deletions
diff --git a/Android.bp b/Android.bp index 27f22bde9a3a..f57acfa4ab60 100644 --- a/Android.bp +++ b/Android.bp @@ -232,6 +232,7 @@ filegroup { ":framework-wifi-sources", ":PacProcessor-aidl-sources", ":ProxyHandler-aidl-sources", + ":net-utils-framework-common-srcs", // AIDL from frameworks/base/native/ ":platform-compat-native-aidl", @@ -265,9 +266,10 @@ filegroup { filegroup { name: "framework-updatable-sources", srcs: [ - ":framework-sdkext-sources", + ":framework-sdkextensions-sources", ":framework-tethering-srcs", ":updatable-media-srcs", + ":ike-srcs", ] } @@ -430,6 +432,7 @@ java_library { name: "framework-minus-apex", defaults: ["framework-defaults"], srcs: [":framework-non-updatable-sources"], + libs: ["ike-stubs"], installable: true, javac_shard_size: 150, required: [ @@ -463,8 +466,10 @@ java_library { static_libs: [ "framework-minus-apex", "updatable_media_stubs", - "framework-sdkext-stubs-systemapi", - // TODO(jiyong): add more stubs for APEXes here + "framework-sdkextensions-stubs-systemapi", + // TODO(b/147200698): should be the stub of framework-tethering + "framework-tethering", + "ike-stubs", ], sdk_version: "core_platform", apex_available: ["//apex_available:platform"], @@ -587,6 +592,19 @@ java_library { } filegroup { + name: "framework-ike-shared-srcs", + visibility: ["//frameworks/opt/net/ike"], + srcs: [ + "core/java/android/annotation/StringDef.java", + "core/java/android/net/annotations/PolicyDirection.java", + "core/java/com/android/internal/util/IState.java", + "core/java/com/android/internal/util/State.java", + "core/java/com/android/internal/util/StateMachine.java", + "telephony/java/android/telephony/Annotation.java", + ], +} + +filegroup { name: "framework-networkstack-shared-srcs", srcs: [ // TODO: remove these annotations as soon as we can use andoid.support.annotations.* @@ -619,6 +637,7 @@ filegroup { "core/java/com/android/internal/util/Preconditions.java", "core/java/com/android/internal/util/State.java", "core/java/com/android/internal/util/StateMachine.java", + "core/java/com/android/internal/util/TrafficStatsConstants.java", "core/java/android/net/shared/Inet4AddressUtils.java", ], } @@ -906,6 +925,7 @@ java_library { "core/java/android/os/RemoteException.java", "core/java/android/util/AndroidException.java", ], + libs: [ "unsupportedappusage" ], dxflags: ["--core-library"], installable: false, @@ -1006,6 +1026,7 @@ filegroup { "core/java/android/util/TimeUtils.java", "core/java/com/android/internal/os/SomeArgs.java", "core/java/com/android/internal/util/AsyncChannel.java", + "core/java/com/android/internal/util/AsyncService.java", "core/java/com/android/internal/util/BitwiseInputStream.java", "core/java/com/android/internal/util/FastXmlSerializer.java", "core/java/com/android/internal/util/HexDump.java", diff --git a/ApiDocs.bp b/ApiDocs.bp index e373db66925f..c40004cf8e5c 100644 --- a/ApiDocs.bp +++ b/ApiDocs.bp @@ -121,8 +121,10 @@ framework_docs_only_args = " -android -manifest $(location core/res/AndroidManif doc_defaults { name: "framework-docs-default", - libs: framework_docs_only_libs + - ["stub-annotations"], + libs: framework_docs_only_libs + [ + "stub-annotations", + "unsupportedappusage", + ], html_dirs: [ "docs/html", ], diff --git a/StubLibraries.bp b/StubLibraries.bp index d1950474da5a..baa3c615039d 100644 --- a/StubLibraries.bp +++ b/StubLibraries.bp @@ -41,10 +41,9 @@ packages_to_document = [ ] stubs_defaults { - name: "metalava-api-stubs-default", + name: "metalava-non-updatable-api-stubs-default", srcs: [ ":framework-non-updatable-sources", - ":framework-updatable-sources", "core/java/**/*.logtags", ":opt-telephony-srcs", ":opt-net-voip-srcs", @@ -64,14 +63,23 @@ stubs_defaults { "sdk-dir", "api-versions-jars-dir", ], - sdk_version: "core_platform", filter_packages: packages_to_document, } +stubs_defaults { + name: "metalava-api-stubs-default", + defaults: ["metalava-non-updatable-api-stubs-default"], + srcs: [":framework-updatable-sources"], + sdk_version: "core_platform", +} + ///////////////////////////////////////////////////////////////////// // *-api-stubs-docs modules providing source files for the stub libraries ///////////////////////////////////////////////////////////////////// +// api-stubs-docs, system-api-stubs-docs, and test-api-stubs-docs have APIs +// from the non-updatable part of the platform as well as from the updatable +// modules droidstubs { name: "api-stubs-docs", defaults: ["metalava-api-stubs-default"], @@ -112,7 +120,10 @@ droidstubs { arg_files: [ "core/res/AndroidManifest.xml", ], - args: metalava_framework_docs_args + " --show-annotation android.annotation.SystemApi\\(client=android.annotation.SystemApi.Client.PRIVILEGED_APPS,process=android.annotation.SystemApi.Process.ALL\\)", + args: metalava_framework_docs_args + + " --show-annotation android.annotation.SystemApi\\(" + + "client=android.annotation.SystemApi.Client.PRIVILEGED_APPS," + + "process=android.annotation.SystemApi.Process.ALL\\)", check_api: { current: { api_file: "api/system-current.txt", @@ -155,6 +166,111 @@ droidstubs { } ///////////////////////////////////////////////////////////////////// +// 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) +///////////////////////////////////////////////////////////////////// + +// TODO(b/146727827) remove the *-api modules 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-app-api", + defaults: ["metalava-non-updatable-api-stubs-default"], + libs: ["framework-all"], + arg_files: ["core/res/AndroidManifest.xml"], + args: metalava_framework_docs_args + + " --show-annotation android.annotation.SystemApi\\(" + + "client=android.annotation.SystemApi.Client.MODULE_APPS," + + "process=android.annotation.SystemApi.Process.ALL\\)", + check_api: { + current: { + api_file: "api/module-app-current.txt", + removed_api_file: "api/module-app-removed.txt", + }, + // TODO(b/147559833) enable the compatibility check against the last release API + // and the API lint + //last_released: { + // api_file: ":last-released-module-app-api", + // removed_api_file: "api/module-app-removed.txt", + // baseline_file: ":module-app-api-incompatibilities-with-last-released" + //}, + //api_lint: { + // enabled: true, + // new_since: ":last-released-module-app-api", + // baseline_file: "api/module-app-lint-baseline.txt", + //}, + }, + //jdiff_enabled: true, +} + +droidstubs { + name: "module-lib-api", + defaults: ["metalava-non-updatable-api-stubs-default"], + libs: ["framework-all"], + arg_files: ["core/res/AndroidManifest.xml"], + args: metalava_framework_docs_args + + " --show-annotation android.annotation.SystemApi\\(" + + "client=android.annotation.SystemApi.Client.MODULE_LIBRARIES," + + "process=android.annotation.SystemApi.Process.ALL\\)", + check_api: { + current: { + api_file: "api/module-lib-current.txt", + removed_api_file: "api/module-lib-removed.txt", + }, + // TODO(b/147559833) enable the compatibility check against the last release API + // and the API lint + //last_released: { + // api_file: ":last-released-module-lib-api", + // removed_api_file: "api/module-lib-removed.txt", + // baseline_file: ":module-lib-api-incompatibilities-with-last-released" + //}, + //api_lint: { + // enabled: true, + // new_since: ":last-released-module-lib-api", + // baseline_file: "api/module-lib-lint-baseline.txt", + //}, + }, + //jdiff_enabled: true, +} + +// The following two droidstubs modules generate source files for the API stub libraries for +// modules. Note that they not only include their own APIs but also other APIs that have +// narrower scope. For example, module-lib-api-stubs-docs includes all @SystemApis not just +// the ones with 'client=MODULE_LIBRARIES'. +droidstubs { + name: "module-app-api-stubs-docs", + defaults: ["metalava-non-updatable-api-stubs-default"], + libs: ["framework-all"], + arg_files: ["core/res/AndroidManifest.xml"], + args: metalava_framework_docs_args + + " --show-annotation android.annotation.SystemApi\\(" + + "client=android.annotation.SystemApi.Client.PRIVILEGED_APPS," + + "process=android.annotation.SystemApi.Process.ALL\\)" + + " --show-annotation android.annotation.SystemApi\\(" + + "client=android.annotation.SystemApi.Client.MODULE_APPS," + + "process=android.annotation.SystemApi.Process.ALL\\)", +} + +droidstubs { + name: "module-lib-api-stubs-docs", + defaults: ["metalava-non-updatable-api-stubs-default"], + libs: ["framework-all"], + arg_files: ["core/res/AndroidManifest.xml"], + args: metalava_framework_docs_args + + " --show-annotation android.annotation.SystemApi\\(" + + "client=android.annotation.SystemApi.Client.PRIVILEGED_APPS," + + "process=android.annotation.SystemApi.Process.ALL\\)" + + " --show-annotation android.annotation.SystemApi\\(" + + "client=android.annotation.SystemApi.Client.MODULE_APPS," + + "process=android.annotation.SystemApi.Process.ALL\\)" + + " --show-annotation android.annotation.SystemApi\\(" + + "client=android.annotation.SystemApi.Client.MODULE_LIBRARIES," + + "process=android.annotation.SystemApi.Process.ALL\\)", +} + +///////////////////////////////////////////////////////////////////// // android_*_stubs_current modules are the stubs libraries compiled // from *-api-stubs-docs ///////////////////////////////////////////////////////////////////// @@ -169,7 +285,6 @@ java_defaults { java_resources: [ ":notices-for-framework-stubs", ], - sdk_version: "core_current", system_modules: "none", java_version: "1.8", compile_dex: true, @@ -187,6 +302,7 @@ java_library_static { "private-stub-annotations-jar", ], defaults: ["framework-stubs-default"], + sdk_version: "core_current", } java_library_static { @@ -201,6 +317,7 @@ java_library_static { "private-stub-annotations-jar", ], defaults: ["framework-stubs-default"], + sdk_version: "core_current", } java_library_static { @@ -215,6 +332,37 @@ java_library_static { "private-stub-annotations-jar", ], defaults: ["framework-stubs-default"], + sdk_version: "core_current", +} + +java_library_static { + name: "framework_module_app_stubs_current", + srcs: [ + ":module-app-api-stubs-docs", + ], + libs: [ + "stub-annotations", + "framework-all", + ], + static_libs: [ + "private-stub-annotations-jar", + ], + defaults: ["framework-stubs-default"], +} + +java_library_static { + name: "framework_module_lib_stubs_current", + srcs: [ + ":module-lib-api-stubs-docs", + ], + libs: [ + "stub-annotations", + "framework-all", + ], + static_libs: [ + "private-stub-annotations-jar", + ], + defaults: ["framework-stubs-default"], } ///////////////////////////////////////////////////////////////////// diff --git a/apex/Android.bp b/apex/Android.bp index 9ea395374e3a..c3b001471a12 100644 --- a/apex/Android.bp +++ b/apex/Android.bp @@ -34,6 +34,36 @@ stubs_defaults { stubs_defaults { name: "framework-module-stubs-defaults-systemapi", - args: mainline_stubs_args + " --show-annotation android.annotation.SystemApi ", + args: mainline_stubs_args + + " --show-annotation android.annotation.SystemApi\\(" + + "client=android.annotation.SystemApi.Client.PRIVILEGED_APPS," + + "process=android.annotation.SystemApi.Process.ALL\\) ", + installable: false, +} + +stubs_defaults { + name: "framework-module-stubs-defaults-module_apps_api", + args: mainline_stubs_args + + " --show-annotation android.annotation.SystemApi\\(" + + "client=android.annotation.SystemApi.Client.PRIVILEGED_APPS," + + "process=android.annotation.SystemApi.Process.ALL\\) " + + " --show-annotation android.annotation.SystemApi\\(" + + "client=android.annotation.SystemApi.Client.MODULE_APPS," + + "process=android.annotation.SystemApi.Process.ALL\\) ", + installable: false, +} + +stubs_defaults { + name: "framework-module-stubs-defaults-module_libs_api", + args: mainline_stubs_args + + " --show-annotation android.annotation.SystemApi\\(" + + "client=android.annotation.SystemApi.Client.PRIVILEGED_APPS," + + "process=android.annotation.SystemApi.Process.ALL\\) " + + " --show-annotation android.annotation.SystemApi\\(" + + "client=android.annotation.SystemApi.Client.MODULE_APPS," + + "process=android.annotation.SystemApi.Process.ALL\\) " + + " --show-annotation android.annotation.SystemApi\\(" + + "client=android.annotation.SystemApi.Client.MODULE_LIBRARIES," + + "process=android.annotation.SystemApi.Process.ALL\\) ", installable: false, } diff --git a/apex/sdkext/TEST_MAPPING b/apex/sdkext/TEST_MAPPING deleted file mode 100644 index 91947f39980a..000000000000 --- a/apex/sdkext/TEST_MAPPING +++ /dev/null @@ -1,7 +0,0 @@ -{ - "presubmit": [ - { - "name": "CtsSdkExtTestCases" - } - ] -} diff --git a/apex/sdkext/Android.bp b/apex/sdkextensions/Android.bp index f62f167cdcfa..4c5c2b2cfd4f 100644 --- a/apex/sdkext/Android.bp +++ b/apex/sdkextensions/Android.bp @@ -18,21 +18,26 @@ package { apex { name: "com.android.sdkext", - manifest: "manifest.json", + defaults: [ "com.android.sdkext-defaults" ], binaries: [ "derive_sdk" ], - java_libs: [ "framework-sdkext" ], + prebuilts: [ "cur_sdkinfo" ], + manifest: "manifest.json", +} + +apex_defaults { + name: "com.android.sdkext-defaults", + java_libs: [ "framework-sdkextensions" ], prebuilts: [ - "com.android.sdkext.ldconfig", - "cur_sdkinfo", - "derive_sdk.rc", + "com.android.sdkext.ldconfig", + "derive_sdk.rc", ], key: "com.android.sdkext.key", certificate: ":com.android.sdkext.certificate", } sdk { - name: "sdkext-sdk", - java_header_libs: [ "framework-sdkext-stubs-systemapi" ], + name: "sdkextensions-sdk", + java_header_libs: [ "framework-sdkextensions-stubs-systemapi" ], } apex_key { diff --git a/apex/sdkext/OWNERS b/apex/sdkextensions/OWNERS index feb274262bef..feb274262bef 100644 --- a/apex/sdkext/OWNERS +++ b/apex/sdkextensions/OWNERS diff --git a/apex/sdkextensions/TEST_MAPPING b/apex/sdkextensions/TEST_MAPPING new file mode 100644 index 000000000000..4e1883382e2c --- /dev/null +++ b/apex/sdkextensions/TEST_MAPPING @@ -0,0 +1,10 @@ +{ + "presubmit": [ + { + "name": "CtsSdkExtensionsTestCases" + }, + { + "name": "apiextensions_e2e_tests" + } + ] +} diff --git a/apex/sdkext/com.android.sdkext.avbpubkey b/apex/sdkextensions/com.android.sdkext.avbpubkey Binary files differindex 8f47741ed3b8..8f47741ed3b8 100644 --- a/apex/sdkext/com.android.sdkext.avbpubkey +++ b/apex/sdkextensions/com.android.sdkext.avbpubkey diff --git a/apex/sdkext/com.android.sdkext.pem b/apex/sdkextensions/com.android.sdkext.pem index 816460183aa3..816460183aa3 100644 --- a/apex/sdkext/com.android.sdkext.pem +++ b/apex/sdkextensions/com.android.sdkext.pem diff --git a/apex/sdkext/com.android.sdkext.pk8 b/apex/sdkextensions/com.android.sdkext.pk8 Binary files differindex ccc0bf438cd1..ccc0bf438cd1 100644 --- a/apex/sdkext/com.android.sdkext.pk8 +++ b/apex/sdkextensions/com.android.sdkext.pk8 diff --git a/apex/sdkext/com.android.sdkext.x509.pem b/apex/sdkextensions/com.android.sdkext.x509.pem index 45d2ade354d4..45d2ade354d4 100644 --- a/apex/sdkext/com.android.sdkext.x509.pem +++ b/apex/sdkextensions/com.android.sdkext.x509.pem diff --git a/apex/sdkext/derive_sdk/Android.bp b/apex/sdkextensions/derive_sdk/Android.bp index c4e3c296f210..cf49902d9978 100644 --- a/apex/sdkext/derive_sdk/Android.bp +++ b/apex/sdkextensions/derive_sdk/Android.bp @@ -12,8 +12,8 @@ // See the License for the specific language governing permissions and // limitations under the License. -cc_binary { - name: "derive_sdk", +cc_defaults { + name: "derive_sdk-defaults", srcs: [ "derive_sdk.cpp", "sdk.proto", @@ -30,6 +30,24 @@ cc_binary { ], } +cc_binary { + name: "derive_sdk", + defaults: [ "derive_sdk-defaults" ], + apex_available: [ "com.android.sdkext" ], + visibility: [ "//frameworks/base/apex/sdkextensions" ] +} + +// Work around testing using a 64-bit test suite on 32-bit test device by +// using a prefer32 version of derive_sdk in testing. +cc_binary { + name: "derive_sdk_prefer32", + defaults: [ "derive_sdk-defaults" ], + compile_multilib: "prefer32", + stem: "derive_sdk", + apex_available: [ "test_com.android.sdkext" ], + visibility: [ "//frameworks/base/apex/sdkextensions/testing" ] +} + prebuilt_etc { name: "derive_sdk.rc", src: "derive_sdk.rc", diff --git a/apex/sdkext/derive_sdk/derive_sdk.cpp b/apex/sdkextensions/derive_sdk/derive_sdk.cpp index 0a9711677015..6fb7ef43416e 100644 --- a/apex/sdkext/derive_sdk/derive_sdk.cpp +++ b/apex/sdkextensions/derive_sdk/derive_sdk.cpp @@ -26,7 +26,7 @@ #include <android-base/logging.h> #include <android-base/properties.h> -#include "frameworks/base/apex/sdkext/derive_sdk/sdk.pb.h" +#include "frameworks/base/apex/sdkextensions/derive_sdk/sdk.pb.h" using com::android::sdkext::proto::SdkVersion; diff --git a/apex/sdkext/derive_sdk/derive_sdk.rc b/apex/sdkextensions/derive_sdk/derive_sdk.rc index 1b667949eeaa..1b667949eeaa 100644 --- a/apex/sdkext/derive_sdk/derive_sdk.rc +++ b/apex/sdkextensions/derive_sdk/derive_sdk.rc diff --git a/apex/sdkext/derive_sdk/sdk.proto b/apex/sdkextensions/derive_sdk/sdk.proto index d15b93552ff4..d15b93552ff4 100644 --- a/apex/sdkext/derive_sdk/sdk.proto +++ b/apex/sdkextensions/derive_sdk/sdk.proto diff --git a/apex/sdkext/framework/Android.bp b/apex/sdkextensions/framework/Android.bp index a50dc3d4f349..dd174734df6d 100644 --- a/apex/sdkext/framework/Android.bp +++ b/apex/sdkextensions/framework/Android.bp @@ -17,55 +17,63 @@ package { } filegroup { - name: "framework-sdkext-sources", + name: "framework-sdkextensions-sources", srcs: [ "java/**/*.java", ], path: "java", - visibility: [ "//frameworks/base:__pkg__" ] // For the "global" stubs. + visibility: [ "//frameworks/base" ] // For the "global" stubs. } java_library { - name: "framework-sdkext", - srcs: [ ":framework-sdkext-sources" ], + name: "framework-sdkextensions", + srcs: [ ":framework-sdkextensions-sources" ], sdk_version: "system_current", libs: [ "framework-annotations-lib" ], permitted_packages: [ "android.os.ext" ], installable: true, - visibility: [ "//frameworks/base/apex/sdkext:__pkg__" ], + visibility: [ + "//frameworks/base/apex/sdkextensions", + "//frameworks/base/apex/sdkextensions/testing", + ], + hostdex: true, // for hiddenapi check + apex_available: [ + "com.android.sdkext", + "test_com.android.sdkext", + ], } droidstubs { - name: "framework-sdkext-droidstubs-publicapi", + name: "framework-sdkextensions-droidstubs-publicapi", defaults: [ - "framework-sdkext-stubs-defaults", + "framework-sdkextensions-stubs-defaults", "framework-module-stubs-defaults-publicapi", ] } droidstubs { - name: "framework-sdkext-droidstubs-systemapi", + name: "framework-sdkextensions-droidstubs-systemapi", defaults: [ - "framework-sdkext-stubs-defaults", + "framework-sdkextensions-stubs-defaults", "framework-module-stubs-defaults-systemapi", ] } stubs_defaults { - name: "framework-sdkext-stubs-defaults", + name: "framework-sdkextensions-stubs-defaults", srcs: [ - ":framework-sdkext-sources", + ":framework-sdkextensions-sources", ":framework-annotations", ], sdk_version: "system_current", } java_library { - name: "framework-sdkext-stubs-systemapi", - srcs: [":framework-sdkext-droidstubs-systemapi"], + name: "framework-sdkextensions-stubs-systemapi", + srcs: [":framework-sdkextensions-droidstubs-systemapi"], sdk_version: "system_current", visibility: [ - "//frameworks/base:__pkg__", // Framework - "//frameworks/base/apex/sdkext:__pkg__", // sdkext SDK + "//frameworks/base", // Framework + "//frameworks/base/apex/sdkextensions", // sdkextensions SDK ] } diff --git a/apex/sdkext/framework/java/android/os/ext/SdkExtensions.java b/apex/sdkextensions/framework/java/android/os/ext/SdkExtensions.java index a8a7effa9b6c..a8a7effa9b6c 100644 --- a/apex/sdkext/framework/java/android/os/ext/SdkExtensions.java +++ b/apex/sdkextensions/framework/java/android/os/ext/SdkExtensions.java diff --git a/apex/sdkext/framework/java/android/os/ext/package.html b/apex/sdkextensions/framework/java/android/os/ext/package.html index 34c1697c01fd..34c1697c01fd 100644 --- a/apex/sdkext/framework/java/android/os/ext/package.html +++ b/apex/sdkextensions/framework/java/android/os/ext/package.html diff --git a/apex/sdkext/gen_sdkinfo.py b/apex/sdkextensions/gen_sdkinfo.py index 5af478ba7fe6..5af478ba7fe6 100644 --- a/apex/sdkext/gen_sdkinfo.py +++ b/apex/sdkextensions/gen_sdkinfo.py diff --git a/apex/sdkext/ld.config.txt b/apex/sdkextensions/ld.config.txt index b4470685f4fc..dcc69b892760 100644 --- a/apex/sdkext/ld.config.txt +++ b/apex/sdkextensions/ld.config.txt @@ -1,10 +1,10 @@ # Copyright (C) 2019 The Android Open Source Project # -# Bionic loader config file for the sdkext apex. +# Bionic loader config file for the sdkextensions apex. -dir.sdkext = /apex/com.android.sdkext/bin/ +dir.sdkextensions = /apex/com.android.sdkext/bin/ -[sdkext] +[sdkextensions] additional.namespaces = platform namespace.default.isolated = true diff --git a/apex/sdkext/manifest.json b/apex/sdkextensions/manifest.json index 048f5c4f177b..048f5c4f177b 100644 --- a/apex/sdkext/manifest.json +++ b/apex/sdkextensions/manifest.json diff --git a/apex/sdkext/sdk.proto b/apex/sdkextensions/sdk.proto index d15b93552ff4..d15b93552ff4 100644 --- a/apex/sdkext/sdk.proto +++ b/apex/sdkextensions/sdk.proto diff --git a/apex/sdkextensions/testing/Android.bp b/apex/sdkextensions/testing/Android.bp new file mode 100644 index 000000000000..e6451cc29bc2 --- /dev/null +++ b/apex/sdkextensions/testing/Android.bp @@ -0,0 +1,46 @@ +// 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: "test_com.android.sdkext", + visibility: [ "//system/apex/tests" ], + defaults: ["com.android.sdkext-defaults"], + manifest: "test_manifest.json", + prebuilts: [ "sdkinfo_45" ], + file_contexts: ":com.android.sdkext-file_contexts", + installable: false, // Should never be installed on the systemimage + multilib: { + prefer32: { + binaries: ["derive_sdk_prefer32"], + }, + }, + // The automated test infra ends up building this apex for 64+32-bit and + // then installs it on a 32-bit-only device. Work around this weirdness + // by preferring 32-bit. + compile_multilib: "prefer32", +} + +genrule { + name: "sdkinfo_45_src", + out: [ "sdkinfo.binarypb" ], + tools: [ "gen_sdkinfo" ], + cmd: "$(location) -v 45 -o $(out)", +} + +prebuilt_etc { + name: "sdkinfo_45", + src: ":sdkinfo_45_src", + filename: "sdkinfo.binarypb", + installable: false, +} diff --git a/apex/sdkextensions/testing/test_manifest.json b/apex/sdkextensions/testing/test_manifest.json new file mode 100644 index 000000000000..1b4a2b0c6e60 --- /dev/null +++ b/apex/sdkextensions/testing/test_manifest.json @@ -0,0 +1,4 @@ +{ + "name": "com.android.sdkext", + "version": 2147483647 +} diff --git a/api/current.txt b/api/current.txt index dc646787beb8..08d7034ce959 100644 --- a/api/current.txt +++ b/api/current.txt @@ -112,6 +112,7 @@ package android { field public static final String READ_LOGS = "android.permission.READ_LOGS"; field public static final String READ_PHONE_NUMBERS = "android.permission.READ_PHONE_NUMBERS"; field public static final String READ_PHONE_STATE = "android.permission.READ_PHONE_STATE"; + field public static final String READ_PRECISE_PHONE_STATE = "android.permission.READ_PRECISE_PHONE_STATE"; field public static final String READ_SMS = "android.permission.READ_SMS"; field public static final String READ_SYNC_SETTINGS = "android.permission.READ_SYNC_SETTINGS"; field public static final String READ_SYNC_STATS = "android.permission.READ_SYNC_STATS"; @@ -17963,6 +17964,7 @@ package android.icu.lang { field public static final int RIGHT = 7; // 0x7 field public static final int TOP = 8; // 0x8 field public static final int TOP_AND_BOTTOM = 9; // 0x9 + field public static final int TOP_AND_BOTTOM_AND_LEFT = 15; // 0xf field public static final int TOP_AND_BOTTOM_AND_RIGHT = 10; // 0xa field public static final int TOP_AND_LEFT = 11; // 0xb field public static final int TOP_AND_LEFT_AND_RIGHT = 12; // 0xc @@ -18285,6 +18287,7 @@ package android.icu.lang { field public static final int CHEROKEE_SUPPLEMENT_ID = 255; // 0xff field public static final android.icu.lang.UCharacter.UnicodeBlock CHESS_SYMBOLS; field public static final int CHESS_SYMBOLS_ID = 281; // 0x119 + field public static final int CHORASMIAN_ID = 301; // 0x12d field public static final android.icu.lang.UCharacter.UnicodeBlock CJK_COMPATIBILITY; field public static final android.icu.lang.UCharacter.UnicodeBlock CJK_COMPATIBILITY_FORMS; field public static final int CJK_COMPATIBILITY_FORMS_ID = 83; // 0x53 @@ -18312,6 +18315,7 @@ package android.icu.lang { field public static final int CJK_UNIFIED_IDEOGRAPHS_EXTENSION_E_ID = 256; // 0x100 field public static final android.icu.lang.UCharacter.UnicodeBlock CJK_UNIFIED_IDEOGRAPHS_EXTENSION_F; field public static final int CJK_UNIFIED_IDEOGRAPHS_EXTENSION_F_ID = 274; // 0x112 + field public static final int CJK_UNIFIED_IDEOGRAPHS_EXTENSION_G_ID = 302; // 0x12e field public static final int CJK_UNIFIED_IDEOGRAPHS_ID = 71; // 0x47 field public static final android.icu.lang.UCharacter.UnicodeBlock COMBINING_DIACRITICAL_MARKS; field public static final android.icu.lang.UCharacter.UnicodeBlock COMBINING_DIACRITICAL_MARKS_EXTENDED; @@ -18361,6 +18365,7 @@ package android.icu.lang { field public static final int DEVANAGARI_ID = 15; // 0xf field public static final android.icu.lang.UCharacter.UnicodeBlock DINGBATS; field public static final int DINGBATS_ID = 56; // 0x38 + field public static final int DIVES_AKURU_ID = 303; // 0x12f field public static final android.icu.lang.UCharacter.UnicodeBlock DOGRA; field public static final int DOGRA_ID = 282; // 0x11a field public static final android.icu.lang.UCharacter.UnicodeBlock DOMINO_TILES; @@ -18489,6 +18494,8 @@ package android.icu.lang { field public static final int KAYAH_LI_ID = 162; // 0xa2 field public static final android.icu.lang.UCharacter.UnicodeBlock KHAROSHTHI; field public static final int KHAROSHTHI_ID = 137; // 0x89 + field public static final android.icu.lang.UCharacter.UnicodeBlock KHITAN_SMALL_SCRIPT; + field public static final int KHITAN_SMALL_SCRIPT_ID = 304; // 0x130 field public static final android.icu.lang.UCharacter.UnicodeBlock KHMER; field public static final int KHMER_ID = 36; // 0x24 field public static final android.icu.lang.UCharacter.UnicodeBlock KHMER_SYMBOLS; @@ -18527,6 +18534,8 @@ package android.icu.lang { field public static final int LINEAR_B_SYLLABARY_ID = 117; // 0x75 field public static final android.icu.lang.UCharacter.UnicodeBlock LISU; field public static final int LISU_ID = 176; // 0xb0 + field public static final android.icu.lang.UCharacter.UnicodeBlock LISU_SUPPLEMENT; + field public static final int LISU_SUPPLEMENT_ID = 305; // 0x131 field public static final android.icu.lang.UCharacter.UnicodeBlock LOW_SURROGATES; field public static final int LOW_SURROGATES_ID = 77; // 0x4d field public static final android.icu.lang.UCharacter.UnicodeBlock LYCIAN; @@ -18738,6 +18747,8 @@ package android.icu.lang { field public static final int SYLOTI_NAGRI_ID = 143; // 0x8f field public static final android.icu.lang.UCharacter.UnicodeBlock SYMBOLS_AND_PICTOGRAPHS_EXTENDED_A; field public static final int SYMBOLS_AND_PICTOGRAPHS_EXTENDED_A_ID = 298; // 0x12a + field public static final android.icu.lang.UCharacter.UnicodeBlock SYMBOLS_FOR_LEGACY_COMPUTING; + field public static final int SYMBOLS_FOR_LEGACY_COMPUTING_ID = 306; // 0x132 field public static final android.icu.lang.UCharacter.UnicodeBlock SYRIAC; field public static final int SYRIAC_ID = 13; // 0xd field public static final android.icu.lang.UCharacter.UnicodeBlock SYRIAC_SUPPLEMENT; @@ -18766,6 +18777,8 @@ package android.icu.lang { field public static final android.icu.lang.UCharacter.UnicodeBlock TANGUT_COMPONENTS; field public static final int TANGUT_COMPONENTS_ID = 273; // 0x111 field public static final int TANGUT_ID = 272; // 0x110 + field public static final android.icu.lang.UCharacter.UnicodeBlock TANGUT_SUPPLEMENT; + field public static final int TANGUT_SUPPLEMENT_ID = 307; // 0x133 field public static final android.icu.lang.UCharacter.UnicodeBlock TELUGU; field public static final int TELUGU_ID = 21; // 0x15 field public static final android.icu.lang.UCharacter.UnicodeBlock THAANA; @@ -18800,6 +18813,8 @@ package android.icu.lang { field public static final int WANCHO_ID = 300; // 0x12c field public static final android.icu.lang.UCharacter.UnicodeBlock WARANG_CITI; field public static final int WARANG_CITI_ID = 252; // 0xfc + field public static final android.icu.lang.UCharacter.UnicodeBlock YEZIDI; + field public static final int YEZIDI_ID = 308; // 0x134 field public static final android.icu.lang.UCharacter.UnicodeBlock YIJING_HEXAGRAM_SYMBOLS; field public static final int YIJING_HEXAGRAM_SYMBOLS_ID = 116; // 0x74 field public static final android.icu.lang.UCharacter.UnicodeBlock YI_RADICALS; @@ -19096,6 +19111,7 @@ package android.icu.lang { field public static final int CHAKMA = 118; // 0x76 field public static final int CHAM = 66; // 0x42 field public static final int CHEROKEE = 6; // 0x6 + field public static final int CHORASMIAN = 189; // 0xbd field public static final int CIRTH = 67; // 0x43 field public static final int COMMON = 0; // 0x0 field public static final int COPTIC = 7; // 0x7 @@ -19105,6 +19121,7 @@ package android.icu.lang { field public static final int DEMOTIC_EGYPTIAN = 69; // 0x45 field public static final int DESERET = 9; // 0x9 field public static final int DEVANAGARI = 10; // 0xa + field public static final int DIVES_AKURU = 190; // 0xbe field public static final int DOGRA = 178; // 0xb2 field public static final int DUPLOYAN = 135; // 0x87 field public static final int EASTERN_SYRIAC = 97; // 0x61 @@ -19146,6 +19163,7 @@ package android.icu.lang { field public static final int KATAKANA_OR_HIRAGANA = 54; // 0x36 field public static final int KAYAH_LI = 79; // 0x4f field public static final int KHAROSHTHI = 57; // 0x39 + field public static final int KHITAN_SMALL_SCRIPT = 191; // 0xbf field public static final int KHMER = 23; // 0x17 field public static final int KHOJKI = 157; // 0x9d field public static final int KHUDAWADI = 145; // 0x91 @@ -19263,6 +19281,7 @@ package android.icu.lang { field public static final int WARANG_CITI = 146; // 0x92 field public static final int WESTERN_SYRIAC = 96; // 0x60 field public static final int WOLEAI = 155; // 0x9b + field public static final int YEZIDI = 192; // 0xc0 field public static final int YI = 41; // 0x29 field public static final int ZANABAZAR_SQUARE = 177; // 0xb1 } @@ -28329,6 +28348,8 @@ package android.media.tv { method public int getVideoWidth(); method public boolean isAudioDescription(); method public boolean isEncrypted(); + method public boolean isHardOfHearing(); + method public boolean isSpokenSubtitle(); method public void writeToParcel(android.os.Parcel, int); field @NonNull public static final android.os.Parcelable.Creator<android.media.tv.TvTrackInfo> CREATOR; field public static final int TYPE_AUDIO = 0; // 0x0 @@ -28345,7 +28366,9 @@ package android.media.tv { method public android.media.tv.TvTrackInfo.Builder setDescription(CharSequence); method @NonNull public android.media.tv.TvTrackInfo.Builder setEncrypted(boolean); method public android.media.tv.TvTrackInfo.Builder setExtra(android.os.Bundle); + method @NonNull public android.media.tv.TvTrackInfo.Builder setHardOfHearing(boolean); method public android.media.tv.TvTrackInfo.Builder setLanguage(String); + method @NonNull public android.media.tv.TvTrackInfo.Builder setSpokenSubtitle(boolean); method public android.media.tv.TvTrackInfo.Builder setVideoActiveFormatDescription(byte); method public android.media.tv.TvTrackInfo.Builder setVideoFrameRate(float); method public android.media.tv.TvTrackInfo.Builder setVideoHeight(int); @@ -28657,6 +28680,37 @@ package android.net { field @NonNull public static final android.os.Parcelable.Creator<android.net.CaptivePortal> CREATOR; } + public class ConnectivityDiagnosticsManager { + method public void registerConnectivityDiagnosticsCallback(@NonNull android.net.NetworkRequest, @NonNull java.util.concurrent.Executor, @NonNull android.net.ConnectivityDiagnosticsManager.ConnectivityDiagnosticsCallback); + method public void unregisterConnectivityDiagnosticsCallback(@NonNull android.net.ConnectivityDiagnosticsManager.ConnectivityDiagnosticsCallback); + field public static final int DETECTION_METHOD_DNS_EVENTS = 1; // 0x1 + field public static final int DETECTION_METHOD_TCP_METRICS = 2; // 0x2 + } + + public abstract static class ConnectivityDiagnosticsManager.ConnectivityDiagnosticsCallback { + ctor public ConnectivityDiagnosticsManager.ConnectivityDiagnosticsCallback(); + method public void onConnectivityReport(@NonNull android.net.ConnectivityDiagnosticsManager.ConnectivityReport); + method public void onDataStallSuspected(@NonNull android.net.ConnectivityDiagnosticsManager.DataStallReport); + method public void onNetworkConnectivityReported(@NonNull android.net.Network, boolean); + } + + public static class ConnectivityDiagnosticsManager.ConnectivityReport { + ctor public ConnectivityDiagnosticsManager.ConnectivityReport(@NonNull android.net.Network, long, @NonNull android.net.LinkProperties, @NonNull android.net.NetworkCapabilities, @NonNull android.os.PersistableBundle); + field @NonNull public final android.os.PersistableBundle additionalInfo; + field @NonNull public final android.net.LinkProperties linkProperties; + field @NonNull public final android.net.Network network; + field @NonNull public final android.net.NetworkCapabilities networkCapabilities; + field public final long reportTimestamp; + } + + public static class ConnectivityDiagnosticsManager.DataStallReport { + ctor public ConnectivityDiagnosticsManager.DataStallReport(@NonNull android.net.Network, long, int, @NonNull android.os.PersistableBundle); + field public final int detectionMethod; + field @NonNull public final android.net.Network network; + field public final long reportTimestamp; + field @NonNull public final android.os.PersistableBundle stallDetails; + } + public class ConnectivityManager { method public void addDefaultNetworkActiveListener(android.net.ConnectivityManager.OnNetworkActiveListener); method public boolean bindProcessToNetwork(@Nullable android.net.Network); @@ -28761,6 +28815,7 @@ package android.net { ctor public DhcpInfo(); method public int describeContents(); method public void writeToParcel(android.os.Parcel, int); + field @NonNull public static final android.os.Parcelable.Creator<android.net.DhcpInfo> CREATOR; field public int dns1; field public int dns2; field public int gateway; @@ -29127,9 +29182,10 @@ package android.net { method public android.net.NetworkRequest.Builder addCapability(int); method public android.net.NetworkRequest.Builder addTransportType(int); method public android.net.NetworkRequest build(); + method @NonNull public android.net.NetworkRequest.Builder clearCapabilities(); method public android.net.NetworkRequest.Builder removeCapability(int); method public android.net.NetworkRequest.Builder removeTransportType(int); - method public android.net.NetworkRequest.Builder setNetworkSpecifier(String); + method @Deprecated public android.net.NetworkRequest.Builder setNetworkSpecifier(String); method public android.net.NetworkRequest.Builder setNetworkSpecifier(android.net.NetworkSpecifier); } @@ -29228,6 +29284,19 @@ package android.net { method public void onStopped(); } + public final class TelephonyNetworkSpecifier extends android.net.NetworkSpecifier implements android.os.Parcelable { + method public int describeContents(); + method public int getSubscriptionId(); + method public void writeToParcel(@NonNull android.os.Parcel, int); + field @NonNull public static final android.os.Parcelable.Creator<android.net.TelephonyNetworkSpecifier> CREATOR; + } + + public static final class TelephonyNetworkSpecifier.Builder { + ctor public TelephonyNetworkSpecifier.Builder(); + method @NonNull public android.net.TelephonyNetworkSpecifier build(); + method @NonNull public android.net.TelephonyNetworkSpecifier.Builder setSubscriptionId(int); + } + public class TrafficStats { ctor public TrafficStats(); method public static void clearThreadStatsTag(); @@ -35222,7 +35291,9 @@ package android.os { method public int describeContents(); method @Nullable public android.os.PersistableBundle getPersistableBundle(@Nullable String); method public void putPersistableBundle(@Nullable String, @Nullable android.os.PersistableBundle); + method @NonNull public static android.os.PersistableBundle readFromStream(@NonNull java.io.InputStream) throws java.io.IOException; method public void writeToParcel(android.os.Parcel, int); + method public void writeToStream(@NonNull java.io.OutputStream) throws java.io.IOException; field @NonNull public static final android.os.Parcelable.Creator<android.os.PersistableBundle> CREATOR; field public static final android.os.PersistableBundle EMPTY; } @@ -43260,6 +43331,7 @@ package android.telecom { method public java.util.List<android.telecom.Call> getChildren(); method public java.util.List<android.telecom.Call> getConferenceableCalls(); method public android.telecom.Call.Details getDetails(); + method @Nullable public android.telecom.Call getGenericConferenceActiveChildCall(); method public android.telecom.Call getParent(); method public String getRemainingPostDialSequence(); method @Nullable public android.telecom.Call.RttCall getRttCall(); @@ -43343,6 +43415,7 @@ package android.telecom { method public int getCallerDisplayNamePresentation(); method public int getCallerNumberVerificationStatus(); method public final long getConnectTimeMillis(); + method @Nullable public String getContactDisplayName(); method public long getCreationTimeMillis(); method public android.telecom.DisconnectCause getDisconnectCause(); method public android.os.Bundle getExtras(); @@ -44189,6 +44262,8 @@ package android.telecom { package android.telephony { public final class AccessNetworkConstants { + field public static final int TRANSPORT_TYPE_WLAN = 2; // 0x2 + field public static final int TRANSPORT_TYPE_WWAN = 1; // 0x1 } public static final class AccessNetworkConstants.AccessNetworkType { @@ -44363,6 +44438,9 @@ package android.telephony { field public static final int DATA_CYCLE_USE_PLATFORM_DEFAULT = -1; // 0xffffffff field public static final String EXTRA_SLOT_INDEX = "android.telephony.extra.SLOT_INDEX"; field public static final String EXTRA_SUBSCRIPTION_INDEX = "android.telephony.extra.SUBSCRIPTION_INDEX"; + field public static final String IMSI_KEY_AVAILABILITY_INT = "imsi_key_availability_int"; + field public static final String KEY_5G_ICON_CONFIGURATION_STRING = "5g_icon_configuration_string"; + field public static final String KEY_5G_ICON_DISPLAY_GRACE_PERIOD_SEC_INT = "5g_icon_display_grace_period_sec_int"; field public static final String KEY_5G_NR_SSRSRP_THRESHOLDS_INT_ARRAY = "5g_nr_ssrsrp_thresholds_int_array"; field public static final String KEY_5G_NR_SSRSRQ_THRESHOLDS_INT_ARRAY = "5g_nr_ssrsrq_thresholds_int_array"; field public static final String KEY_5G_NR_SSSINR_THRESHOLDS_INT_ARRAY = "5g_nr_sssinr_thresholds_int_array"; @@ -44376,18 +44454,32 @@ package android.telephony { field public static final String KEY_ALLOW_LOCAL_DTMF_TONES_BOOL = "allow_local_dtmf_tones_bool"; field public static final String KEY_ALLOW_MERGE_WIFI_CALLS_WHEN_VOWIFI_OFF_BOOL = "allow_merge_wifi_calls_when_vowifi_off_bool"; field public static final String KEY_ALLOW_NON_EMERGENCY_CALLS_IN_ECM_BOOL = "allow_non_emergency_calls_in_ecm_bool"; - field public static final String KEY_ALWAYS_SHOW_EMERGENCY_ALERT_ONOFF_BOOL = "always_show_emergency_alert_onoff_bool"; + field public static final String KEY_ALLOW_VIDEO_CALLING_FALLBACK_BOOL = "allow_video_calling_fallback_bool"; + field public static final String KEY_ALWAYS_SHOW_DATA_RAT_ICON_BOOL = "always_show_data_rat_icon_bool"; + field @Deprecated public static final String KEY_ALWAYS_SHOW_EMERGENCY_ALERT_ONOFF_BOOL = "always_show_emergency_alert_onoff_bool"; + field public static final String KEY_ALWAYS_SHOW_PRIMARY_SIGNAL_BAR_IN_OPPORTUNISTIC_NETWORK_BOOLEAN = "always_show_primary_signal_bar_in_opportunistic_network_boolean"; field public static final String KEY_APN_EXPAND_BOOL = "apn_expand_bool"; + field public static final String KEY_APN_SETTINGS_DEFAULT_APN_TYPES_STRING_ARRAY = "apn_settings_default_apn_types_string_array"; field public static final String KEY_AUTO_RETRY_ENABLED_BOOL = "auto_retry_enabled_bool"; field public static final String KEY_CALL_BARRING_SUPPORTS_DEACTIVATE_ALL_BOOL = "call_barring_supports_deactivate_all_bool"; field public static final String KEY_CALL_BARRING_SUPPORTS_PASSWORD_CHANGE_BOOL = "call_barring_supports_password_change_bool"; field public static final String KEY_CALL_BARRING_VISIBILITY_BOOL = "call_barring_visibility_bool"; field public static final String KEY_CALL_FORWARDING_BLOCKS_WHILE_ROAMING_STRING_ARRAY = "call_forwarding_blocks_while_roaming_string_array"; + field public static final String KEY_CALL_REDIRECTION_SERVICE_COMPONENT_NAME_STRING = "call_redirection_service_component_name_string"; + field public static final String KEY_CARRIER_ALLOW_DEFLECT_IMS_CALL_BOOL = "carrier_allow_deflect_ims_call_bool"; field public static final String KEY_CARRIER_ALLOW_TURNOFF_IMS_BOOL = "carrier_allow_turnoff_ims_bool"; field public static final String KEY_CARRIER_APP_REQUIRED_DURING_SIM_SETUP_BOOL = "carrier_app_required_during_setup_bool"; field public static final String KEY_CARRIER_CALL_SCREENING_APP_STRING = "call_screening_app"; + field public static final String KEY_CARRIER_CERTIFICATE_STRING_ARRAY = "carrier_certificate_string_array"; + field public static final String KEY_CARRIER_CONFIG_APPLIED_BOOL = "carrier_config_applied_bool"; field public static final String KEY_CARRIER_CONFIG_VERSION_STRING = "carrier_config_version_string"; field public static final String KEY_CARRIER_DATA_CALL_PERMANENT_FAILURE_STRINGS = "carrier_data_call_permanent_failure_strings"; + field public static final String KEY_CARRIER_DEFAULT_ACTIONS_ON_DCFAILURE_STRING_ARRAY = "carrier_default_actions_on_dcfailure_string_array"; + field public static final String KEY_CARRIER_DEFAULT_ACTIONS_ON_DEFAULT_NETWORK_AVAILABLE = "carrier_default_actions_on_default_network_available_string_array"; + field public static final String KEY_CARRIER_DEFAULT_ACTIONS_ON_REDIRECTION_STRING_ARRAY = "carrier_default_actions_on_redirection_string_array"; + field public static final String KEY_CARRIER_DEFAULT_ACTIONS_ON_RESET = "carrier_default_actions_on_reset_string_array"; + field public static final String KEY_CARRIER_DEFAULT_REDIRECTION_URL_STRING_ARRAY = "carrier_default_redirection_url_string_array"; + field public static final String KEY_CARRIER_DEFAULT_WFC_IMS_ENABLED_BOOL = "carrier_default_wfc_ims_enabled_bool"; field public static final String KEY_CARRIER_DEFAULT_WFC_IMS_MODE_INT = "carrier_default_wfc_ims_mode_int"; field public static final String KEY_CARRIER_DEFAULT_WFC_IMS_ROAMING_MODE_INT = "carrier_default_wfc_ims_roaming_mode_int"; field @Deprecated public static final String KEY_CARRIER_FORCE_DISABLE_ETWS_CMAS_TEST_BOOL = "carrier_force_disable_etws_cmas_test_bool"; @@ -44399,11 +44491,14 @@ package android.telephony { field public static final String KEY_CARRIER_INSTANT_LETTERING_LENGTH_LIMIT_INT = "carrier_instant_lettering_length_limit_int"; field public static final String KEY_CARRIER_NAME_OVERRIDE_BOOL = "carrier_name_override_bool"; field public static final String KEY_CARRIER_NAME_STRING = "carrier_name_string"; + field public static final String KEY_CARRIER_RCS_PROVISIONING_REQUIRED_BOOL = "carrier_rcs_provisioning_required_bool"; + field public static final String KEY_CARRIER_SETTINGS_ACTIVITY_COMPONENT_NAME_STRING = "carrier_settings_activity_component_name_string"; field public static final String KEY_CARRIER_SETTINGS_ENABLE_BOOL = "carrier_settings_enable_bool"; field public static final String KEY_CARRIER_SUPPORTS_SS_OVER_UT_BOOL = "carrier_supports_ss_over_ut_bool"; field public static final String KEY_CARRIER_USE_IMS_FIRST_FOR_EMERGENCY_BOOL = "carrier_use_ims_first_for_emergency_bool"; field public static final String KEY_CARRIER_UT_PROVISIONING_REQUIRED_BOOL = "carrier_ut_provisioning_required_bool"; field public static final String KEY_CARRIER_VOLTE_AVAILABLE_BOOL = "carrier_volte_available_bool"; + field public static final String KEY_CARRIER_VOLTE_OVERRIDE_WFC_PROVISIONING_BOOL = "carrier_volte_override_wfc_provisioning_bool"; field public static final String KEY_CARRIER_VOLTE_PROVISIONED_BOOL = "carrier_volte_provisioned_bool"; field public static final String KEY_CARRIER_VOLTE_PROVISIONING_REQUIRED_BOOL = "carrier_volte_provisioning_required_bool"; field public static final String KEY_CARRIER_VOLTE_TTY_SUPPORTED_BOOL = "carrier_volte_tty_supported_bool"; @@ -44417,6 +44512,7 @@ package android.telephony { field public static final String KEY_CDMA_NONROAMING_NETWORKS_STRING_ARRAY = "cdma_nonroaming_networks_string_array"; field public static final String KEY_CDMA_ROAMING_MODE_INT = "cdma_roaming_mode_int"; field public static final String KEY_CDMA_ROAMING_NETWORKS_STRING_ARRAY = "cdma_roaming_networks_string_array"; + field public static final String KEY_CHECK_PRICING_WITH_CARRIER_FOR_DATA_ROAMING_BOOL = "check_pricing_with_carrier_data_roaming_bool"; field public static final String KEY_CI_ACTION_ON_SYS_UPDATE_BOOL = "ci_action_on_sys_update_bool"; field public static final String KEY_CI_ACTION_ON_SYS_UPDATE_EXTRA_STRING = "ci_action_on_sys_update_extra_string"; field public static final String KEY_CI_ACTION_ON_SYS_UPDATE_EXTRA_VAL_STRING = "ci_action_on_sys_update_extra_val_string"; @@ -44426,6 +44522,7 @@ package android.telephony { field public static final String KEY_CONFIG_IMS_RCS_PACKAGE_OVERRIDE_STRING = "config_ims_rcs_package_override_string"; field public static final String KEY_CONFIG_PLANS_PACKAGE_OVERRIDE_STRING = "config_plans_package_override_string"; field public static final String KEY_CONFIG_TELEPHONY_USE_OWN_NUMBER_FOR_VOICEMAIL_BOOL = "config_telephony_use_own_number_for_voicemail_bool"; + field public static final String KEY_CONFIG_WIFI_DISABLE_IN_ECBM = "config_wifi_disable_in_ecbm"; field public static final String KEY_CSP_ENABLED_BOOL = "csp_enabled_bool"; field public static final String KEY_DATA_LIMIT_NOTIFICATION_BOOL = "data_limit_notification_bool"; field public static final String KEY_DATA_LIMIT_THRESHOLD_BYTES_LONG = "data_limit_threshold_bytes_long"; @@ -44437,6 +44534,7 @@ package android.telephony { field public static final String KEY_DEFAULT_VM_NUMBER_STRING = "default_vm_number_string"; field public static final String KEY_DIAL_STRING_REPLACE_STRING_ARRAY = "dial_string_replace_string_array"; field public static final String KEY_DISABLE_CDMA_ACTIVATION_CODE_BOOL = "disable_cdma_activation_code_bool"; + field public static final String KEY_DISABLE_CHARGE_INDICATION_BOOL = "disable_charge_indication_bool"; field public static final String KEY_DISABLE_SUPPLEMENTARY_SERVICES_IN_AIRPLANE_MODE_BOOL = "disable_supplementary_services_in_airplane_mode_bool"; field public static final String KEY_DISCONNECT_CAUSE_PLAY_BUSYTONE_INT_ARRAY = "disconnect_cause_play_busytone_int_array"; field public static final String KEY_DISPLAY_HD_AUDIO_PROPERTY_BOOL = "display_hd_audio_property_bool"; @@ -44446,9 +44544,13 @@ package android.telephony { field public static final String KEY_EDITABLE_ENHANCED_4G_LTE_BOOL = "editable_enhanced_4g_lte_bool"; field public static final String KEY_EDITABLE_VOICEMAIL_NUMBER_BOOL = "editable_voicemail_number_bool"; field public static final String KEY_EDITABLE_VOICEMAIL_NUMBER_SETTING_BOOL = "editable_voicemail_number_setting_bool"; + field public static final String KEY_EDITABLE_WFC_MODE_BOOL = "editable_wfc_mode_bool"; + field public static final String KEY_EDITABLE_WFC_ROAMING_MODE_BOOL = "editable_wfc_roaming_mode_bool"; + field public static final String KEY_EMERGENCY_NOTIFICATION_DELAY_INT = "emergency_notification_delay_int"; field public static final String KEY_EMERGENCY_NUMBER_PREFIX_STRING_ARRAY = "emergency_number_prefix_string_array"; field public static final String KEY_ENABLE_DIALER_KEY_VIBRATION_BOOL = "enable_dialer_key_vibration_bool"; field public static final String KEY_ENHANCED_4G_LTE_ON_BY_DEFAULT_BOOL = "enhanced_4g_lte_on_by_default_bool"; + field public static final String KEY_ENHANCED_4G_LTE_TITLE_VARIANT_INT = "enhanced_4g_lte_title_variant_int"; field public static final String KEY_FORCE_HOME_NETWORK_BOOL = "force_home_network_bool"; field public static final String KEY_GSM_DTMF_TONE_DELAY_INT = "gsm_dtmf_tone_delay_int"; field public static final String KEY_GSM_NONROAMING_NETWORKS_STRING_ARRAY = "gsm_nonroaming_networks_string_array"; @@ -44457,13 +44559,17 @@ package android.telephony { field public static final String KEY_HIDE_CARRIER_NETWORK_SETTINGS_BOOL = "hide_carrier_network_settings_bool"; field public static final String KEY_HIDE_ENHANCED_4G_LTE_BOOL = "hide_enhanced_4g_lte_bool"; field public static final String KEY_HIDE_IMS_APN_BOOL = "hide_ims_apn_bool"; + field public static final String KEY_HIDE_LTE_PLUS_DATA_ICON_BOOL = "hide_lte_plus_data_icon_bool"; field public static final String KEY_HIDE_PREFERRED_NETWORK_TYPE_BOOL = "hide_preferred_network_type_bool"; field public static final String KEY_HIDE_PRESET_APN_DETAILS_BOOL = "hide_preset_apn_details_bool"; field public static final String KEY_HIDE_SIM_LOCK_SETTINGS_BOOL = "hide_sim_lock_settings_bool"; + field public static final String KEY_IGNORE_DATA_ENABLED_CHANGED_FOR_VIDEO_CALLS = "ignore_data_enabled_changed_for_video_calls"; + field public static final String KEY_IGNORE_RTT_MODE_SETTING_BOOL = "ignore_rtt_mode_setting_bool"; field public static final String KEY_IGNORE_SIM_NETWORK_LOCKED_EVENTS_BOOL = "ignore_sim_network_locked_events_bool"; field public static final String KEY_IMS_CONFERENCE_SIZE_LIMIT_INT = "ims_conference_size_limit_int"; field public static final String KEY_IMS_DTMF_TONE_DELAY_INT = "ims_dtmf_tone_delay_int"; field public static final String KEY_IS_IMS_CONFERENCE_SIZE_ENFORCED_BOOL = "is_ims_conference_size_enforced_bool"; + field public static final String KEY_LTE_ENABLED_BOOL = "lte_enabled_bool"; field public static final String KEY_LTE_RSRQ_THRESHOLDS_INT_ARRAY = "lte_rsrq_thresholds_int_array"; field public static final String KEY_LTE_RSSNR_THRESHOLDS_INT_ARRAY = "lte_rssnr_thresholds_int_array"; field public static final String KEY_MDN_IS_ADDITIONAL_VOICEMAIL_NUMBER_BOOL = "mdn_is_additional_voicemail_number_bool"; @@ -44472,6 +44578,7 @@ package android.telephony { field public static final String KEY_MMS_ALIAS_MIN_CHARS_INT = "aliasMinChars"; field public static final String KEY_MMS_ALLOW_ATTACH_AUDIO_BOOL = "allowAttachAudio"; field public static final String KEY_MMS_APPEND_TRANSACTION_ID_BOOL = "enabledTransID"; + field public static final String KEY_MMS_CLOSE_CONNECTION_BOOL = "mmsCloseConnection"; field public static final String KEY_MMS_EMAIL_GATEWAY_NUMBER_STRING = "emailGatewayNumber"; field public static final String KEY_MMS_GROUP_MMS_ENABLED_BOOL = "enableGroupMms"; field public static final String KEY_MMS_HTTP_PARAMS_STRING = "httpParams"; @@ -44499,6 +44606,7 @@ package android.telephony { field public static final String KEY_MMS_UA_PROF_URL_STRING = "uaProfUrl"; field public static final String KEY_MMS_USER_AGENT_STRING = "userAgent"; field public static final String KEY_MONTHLY_DATA_CYCLE_DAY_INT = "monthly_data_cycle_day_int"; + field public static final String KEY_ONLY_AUTO_SELECT_IN_HOME_NETWORK_BOOL = "only_auto_select_in_home_network"; field public static final String KEY_ONLY_SINGLE_DC_ALLOWED_INT_ARRAY = "only_single_dc_allowed_int_array"; field public static final String KEY_OPERATOR_SELECTION_EXPAND_BOOL = "operator_selection_expand_bool"; field public static final String KEY_OPPORTUNISTIC_NETWORK_DATA_SWITCH_HYSTERESIS_TIME_LONG = "opportunistic_network_data_switch_hysteresis_time_long"; @@ -44512,15 +44620,24 @@ package android.telephony { field public static final String KEY_PREVENT_CLIR_ACTIVATION_AND_DEACTIVATION_CODE_BOOL = "prevent_clir_activation_and_deactivation_code_bool"; field public static final String KEY_RADIO_RESTART_FAILURE_CAUSES_INT_ARRAY = "radio_restart_failure_causes_int_array"; field public static final String KEY_RCS_CONFIG_SERVER_URL_STRING = "rcs_config_server_url_string"; + field public static final String KEY_READ_ONLY_APN_FIELDS_STRING_ARRAY = "read_only_apn_fields_string_array"; + field public static final String KEY_READ_ONLY_APN_TYPES_STRING_ARRAY = "read_only_apn_types_string_array"; field public static final String KEY_REQUIRE_ENTITLEMENT_CHECKS_BOOL = "require_entitlement_checks_bool"; field @Deprecated public static final String KEY_RESTART_RADIO_ON_PDP_FAIL_REGULAR_DEACTIVATION_BOOL = "restart_radio_on_pdp_fail_regular_deactivation_bool"; field public static final String KEY_RTT_SUPPORTED_BOOL = "rtt_supported_bool"; + field public static final String KEY_SHOW_4G_FOR_3G_DATA_ICON_BOOL = "show_4g_for_3g_data_icon_bool"; + field public static final String KEY_SHOW_4G_FOR_LTE_DATA_ICON_BOOL = "show_4g_for_lte_data_icon_bool"; field public static final String KEY_SHOW_APN_SETTING_CDMA_BOOL = "show_apn_setting_cdma_bool"; + field public static final String KEY_SHOW_BLOCKING_PAY_PHONE_OPTION_BOOL = "show_blocking_pay_phone_option_bool"; field public static final String KEY_SHOW_CALL_BLOCKING_DISABLED_NOTIFICATION_ALWAYS_BOOL = "show_call_blocking_disabled_notification_always_bool"; + field public static final String KEY_SHOW_CARRIER_DATA_ICON_PATTERN_STRING = "show_carrier_data_icon_pattern_string"; field public static final String KEY_SHOW_CDMA_CHOICES_BOOL = "show_cdma_choices_bool"; field public static final String KEY_SHOW_ICCID_IN_SIM_STATUS_BOOL = "show_iccid_in_sim_status_bool"; + field public static final String KEY_SHOW_IMS_REGISTRATION_STATUS_BOOL = "show_ims_registration_status_bool"; field public static final String KEY_SHOW_ONSCREEN_DIAL_BUTTON_BOOL = "show_onscreen_dial_button_bool"; field public static final String KEY_SHOW_SIGNAL_STRENGTH_IN_SIM_STATUS_BOOL = "show_signal_strength_in_sim_status_bool"; + field public static final String KEY_SHOW_VIDEO_CALL_CHARGES_ALERT_DIALOG_BOOL = "show_video_call_charges_alert_dialog_bool"; + field public static final String KEY_SHOW_WFC_LOCATION_PRIVACY_POLICY_BOOL = "show_wfc_location_privacy_policy_bool"; field public static final String KEY_SIMPLIFIED_NETWORK_SETTINGS_BOOL = "simplified_network_settings_bool"; field public static final String KEY_SIM_NETWORK_UNLOCK_ALLOW_DISMISS_BOOL = "sim_network_unlock_allow_dismiss_bool"; field public static final String KEY_SMS_REQUIRES_DESTINATION_NUMBER_CONVERSION_BOOL = "sms_requires_destination_number_conversion_bool"; @@ -44528,14 +44645,20 @@ package android.telephony { field public static final String KEY_SUPPORT_CLIR_NETWORK_DEFAULT_BOOL = "support_clir_network_default_bool"; field public static final String KEY_SUPPORT_CONFERENCE_CALL_BOOL = "support_conference_call_bool"; field public static final String KEY_SUPPORT_EMERGENCY_SMS_OVER_IMS_BOOL = "support_emergency_sms_over_ims_bool"; + field public static final String KEY_SUPPORT_ENHANCED_CALL_BLOCKING_BOOL = "support_enhanced_call_blocking_bool"; + field public static final String KEY_SUPPORT_IMS_CONFERENCE_EVENT_PACKAGE_BOOL = "support_ims_conference_event_package_bool"; field public static final String KEY_SUPPORT_PAUSE_IMS_VIDEO_CALLS_BOOL = "support_pause_ims_video_calls_bool"; field public static final String KEY_SUPPORT_SWAP_AFTER_MERGE_BOOL = "support_swap_after_merge_bool"; + field public static final String KEY_SUPPORT_TDSCDMA_BOOL = "support_tdscdma_bool"; + field public static final String KEY_SUPPORT_TDSCDMA_ROAMING_NETWORKS_STRING_ARRAY = "support_tdscdma_roaming_networks_string_array"; field public static final String KEY_TREAT_DOWNGRADED_VIDEO_CALLS_AS_VIDEO_CALLS_BOOL = "treat_downgraded_video_calls_as_video_calls_bool"; field public static final String KEY_TTY_SUPPORTED_BOOL = "tty_supported_bool"; + field public static final String KEY_UNLOGGABLE_NUMBERS_STRING_ARRAY = "unloggable_numbers_string_array"; field public static final String KEY_USE_HFA_FOR_PROVISIONING_BOOL = "use_hfa_for_provisioning_bool"; field public static final String KEY_USE_OTASP_FOR_PROVISIONING_BOOL = "use_otasp_for_provisioning_bool"; field public static final String KEY_USE_RCS_PRESENCE_BOOL = "use_rcs_presence_bool"; field public static final String KEY_USE_RCS_SIP_OPTIONS_BOOL = "use_rcs_sip_options_bool"; + field public static final String KEY_USE_WFC_HOME_NETWORK_MODE_IN_ROAMING_NETWORK_BOOL = "use_wfc_home_network_mode_in_roaming_network_bool"; field public static final String KEY_VOICEMAIL_NOTIFICATION_PERSISTENT_BOOL = "voicemail_notification_persistent_bool"; field public static final String KEY_VOICE_PRIVACY_DISABLE_UI_BOOL = "voice_privacy_disable_ui_bool"; field public static final String KEY_VOLTE_REPLACEMENT_RAT_INT = "volte_replacement_rat_int"; @@ -44548,6 +44671,8 @@ package android.telephony { field public static final String KEY_VVM_PREFETCH_BOOL = "vvm_prefetch_bool"; field public static final String KEY_VVM_SSL_ENABLED_BOOL = "vvm_ssl_enabled_bool"; field public static final String KEY_VVM_TYPE_STRING = "vvm_type_string"; + field public static final String KEY_WFC_EMERGENCY_ADDRESS_CARRIER_APP_STRING = "wfc_emergency_address_carrier_app_string"; + field public static final String KEY_WORLD_MODE_ENABLED_BOOL = "world_mode_enabled_bool"; field public static final String KEY_WORLD_PHONE_BOOL = "world_phone_bool"; } @@ -44650,7 +44775,8 @@ package android.telephony { method public int getCellConnectionStatus(); method @NonNull public abstract android.telephony.CellIdentity getCellIdentity(); method @NonNull public abstract android.telephony.CellSignalStrength getCellSignalStrength(); - method public long getTimeStamp(); + method @Deprecated public long getTimeStamp(); + method public long getTimestampNanos(); method public boolean isRegistered(); field public static final int CONNECTION_NONE = 0; // 0x0 field public static final int CONNECTION_PRIMARY_SERVING = 1; // 0x1 @@ -44885,6 +45011,35 @@ package android.telephony { field @Deprecated public static final int UNKNOWN_RSSI = 99; // 0x63 } + public final class NetworkRegistrationInfo implements android.os.Parcelable { + method public int describeContents(); + method public int getAccessNetworkTechnology(); + method @NonNull public java.util.List<java.lang.Integer> getAvailableServices(); + method @Nullable public android.telephony.CellIdentity getCellIdentity(); + method public int getDomain(); + method public int getNrState(); + method public int getTransportType(); + method public boolean isRegistered(); + method public boolean isRoaming(); + method public boolean isSearching(); + method public void writeToParcel(android.os.Parcel, int); + field @NonNull public static final android.os.Parcelable.Creator<android.telephony.NetworkRegistrationInfo> CREATOR; + field public static final int DOMAIN_CS = 1; // 0x1 + field public static final int DOMAIN_CS_PS = 3; // 0x3 + field public static final int DOMAIN_PS = 2; // 0x2 + field public static final int DOMAIN_UNKNOWN = 0; // 0x0 + field public static final int NR_STATE_CONNECTED = 3; // 0x3 + field public static final int NR_STATE_NONE = 0; // 0x0 + field public static final int NR_STATE_NOT_RESTRICTED = 2; // 0x2 + field public static final int NR_STATE_RESTRICTED = 1; // 0x1 + field public static final int SERVICE_TYPE_DATA = 2; // 0x2 + field public static final int SERVICE_TYPE_EMERGENCY = 5; // 0x5 + field public static final int SERVICE_TYPE_SMS = 3; // 0x3 + field public static final int SERVICE_TYPE_UNKNOWN = 0; // 0x0 + field public static final int SERVICE_TYPE_VIDEO = 4; // 0x4 + field public static final int SERVICE_TYPE_VOICE = 1; // 0x1 + } + public class NetworkScan { method public void stopScan(); field public static final int ERROR_INTERRUPTED = 10002; // 0x2712 @@ -45000,6 +45155,7 @@ package android.telephony { method @RequiresPermission("android.permission.READ_PRECISE_PHONE_STATE") public void onImsCallDisconnectCauseChanged(@NonNull android.telephony.ims.ImsReasonInfo); method public void onMessageWaitingIndicatorChanged(boolean); method @RequiresPermission("android.permission.MODIFY_PHONE_STATE") public void onPreciseDataConnectionStateChanged(@NonNull android.telephony.PreciseDataConnectionState); + method public void onRegistrationFailed(@NonNull android.telephony.CellIdentity, @NonNull String, int, int, int); method public void onServiceStateChanged(android.telephony.ServiceState); method @Deprecated public void onSignalStrengthChanged(int); method public void onSignalStrengthsChanged(android.telephony.SignalStrength); @@ -45017,6 +45173,7 @@ package android.telephony { field public static final int LISTEN_MESSAGE_WAITING_INDICATOR = 4; // 0x4 field public static final int LISTEN_NONE = 0; // 0x0 field @RequiresPermission("android.permission.MODIFY_PHONE_STATE") public static final int LISTEN_PRECISE_DATA_CONNECTION_STATE = 4096; // 0x1000 + field @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE) public static final int LISTEN_REGISTRATION_FAILURE = 1073741824; // 0x40000000 field public static final int LISTEN_SERVICE_STATE = 1; // 0x1 field @Deprecated public static final int LISTEN_SIGNAL_STRENGTH = 2; // 0x2 field public static final int LISTEN_SIGNAL_STRENGTHS = 256; // 0x100 @@ -45055,11 +45212,13 @@ package android.telephony { method public int getChannelNumber(); method public int getDuplexMode(); method public boolean getIsManualSelection(); + method @NonNull public java.util.List<android.telephony.NetworkRegistrationInfo> getNetworkRegistrationInfoList(); method public String getOperatorAlphaLong(); method public String getOperatorAlphaShort(); method public String getOperatorNumeric(); method public boolean getRoaming(); method public int getState(); + method public boolean isSearching(); method public void setIsManualSelection(boolean); method public void setOperatorName(String, String, String); method public void setRoaming(boolean); @@ -45090,6 +45249,7 @@ package android.telephony { method @Deprecated public int getGsmBitErrorRate(); method @Deprecated public int getGsmSignalStrength(); method public int getLevel(); + method public long getTimestampNanos(); method @Deprecated public boolean isGsm(); method public void writeToParcel(android.os.Parcel, int); field @NonNull public static final android.os.Parcelable.Creator<android.telephony.SignalStrength> CREATOR; @@ -45239,6 +45399,7 @@ package android.telephony { method public byte[] getPdu(); method public int getProtocolIdentifier(); method public String getPseudoSubject(); + method @Nullable public String getRecipientAddress(); method public String getServiceCenterAddress(); method public int getStatus(); method public int getStatusOnIcc(); @@ -45310,6 +45471,7 @@ package android.telephony { public class SubscriptionManager { method public void addOnOpportunisticSubscriptionsChangedListener(@NonNull java.util.concurrent.Executor, @NonNull android.telephony.SubscriptionManager.OnOpportunisticSubscriptionsChangedListener); method public void addOnSubscriptionsChangedListener(android.telephony.SubscriptionManager.OnSubscriptionsChangedListener); + method public void addOnSubscriptionsChangedListener(@NonNull java.util.concurrent.Executor, @NonNull android.telephony.SubscriptionManager.OnSubscriptionsChangedListener); method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void addSubscriptionsIntoGroup(@NonNull java.util.List<java.lang.Integer>, @NonNull android.os.ParcelUuid); method public boolean canManageSubscription(android.telephony.SubscriptionInfo); method @NonNull @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public android.os.ParcelUuid createSubscriptionGroup(@NonNull java.util.List<java.lang.Integer>); @@ -45375,6 +45537,7 @@ package android.telephony { method public long getDataLimitBytes(); method public long getDataUsageBytes(); method public long getDataUsageTime(); + method @Nullable public int[] getNetworkTypes(); method @Nullable public CharSequence getSummary(); method @Nullable public CharSequence getTitle(); method public void writeToParcel(android.os.Parcel, int); @@ -45394,6 +45557,7 @@ package android.telephony { method public static android.telephony.SubscriptionPlan.Builder createRecurring(java.time.ZonedDateTime, java.time.Period); method public android.telephony.SubscriptionPlan.Builder setDataLimit(long, int); method public android.telephony.SubscriptionPlan.Builder setDataUsage(long, long); + method @NonNull public android.telephony.SubscriptionPlan.Builder setNetworkTypes(@Nullable int[]); method public android.telephony.SubscriptionPlan.Builder setSummary(@Nullable CharSequence); method public android.telephony.SubscriptionPlan.Builder setTitle(@Nullable CharSequence); } @@ -45465,12 +45629,12 @@ package android.telephony { method public android.net.Uri getVoicemailRingtoneUri(android.telecom.PhoneAccountHandle); method public boolean hasCarrierPrivileges(); method public boolean hasIccCard(); - method public boolean iccCloseLogicalChannel(int); - method public byte[] iccExchangeSimIO(int, int, int, int, int, String); + method @Deprecated public boolean iccCloseLogicalChannel(int); + method @Deprecated public byte[] iccExchangeSimIO(int, int, int, int, int, String); method @Deprecated public android.telephony.IccOpenLogicalChannelResponse iccOpenLogicalChannel(String); - method public android.telephony.IccOpenLogicalChannelResponse iccOpenLogicalChannel(String, int); - method public String iccTransmitApduBasicChannel(int, int, int, int, int, String); - method public String iccTransmitApduLogicalChannel(int, int, int, int, int, int, String); + method @Deprecated public android.telephony.IccOpenLogicalChannelResponse iccOpenLogicalChannel(String, int); + method @Deprecated public String iccTransmitApduBasicChannel(int, int, int, int, int, String); + method @Deprecated public String iccTransmitApduLogicalChannel(int, int, int, int, int, int, String); method public boolean isConcurrentVoiceAndDataSupported(); method @RequiresPermission(anyOf={android.Manifest.permission.ACCESS_NETWORK_STATE, android.Manifest.permission.MODIFY_PHONE_STATE}) public boolean isDataEnabled(); method @RequiresPermission(anyOf={android.Manifest.permission.ACCESS_NETWORK_STATE, android.Manifest.permission.READ_PHONE_STATE}) public boolean isDataRoamingEnabled(); @@ -45488,7 +45652,7 @@ package android.telephony { method @RequiresPermission(android.Manifest.permission.ACCESS_FINE_LOCATION) public void requestCellInfoUpdate(@NonNull java.util.concurrent.Executor, @NonNull android.telephony.TelephonyManager.CellInfoCallback); method @RequiresPermission(allOf={android.Manifest.permission.MODIFY_PHONE_STATE, android.Manifest.permission.ACCESS_FINE_LOCATION}) public android.telephony.NetworkScan requestNetworkScan(android.telephony.NetworkScanRequest, java.util.concurrent.Executor, android.telephony.TelephonyScanManager.NetworkScanCallback); method public void sendDialerSpecialCode(String); - method public String sendEnvelopeWithStatus(String); + method @Deprecated public String sendEnvelopeWithStatus(String); method @RequiresPermission(android.Manifest.permission.CALL_PHONE) public void sendUssdRequest(String, android.telephony.TelephonyManager.UssdResponseCallback, android.os.Handler); method public void sendVisualVoicemailSms(String, int, String, android.app.PendingIntent); method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void setDataEnabled(boolean); diff --git a/api/lint-baseline.txt b/api/lint-baseline.txt index 27204985d8d9..07106babeb76 100644 --- a/api/lint-baseline.txt +++ b/api/lint-baseline.txt @@ -489,6 +489,10 @@ MissingNullability: android.icu.lang.UCharacter.UnicodeBlock#EGYPTIAN_HIEROGLYPH MissingNullability: android.icu.lang.UCharacter.UnicodeBlock#ELYMAIC: +MissingNullability: android.icu.lang.UCharacter.UnicodeBlock#KHITAN_SMALL_SCRIPT: + +MissingNullability: android.icu.lang.UCharacter.UnicodeBlock#LISU_SUPPLEMENT: + MissingNullability: android.icu.lang.UCharacter.UnicodeBlock#NANDINAGARI: MissingNullability: android.icu.lang.UCharacter.UnicodeBlock#NYIAKENG_PUACHUE_HMONG: @@ -499,22 +503,28 @@ MissingNullability: android.icu.lang.UCharacter.UnicodeBlock#SMALL_KANA_EXTENSIO MissingNullability: android.icu.lang.UCharacter.UnicodeBlock#SYMBOLS_AND_PICTOGRAPHS_EXTENDED_A: +MissingNullability: android.icu.lang.UCharacter.UnicodeBlock#SYMBOLS_FOR_LEGACY_COMPUTING: + MissingNullability: android.icu.lang.UCharacter.UnicodeBlock#TAMIL_SUPPLEMENT: +MissingNullability: android.icu.lang.UCharacter.UnicodeBlock#TANGUT_SUPPLEMENT: + MissingNullability: android.icu.lang.UCharacter.UnicodeBlock#WANCHO: +MissingNullability: android.icu.lang.UCharacter.UnicodeBlock#YEZIDI: + MissingNullability: android.icu.text.DateTimePatternGenerator#getFieldDisplayName(int, android.icu.text.DateTimePatternGenerator.DisplayWidth): MissingNullability: android.icu.text.DateTimePatternGenerator#getFieldDisplayName(int, android.icu.text.DateTimePatternGenerator.DisplayWidth) parameter #1: MissingNullability: android.icu.util.MeasureUnit#ATMOSPHERE: - Missing nullability on field `ATMOSPHERE` in class `class android.icu.util.MeasureUnit` + MissingNullability: android.icu.util.MeasureUnit#PERCENT: - Missing nullability on field `PERCENT` in class `class android.icu.util.MeasureUnit` + MissingNullability: android.icu.util.MeasureUnit#PERMILLE: - Missing nullability on field `PERMILLE` in class `class android.icu.util.MeasureUnit` + MissingNullability: android.icu.util.MeasureUnit#PETABYTE: - Missing nullability on field `PETABYTE` in class `class android.icu.util.MeasureUnit` + MissingNullability: android.icu.util.VersionInfo#UNICODE_12_0: MissingNullability: android.icu.util.VersionInfo#UNICODE_12_1: diff --git a/api/module-app-current.txt b/api/module-app-current.txt new file mode 100644 index 000000000000..d802177e249b --- /dev/null +++ b/api/module-app-current.txt @@ -0,0 +1 @@ +// Signature format: 2.0 diff --git a/api/module-app-removed.txt b/api/module-app-removed.txt new file mode 100644 index 000000000000..d802177e249b --- /dev/null +++ b/api/module-app-removed.txt @@ -0,0 +1 @@ +// Signature format: 2.0 diff --git a/api/module-lib-current.txt b/api/module-lib-current.txt new file mode 100644 index 000000000000..c8253a0b9e88 --- /dev/null +++ b/api/module-lib-current.txt @@ -0,0 +1,126 @@ +// Signature format: 2.0 +package android.app.timedetector { + + public final class PhoneTimeSuggestion implements android.os.Parcelable { + method public void addDebugInfo(@NonNull String); + method public void addDebugInfo(@NonNull java.util.List<java.lang.String>); + method public int describeContents(); + method @NonNull public java.util.List<java.lang.String> getDebugInfo(); + method public int getPhoneId(); + method @Nullable public android.os.TimestampedValue<java.lang.Long> getUtcTime(); + method public void writeToParcel(@NonNull android.os.Parcel, int); + field @NonNull public static final android.os.Parcelable.Creator<android.app.timedetector.PhoneTimeSuggestion> CREATOR; + } + + public static final class PhoneTimeSuggestion.Builder { + ctor public PhoneTimeSuggestion.Builder(int); + method @NonNull public android.app.timedetector.PhoneTimeSuggestion.Builder addDebugInfo(@NonNull String); + method @NonNull public android.app.timedetector.PhoneTimeSuggestion build(); + method @NonNull public android.app.timedetector.PhoneTimeSuggestion.Builder setUtcTime(@Nullable android.os.TimestampedValue<java.lang.Long>); + } + + public class TimeDetector { + method @RequiresPermission("android.permission.SUGGEST_PHONE_TIME_AND_ZONE") public void suggestPhoneTime(@NonNull android.app.timedetector.PhoneTimeSuggestion); + } + +} + +package android.app.timezonedetector { + + public final class PhoneTimeZoneSuggestion implements android.os.Parcelable { + method public void addDebugInfo(@NonNull String); + method public void addDebugInfo(@NonNull java.util.List<java.lang.String>); + method @NonNull public static android.app.timezonedetector.PhoneTimeZoneSuggestion createEmptySuggestion(int, @NonNull String); + method public int describeContents(); + method @NonNull public java.util.List<java.lang.String> getDebugInfo(); + method public int getMatchType(); + method public int getPhoneId(); + method public int getQuality(); + method @Nullable public String getZoneId(); + method public void writeToParcel(@NonNull android.os.Parcel, int); + field @NonNull public static final android.os.Parcelable.Creator<android.app.timezonedetector.PhoneTimeZoneSuggestion> CREATOR; + field public static final int MATCH_TYPE_EMULATOR_ZONE_ID = 4; // 0x4 + field public static final int MATCH_TYPE_NA = 0; // 0x0 + field public static final int MATCH_TYPE_NETWORK_COUNTRY_AND_OFFSET = 3; // 0x3 + field public static final int MATCH_TYPE_NETWORK_COUNTRY_ONLY = 2; // 0x2 + field public static final int MATCH_TYPE_TEST_NETWORK_OFFSET_ONLY = 5; // 0x5 + field public static final int QUALITY_MULTIPLE_ZONES_WITH_DIFFERENT_OFFSETS = 3; // 0x3 + field public static final int QUALITY_MULTIPLE_ZONES_WITH_SAME_OFFSET = 2; // 0x2 + field public static final int QUALITY_NA = 0; // 0x0 + field public static final int QUALITY_SINGLE_ZONE = 1; // 0x1 + } + + public static final class PhoneTimeZoneSuggestion.Builder { + ctor public PhoneTimeZoneSuggestion.Builder(int); + method @NonNull public android.app.timezonedetector.PhoneTimeZoneSuggestion.Builder addDebugInfo(@NonNull String); + method @NonNull public android.app.timezonedetector.PhoneTimeZoneSuggestion build(); + method @NonNull public android.app.timezonedetector.PhoneTimeZoneSuggestion.Builder setMatchType(int); + method @NonNull public android.app.timezonedetector.PhoneTimeZoneSuggestion.Builder setQuality(int); + method @NonNull public android.app.timezonedetector.PhoneTimeZoneSuggestion.Builder setZoneId(@Nullable String); + } + + public class TimeZoneDetector { + method @RequiresPermission("android.permission.SUGGEST_PHONE_TIME_AND_ZONE") public void suggestPhoneTimeZone(@NonNull android.app.timezonedetector.PhoneTimeZoneSuggestion); + } + +} + +package android.os { + + public final class TimestampedValue<T> implements android.os.Parcelable { + ctor public TimestampedValue(long, @Nullable T); + method public int describeContents(); + method public long getReferenceTimeMillis(); + method @Nullable public T getValue(); + method public static long referenceTimeDifference(@NonNull android.os.TimestampedValue<?>, @NonNull android.os.TimestampedValue<?>); + method public void writeToParcel(@NonNull android.os.Parcel, int); + field @NonNull public static final android.os.Parcelable.Creator<android.os.TimestampedValue<?>> CREATOR; + } + +} + +package android.timezone { + + public final class CountryTimeZones { + method @Nullable public android.icu.util.TimeZone getDefaultTimeZone(); + method @Nullable public String getDefaultTimeZoneId(); + method @NonNull public java.util.List<android.timezone.CountryTimeZones.TimeZoneMapping> getEffectiveTimeZoneMappingsAt(long); + method public boolean hasUtcZone(long); + method public boolean isDefaultTimeZoneBoosted(); + method public boolean isForCountryCode(@NonNull String); + method @Nullable public android.timezone.CountryTimeZones.OffsetResult lookupByOffsetWithBias(int, @Nullable Boolean, @Nullable Integer, long, @Nullable android.icu.util.TimeZone); + } + + public static final class CountryTimeZones.OffsetResult { + ctor public CountryTimeZones.OffsetResult(@NonNull android.icu.util.TimeZone, boolean); + method @NonNull public android.icu.util.TimeZone getTimeZone(); + method public boolean isOnlyMatch(); + } + + public static final class CountryTimeZones.TimeZoneMapping { + method @Nullable public android.icu.util.TimeZone getTimeZone(); + method @NonNull public String getTimeZoneId(); + } + + public class TelephonyLookup { + method @NonNull public static android.timezone.TelephonyLookup getInstance(); + method @Nullable public android.timezone.TelephonyNetworkFinder getTelephonyNetworkFinder(); + } + + public class TelephonyNetwork { + method @NonNull public String getCountryIsoCode(); + method @NonNull public String getMcc(); + method @NonNull public String getMnc(); + } + + public class TelephonyNetworkFinder { + method @Nullable public android.timezone.TelephonyNetwork findNetworkByMccMnc(@NonNull String, @NonNull String); + } + + public final class TimeZoneFinder { + method @NonNull public static android.timezone.TimeZoneFinder getInstance(); + method @Nullable public android.timezone.CountryTimeZones lookupCountryTimeZones(@NonNull String); + } + +} + diff --git a/api/module-lib-removed.txt b/api/module-lib-removed.txt new file mode 100644 index 000000000000..d802177e249b --- /dev/null +++ b/api/module-lib-removed.txt @@ -0,0 +1 @@ +// Signature format: 2.0 diff --git a/api/system-current.txt b/api/system-current.txt index a883bec2b956..04aa300ea88b 100755 --- a/api/system-current.txt +++ b/api/system-current.txt @@ -8,6 +8,7 @@ package android { field public static final String ACCESS_DRM_CERTIFICATES = "android.permission.ACCESS_DRM_CERTIFICATES"; field @Deprecated public static final String ACCESS_FM_RADIO = "android.permission.ACCESS_FM_RADIO"; field public static final String ACCESS_INSTANT_APPS = "android.permission.ACCESS_INSTANT_APPS"; + field public static final String ACCESS_MESSAGES_ON_ICC = "android.permission.ACCESS_MESSAGES_ON_ICC"; field public static final String ACCESS_MOCK_LOCATION = "android.permission.ACCESS_MOCK_LOCATION"; field public static final String ACCESS_MTP = "android.permission.ACCESS_MTP"; field public static final String ACCESS_NETWORK_CONDITIONS = "android.permission.ACCESS_NETWORK_CONDITIONS"; @@ -181,6 +182,7 @@ package android { field public static final String REVIEW_ACCESSIBILITY_SERVICES = "android.permission.REVIEW_ACCESSIBILITY_SERVICES"; field public static final String REVOKE_RUNTIME_PERMISSIONS = "android.permission.REVOKE_RUNTIME_PERMISSIONS"; field public static final String SCORE_NETWORKS = "android.permission.SCORE_NETWORKS"; + field public static final String SECURE_ELEMENT_PRIVILEGED = "android.permission.SECURE_ELEMENT_PRIVILEGED"; field public static final String SEND_DEVICE_CUSTOMIZATION_READY = "android.permission.SEND_DEVICE_CUSTOMIZATION_READY"; field public static final String SEND_SHOW_SUSPENDED_APP_DETAILS = "android.permission.SEND_SHOW_SUSPENDED_APP_DETAILS"; field public static final String SEND_SMS_NO_CONFIRMATION = "android.permission.SEND_SMS_NO_CONFIRMATION"; @@ -198,6 +200,7 @@ package android { field public static final String STOP_APP_SWITCHES = "android.permission.STOP_APP_SWITCHES"; field public static final String SUBSTITUTE_NOTIFICATION_APP_NAME = "android.permission.SUBSTITUTE_NOTIFICATION_APP_NAME"; field public static final String SUBSTITUTE_SHARE_TARGET_APP_NAME_AND_ICON = "android.permission.SUBSTITUTE_SHARE_TARGET_APP_NAME_AND_ICON"; + field public static final String SUGGEST_PHONE_TIME_AND_ZONE = "android.permission.SUGGEST_PHONE_TIME_AND_ZONE"; field public static final String SUSPEND_APPS = "android.permission.SUSPEND_APPS"; field public static final String TETHER_PRIVILEGED = "android.permission.TETHER_PRIVILEGED"; field public static final String TV_INPUT_HARDWARE = "android.permission.TV_INPUT_HARDWARE"; @@ -596,6 +599,7 @@ package android.app { public class StatusBarManager { 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 { @@ -680,6 +684,7 @@ package android.app { package android.app.admin { public class DevicePolicyManager { + method @RequiresPermission(android.Manifest.permission.INTERACT_ACROSS_USERS) public boolean getBluetoothContactSharingDisabled(@NonNull android.os.UserHandle); method @Nullable @RequiresPermission(android.Manifest.permission.MANAGE_USERS) public String getDeviceOwner(); method @RequiresPermission(android.Manifest.permission.MANAGE_USERS) public android.content.ComponentName getDeviceOwnerComponentOnAnyUser(); method @RequiresPermission(android.Manifest.permission.MANAGE_USERS) public String getDeviceOwnerNameOnAnyUser(); @@ -1206,6 +1211,10 @@ package android.app.usage { field public static final String SERVICE_INTERFACE = "android.app.usage.CacheQuotaService"; } + public class NetworkStatsManager { + method @NonNull @RequiresPermission(android.Manifest.permission.UPDATE_DEVICE_STATS) public android.net.netstats.provider.NetworkStatsProviderCallback registerNetworkStatsProvider(@NonNull String, @NonNull android.net.netstats.provider.AbstractNetworkStatsProvider); + } + public static final class UsageEvents.Event { method public int getInstanceId(); method @Nullable public String getNotificationChannelId(); @@ -1412,6 +1421,10 @@ package android.bluetooth { method @RequiresPermission(android.Manifest.permission.BLUETOOTH_ADMIN) public boolean setConnectionPolicy(@NonNull android.bluetooth.BluetoothDevice, int); } + public final class BluetoothHidDevice implements android.bluetooth.BluetoothProfile { + method @RequiresPermission(android.Manifest.permission.BLUETOOTH_ADMIN) public boolean setConnectionPolicy(@NonNull android.bluetooth.BluetoothDevice, int); + } + public final class BluetoothHidHost implements android.bluetooth.BluetoothProfile { method @NonNull public java.util.List<android.bluetooth.BluetoothDevice> getConnectedDevices(); method @RequiresPermission(android.Manifest.permission.BLUETOOTH) public int getConnectionPolicy(@Nullable android.bluetooth.BluetoothDevice); @@ -1420,12 +1433,20 @@ package android.bluetooth { field public static final String ACTION_CONNECTION_STATE_CHANGED = "android.bluetooth.input.profile.action.CONNECTION_STATE_CHANGED"; } + public final class BluetoothMap implements android.bluetooth.BluetoothProfile { + method @NonNull public java.util.List<android.bluetooth.BluetoothDevice> getConnectedDevices(); + method @RequiresPermission(android.Manifest.permission.BLUETOOTH) public int getConnectionPolicy(@Nullable android.bluetooth.BluetoothDevice); + method @RequiresPermission(android.Manifest.permission.BLUETOOTH_ADMIN) public boolean setConnectionPolicy(@Nullable android.bluetooth.BluetoothDevice, int); + field public static final String ACTION_CONNECTION_STATE_CHANGED = "android.bluetooth.map.profile.action.CONNECTION_STATE_CHANGED"; + } + public final class BluetoothPan implements android.bluetooth.BluetoothProfile { method protected void finalize(); method @NonNull public java.util.List<android.bluetooth.BluetoothDevice> getConnectedDevices(); method public int getConnectionState(@Nullable android.bluetooth.BluetoothDevice); method public boolean isTetheringOn(); method public void setBluetoothTethering(boolean); + method @RequiresPermission(android.Manifest.permission.BLUETOOTH_ADMIN) public boolean setConnectionPolicy(@NonNull android.bluetooth.BluetoothDevice, int); field public static final String ACTION_CONNECTION_STATE_CHANGED = "android.bluetooth.pan.profile.action.CONNECTION_STATE_CHANGED"; field public static final String EXTRA_LOCAL_ROLE = "android.bluetooth.pan.extra.LOCAL_ROLE"; field public static final int LOCAL_NAP_ROLE = 1; // 0x1 @@ -1555,6 +1576,7 @@ package android.content { field public static final String NETD_SERVICE = "netd"; field public static final String NETWORK_POLICY_SERVICE = "netpolicy"; field public static final String NETWORK_SCORE_SERVICE = "network_score"; + field public static final String NETWORK_STACK_SERVICE = "network_stack"; field public static final String OEM_LOCK_SERVICE = "oem_lock"; field public static final String PERMISSION_SERVICE = "permission"; field public static final String PERSISTENT_DATA_BLOCK_SERVICE = "persistent_data_block"; @@ -3240,9 +3262,17 @@ package android.hardware.usb { } public class UsbManager { + method @RequiresPermission(android.Manifest.permission.MANAGE_USB) public long getCurrentFunctions(); method @NonNull @RequiresPermission(android.Manifest.permission.MANAGE_USB) public java.util.List<android.hardware.usb.UsbPort> getPorts(); method @RequiresPermission(android.Manifest.permission.MANAGE_USB) public void grantPermission(android.hardware.usb.UsbDevice, String); + method @RequiresPermission(android.Manifest.permission.MANAGE_USB) public void setCurrentFunctions(long); field @RequiresPermission(android.Manifest.permission.MANAGE_USB) public static final String ACTION_USB_PORT_CHANGED = "android.hardware.usb.action.USB_PORT_CHANGED"; + field public static final String ACTION_USB_STATE = "android.hardware.usb.action.USB_STATE"; + field public static final long FUNCTION_NONE = 0L; // 0x0L + field public static final long FUNCTION_RNDIS = 32L; // 0x20L + field public static final String USB_CONFIGURED = "configured"; + field public static final String USB_CONNECTED = "connected"; + field public static final String USB_FUNCTION_RNDIS = "rndis"; } public final class UsbPort { @@ -3676,6 +3706,19 @@ package android.media { method public android.media.AudioAttributes.Builder setInternalCapturePreset(int); } + public final class AudioDeviceAddress implements android.os.Parcelable { + ctor public AudioDeviceAddress(@NonNull android.media.AudioDeviceInfo); + ctor public AudioDeviceAddress(int, int, @NonNull String); + method public int describeContents(); + method @NonNull public String getAddress(); + method public int getRole(); + method public int getType(); + method public void writeToParcel(@NonNull android.os.Parcel, int); + field @NonNull public static final android.os.Parcelable.Creator<android.media.AudioDeviceAddress> CREATOR; + field public static final int ROLE_INPUT = 1; // 0x1 + field public static final int ROLE_OUTPUT = 2; // 0x2 + } + public final class AudioFocusInfo implements android.os.Parcelable { method public int describeContents(); method @NonNull public android.media.AudioAttributes getAttributes(); @@ -3797,6 +3840,14 @@ package android.media { } +package android.media.audiofx { + + public class AudioEffect { + ctor @RequiresPermission("android.permission.MODIFY_DEFAULT_AUDIO_EFFECTS") public AudioEffect(@NonNull java.util.UUID, @NonNull android.media.AudioDeviceAddress); + } + +} + package android.media.audiopolicy { public class AudioMix { @@ -4234,7 +4285,9 @@ package android.net { public class CaptivePortal implements android.os.Parcelable { method public void logEvent(int, @NonNull String); + method 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 @@ -4246,13 +4299,16 @@ package android.net { method @Deprecated @RequiresPermission("android.permission.NETWORK_SETTINGS") public String getCaptivePortalServerUrl(); method @RequiresPermission(android.Manifest.permission.TETHER_PRIVILEGED) public void getLatestTetheringEntitlementResult(int, boolean, @NonNull java.util.concurrent.Executor, @NonNull android.net.ConnectivityManager.OnTetheringEntitlementResultListener); method @RequiresPermission(anyOf={android.Manifest.permission.TETHER_PRIVILEGED, android.Manifest.permission.WRITE_SETTINGS}) public boolean isTetheringSupported(); + method @RequiresPermission(android.Manifest.permission.NETWORK_FACTORY) public int registerNetworkProvider(@NonNull android.net.NetworkProvider); method @RequiresPermission(android.Manifest.permission.TETHER_PRIVILEGED) public void registerTetheringEventCallback(@NonNull java.util.concurrent.Executor, @NonNull android.net.ConnectivityManager.OnTetheringEventCallback); + method @Deprecated public void requestNetwork(@NonNull android.net.NetworkRequest, @NonNull android.net.ConnectivityManager.NetworkCallback, int, int, @NonNull android.os.Handler); method @RequiresPermission(anyOf={"android.permission.NETWORK_SETTINGS", android.Manifest.permission.NETWORK_SETUP_WIZARD, "android.permission.NETWORK_STACK"}) public void setAirplaneMode(boolean); method @RequiresPermission(anyOf={android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK, "android.permission.NETWORK_STACK"}) public boolean shouldAvoidBadWifi(); method @RequiresPermission(android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK) public void startCaptivePortalApp(@NonNull android.net.Network, @NonNull android.os.Bundle); method @RequiresPermission(android.Manifest.permission.TETHER_PRIVILEGED) public void startTethering(int, boolean, android.net.ConnectivityManager.OnStartTetheringCallback); method @RequiresPermission(android.Manifest.permission.TETHER_PRIVILEGED) public void startTethering(int, boolean, android.net.ConnectivityManager.OnStartTetheringCallback, android.os.Handler); method @RequiresPermission(android.Manifest.permission.TETHER_PRIVILEGED) public void stopTethering(int); + method @RequiresPermission(android.Manifest.permission.NETWORK_FACTORY) public void unregisterNetworkProvider(@NonNull android.net.NetworkProvider); method @RequiresPermission(android.Manifest.permission.TETHER_PRIVILEGED) public void unregisterTetheringEventCallback(@NonNull android.net.ConnectivityManager.OnTetheringEventCallback); 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"; @@ -4262,6 +4318,8 @@ package android.net { field public static final int TETHER_ERROR_ENTITLEMENT_UNKONWN = 13; // 0xd field public static final int TETHER_ERROR_NO_ERROR = 0; // 0x0 field public static final int TETHER_ERROR_PROVISION_FAILED = 11; // 0xb + field public static final int TYPE_NONE = -1; // 0xffffffff + field @Deprecated public static final int TYPE_WIFI_P2P = 13; // 0xd } public abstract static class ConnectivityManager.OnStartTetheringCallback { @@ -4279,6 +4337,14 @@ package android.net { method public void onUpstreamChanged(@Nullable android.net.Network); } + public class InvalidPacketException extends java.lang.Exception { + ctor public InvalidPacketException(int); + field public static final int ERROR_INVALID_IP_ADDRESS = -21; // 0xffffffeb + field public static final int ERROR_INVALID_LENGTH = -23; // 0xffffffe9 + field public static final int ERROR_INVALID_PORT = -22; // 0xffffffea + field public final int error; + } + public final class IpConfiguration implements android.os.Parcelable { ctor public IpConfiguration(); ctor public IpConfiguration(@NonNull android.net.IpConfiguration); @@ -4329,6 +4395,15 @@ package android.net { method @NonNull @RequiresPermission(android.Manifest.permission.MANAGE_IPSEC_TUNNELS) public android.net.IpSecTransform buildTunnelModeTransform(@NonNull java.net.InetAddress, @NonNull android.net.IpSecManager.SecurityParameterIndex) throws java.io.IOException, android.net.IpSecManager.ResourceUnavailableException, android.net.IpSecManager.SpiUnavailableException; } + public class KeepalivePacketData { + ctor protected KeepalivePacketData(@NonNull java.net.InetAddress, int, @NonNull java.net.InetAddress, int, @NonNull byte[]) throws android.net.InvalidPacketException; + method @NonNull public byte[] getPacket(); + field @NonNull public final java.net.InetAddress dstAddress; + field public final int dstPort; + field @NonNull public final java.net.InetAddress srcAddress; + field public final int srcPort; + } + 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); @@ -4375,10 +4450,18 @@ package android.net { public final class MatchAllNetworkSpecifier extends android.net.NetworkSpecifier implements android.os.Parcelable { ctor public MatchAllNetworkSpecifier(); method public int describeContents(); + method public boolean satisfiedBy(android.net.NetworkSpecifier); method public void writeToParcel(@NonNull android.os.Parcel, int); field @NonNull public static final android.os.Parcelable.Creator<android.net.MatchAllNetworkSpecifier> CREATOR; } + public final class NattKeepalivePacketData extends android.net.KeepalivePacketData implements android.os.Parcelable { + ctor public NattKeepalivePacketData(@NonNull java.net.InetAddress, int, @NonNull java.net.InetAddress, int, @NonNull byte[]) throws android.net.InvalidPacketException; + method public int describeContents(); + method public void writeToParcel(@NonNull android.os.Parcel, int); + field @NonNull public static final android.os.Parcelable.Creator<android.net.NattKeepalivePacketData> CREATOR; + } + public class Network implements android.os.Parcelable { ctor public Network(@NonNull android.net.Network); method @NonNull public android.net.Network getPrivateDnsBypassingCopy(); @@ -4386,6 +4469,7 @@ package android.net { } public final class NetworkCapabilities implements android.os.Parcelable { + method public boolean deduceRestrictedCapability(); method @NonNull public int[] getTransportTypes(); method public boolean satisfiedByNetworkCapabilities(@Nullable android.net.NetworkCapabilities); method @NonNull public android.net.NetworkCapabilities setSSID(@Nullable String); @@ -4405,6 +4489,17 @@ package android.net { field public final android.net.WifiKey wifiKey; } + public class NetworkProvider { + ctor public NetworkProvider(@NonNull android.content.Context, @NonNull android.os.Looper, @NonNull String); + method @RequiresPermission(android.Manifest.permission.NETWORK_FACTORY) public void declareNetworkRequestUnfulfillable(@NonNull android.net.NetworkRequest); + method @Nullable public android.os.Messenger getMessenger(); + method @NonNull public String getName(); + method public int getProviderId(); + method public void onNetworkRequested(@NonNull android.net.NetworkRequest, int, int); + method public void onRequestWithdrawn(@NonNull android.net.NetworkRequest); + field public static final int ID_NONE = -1; // 0xffffffff + } + public abstract class NetworkRecommendationProvider { ctor public NetworkRecommendationProvider(android.content.Context, java.util.concurrent.Executor); method public final android.os.IBinder getBinder(); @@ -4431,6 +4526,9 @@ package android.net { field @Deprecated public static final String EXTRA_NETWORKS_TO_SCORE = "networksToScore"; field public static final String EXTRA_NEW_SCORER = "newScorer"; field @Deprecated public static final String EXTRA_PACKAGE_NAME = "packageName"; + field public static final int SCORE_FILTER_CURRENT_NETWORK = 1; // 0x1 + field public static final int SCORE_FILTER_NONE = 0; // 0x0 + field public static final int SCORE_FILTER_SCAN_RESULTS = 2; // 0x2 } public static interface NetworkScoreManager.NetworkScoreCallback { @@ -4438,10 +4536,43 @@ package android.net { method public void updateScores(@NonNull java.util.List<android.net.ScoredNetwork>); } + public abstract class NetworkSpecifier { + method public void assertValidFromUid(int); + method @Nullable public android.net.NetworkSpecifier redact(); + method public abstract boolean satisfiedBy(@Nullable android.net.NetworkSpecifier); + } + public class NetworkStack { field public static final String PERMISSION_MAINLINE_NETWORK_STACK = "android.permission.MAINLINE_NETWORK_STACK"; } + public final class NetworkStats implements android.os.Parcelable { + ctor public NetworkStats(long, int); + method @NonNull public android.net.NetworkStats add(@NonNull android.net.NetworkStats); + method @NonNull public android.net.NetworkStats addValues(@NonNull android.net.NetworkStats.Entry); + method public int describeContents(); + method @NonNull public android.net.NetworkStats subtract(@NonNull android.net.NetworkStats); + method public void writeToParcel(@NonNull android.os.Parcel, int); + field @NonNull public static final android.os.Parcelable.Creator<android.net.NetworkStats> CREATOR; + field public static final int DEFAULT_NETWORK_NO = 0; // 0x0 + field public static final int DEFAULT_NETWORK_YES = 1; // 0x1 + field @Nullable public static final String IFACE_ALL; + field public static final String IFACE_VT = "vt_data0"; + field public static final int METERED_NO = 0; // 0x0 + field public static final int METERED_YES = 1; // 0x1 + field public static final int ROAMING_NO = 0; // 0x0 + field public static final int ROAMING_YES = 1; // 0x1 + field public static final int SET_DEFAULT = 0; // 0x0 + field public static final int SET_FOREGROUND = 1; // 0x1 + field public static final int TAG_NONE = 0; // 0x0 + field public static final int UID_ALL = -1; // 0xffffffff + field public static final int UID_TETHERING = -5; // 0xfffffffb + } + + public static class NetworkStats.Entry { + ctor public NetworkStats.Entry(@Nullable String, int, int, int, int, int, int, long, long, long, long, long); + } + 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(); @@ -4481,6 +4612,10 @@ package android.net { field public final android.net.RssiCurve rssiCurve; } + public abstract class SocketKeepalive implements java.lang.AutoCloseable { + field public static final int SUCCESS = 0; // 0x0 + } + public final class StaticIpConfiguration implements android.os.Parcelable { ctor public StaticIpConfiguration(); ctor public StaticIpConfiguration(@Nullable android.net.StaticIpConfiguration); @@ -4508,11 +4643,16 @@ package android.net { public final class StringNetworkSpecifier extends android.net.NetworkSpecifier implements android.os.Parcelable { ctor public StringNetworkSpecifier(@NonNull String); method public int describeContents(); + method public boolean satisfiedBy(android.net.NetworkSpecifier); method public void writeToParcel(@NonNull android.os.Parcel, int); field @NonNull public static final android.os.Parcelable.Creator<android.net.StringNetworkSpecifier> CREATOR; field @NonNull public final String specifier; } + public final class TelephonyNetworkSpecifier extends android.net.NetworkSpecifier implements android.os.Parcelable { + method public boolean satisfiedBy(android.net.NetworkSpecifier); + } + public class TrafficStats { method public static void setThreadStatsTagApp(); method public static void setThreadStatsTagBackup(); @@ -5032,6 +5172,25 @@ package android.net.metrics { } +package android.net.netstats.provider { + + public abstract class AbstractNetworkStatsProvider { + ctor public AbstractNetworkStatsProvider(); + method public abstract void requestStatsUpdate(int); + method public abstract void setAlert(long); + method public abstract void setLimit(@NonNull String, long); + field public static final int QUOTA_UNLIMITED = -1; // 0xffffffff + } + + public class NetworkStatsProviderCallback { + method public void onAlertReached(); + method public void onLimitReached(); + method public void onStatsUpdated(int, @NonNull android.net.NetworkStats, @NonNull android.net.NetworkStats); + method public void unregister(); + } + +} + package android.net.util { public final class SocketUtils { @@ -5381,6 +5540,10 @@ package android.net.wifi { field public int numUsage; } + public final class WifiNetworkSpecifier extends android.net.NetworkSpecifier implements android.os.Parcelable { + method public boolean satisfiedBy(android.net.NetworkSpecifier); + } + 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); @@ -5545,6 +5708,10 @@ package android.net.wifi.aware { method @Deprecated public android.net.NetworkSpecifier createNetworkSpecifierPmk(@NonNull android.net.wifi.aware.PeerHandle, @NonNull byte[]); } + public final class WifiAwareNetworkSpecifier extends android.net.NetworkSpecifier implements android.os.Parcelable { + method public boolean satisfiedBy(android.net.NetworkSpecifier); + } + public static final class WifiAwareNetworkSpecifier.Builder { method @NonNull public android.net.wifi.aware.WifiAwareNetworkSpecifier.Builder setPmk(@NonNull byte[]); } @@ -6121,11 +6288,13 @@ package android.os { public class UpdateEngine { ctor public UpdateEngine(); + method @NonNull public android.os.UpdateEngine.AllocateSpaceResult allocateSpace(@NonNull String, @NonNull String[]); method public void applyPayload(String, long, long, String[]); - method public void applyPayload(@NonNull android.os.ParcelFileDescriptor, long, long, @NonNull String[]); + method public void applyPayload(@NonNull android.content.res.AssetFileDescriptor, @NonNull String[]); method public boolean bind(android.os.UpdateEngineCallback, android.os.Handler); method public boolean bind(android.os.UpdateEngineCallback); method public void cancel(); + method public int cleanupAppliedPayload(); method public void resetStatus(); method public void resume(); method public void suspend(); @@ -6133,14 +6302,21 @@ package android.os { method public boolean verifyPayloadMetadata(String); } + public static final class UpdateEngine.AllocateSpaceResult { + method public int errorCode(); + method public long freeSpaceRequired(); + } + public static final class UpdateEngine.ErrorCodeConstants { ctor public UpdateEngine.ErrorCodeConstants(); + field public static final int DEVICE_CORRUPTED = 61; // 0x3d field public static final int DOWNLOAD_PAYLOAD_VERIFICATION_ERROR = 12; // 0xc field public static final int DOWNLOAD_TRANSFER_ERROR = 9; // 0x9 field public static final int ERROR = 1; // 0x1 field public static final int FILESYSTEM_COPIER_ERROR = 4; // 0x4 field public static final int INSTALL_DEVICE_OPEN_ERROR = 7; // 0x7 field public static final int KERNEL_DEVICE_OPEN_ERROR = 8; // 0x8 + field public static final int NOT_ENOUGH_SPACE = 60; // 0x3c field public static final int PAYLOAD_HASH_MISMATCH_ERROR = 10; // 0xa field public static final int PAYLOAD_MISMATCHED_TYPE_ERROR = 6; // 0x6 field public static final int PAYLOAD_SIZE_MISMATCH_ERROR = 11; // 0xb @@ -6660,6 +6836,7 @@ package android.provider { } public final class Settings { + method public static boolean checkAndNoteWriteSettingsOperation(@NonNull android.content.Context, int, @NonNull String, boolean); field public static final String ACTION_ACCESSIBILITY_DETAILS_SETTINGS = "android.settings.ACCESSIBILITY_DETAILS_SETTINGS"; field public static final String ACTION_ENTERPRISE_PRIVACY_SETTINGS = "android.settings.ENTERPRISE_PRIVACY_SETTINGS"; field public static final String ACTION_LOCATION_CONTROLLER_EXTRA_PACKAGE_SETTINGS = "android.settings.LOCATION_CONTROLLER_EXTRA_PACKAGE_SETTINGS"; @@ -6668,6 +6845,7 @@ package android.provider { field public static final String ACTION_NOTIFICATION_POLICY_ACCESS_DETAIL_SETTINGS = "android.settings.NOTIFICATION_POLICY_ACCESS_DETAIL_SETTINGS"; field public static final String ACTION_REQUEST_ENABLE_CONTENT_CAPTURE = "android.settings.REQUEST_ENABLE_CONTENT_CAPTURE"; field public static final String ACTION_SHOW_ADMIN_SUPPORT_DETAILS = "android.settings.SHOW_ADMIN_SUPPORT_DETAILS"; + field public static final String ACTION_TETHER_PROVISIONING_UI = "android.settings.TETHER_PROVISIONING_UI"; } public static final class Settings.Global extends android.provider.Settings.NameValueTable { @@ -6685,6 +6863,7 @@ package android.provider { field public static final String INSTALL_CARRIER_APP_NOTIFICATION_SLEEP_MILLIS = "install_carrier_app_notification_sleep_millis"; field public static final String OTA_DISABLE_AUTOMATIC_UPDATE = "ota_disable_automatic_update"; field public static final String REQUIRE_PASSWORD_TO_DECRYPT = "require_password_to_decrypt"; + field public static final String TETHER_OFFLOAD_DISABLED = "tether_offload_disabled"; field public static final String TETHER_SUPPORTED = "tether_supported"; field public static final String THEATER_MODE_ON = "theater_mode_on"; field public static final String WEBVIEW_MULTIPROCESS = "webview_multiprocess"; @@ -6774,6 +6953,9 @@ package android.provider { } public static final class Telephony.CellBroadcasts implements android.provider.BaseColumns { + field @NonNull public static final String AUTHORITY_LEGACY = "cellbroadcast-legacy"; + field @NonNull public static final android.net.Uri AUTHORITY_LEGACY_URI; + field @NonNull public static final String CALL_METHOD_GET_PREFERENCE = "get_preference"; 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"; @@ -6804,6 +6986,20 @@ package android.provider { field public static final String SUB_ID = "sub_id"; } + public static final class Telephony.CellBroadcasts.Preference { + field @NonNull public static final String ENABLE_ALERT_VIBRATION_PREF = "enable_alert_vibrate"; + field @NonNull public static final String ENABLE_AREA_UPDATE_INFO_PREF = "enable_area_update_info_alerts"; + field @NonNull public static final String ENABLE_CMAS_AMBER_PREF = "enable_cmas_amber_alerts"; + field @NonNull public static final String ENABLE_CMAS_EXTREME_THREAT_PREF = "enable_cmas_extreme_threat_alerts"; + field @NonNull public static final String ENABLE_CMAS_IN_SECOND_LANGUAGE_PREF = "receive_cmas_in_second_language"; + field @NonNull public static final String ENABLE_CMAS_PRESIDENTIAL_PREF = "enable_cmas_presidential_alerts"; + field @NonNull public static final String ENABLE_CMAS_SEVERE_THREAT_PREF = "enable_cmas_severe_threat_alerts"; + field @NonNull public static final String ENABLE_EMERGENCY_PERF = "enable_emergency_alerts"; + field @NonNull public static final String ENABLE_PUBLIC_SAFETY_PREF = "enable_public_safety_messages"; + field @NonNull public static final String ENABLE_STATE_LOCAL_TEST_PREF = "enable_state_local_test_alerts"; + field @NonNull public static final String ENABLE_TEST_ALERT_PREF = "enable_test_alerts"; + } + public static final class Telephony.SimInfo { field @NonNull public static final android.net.Uri CONTENT_URI; } @@ -7918,8 +8114,6 @@ package android.telephony { public final class AccessNetworkConstants { field public static final int TRANSPORT_TYPE_INVALID = -1; // 0xffffffff - field public static final int TRANSPORT_TYPE_WLAN = 2; // 0x2 - field public static final int TRANSPORT_TYPE_WWAN = 1; // 0x1 } public final class CallAttributes implements android.os.Parcelable { @@ -8031,6 +8225,41 @@ package android.telephony { field public static final String CELL_BROADCAST_SERVICE_INTERFACE = "android.telephony.CellBroadcastService"; } + public abstract class CellIdentity implements android.os.Parcelable { + method @NonNull public abstract android.telephony.CellLocation asCellLocation(); + method @NonNull public abstract android.telephony.CellIdentity sanitizeLocationInfo(); + } + + public final class CellIdentityCdma extends android.telephony.CellIdentity { + method @NonNull public android.telephony.cdma.CdmaCellLocation asCellLocation(); + method @NonNull public android.telephony.CellIdentityCdma sanitizeLocationInfo(); + } + + public final class CellIdentityGsm extends android.telephony.CellIdentity { + method @NonNull public android.telephony.gsm.GsmCellLocation asCellLocation(); + method @NonNull public android.telephony.CellIdentityGsm sanitizeLocationInfo(); + } + + public final class CellIdentityLte extends android.telephony.CellIdentity { + method @NonNull public android.telephony.gsm.GsmCellLocation asCellLocation(); + method @NonNull public android.telephony.CellIdentityLte sanitizeLocationInfo(); + } + + public final class CellIdentityNr extends android.telephony.CellIdentity { + method @NonNull public android.telephony.CellLocation asCellLocation(); + method @NonNull public android.telephony.CellIdentityNr sanitizeLocationInfo(); + } + + public final class CellIdentityTdscdma extends android.telephony.CellIdentity { + method @NonNull public android.telephony.gsm.GsmCellLocation asCellLocation(); + method @NonNull public android.telephony.CellIdentityTdscdma sanitizeLocationInfo(); + } + + public final class CellIdentityWcdma extends android.telephony.CellIdentity { + method @NonNull public android.telephony.gsm.GsmCellLocation asCellLocation(); + method @NonNull public android.telephony.CellIdentityWcdma sanitizeLocationInfo(); + } + public final class DataFailCause { field public static final int ACCESS_ATTEMPT_ALREADY_IN_PROGRESS = 2219; // 0x8ab field public static final int ACCESS_BLOCK = 2087; // 0x827 @@ -8512,35 +8741,18 @@ package android.telephony { } public final class NetworkRegistrationInfo implements android.os.Parcelable { - method public int describeContents(); - method public int getAccessNetworkTechnology(); - method @NonNull public java.util.List<java.lang.Integer> getAvailableServices(); - method @Nullable public android.telephony.CellIdentity getCellIdentity(); method @Nullable public android.telephony.DataSpecificRegistrationInfo getDataSpecificInfo(); - method public int getDomain(); - method public int getNrState(); method public int getRegistrationState(); method public int getRejectCause(); method public int getRoamingType(); - method public int getTransportType(); method public boolean isEmergencyEnabled(); - method public boolean isRoaming(); method public void writeToParcel(android.os.Parcel, int); - field @NonNull public static final android.os.Parcelable.Creator<android.telephony.NetworkRegistrationInfo> CREATOR; - field public static final int DOMAIN_CS = 1; // 0x1 - field public static final int DOMAIN_PS = 2; // 0x2 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 - field public static final int SERVICE_TYPE_DATA = 2; // 0x2 - field public static final int SERVICE_TYPE_EMERGENCY = 5; // 0x5 - field public static final int SERVICE_TYPE_SMS = 3; // 0x3 - field public static final int SERVICE_TYPE_UNKNOWN = 0; // 0x0 - field public static final int SERVICE_TYPE_VIDEO = 4; // 0x4 - field public static final int SERVICE_TYPE_VOICE = 1; // 0x1 } public static final class NetworkRegistrationInfo.Builder { @@ -8645,6 +8857,7 @@ package android.telephony { } public final class PreciseDataConnectionState implements android.os.Parcelable { + ctor public PreciseDataConnectionState(int, int, int, @NonNull String, @Nullable android.net.LinkProperties, int, @Nullable android.telephony.data.ApnSetting); method @Deprecated @NonNull public String getDataConnectionApn(); method @Deprecated public int getDataConnectionApnTypeBitMask(); method @Deprecated public int getDataConnectionFailCause(); @@ -8751,20 +8964,27 @@ package android.telephony { } public class ServiceState implements android.os.Parcelable { + method @NonNull public android.telephony.ServiceState createLocationInfoSanitizedCopy(boolean); + method public void fillInNotifierBundle(@NonNull android.os.Bundle); + method public int getDataNetworkType(); method public int getDataRegistrationState(); method @Nullable public android.telephony.NetworkRegistrationInfo getNetworkRegistrationInfo(int, int); - method @NonNull public java.util.List<android.telephony.NetworkRegistrationInfo> getNetworkRegistrationInfoList(); method @NonNull public java.util.List<android.telephony.NetworkRegistrationInfo> getNetworkRegistrationInfoListForDomain(int); method @NonNull public java.util.List<android.telephony.NetworkRegistrationInfo> getNetworkRegistrationInfoListForTransportType(int); method public int getNrFrequencyRange(); method @Nullable public String getOperatorAlphaLongRaw(); method @Nullable public String getOperatorAlphaShortRaw(); + method @NonNull public static android.telephony.ServiceState newFromBundle(@NonNull android.os.Bundle); field public static final int ROAMING_TYPE_DOMESTIC = 2; // 0x2 field public static final int ROAMING_TYPE_INTERNATIONAL = 3; // 0x3 field public static final int ROAMING_TYPE_NOT_ROAMING = 0; // 0x0 field public static final int ROAMING_TYPE_UNKNOWN = 1; // 0x1 } + public class SignalStrength implements android.os.Parcelable { + ctor public SignalStrength(@NonNull android.telephony.SignalStrength); + } + public final class SmsCbCmasInfo implements android.os.Parcelable { ctor public SmsCbCmasInfo(int, int, int, int, int, int); method public int describeContents(); @@ -8888,13 +9108,20 @@ package android.telephony { } public final class SmsManager { + method @RequiresPermission(android.Manifest.permission.ACCESS_MESSAGES_ON_ICC) public boolean deleteMessageFromIcc(int); method public boolean disableCellBroadcastRange(int, int, int); method public boolean enableCellBroadcastRange(int, int, int); + method @NonNull @RequiresPermission(android.Manifest.permission.ACCESS_MESSAGES_ON_ICC) public java.util.List<android.telephony.SmsMessage> getMessagesFromIcc(); method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public int getSmsCapacityOnIcc(); method public void sendMultipartTextMessage(@NonNull String, @NonNull String, @NonNull java.util.List<java.lang.String>, @Nullable java.util.List<android.app.PendingIntent>, @Nullable java.util.List<android.app.PendingIntent>, @NonNull String); method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void sendMultipartTextMessageWithoutPersisting(String, String, java.util.List<java.lang.String>, java.util.List<android.app.PendingIntent>, java.util.List<android.app.PendingIntent>); } + public class SmsMessage { + method @Nullable public static android.telephony.SmsMessage createFromNativeSmsSubmitPdu(@NonNull byte[], boolean); + method @NonNull @RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED) public static byte[] getSubmitPduEncodedMessage(boolean, @NonNull String, @NonNull String, int, int, int, int, int, int); + } + public class SubscriptionInfo implements android.os.Parcelable { method public boolean areUiccApplicationsEnabled(); method @Nullable public java.util.List<android.telephony.UiccAccessRule> getAccessRules(); @@ -8904,6 +9131,7 @@ package android.telephony { public class SubscriptionManager { method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public boolean canDisablePhysicalSubscription(); + method public boolean canManageSubscription(@Nullable android.telephony.SubscriptionInfo, @Nullable String); method @Nullable @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public android.telephony.SubscriptionInfo getActiveSubscriptionInfoForIcc(@NonNull String); method public java.util.List<android.telephony.SubscriptionInfo> getAvailableSubscriptionInfoList(); method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public int getEnabledSubscriptionId(int); @@ -8916,6 +9144,7 @@ package android.telephony { method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void setDefaultVoiceSubscriptionId(int); method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void setPreferredDataSubscriptionId(int, boolean, @Nullable java.util.concurrent.Executor, @Nullable java.util.function.Consumer<java.lang.Integer>); method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public boolean setSubscriptionEnabled(int, boolean); + method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void setUiccApplicationsEnabled(boolean, int); field @RequiresPermission(android.Manifest.permission.MANAGE_SUBSCRIPTION_PLANS) public static final String ACTION_SUBSCRIPTION_PLANS_CHANGED = "android.telephony.action.SUBSCRIPTION_PLANS_CHANGED"; field @NonNull public static final android.net.Uri ADVANCED_CALLING_ENABLED_CONTENT_URI; field public static final int PROFILE_CLASS_DEFAULT = -1; // 0xffffffff @@ -8971,6 +9200,7 @@ package android.telephony { method @Nullable @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public android.telephony.ImsiEncryptionInfo getCarrierInfoForImsiEncryption(int); method public java.util.List<java.lang.String> getCarrierPackageNamesForIntent(android.content.Intent); method public java.util.List<java.lang.String> getCarrierPackageNamesForIntentAndPhone(android.content.Intent, int); + method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public int getCarrierPrivilegeStatus(int); method @NonNull @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public java.util.List<java.lang.String> getCarrierPrivilegedPackagesForAllActiveSubscriptions(); method @Nullable @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public android.telephony.CarrierRestrictionRules getCarrierRestrictionRules(); method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public String getCdmaMdn(); @@ -8989,6 +9219,7 @@ package android.telephony { method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public boolean getEmergencyCallbackMode(); method public int getEmergencyNumberDbVersion(); method @Nullable @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public String getIsimDomain(); + method @Nullable @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public String[] getIsimImpu(); method @Nullable @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public String getIsimIst(); method @NonNull @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public java.util.Map<java.lang.Integer,java.lang.Integer> getLogicalToPhysicalSlotMapping(); method public int getMaxNumberOfSimultaneouslyActiveSims(); @@ -9008,12 +9239,13 @@ package android.telephony { method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public int getVoiceActivationState(); method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public boolean handlePinMmi(String); method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public boolean handlePinMmiForSubscriber(int, String); - method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public boolean iccCloseLogicalChannelBySlot(int, int); + method @Deprecated @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public boolean iccCloseLogicalChannelBySlot(int, int); method @Nullable @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public android.telephony.IccOpenLogicalChannelResponse iccOpenLogicalChannelBySlot(int, @Nullable String, int); - method @NonNull @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public String iccTransmitApduBasicChannelBySlot(int, int, int, int, int, int, @Nullable String); - method @Nullable @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public String iccTransmitApduLogicalChannelBySlot(int, int, int, int, int, int, int, @Nullable String); + method @Deprecated @NonNull @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public String iccTransmitApduBasicChannelBySlot(int, int, int, int, int, int, @Nullable String); + method @Deprecated @Nullable @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public String iccTransmitApduLogicalChannelBySlot(int, int, int, int, int, int, int, @Nullable String); method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public boolean isAnyRadioPoweredOn(); method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public boolean isApplicationOnUicc(int); + method public boolean isCurrentSimOperator(@NonNull String, int, @Nullable String); method public boolean isDataConnectivityPossible(); method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public boolean isDataEnabledForApn(int); method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public boolean isEmergencyAssistanceEnabled(); @@ -9067,10 +9299,12 @@ package android.telephony { method @RequiresPermission(android.Manifest.permission.READ_ACTIVE_EMERGENCY_SESSION) public void updateTestOtaEmergencyNumberDbFilePath(@NonNull String); field @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public static final String ACTION_ANOMALY_REPORTED = "android.telephony.action.ANOMALY_REPORTED"; field public static final String ACTION_EMERGENCY_ASSISTANCE = "android.telephony.action.EMERGENCY_ASSISTANCE"; - field public static final String ACTION_NETWORK_SET_TIME = "android.telephony.action.NETWORK_SET_TIME"; field public static final String ACTION_SIM_APPLICATION_STATE_CHANGED = "android.telephony.action.SIM_APPLICATION_STATE_CHANGED"; field public static final String ACTION_SIM_CARD_STATE_CHANGED = "android.telephony.action.SIM_CARD_STATE_CHANGED"; field public static final String ACTION_SIM_SLOT_STATUS_CHANGED = "android.telephony.action.SIM_SLOT_STATUS_CHANGED"; + field public static final int CARD_POWER_DOWN = 0; // 0x0 + field public static final int CARD_POWER_UP = 1; // 0x1 + field public static final int CARD_POWER_UP_PASS_THROUGH = 2; // 0x2 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 @@ -9128,6 +9362,7 @@ package android.telephony { method public void addOnSubscriptionsChangedListener(@NonNull android.telephony.SubscriptionManager.OnSubscriptionsChangedListener, @NonNull java.util.concurrent.Executor); method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void notifyCallStateChangedForAllSubscriptions(int, @Nullable String); method public void notifyCarrierNetworkChange(boolean); + method public void notifyRegistrationFailed(int, int, @NonNull android.telephony.CellIdentity, @NonNull String, int, int, int); method public void removeOnOpportunisticSubscriptionsChangedListener(@NonNull android.telephony.SubscriptionManager.OnOpportunisticSubscriptionsChangedListener); method public void removeOnSubscriptionsChangedListener(@NonNull android.telephony.SubscriptionManager.OnSubscriptionsChangedListener); } @@ -9665,6 +9900,7 @@ package android.telephony.ims { public class ImsManager { method @NonNull public android.telephony.ims.ImsMmTelManager getImsMmTelManager(int); method @NonNull public android.telephony.ims.ImsRcsManager getImsRcsManager(int); + field public static final String ACTION_FORBIDDEN_NO_SERVICE_AUTHORIZATION = "com.android.internal.intent.action.ACTION_FORBIDDEN_NO_SERVICE_AUTHORIZATION"; } public class ImsMmTelManager implements android.telephony.ims.RegistrationManager { @@ -9959,13 +10195,30 @@ package android.telephony.ims { method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) @WorkerThread public int getProvisioningIntValue(int); method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) @WorkerThread public boolean getProvisioningStatusForCapability(@android.telephony.ims.feature.MmTelFeature.MmTelCapabilities.MmTelCapability int, int); method @Nullable @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) @WorkerThread public String getProvisioningStringValue(int); + method @RequiresPermission(android.Manifest.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.Manifest.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(@android.telephony.ims.feature.MmTelFeature.MmTelCapabilities.MmTelCapability 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.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public void unregisterProvisioningChangedCallback(@NonNull android.telephony.ims.ProvisioningManager.Callback); + field public static final int KEY_EAB_PROVISIONING_STATUS = 25; // 0x19 + field public static final int KEY_RCS_AVAILABILITY_CACHE_EXPIRATION_SEC = 19; // 0x13 + field public static final int KEY_RCS_CAPABILITIES_CACHE_EXPIRATION_SEC = 18; // 0x12 + field public static final int KEY_RCS_CAPABILITIES_POLL_INTERVAL_SEC = 20; // 0x14 + field public static final int KEY_RCS_CAPABILITY_DISCOVERY_ENABLED = 17; // 0x11 + field public static final int KEY_RCS_CAPABILITY_POLL_LIST_SUB_EXP_SEC = 23; // 0x17 + field public static final int KEY_RCS_MAX_NUM_ENTRIES_IN_RCL = 22; // 0x16 + field public static final int KEY_RCS_PUBLISH_SOURCE_THROTTLE_MS = 21; // 0x15 + field public static final int KEY_RCS_PUBLISH_TIMER_EXTENDED_SEC = 16; // 0x10 + field public static final int KEY_RCS_PUBLISH_TIMER_SEC = 15; // 0xf + field public static final int KEY_T1_TIMER_VALUE_MS = 7; // 0x7 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 KEY_VOLTE_PROVISIONING_STATUS = 10; // 0xa + field public static final int KEY_VT_PROVISIONING_STATUS = 11; // 0xb + field public static final int PROVISIONING_RESULT_UNKNOWN = -1; // 0xffffffff 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"; @@ -9978,6 +10231,47 @@ package android.telephony.ims { method public void onProvisioningStringChanged(int, @NonNull String); } + public final class RcsContactUceCapability implements android.os.Parcelable { + method public int describeContents(); + method @NonNull public java.util.List<java.lang.String> getCapableExtensionTags(); + method @NonNull public android.net.Uri getContactUri(); + method @Nullable public android.net.Uri getServiceUri(int); + method public boolean isCapable(int); + method public boolean isCapable(@NonNull String); + method public void writeToParcel(@NonNull android.os.Parcel, int); + field public static final int CAPABILITY_CHAT_SESSION = 2; // 0x2 + field public static final int CAPABILITY_CHAT_SESSION_STORE_FORWARD = 4; // 0x4 + field public static final int CAPABILITY_CHAT_STANDALONE = 1; // 0x1 + field public static final int CAPABILITY_DISCOVERY_VIA_PRESENCE = 4096; // 0x1000 + field public static final int CAPABILITY_FILE_TRANSFER = 8; // 0x8 + field public static final int CAPABILITY_FILE_TRANSFER_HTTP = 64; // 0x40 + field public static final int CAPABILITY_FILE_TRANSFER_SMS = 128; // 0x80 + field public static final int CAPABILITY_FILE_TRANSFER_STORE_FORWARD = 32; // 0x20 + field public static final int CAPABILITY_FILE_TRANSFER_THUMBNAIL = 16; // 0x10 + field public static final int CAPABILITY_GEOLOCATION_PULL = 131072; // 0x20000 + field public static final int CAPABILITY_GEOLOCATION_PULL_FILE_TRANSFER = 262144; // 0x40000 + field public static final int CAPABILITY_GEOLOCATION_PUSH = 32768; // 0x8000 + field public static final int CAPABILITY_GEOLOCATION_PUSH_SMS = 65536; // 0x10000 + field public static final int CAPABILITY_IMAGE_SHARE = 256; // 0x100 + field public static final int CAPABILITY_IP_VIDEO_CALL = 16384; // 0x4000 + field public static final int CAPABILITY_IP_VOICE_CALL = 8192; // 0x2000 + field public static final int CAPABILITY_RCS_VIDEO_CALL = 1048576; // 0x100000 + field public static final int CAPABILITY_RCS_VIDEO_ONLY_CALL = 2097152; // 0x200000 + field public static final int CAPABILITY_RCS_VOICE_CALL = 524288; // 0x80000 + field public static final int CAPABILITY_SOCIAL_PRESENCE = 2048; // 0x800 + field public static final int CAPABILITY_VIDEO_SHARE = 1024; // 0x400 + field public static final int CAPABILITY_VIDEO_SHARE_DURING_CS_CALL = 512; // 0x200 + field @NonNull public static final android.os.Parcelable.Creator<android.telephony.ims.RcsContactUceCapability> CREATOR; + } + + public static class RcsContactUceCapability.Builder { + ctor public RcsContactUceCapability.Builder(@NonNull android.net.Uri); + method @NonNull public android.telephony.ims.RcsContactUceCapability.Builder add(int, @NonNull android.net.Uri); + method @NonNull public android.telephony.ims.RcsContactUceCapability.Builder add(int); + method @NonNull public android.telephony.ims.RcsContactUceCapability.Builder add(@NonNull String); + method @NonNull public android.telephony.ims.RcsContactUceCapability build(); + } + public interface RegistrationManager { method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public void getRegistrationState(@NonNull java.util.concurrent.Executor, @NonNull java.util.function.Consumer<java.lang.Integer>); method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public void getRegistrationTransportType(@NonNull java.util.concurrent.Executor, @NonNull java.util.function.Consumer<java.lang.Integer>); @@ -10019,6 +10313,7 @@ package android.telephony.ims.feature { 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(); @@ -10167,6 +10462,7 @@ package android.telephony.ims.stub { 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 @@ -10265,6 +10561,17 @@ package android.telephony.ims.stub { method public int updateClir(int); method public int updateColp(boolean); method public int updateColr(int); + field public static final int CALL_BARRING_ALL = 7; // 0x7 + field public static final int CALL_BARRING_ALL_INCOMING = 1; // 0x1 + field public static final int CALL_BARRING_ALL_OUTGOING = 2; // 0x2 + field public static final int CALL_BARRING_ANONYMOUS_INCOMING = 6; // 0x6 + field public static final int CALL_BARRING_INCOMING_ALL_SERVICES = 9; // 0x9 + field public static final int CALL_BARRING_OUTGOING_ALL_SERVICES = 8; // 0x8 + field public static final int CALL_BARRING_OUTGOING_INTL = 3; // 0x3 + field public static final int CALL_BARRING_OUTGOING_INTL_EXCL_HOME = 4; // 0x4 + field public static final int CALL_BARRING_SPECIFIC_INCOMING_CALLS = 10; // 0xa + field public static final int CALL_BLOCKING_INCOMING_WHEN_ROAMING = 5; // 0x5 + field public static final int INVALID_RESULT = -1; // 0xffffffff } } diff --git a/api/test-current.txt b/api/test-current.txt index 80f7e4bff61c..f438d551e596 100644 --- a/api/test-current.txt +++ b/api/test-current.txt @@ -352,6 +352,7 @@ package android.app { public class StatusBarManager { 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 { @@ -650,6 +651,7 @@ package android.content { method public void setContentCaptureOptions(@Nullable android.content.ContentCaptureOptions); field public static final String BUGREPORT_SERVICE = "bugreport"; field public static final String CONTENT_CAPTURE_MANAGER_SERVICE = "content_capture"; + field public static final String NETWORK_STACK_SERVICE = "network_stack"; field public static final String PERMISSION_SERVICE = "permission"; field public static final String ROLLBACK_SERVICE = "rollback"; field public static final String STATUS_BAR_SERVICE = "statusbar"; @@ -1349,7 +1351,9 @@ package android.net { public class CaptivePortal implements android.os.Parcelable { method public void logEvent(int, @NonNull String); + method 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 @@ -2355,6 +2359,7 @@ package android.provider { public final class Settings { field public static final String ACTION_ENTERPRISE_PRIVACY_SETTINGS = "android.settings.ENTERPRISE_PRIVACY_SETTINGS"; 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 } @@ -2371,6 +2376,7 @@ package android.provider { 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"; } @@ -2882,8 +2888,6 @@ package android.telephony { public final class AccessNetworkConstants { field public static final int TRANSPORT_TYPE_INVALID = -1; // 0xffffffff - field public static final int TRANSPORT_TYPE_WLAN = 2; // 0x2 - field public static final int TRANSPORT_TYPE_WWAN = 1; // 0x1 } public final class CallQuality implements android.os.Parcelable { @@ -2946,34 +2950,18 @@ package android.telephony { } public final class NetworkRegistrationInfo implements android.os.Parcelable { - method public int describeContents(); - method public int getAccessNetworkTechnology(); - method @NonNull public java.util.List<java.lang.Integer> getAvailableServices(); - method @Nullable public android.telephony.CellIdentity getCellIdentity(); method @Nullable public android.telephony.DataSpecificRegistrationInfo getDataSpecificInfo(); - method public int getDomain(); method public int getRegistrationState(); method public int getRejectCause(); method public int getRoamingType(); - method public int getTransportType(); method public boolean isEmergencyEnabled(); - method public boolean isRoaming(); method public void writeToParcel(android.os.Parcel, int); - field @NonNull public static final android.os.Parcelable.Creator<android.telephony.NetworkRegistrationInfo> CREATOR; - field public static final int DOMAIN_CS = 1; // 0x1 - field public static final int DOMAIN_PS = 2; // 0x2 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 - field public static final int SERVICE_TYPE_DATA = 2; // 0x2 - field public static final int SERVICE_TYPE_EMERGENCY = 5; // 0x5 - field public static final int SERVICE_TYPE_SMS = 3; // 0x3 - field public static final int SERVICE_TYPE_UNKNOWN = 0; // 0x0 - field public static final int SERVICE_TYPE_VIDEO = 4; // 0x4 - field public static final int SERVICE_TYPE_VOICE = 1; // 0x1 } public static final class NetworkRegistrationInfo.Builder { @@ -3010,6 +2998,7 @@ package android.telephony { public class ServiceState implements android.os.Parcelable { method public void addNetworkRegistrationInfo(android.telephony.NetworkRegistrationInfo); + method public int getDataNetworkType(); method public void setCdmaSystemAndNetworkId(int, int); method public void setCellBandwidths(int[]); method public void setChannelNumber(int); @@ -3280,6 +3269,7 @@ package android.telephony.ims { public class ImsManager { method @NonNull public android.telephony.ims.ImsMmTelManager getImsMmTelManager(int); method @NonNull public android.telephony.ims.ImsRcsManager getImsRcsManager(int); + field public static final String ACTION_FORBIDDEN_NO_SERVICE_AUTHORIZATION = "com.android.internal.intent.action.ACTION_FORBIDDEN_NO_SERVICE_AUTHORIZATION"; } public class ImsMmTelManager implements android.telephony.ims.RegistrationManager { @@ -3570,13 +3560,30 @@ package android.telephony.ims { 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(@android.telephony.ims.feature.MmTelFeature.MmTelCapabilities.MmTelCapability 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(@android.telephony.ims.feature.MmTelFeature.MmTelCapabilities.MmTelCapability 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_EAB_PROVISIONING_STATUS = 25; // 0x19 + field public static final int KEY_RCS_AVAILABILITY_CACHE_EXPIRATION_SEC = 19; // 0x13 + field public static final int KEY_RCS_CAPABILITIES_CACHE_EXPIRATION_SEC = 18; // 0x12 + field public static final int KEY_RCS_CAPABILITIES_POLL_INTERVAL_SEC = 20; // 0x14 + field public static final int KEY_RCS_CAPABILITY_DISCOVERY_ENABLED = 17; // 0x11 + field public static final int KEY_RCS_CAPABILITY_POLL_LIST_SUB_EXP_SEC = 23; // 0x17 + field public static final int KEY_RCS_MAX_NUM_ENTRIES_IN_RCL = 22; // 0x16 + field public static final int KEY_RCS_PUBLISH_SOURCE_THROTTLE_MS = 21; // 0x15 + field public static final int KEY_RCS_PUBLISH_TIMER_EXTENDED_SEC = 16; // 0x10 + field public static final int KEY_RCS_PUBLISH_TIMER_SEC = 15; // 0xf + field public static final int KEY_T1_TIMER_VALUE_MS = 7; // 0x7 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 KEY_VOLTE_PROVISIONING_STATUS = 10; // 0xa + field public static final int KEY_VT_PROVISIONING_STATUS = 11; // 0xb + field public static final int PROVISIONING_RESULT_UNKNOWN = -1; // 0xffffffff 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"; @@ -3630,6 +3637,7 @@ package android.telephony.ims.feature { 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(); @@ -3778,6 +3786,7 @@ package android.telephony.ims.stub { 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 @@ -3876,6 +3885,17 @@ package android.telephony.ims.stub { method public int updateClir(int); method public int updateColp(boolean); method public int updateColr(int); + field public static final int CALL_BARRING_ALL = 7; // 0x7 + field public static final int CALL_BARRING_ALL_INCOMING = 1; // 0x1 + field public static final int CALL_BARRING_ALL_OUTGOING = 2; // 0x2 + field public static final int CALL_BARRING_ANONYMOUS_INCOMING = 6; // 0x6 + field public static final int CALL_BARRING_INCOMING_ALL_SERVICES = 9; // 0x9 + field public static final int CALL_BARRING_OUTGOING_ALL_SERVICES = 8; // 0x8 + field public static final int CALL_BARRING_OUTGOING_INTL = 3; // 0x3 + field public static final int CALL_BARRING_OUTGOING_INTL_EXCL_HOME = 4; // 0x4 + field public static final int CALL_BARRING_SPECIFIC_INCOMING_CALLS = 10; // 0xa + field public static final int CALL_BLOCKING_INCOMING_WHEN_ROAMING = 5; // 0x5 + field public static final int INVALID_RESULT = -1; // 0xffffffff } } diff --git a/cmds/sm/src/com/android/commands/sm/Sm.java b/cmds/sm/src/com/android/commands/sm/Sm.java index 6033655c8513..c2ee6dcd13b2 100644 --- a/cmds/sm/src/com/android/commands/sm/Sm.java +++ b/cmds/sm/src/com/android/commands/sm/Sm.java @@ -103,6 +103,10 @@ public final class Sm { runSetVirtualDisk(); } else if ("set-isolated-storage".equals(op)) { runIsolatedStorage(); + } else if ("start-checkpoint".equals(op)) { + runStartCheckpoint(); + } else if ("supports-checkpoint".equals(op)) { + runSupportsCheckpoint(); } else { throw new IllegalArgumentException(); } @@ -313,6 +317,27 @@ public final class Sm { } } + private void runStartCheckpoint() throws RemoteException { + final String numRetriesString = nextArg(); + if (numRetriesString == null) { + throw new IllegalArgumentException("Expected <num-retries>"); + } + int numRetries; + try { + numRetries = Integer.parseInt(numRetriesString); + } catch (NumberFormatException e) { + throw new IllegalArgumentException("<num-retries> must be a positive integer"); + } + if (numRetries <= 0) { + throw new IllegalArgumentException("<num-retries> must be a positive integer"); + } + mSm.startCheckpoint(numRetries); + } + + private void runSupportsCheckpoint() throws RemoteException { + System.out.println(mSm.supportsCheckpoint()); + } + private String nextArg() { if (mNextArg >= mArgs.length) { return null; @@ -344,6 +369,10 @@ public final class Sm { System.err.println(""); System.err.println(" sm set-isolated-storage [on|off|default]"); System.err.println(""); + System.err.println(" sm start-checkpoint <num-retries>"); + System.err.println(""); + System.err.println(" sm supports-checkpoint"); + System.err.println(""); return 1; } } diff --git a/cmds/statsd/Android.bp b/cmds/statsd/Android.bp index 8944dedd6c96..da1a76f8169d 100644 --- a/cmds/statsd/Android.bp +++ b/cmds/statsd/Android.bp @@ -138,11 +138,57 @@ cc_defaults { "android.hardware.power@1.1", "android.hardware.power.stats@1.0", "libpackagelistparser", + "libstatsmetadata", "libsysutils", "libcutils", ], } +// ================ +// libstatsmetadata +// ================ + +genrule { + name: "atoms_info.h", + tools: ["stats-log-api-gen"], + cmd: "$(location stats-log-api-gen) --atomsInfoHeader $(genDir)/atoms_info.h", + out: [ + "atoms_info.h", + ], +} + +genrule { + name: "atoms_info.cpp", + tools: ["stats-log-api-gen"], + cmd: "$(location stats-log-api-gen) --atomsInfoCpp $(genDir)/atoms_info.cpp", + out: [ + "atoms_info.cpp", + ], +} + +cc_library_shared { + name: "libstatsmetadata", + host_supported: true, + generated_sources: [ + "atoms_info.cpp", + ], + generated_headers: [ + "atoms_info.h", + ], + cflags: [ + "-Wall", + "-Werror", + ], + export_generated_headers: [ + "atoms_info.h", + ], + shared_libs: [ + "libcutils", + "libstatslog", + ], +} + + // ========= // statsd // ========= diff --git a/cmds/statsd/OWNERS b/cmds/statsd/OWNERS index 380e499a5abf..a61babf32e58 100644 --- a/cmds/statsd/OWNERS +++ b/cmds/statsd/OWNERS @@ -1,7 +1,9 @@ -jianjin@google.com +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/src/FieldValue.cpp b/cmds/statsd/src/FieldValue.cpp index 13f5c8ae5fd8..320a32ab4648 100644 --- a/cmds/statsd/src/FieldValue.cpp +++ b/cmds/statsd/src/FieldValue.cpp @@ -18,8 +18,8 @@ #include "Log.h" #include "FieldValue.h" #include "HashableDimensionKey.h" +#include "atoms_info.h" #include "math.h" -#include "statslog.h" namespace android { namespace os { diff --git a/cmds/statsd/src/StatsLogProcessor.cpp b/cmds/statsd/src/StatsLogProcessor.cpp index ff7416c4b9e0..c9e026bf231c 100644 --- a/cmds/statsd/src/StatsLogProcessor.cpp +++ b/cmds/statsd/src/StatsLogProcessor.cpp @@ -23,6 +23,7 @@ #include <frameworks/base/cmds/statsd/src/active_config_list.pb.h> #include "StatsLogProcessor.h" #include "android-base/stringprintf.h" +#include "atoms_info.h" #include "external/StatsPullerManager.h" #include "guardrail/StatsdStats.h" #include "metrics/CountMetricProducer.h" diff --git a/cmds/statsd/src/atoms.proto b/cmds/statsd/src/atoms.proto index c92315687e71..c0e414fc2b45 100644 --- a/cmds/statsd/src/atoms.proto +++ b/cmds/statsd/src/atoms.proto @@ -123,10 +123,10 @@ message Atom { AppStartOccurred app_start_occurred = 48; AppStartCanceled app_start_canceled = 49; AppStartFullyDrawn app_start_fully_drawn = 50; - LmkKillOccurred lmk_kill_occurred = 51; + LmkKillOccurred lmk_kill_occurred = 51 [(log_from_module) = "lmkd"]; PictureInPictureStateChanged picture_in_picture_state_changed = 52; WifiMulticastLockStateChanged wifi_multicast_lock_state_changed = 53; - LmkStateChanged lmk_state_changed = 54; + LmkStateChanged lmk_state_changed = 54 [(log_from_module) = "lmkd"]; AppStartMemoryStateCaptured app_start_memory_state_captured = 55; ShutdownSequenceReported shutdown_sequence_reported = 56; BootSequenceReported boot_sequence_reported = 57; diff --git a/cmds/statsd/src/external/PowerStatsPuller.cpp b/cmds/statsd/src/external/PowerStatsPuller.cpp index b142caca3acc..dc69b78f0329 100644 --- a/cmds/statsd/src/external/PowerStatsPuller.cpp +++ b/cmds/statsd/src/external/PowerStatsPuller.cpp @@ -22,6 +22,7 @@ #include <vector> #include "PowerStatsPuller.h" +#include "statslog.h" #include "stats_log_util.h" using android::hardware::hidl_vec; diff --git a/cmds/statsd/src/external/puller_util.cpp b/cmds/statsd/src/external/puller_util.cpp index 0b9b6abfd6d6..ccfd666573c4 100644 --- a/cmds/statsd/src/external/puller_util.cpp +++ b/cmds/statsd/src/external/puller_util.cpp @@ -18,8 +18,8 @@ #include "Log.h" #include "StatsPullerManager.h" +#include "atoms_info.h" #include "puller_util.h" -#include "statslog.h" namespace android { namespace os { diff --git a/cmds/statsd/src/guardrail/StatsdStats.h b/cmds/statsd/src/guardrail/StatsdStats.h index 23d2aceb4fc3..564b9ee8051c 100644 --- a/cmds/statsd/src/guardrail/StatsdStats.h +++ b/cmds/statsd/src/guardrail/StatsdStats.h @@ -16,7 +16,7 @@ #pragma once #include "config/ConfigKey.h" -#include "statslog.h" +#include "atoms_info.h" #include <gtest/gtest_prod.h> #include <log/log_time.h> diff --git a/cmds/statsd/src/metrics/MetricsManager.cpp b/cmds/statsd/src/metrics/MetricsManager.cpp index 963205ee56f4..7b7d0cac0d30 100644 --- a/cmds/statsd/src/metrics/MetricsManager.cpp +++ b/cmds/statsd/src/metrics/MetricsManager.cpp @@ -19,6 +19,7 @@ #include "statslog.h" #include "CountMetricProducer.h" +#include "atoms_info.h" #include "condition/CombinationConditionTracker.h" #include "condition/SimpleConditionTracker.h" #include "guardrail/StatsdStats.h" diff --git a/cmds/statsd/src/metrics/metrics_manager_util.cpp b/cmds/statsd/src/metrics/metrics_manager_util.cpp index 5cfb1239d30e..46442b57126c 100644 --- a/cmds/statsd/src/metrics/metrics_manager_util.cpp +++ b/cmds/statsd/src/metrics/metrics_manager_util.cpp @@ -32,8 +32,8 @@ #include "../metrics/GaugeMetricProducer.h" #include "../metrics/ValueMetricProducer.h" +#include "atoms_info.h" #include "stats_util.h" -#include "statslog.h" #include <inttypes.h> diff --git a/cmds/statsd/src/stats_log_util.h b/cmds/statsd/src/stats_log_util.h index bfb84cf4d1b9..a28165d09cdf 100644 --- a/cmds/statsd/src/stats_log_util.h +++ b/cmds/statsd/src/stats_log_util.h @@ -19,9 +19,9 @@ #include <android/util/ProtoOutputStream.h> #include "FieldValue.h" #include "HashableDimensionKey.h" +#include "atoms_info.h" #include "frameworks/base/cmds/statsd/src/statsd_config.pb.h" #include "guardrail/StatsdStats.h" -#include "statslog.h" namespace android { namespace os { diff --git a/cmds/statsd/tests/external/GpuStatsPuller_test.cpp b/cmds/statsd/tests/external/GpuStatsPuller_test.cpp index bdc52b0af34c..32409184b02f 100644 --- a/cmds/statsd/tests/external/GpuStatsPuller_test.cpp +++ b/cmds/statsd/tests/external/GpuStatsPuller_test.cpp @@ -24,6 +24,7 @@ #include <log/log.h> #include "src/external/GpuStatsPuller.h" +#include "statslog.h" #ifdef __ANDROID__ diff --git a/cmds/statsd/tests/external/puller_util_test.cpp b/cmds/statsd/tests/external/puller_util_test.cpp index 266ea351b5d4..673082834e18 100644 --- a/cmds/statsd/tests/external/puller_util_test.cpp +++ b/cmds/statsd/tests/external/puller_util_test.cpp @@ -17,6 +17,7 @@ #include <gtest/gtest.h> #include <stdio.h> #include <vector> +#include "statslog.h" #include "../metrics/metrics_test_helper.h" #ifdef __ANDROID__ diff --git a/config/boot-image-profile.txt b/config/boot-image-profile.txt index 2ac8409f8e1a..773942c8b753 100644 --- a/config/boot-image-profile.txt +++ b/config/boot-image-profile.txt @@ -14142,7 +14142,6 @@ HSPLandroid/telephony/ServiceState;->convertNetworkTypeBitmaskToBearerBitmask(I) HSPLandroid/telephony/ServiceState;->copyFrom(Landroid/telephony/ServiceState;)V HSPLandroid/telephony/ServiceState;->describeContents()I HSPLandroid/telephony/ServiceState;->equals(Ljava/lang/Object;)Z -HSPLandroid/telephony/ServiceState;->fillInNotifierBundle(Landroid/os/Bundle;)V HSPLandroid/telephony/ServiceState;->getCdmaDefaultRoamingIndicator()I HSPLandroid/telephony/ServiceState;->getCdmaEriIconIndex()I HSPLandroid/telephony/ServiceState;->getCdmaEriIconMode()I diff --git a/core/java/android/accessibilityservice/AccessibilityService.java b/core/java/android/accessibilityservice/AccessibilityService.java index 90b80e73c323..842c3ef7dcdc 100644 --- a/core/java/android/accessibilityservice/AccessibilityService.java +++ b/core/java/android/accessibilityservice/AccessibilityService.java @@ -21,8 +21,8 @@ import android.annotation.IntDef; import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.RequiresPermission; -import android.annotation.UnsupportedAppUsage; import android.app.Service; +import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; import android.content.Intent; import android.content.pm.ParceledListSlice; diff --git a/core/java/android/accessibilityservice/AccessibilityServiceInfo.java b/core/java/android/accessibilityservice/AccessibilityServiceInfo.java index cf24b8e1ffa6..8e1ac7623e45 100644 --- a/core/java/android/accessibilityservice/AccessibilityServiceInfo.java +++ b/core/java/android/accessibilityservice/AccessibilityServiceInfo.java @@ -20,7 +20,7 @@ import static android.content.pm.PackageManager.FEATURE_FINGERPRINT; import android.annotation.IntDef; import android.annotation.IntRange; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.ComponentName; import android.content.Context; import android.content.pm.PackageManager; diff --git a/core/java/android/accounts/Account.java b/core/java/android/accounts/Account.java index c822d20445ec..9a18880a353b 100644 --- a/core/java/android/accounts/Account.java +++ b/core/java/android/accounts/Account.java @@ -18,7 +18,7 @@ package android.accounts; import android.annotation.NonNull; import android.annotation.Nullable; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; import android.os.Parcel; import android.os.Parcelable; diff --git a/core/java/android/accounts/AccountAndUser.java b/core/java/android/accounts/AccountAndUser.java index b0d53438d97c..fd6739410ce2 100644 --- a/core/java/android/accounts/AccountAndUser.java +++ b/core/java/android/accounts/AccountAndUser.java @@ -16,7 +16,7 @@ package android.accounts; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; /** * Used to store the Account and the UserId this account is associated with. diff --git a/core/java/android/accounts/AccountAuthenticatorResponse.java b/core/java/android/accounts/AccountAuthenticatorResponse.java index bb2e327a9be8..a2a57990297c 100644 --- a/core/java/android/accounts/AccountAuthenticatorResponse.java +++ b/core/java/android/accounts/AccountAuthenticatorResponse.java @@ -16,10 +16,10 @@ package android.accounts; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.os.Bundle; -import android.os.Parcelable; import android.os.Parcel; +import android.os.Parcelable; import android.os.RemoteException; import android.util.Log; diff --git a/core/java/android/accounts/AccountManager.java b/core/java/android/accounts/AccountManager.java index c80be8e5c3fa..7ecaacae6b09 100644 --- a/core/java/android/accounts/AccountManager.java +++ b/core/java/android/accounts/AccountManager.java @@ -25,8 +25,8 @@ import android.annotation.SdkConstant.SdkConstantType; import android.annotation.Size; import android.annotation.SystemApi; import android.annotation.SystemService; -import android.annotation.UnsupportedAppUsage; import android.app.Activity; +import android.compat.annotation.UnsupportedAppUsage; import android.content.BroadcastReceiver; import android.content.ComponentName; import android.content.Context; diff --git a/core/java/android/accounts/AuthenticatorDescription.java b/core/java/android/accounts/AuthenticatorDescription.java index 555639445e85..b7bf11d4d5b6 100644 --- a/core/java/android/accounts/AuthenticatorDescription.java +++ b/core/java/android/accounts/AuthenticatorDescription.java @@ -16,10 +16,10 @@ package android.accounts; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.os.Build; -import android.os.Parcelable; import android.os.Parcel; +import android.os.Parcelable; /** * A {@link Parcelable} value type that contains information about an account authenticator. diff --git a/core/java/android/animation/Animator.java b/core/java/android/animation/Animator.java index 17d54d2455fe..3cdd691fd5dd 100644 --- a/core/java/android/animation/Animator.java +++ b/core/java/android/animation/Animator.java @@ -17,7 +17,7 @@ package android.animation; import android.annotation.Nullable; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.pm.ActivityInfo.Config; import android.content.res.ConstantState; diff --git a/core/java/android/animation/ArgbEvaluator.java b/core/java/android/animation/ArgbEvaluator.java index 5b69d18a8386..9519ddde86f4 100644 --- a/core/java/android/animation/ArgbEvaluator.java +++ b/core/java/android/animation/ArgbEvaluator.java @@ -16,7 +16,7 @@ package android.animation; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; /** * This evaluator can be used to perform type interpolation between integer diff --git a/core/java/android/animation/LayoutTransition.java b/core/java/android/animation/LayoutTransition.java index c7537102d40c..21f0b6b2ae62 100644 --- a/core/java/android/animation/LayoutTransition.java +++ b/core/java/android/animation/LayoutTransition.java @@ -16,7 +16,7 @@ package android.animation; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.os.Build; import android.view.View; import android.view.ViewGroup; diff --git a/core/java/android/animation/ValueAnimator.java b/core/java/android/animation/ValueAnimator.java index 764e5992fbd9..ca37e9b107a0 100644 --- a/core/java/android/animation/ValueAnimator.java +++ b/core/java/android/animation/ValueAnimator.java @@ -19,7 +19,7 @@ package android.animation; import android.annotation.CallSuper; import android.annotation.IntDef; import android.annotation.TestApi; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.os.Build; import android.os.Looper; import android.os.Trace; diff --git a/core/java/android/app/ActionBar.java b/core/java/android/app/ActionBar.java index e57327991a82..504364c8c1d9 100644 --- a/core/java/android/app/ActionBar.java +++ b/core/java/android/app/ActionBar.java @@ -22,7 +22,7 @@ import android.annotation.LayoutRes; import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.StringRes; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; import android.content.res.Configuration; import android.content.res.TypedArray; diff --git a/core/java/android/app/Activity.java b/core/java/android/app/Activity.java index bf7b2f8b7be4..b6f61a2b8f01 100644 --- a/core/java/android/app/Activity.java +++ b/core/java/android/app/Activity.java @@ -33,10 +33,10 @@ import android.annotation.RequiresPermission; import android.annotation.StyleRes; import android.annotation.SystemApi; import android.annotation.TestApi; -import android.annotation.UnsupportedAppUsage; import android.app.VoiceInteractor.Request; import android.app.admin.DevicePolicyManager; import android.app.assist.AssistContent; +import android.compat.annotation.UnsupportedAppUsage; import android.content.ComponentCallbacks2; import android.content.ComponentName; import android.content.ContentResolver; diff --git a/core/java/android/app/ActivityGroup.java b/core/java/android/app/ActivityGroup.java index d4aa01b8f43e..cb06eea2059e 100644 --- a/core/java/android/app/ActivityGroup.java +++ b/core/java/android/app/ActivityGroup.java @@ -16,7 +16,7 @@ package android.app; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.Intent; import android.os.Bundle; diff --git a/core/java/android/app/ActivityManager.java b/core/java/android/app/ActivityManager.java index e8e4085f731d..726a6195efc5 100644 --- a/core/java/android/app/ActivityManager.java +++ b/core/java/android/app/ActivityManager.java @@ -27,7 +27,7 @@ import android.annotation.RequiresPermission; import android.annotation.SystemApi; import android.annotation.SystemService; import android.annotation.TestApi; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.ComponentName; import android.content.Context; import android.content.Intent; diff --git a/core/java/android/app/ActivityManagerNative.java b/core/java/android/app/ActivityManagerNative.java index 607ef185ae60..b9eb95739aa1 100644 --- a/core/java/android/app/ActivityManagerNative.java +++ b/core/java/android/app/ActivityManagerNative.java @@ -15,7 +15,7 @@ */ package android.app; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.Intent; import android.os.IBinder; diff --git a/core/java/android/app/ActivityOptions.java b/core/java/android/app/ActivityOptions.java index 926044bffdd0..10bee4013de0 100644 --- a/core/java/android/app/ActivityOptions.java +++ b/core/java/android/app/ActivityOptions.java @@ -25,7 +25,7 @@ import static android.view.Display.INVALID_DISPLAY; import android.annotation.Nullable; import android.annotation.RequiresPermission; import android.annotation.TestApi; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.ComponentName; import android.content.Context; import android.content.Intent; diff --git a/core/java/android/app/ActivityTaskManager.java b/core/java/android/app/ActivityTaskManager.java index 4ef554dc64cc..28d4c7f8a448 100644 --- a/core/java/android/app/ActivityTaskManager.java +++ b/core/java/android/app/ActivityTaskManager.java @@ -19,7 +19,7 @@ package android.app; import android.annotation.RequiresPermission; import android.annotation.SystemService; import android.annotation.TestApi; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; import android.content.pm.PackageManager; import android.content.res.Resources; diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java index 4e8bee24052e..c4281f0b8d28 100644 --- a/core/java/android/app/ActivityThread.java +++ b/core/java/android/app/ActivityThread.java @@ -32,7 +32,6 @@ import static com.android.internal.annotations.VisibleForTesting.Visibility.PACK import android.annotation.NonNull; import android.annotation.Nullable; -import android.annotation.UnsupportedAppUsage; import android.app.assist.AssistContent; import android.app.assist.AssistStructure; import android.app.backup.BackupAgent; @@ -46,6 +45,7 @@ import android.app.servertransaction.PendingTransactionActions; import android.app.servertransaction.PendingTransactionActions.StopInfo; import android.app.servertransaction.TransactionExecutor; import android.app.servertransaction.TransactionExecutorHelper; +import android.compat.annotation.UnsupportedAppUsage; import android.content.AutofillOptions; import android.content.BroadcastReceiver; import android.content.ComponentCallbacks2; diff --git a/core/java/android/app/AlarmManager.java b/core/java/android/app/AlarmManager.java index 3a34b7926611..a0040ffd13fa 100644 --- a/core/java/android/app/AlarmManager.java +++ b/core/java/android/app/AlarmManager.java @@ -21,7 +21,7 @@ import android.annotation.RequiresPermission; import android.annotation.SdkConstant; import android.annotation.SystemApi; import android.annotation.SystemService; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; import android.content.Intent; import android.os.Build; diff --git a/core/java/android/app/AlertDialog.java b/core/java/android/app/AlertDialog.java index bfc216a24c1b..4c347373d642 100644 --- a/core/java/android/app/AlertDialog.java +++ b/core/java/android/app/AlertDialog.java @@ -21,7 +21,7 @@ import android.annotation.AttrRes; import android.annotation.DrawableRes; import android.annotation.StringRes; import android.annotation.StyleRes; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; import android.content.DialogInterface; import android.content.res.ResourceId; diff --git a/core/java/android/app/AppGlobals.java b/core/java/android/app/AppGlobals.java index 1f737b60964c..552d6e9334e2 100644 --- a/core/java/android/app/AppGlobals.java +++ b/core/java/android/app/AppGlobals.java @@ -16,7 +16,7 @@ package android.app; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.pm.IPackageManager; /** diff --git a/core/java/android/app/AppOpsManager.java b/core/java/android/app/AppOpsManager.java index 33d83f9b123b..7d3cd28c22d6 100644 --- a/core/java/android/app/AppOpsManager.java +++ b/core/java/android/app/AppOpsManager.java @@ -25,8 +25,8 @@ import android.annotation.RequiresPermission; import android.annotation.SystemApi; import android.annotation.SystemService; import android.annotation.TestApi; -import android.annotation.UnsupportedAppUsage; import android.app.usage.UsageStatsManager; +import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; import android.content.pm.PackageManager; import android.content.pm.ParceledListSlice; diff --git a/core/java/android/app/AppOpsManagerInternal.java b/core/java/android/app/AppOpsManagerInternal.java index 08cad04401e9..996939eb9ee1 100644 --- a/core/java/android/app/AppOpsManagerInternal.java +++ b/core/java/android/app/AppOpsManagerInternal.java @@ -16,7 +16,6 @@ package android.app; -import android.annotation.NonNull; import android.util.SparseIntArray; import com.android.internal.util.function.QuadFunction; @@ -77,38 +76,10 @@ public abstract class AppOpsManagerInternal { public abstract void setDeviceAndProfileOwners(SparseIntArray owners); /** - * Sets the app-ops mode for a certain app-op and uid. - * - * <p>Similar as {@link AppOpsManager#setUidMode} but does not require the package manager to be - * working. Hence this can be used very early during boot. - * - * <p>Only for internal callers. Does <u>not</u> verify that package name belongs to uid. - * - * @param code The op code to set. - * @param uid The UID for which to set. - * @param mode The new mode to set. - */ - public abstract void setUidMode(int code, int uid, int mode); - - /** * Set all {@link #setMode (package) modes} for this uid to the default value. * * @param code The app-op * @param uid The uid */ public abstract void setAllPkgModesToDefault(int code, int uid); - - /** - * Get the (raw) mode of an app-op. - * - * <p>Does <u>not</u> verify that package belongs to uid. The caller needs to do that. - * - * @param code The code of the op - * @param uid The uid of the package the op belongs to - * @param packageName The package the op belongs to - * - * @return The mode of the op - */ - public abstract @AppOpsManager.Mode int checkOperationUnchecked(int code, int uid, - @NonNull String packageName); } diff --git a/core/java/android/app/Application.java b/core/java/android/app/Application.java index e12942f248d4..941467fad736 100644 --- a/core/java/android/app/Application.java +++ b/core/java/android/app/Application.java @@ -19,7 +19,7 @@ package android.app; import android.annotation.CallSuper; import android.annotation.NonNull; import android.annotation.Nullable; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.ComponentCallbacks; import android.content.ComponentCallbacks2; import android.content.Context; diff --git a/core/java/android/app/ApplicationLoaders.java b/core/java/android/app/ApplicationLoaders.java index 2e59b903f06d..bac432e42318 100644 --- a/core/java/android/app/ApplicationLoaders.java +++ b/core/java/android/app/ApplicationLoaders.java @@ -16,7 +16,7 @@ package android.app; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.pm.SharedLibraryInfo; import android.os.Build; import android.os.GraphicsEnvironment; diff --git a/core/java/android/app/ApplicationPackageManager.java b/core/java/android/app/ApplicationPackageManager.java index 835769f69951..1158c44e63c0 100644 --- a/core/java/android/app/ApplicationPackageManager.java +++ b/core/java/android/app/ApplicationPackageManager.java @@ -20,9 +20,9 @@ import android.annotation.DrawableRes; import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.StringRes; -import android.annotation.UnsupportedAppUsage; import android.annotation.UserIdInt; import android.annotation.XmlRes; +import android.compat.annotation.UnsupportedAppUsage; import android.content.ComponentName; import android.content.ContentResolver; import android.content.Context; diff --git a/core/java/android/app/ContentProviderHolder.java b/core/java/android/app/ContentProviderHolder.java index 004dca1a708f..3d745831ce1c 100644 --- a/core/java/android/app/ContentProviderHolder.java +++ b/core/java/android/app/ContentProviderHolder.java @@ -16,7 +16,7 @@ package android.app; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.ContentProviderNative; import android.content.IContentProvider; import android.content.pm.ProviderInfo; diff --git a/core/java/android/app/ContextImpl.java b/core/java/android/app/ContextImpl.java index d317c34c6518..ce4d312318d4 100644 --- a/core/java/android/app/ContextImpl.java +++ b/core/java/android/app/ContextImpl.java @@ -20,7 +20,7 @@ import android.annotation.IntDef; import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.TestApi; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.AutofillOptions; import android.content.BroadcastReceiver; import android.content.ComponentName; diff --git a/core/java/android/app/DatePickerDialog.java b/core/java/android/app/DatePickerDialog.java index 9d82ffa838ca..195c3e1c296a 100644 --- a/core/java/android/app/DatePickerDialog.java +++ b/core/java/android/app/DatePickerDialog.java @@ -19,7 +19,7 @@ package android.app; import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.StyleRes; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; import android.content.DialogInterface; import android.content.DialogInterface.OnClickListener; diff --git a/core/java/android/app/Dialog.java b/core/java/android/app/Dialog.java index 088c245c9c2c..10525f7afc54 100644 --- a/core/java/android/app/Dialog.java +++ b/core/java/android/app/Dialog.java @@ -24,7 +24,7 @@ import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.StringRes; import android.annotation.StyleRes; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.ComponentName; import android.content.Context; import android.content.ContextWrapper; diff --git a/core/java/android/app/DialogFragment.java b/core/java/android/app/DialogFragment.java index bfc15c221702..e4c84d7e7997 100644 --- a/core/java/android/app/DialogFragment.java +++ b/core/java/android/app/DialogFragment.java @@ -16,7 +16,7 @@ package android.app; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; import android.content.DialogInterface; import android.os.Bundle; diff --git a/core/java/android/app/DownloadManager.java b/core/java/android/app/DownloadManager.java index 77a777024a21..bcc08e9a96fb 100644 --- a/core/java/android/app/DownloadManager.java +++ b/core/java/android/app/DownloadManager.java @@ -22,7 +22,7 @@ import android.annotation.SdkConstant.SdkConstantType; import android.annotation.SystemApi; import android.annotation.SystemService; import android.annotation.TestApi; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.ContentProviderClient; import android.content.ContentResolver; import android.content.ContentUris; diff --git a/core/java/android/app/Fragment.java b/core/java/android/app/Fragment.java index 4f121aa35f7c..c6a0de458df0 100644 --- a/core/java/android/app/Fragment.java +++ b/core/java/android/app/Fragment.java @@ -21,7 +21,7 @@ import android.annotation.CallSuper; import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.StringRes; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.ComponentCallbacks2; import android.content.Context; import android.content.Intent; diff --git a/core/java/android/app/FragmentController.java b/core/java/android/app/FragmentController.java index 9316be7a7968..f021f7690283 100644 --- a/core/java/android/app/FragmentController.java +++ b/core/java/android/app/FragmentController.java @@ -17,7 +17,7 @@ package android.app; import android.annotation.Nullable; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; import android.content.res.Configuration; import android.os.Bundle; diff --git a/core/java/android/app/FragmentHostCallback.java b/core/java/android/app/FragmentHostCallback.java index 26b4a11f4c10..9e887b88c407 100644 --- a/core/java/android/app/FragmentHostCallback.java +++ b/core/java/android/app/FragmentHostCallback.java @@ -18,7 +18,7 @@ package android.app; import android.annotation.NonNull; import android.annotation.Nullable; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; import android.content.Intent; import android.content.IntentSender; diff --git a/core/java/android/app/FragmentManager.java b/core/java/android/app/FragmentManager.java index 68daf44b19a5..904c4735e0ff 100644 --- a/core/java/android/app/FragmentManager.java +++ b/core/java/android/app/FragmentManager.java @@ -22,7 +22,7 @@ import android.animation.AnimatorListenerAdapter; import android.animation.AnimatorSet; import android.animation.PropertyValuesHolder; import android.animation.ValueAnimator; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; import android.content.pm.ApplicationInfo; import android.content.res.Configuration; diff --git a/core/java/android/app/Instrumentation.java b/core/java/android/app/Instrumentation.java index 9720e9f47f83..cff6411c882c 100644 --- a/core/java/android/app/Instrumentation.java +++ b/core/java/android/app/Instrumentation.java @@ -19,7 +19,7 @@ package android.app; import android.annotation.IntDef; import android.annotation.NonNull; import android.annotation.Nullable; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.ActivityNotFoundException; import android.content.ComponentName; import android.content.Context; diff --git a/core/java/android/app/IntentService.java b/core/java/android/app/IntentService.java index 74fb99a0909f..71b28fba6019 100644 --- a/core/java/android/app/IntentService.java +++ b/core/java/android/app/IntentService.java @@ -16,9 +16,9 @@ package android.app; -import android.annotation.UnsupportedAppUsage; -import android.annotation.WorkerThread; import android.annotation.Nullable; +import android.annotation.WorkerThread; +import android.compat.annotation.UnsupportedAppUsage; import android.content.Intent; import android.os.Handler; import android.os.HandlerThread; diff --git a/core/java/android/app/KeyguardManager.java b/core/java/android/app/KeyguardManager.java index 667758755c99..376acfaa6d90 100644 --- a/core/java/android/app/KeyguardManager.java +++ b/core/java/android/app/KeyguardManager.java @@ -23,8 +23,8 @@ import android.annotation.RequiresFeature; import android.annotation.RequiresPermission; import android.annotation.SystemApi; import android.annotation.SystemService; -import android.annotation.UnsupportedAppUsage; import android.app.trust.ITrustManager; +import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; import android.content.Intent; import android.content.pm.PackageManager; diff --git a/core/java/android/app/LoadedApk.java b/core/java/android/app/LoadedApk.java index 4efaaad91eb6..2a72d43eccad 100644 --- a/core/java/android/app/LoadedApk.java +++ b/core/java/android/app/LoadedApk.java @@ -18,7 +18,7 @@ package android.app; import android.annotation.NonNull; import android.annotation.Nullable; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.BroadcastReceiver; import android.content.ComponentName; import android.content.Context; diff --git a/core/java/android/app/LocalActivityManager.java b/core/java/android/app/LocalActivityManager.java index 19575b2b36ba..1d27f8fb6dbc 100644 --- a/core/java/android/app/LocalActivityManager.java +++ b/core/java/android/app/LocalActivityManager.java @@ -16,9 +16,9 @@ package android.app; -import android.annotation.UnsupportedAppUsage; import android.app.ActivityThread.ActivityClientRecord; import android.app.servertransaction.PendingTransactionActions; +import android.compat.annotation.UnsupportedAppUsage; import android.content.Intent; import android.content.pm.ActivityInfo; import android.os.Binder; diff --git a/core/java/android/app/NativeActivity.java b/core/java/android/app/NativeActivity.java index 25eb958b61e3..74bc9e215106 100644 --- a/core/java/android/app/NativeActivity.java +++ b/core/java/android/app/NativeActivity.java @@ -16,7 +16,7 @@ package android.app; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; import android.content.pm.ActivityInfo; import android.content.pm.PackageManager; diff --git a/core/java/android/app/Notification.java b/core/java/android/app/Notification.java index 412ef04c2284..cefec441e702 100644 --- a/core/java/android/app/Notification.java +++ b/core/java/android/app/Notification.java @@ -33,7 +33,7 @@ import android.annotation.RequiresPermission; import android.annotation.SdkConstant; import android.annotation.SdkConstant.SdkConstantType; import android.annotation.SystemApi; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; import android.content.Intent; import android.content.LocusId; diff --git a/core/java/android/app/NotificationChannel.java b/core/java/android/app/NotificationChannel.java index 69ec831b5d1d..b1d791b58a79 100644 --- a/core/java/android/app/NotificationChannel.java +++ b/core/java/android/app/NotificationChannel.java @@ -15,13 +15,11 @@ */ package android.app; -import static android.app.NotificationManager.IMPORTANCE_HIGH; - import android.annotation.Nullable; import android.annotation.SystemApi; import android.annotation.TestApi; -import android.annotation.UnsupportedAppUsage; import android.app.NotificationManager.Importance; +import android.compat.annotation.UnsupportedAppUsage; import android.content.ContentResolver; import android.content.Context; import android.content.Intent; diff --git a/core/java/android/app/NotificationChannelGroup.java b/core/java/android/app/NotificationChannelGroup.java index a8ee414cac0a..afbd0b5afe1c 100644 --- a/core/java/android/app/NotificationChannelGroup.java +++ b/core/java/android/app/NotificationChannelGroup.java @@ -17,7 +17,7 @@ package android.app; import android.annotation.SystemApi; import android.annotation.TestApi; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.Intent; import android.os.Parcel; import android.os.Parcelable; diff --git a/core/java/android/app/NotificationManager.java b/core/java/android/app/NotificationManager.java index c6aa4fd86594..e25558f16f26 100644 --- a/core/java/android/app/NotificationManager.java +++ b/core/java/android/app/NotificationManager.java @@ -23,8 +23,8 @@ import android.annotation.SdkConstant; import android.annotation.SystemApi; import android.annotation.SystemService; import android.annotation.TestApi; -import android.annotation.UnsupportedAppUsage; import android.app.Notification.Builder; +import android.compat.annotation.UnsupportedAppUsage; import android.content.ComponentName; import android.content.Context; import android.content.Intent; diff --git a/core/java/android/app/PackageDeleteObserver.java b/core/java/android/app/PackageDeleteObserver.java index b7b0b192e7ae..d8803aa13e42 100644 --- a/core/java/android/app/PackageDeleteObserver.java +++ b/core/java/android/app/PackageDeleteObserver.java @@ -16,7 +16,7 @@ package android.app; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.Intent; import android.content.pm.IPackageDeleteObserver2; diff --git a/core/java/android/app/PackageInstallObserver.java b/core/java/android/app/PackageInstallObserver.java index 50031e0e4d35..0820367db1f8 100644 --- a/core/java/android/app/PackageInstallObserver.java +++ b/core/java/android/app/PackageInstallObserver.java @@ -16,7 +16,7 @@ package android.app; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.Intent; import android.content.pm.IPackageInstallObserver2; import android.os.Bundle; diff --git a/core/java/android/app/PendingIntent.java b/core/java/android/app/PendingIntent.java index 6f7a0607cbdb..6acbf21e5602 100644 --- a/core/java/android/app/PendingIntent.java +++ b/core/java/android/app/PendingIntent.java @@ -19,7 +19,7 @@ package android.app; import android.annotation.IntDef; import android.annotation.NonNull; import android.annotation.Nullable; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; import android.content.IIntentReceiver; import android.content.IIntentSender; diff --git a/core/java/android/app/PictureInPictureArgs.java b/core/java/android/app/PictureInPictureArgs.java index 3ee51739e455..9d49d107c99e 100644 --- a/core/java/android/app/PictureInPictureArgs.java +++ b/core/java/android/app/PictureInPictureArgs.java @@ -17,7 +17,7 @@ package android.app; import android.annotation.Nullable; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.graphics.Rect; import android.os.Parcel; import android.os.Parcelable; diff --git a/core/java/android/app/Presentation.java b/core/java/android/app/Presentation.java index cb72d4d5dc2c..f864fb57d00a 100644 --- a/core/java/android/app/Presentation.java +++ b/core/java/android/app/Presentation.java @@ -20,24 +20,24 @@ import static android.content.Context.DISPLAY_SERVICE; import static android.content.Context.WINDOW_SERVICE; import static android.view.WindowManager.LayoutParams.TYPE_PRESENTATION; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; import android.content.res.Resources; import android.hardware.display.DisplayManager; import android.hardware.display.DisplayManager.DisplayListener; import android.os.Binder; +import android.os.Handler; import android.os.IBinder; +import android.os.Message; +import android.util.DisplayMetrics; +import android.util.Log; +import android.util.TypedValue; import android.view.ContextThemeWrapper; import android.view.Display; import android.view.Gravity; import android.view.Window; import android.view.WindowManager; import android.view.WindowManagerImpl; -import android.os.Handler; -import android.os.Message; -import android.util.DisplayMetrics; -import android.util.Log; -import android.util.TypedValue; /** * Base class for presentations. diff --git a/core/java/android/app/ProgressDialog.java b/core/java/android/app/ProgressDialog.java index 3193eb89ac80..432fae5e9033 100644 --- a/core/java/android/app/ProgressDialog.java +++ b/core/java/android/app/ProgressDialog.java @@ -16,9 +16,7 @@ package android.app; -import com.android.internal.R; - -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; import android.content.res.TypedArray; import android.graphics.drawable.Drawable; @@ -34,6 +32,8 @@ import android.view.View; import android.widget.ProgressBar; import android.widget.TextView; +import com.android.internal.R; + import java.text.NumberFormat; /** diff --git a/core/java/android/app/QueuedWork.java b/core/java/android/app/QueuedWork.java index 76265390fe1a..82cc2c4daa0b 100644 --- a/core/java/android/app/QueuedWork.java +++ b/core/java/android/app/QueuedWork.java @@ -16,7 +16,7 @@ package android.app; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.os.Handler; import android.os.HandlerThread; import android.os.Looper; diff --git a/core/java/android/app/ResourcesManager.java b/core/java/android/app/ResourcesManager.java index e9ae60f23cf2..7d742f7e11eb 100644 --- a/core/java/android/app/ResourcesManager.java +++ b/core/java/android/app/ResourcesManager.java @@ -20,7 +20,7 @@ import static android.app.ActivityThread.DEBUG_CONFIGURATION; import android.annotation.NonNull; import android.annotation.Nullable; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.pm.ActivityInfo; import android.content.pm.ApplicationInfo; import android.content.res.ApkAssets; diff --git a/core/java/android/app/ResultInfo.java b/core/java/android/app/ResultInfo.java index 9ee0f3126432..979d3dbf36a7 100644 --- a/core/java/android/app/ResultInfo.java +++ b/core/java/android/app/ResultInfo.java @@ -16,7 +16,7 @@ package android.app; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.Intent; import android.os.Build; import android.os.Parcel; diff --git a/core/java/android/app/SearchDialog.java b/core/java/android/app/SearchDialog.java index 8493fb25b8a5..9fe894b75455 100644 --- a/core/java/android/app/SearchDialog.java +++ b/core/java/android/app/SearchDialog.java @@ -17,7 +17,7 @@ package android.app; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.BroadcastReceiver; import android.content.ComponentName; import android.content.Context; diff --git a/core/java/android/app/SearchManager.java b/core/java/android/app/SearchManager.java index acca6fc177b8..93107ad4bfcb 100644 --- a/core/java/android/app/SearchManager.java +++ b/core/java/android/app/SearchManager.java @@ -17,7 +17,7 @@ package android.app; import android.annotation.SystemService; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.ActivityNotFoundException; import android.content.ComponentName; import android.content.ContentResolver; diff --git a/core/java/android/app/SearchableInfo.java b/core/java/android/app/SearchableInfo.java index a01cec7aa944..83eb2ee1da14 100644 --- a/core/java/android/app/SearchableInfo.java +++ b/core/java/android/app/SearchableInfo.java @@ -16,17 +16,14 @@ package android.app; -import org.xmlpull.v1.XmlPullParser; -import org.xmlpull.v1.XmlPullParserException; - import android.annotation.StringRes; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.ComponentName; import android.content.Context; import android.content.pm.ActivityInfo; import android.content.pm.PackageManager; -import android.content.pm.ProviderInfo; import android.content.pm.PackageManager.NameNotFoundException; +import android.content.pm.ProviderInfo; import android.content.res.TypedArray; import android.content.res.XmlResourceParser; import android.os.Parcel; @@ -38,6 +35,9 @@ import android.util.Log; import android.util.Xml; import android.view.inputmethod.EditorInfo; +import org.xmlpull.v1.XmlPullParser; +import org.xmlpull.v1.XmlPullParserException; + import java.io.IOException; import java.util.HashMap; diff --git a/core/java/android/app/Service.java b/core/java/android/app/Service.java index 9b62e3b3af98..dc8269f900b7 100644 --- a/core/java/android/app/Service.java +++ b/core/java/android/app/Service.java @@ -21,7 +21,7 @@ import static android.content.pm.ServiceInfo.FOREGROUND_SERVICE_TYPE_MANIFEST; import android.annotation.IntDef; import android.annotation.NonNull; import android.annotation.Nullable; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.ComponentCallbacks2; import android.content.ComponentName; import android.content.Context; diff --git a/core/java/android/app/SharedPreferencesImpl.java b/core/java/android/app/SharedPreferencesImpl.java index 0f8976fe924a..3783d1c52ab1 100644 --- a/core/java/android/app/SharedPreferencesImpl.java +++ b/core/java/android/app/SharedPreferencesImpl.java @@ -17,7 +17,7 @@ package android.app; import android.annotation.Nullable; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.SharedPreferences; import android.os.FileUtils; import android.os.Looper; diff --git a/core/java/android/app/StatusBarManager.java b/core/java/android/app/StatusBarManager.java index 28413be29a1d..078e4538c66b 100644 --- a/core/java/android/app/StatusBarManager.java +++ b/core/java/android/app/StatusBarManager.java @@ -23,7 +23,7 @@ import android.annotation.RequiresPermission; import android.annotation.SystemApi; import android.annotation.SystemService; import android.annotation.TestApi; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; import android.os.Binder; import android.os.IBinder; @@ -153,6 +153,11 @@ public class StatusBarManager { */ public static final int DEFAULT_SETUP_DISABLE2_FLAGS = DISABLE2_ROTATE_SUGGESTIONS; + /** + * disable flags to be applied when the device is sim-locked. + */ + private static final int DEFAULT_SIM_LOCKED_DISABLED_FLAGS = DISABLE_EXPAND; + /** @hide */ public static final int NAVIGATION_HINT_BACK_ALT = 1 << 0; /** @hide */ @@ -385,6 +390,30 @@ public class StatusBarManager { } /** + * Enable or disable expansion of the status bar. When the device is SIM-locked, the status + * bar should not be expandable. + * + * @param disabled If {@code true}, the status bar will be set to non-expandable. If + * {@code false}, re-enables expansion of the status bar. + * @hide + */ + @SystemApi + @TestApi + @RequiresPermission(android.Manifest.permission.STATUS_BAR) + public void setDisabledForSimNetworkLock(boolean disabled) { + try { + final int userId = Binder.getCallingUserHandle().getIdentifier(); + final IStatusBarService svc = getService(); + if (svc != null) { + svc.disableForUser(disabled ? DEFAULT_SIM_LOCKED_DISABLED_FLAGS : DISABLE_NONE, + mToken, mContext.getPackageName(), userId); + } + } catch (RemoteException ex) { + throw ex.rethrowFromSystemServer(); + } + } + + /** * Get this app's currently requested disabled components * * @return a new DisableInfo diff --git a/core/java/android/app/SystemServiceRegistry.java b/core/java/android/app/SystemServiceRegistry.java index 82df702eb7e5..88976e182e6d 100644 --- a/core/java/android/app/SystemServiceRegistry.java +++ b/core/java/android/app/SystemServiceRegistry.java @@ -341,6 +341,14 @@ final class SystemServiceRegistry { } }); + registerService(Context.NETWORK_STACK_SERVICE, IBinder.class, + new StaticServiceFetcher<IBinder>() { + @Override + public IBinder createService() { + return ServiceManager.getService(Context.NETWORK_STACK_SERVICE); + } + }); + registerService(Context.TETHERING_SERVICE, TetheringManager.class, new CachedServiceFetcher<TetheringManager>() { @Override diff --git a/core/java/android/app/TaskInfo.java b/core/java/android/app/TaskInfo.java index de64db9def64..fe9c64038909 100644 --- a/core/java/android/app/TaskInfo.java +++ b/core/java/android/app/TaskInfo.java @@ -18,7 +18,7 @@ package android.app; import android.annotation.NonNull; import android.annotation.Nullable; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.ComponentName; import android.content.Intent; import android.content.res.Configuration; diff --git a/core/java/android/app/TaskStackListener.java b/core/java/android/app/TaskStackListener.java index 50130400deab..6247187bbfab 100644 --- a/core/java/android/app/TaskStackListener.java +++ b/core/java/android/app/TaskStackListener.java @@ -16,8 +16,8 @@ package android.app; -import android.annotation.UnsupportedAppUsage; import android.app.ActivityManager.TaskSnapshot; +import android.compat.annotation.UnsupportedAppUsage; import android.content.ComponentName; import android.os.Binder; import android.os.IBinder; diff --git a/core/java/android/app/TimePickerDialog.java b/core/java/android/app/TimePickerDialog.java index 1b281d521957..c529297b14db 100644 --- a/core/java/android/app/TimePickerDialog.java +++ b/core/java/android/app/TimePickerDialog.java @@ -17,7 +17,7 @@ package android.app; import android.annotation.TestApi; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; import android.content.DialogInterface; import android.content.DialogInterface.OnClickListener; diff --git a/core/java/android/app/UiAutomation.java b/core/java/android/app/UiAutomation.java index 3935628b707f..20e31cab4b00 100644 --- a/core/java/android/app/UiAutomation.java +++ b/core/java/android/app/UiAutomation.java @@ -24,7 +24,7 @@ import android.accessibilityservice.IAccessibilityServiceConnection; import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.TestApi; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.graphics.Bitmap; import android.graphics.Point; import android.graphics.Rect; diff --git a/core/java/android/app/UiAutomationConnection.java b/core/java/android/app/UiAutomationConnection.java index f251b3eb4a15..5f89e5c2a9b0 100644 --- a/core/java/android/app/UiAutomationConnection.java +++ b/core/java/android/app/UiAutomationConnection.java @@ -19,6 +19,7 @@ package android.app; import android.accessibilityservice.AccessibilityServiceInfo; import android.accessibilityservice.IAccessibilityServiceClient; import android.annotation.Nullable; +import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; import android.content.pm.IPackageManager; import android.graphics.Bitmap; @@ -40,8 +41,6 @@ import android.view.WindowContentFrameStats; import android.view.accessibility.AccessibilityEvent; import android.view.accessibility.IAccessibilityManager; -import dalvik.annotation.compat.UnsupportedAppUsage; - import libcore.io.IoUtils; import java.io.FileInputStream; diff --git a/core/java/android/app/UiModeManager.java b/core/java/android/app/UiModeManager.java index 83247875c8a5..6582d240554b 100644 --- a/core/java/android/app/UiModeManager.java +++ b/core/java/android/app/UiModeManager.java @@ -23,7 +23,7 @@ import android.annotation.RequiresPermission; import android.annotation.SystemApi; import android.annotation.SystemService; import android.annotation.TestApi; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; import android.content.res.Configuration; import android.os.RemoteException; diff --git a/core/java/android/app/UserSwitchObserver.java b/core/java/android/app/UserSwitchObserver.java index 2f8ee744bfd6..6abc4f09ba38 100644 --- a/core/java/android/app/UserSwitchObserver.java +++ b/core/java/android/app/UserSwitchObserver.java @@ -16,7 +16,7 @@ package android.app; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.os.IRemoteCallback; import android.os.RemoteException; diff --git a/core/java/android/app/VrManager.java b/core/java/android/app/VrManager.java index c74f8c389c20..08a210b069b9 100644 --- a/core/java/android/app/VrManager.java +++ b/core/java/android/app/VrManager.java @@ -6,7 +6,7 @@ import android.annotation.Nullable; import android.annotation.RequiresPermission; import android.annotation.SystemApi; import android.annotation.SystemService; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.ComponentName; import android.content.Context; import android.os.RemoteException; diff --git a/core/java/android/app/WallpaperManager.java b/core/java/android/app/WallpaperManager.java index 325a54bffbfb..102de950a129 100644 --- a/core/java/android/app/WallpaperManager.java +++ b/core/java/android/app/WallpaperManager.java @@ -26,7 +26,7 @@ import android.annotation.SdkConstant.SdkConstantType; import android.annotation.SystemApi; import android.annotation.SystemService; import android.annotation.TestApi; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.ComponentName; import android.content.ContentResolver; import android.content.Context; diff --git a/core/java/android/app/WindowConfiguration.java b/core/java/android/app/WindowConfiguration.java index 74237b4bfcb1..f4240b1c8a46 100644 --- a/core/java/android/app/WindowConfiguration.java +++ b/core/java/android/app/WindowConfiguration.java @@ -26,6 +26,7 @@ import static android.view.Surface.rotationToString; import android.annotation.IntDef; import android.annotation.NonNull; import android.annotation.TestApi; +import android.compat.annotation.UnsupportedAppUsage; import android.content.res.Configuration; import android.graphics.Rect; import android.os.Parcel; @@ -35,8 +36,6 @@ import android.util.proto.ProtoOutputStream; import android.util.proto.WireTypeMismatchException; import android.view.DisplayInfo; -import dalvik.annotation.compat.UnsupportedAppUsage; - import java.io.IOException; /** diff --git a/core/java/android/app/admin/DeviceAdminInfo.java b/core/java/android/app/admin/DeviceAdminInfo.java index 00903c43b291..3cc7f1e5df42 100644 --- a/core/java/android/app/admin/DeviceAdminInfo.java +++ b/core/java/android/app/admin/DeviceAdminInfo.java @@ -17,7 +17,7 @@ package android.app.admin; import android.annotation.NonNull; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.ComponentName; import android.content.Context; import android.content.pm.ActivityInfo; diff --git a/core/java/android/app/admin/DevicePolicyManager.java b/core/java/android/app/admin/DevicePolicyManager.java index a17b2ddd7215..79a2c9010f35 100644 --- a/core/java/android/app/admin/DevicePolicyManager.java +++ b/core/java/android/app/admin/DevicePolicyManager.java @@ -33,13 +33,13 @@ import android.annotation.SuppressLint; import android.annotation.SystemApi; import android.annotation.SystemService; import android.annotation.TestApi; -import android.annotation.UnsupportedAppUsage; import android.annotation.UserIdInt; import android.annotation.WorkerThread; import android.app.Activity; import android.app.IServiceConnection; import android.app.KeyguardManager; import android.app.admin.SecurityLog.SecurityEvent; +import android.compat.annotation.UnsupportedAppUsage; import android.content.ComponentName; import android.content.Context; import android.content.Intent; @@ -6993,7 +6993,9 @@ public class DevicePolicyManager { * @param userHandle The user for whom to check the caller-id permission * @hide */ - public boolean getBluetoothContactSharingDisabled(UserHandle userHandle) { + @SystemApi + @RequiresPermission(permission.INTERACT_ACROSS_USERS) + public boolean getBluetoothContactSharingDisabled(@NonNull UserHandle userHandle) { if (mService != null) { try { return mService.getBluetoothContactSharingDisabledForUser(userHandle diff --git a/core/java/android/app/admin/SecurityLog.java b/core/java/android/app/admin/SecurityLog.java index 972762152d3a..f0b87a8e2561 100644 --- a/core/java/android/app/admin/SecurityLog.java +++ b/core/java/android/app/admin/SecurityLog.java @@ -18,7 +18,7 @@ package android.app.admin; import android.annotation.IntDef; import android.annotation.TestApi; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.ComponentName; import android.os.Parcel; import android.os.Parcelable; diff --git a/core/java/android/app/assist/AssistContent.java b/core/java/android/app/assist/AssistContent.java index db6ae4f2260a..e5316bc05749 100644 --- a/core/java/android/app/assist/AssistContent.java +++ b/core/java/android/app/assist/AssistContent.java @@ -1,6 +1,6 @@ package android.app.assist; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.ClipData; import android.content.Intent; import android.net.Uri; diff --git a/core/java/android/app/backup/BackupDataInput.java b/core/java/android/app/backup/BackupDataInput.java index 2a98ca715a26..d1383c8d0a6a 100644 --- a/core/java/android/app/backup/BackupDataInput.java +++ b/core/java/android/app/backup/BackupDataInput.java @@ -17,7 +17,7 @@ package android.app.backup; import android.annotation.SystemApi; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import java.io.FileDescriptor; import java.io.IOException; diff --git a/core/java/android/app/backup/BackupDataInputStream.java b/core/java/android/app/backup/BackupDataInputStream.java index 08880665d921..11a3d0c3d725 100644 --- a/core/java/android/app/backup/BackupDataInputStream.java +++ b/core/java/android/app/backup/BackupDataInputStream.java @@ -16,9 +16,10 @@ package android.app.backup; -import android.annotation.UnsupportedAppUsage; -import java.io.InputStream; +import android.compat.annotation.UnsupportedAppUsage; + import java.io.IOException; +import java.io.InputStream; /** * Provides an {@link java.io.InputStream}-like interface for accessing an diff --git a/core/java/android/app/backup/BackupDataOutput.java b/core/java/android/app/backup/BackupDataOutput.java index 01961e78777f..fb161d41acd2 100644 --- a/core/java/android/app/backup/BackupDataOutput.java +++ b/core/java/android/app/backup/BackupDataOutput.java @@ -17,7 +17,7 @@ package android.app.backup; import android.annotation.SystemApi; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.os.ParcelFileDescriptor; import java.io.FileDescriptor; diff --git a/core/java/android/app/backup/BackupHelperDispatcher.java b/core/java/android/app/backup/BackupHelperDispatcher.java index e9acdbfb61b9..6faa887206c1 100644 --- a/core/java/android/app/backup/BackupHelperDispatcher.java +++ b/core/java/android/app/backup/BackupHelperDispatcher.java @@ -16,7 +16,7 @@ package android.app.backup; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.os.ParcelFileDescriptor; import android.util.Log; diff --git a/core/java/android/app/backup/BackupManager.java b/core/java/android/app/backup/BackupManager.java index 25caaaa6e5ad..dc815b631e46 100644 --- a/core/java/android/app/backup/BackupManager.java +++ b/core/java/android/app/backup/BackupManager.java @@ -21,7 +21,7 @@ import android.annotation.Nullable; import android.annotation.RequiresPermission; import android.annotation.SystemApi; import android.annotation.TestApi; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.ComponentName; import android.content.Context; import android.content.Intent; diff --git a/core/java/android/app/backup/FileBackupHelperBase.java b/core/java/android/app/backup/FileBackupHelperBase.java index 0caab983448b..5ad5d0865e56 100644 --- a/core/java/android/app/backup/FileBackupHelperBase.java +++ b/core/java/android/app/backup/FileBackupHelperBase.java @@ -16,7 +16,7 @@ package android.app.backup; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; import android.os.ParcelFileDescriptor; import android.util.Log; diff --git a/core/java/android/app/backup/FullBackup.java b/core/java/android/app/backup/FullBackup.java index 9a595b2da59f..587e883edaf2 100644 --- a/core/java/android/app/backup/FullBackup.java +++ b/core/java/android/app/backup/FullBackup.java @@ -16,7 +16,7 @@ package android.app.backup; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; import android.content.pm.PackageManager; import android.content.res.XmlResourceParser; diff --git a/core/java/android/app/backup/FullBackupDataOutput.java b/core/java/android/app/backup/FullBackupDataOutput.java index 0ce86534afdd..d8fa0f586b7a 100644 --- a/core/java/android/app/backup/FullBackupDataOutput.java +++ b/core/java/android/app/backup/FullBackupDataOutput.java @@ -1,6 +1,6 @@ package android.app.backup; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.os.ParcelFileDescriptor; /** diff --git a/core/java/android/app/job/JobInfo.java b/core/java/android/app/job/JobInfo.java index a8f89df8058c..72eea849cbf4 100644 --- a/core/java/android/app/job/JobInfo.java +++ b/core/java/android/app/job/JobInfo.java @@ -29,7 +29,7 @@ import android.annotation.IntDef; import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.RequiresPermission; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.ClipData; import android.content.ComponentName; import android.net.NetworkRequest; diff --git a/core/java/android/app/job/JobParameters.java b/core/java/android/app/job/JobParameters.java index dadfe3d3746a..763520272e2e 100644 --- a/core/java/android/app/job/JobParameters.java +++ b/core/java/android/app/job/JobParameters.java @@ -18,8 +18,7 @@ package android.app.job; import android.annotation.NonNull; import android.annotation.Nullable; -import android.annotation.UnsupportedAppUsage; -import android.app.job.IJobCallback; +import android.compat.annotation.UnsupportedAppUsage; import android.content.ClipData; import android.net.Network; import android.net.Uri; diff --git a/core/java/android/app/job/JobWorkItem.java b/core/java/android/app/job/JobWorkItem.java index a055ab48c766..237c5071a130 100644 --- a/core/java/android/app/job/JobWorkItem.java +++ b/core/java/android/app/job/JobWorkItem.java @@ -19,7 +19,7 @@ package android.app.job; import static android.app.job.JobInfo.NETWORK_BYTES_UNKNOWN; import android.annotation.BytesLong; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.Intent; import android.os.Build; import android.os.Parcel; diff --git a/core/java/android/app/servertransaction/ActivityResultItem.java b/core/java/android/app/servertransaction/ActivityResultItem.java index 52ec3e60a9c7..4e743caccad6 100644 --- a/core/java/android/app/servertransaction/ActivityResultItem.java +++ b/core/java/android/app/servertransaction/ActivityResultItem.java @@ -18,9 +18,9 @@ package android.app.servertransaction; import static android.os.Trace.TRACE_TAG_ACTIVITY_MANAGER; -import android.annotation.UnsupportedAppUsage; import android.app.ClientTransactionHandler; import android.app.ResultInfo; +import android.compat.annotation.UnsupportedAppUsage; import android.os.IBinder; import android.os.Parcel; import android.os.Parcelable; diff --git a/core/java/android/app/servertransaction/ClientTransaction.java b/core/java/android/app/servertransaction/ClientTransaction.java index b08e5973faa2..4d2e9a503ac5 100644 --- a/core/java/android/app/servertransaction/ClientTransaction.java +++ b/core/java/android/app/servertransaction/ClientTransaction.java @@ -17,9 +17,9 @@ package android.app.servertransaction; import android.annotation.Nullable; -import android.annotation.UnsupportedAppUsage; import android.app.ClientTransactionHandler; import android.app.IApplicationThread; +import android.compat.annotation.UnsupportedAppUsage; import android.os.IBinder; import android.os.Parcel; import android.os.Parcelable; diff --git a/core/java/android/app/servertransaction/LaunchActivityItem.java b/core/java/android/app/servertransaction/LaunchActivityItem.java index 1236e0ac7401..6d674ae7df14 100644 --- a/core/java/android/app/servertransaction/LaunchActivityItem.java +++ b/core/java/android/app/servertransaction/LaunchActivityItem.java @@ -18,11 +18,11 @@ package android.app.servertransaction; import static android.os.Trace.TRACE_TAG_ACTIVITY_MANAGER; -import android.annotation.UnsupportedAppUsage; import android.app.ActivityThread.ActivityClientRecord; import android.app.ClientTransactionHandler; import android.app.ProfilerInfo; import android.app.ResultInfo; +import android.compat.annotation.UnsupportedAppUsage; import android.content.Intent; import android.content.pm.ActivityInfo; import android.content.res.CompatibilityInfo; diff --git a/core/java/android/app/servertransaction/NewIntentItem.java b/core/java/android/app/servertransaction/NewIntentItem.java index bb775fc4a5fb..6a4996da38ca 100644 --- a/core/java/android/app/servertransaction/NewIntentItem.java +++ b/core/java/android/app/servertransaction/NewIntentItem.java @@ -19,8 +19,8 @@ package android.app.servertransaction; import static android.app.servertransaction.ActivityLifecycleItem.ON_RESUME; import static android.app.servertransaction.ActivityLifecycleItem.UNDEFINED; -import android.annotation.UnsupportedAppUsage; import android.app.ClientTransactionHandler; +import android.compat.annotation.UnsupportedAppUsage; import android.os.IBinder; import android.os.Parcel; import android.os.Parcelable; diff --git a/core/java/android/app/timedetector/ManualTimeSuggestion.java b/core/java/android/app/timedetector/ManualTimeSuggestion.java index 55f92be14cd0..50de73855511 100644 --- a/core/java/android/app/timedetector/ManualTimeSuggestion.java +++ b/core/java/android/app/timedetector/ManualTimeSuggestion.java @@ -20,7 +20,7 @@ import android.annotation.NonNull; import android.annotation.Nullable; import android.os.Parcel; import android.os.Parcelable; -import android.util.TimestampedValue; +import android.os.TimestampedValue; import java.util.ArrayList; import java.util.Arrays; diff --git a/core/java/android/app/timedetector/NetworkTimeSuggestion.java b/core/java/android/app/timedetector/NetworkTimeSuggestion.java index 4c55ba12d881..17e9c5a79fa5 100644 --- a/core/java/android/app/timedetector/NetworkTimeSuggestion.java +++ b/core/java/android/app/timedetector/NetworkTimeSuggestion.java @@ -20,7 +20,7 @@ import android.annotation.NonNull; import android.annotation.Nullable; import android.os.Parcel; import android.os.Parcelable; -import android.util.TimestampedValue; +import android.os.TimestampedValue; import java.util.ArrayList; import java.util.Arrays; diff --git a/core/java/android/app/timedetector/PhoneTimeSuggestion.java b/core/java/android/app/timedetector/PhoneTimeSuggestion.java index 4a89a1245473..bd649f88f40a 100644 --- a/core/java/android/app/timedetector/PhoneTimeSuggestion.java +++ b/core/java/android/app/timedetector/PhoneTimeSuggestion.java @@ -18,9 +18,10 @@ package android.app.timedetector; import android.annotation.NonNull; import android.annotation.Nullable; +import android.annotation.SystemApi; import android.os.Parcel; import android.os.Parcelable; -import android.util.TimestampedValue; +import android.os.TimestampedValue; import java.util.ArrayList; import java.util.Collections; @@ -28,17 +29,23 @@ import java.util.List; import java.util.Objects; /** - * A time signal from a telephony source. The value can be {@code null} to indicate that the - * telephony source has entered an "un-opinionated" state and any previously sent suggestions are - * being withdrawn. When not {@code null}, the value consists of the number of milliseconds elapsed - * since 1/1/1970 00:00:00 UTC and the time according to the elapsed realtime clock when that number - * was established. The elapsed realtime clock is considered accurate but volatile, so time signals - * must not be persisted across device resets. + * A time suggestion from an identified telephony source. e.g. from NITZ information from a specific + * radio. + * + * <p>The time value can be {@code null} to indicate that the telephony source has entered an + * "un-opinionated" state and any previous suggestions from the source are being withdrawn. When not + * {@code null}, the value consists of the number of milliseconds elapsed since 1/1/1970 00:00:00 + * UTC and the time according to the elapsed realtime clock when that number was established. The + * elapsed realtime clock is considered accurate but volatile, so time suggestions must not be + * persisted across device resets. * * @hide */ +@SystemApi(client = SystemApi.Client.MODULE_LIBRARIES) public final class PhoneTimeSuggestion implements Parcelable { + /** @hide */ + @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES) public static final @NonNull Parcelable.Creator<PhoneTimeSuggestion> CREATOR = new Parcelable.Creator<PhoneTimeSuggestion>() { public PhoneTimeSuggestion createFromParcel(Parcel in) { @@ -85,15 +92,27 @@ public final class PhoneTimeSuggestion implements Parcelable { dest.writeList(mDebugInfo); } + /** + * Returns an identifier for the source of this suggestion. When a device has several "phones", + * i.e. sim slots or equivalent, it is used to identify which one. + */ public int getPhoneId() { return mPhoneId; } + /** + * Returns the suggestion. {@code null} means that the caller is no longer sure what time it + * is. + */ @Nullable public TimestampedValue<Long> getUtcTime() { return mUtcTime; } + /** + * Returns debug metadata for the suggestion. The information is present in {@link #toString()} + * but is not considered for {@link #equals(Object)} and {@link #hashCode()}. + */ @NonNull public List<String> getDebugInfo() { return mDebugInfo == null @@ -105,7 +124,7 @@ public final class PhoneTimeSuggestion implements Parcelable { * information is present in {@link #toString()} but is not considered for * {@link #equals(Object)} and {@link #hashCode()}. */ - public void addDebugInfo(String debugInfo) { + public void addDebugInfo(@NonNull String debugInfo) { if (mDebugInfo == null) { mDebugInfo = new ArrayList<>(); } @@ -156,16 +175,19 @@ public final class PhoneTimeSuggestion implements Parcelable { * * @hide */ - public static class Builder { + @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES) + public static final class Builder { private final int mPhoneId; - private TimestampedValue<Long> mUtcTime; - private List<String> mDebugInfo; + @Nullable private TimestampedValue<Long> mUtcTime; + @Nullable private List<String> mDebugInfo; + /** Creates a builder with the specified {@code phoneId}. */ public Builder(int phoneId) { mPhoneId = phoneId; } /** Returns the builder for call chaining. */ + @NonNull public Builder setUtcTime(@Nullable TimestampedValue<Long> utcTime) { if (utcTime != null) { // utcTime can be null, but the value it holds cannot. @@ -177,6 +199,7 @@ public final class PhoneTimeSuggestion implements Parcelable { } /** Returns the builder for call chaining. */ + @NonNull public Builder addDebugInfo(@NonNull String debugInfo) { if (mDebugInfo == null) { mDebugInfo = new ArrayList<>(); @@ -186,6 +209,7 @@ public final class PhoneTimeSuggestion implements Parcelable { } /** Returns the {@link PhoneTimeSuggestion}. */ + @NonNull public PhoneTimeSuggestion build() { return new PhoneTimeSuggestion(this); } diff --git a/core/java/android/app/timedetector/TimeDetector.java b/core/java/android/app/timedetector/TimeDetector.java index af9ece00f491..7c29f017c02b 100644 --- a/core/java/android/app/timedetector/TimeDetector.java +++ b/core/java/android/app/timedetector/TimeDetector.java @@ -18,19 +18,23 @@ package android.app.timedetector; import android.annotation.NonNull; import android.annotation.RequiresPermission; +import android.annotation.SystemApi; import android.annotation.SystemService; import android.content.Context; import android.os.RemoteException; import android.os.ServiceManager; import android.os.ServiceManager.ServiceNotFoundException; import android.os.SystemClock; +import android.os.TimestampedValue; import android.util.Log; -import android.util.TimestampedValue; /** * The interface through which system components can send signals to the TimeDetectorService. + * + * <p>This class is marked non-final for mockito. * @hide */ +@SystemApi(client = SystemApi.Client.MODULE_LIBRARIES) @SystemService(Context.TIME_DETECTOR_SERVICE) public class TimeDetector { private static final String TAG = "timedetector.TimeDetector"; @@ -38,6 +42,7 @@ public class TimeDetector { private final ITimeDetectorService mITimeDetectorService; + /** @hide */ public TimeDetector() throws ServiceNotFoundException { mITimeDetectorService = ITimeDetectorService.Stub.asInterface( ServiceManager.getServiceOrThrow(Context.TIME_DETECTOR_SERVICE)); @@ -62,6 +67,8 @@ public class TimeDetector { /** * Suggests the user's manually entered current time to the detector. + * + * @hide */ @RequiresPermission(android.Manifest.permission.SUGGEST_MANUAL_TIME_AND_ZONE) public void suggestManualTime(@NonNull ManualTimeSuggestion timeSuggestion) { @@ -77,6 +84,8 @@ public class TimeDetector { /** * A shared utility method to create a {@link ManualTimeSuggestion}. + * + * @hide */ public static ManualTimeSuggestion createManualTimeSuggestion(long when, String why) { TimestampedValue<Long> utcTime = @@ -88,6 +97,8 @@ public class TimeDetector { /** * Suggests the time according to a network time source like NTP. + * + * @hide */ @RequiresPermission(android.Manifest.permission.SET_TIME) public void suggestNetworkTime(NetworkTimeSuggestion timeSuggestion) { diff --git a/core/java/android/app/timezonedetector/PhoneTimeZoneSuggestion.java b/core/java/android/app/timezonedetector/PhoneTimeZoneSuggestion.java index e8162488394c..d71ffcb9f772 100644 --- a/core/java/android/app/timezonedetector/PhoneTimeZoneSuggestion.java +++ b/core/java/android/app/timezonedetector/PhoneTimeZoneSuggestion.java @@ -19,6 +19,7 @@ package android.app.timezonedetector; import android.annotation.IntDef; import android.annotation.NonNull; import android.annotation.Nullable; +import android.annotation.SystemApi; import android.os.Parcel; import android.os.Parcelable; @@ -30,12 +31,27 @@ import java.util.List; import java.util.Objects; /** - * A suggested time zone from a Phone-based signal, e.g. from MCC and NITZ information. + * A time zone suggestion from an identified telephony source, e.g. from MCC and NITZ information + * associated with a specific radio. + * + * <p>The time zone ID can be {@code null} to indicate that the telephony source has entered an + * "un-opinionated" state and any previous suggestions from that source are being withdrawn. + * When not {@code null}, the value consists of a suggested time zone ID and metadata that can be + * used to judge quality / certainty of the suggestion. + * + * <p>{@code matchType} must be set to {@link #MATCH_TYPE_NA} when {@code zoneId} is {@code null}, + * and one of the other {@code MATCH_TYPE_} values when it is not {@code null}. + * + * <p>{@code quality} must be set to {@link #QUALITY_NA} when {@code zoneId} is {@code null}, + * and one of the other {@code QUALITY_} values when it is not {@code null}. * * @hide */ +@SystemApi(client = SystemApi.Client.MODULE_LIBRARIES) public final class PhoneTimeZoneSuggestion implements Parcelable { + /** @hide */ + @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES) @NonNull public static final Creator<PhoneTimeZoneSuggestion> CREATOR = new Creator<PhoneTimeZoneSuggestion>() { @@ -58,6 +74,7 @@ public final class PhoneTimeZoneSuggestion implements Parcelable { return new Builder(phoneId).addDebugInfo(debugInfo).build(); } + /** @hide */ @IntDef({ MATCH_TYPE_NA, MATCH_TYPE_NETWORK_COUNTRY_ONLY, MATCH_TYPE_NETWORK_COUNTRY_AND_OFFSET, MATCH_TYPE_EMULATOR_ZONE_ID, MATCH_TYPE_TEST_NETWORK_OFFSET_ONLY }) @Retention(RetentionPolicy.SOURCE) @@ -90,6 +107,7 @@ public final class PhoneTimeZoneSuggestion implements Parcelable { */ public static final int MATCH_TYPE_TEST_NETWORK_OFFSET_ONLY = 5; + /** @hide */ @IntDef({ QUALITY_NA, QUALITY_SINGLE_ZONE, QUALITY_MULTIPLE_ZONES_WITH_SAME_OFFSET, QUALITY_MULTIPLE_ZONES_WITH_DIFFERENT_OFFSETS }) @Retention(RetentionPolicy.SOURCE) @@ -115,7 +133,7 @@ public final class PhoneTimeZoneSuggestion implements Parcelable { /** * The ID of the phone this suggestion is associated with. For multiple-sim devices this - * helps to establish origin so filtering / stickiness can be implemented. + * helps to establish source so filtering / stickiness can be implemented. */ private final int mPhoneId; @@ -123,6 +141,7 @@ public final class PhoneTimeZoneSuggestion implements Parcelable { * The suggestion. {@code null} means there is no current suggestion and any previous suggestion * should be forgotten. */ + @Nullable private final String mZoneId; /** @@ -139,9 +158,10 @@ public final class PhoneTimeZoneSuggestion implements Parcelable { private final int mQuality; /** - * Free-form debug information about how the signal was derived. Used for debug only, + * Free-form debug information about how the suggestion was derived. Used for debug only, * intentionally not used in equals(), etc. */ + @Nullable private List<String> mDebugInfo; private PhoneTimeZoneSuggestion(Builder builder) { @@ -182,25 +202,47 @@ public final class PhoneTimeZoneSuggestion implements Parcelable { return 0; } + /** + * Returns an identifier for the source of this suggestion. When a device has several "phones", + * i.e. sim slots or equivalent, it is used to identify which one. + */ public int getPhoneId() { return mPhoneId; } + /** + * Returns the suggested time zone Olson ID, e.g. "America/Los_Angeles". {@code null} means that + * the caller is no longer sure what the current time zone is. See + * {@link PhoneTimeZoneSuggestion} for the associated {@code matchType} / {@code quality} rules. + */ @Nullable public String getZoneId() { return mZoneId; } + /** + * Returns information about how the suggestion was determined which could be used to rank + * suggestions when several are available from different sources. See + * {@link PhoneTimeZoneSuggestion} for the associated rules. + */ @MatchType public int getMatchType() { return mMatchType; } + /** + * Returns information about the likelihood of the suggested zone being correct. See + * {@link PhoneTimeZoneSuggestion} for the associated rules. + */ @Quality public int getQuality() { return mQuality; } + /** + * Returns debug metadata for the suggestion. The information is present in {@link #toString()} + * but is not considered for {@link #equals(Object)} and {@link #hashCode()}. + */ @NonNull public List<String> getDebugInfo() { return mDebugInfo == null @@ -267,36 +309,43 @@ public final class PhoneTimeZoneSuggestion implements Parcelable { * * @hide */ - public static class Builder { + @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES) + public static final class Builder { private final int mPhoneId; - private String mZoneId; + @Nullable private String mZoneId; @MatchType private int mMatchType; @Quality private int mQuality; - private List<String> mDebugInfo; + @Nullable private List<String> mDebugInfo; public Builder(int phoneId) { mPhoneId = phoneId; } - /** Returns the builder for call chaining. */ - public Builder setZoneId(String zoneId) { + /** + * Returns the builder for call chaining. + */ + @NonNull + public Builder setZoneId(@Nullable String zoneId) { mZoneId = zoneId; return this; } /** Returns the builder for call chaining. */ + @NonNull public Builder setMatchType(@MatchType int matchType) { mMatchType = matchType; return this; } /** Returns the builder for call chaining. */ + @NonNull public Builder setQuality(@Quality int quality) { mQuality = quality; return this; } /** Returns the builder for call chaining. */ + @NonNull public Builder addDebugInfo(@NonNull String debugInfo) { if (mDebugInfo == null) { mDebugInfo = new ArrayList<>(); @@ -333,6 +382,7 @@ public final class PhoneTimeZoneSuggestion implements Parcelable { } /** Returns the {@link PhoneTimeZoneSuggestion}. */ + @NonNull public PhoneTimeZoneSuggestion build() { validate(); return new PhoneTimeZoneSuggestion(this); diff --git a/core/java/android/app/timezonedetector/TimeZoneDetector.java b/core/java/android/app/timezonedetector/TimeZoneDetector.java index e165d8a76caa..5b5f311264e3 100644 --- a/core/java/android/app/timezonedetector/TimeZoneDetector.java +++ b/core/java/android/app/timezonedetector/TimeZoneDetector.java @@ -18,6 +18,7 @@ package android.app.timezonedetector; import android.annotation.NonNull; import android.annotation.RequiresPermission; +import android.annotation.SystemApi; import android.annotation.SystemService; import android.content.Context; import android.os.RemoteException; @@ -28,8 +29,10 @@ import android.util.Log; /** * The interface through which system components can send signals to the TimeZoneDetectorService. * + * <p>This class is non-final for mockito. * @hide */ +@SystemApi(client = SystemApi.Client.MODULE_LIBRARIES) @SystemService(Context.TIME_ZONE_DETECTOR_SERVICE) public class TimeZoneDetector { private static final String TAG = "timezonedetector.TimeZoneDetector"; @@ -37,6 +40,7 @@ public class TimeZoneDetector { private final ITimeZoneDetectorService mITimeZoneDetectorService; + /** @hide */ public TimeZoneDetector() throws ServiceNotFoundException { mITimeZoneDetectorService = ITimeZoneDetectorService.Stub.asInterface( ServiceManager.getServiceOrThrow(Context.TIME_ZONE_DETECTOR_SERVICE)); @@ -46,7 +50,10 @@ public class TimeZoneDetector { * Suggests the current time zone, determined using telephony signals, to the detector. The * detector may ignore the signal based on system settings, whether better information is * available, and so on. + * + * @hide */ + @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES) @RequiresPermission(android.Manifest.permission.SUGGEST_PHONE_TIME_AND_ZONE) public void suggestPhoneTimeZone(@NonNull PhoneTimeZoneSuggestion timeZoneSuggestion) { if (DEBUG) { @@ -62,6 +69,8 @@ public class TimeZoneDetector { /** * Suggests the current time zone, determined for the user's manually information, to the * detector. The detector may ignore the signal based on system settings. + * + * @hide */ @RequiresPermission(android.Manifest.permission.SUGGEST_MANUAL_TIME_AND_ZONE) public void suggestManualTimeZone(@NonNull ManualTimeZoneSuggestion timeZoneSuggestion) { @@ -77,6 +86,8 @@ public class TimeZoneDetector { /** * A shared utility method to create a {@link ManualTimeZoneSuggestion}. + * + * @hide */ public static ManualTimeZoneSuggestion createManualTimeZoneSuggestion(String tzId, String why) { ManualTimeZoneSuggestion suggestion = new ManualTimeZoneSuggestion(tzId); diff --git a/core/java/android/app/trust/TrustManager.java b/core/java/android/app/trust/TrustManager.java index 27abdcfbefc9..65b2775fd66b 100644 --- a/core/java/android/app/trust/TrustManager.java +++ b/core/java/android/app/trust/TrustManager.java @@ -19,7 +19,7 @@ package android.app.trust; import android.Manifest; import android.annotation.RequiresPermission; import android.annotation.SystemService; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; import android.hardware.biometrics.BiometricSourceType; import android.os.Handler; diff --git a/core/java/android/app/usage/ConfigurationStats.java b/core/java/android/app/usage/ConfigurationStats.java index da3b76972ced..8a7107de8363 100644 --- a/core/java/android/app/usage/ConfigurationStats.java +++ b/core/java/android/app/usage/ConfigurationStats.java @@ -15,7 +15,7 @@ */ package android.app.usage; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.res.Configuration; import android.os.Build; import android.os.Parcel; diff --git a/core/java/android/app/usage/NetworkStatsManager.java b/core/java/android/app/usage/NetworkStatsManager.java index 6bade901826a..9c4a8f4fbe27 100644 --- a/core/java/android/app/usage/NetworkStatsManager.java +++ b/core/java/android/app/usage/NetworkStatsManager.java @@ -16,19 +16,23 @@ package android.app.usage; -import static com.android.internal.util.Preconditions.checkNotNull; - +import android.annotation.NonNull; import android.annotation.Nullable; +import android.annotation.RequiresPermission; +import android.annotation.SystemApi; import android.annotation.SystemService; import android.annotation.TestApi; -import android.annotation.UnsupportedAppUsage; import android.app.usage.NetworkStats.Bucket; +import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; import android.net.ConnectivityManager; import android.net.DataUsageRequest; import android.net.INetworkStatsService; import android.net.NetworkIdentity; import android.net.NetworkTemplate; +import android.net.netstats.provider.AbstractNetworkStatsProvider; +import android.net.netstats.provider.NetworkStatsProviderCallback; +import android.net.netstats.provider.NetworkStatsProviderWrapper; import android.os.Binder; import android.os.Handler; import android.os.Looper; @@ -42,6 +46,8 @@ import android.util.Log; import com.android.internal.annotations.VisibleForTesting; +import java.util.Objects; + /** * Provides access to network usage history and statistics. Usage data is collected in * discrete bins of time called 'Buckets'. See {@link NetworkStats.Bucket} for details. @@ -418,7 +424,7 @@ public class NetworkStatsManager { /** @hide */ public void registerUsageCallback(NetworkTemplate template, int networkType, long thresholdBytes, UsageCallback callback, @Nullable Handler handler) { - checkNotNull(callback, "UsageCallback cannot be null"); + Objects.requireNonNull(callback, "UsageCallback cannot be null"); final Looper looper; if (handler == null) { @@ -519,6 +525,34 @@ public class NetworkStatsManager { private DataUsageRequest request; } + /** + * Registers a custom provider of {@link android.net.NetworkStats} to combine the network + * statistics that cannot be seen by the kernel to system. To unregister, invoke + * {@link NetworkStatsProviderCallback#unregister()}. + * + * @param tag a human readable identifier of the custom network stats provider. + * @param provider a custom implementation of {@link AbstractNetworkStatsProvider} that needs to + * be registered to the system. + * @return a {@link NetworkStatsProviderCallback}, which can be used to report events to the + * system. + * @hide + */ + @SystemApi + @RequiresPermission(android.Manifest.permission.UPDATE_DEVICE_STATS) + @NonNull public NetworkStatsProviderCallback registerNetworkStatsProvider( + @NonNull String tag, + @NonNull AbstractNetworkStatsProvider provider) { + try { + final NetworkStatsProviderWrapper wrapper = new NetworkStatsProviderWrapper(provider); + return new NetworkStatsProviderCallback( + mService.registerNetworkStatsProvider(tag, wrapper)); + } catch (RemoteException e) { + e.rethrowAsRuntimeException(); + } + // Unreachable code, but compiler doesn't know about it. + return null; + } + private static NetworkTemplate createTemplate(int networkType, String subscriberId) { final NetworkTemplate template; switch (networkType) { diff --git a/core/java/android/app/usage/UsageEvents.java b/core/java/android/app/usage/UsageEvents.java index 84c68552c40a..c646fc69702d 100644 --- a/core/java/android/app/usage/UsageEvents.java +++ b/core/java/android/app/usage/UsageEvents.java @@ -18,7 +18,7 @@ package android.app.usage; import android.annotation.IntDef; import android.annotation.Nullable; import android.annotation.SystemApi; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.res.Configuration; import android.os.Build; import android.os.Parcel; diff --git a/core/java/android/app/usage/UsageStats.java b/core/java/android/app/usage/UsageStats.java index 2c021cc42cb5..3550ebd24026 100644 --- a/core/java/android/app/usage/UsageStats.java +++ b/core/java/android/app/usage/UsageStats.java @@ -29,7 +29,7 @@ import static android.app.usage.UsageEvents.Event.FOREGROUND_SERVICE_STOP; import static android.app.usage.UsageEvents.Event.ROLLOVER_FOREGROUND_SERVICE; import android.annotation.SystemApi; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.os.Build; import android.os.Bundle; import android.os.Parcel; diff --git a/core/java/android/app/usage/UsageStatsManager.java b/core/java/android/app/usage/UsageStatsManager.java index 92e1b30793c9..102a08d17deb 100644 --- a/core/java/android/app/usage/UsageStatsManager.java +++ b/core/java/android/app/usage/UsageStatsManager.java @@ -23,9 +23,9 @@ import android.annotation.RequiresPermission; import android.annotation.SystemApi; import android.annotation.SystemService; import android.annotation.TestApi; -import android.annotation.UnsupportedAppUsage; import android.app.Activity; import android.app.PendingIntent; +import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; import android.content.pm.ParceledListSlice; import android.os.Build; diff --git a/core/java/android/appwidget/AppWidgetHost.java b/core/java/android/appwidget/AppWidgetHost.java index f003d4bea028..f61d35bc7d33 100644 --- a/core/java/android/appwidget/AppWidgetHost.java +++ b/core/java/android/appwidget/AppWidgetHost.java @@ -18,8 +18,8 @@ package android.appwidget; import android.annotation.NonNull; import android.annotation.Nullable; -import android.annotation.UnsupportedAppUsage; import android.app.Activity; +import android.compat.annotation.UnsupportedAppUsage; import android.content.ActivityNotFoundException; import android.content.Context; import android.content.IntentSender; diff --git a/core/java/android/appwidget/AppWidgetHostView.java b/core/java/android/appwidget/AppWidgetHostView.java index 85f0e2342412..09d56ec70e56 100644 --- a/core/java/android/appwidget/AppWidgetHostView.java +++ b/core/java/android/appwidget/AppWidgetHostView.java @@ -16,9 +16,9 @@ package android.appwidget; -import android.annotation.UnsupportedAppUsage; import android.app.Activity; import android.app.ActivityOptions; +import android.compat.annotation.UnsupportedAppUsage; import android.content.ComponentName; import android.content.Context; import android.content.ContextWrapper; diff --git a/core/java/android/appwidget/AppWidgetManager.java b/core/java/android/appwidget/AppWidgetManager.java index dbc1c199cb4d..6dea1c69ce86 100644 --- a/core/java/android/appwidget/AppWidgetManager.java +++ b/core/java/android/appwidget/AppWidgetManager.java @@ -23,9 +23,9 @@ import android.annotation.RequiresFeature; import android.annotation.SdkConstant; import android.annotation.SdkConstant.SdkConstantType; import android.annotation.SystemService; -import android.annotation.UnsupportedAppUsage; import android.app.IServiceConnection; import android.app.PendingIntent; +import android.compat.annotation.UnsupportedAppUsage; import android.content.ComponentName; import android.content.Context; import android.content.Intent; diff --git a/core/java/android/appwidget/AppWidgetProviderInfo.java b/core/java/android/appwidget/AppWidgetProviderInfo.java index 2faa9007fc29..130a20dfb07b 100644 --- a/core/java/android/appwidget/AppWidgetProviderInfo.java +++ b/core/java/android/appwidget/AppWidgetProviderInfo.java @@ -18,8 +18,8 @@ package android.appwidget; import android.annotation.IntDef; import android.annotation.NonNull; -import android.annotation.UnsupportedAppUsage; import android.app.PendingIntent; +import android.compat.annotation.UnsupportedAppUsage; import android.content.ComponentName; import android.content.Context; import android.content.pm.ActivityInfo; diff --git a/core/java/android/bluetooth/BluetoothA2dp.java b/core/java/android/bluetooth/BluetoothA2dp.java index 64df0e84f6dc..d8c653c6d0d5 100644 --- a/core/java/android/bluetooth/BluetoothA2dp.java +++ b/core/java/android/bluetooth/BluetoothA2dp.java @@ -24,7 +24,7 @@ import android.annotation.RequiresPermission; import android.annotation.SdkConstant; import android.annotation.SdkConstant.SdkConstantType; import android.annotation.SystemApi; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; import android.os.Binder; import android.os.Build; diff --git a/core/java/android/bluetooth/BluetoothA2dpSink.java b/core/java/android/bluetooth/BluetoothA2dpSink.java index c6957e14116b..8993de0939e6 100755 --- a/core/java/android/bluetooth/BluetoothA2dpSink.java +++ b/core/java/android/bluetooth/BluetoothA2dpSink.java @@ -21,7 +21,7 @@ import android.annotation.Nullable; import android.annotation.RequiresPermission; import android.annotation.SuppressLint; import android.annotation.SystemApi; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; import android.os.Binder; import android.os.IBinder; diff --git a/core/java/android/bluetooth/BluetoothAdapter.java b/core/java/android/bluetooth/BluetoothAdapter.java index 291d1d99fdc9..1869c6fa7621 100644 --- a/core/java/android/bluetooth/BluetoothAdapter.java +++ b/core/java/android/bluetooth/BluetoothAdapter.java @@ -25,7 +25,6 @@ import android.annotation.RequiresPermission; import android.annotation.SdkConstant; import android.annotation.SdkConstant.SdkConstantType; import android.annotation.SystemApi; -import android.annotation.UnsupportedAppUsage; import android.app.ActivityThread; import android.bluetooth.BluetoothProfile.ConnectionPolicy; import android.bluetooth.le.BluetoothLeAdvertiser; @@ -36,6 +35,7 @@ import android.bluetooth.le.ScanFilter; import android.bluetooth.le.ScanRecord; import android.bluetooth.le.ScanResult; import android.bluetooth.le.ScanSettings; +import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; import android.os.BatteryStats; import android.os.Binder; @@ -2670,6 +2670,9 @@ public final class BluetoothAdapter { } else if (profile == BluetoothProfile.PAN) { BluetoothPan pan = new BluetoothPan(context, listener); return true; + } else if (profile == BluetoothProfile.PBAP) { + BluetoothPbap pbap = new BluetoothPbap(context, listener); + return true; } else if (profile == BluetoothProfile.HEALTH) { Log.e(TAG, "getProfileProxy(): BluetoothHealth is deprecated"); return false; @@ -2742,6 +2745,10 @@ public final class BluetoothAdapter { BluetoothPan pan = (BluetoothPan) proxy; pan.close(); break; + case BluetoothProfile.PBAP: + BluetoothPbap pbap = (BluetoothPbap) proxy; + pbap.close(); + break; case BluetoothProfile.GATT: BluetoothGatt gatt = (BluetoothGatt) proxy; gatt.close(); diff --git a/core/java/android/bluetooth/BluetoothClass.java b/core/java/android/bluetooth/BluetoothClass.java index 260e2fb1b80c..905b0ceec4ee 100755 --- a/core/java/android/bluetooth/BluetoothClass.java +++ b/core/java/android/bluetooth/BluetoothClass.java @@ -17,7 +17,7 @@ package android.bluetooth; import android.annotation.TestApi; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.os.Build; import android.os.Parcel; import android.os.Parcelable; diff --git a/core/java/android/bluetooth/BluetoothCodecConfig.java b/core/java/android/bluetooth/BluetoothCodecConfig.java index 08d0797997b5..93e76fa5ba7d 100644 --- a/core/java/android/bluetooth/BluetoothCodecConfig.java +++ b/core/java/android/bluetooth/BluetoothCodecConfig.java @@ -19,7 +19,7 @@ package android.bluetooth; import android.annotation.IntDef; import android.annotation.NonNull; import android.annotation.SystemApi; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.os.Parcel; import android.os.Parcelable; diff --git a/core/java/android/bluetooth/BluetoothDevice.java b/core/java/android/bluetooth/BluetoothDevice.java index 323c7d172033..9fe4dd66b874 100644 --- a/core/java/android/bluetooth/BluetoothDevice.java +++ b/core/java/android/bluetooth/BluetoothDevice.java @@ -24,7 +24,7 @@ import android.annotation.RequiresPermission; import android.annotation.SdkConstant; import android.annotation.SdkConstant.SdkConstantType; import android.annotation.SystemApi; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; import android.os.Handler; import android.os.Parcel; diff --git a/core/java/android/bluetooth/BluetoothGatt.java b/core/java/android/bluetooth/BluetoothGatt.java index d616b8f92d3a..f877f04626da 100644 --- a/core/java/android/bluetooth/BluetoothGatt.java +++ b/core/java/android/bluetooth/BluetoothGatt.java @@ -16,7 +16,7 @@ package android.bluetooth; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.os.Build; import android.os.Handler; import android.os.ParcelUuid; diff --git a/core/java/android/bluetooth/BluetoothGattCharacteristic.java b/core/java/android/bluetooth/BluetoothGattCharacteristic.java index edacf3e0b706..7066f470aa96 100644 --- a/core/java/android/bluetooth/BluetoothGattCharacteristic.java +++ b/core/java/android/bluetooth/BluetoothGattCharacteristic.java @@ -15,7 +15,7 @@ */ package android.bluetooth; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.os.Parcel; import android.os.ParcelUuid; import android.os.Parcelable; diff --git a/core/java/android/bluetooth/BluetoothGattDescriptor.java b/core/java/android/bluetooth/BluetoothGattDescriptor.java index 0783cd2b73cc..7cc2d6bc53fb 100644 --- a/core/java/android/bluetooth/BluetoothGattDescriptor.java +++ b/core/java/android/bluetooth/BluetoothGattDescriptor.java @@ -16,7 +16,7 @@ package android.bluetooth; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.os.Parcel; import android.os.ParcelUuid; import android.os.Parcelable; diff --git a/core/java/android/bluetooth/BluetoothGattService.java b/core/java/android/bluetooth/BluetoothGattService.java index c20faf9db698..13d6d7021ec8 100644 --- a/core/java/android/bluetooth/BluetoothGattService.java +++ b/core/java/android/bluetooth/BluetoothGattService.java @@ -15,7 +15,7 @@ */ package android.bluetooth; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.os.Parcel; import android.os.ParcelUuid; import android.os.Parcelable; diff --git a/core/java/android/bluetooth/BluetoothHeadset.java b/core/java/android/bluetooth/BluetoothHeadset.java index 0955b103a8e8..1ba2bb5e31ad 100644 --- a/core/java/android/bluetooth/BluetoothHeadset.java +++ b/core/java/android/bluetooth/BluetoothHeadset.java @@ -23,7 +23,7 @@ import android.annotation.RequiresPermission; import android.annotation.SdkConstant; import android.annotation.SdkConstant.SdkConstantType; import android.annotation.SystemApi; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.ComponentName; import android.content.Context; import android.os.Binder; diff --git a/core/java/android/bluetooth/BluetoothHeadsetClient.java b/core/java/android/bluetooth/BluetoothHeadsetClient.java index 7ee29ff1c50b..6de1ffb6344e 100644 --- a/core/java/android/bluetooth/BluetoothHeadsetClient.java +++ b/core/java/android/bluetooth/BluetoothHeadsetClient.java @@ -19,7 +19,7 @@ package android.bluetooth; import android.Manifest; import android.annotation.RequiresPermission; import android.annotation.SystemApi; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; import android.os.Binder; import android.os.Bundle; diff --git a/core/java/android/bluetooth/BluetoothHeadsetClientCall.java b/core/java/android/bluetooth/BluetoothHeadsetClientCall.java index 7165dd56a213..d1a096e605dd 100644 --- a/core/java/android/bluetooth/BluetoothHeadsetClientCall.java +++ b/core/java/android/bluetooth/BluetoothHeadsetClientCall.java @@ -16,7 +16,7 @@ package android.bluetooth; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.os.Parcel; import android.os.Parcelable; import android.os.SystemClock; diff --git a/core/java/android/bluetooth/BluetoothHearingAid.java b/core/java/android/bluetooth/BluetoothHearingAid.java index a65162ad5d89..38498bc147b2 100644 --- a/core/java/android/bluetooth/BluetoothHearingAid.java +++ b/core/java/android/bluetooth/BluetoothHearingAid.java @@ -23,7 +23,7 @@ import android.annotation.RequiresPermission; import android.annotation.SdkConstant; import android.annotation.SdkConstant.SdkConstantType; import android.annotation.SystemApi; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; import android.os.Binder; import android.os.IBinder; diff --git a/core/java/android/bluetooth/BluetoothHidDevice.java b/core/java/android/bluetooth/BluetoothHidDevice.java index e9b0be2c4cd6..a923be62fbce 100644 --- a/core/java/android/bluetooth/BluetoothHidDevice.java +++ b/core/java/android/bluetooth/BluetoothHidDevice.java @@ -16,8 +16,12 @@ package android.bluetooth; +import android.Manifest; +import android.annotation.NonNull; +import android.annotation.RequiresPermission; import android.annotation.SdkConstant; import android.annotation.SdkConstant.SdkConstantType; +import android.annotation.SystemApi; import android.content.Context; import android.os.Binder; import android.os.IBinder; @@ -36,6 +40,7 @@ import java.util.concurrent.Executor; */ public final class BluetoothHidDevice implements BluetoothProfile { private static final String TAG = BluetoothHidDevice.class.getSimpleName(); + private static final boolean DBG = false; /** * Intent used to broadcast the change in connection state of the Input Host profile. @@ -682,4 +687,62 @@ public final class BluetoothHidDevice implements BluetoothProfile { return result; } + + /** + * Connects Hid Device if connectionPolicy is {@link BluetoothProfile#CONNECTION_POLICY_ALLOWED} + * and disconnects Hid device if connectionPolicy is + * {@link BluetoothProfile#CONNECTION_POLICY_FORBIDDEN}. + * + * <p> The device should already be paired. + * Connection policy can be one of: + * {@link BluetoothProfile#CONNECTION_POLICY_ALLOWED}, + * {@link BluetoothProfile#CONNECTION_POLICY_FORBIDDEN}, + * {@link BluetoothProfile#CONNECTION_POLICY_UNKNOWN} + * + * @param device Paired bluetooth device + * @param connectionPolicy determines whether hid device should be connected or disconnected + * @return true if hid device is connected or disconnected, false otherwise + * + * @hide + */ + @SystemApi + @RequiresPermission(Manifest.permission.BLUETOOTH_ADMIN) + public boolean setConnectionPolicy(@NonNull BluetoothDevice device, + @ConnectionPolicy int connectionPolicy) { + log("setConnectionPolicy(" + device + ", " + connectionPolicy + ")"); + try { + final IBluetoothHidDevice service = getService(); + if (service != null && isEnabled() + && isValidDevice(device)) { + if (connectionPolicy != BluetoothProfile.CONNECTION_POLICY_FORBIDDEN + && connectionPolicy != BluetoothProfile.CONNECTION_POLICY_ALLOWED) { + return false; + } + return service.setConnectionPolicy(device, connectionPolicy); + } + if (service == null) Log.w(TAG, "Proxy not attached to service"); + return false; + } catch (RemoteException e) { + Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable())); + return false; + } + } + + private boolean isEnabled() { + if (mAdapter.getState() == BluetoothAdapter.STATE_ON) return true; + return false; + } + + private boolean isValidDevice(BluetoothDevice device) { + if (device == null) return false; + + if (BluetoothAdapter.checkBluetoothAddress(device.getAddress())) return true; + return false; + } + + private static void log(String msg) { + if (DBG) { + Log.d(TAG, msg); + } + } } diff --git a/core/java/android/bluetooth/BluetoothMap.java b/core/java/android/bluetooth/BluetoothMap.java index 979dfd4e3ba5..467470674286 100644 --- a/core/java/android/bluetooth/BluetoothMap.java +++ b/core/java/android/bluetooth/BluetoothMap.java @@ -17,9 +17,12 @@ package android.bluetooth; import android.Manifest; +import android.annotation.NonNull; +import android.annotation.Nullable; import android.annotation.RequiresPermission; +import android.annotation.SuppressLint; import android.annotation.SystemApi; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; import android.os.Binder; import android.os.IBinder; @@ -35,21 +38,35 @@ import java.util.List; * * @hide */ +@SystemApi public final class BluetoothMap implements BluetoothProfile { private static final String TAG = "BluetoothMap"; private static final boolean DBG = true; private static final boolean VDBG = false; + /** @hide */ + @SuppressLint("ActionValue") + @SystemApi public static final String ACTION_CONNECTION_STATE_CHANGED = "android.bluetooth.map.profile.action.CONNECTION_STATE_CHANGED"; - /** There was an error trying to obtain the state */ + /** + * There was an error trying to obtain the state + * + * @hide + */ public static final int STATE_ERROR = -1; + /** @hide */ public static final int RESULT_FAILURE = 0; + /** @hide */ public static final int RESULT_SUCCESS = 1; - /** Connection canceled before completion. */ + /** + * Connection canceled before completion. + * + * @hide + */ public static final int RESULT_CANCELED = 2; private BluetoothAdapter mAdapter; @@ -71,6 +88,7 @@ public final class BluetoothMap implements BluetoothProfile { mProfileConnector.connect(context, listener); } + @SuppressLint("GenericException") protected void finalize() throws Throwable { try { close(); @@ -84,6 +102,8 @@ public final class BluetoothMap implements BluetoothProfile { * Other public functions of BluetoothMap will return default error * results once close() has been called. Multiple invocations of close() * are ok. + * + * @hide */ public synchronized void close() { mProfileConnector.disconnect(); @@ -98,6 +118,8 @@ public final class BluetoothMap implements BluetoothProfile { * * @return One of the STATE_ return codes, or STATE_ERROR if this proxy object is currently not * connected to the Map service. + * + * @hide */ public int getState() { if (VDBG) log("getState()"); @@ -120,6 +142,8 @@ public final class BluetoothMap implements BluetoothProfile { * * @return The remote Bluetooth device, or null if not in connected or connecting state, or if * this proxy object is not connected to the Map service. + * + * @hide */ public BluetoothDevice getClient() { if (VDBG) log("getClient()"); @@ -141,6 +165,8 @@ public final class BluetoothMap implements BluetoothProfile { * Returns true if the specified Bluetooth device is connected. * Returns false if not connected, or if this proxy object is not * currently connected to the Map service. + * + * @hide */ public boolean isConnected(BluetoothDevice device) { if (VDBG) log("isConnected(" + device + ")"); @@ -161,6 +187,8 @@ public final class BluetoothMap implements BluetoothProfile { /** * Initiate connection. Initiation of outgoing connections is not * supported for MAP server. + * + * @hide */ public boolean connect(BluetoothDevice device) { if (DBG) log("connect(" + device + ")" + "not supported for MAPS"); @@ -172,6 +200,8 @@ public final class BluetoothMap implements BluetoothProfile { * * @param device Remote Bluetooth Device * @return false on error, true otherwise + * + * @hide */ @UnsupportedAppUsage public boolean disconnect(BluetoothDevice device) { @@ -196,6 +226,8 @@ public final class BluetoothMap implements BluetoothProfile { * devices. It tries to err on the side of false positives. * * @return True if this device might support Map. + * + * @hide */ public static boolean doesClassMatchSink(BluetoothClass btClass) { // TODO optimize the rule @@ -214,8 +246,11 @@ public final class BluetoothMap implements BluetoothProfile { * Get the list of connected devices. Currently at most one. * * @return list of connected devices + * + * @hide */ - public List<BluetoothDevice> getConnectedDevices() { + @SystemApi + public @NonNull List<BluetoothDevice> getConnectedDevices() { if (DBG) log("getConnectedDevices()"); final IBluetoothMap service = getService(); if (service != null && isEnabled()) { @@ -234,6 +269,8 @@ public final class BluetoothMap implements BluetoothProfile { * Get the list of devices matching specified states. Currently at most one. * * @return list of matching devices + * + * @hide */ public List<BluetoothDevice> getDevicesMatchingConnectionStates(int[] states) { if (DBG) log("getDevicesMatchingStates()"); @@ -254,6 +291,8 @@ public final class BluetoothMap implements BluetoothProfile { * Get connection state of device * * @return device connection state + * + * @hide */ public int getConnectionState(BluetoothDevice device) { if (DBG) log("getConnectionState(" + device + ")"); @@ -301,7 +340,7 @@ public final class BluetoothMap implements BluetoothProfile { */ @SystemApi @RequiresPermission(Manifest.permission.BLUETOOTH_ADMIN) - public boolean setConnectionPolicy(BluetoothDevice device, int connectionPolicy) { + public boolean setConnectionPolicy(@Nullable BluetoothDevice device, int connectionPolicy) { if (DBG) log("setConnectionPolicy(" + device + ", " + connectionPolicy + ")"); final IBluetoothMap service = getService(); if (service != null && isEnabled() && isValidDevice(device)) { @@ -349,7 +388,7 @@ public final class BluetoothMap implements BluetoothProfile { */ @SystemApi @RequiresPermission(Manifest.permission.BLUETOOTH) - public int getConnectionPolicy(BluetoothDevice device) { + public int getConnectionPolicy(@Nullable BluetoothDevice device) { if (VDBG) log("getConnectionPolicy(" + device + ")"); final IBluetoothMap service = getService(); if (service != null && isEnabled() && isValidDevice(device)) { diff --git a/core/java/android/bluetooth/BluetoothMapClient.java b/core/java/android/bluetooth/BluetoothMapClient.java index 0ec473c85adc..0aa5aac5d8f6 100644 --- a/core/java/android/bluetooth/BluetoothMapClient.java +++ b/core/java/android/bluetooth/BluetoothMapClient.java @@ -19,8 +19,8 @@ package android.bluetooth; import android.Manifest; import android.annotation.RequiresPermission; import android.annotation.SystemApi; -import android.annotation.UnsupportedAppUsage; import android.app.PendingIntent; +import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; import android.net.Uri; import android.os.Binder; diff --git a/core/java/android/bluetooth/BluetoothPan.java b/core/java/android/bluetooth/BluetoothPan.java index 4e9762737c07..024bb06098ab 100644 --- a/core/java/android/bluetooth/BluetoothPan.java +++ b/core/java/android/bluetooth/BluetoothPan.java @@ -16,14 +16,16 @@ package android.bluetooth; +import android.Manifest; 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.SuppressLint; import android.annotation.SystemApi; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; import android.os.Binder; import android.os.IBinder; @@ -256,6 +258,41 @@ public final class BluetoothPan implements BluetoothProfile { } /** + * Set connection policy of the profile + * + * <p> The device should already be paired. + * Connection policy can be one of {@link #CONNECTION_POLICY_ALLOWED}, + * {@link #CONNECTION_POLICY_FORBIDDEN}, {@link #CONNECTION_POLICY_UNKNOWN} + * + * @param device Paired bluetooth device + * @param connectionPolicy is the connection policy to set to for this profile + * @return true if connectionPolicy is set, false on error + * @hide + */ + @SystemApi + @RequiresPermission(Manifest.permission.BLUETOOTH_ADMIN) + public boolean setConnectionPolicy(@NonNull BluetoothDevice device, + @ConnectionPolicy int connectionPolicy) { + if (DBG) log("setConnectionPolicy(" + device + ", " + connectionPolicy + ")"); + try { + final IBluetoothPan service = getService(); + if (service != null && isEnabled() + && isValidDevice(device)) { + if (connectionPolicy != BluetoothProfile.CONNECTION_POLICY_FORBIDDEN + && connectionPolicy != BluetoothProfile.CONNECTION_POLICY_ALLOWED) { + return false; + } + return service.setConnectionPolicy(device, connectionPolicy); + } + if (service == null) Log.w(TAG, "Proxy not attached to service"); + return false; + } catch (RemoteException e) { + Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable())); + return false; + } + } + + /** * {@inheritDoc} */ @Override diff --git a/core/java/android/bluetooth/BluetoothPbap.java b/core/java/android/bluetooth/BluetoothPbap.java index 291015070385..e07ca521e77d 100644 --- a/core/java/android/bluetooth/BluetoothPbap.java +++ b/core/java/android/bluetooth/BluetoothPbap.java @@ -23,7 +23,7 @@ import android.annotation.RequiresPermission; import android.annotation.SdkConstant; import android.annotation.SuppressLint; import android.annotation.SystemApi; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.ComponentName; import android.content.Context; import android.content.Intent; @@ -274,15 +274,15 @@ public class BluetoothPbap implements BluetoothProfile { } /** - * Pbap does not store connection policy, so this function only disconnects Pbap if - * connectionPolicy is CONNECTION_POLICY_FORBIDDEN. + * Pbap does not store connection policy, so this function only disconnects pbap if + * connectionPolicy is {@link #CONNECTION_POLICY_FORBIDDEN}. * * <p> The device should already be paired. * Connection policy can be one of {@link #CONNECTION_POLICY_ALLOWED}, * {@link #CONNECTION_POLICY_FORBIDDEN}, {@link #CONNECTION_POLICY_UNKNOWN} * * @param device Paired bluetooth device - * @param connectionPolicy is the connection policy to set to for this profile + * @param connectionPolicy determines whether to disconnect the device * @return true if pbap is successfully disconnected, false otherwise * @hide */ diff --git a/core/java/android/bluetooth/BluetoothProfile.java b/core/java/android/bluetooth/BluetoothProfile.java index 097a3677ac4b..638e6de06be7 100644 --- a/core/java/android/bluetooth/BluetoothProfile.java +++ b/core/java/android/bluetooth/BluetoothProfile.java @@ -22,7 +22,7 @@ import android.annotation.IntDef; import android.annotation.RequiresPermission; import android.annotation.SuppressLint; import android.annotation.SystemApi; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; diff --git a/core/java/android/bluetooth/BluetoothSap.java b/core/java/android/bluetooth/BluetoothSap.java index 9b4dabcdcfdc..8bf1b588c89a 100644 --- a/core/java/android/bluetooth/BluetoothSap.java +++ b/core/java/android/bluetooth/BluetoothSap.java @@ -19,7 +19,7 @@ package android.bluetooth; import android.Manifest; import android.annotation.RequiresPermission; import android.annotation.SystemApi; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; import android.os.Binder; import android.os.IBinder; diff --git a/core/java/android/bluetooth/BluetoothServerSocket.java b/core/java/android/bluetooth/BluetoothServerSocket.java index 3a23808f3617..88c186c88aaf 100644 --- a/core/java/android/bluetooth/BluetoothServerSocket.java +++ b/core/java/android/bluetooth/BluetoothServerSocket.java @@ -16,7 +16,7 @@ package android.bluetooth; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.os.Handler; import android.os.ParcelUuid; import android.util.Log; diff --git a/core/java/android/bluetooth/BluetoothSocket.java b/core/java/android/bluetooth/BluetoothSocket.java index 760166bfcc5d..f77436965537 100644 --- a/core/java/android/bluetooth/BluetoothSocket.java +++ b/core/java/android/bluetooth/BluetoothSocket.java @@ -16,7 +16,7 @@ package android.bluetooth; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.net.LocalSocket; import android.os.ParcelFileDescriptor; import android.os.ParcelUuid; diff --git a/core/java/android/bluetooth/BluetoothUuid.java b/core/java/android/bluetooth/BluetoothUuid.java index 7e96c23af4b9..e274af1b5c5d 100644 --- a/core/java/android/bluetooth/BluetoothUuid.java +++ b/core/java/android/bluetooth/BluetoothUuid.java @@ -19,7 +19,7 @@ package android.bluetooth; import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.SystemApi; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.os.ParcelUuid; import java.nio.ByteBuffer; diff --git a/core/java/android/bluetooth/le/ScanRecord.java b/core/java/android/bluetooth/le/ScanRecord.java index 97e3f5221c72..c0c1aa1634ff 100644 --- a/core/java/android/bluetooth/le/ScanRecord.java +++ b/core/java/android/bluetooth/le/ScanRecord.java @@ -18,8 +18,8 @@ package android.bluetooth.le; import android.annotation.NonNull; import android.annotation.Nullable; -import android.annotation.UnsupportedAppUsage; import android.bluetooth.BluetoothUuid; +import android.compat.annotation.UnsupportedAppUsage; import android.os.ParcelUuid; import android.util.ArrayMap; import android.util.Log; diff --git a/core/java/android/companion/AssociationRequest.java b/core/java/android/companion/AssociationRequest.java index e4114c66bac7..489d125a1bf6 100644 --- a/core/java/android/companion/AssociationRequest.java +++ b/core/java/android/companion/AssociationRequest.java @@ -18,7 +18,7 @@ package android.companion; import android.annotation.NonNull; import android.annotation.Nullable; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.os.Parcel; import android.os.Parcelable; import android.provider.OneTimeUseBuilder; diff --git a/core/java/android/companion/BluetoothDeviceFilter.java b/core/java/android/companion/BluetoothDeviceFilter.java index fe0123c56e57..2649fbee4246 100644 --- a/core/java/android/companion/BluetoothDeviceFilter.java +++ b/core/java/android/companion/BluetoothDeviceFilter.java @@ -25,8 +25,8 @@ import static android.companion.BluetoothDeviceFilterUtils.patternToString; import android.annotation.NonNull; import android.annotation.Nullable; -import android.annotation.UnsupportedAppUsage; import android.bluetooth.BluetoothDevice; +import android.compat.annotation.UnsupportedAppUsage; import android.os.Parcel; import android.os.ParcelUuid; import android.provider.OneTimeUseBuilder; diff --git a/core/java/android/companion/BluetoothDeviceFilterUtils.java b/core/java/android/companion/BluetoothDeviceFilterUtils.java index 0f67f6b50251..24be45cb20fe 100644 --- a/core/java/android/companion/BluetoothDeviceFilterUtils.java +++ b/core/java/android/companion/BluetoothDeviceFilterUtils.java @@ -21,9 +21,9 @@ import static android.text.TextUtils.firstNotEmpty; import android.annotation.NonNull; import android.annotation.Nullable; -import android.annotation.UnsupportedAppUsage; import android.bluetooth.BluetoothDevice; import android.bluetooth.le.ScanFilter; +import android.compat.annotation.UnsupportedAppUsage; import android.net.wifi.ScanResult; import android.os.ParcelUuid; import android.os.Parcelable; diff --git a/core/java/android/companion/BluetoothLeDeviceFilter.java b/core/java/android/companion/BluetoothLeDeviceFilter.java index 2701619112c5..730bc60e331c 100644 --- a/core/java/android/companion/BluetoothLeDeviceFilter.java +++ b/core/java/android/companion/BluetoothLeDeviceFilter.java @@ -25,11 +25,11 @@ import static com.android.internal.util.Preconditions.checkState; import android.annotation.NonNull; import android.annotation.Nullable; -import android.annotation.UnsupportedAppUsage; import android.bluetooth.BluetoothDevice; import android.bluetooth.le.ScanFilter; import android.bluetooth.le.ScanRecord; import android.bluetooth.le.ScanResult; +import android.compat.annotation.UnsupportedAppUsage; import android.os.Parcel; import android.provider.OneTimeUseBuilder; import android.text.TextUtils; diff --git a/core/java/android/companion/DeviceFilter.java b/core/java/android/companion/DeviceFilter.java index dc7cf82613e6..c9cb072904b4 100644 --- a/core/java/android/companion/DeviceFilter.java +++ b/core/java/android/companion/DeviceFilter.java @@ -19,7 +19,7 @@ package android.companion; import android.annotation.IntDef; import android.annotation.Nullable; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.os.Parcelable; import java.lang.annotation.Retention; diff --git a/core/java/android/content/AsyncTaskLoader.java b/core/java/android/content/AsyncTaskLoader.java index bb7d5e49ccfb..14c3387d47dc 100644 --- a/core/java/android/content/AsyncTaskLoader.java +++ b/core/java/android/content/AsyncTaskLoader.java @@ -16,7 +16,7 @@ package android.content; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.os.AsyncTask; import android.os.Handler; import android.os.OperationCanceledException; diff --git a/core/java/android/content/BroadcastReceiver.java b/core/java/android/content/BroadcastReceiver.java index f73a376dfc69..1d4d30d87560 100644 --- a/core/java/android/content/BroadcastReceiver.java +++ b/core/java/android/content/BroadcastReceiver.java @@ -18,11 +18,11 @@ package android.content; import android.annotation.NonNull; import android.annotation.SystemApi; -import android.annotation.UnsupportedAppUsage; import android.app.ActivityManager; import android.app.ActivityThread; import android.app.IActivityManager; import android.app.QueuedWork; +import android.compat.annotation.UnsupportedAppUsage; import android.os.Build; import android.os.Bundle; import android.os.IBinder; diff --git a/core/java/android/content/ClipData.java b/core/java/android/content/ClipData.java index 88e2c220bb8d..5c6728348893 100644 --- a/core/java/android/content/ClipData.java +++ b/core/java/android/content/ClipData.java @@ -21,7 +21,7 @@ import static android.content.ContentResolver.SCHEME_ANDROID_RESOURCE; import static android.content.ContentResolver.SCHEME_CONTENT; import static android.content.ContentResolver.SCHEME_FILE; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.res.AssetFileDescriptor; import android.graphics.Bitmap; import android.net.Uri; diff --git a/core/java/android/content/ClipboardManager.java b/core/java/android/content/ClipboardManager.java index dc1c700f5d08..dec9589981c6 100644 --- a/core/java/android/content/ClipboardManager.java +++ b/core/java/android/content/ClipboardManager.java @@ -19,7 +19,7 @@ package android.content; import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.SystemService; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.os.Handler; import android.os.RemoteException; import android.os.ServiceManager; diff --git a/core/java/android/content/ComponentName.java b/core/java/android/content/ComponentName.java index 18147b572125..e955c2df2881 100644 --- a/core/java/android/content/ComponentName.java +++ b/core/java/android/content/ComponentName.java @@ -18,7 +18,7 @@ package android.content; import android.annotation.NonNull; import android.annotation.Nullable; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.os.Parcel; import android.os.Parcelable; import android.text.TextUtils; diff --git a/core/java/android/content/ContentProvider.java b/core/java/android/content/ContentProvider.java index 7cdd2683905f..137faea5121f 100644 --- a/core/java/android/content/ContentProvider.java +++ b/core/java/android/content/ContentProvider.java @@ -26,8 +26,8 @@ import static android.os.Trace.TRACE_TAG_DATABASE; import android.annotation.NonNull; import android.annotation.Nullable; -import android.annotation.UnsupportedAppUsage; import android.app.AppOpsManager; +import android.compat.annotation.UnsupportedAppUsage; import android.content.pm.PathPermission; import android.content.pm.ProviderInfo; import android.content.res.AssetFileDescriptor; diff --git a/core/java/android/content/ContentProviderClient.java b/core/java/android/content/ContentProviderClient.java index 93bf5188705c..db8aa40978b3 100644 --- a/core/java/android/content/ContentProviderClient.java +++ b/core/java/android/content/ContentProviderClient.java @@ -22,7 +22,7 @@ import android.annotation.Nullable; import android.annotation.RequiresPermission; import android.annotation.SystemApi; import android.annotation.TestApi; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.res.AssetFileDescriptor; import android.database.CrossProcessCursorWrapper; import android.database.Cursor; diff --git a/core/java/android/content/ContentProviderNative.java b/core/java/android/content/ContentProviderNative.java index 994833866f40..234f567f2ad2 100644 --- a/core/java/android/content/ContentProviderNative.java +++ b/core/java/android/content/ContentProviderNative.java @@ -17,7 +17,7 @@ package android.content; import android.annotation.Nullable; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.res.AssetFileDescriptor; import android.database.BulkCursorDescriptor; import android.database.BulkCursorToCursorAdaptor; diff --git a/core/java/android/content/ContentProviderOperation.java b/core/java/android/content/ContentProviderOperation.java index c201e4d2a129..e401f2aeb23a 100644 --- a/core/java/android/content/ContentProviderOperation.java +++ b/core/java/android/content/ContentProviderOperation.java @@ -16,7 +16,7 @@ package android.content; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.database.Cursor; import android.net.Uri; import android.os.Parcel; diff --git a/core/java/android/content/ContentResolver.java b/core/java/android/content/ContentResolver.java index 0a1bc85202ff..a50831fd0193 100644 --- a/core/java/android/content/ContentResolver.java +++ b/core/java/android/content/ContentResolver.java @@ -25,12 +25,12 @@ import android.annotation.Nullable; import android.annotation.RequiresPermission; import android.annotation.SystemApi; import android.annotation.TestApi; -import android.annotation.UnsupportedAppUsage; import android.annotation.UserIdInt; import android.app.ActivityManager; import android.app.ActivityThread; import android.app.AppGlobals; import android.app.UriGrantsManager; +import android.compat.annotation.UnsupportedAppUsage; import android.content.pm.PackageManager.NameNotFoundException; import android.content.res.AssetFileDescriptor; import android.content.res.Resources; diff --git a/core/java/android/content/ContentValues.java b/core/java/android/content/ContentValues.java index eafeed220050..76d37fcd2ce9 100644 --- a/core/java/android/content/ContentValues.java +++ b/core/java/android/content/ContentValues.java @@ -16,7 +16,7 @@ package android.content; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.os.Parcel; import android.os.Parcelable; import android.util.ArrayMap; diff --git a/core/java/android/content/Context.java b/core/java/android/content/Context.java index f3596411fb6b..f2f905126715 100644 --- a/core/java/android/content/Context.java +++ b/core/java/android/content/Context.java @@ -32,12 +32,12 @@ import android.annotation.StyleRes; import android.annotation.StyleableRes; import android.annotation.SystemApi; import android.annotation.TestApi; -import android.annotation.UnsupportedAppUsage; import android.annotation.UserIdInt; import android.app.ActivityManager; import android.app.IApplicationThread; import android.app.IServiceConnection; import android.app.VrManager; +import android.compat.annotation.UnsupportedAppUsage; import android.content.pm.ApplicationInfo; import android.content.pm.PackageManager; import android.content.res.AssetManager; @@ -3851,10 +3851,12 @@ public abstract class Context { /** * Use with {@link android.os.ServiceManager.getService()} to retrieve a - * {@link NetworkStackClient} IBinder for communicating with the network stack + * {@link INetworkStackConnector} IBinder for communicating with the network stack * @hide * @see NetworkStackClient */ + @SystemApi + @TestApi public static final String NETWORK_STACK_SERVICE = "network_stack"; /** diff --git a/core/java/android/content/ContextWrapper.java b/core/java/android/content/ContextWrapper.java index 877557f4f590..72cc021b6ea4 100644 --- a/core/java/android/content/ContextWrapper.java +++ b/core/java/android/content/ContextWrapper.java @@ -21,9 +21,9 @@ import android.annotation.Nullable; import android.annotation.RequiresPermission; import android.annotation.SystemApi; import android.annotation.TestApi; -import android.annotation.UnsupportedAppUsage; import android.app.IApplicationThread; import android.app.IServiceConnection; +import android.compat.annotation.UnsupportedAppUsage; import android.content.pm.ApplicationInfo; import android.content.pm.PackageManager; import android.content.res.AssetManager; diff --git a/core/java/android/content/CursorEntityIterator.java b/core/java/android/content/CursorEntityIterator.java index 2c630d29621b..952366d1cd75 100644 --- a/core/java/android/content/CursorEntityIterator.java +++ b/core/java/android/content/CursorEntityIterator.java @@ -16,7 +16,7 @@ package android.content; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.database.Cursor; import android.os.RemoteException; diff --git a/core/java/android/content/CursorLoader.java b/core/java/android/content/CursorLoader.java index 4ccafab741d8..4ff5ccabbcb7 100644 --- a/core/java/android/content/CursorLoader.java +++ b/core/java/android/content/CursorLoader.java @@ -16,7 +16,7 @@ package android.content; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.database.Cursor; import android.net.Uri; import android.os.CancellationSignal; diff --git a/core/java/android/content/Entity.java b/core/java/android/content/Entity.java index ff4f15006280..13137c48e7f2 100644 --- a/core/java/android/content/Entity.java +++ b/core/java/android/content/Entity.java @@ -16,7 +16,7 @@ package android.content; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.net.Uri; import android.os.Build; diff --git a/core/java/android/content/IContentProvider.java b/core/java/android/content/IContentProvider.java index 0427c2f52415..92df7eea9216 100644 --- a/core/java/android/content/IContentProvider.java +++ b/core/java/android/content/IContentProvider.java @@ -17,7 +17,7 @@ package android.content; import android.annotation.Nullable; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.res.AssetFileDescriptor; import android.database.Cursor; import android.net.Uri; diff --git a/core/java/android/content/Intent.java b/core/java/android/content/Intent.java index a6867ff209e4..9c7bf1f7c996 100644 --- a/core/java/android/content/Intent.java +++ b/core/java/android/content/Intent.java @@ -28,8 +28,8 @@ import android.annotation.SdkConstant; import android.annotation.SdkConstant.SdkConstantType; import android.annotation.SystemApi; import android.annotation.TestApi; -import android.annotation.UnsupportedAppUsage; import android.app.AppGlobals; +import android.compat.annotation.UnsupportedAppUsage; import android.content.pm.ActivityInfo; import android.content.pm.ApplicationInfo; import android.content.pm.ComponentInfo; diff --git a/core/java/android/content/IntentFilter.java b/core/java/android/content/IntentFilter.java index 099dea29eaf7..4d0ecff38806 100644 --- a/core/java/android/content/IntentFilter.java +++ b/core/java/android/content/IntentFilter.java @@ -18,7 +18,7 @@ package android.content; import android.annotation.IntDef; import android.annotation.SystemApi; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.net.Uri; import android.os.Build; import android.os.Parcel; diff --git a/core/java/android/content/IntentSender.java b/core/java/android/content/IntentSender.java index ec0bac486c65..f40dc298d560 100644 --- a/core/java/android/content/IntentSender.java +++ b/core/java/android/content/IntentSender.java @@ -16,14 +16,14 @@ package android.content; -import android.annotation.UnsupportedAppUsage; import android.app.ActivityManager; +import android.compat.annotation.UnsupportedAppUsage; import android.os.Bundle; -import android.os.RemoteException; import android.os.Handler; import android.os.IBinder; import android.os.Parcel; import android.os.Parcelable; +import android.os.RemoteException; import android.os.UserHandle; import android.util.AndroidException; diff --git a/core/java/android/content/RestrictionsManager.java b/core/java/android/content/RestrictionsManager.java index bbdab048207b..885eb708d92c 100644 --- a/core/java/android/content/RestrictionsManager.java +++ b/core/java/android/content/RestrictionsManager.java @@ -17,9 +17,9 @@ package android.content; import android.annotation.SystemService; -import android.annotation.UnsupportedAppUsage; import android.app.Activity; import android.app.admin.DevicePolicyManager; +import android.compat.annotation.UnsupportedAppUsage; import android.content.pm.ApplicationInfo; import android.content.pm.PackageManager; import android.content.pm.PackageManager.NameNotFoundException; diff --git a/core/java/android/content/SearchRecentSuggestionsProvider.java b/core/java/android/content/SearchRecentSuggestionsProvider.java index 8ee7b9e403b4..fc3ddf6148de 100644 --- a/core/java/android/content/SearchRecentSuggestionsProvider.java +++ b/core/java/android/content/SearchRecentSuggestionsProvider.java @@ -16,8 +16,8 @@ package android.content; -import android.annotation.UnsupportedAppUsage; import android.app.SearchManager; +import android.compat.annotation.UnsupportedAppUsage; import android.database.Cursor; import android.database.sqlite.SQLiteDatabase; import android.database.sqlite.SQLiteOpenHelper; diff --git a/core/java/android/content/SyncAdapterType.java b/core/java/android/content/SyncAdapterType.java index 8c8fe5a06888..7bcdbfd1085c 100644 --- a/core/java/android/content/SyncAdapterType.java +++ b/core/java/android/content/SyncAdapterType.java @@ -17,11 +17,11 @@ package android.content; import android.annotation.Nullable; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.os.Build; -import android.text.TextUtils; -import android.os.Parcelable; import android.os.Parcel; +import android.os.Parcelable; +import android.text.TextUtils; /** * Value type that represents a SyncAdapterType. This object overrides {@link #equals} and diff --git a/core/java/android/content/SyncAdaptersCache.java b/core/java/android/content/SyncAdaptersCache.java index d4e52175f9b5..58445a7f9242 100644 --- a/core/java/android/content/SyncAdaptersCache.java +++ b/core/java/android/content/SyncAdaptersCache.java @@ -16,7 +16,7 @@ package android.content; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.pm.RegisteredServicesCache; import android.content.pm.XmlSerializerAndParser; import android.content.res.Resources; @@ -29,8 +29,8 @@ import android.util.SparseArray; import com.android.internal.annotations.GuardedBy; import org.xmlpull.v1.XmlPullParser; -import org.xmlpull.v1.XmlSerializer; import org.xmlpull.v1.XmlPullParserException; +import org.xmlpull.v1.XmlSerializer; import java.io.IOException; import java.util.ArrayList; diff --git a/core/java/android/content/SyncContext.java b/core/java/android/content/SyncContext.java index 50d1dc96fc0a..4a9f66c474db 100644 --- a/core/java/android/content/SyncContext.java +++ b/core/java/android/content/SyncContext.java @@ -16,10 +16,10 @@ package android.content; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; +import android.os.IBinder; import android.os.RemoteException; import android.os.SystemClock; -import android.os.IBinder; public class SyncContext { private ISyncContext mSyncContext; diff --git a/core/java/android/content/SyncInfo.java b/core/java/android/content/SyncInfo.java index d3f2eed8126f..017a92b1e8bb 100644 --- a/core/java/android/content/SyncInfo.java +++ b/core/java/android/content/SyncInfo.java @@ -17,7 +17,7 @@ package android.content; import android.accounts.Account; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.os.Build; import android.os.Parcel; import android.os.Parcelable; diff --git a/core/java/android/content/SyncRequest.java b/core/java/android/content/SyncRequest.java index 5f1f18016e0d..9e568a40e0ee 100644 --- a/core/java/android/content/SyncRequest.java +++ b/core/java/android/content/SyncRequest.java @@ -17,7 +17,7 @@ package android.content; import android.accounts.Account; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.os.Build; import android.os.Bundle; import android.os.Parcel; diff --git a/core/java/android/content/SyncStatusInfo.java b/core/java/android/content/SyncStatusInfo.java index 3f6451577258..620fdb7deec4 100644 --- a/core/java/android/content/SyncStatusInfo.java +++ b/core/java/android/content/SyncStatusInfo.java @@ -16,7 +16,7 @@ package android.content; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.os.Parcel; import android.os.Parcelable; import android.util.Log; diff --git a/core/java/android/content/UndoManager.java b/core/java/android/content/UndoManager.java index f9c58d624a2f..ed9cd86927ae 100644 --- a/core/java/android/content/UndoManager.java +++ b/core/java/android/content/UndoManager.java @@ -16,7 +16,7 @@ package android.content; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.os.Parcel; import android.text.TextUtils; import android.util.ArrayMap; diff --git a/core/java/android/content/UndoOperation.java b/core/java/android/content/UndoOperation.java index a425486e5739..235d72123ff6 100644 --- a/core/java/android/content/UndoOperation.java +++ b/core/java/android/content/UndoOperation.java @@ -16,7 +16,7 @@ package android.content; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.os.Parcel; import android.os.Parcelable; diff --git a/core/java/android/content/UriMatcher.java b/core/java/android/content/UriMatcher.java index 208bc01aef9d..7fa48f0e9a78 100644 --- a/core/java/android/content/UriMatcher.java +++ b/core/java/android/content/UriMatcher.java @@ -16,7 +16,7 @@ package android.content; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.net.Uri; import java.util.ArrayList; diff --git a/core/java/android/content/om/OverlayInfo.java b/core/java/android/content/om/OverlayInfo.java index 1a78f793c008..a3487be3cb81 100644 --- a/core/java/android/content/om/OverlayInfo.java +++ b/core/java/android/content/om/OverlayInfo.java @@ -20,8 +20,8 @@ import android.annotation.IntDef; import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.SystemApi; -import android.annotation.UnsupportedAppUsage; import android.annotation.UserIdInt; +import android.compat.annotation.UnsupportedAppUsage; import android.os.Parcel; import android.os.Parcelable; diff --git a/core/java/android/content/pm/ActivityInfo.java b/core/java/android/content/pm/ActivityInfo.java index 95e5f6b322ad..43dd1f451ab7 100644 --- a/core/java/android/content/pm/ActivityInfo.java +++ b/core/java/android/content/pm/ActivityInfo.java @@ -18,7 +18,7 @@ package android.content.pm; import android.annotation.IntDef; import android.annotation.TestApi; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.ComponentName; import android.content.Intent; import android.content.res.Configuration; diff --git a/core/java/android/content/pm/ApplicationInfo.java b/core/java/android/content/pm/ApplicationInfo.java index 0ea1845b6c2d..49d22015c432 100644 --- a/core/java/android/content/pm/ApplicationInfo.java +++ b/core/java/android/content/pm/ApplicationInfo.java @@ -22,7 +22,7 @@ import android.annotation.IntDef; import android.annotation.Nullable; import android.annotation.SystemApi; import android.annotation.TestApi; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; import android.content.pm.PackageManager.NameNotFoundException; import android.content.res.Resources; diff --git a/core/java/android/content/pm/BaseParceledListSlice.java b/core/java/android/content/pm/BaseParceledListSlice.java index 4178309450bd..5d1a08cf5de0 100644 --- a/core/java/android/content/pm/BaseParceledListSlice.java +++ b/core/java/android/content/pm/BaseParceledListSlice.java @@ -16,7 +16,7 @@ package android.content.pm; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.os.Binder; import android.os.IBinder; import android.os.Parcel; diff --git a/core/java/android/content/pm/ComponentInfo.java b/core/java/android/content/pm/ComponentInfo.java index 29612c25d0cd..988b280d78ef 100644 --- a/core/java/android/content/pm/ComponentInfo.java +++ b/core/java/android/content/pm/ComponentInfo.java @@ -16,7 +16,7 @@ package android.content.pm; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.ComponentName; import android.graphics.drawable.Drawable; import android.os.Parcel; diff --git a/core/java/android/content/pm/LauncherActivityInfo.java b/core/java/android/content/pm/LauncherActivityInfo.java index 1451431b7852..67deb82f1fbb 100644 --- a/core/java/android/content/pm/LauncherActivityInfo.java +++ b/core/java/android/content/pm/LauncherActivityInfo.java @@ -16,7 +16,7 @@ package android.content.pm; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.ComponentName; import android.content.Context; import android.content.pm.PackageManager.NameNotFoundException; diff --git a/core/java/android/content/pm/LauncherApps.java b/core/java/android/content/pm/LauncherApps.java index 3933e81c732a..ac8eab786dcf 100644 --- a/core/java/android/content/pm/LauncherApps.java +++ b/core/java/android/content/pm/LauncherApps.java @@ -25,10 +25,10 @@ import android.annotation.SdkConstant.SdkConstantType; import android.annotation.SystemApi; import android.annotation.SystemService; import android.annotation.TestApi; -import android.annotation.UnsupportedAppUsage; import android.app.PendingIntent; import android.appwidget.AppWidgetManager; import android.appwidget.AppWidgetProviderInfo; +import android.compat.annotation.UnsupportedAppUsage; import android.content.ActivityNotFoundException; import android.content.ComponentName; import android.content.Context; diff --git a/core/java/android/content/pm/PackageInfo.java b/core/java/android/content/pm/PackageInfo.java index d6fb28f694fd..f4d4a8d8e1c5 100644 --- a/core/java/android/content/pm/PackageInfo.java +++ b/core/java/android/content/pm/PackageInfo.java @@ -17,7 +17,7 @@ package android.content.pm; import android.annotation.Nullable; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.os.Build; import android.os.Parcel; import android.os.Parcelable; diff --git a/core/java/android/content/pm/PackageInfoLite.java b/core/java/android/content/pm/PackageInfoLite.java index f5442ec48d19..6743a3f86944 100644 --- a/core/java/android/content/pm/PackageInfoLite.java +++ b/core/java/android/content/pm/PackageInfoLite.java @@ -16,7 +16,7 @@ package android.content.pm; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.os.Build; import android.os.Parcel; import android.os.Parcelable; diff --git a/core/java/android/content/pm/PackageInstaller.java b/core/java/android/content/pm/PackageInstaller.java index 1099d8bdc7dd..78db3d82ce93 100644 --- a/core/java/android/content/pm/PackageInstaller.java +++ b/core/java/android/content/pm/PackageInstaller.java @@ -26,9 +26,9 @@ import android.annotation.SdkConstant; import android.annotation.SdkConstant.SdkConstantType; import android.annotation.SystemApi; import android.annotation.TestApi; -import android.annotation.UnsupportedAppUsage; import android.app.ActivityManager; import android.app.AppGlobals; +import android.compat.annotation.UnsupportedAppUsage; import android.content.Intent; import android.content.IntentSender; import android.content.pm.PackageManager.DeleteFlags; diff --git a/core/java/android/content/pm/PackageManager.java b/core/java/android/content/pm/PackageManager.java index 81670cd0d2b8..0ae00fb68d84 100644 --- a/core/java/android/content/pm/PackageManager.java +++ b/core/java/android/content/pm/PackageManager.java @@ -29,7 +29,6 @@ import android.annotation.SdkConstant.SdkConstantType; import android.annotation.StringRes; import android.annotation.SystemApi; import android.annotation.TestApi; -import android.annotation.UnsupportedAppUsage; import android.annotation.UserIdInt; import android.annotation.XmlRes; import android.app.ActivityManager; @@ -38,6 +37,7 @@ import android.app.PackageDeleteObserver; import android.app.PackageInstallObserver; import android.app.admin.DevicePolicyManager; import android.app.usage.StorageStatsManager; +import android.compat.annotation.UnsupportedAppUsage; import android.content.ComponentName; import android.content.Context; import android.content.Intent; diff --git a/core/java/android/content/pm/PackageParser.java b/core/java/android/content/pm/PackageParser.java index 812ae93f0641..0e610169ffa6 100644 --- a/core/java/android/content/pm/PackageParser.java +++ b/core/java/android/content/pm/PackageParser.java @@ -47,11 +47,11 @@ import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.StringRes; import android.annotation.TestApi; -import android.annotation.UnsupportedAppUsage; import android.apex.ApexInfo; import android.app.ActivityTaskManager; import android.app.ActivityThread; import android.app.ResourcesManager; +import android.compat.annotation.UnsupportedAppUsage; import android.content.ComponentName; import android.content.Intent; import android.content.IntentFilter; diff --git a/core/java/android/content/pm/PackageStats.java b/core/java/android/content/pm/PackageStats.java index b0fecfac2471..7c1252737f09 100644 --- a/core/java/android/content/pm/PackageStats.java +++ b/core/java/android/content/pm/PackageStats.java @@ -16,8 +16,8 @@ package android.content.pm; -import android.annotation.UnsupportedAppUsage; import android.app.usage.StorageStatsManager; +import android.compat.annotation.UnsupportedAppUsage; import android.os.Build; import android.os.Parcel; import android.os.Parcelable; diff --git a/core/java/android/content/pm/PackageUserState.java b/core/java/android/content/pm/PackageUserState.java index 249b6919fc28..d1e113293251 100644 --- a/core/java/android/content/pm/PackageUserState.java +++ b/core/java/android/content/pm/PackageUserState.java @@ -27,7 +27,7 @@ import static android.content.pm.PackageManager.MATCH_DISABLED_COMPONENTS; import static android.content.pm.PackageManager.MATCH_DISABLED_UNTIL_USED_COMPONENTS; import static android.content.pm.PackageManager.MATCH_SYSTEM_ONLY; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.os.BaseBundle; import android.os.Debug; import android.os.PersistableBundle; diff --git a/core/java/android/content/pm/ParceledListSlice.java b/core/java/android/content/pm/ParceledListSlice.java index dccc52494f59..73119e05095b 100644 --- a/core/java/android/content/pm/ParceledListSlice.java +++ b/core/java/android/content/pm/ParceledListSlice.java @@ -16,7 +16,7 @@ package android.content.pm; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.os.Build; import android.os.Parcel; import android.os.Parcelable; diff --git a/core/java/android/content/pm/PermissionInfo.java b/core/java/android/content/pm/PermissionInfo.java index c77c53f387e2..89a1c6ad9241 100644 --- a/core/java/android/content/pm/PermissionInfo.java +++ b/core/java/android/content/pm/PermissionInfo.java @@ -22,7 +22,7 @@ import android.annotation.Nullable; import android.annotation.StringRes; import android.annotation.SystemApi; import android.annotation.TestApi; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.os.Parcel; import android.os.Parcelable; import android.text.TextUtils; diff --git a/core/java/android/content/pm/RegisteredServicesCache.java b/core/java/android/content/pm/RegisteredServicesCache.java index 23fbefb73c50..bd909c7a3f59 100644 --- a/core/java/android/content/pm/RegisteredServicesCache.java +++ b/core/java/android/content/pm/RegisteredServicesCache.java @@ -17,7 +17,7 @@ package android.content.pm; import android.Manifest; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.BroadcastReceiver; import android.content.ComponentName; import android.content.Context; @@ -43,11 +43,11 @@ import com.android.internal.annotations.VisibleForTesting; import com.android.internal.util.ArrayUtils; import com.android.internal.util.FastXmlSerializer; +import libcore.io.IoUtils; + import com.google.android.collect.Lists; import com.google.android.collect.Maps; -import libcore.io.IoUtils; - import org.xmlpull.v1.XmlPullParser; import org.xmlpull.v1.XmlPullParserException; import org.xmlpull.v1.XmlSerializer; diff --git a/core/java/android/content/pm/ResolveInfo.java b/core/java/android/content/pm/ResolveInfo.java index 1734182b3a9a..7755fe3051e0 100644 --- a/core/java/android/content/pm/ResolveInfo.java +++ b/core/java/android/content/pm/ResolveInfo.java @@ -17,7 +17,7 @@ package android.content.pm; import android.annotation.SystemApi; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.ComponentName; import android.content.IntentFilter; import android.graphics.drawable.Drawable; diff --git a/core/java/android/content/pm/ShortcutInfo.java b/core/java/android/content/pm/ShortcutInfo.java index 58aacc2c36c7..e14bcf6e5bed 100644 --- a/core/java/android/content/pm/ShortcutInfo.java +++ b/core/java/android/content/pm/ShortcutInfo.java @@ -20,11 +20,11 @@ import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.SystemApi; import android.annotation.TestApi; -import android.annotation.UnsupportedAppUsage; import android.annotation.UserIdInt; import android.app.Notification; import android.app.Person; import android.app.TaskStackBuilder; +import android.compat.annotation.UnsupportedAppUsage; import android.content.ComponentName; import android.content.Context; import android.content.Intent; diff --git a/core/java/android/content/pm/ShortcutManager.java b/core/java/android/content/pm/ShortcutManager.java index f85179942938..dde8865467a1 100644 --- a/core/java/android/content/pm/ShortcutManager.java +++ b/core/java/android/content/pm/ShortcutManager.java @@ -22,9 +22,9 @@ import android.annotation.RequiresPermission; import android.annotation.SystemApi; import android.annotation.SystemService; import android.annotation.TestApi; -import android.annotation.UnsupportedAppUsage; import android.annotation.UserIdInt; import android.app.usage.UsageStatsManager; +import android.compat.annotation.UnsupportedAppUsage; import android.content.ComponentName; import android.content.Context; import android.content.Intent; diff --git a/core/java/android/content/pm/Signature.java b/core/java/android/content/pm/Signature.java index 25a4dca4d815..3b84ae775ad1 100644 --- a/core/java/android/content/pm/Signature.java +++ b/core/java/android/content/pm/Signature.java @@ -16,7 +16,7 @@ package android.content.pm; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.os.Parcel; import android.os.Parcelable; diff --git a/core/java/android/content/pm/UserInfo.java b/core/java/android/content/pm/UserInfo.java index 2b1b32ed3df2..caf095884db2 100644 --- a/core/java/android/content/pm/UserInfo.java +++ b/core/java/android/content/pm/UserInfo.java @@ -16,10 +16,9 @@ package android.content.pm; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.os.Parcel; import android.os.Parcelable; -import android.os.SystemProperties; import android.os.UserHandle; import android.os.UserManager; diff --git a/core/java/android/content/pm/VerifierInfo.java b/core/java/android/content/pm/VerifierInfo.java index 224ca628cf27..5f8855572ef0 100644 --- a/core/java/android/content/pm/VerifierInfo.java +++ b/core/java/android/content/pm/VerifierInfo.java @@ -16,7 +16,7 @@ package android.content.pm; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.os.Parcel; import android.os.Parcelable; diff --git a/core/java/android/content/pm/XmlSerializerAndParser.java b/core/java/android/content/pm/XmlSerializerAndParser.java index 6d24800edb07..5dce83902f78 100644 --- a/core/java/android/content/pm/XmlSerializerAndParser.java +++ b/core/java/android/content/pm/XmlSerializerAndParser.java @@ -16,11 +16,12 @@ package android.content.pm; -import org.xmlpull.v1.XmlSerializer; +import android.compat.annotation.UnsupportedAppUsage; + import org.xmlpull.v1.XmlPullParser; import org.xmlpull.v1.XmlPullParserException; +import org.xmlpull.v1.XmlSerializer; -import android.annotation.UnsupportedAppUsage; import java.io.IOException; /** @hide */ diff --git a/core/java/android/content/res/ApkAssets.java b/core/java/android/content/res/ApkAssets.java index 69462ab99483..baa3e849a194 100644 --- a/core/java/android/content/res/ApkAssets.java +++ b/core/java/android/content/res/ApkAssets.java @@ -16,7 +16,7 @@ package android.content.res; import android.annotation.NonNull; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import com.android.internal.annotations.GuardedBy; import com.android.internal.util.Preconditions; diff --git a/core/java/android/content/res/AssetFileDescriptor.java b/core/java/android/content/res/AssetFileDescriptor.java index 2ba55798d665..e93ec00468f5 100644 --- a/core/java/android/content/res/AssetFileDescriptor.java +++ b/core/java/android/content/res/AssetFileDescriptor.java @@ -16,7 +16,7 @@ package android.content.res; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.os.Bundle; import android.os.Parcel; import android.os.ParcelFileDescriptor; diff --git a/core/java/android/content/res/AssetManager.java b/core/java/android/content/res/AssetManager.java index e5ef67b7d4bd..a70eff9fc810 100644 --- a/core/java/android/content/res/AssetManager.java +++ b/core/java/android/content/res/AssetManager.java @@ -24,7 +24,7 @@ import android.annotation.Nullable; import android.annotation.StringRes; import android.annotation.StyleRes; import android.annotation.TestApi; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.pm.ActivityInfo; import android.content.res.Configuration.NativeConfig; import android.os.ParcelFileDescriptor; diff --git a/core/java/android/content/res/ColorStateList.java b/core/java/android/content/res/ColorStateList.java index b5b097b33ef3..f23c802d98e2 100644 --- a/core/java/android/content/res/ColorStateList.java +++ b/core/java/android/content/res/ColorStateList.java @@ -19,9 +19,18 @@ package android.content.res; import android.annotation.ColorInt; import android.annotation.NonNull; import android.annotation.Nullable; +import android.compat.annotation.UnsupportedAppUsage; import android.content.pm.ActivityInfo.Config; import android.content.res.Resources.Theme; import android.graphics.Color; +import android.os.Parcel; +import android.os.Parcelable; +import android.util.AttributeSet; +import android.util.Log; +import android.util.MathUtils; +import android.util.SparseArray; +import android.util.StateSet; +import android.util.Xml; import com.android.internal.R; import com.android.internal.util.ArrayUtils; @@ -30,16 +39,6 @@ import com.android.internal.util.GrowingArrayUtils; import org.xmlpull.v1.XmlPullParser; import org.xmlpull.v1.XmlPullParserException; -import android.annotation.UnsupportedAppUsage; -import android.util.AttributeSet; -import android.util.Log; -import android.util.MathUtils; -import android.util.SparseArray; -import android.util.StateSet; -import android.util.Xml; -import android.os.Parcel; -import android.os.Parcelable; - import java.io.IOException; import java.lang.ref.WeakReference; import java.util.Arrays; diff --git a/core/java/android/content/res/CompatibilityInfo.java b/core/java/android/content/res/CompatibilityInfo.java index f3b7553577ca..c66c70a20729 100644 --- a/core/java/android/content/res/CompatibilityInfo.java +++ b/core/java/android/content/res/CompatibilityInfo.java @@ -16,7 +16,7 @@ package android.content.res; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.pm.ApplicationInfo; import android.graphics.Canvas; import android.graphics.PointF; diff --git a/core/java/android/content/res/Configuration.java b/core/java/android/content/res/Configuration.java index e40e56606080..cec6382cf559 100644 --- a/core/java/android/content/res/Configuration.java +++ b/core/java/android/content/res/Configuration.java @@ -45,8 +45,8 @@ import android.annotation.IntDef; import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.TestApi; -import android.annotation.UnsupportedAppUsage; import android.app.WindowConfiguration; +import android.compat.annotation.UnsupportedAppUsage; import android.content.LocaleProto; import android.content.pm.ActivityInfo; import android.content.pm.ActivityInfo.Config; diff --git a/core/java/android/content/res/ConfigurationBoundResourceCache.java b/core/java/android/content/res/ConfigurationBoundResourceCache.java index 848790f46734..5e10a5768358 100644 --- a/core/java/android/content/res/ConfigurationBoundResourceCache.java +++ b/core/java/android/content/res/ConfigurationBoundResourceCache.java @@ -16,7 +16,7 @@ package android.content.res; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.pm.ActivityInfo.Config; /** diff --git a/core/java/android/content/res/DrawableCache.java b/core/java/android/content/res/DrawableCache.java index 90604b8d536a..5497e61fa2e9 100644 --- a/core/java/android/content/res/DrawableCache.java +++ b/core/java/android/content/res/DrawableCache.java @@ -16,7 +16,7 @@ package android.content.res; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.graphics.drawable.Drawable; /** diff --git a/core/java/android/content/res/ObbInfo.java b/core/java/android/content/res/ObbInfo.java index 8af27ca825d0..c477abcea8ba 100644 --- a/core/java/android/content/res/ObbInfo.java +++ b/core/java/android/content/res/ObbInfo.java @@ -16,7 +16,7 @@ package android.content.res; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.os.Parcel; import android.os.Parcelable; diff --git a/core/java/android/content/res/Resources.java b/core/java/android/content/res/Resources.java index d7e4e1452cfe..4f6449ecd4eb 100644 --- a/core/java/android/content/res/Resources.java +++ b/core/java/android/content/res/Resources.java @@ -39,8 +39,8 @@ import android.annotation.RawRes; import android.annotation.StringRes; import android.annotation.StyleRes; import android.annotation.StyleableRes; -import android.annotation.UnsupportedAppUsage; import android.annotation.XmlRes; +import android.compat.annotation.UnsupportedAppUsage; import android.content.pm.ActivityInfo; import android.content.pm.ActivityInfo.Config; import android.graphics.Movie; diff --git a/core/java/android/content/res/ResourcesImpl.java b/core/java/android/content/res/ResourcesImpl.java index 794be9e202be..86ba0b61fbad 100644 --- a/core/java/android/content/res/ResourcesImpl.java +++ b/core/java/android/content/res/ResourcesImpl.java @@ -27,7 +27,7 @@ import android.annotation.PluralsRes; import android.annotation.RawRes; import android.annotation.StyleRes; import android.annotation.StyleableRes; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.pm.ActivityInfo; import android.content.pm.ActivityInfo.Config; import android.content.res.AssetManager.AssetInputStream; diff --git a/core/java/android/content/res/ResourcesKey.java b/core/java/android/content/res/ResourcesKey.java index 1db2dd85fb37..a29fea09c5ce 100644 --- a/core/java/android/content/res/ResourcesKey.java +++ b/core/java/android/content/res/ResourcesKey.java @@ -18,7 +18,7 @@ package android.content.res; import android.annotation.NonNull; import android.annotation.Nullable; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.text.TextUtils; import java.util.Arrays; diff --git a/core/java/android/content/res/StringBlock.java b/core/java/android/content/res/StringBlock.java index b7bc8229fa45..625889216719 100644 --- a/core/java/android/content/res/StringBlock.java +++ b/core/java/android/content/res/StringBlock.java @@ -16,7 +16,7 @@ package android.content.res; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.graphics.Color; import android.graphics.Paint; import android.graphics.Rect; diff --git a/core/java/android/content/res/ThemedResourceCache.java b/core/java/android/content/res/ThemedResourceCache.java index 06cafdb2bb91..f24e6f2a89c9 100644 --- a/core/java/android/content/res/ThemedResourceCache.java +++ b/core/java/android/content/res/ThemedResourceCache.java @@ -18,12 +18,12 @@ package android.content.res; import android.annotation.NonNull; import android.annotation.Nullable; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.pm.ActivityInfo.Config; import android.content.res.Resources.Theme; import android.content.res.Resources.ThemeKey; -import android.util.LongSparseArray; import android.util.ArrayMap; +import android.util.LongSparseArray; import java.lang.ref.WeakReference; diff --git a/core/java/android/content/res/TypedArray.java b/core/java/android/content/res/TypedArray.java index b79cf6566987..90affdfed39f 100644 --- a/core/java/android/content/res/TypedArray.java +++ b/core/java/android/content/res/TypedArray.java @@ -20,7 +20,7 @@ import android.annotation.AnyRes; import android.annotation.ColorInt; import android.annotation.Nullable; import android.annotation.StyleableRes; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.pm.ActivityInfo; import android.content.pm.ActivityInfo.Config; import android.graphics.Typeface; diff --git a/core/java/android/content/res/XmlBlock.java b/core/java/android/content/res/XmlBlock.java index 626bf77046bf..cb93cbfcbfc9 100644 --- a/core/java/android/content/res/XmlBlock.java +++ b/core/java/android/content/res/XmlBlock.java @@ -20,7 +20,7 @@ import static android.content.res.Resources.ID_NULL; import android.annotation.AnyRes; import android.annotation.Nullable; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.util.TypedValue; import com.android.internal.util.XmlUtils; diff --git a/core/java/android/database/AbstractCursor.java b/core/java/android/database/AbstractCursor.java index cc5d3b16ff08..3e10a6c0b849 100644 --- a/core/java/android/database/AbstractCursor.java +++ b/core/java/android/database/AbstractCursor.java @@ -17,7 +17,7 @@ package android.database; import android.annotation.NonNull; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.ContentResolver; import android.net.Uri; import android.os.Build; diff --git a/core/java/android/database/AbstractWindowedCursor.java b/core/java/android/database/AbstractWindowedCursor.java index a988f0684fca..daf7d2b1e908 100644 --- a/core/java/android/database/AbstractWindowedCursor.java +++ b/core/java/android/database/AbstractWindowedCursor.java @@ -16,7 +16,7 @@ package android.database; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; /** * A base class for Cursors that store their data in {@link CursorWindow}s. diff --git a/core/java/android/database/BulkCursorNative.java b/core/java/android/database/BulkCursorNative.java index 77a13cf80073..8ea450c6ca44 100644 --- a/core/java/android/database/BulkCursorNative.java +++ b/core/java/android/database/BulkCursorNative.java @@ -16,7 +16,7 @@ package android.database; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.os.Binder; import android.os.Bundle; import android.os.IBinder; diff --git a/core/java/android/database/ContentObserver.java b/core/java/android/database/ContentObserver.java index 798b7830ac50..69ca581e1559 100644 --- a/core/java/android/database/ContentObserver.java +++ b/core/java/android/database/ContentObserver.java @@ -16,7 +16,7 @@ package android.database; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.net.Uri; import android.os.Handler; import android.os.UserHandle; diff --git a/core/java/android/database/CursorWindow.java b/core/java/android/database/CursorWindow.java index 6873577553a7..063a2d00a306 100644 --- a/core/java/android/database/CursorWindow.java +++ b/core/java/android/database/CursorWindow.java @@ -17,7 +17,7 @@ package android.database; import android.annotation.BytesLong; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.res.Resources; import android.database.sqlite.SQLiteClosable; import android.database.sqlite.SQLiteException; diff --git a/core/java/android/database/CursorWrapper.java b/core/java/android/database/CursorWrapper.java index c9cafafe4041..4496f805cc2e 100644 --- a/core/java/android/database/CursorWrapper.java +++ b/core/java/android/database/CursorWrapper.java @@ -16,7 +16,7 @@ package android.database; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.ContentResolver; import android.net.Uri; import android.os.Bundle; diff --git a/core/java/android/database/DatabaseUtils.java b/core/java/android/database/DatabaseUtils.java index 992da312201d..4246b84dc52f 100644 --- a/core/java/android/database/DatabaseUtils.java +++ b/core/java/android/database/DatabaseUtils.java @@ -17,7 +17,7 @@ package android.database; import android.annotation.Nullable; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.ContentValues; import android.content.Context; import android.content.OperationApplicationException; diff --git a/core/java/android/database/MatrixCursor.java b/core/java/android/database/MatrixCursor.java index b0d399c64ea9..050a49ac959e 100644 --- a/core/java/android/database/MatrixCursor.java +++ b/core/java/android/database/MatrixCursor.java @@ -16,7 +16,7 @@ package android.database; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.os.Build; import java.util.ArrayList; diff --git a/core/java/android/database/sqlite/DatabaseObjectNotClosedException.java b/core/java/android/database/sqlite/DatabaseObjectNotClosedException.java index 2af06e116da0..ba546f34c9ea 100644 --- a/core/java/android/database/sqlite/DatabaseObjectNotClosedException.java +++ b/core/java/android/database/sqlite/DatabaseObjectNotClosedException.java @@ -16,7 +16,7 @@ package android.database.sqlite; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; /** * An exception that indicates that garbage-collector is finalizing a database object diff --git a/core/java/android/database/sqlite/SQLiteClosable.java b/core/java/android/database/sqlite/SQLiteClosable.java index d6a71da105dd..2fca729f2551 100644 --- a/core/java/android/database/sqlite/SQLiteClosable.java +++ b/core/java/android/database/sqlite/SQLiteClosable.java @@ -16,7 +16,8 @@ package android.database.sqlite; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; + import java.io.Closeable; /** diff --git a/core/java/android/database/sqlite/SQLiteCursor.java b/core/java/android/database/sqlite/SQLiteCursor.java index e3c409891c54..4559e918acc5 100644 --- a/core/java/android/database/sqlite/SQLiteCursor.java +++ b/core/java/android/database/sqlite/SQLiteCursor.java @@ -16,7 +16,7 @@ package android.database.sqlite; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.database.AbstractWindowedCursor; import android.database.CursorWindow; import android.database.DatabaseUtils; diff --git a/core/java/android/database/sqlite/SQLiteCustomFunction.java b/core/java/android/database/sqlite/SQLiteCustomFunction.java index 41b78d3a7745..1ace40d7e913 100644 --- a/core/java/android/database/sqlite/SQLiteCustomFunction.java +++ b/core/java/android/database/sqlite/SQLiteCustomFunction.java @@ -16,7 +16,7 @@ package android.database.sqlite; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.os.Build; /** diff --git a/core/java/android/database/sqlite/SQLiteDatabase.java b/core/java/android/database/sqlite/SQLiteDatabase.java index caf3e9337b92..7a0e183c03fe 100644 --- a/core/java/android/database/sqlite/SQLiteDatabase.java +++ b/core/java/android/database/sqlite/SQLiteDatabase.java @@ -20,9 +20,9 @@ import android.annotation.IntDef; import android.annotation.IntRange; import android.annotation.NonNull; import android.annotation.Nullable; -import android.annotation.UnsupportedAppUsage; import android.app.ActivityManager; import android.app.ActivityThread; +import android.compat.annotation.UnsupportedAppUsage; import android.content.ContentResolver; import android.content.ContentValues; import android.database.Cursor; diff --git a/core/java/android/database/sqlite/SQLiteDatabaseConfiguration.java b/core/java/android/database/sqlite/SQLiteDatabaseConfiguration.java index fcdaf0abafcb..6a52b72a9e1c 100644 --- a/core/java/android/database/sqlite/SQLiteDatabaseConfiguration.java +++ b/core/java/android/database/sqlite/SQLiteDatabaseConfiguration.java @@ -16,7 +16,7 @@ package android.database.sqlite; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import java.util.ArrayList; import java.util.Locale; diff --git a/core/java/android/database/sqlite/SQLiteDebug.java b/core/java/android/database/sqlite/SQLiteDebug.java index 3d0ac611b2df..165f863ccde7 100644 --- a/core/java/android/database/sqlite/SQLiteDebug.java +++ b/core/java/android/database/sqlite/SQLiteDebug.java @@ -17,14 +17,13 @@ package android.database.sqlite; import android.annotation.TestApi; +import android.compat.annotation.UnsupportedAppUsage; import android.os.Build; import android.os.Process; import android.os.SystemProperties; import android.util.Log; import android.util.Printer; -import dalvik.annotation.compat.UnsupportedAppUsage; - import java.util.ArrayList; /** diff --git a/core/java/android/database/sqlite/SQLiteOpenHelper.java b/core/java/android/database/sqlite/SQLiteOpenHelper.java index 62cec0e1aa92..943afc7e04c3 100644 --- a/core/java/android/database/sqlite/SQLiteOpenHelper.java +++ b/core/java/android/database/sqlite/SQLiteOpenHelper.java @@ -19,7 +19,7 @@ package android.database.sqlite; import android.annotation.IntRange; import android.annotation.NonNull; import android.annotation.Nullable; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; import android.database.DatabaseErrorHandler; import android.database.SQLException; diff --git a/core/java/android/database/sqlite/SQLiteProgram.java b/core/java/android/database/sqlite/SQLiteProgram.java index 8304133cd41e..de1c54321985 100644 --- a/core/java/android/database/sqlite/SQLiteProgram.java +++ b/core/java/android/database/sqlite/SQLiteProgram.java @@ -16,7 +16,7 @@ package android.database.sqlite; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.database.DatabaseUtils; import android.os.CancellationSignal; diff --git a/core/java/android/database/sqlite/SQLiteQueryBuilder.java b/core/java/android/database/sqlite/SQLiteQueryBuilder.java index 58901798b5f7..02c8a97a6902 100644 --- a/core/java/android/database/sqlite/SQLiteQueryBuilder.java +++ b/core/java/android/database/sqlite/SQLiteQueryBuilder.java @@ -18,7 +18,7 @@ package android.database.sqlite; import android.annotation.NonNull; import android.annotation.Nullable; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.ContentValues; import android.database.Cursor; import android.database.DatabaseUtils; diff --git a/core/java/android/database/sqlite/SQLiteSession.java b/core/java/android/database/sqlite/SQLiteSession.java index a9ac9e7f882f..24b62b89454d 100644 --- a/core/java/android/database/sqlite/SQLiteSession.java +++ b/core/java/android/database/sqlite/SQLiteSession.java @@ -16,7 +16,7 @@ package android.database.sqlite; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.database.CursorWindow; import android.database.DatabaseUtils; import android.os.CancellationSignal; diff --git a/core/java/android/database/sqlite/SQLiteStatement.java b/core/java/android/database/sqlite/SQLiteStatement.java index 42e7ac7e8431..9fda8b011e52 100644 --- a/core/java/android/database/sqlite/SQLiteStatement.java +++ b/core/java/android/database/sqlite/SQLiteStatement.java @@ -16,7 +16,7 @@ package android.database.sqlite; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.os.ParcelFileDescriptor; /** diff --git a/core/java/android/database/sqlite/SqliteWrapper.java b/core/java/android/database/sqlite/SqliteWrapper.java index e3171640a25c..f335fbdd89e0 100644 --- a/core/java/android/database/sqlite/SqliteWrapper.java +++ b/core/java/android/database/sqlite/SqliteWrapper.java @@ -17,12 +17,11 @@ package android.database.sqlite; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.ContentResolver; import android.content.ContentValues; import android.content.Context; import android.database.Cursor; -import android.database.sqlite.SQLiteException; import android.net.Uri; import android.util.Log; import android.widget.Toast; diff --git a/core/java/android/ddm/DdmHandleAppName.java b/core/java/android/ddm/DdmHandleAppName.java index 956078772ca8..e6fb4ec25210 100644 --- a/core/java/android/ddm/DdmHandleAppName.java +++ b/core/java/android/ddm/DdmHandleAppName.java @@ -16,11 +16,13 @@ package android.ddm; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; +import android.util.Log; + import org.apache.harmony.dalvik.ddmc.Chunk; import org.apache.harmony.dalvik.ddmc.ChunkHandler; import org.apache.harmony.dalvik.ddmc.DdmServer; -import android.util.Log; + import java.nio.ByteBuffer; diff --git a/core/java/android/hardware/Camera.java b/core/java/android/hardware/Camera.java index 33e51c9fa11c..c847f86f6b62 100644 --- a/core/java/android/hardware/Camera.java +++ b/core/java/android/hardware/Camera.java @@ -16,14 +16,20 @@ package android.hardware; -import static android.system.OsConstants.*; +import static android.system.OsConstants.EACCES; +import static android.system.OsConstants.EBUSY; +import static android.system.OsConstants.EINVAL; +import static android.system.OsConstants.ENODEV; +import static android.system.OsConstants.ENOSYS; +import static android.system.OsConstants.EOPNOTSUPP; +import static android.system.OsConstants.EUSERS; import android.annotation.Nullable; import android.annotation.SdkConstant; import android.annotation.SdkConstant.SdkConstantType; -import android.annotation.UnsupportedAppUsage; import android.app.ActivityThread; import android.app.AppOpsManager; +import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; import android.graphics.ImageFormat; import android.graphics.Point; diff --git a/core/java/android/hardware/HardwareBuffer.java b/core/java/android/hardware/HardwareBuffer.java index c569e05112a3..67797510870a 100644 --- a/core/java/android/hardware/HardwareBuffer.java +++ b/core/java/android/hardware/HardwareBuffer.java @@ -20,7 +20,7 @@ import android.annotation.IntDef; import android.annotation.IntRange; import android.annotation.LongDef; import android.annotation.NonNull; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.graphics.GraphicBuffer; import android.os.Build; import android.os.Parcel; diff --git a/core/java/android/hardware/Sensor.java b/core/java/android/hardware/Sensor.java index e78fb7f00797..a71a7b63f30e 100644 --- a/core/java/android/hardware/Sensor.java +++ b/core/java/android/hardware/Sensor.java @@ -18,7 +18,7 @@ package android.hardware; import android.annotation.SystemApi; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.os.Build; /** diff --git a/core/java/android/hardware/SensorEvent.java b/core/java/android/hardware/SensorEvent.java index 8c910b254b9c..64c45bf290ec 100644 --- a/core/java/android/hardware/SensorEvent.java +++ b/core/java/android/hardware/SensorEvent.java @@ -16,7 +16,7 @@ package android.hardware; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; /** * This class represents a {@link android.hardware.Sensor Sensor} event and diff --git a/core/java/android/hardware/SensorManager.java b/core/java/android/hardware/SensorManager.java index 32504282d98f..6036d7938b95 100644 --- a/core/java/android/hardware/SensorManager.java +++ b/core/java/android/hardware/SensorManager.java @@ -18,7 +18,7 @@ package android.hardware; import android.annotation.SystemApi; import android.annotation.SystemService; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; import android.os.Build; import android.os.Handler; diff --git a/core/java/android/hardware/SerialManager.java b/core/java/android/hardware/SerialManager.java index 571c3cc0451f..b51382e01ccd 100644 --- a/core/java/android/hardware/SerialManager.java +++ b/core/java/android/hardware/SerialManager.java @@ -17,7 +17,7 @@ package android.hardware; import android.annotation.SystemService; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; import android.os.ParcelFileDescriptor; import android.os.RemoteException; diff --git a/core/java/android/hardware/SerialPort.java b/core/java/android/hardware/SerialPort.java index 78ac3c007793..0fcaa4989210 100644 --- a/core/java/android/hardware/SerialPort.java +++ b/core/java/android/hardware/SerialPort.java @@ -16,12 +16,11 @@ package android.hardware; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.os.ParcelFileDescriptor; import java.io.FileDescriptor; import java.io.IOException; - import java.nio.ByteBuffer; /** diff --git a/core/java/android/hardware/SystemSensorManager.java b/core/java/android/hardware/SystemSensorManager.java index 7abfabf4a2ac..974913b290b1 100644 --- a/core/java/android/hardware/SystemSensorManager.java +++ b/core/java/android/hardware/SystemSensorManager.java @@ -16,7 +16,7 @@ package android.hardware; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; diff --git a/core/java/android/hardware/biometrics/BiometricConstants.java b/core/java/android/hardware/biometrics/BiometricConstants.java index 27c04b407315..2333251d0802 100644 --- a/core/java/android/hardware/biometrics/BiometricConstants.java +++ b/core/java/android/hardware/biometrics/BiometricConstants.java @@ -16,8 +16,8 @@ package android.hardware.biometrics; -import android.annotation.UnsupportedAppUsage; import android.app.KeyguardManager; +import android.compat.annotation.UnsupportedAppUsage; /** diff --git a/core/java/android/hardware/biometrics/BiometricFingerprintConstants.java b/core/java/android/hardware/biometrics/BiometricFingerprintConstants.java index b025508fc70e..5c74456eb60a 100644 --- a/core/java/android/hardware/biometrics/BiometricFingerprintConstants.java +++ b/core/java/android/hardware/biometrics/BiometricFingerprintConstants.java @@ -16,8 +16,8 @@ package android.hardware.biometrics; -import android.annotation.UnsupportedAppUsage; import android.app.KeyguardManager; +import android.compat.annotation.UnsupportedAppUsage; import android.hardware.fingerprint.FingerprintManager; /** diff --git a/core/java/android/hardware/camera2/CameraCharacteristics.java b/core/java/android/hardware/camera2/CameraCharacteristics.java index 48588e6d40bc..c697d4ce0c4f 100644 --- a/core/java/android/hardware/camera2/CameraCharacteristics.java +++ b/core/java/android/hardware/camera2/CameraCharacteristics.java @@ -18,7 +18,7 @@ package android.hardware.camera2; import android.annotation.NonNull; import android.annotation.Nullable; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.hardware.camera2.impl.CameraMetadataNative; import android.hardware.camera2.impl.PublicKey; import android.hardware.camera2.impl.SyntheticKey; diff --git a/core/java/android/hardware/camera2/CaptureRequest.java b/core/java/android/hardware/camera2/CaptureRequest.java index 6a2fc8a2ca34..d027de88a564 100644 --- a/core/java/android/hardware/camera2/CaptureRequest.java +++ b/core/java/android/hardware/camera2/CaptureRequest.java @@ -18,7 +18,7 @@ package android.hardware.camera2; import android.annotation.NonNull; import android.annotation.Nullable; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.hardware.camera2.impl.CameraMetadataNative; import android.hardware.camera2.impl.PublicKey; import android.hardware.camera2.impl.SyntheticKey; diff --git a/core/java/android/hardware/camera2/CaptureResult.java b/core/java/android/hardware/camera2/CaptureResult.java index ba451e585d27..af05b2980bd9 100644 --- a/core/java/android/hardware/camera2/CaptureResult.java +++ b/core/java/android/hardware/camera2/CaptureResult.java @@ -18,7 +18,7 @@ package android.hardware.camera2; import android.annotation.NonNull; import android.annotation.Nullable; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.hardware.camera2.impl.CameraMetadataNative; import android.hardware.camera2.impl.CaptureResultExtras; import android.hardware.camera2.impl.PublicKey; diff --git a/core/java/android/hardware/camera2/impl/CameraMetadataNative.java b/core/java/android/hardware/camera2/impl/CameraMetadataNative.java index e909c0075f38..706aa4ef1979 100644 --- a/core/java/android/hardware/camera2/impl/CameraMetadataNative.java +++ b/core/java/android/hardware/camera2/impl/CameraMetadataNative.java @@ -16,12 +16,11 @@ package android.hardware.camera2.impl; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.graphics.ImageFormat; import android.graphics.Point; import android.graphics.Rect; import android.hardware.camera2.CameraCharacteristics; -import android.hardware.camera2.CameraDevice; import android.hardware.camera2.CaptureRequest; import android.hardware.camera2.CaptureResult; import android.hardware.camera2.marshal.MarshalQueryable; @@ -52,7 +51,6 @@ import android.hardware.camera2.params.Face; import android.hardware.camera2.params.HighSpeedVideoConfiguration; import android.hardware.camera2.params.LensShadingMap; import android.hardware.camera2.params.MandatoryStreamCombination; -import android.hardware.camera2.params.MandatoryStreamCombination.MandatoryStreamInformation; import android.hardware.camera2.params.OisSample; import android.hardware.camera2.params.RecommendedStreamConfiguration; import android.hardware.camera2.params.RecommendedStreamConfigurationMap; diff --git a/core/java/android/hardware/camera2/utils/HashCodeHelpers.java b/core/java/android/hardware/camera2/utils/HashCodeHelpers.java index 526f086f4baa..16f3f2ab2023 100644 --- a/core/java/android/hardware/camera2/utils/HashCodeHelpers.java +++ b/core/java/android/hardware/camera2/utils/HashCodeHelpers.java @@ -16,7 +16,7 @@ package android.hardware.camera2.utils; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; /** * Provide hashing functions using the Modified Bernstein hash diff --git a/core/java/android/hardware/camera2/utils/SurfaceUtils.java b/core/java/android/hardware/camera2/utils/SurfaceUtils.java index d3c4505c37f0..abe1372ebde4 100644 --- a/core/java/android/hardware/camera2/utils/SurfaceUtils.java +++ b/core/java/android/hardware/camera2/utils/SurfaceUtils.java @@ -16,7 +16,7 @@ package android.hardware.camera2.utils; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.graphics.ImageFormat; import android.hardware.camera2.legacy.LegacyCameraDevice; import android.hardware.camera2.legacy.LegacyExceptionUtils.BufferQueueAbandonedException; diff --git a/core/java/android/hardware/camera2/utils/TypeReference.java b/core/java/android/hardware/camera2/utils/TypeReference.java index d9ba31b4c6f4..435ed153e042 100644 --- a/core/java/android/hardware/camera2/utils/TypeReference.java +++ b/core/java/android/hardware/camera2/utils/TypeReference.java @@ -16,7 +16,10 @@ package android.hardware.camera2.utils; -import android.annotation.UnsupportedAppUsage; +import static com.android.internal.util.Preconditions.checkNotNull; + +import android.compat.annotation.UnsupportedAppUsage; + import java.lang.reflect.Array; import java.lang.reflect.GenericArrayType; import java.lang.reflect.ParameterizedType; @@ -24,8 +27,6 @@ import java.lang.reflect.Type; import java.lang.reflect.TypeVariable; import java.lang.reflect.WildcardType; -import static com.android.internal.util.Preconditions.*; - /** * Super type token; allows capturing generic types at runtime by forcing them to be reified. * diff --git a/core/java/android/hardware/display/DisplayManager.java b/core/java/android/hardware/display/DisplayManager.java index 0b25dbd78611..799dff9632c8 100644 --- a/core/java/android/hardware/display/DisplayManager.java +++ b/core/java/android/hardware/display/DisplayManager.java @@ -23,8 +23,8 @@ import android.annotation.RequiresPermission; import android.annotation.SystemApi; import android.annotation.SystemService; import android.annotation.TestApi; -import android.annotation.UnsupportedAppUsage; import android.app.KeyguardManager; +import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; import android.graphics.Point; import android.media.projection.MediaProjection; diff --git a/core/java/android/hardware/display/DisplayManagerGlobal.java b/core/java/android/hardware/display/DisplayManagerGlobal.java index ea63776dc5b6..2a584951887f 100644 --- a/core/java/android/hardware/display/DisplayManagerGlobal.java +++ b/core/java/android/hardware/display/DisplayManagerGlobal.java @@ -18,7 +18,7 @@ package android.hardware.display; import android.annotation.NonNull; import android.annotation.Nullable; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; import android.content.pm.ParceledListSlice; import android.content.res.Resources; diff --git a/core/java/android/hardware/display/WifiDisplay.java b/core/java/android/hardware/display/WifiDisplay.java index 55e60519707a..5bbbbf9bae77 100644 --- a/core/java/android/hardware/display/WifiDisplay.java +++ b/core/java/android/hardware/display/WifiDisplay.java @@ -16,7 +16,7 @@ package android.hardware.display; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.os.Parcel; import android.os.Parcelable; diff --git a/core/java/android/hardware/display/WifiDisplayStatus.java b/core/java/android/hardware/display/WifiDisplayStatus.java index 1973e51b1bba..e2a825fd990a 100644 --- a/core/java/android/hardware/display/WifiDisplayStatus.java +++ b/core/java/android/hardware/display/WifiDisplayStatus.java @@ -16,7 +16,7 @@ package android.hardware.display; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.os.Parcel; import android.os.Parcelable; diff --git a/core/java/android/hardware/fingerprint/FingerprintManager.java b/core/java/android/hardware/fingerprint/FingerprintManager.java index d0622c88b4ca..315af32580aa 100644 --- a/core/java/android/hardware/fingerprint/FingerprintManager.java +++ b/core/java/android/hardware/fingerprint/FingerprintManager.java @@ -26,8 +26,8 @@ import android.annotation.Nullable; import android.annotation.RequiresFeature; import android.annotation.RequiresPermission; import android.annotation.SystemService; -import android.annotation.UnsupportedAppUsage; import android.app.ActivityManager; +import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; import android.content.pm.PackageManager; import android.hardware.biometrics.BiometricAuthenticator; diff --git a/core/java/android/hardware/input/InputManager.java b/core/java/android/hardware/input/InputManager.java index 0c0f248e3222..8d32db013fb3 100644 --- a/core/java/android/hardware/input/InputManager.java +++ b/core/java/android/hardware/input/InputManager.java @@ -20,7 +20,7 @@ import android.annotation.IntDef; import android.annotation.SdkConstant; import android.annotation.SdkConstant.SdkConstantType; import android.annotation.SystemService; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; import android.media.AudioAttributes; import android.os.Binder; diff --git a/core/java/android/hardware/location/GeofenceHardware.java b/core/java/android/hardware/location/GeofenceHardware.java index 23d8d01dbe9d..a1866af43706 100644 --- a/core/java/android/hardware/location/GeofenceHardware.java +++ b/core/java/android/hardware/location/GeofenceHardware.java @@ -16,7 +16,7 @@ package android.hardware.location; import android.annotation.SystemApi; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.location.Location; import android.os.Build; import android.os.RemoteException; diff --git a/core/java/android/hardware/soundtrigger/SoundTrigger.java b/core/java/android/hardware/soundtrigger/SoundTrigger.java index f96f47dfaffc..2f0265acf4bd 100644 --- a/core/java/android/hardware/soundtrigger/SoundTrigger.java +++ b/core/java/android/hardware/soundtrigger/SoundTrigger.java @@ -25,8 +25,8 @@ import static android.system.OsConstants.EPIPE; import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.SystemApi; -import android.annotation.UnsupportedAppUsage; import android.app.ActivityThread; +import android.compat.annotation.UnsupportedAppUsage; import android.media.AudioFormat; import android.os.Handler; import android.os.Parcel; diff --git a/core/java/android/hardware/soundtrigger/SoundTriggerModule.java b/core/java/android/hardware/soundtrigger/SoundTriggerModule.java index 911354862ff4..694d60531396 100644 --- a/core/java/android/hardware/soundtrigger/SoundTriggerModule.java +++ b/core/java/android/hardware/soundtrigger/SoundTriggerModule.java @@ -16,7 +16,7 @@ package android.hardware.soundtrigger; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.os.Handler; import android.os.Looper; import android.os.Message; diff --git a/core/java/android/hardware/usb/UsbDevice.java b/core/java/android/hardware/usb/UsbDevice.java index 08c9eea6e012..fdb4cc079bd7 100644 --- a/core/java/android/hardware/usb/UsbDevice.java +++ b/core/java/android/hardware/usb/UsbDevice.java @@ -18,8 +18,8 @@ package android.hardware.usb; import android.annotation.NonNull; import android.annotation.Nullable; -import android.annotation.UnsupportedAppUsage; import android.app.ActivityThread; +import android.compat.annotation.UnsupportedAppUsage; import android.os.Parcel; import android.os.Parcelable; import android.os.RemoteException; diff --git a/core/java/android/hardware/usb/UsbDeviceConnection.java b/core/java/android/hardware/usb/UsbDeviceConnection.java index 71297c187e5c..215ac24fcb08 100644 --- a/core/java/android/hardware/usb/UsbDeviceConnection.java +++ b/core/java/android/hardware/usb/UsbDeviceConnection.java @@ -20,7 +20,7 @@ import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.SuppressLint; import android.annotation.SystemApi; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; import android.os.Build; import android.os.ParcelFileDescriptor; diff --git a/core/java/android/hardware/usb/UsbManager.java b/core/java/android/hardware/usb/UsbManager.java index eb148b94ac7b..67fdda37ed3b 100644 --- a/core/java/android/hardware/usb/UsbManager.java +++ b/core/java/android/hardware/usb/UsbManager.java @@ -26,8 +26,8 @@ import android.annotation.SdkConstant; import android.annotation.SdkConstant.SdkConstantType; import android.annotation.SystemApi; import android.annotation.SystemService; -import android.annotation.UnsupportedAppUsage; import android.app.PendingIntent; +import android.compat.annotation.UnsupportedAppUsage; import android.content.ComponentName; import android.content.Context; import android.content.pm.PackageManager; @@ -91,7 +91,7 @@ public class UsbManager { * * {@hide} */ - @UnsupportedAppUsage + @SystemApi public static final String ACTION_USB_STATE = "android.hardware.usb.action.USB_STATE"; @@ -164,7 +164,7 @@ public class UsbManager { * * {@hide} */ - @UnsupportedAppUsage + @SystemApi public static final String USB_CONNECTED = "connected"; /** @@ -181,6 +181,7 @@ public class UsbManager { * * {@hide} */ + @SystemApi public static final String USB_CONFIGURED = "configured"; /** @@ -217,6 +218,7 @@ public class UsbManager { * * {@hide} */ + @SystemApi public static final String USB_FUNCTION_RNDIS = "rndis"; /** @@ -319,6 +321,7 @@ public class UsbManager { * Code for the charging usb function. Passed into {@link #setCurrentFunctions(long)} * {@hide} */ + @SystemApi public static final long FUNCTION_NONE = 0; /** @@ -337,6 +340,7 @@ public class UsbManager { * Code for the rndis usb function. Passed as a mask into {@link #setCurrentFunctions(long)} * {@hide} */ + @SystemApi public static final long FUNCTION_RNDIS = GadgetFunction.RNDIS; /** @@ -698,6 +702,8 @@ public class UsbManager { * * {@hide} */ + @SystemApi + @RequiresPermission(Manifest.permission.MANAGE_USB) public void setCurrentFunctions(long functions) { try { mService.setCurrentFunctions(functions); @@ -737,6 +743,8 @@ public class UsbManager { * * {@hide} */ + @SystemApi + @RequiresPermission(Manifest.permission.MANAGE_USB) public long getCurrentFunctions() { try { return mService.getCurrentFunctions(); diff --git a/core/java/android/hardware/usb/UsbRequest.java b/core/java/android/hardware/usb/UsbRequest.java index 7abf3e9bcc7a..fab2c0baa10e 100644 --- a/core/java/android/hardware/usb/UsbRequest.java +++ b/core/java/android/hardware/usb/UsbRequest.java @@ -17,7 +17,7 @@ package android.hardware.usb; import android.annotation.Nullable; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.os.Build; import android.util.Log; diff --git a/core/java/android/inputmethodservice/IInputMethodSessionWrapper.java b/core/java/android/inputmethodservice/IInputMethodSessionWrapper.java index 7d4849f7562d..9327b241c6c5 100644 --- a/core/java/android/inputmethodservice/IInputMethodSessionWrapper.java +++ b/core/java/android/inputmethodservice/IInputMethodSessionWrapper.java @@ -16,7 +16,7 @@ package android.inputmethodservice; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; import android.graphics.Rect; import android.os.Bundle; diff --git a/core/java/android/inputmethodservice/IInputMethodWrapper.java b/core/java/android/inputmethodservice/IInputMethodWrapper.java index a47f601033cf..69b93b19fc41 100644 --- a/core/java/android/inputmethodservice/IInputMethodWrapper.java +++ b/core/java/android/inputmethodservice/IInputMethodWrapper.java @@ -18,7 +18,7 @@ package android.inputmethodservice; import android.annotation.BinderThread; import android.annotation.MainThread; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; import android.content.pm.PackageManager; import android.os.Binder; diff --git a/core/java/android/inputmethodservice/InputMethodService.java b/core/java/android/inputmethodservice/InputMethodService.java index 82d4d1d10d7e..44825a8f1502 100644 --- a/core/java/android/inputmethodservice/InputMethodService.java +++ b/core/java/android/inputmethodservice/InputMethodService.java @@ -30,9 +30,9 @@ import android.annotation.IntDef; import android.annotation.MainThread; import android.annotation.NonNull; import android.annotation.Nullable; -import android.annotation.UnsupportedAppUsage; import android.app.ActivityManager; import android.app.Dialog; +import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; import android.content.res.Configuration; import android.content.res.Resources; diff --git a/core/java/android/inputmethodservice/Keyboard.java b/core/java/android/inputmethodservice/Keyboard.java index 3f25113874e8..c85fcd990564 100644 --- a/core/java/android/inputmethodservice/Keyboard.java +++ b/core/java/android/inputmethodservice/Keyboard.java @@ -16,8 +16,8 @@ package android.inputmethodservice; -import android.annotation.UnsupportedAppUsage; import android.annotation.XmlRes; +import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; import android.content.res.Resources; import android.content.res.TypedArray; diff --git a/core/java/android/inputmethodservice/KeyboardView.java b/core/java/android/inputmethodservice/KeyboardView.java index 45f067b95298..b780b21bf3d0 100644 --- a/core/java/android/inputmethodservice/KeyboardView.java +++ b/core/java/android/inputmethodservice/KeyboardView.java @@ -16,7 +16,7 @@ package android.inputmethodservice; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; import android.content.res.TypedArray; import android.graphics.Bitmap; diff --git a/core/java/android/net/CaptivePortal.java b/core/java/android/net/CaptivePortal.java index a66fcae7d4a2..fb35b4bde303 100644 --- a/core/java/android/net/CaptivePortal.java +++ b/core/java/android/net/CaptivePortal.java @@ -60,6 +60,18 @@ public class CaptivePortal implements Parcelable { @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; + /** + * Request code from the captive portal application, indicating that the network condition may + * have changed and the network should be re-validated. + * @see ICaptivePortal#appRequest(int) + * @see android.net.INetworkMonitor#forceReevaluation(int) + * @hide + */ + @SystemApi + @TestApi + public static final int APP_REQUEST_REEVALUATION_REQUIRED = APP_REQUEST_BASE + 0; private final IBinder mBinder; @@ -136,6 +148,19 @@ public class CaptivePortal implements Parcelable { } /** + * Request that the system reevaluates the captive portal status. + * @hide + */ + @SystemApi + @TestApi + public void reevaluateNetwork() { + try { + ICaptivePortal.Stub.asInterface(mBinder).appRequest(APP_REQUEST_REEVALUATION_REQUIRED); + } catch (RemoteException e) { + } + } + + /** * Log a captive portal login event. * @param eventId one of the CAPTIVE_PORTAL_LOGIN_* constants in metrics_constants.proto. * @param packageName captive portal application package name. diff --git a/core/java/android/net/ConnectivityDiagnosticsManager.java b/core/java/android/net/ConnectivityDiagnosticsManager.java new file mode 100644 index 000000000000..6afdb5ef1b16 --- /dev/null +++ b/core/java/android/net/ConnectivityDiagnosticsManager.java @@ -0,0 +1,242 @@ +/* + * 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.annotation.IntDef; +import android.annotation.NonNull; +import android.os.PersistableBundle; + +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.util.concurrent.Executor; + +/** + * Class that provides utilities for collecting network connectivity diagnostics information. + * Connectivity information is made available through triggerable diagnostics tools and by listening + * to System validations. Some diagnostics information may be permissions-restricted. + * + * <p>ConnectivityDiagnosticsManager is intended for use by applications offering network + * connectivity on a user device. These tools will provide several mechanisms for these applications + * to be alerted to network conditions as well as diagnose potential network issues themselves. + * + * <p>The primary responsibilities of this class are to: + * + * <ul> + * <li>Allow permissioned applications to register and unregister callbacks for network event + * notifications + * <li>Invoke callbacks for network event notifications, including: + * <ul> + * <li>Network validations + * <li>Data stalls + * <li>Connectivity reports from applications + * </ul> + * </ul> + */ +public class ConnectivityDiagnosticsManager { + public static final int DETECTION_METHOD_DNS_EVENTS = 1; + public static final int DETECTION_METHOD_TCP_METRICS = 2; + + /** @hide */ + @Retention(RetentionPolicy.SOURCE) + @IntDef( + prefix = {"DETECTION_METHOD_"}, + value = {DETECTION_METHOD_DNS_EVENTS, DETECTION_METHOD_TCP_METRICS}) + public @interface DetectionMethod {} + + /** @hide */ + public ConnectivityDiagnosticsManager() {} + + /** Class that includes connectivity information for a specific Network at a specific time. */ + public static class ConnectivityReport { + /** The Network for which this ConnectivityReport applied */ + @NonNull public final Network network; + + /** + * The timestamp for the report. The timestamp is taken from {@link + * System#currentTimeMillis}. + */ + public final long reportTimestamp; + + /** LinkProperties available on the Network at the reported timestamp */ + @NonNull public final LinkProperties linkProperties; + + /** NetworkCapabilities available on the Network at the reported timestamp */ + @NonNull public final NetworkCapabilities networkCapabilities; + + /** PersistableBundle that may contain additional info about the report */ + @NonNull public final PersistableBundle additionalInfo; + + /** + * Constructor for ConnectivityReport. + * + * <p>Apps should obtain instances through {@link + * ConnectivityDiagnosticsCallback#onConnectivityReport} instead of instantiating their own + * instances (unless for testing purposes). + * + * @param network The Network for which this ConnectivityReport applies + * @param reportTimestamp The timestamp for the report + * @param linkProperties The LinkProperties available on network at reportTimestamp + * @param networkCapabilities The NetworkCapabilities available on network at + * reportTimestamp + * @param additionalInfo A PersistableBundle that may contain additional info about the + * report + */ + public ConnectivityReport( + @NonNull Network network, + long reportTimestamp, + @NonNull LinkProperties linkProperties, + @NonNull NetworkCapabilities networkCapabilities, + @NonNull PersistableBundle additionalInfo) { + this.network = network; + this.reportTimestamp = reportTimestamp; + this.linkProperties = linkProperties; + this.networkCapabilities = networkCapabilities; + this.additionalInfo = additionalInfo; + } + } + + /** Class that includes information for a suspected data stall on a specific Network */ + public static class DataStallReport { + /** The Network for which this DataStallReport applied */ + @NonNull public final Network network; + + /** + * The timestamp for the report. The timestamp is taken from {@link + * System#currentTimeMillis}. + */ + public final long reportTimestamp; + + /** The detection method used to identify the suspected data stall */ + @DetectionMethod public final int detectionMethod; + + /** PersistableBundle that may contain additional information on the suspected data stall */ + @NonNull public final PersistableBundle stallDetails; + + /** + * Constructor for DataStallReport. + * + * <p>Apps should obtain instances through {@link + * ConnectivityDiagnosticsCallback#onDataStallSuspected} instead of instantiating their own + * instances (unless for testing purposes). + * + * @param network The Network for which this DataStallReport applies + * @param reportTimestamp The timestamp for the report + * @param detectionMethod The detection method used to identify this data stall + * @param stallDetails A PersistableBundle that may contain additional info about the report + */ + public DataStallReport( + @NonNull Network network, + long reportTimestamp, + @DetectionMethod int detectionMethod, + @NonNull PersistableBundle stallDetails) { + this.network = network; + this.reportTimestamp = reportTimestamp; + this.detectionMethod = detectionMethod; + this.stallDetails = stallDetails; + } + } + + /** + * Abstract base class for Connectivity Diagnostics callbacks. Used for notifications about + * network connectivity events. Must be extended by applications wanting notifications. + */ + public abstract static class ConnectivityDiagnosticsCallback { + /** + * Called when the platform completes a data connectivity check. This will also be invoked + * upon registration with the latest report. + * + * <p>The Network specified in the ConnectivityReport may not be active any more when this + * method is invoked. + * + * @param report The ConnectivityReport containing information about a connectivity check + */ + public void onConnectivityReport(@NonNull ConnectivityReport report) {} + + /** + * Called when the platform suspects a data stall on some Network. + * + * <p>The Network specified in the DataStallReport may not be active any more when this + * method is invoked. + * + * @param report The DataStallReport containing information about the suspected data stall + */ + public void onDataStallSuspected(@NonNull DataStallReport report) {} + + /** + * Called when any app reports connectivity to the System. + * + * @param network The Network for which connectivity has been reported + * @param hasConnectivity The connectivity reported to the System + */ + public void onNetworkConnectivityReported( + @NonNull Network network, boolean hasConnectivity) {} + } + + /** + * Registers a ConnectivityDiagnosticsCallback with the System. + * + * <p>Only apps that offer network connectivity to the user are allowed to register callbacks. + * This includes: + * + * <ul> + * <li>Carrier apps with active subscriptions + * <li>Active VPNs + * <li>WiFi Suggesters + * </ul> + * + * <p>Callbacks will be limited to receiving notifications for networks over which apps provide + * connectivity. + * + * <p>If a registering app loses its relevant permissions, any callbacks it registered will + * silently stop receiving callbacks. + * + * <p>Each register() call <b>MUST</b> use a unique ConnectivityDiagnosticsCallback instance. If + * a single instance is registered with multiple NetworkRequests, an IllegalArgumentException + * will be thrown. + * + * @param request The NetworkRequest that will be used to match with Networks for which + * callbacks will be fired + * @param e The Executor to be used for running the callback method invocations + * @param callback The ConnectivityDiagnosticsCallback that the caller wants registered with the + * System + * @throws IllegalArgumentException if the same callback instance is registered with multiple + * NetworkRequests + * @throws SecurityException if the caller does not have appropriate permissions to register a + * callback + */ + public void registerConnectivityDiagnosticsCallback( + @NonNull NetworkRequest request, + @NonNull Executor e, + @NonNull ConnectivityDiagnosticsCallback callback) { + // TODO(b/143187964): implement ConnectivityDiagnostics functionality + throw new UnsupportedOperationException("registerCallback() not supported yet"); + } + + /** + * Unregisters a ConnectivityDiagnosticsCallback with the System. + * + * <p>If the given callback is not currently registered with the System, this operation will be + * a no-op. + * + * @param callback The ConnectivityDiagnosticsCallback to be unregistered from the System. + */ + public void unregisterConnectivityDiagnosticsCallback( + @NonNull ConnectivityDiagnosticsCallback callback) { + // TODO(b/143187964): implement ConnectivityDiagnostics functionality + throw new UnsupportedOperationException("registerCallback() not supported yet"); + } +} diff --git a/core/java/android/net/ConnectivityManager.java b/core/java/android/net/ConnectivityManager.java index 82cecb6f20ad..674c58d00dcd 100644 --- a/core/java/android/net/ConnectivityManager.java +++ b/core/java/android/net/ConnectivityManager.java @@ -27,8 +27,8 @@ import android.annotation.SdkConstant.SdkConstantType; import android.annotation.SystemApi; import android.annotation.SystemService; import android.annotation.TestApi; -import android.annotation.UnsupportedAppUsage; import android.app.PendingIntent; +import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; import android.content.Intent; import android.net.IpSecManager.UdpEncapsulationSocket; @@ -363,7 +363,7 @@ public class ConnectivityManager { @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) @UnsupportedAppUsage public static final String ACTION_TETHER_STATE_CHANGED = - "android.net.conn.TETHER_STATE_CHANGED"; + TetheringManager.ACTION_TETHER_STATE_CHANGED; /** * @hide @@ -371,14 +371,14 @@ public class ConnectivityManager { * tethering and currently available for tethering. */ @UnsupportedAppUsage - public static final String EXTRA_AVAILABLE_TETHER = "availableArray"; + public static final String EXTRA_AVAILABLE_TETHER = TetheringManager.EXTRA_AVAILABLE_TETHER; /** * @hide * 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 = "localOnlyArray"; + public static final String EXTRA_ACTIVE_LOCAL_ONLY = TetheringManager.EXTRA_ACTIVE_LOCAL_ONLY; /** * @hide @@ -386,7 +386,7 @@ public class ConnectivityManager { * (ie, has DHCPv4 support and packets potentially forwarded/NATed) */ @UnsupportedAppUsage - public static final String EXTRA_ACTIVE_TETHER = "tetherArray"; + public static final String EXTRA_ACTIVE_TETHER = TetheringManager.EXTRA_ACTIVE_TETHER; /** * @hide @@ -395,7 +395,7 @@ public class ConnectivityManager { * for any interfaces listed here. */ @UnsupportedAppUsage - public static final String EXTRA_ERRORED_TETHER = "erroredArray"; + public static final String EXTRA_ERRORED_TETHER = TetheringManager.EXTRA_ERRORED_TETHER; /** * Broadcast Action: The captive portal tracker has finished its test. @@ -445,7 +445,7 @@ public class ConnectivityManager { * @see #startTethering(int, boolean, OnStartTetheringCallback) * @hide */ - public static final int TETHERING_INVALID = -1; + public static final int TETHERING_INVALID = TetheringManager.TETHERING_INVALID; /** * Wifi tethering type. @@ -453,7 +453,7 @@ public class ConnectivityManager { * @hide */ @SystemApi - public static final int TETHERING_WIFI = 0; + public static final int TETHERING_WIFI = TetheringManager.TETHERING_WIFI; /** * USB tethering type. @@ -461,7 +461,7 @@ public class ConnectivityManager { * @hide */ @SystemApi - public static final int TETHERING_USB = 1; + public static final int TETHERING_USB = TetheringManager.TETHERING_USB; /** * Bluetooth tethering type. @@ -469,7 +469,7 @@ public class ConnectivityManager { * @hide */ @SystemApi - public static final int TETHERING_BLUETOOTH = 2; + public static final int TETHERING_BLUETOOTH = TetheringManager.TETHERING_BLUETOOTH; /** * Wifi P2p tethering type. @@ -477,47 +477,47 @@ public class ConnectivityManager { * need to start from #startTethering(int, boolean, OnStartTetheringCallback). * @hide */ - public static final int TETHERING_WIFI_P2P = 3; + public static final int TETHERING_WIFI_P2P = TetheringManager.TETHERING_WIFI_P2P; /** * Extra used for communicating with the TetherService. Includes the type of tethering to * enable if any. * @hide */ - public static final String EXTRA_ADD_TETHER_TYPE = "extraAddTetherType"; + public static final String EXTRA_ADD_TETHER_TYPE = TetheringManager.EXTRA_ADD_TETHER_TYPE; /** * Extra used for communicating with the TetherService. Includes the type of tethering for * which to cancel provisioning. * @hide */ - public static final String EXTRA_REM_TETHER_TYPE = "extraRemTetherType"; + public static final String EXTRA_REM_TETHER_TYPE = TetheringManager.EXTRA_REM_TETHER_TYPE; /** * Extra used for communicating with the TetherService. True to schedule a recheck of tether * provisioning. * @hide */ - public static final String EXTRA_SET_ALARM = "extraSetAlarm"; + public static final String EXTRA_SET_ALARM = TetheringManager.EXTRA_SET_ALARM; /** * Tells the TetherService to run a provision check now. * @hide */ - public static final String EXTRA_RUN_PROVISION = "extraRunProvision"; + public static final String EXTRA_RUN_PROVISION = TetheringManager.EXTRA_RUN_PROVISION; /** * Extra used for communicating with the TetherService. Contains the {@link ResultReceiver} * which will receive provisioning results. Can be left empty. * @hide */ - public static final String EXTRA_PROVISION_CALLBACK = "extraProvisionCallback"; + public static final String EXTRA_PROVISION_CALLBACK = TetheringManager.EXTRA_PROVISION_CALLBACK; /** * The absence of a connection type. * @hide */ - @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 130143562) + @SystemApi public static final int TYPE_NONE = -1; /** @@ -662,7 +662,7 @@ public class ConnectivityManager { * {@hide} */ @Deprecated - @UnsupportedAppUsage + @SystemApi public static final int TYPE_WIFI_P2P = 13; /** @@ -3107,6 +3107,61 @@ public class ConnectivityManager { } } + /** + * Registers the specified {@link NetworkProvider}. + * Each listener must only be registered once. The listener can be unregistered with + * {@link #unregisterNetworkProvider}. + * + * @param provider the provider to register + * @return the ID of the provider. This ID must be used by the provider when registering + * {@link android.net.NetworkAgent}s. + * @hide + */ + @SystemApi + @RequiresPermission(android.Manifest.permission.NETWORK_FACTORY) + public int registerNetworkProvider(@NonNull NetworkProvider provider) { + if (provider.getProviderId() != NetworkProvider.ID_NONE) { + throw new IllegalStateException("NetworkProviders can only be registered once"); + } + + try { + int providerId = mService.registerNetworkProvider(provider.getMessenger(), + provider.getName()); + provider.setProviderId(providerId); + } catch (RemoteException e) { + throw e.rethrowFromSystemServer(); + } + return provider.getProviderId(); + } + + /** + * Unregisters the specified NetworkProvider. + * + * @param provider the provider to unregister + * @hide + */ + @SystemApi + @RequiresPermission(android.Manifest.permission.NETWORK_FACTORY) + public void unregisterNetworkProvider(@NonNull NetworkProvider provider) { + try { + mService.unregisterNetworkProvider(provider.getMessenger()); + } catch (RemoteException e) { + throw e.rethrowFromSystemServer(); + } + provider.setProviderId(NetworkProvider.ID_NONE); + } + + + /** @hide exposed via the NetworkProvider class. */ + @RequiresPermission(android.Manifest.permission.NETWORK_FACTORY) + public void declareNetworkRequestUnfulfillable(@NonNull NetworkRequest request) { + try { + mService.declareNetworkRequestUnfulfillable(request); + } catch (RemoteException e) { + throw e.rethrowFromSystemServer(); + } + } + // TODO : remove this method. It is a stopgap measure to help sheperding a number // of dependent changes that would conflict throughout the automerger graph. Having this // temporarily helps with the process of going through with all these dependent changes across @@ -3119,8 +3174,7 @@ public class ConnectivityManager { @RequiresPermission(android.Manifest.permission.NETWORK_FACTORY) public int registerNetworkAgent(Messenger messenger, NetworkInfo ni, LinkProperties lp, NetworkCapabilities nc, int score, NetworkMisc misc) { - return registerNetworkAgent(messenger, ni, lp, nc, score, misc, - NetworkFactory.SerialNumber.NONE); + return registerNetworkAgent(messenger, ni, lp, nc, score, misc, NetworkProvider.ID_NONE); } /** @@ -3130,10 +3184,9 @@ public class ConnectivityManager { */ @RequiresPermission(android.Manifest.permission.NETWORK_FACTORY) public int registerNetworkAgent(Messenger messenger, NetworkInfo ni, LinkProperties lp, - NetworkCapabilities nc, int score, NetworkMisc misc, int factorySerialNumber) { + NetworkCapabilities nc, int score, NetworkMisc misc, int providerId) { try { - return mService.registerNetworkAgent(messenger, ni, lp, nc, score, misc, - factorySerialNumber); + return mService.registerNetworkAgent(messenger, ni, lp, nc, score, misc, providerId); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } @@ -3569,14 +3622,26 @@ public class ConnectivityManager { /** * Helper function to request a network with a particular legacy type. * - * This is temporarily public @hide so it can be called by system code that uses the - * NetworkRequest API to request networks but relies on CONNECTIVITY_ACTION broadcasts for - * instead network notifications. + * @deprecated This is temporarily public for tethering to backwards compatibility that uses + * the NetworkRequest API to request networks with legacy type and relies on + * CONNECTIVITY_ACTION broadcasts instead of NetworkCallbacks. New caller should use + * {@link #requestNetwork(NetworkRequest, NetworkCallback, Handler)} instead. * * TODO: update said system code to rely on NetworkCallbacks and make this method private. + + * @param request {@link NetworkRequest} describing this request. + * @param networkCallback The {@link NetworkCallback} to be utilized for this request. Note + * the callback must not be shared - it uniquely specifies this request. + * @param timeoutMs The time in milliseconds to attempt looking for a suitable network + * before {@link NetworkCallback#onUnavailable()} is called. The timeout must + * be a positive value (i.e. >0). + * @param legacyType to specify the network type(#TYPE_*). + * @param handler {@link Handler} to specify the thread upon which the callback will be invoked. * * @hide */ + @SystemApi + @Deprecated public void requestNetwork(@NonNull NetworkRequest request, @NonNull NetworkCallback networkCallback, int timeoutMs, int legacyType, @NonNull Handler handler) { diff --git a/core/java/android/net/DhcpInfo.java b/core/java/android/net/DhcpInfo.java index 98bab44e19fb..912df67a0b45 100644 --- a/core/java/android/net/DhcpInfo.java +++ b/core/java/android/net/DhcpInfo.java @@ -16,8 +16,8 @@ package android.net; -import android.os.Parcelable; import android.os.Parcel; +import android.os.Parcelable; /** * A simple object for retrieving the results of a DHCP request. @@ -67,12 +67,12 @@ public class DhcpInfo implements Parcelable { buf.append(NetworkUtils.intToInetAddress(addr).getHostAddress()); } - /** Implement the Parcelable interface {@hide} */ + /** Implement the Parcelable interface */ public int describeContents() { return 0; } - /** Implement the Parcelable interface {@hide} */ + /** Implement the Parcelable interface */ public void writeToParcel(Parcel dest, int flags) { dest.writeInt(ipAddress); dest.writeInt(gateway); @@ -83,7 +83,7 @@ public class DhcpInfo implements Parcelable { dest.writeInt(leaseDuration); } - /** Implement the Parcelable interface {@hide} */ + /** Implement the Parcelable interface */ public static final @android.annotation.NonNull Creator<DhcpInfo> CREATOR = new Creator<DhcpInfo>() { public DhcpInfo createFromParcel(Parcel in) { diff --git a/core/java/android/net/DhcpResults.java b/core/java/android/net/DhcpResults.java index 97be51a30641..059cd94accfe 100644 --- a/core/java/android/net/DhcpResults.java +++ b/core/java/android/net/DhcpResults.java @@ -16,7 +16,7 @@ package android.net; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.net.shared.InetAddressUtils; import android.os.Parcel; import android.os.Parcelable; diff --git a/core/java/android/net/EthernetManager.java b/core/java/android/net/EthernetManager.java index 72565024d3a5..fd015b4fe52c 100644 --- a/core/java/android/net/EthernetManager.java +++ b/core/java/android/net/EthernetManager.java @@ -17,7 +17,7 @@ package android.net; import android.annotation.SystemService; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; import android.os.Handler; import android.os.Message; diff --git a/core/java/android/net/ICaptivePortal.aidl b/core/java/android/net/ICaptivePortal.aidl index 707b4f699873..fe21905c7002 100644 --- a/core/java/android/net/ICaptivePortal.aidl +++ b/core/java/android/net/ICaptivePortal.aidl @@ -21,6 +21,7 @@ package android.net; * @hide */ oneway interface ICaptivePortal { + void appRequest(int request); void appResponse(int response); void logEvent(int eventId, String packageName); } diff --git a/core/java/android/net/IConnectivityManager.aidl b/core/java/android/net/IConnectivityManager.aidl index 09c02efbcfc4..e6a0379ff629 100644 --- a/core/java/android/net/IConnectivityManager.aidl +++ b/core/java/android/net/IConnectivityManager.aidl @@ -142,12 +142,16 @@ interface IConnectivityManager void setAirplaneMode(boolean enable); - int registerNetworkFactory(in Messenger messenger, in String name); - boolean requestBandwidthUpdate(in Network network); + int registerNetworkFactory(in Messenger messenger, in String name); void unregisterNetworkFactory(in Messenger messenger); + int registerNetworkProvider(in Messenger messenger, in String name); + void unregisterNetworkProvider(in Messenger messenger); + + void declareNetworkRequestUnfulfillable(in NetworkRequest request); + int registerNetworkAgent(in Messenger messenger, in NetworkInfo ni, in LinkProperties lp, in NetworkCapabilities nc, int score, in NetworkMisc misc, in int factorySerialNumber); diff --git a/core/java/android/net/INetworkPolicyListener.aidl b/core/java/android/net/INetworkPolicyListener.aidl index 10667aecd128..fe9141cb6a20 100644 --- a/core/java/android/net/INetworkPolicyListener.aidl +++ b/core/java/android/net/INetworkPolicyListener.aidl @@ -15,6 +15,7 @@ */ package android.net; +import android.telephony.SubscriptionPlan; /** {@hide} */ oneway interface INetworkPolicyListener { @@ -23,4 +24,5 @@ oneway interface INetworkPolicyListener { void onRestrictBackgroundChanged(boolean restrictBackground); void onUidPoliciesChanged(int uid, int uidPolicies); void onSubscriptionOverride(int subId, int overrideMask, int overrideValue); + void onSubscriptionPlansChanged(int subId, in SubscriptionPlan[] plans); } diff --git a/core/java/android/net/INetworkPolicyManager.aidl b/core/java/android/net/INetworkPolicyManager.aidl index 385cb1d68b57..72a6b397a30c 100644 --- a/core/java/android/net/INetworkPolicyManager.aidl +++ b/core/java/android/net/INetworkPolicyManager.aidl @@ -57,9 +57,6 @@ interface INetworkPolicyManager { @UnsupportedAppUsage boolean getRestrictBackground(); - /** Callback used to change internal state on tethering */ - void onTetheringChanged(String iface, boolean tethering); - /** Gets the restrict background status based on the caller's UID: 1 - disabled 2 - whitelisted diff --git a/core/java/android/net/INetworkStatsService.aidl b/core/java/android/net/INetworkStatsService.aidl index 9994f9f82b07..5fa515a14343 100644 --- a/core/java/android/net/INetworkStatsService.aidl +++ b/core/java/android/net/INetworkStatsService.aidl @@ -23,6 +23,8 @@ import android.net.NetworkState; import android.net.NetworkStats; import android.net.NetworkStatsHistory; import android.net.NetworkTemplate; +import android.net.netstats.provider.INetworkStatsProvider; +import android.net.netstats.provider.INetworkStatsProviderCallback; import android.os.IBinder; import android.os.Messenger; import com.android.internal.net.VpnInfo; @@ -89,4 +91,7 @@ interface INetworkStatsService { /** Get the total network stats information since boot */ long getTotalStats(int type); + /** Registers a network stats provider */ + INetworkStatsProviderCallback registerNetworkStatsProvider(String tag, + in INetworkStatsProvider provider); } diff --git a/core/java/android/net/InterfaceConfiguration.java b/core/java/android/net/InterfaceConfiguration.java index 1ae44e169851..37425ffc18aa 100644 --- a/core/java/android/net/InterfaceConfiguration.java +++ b/core/java/android/net/InterfaceConfiguration.java @@ -16,7 +16,7 @@ package android.net; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.os.Parcel; import android.os.Parcelable; diff --git a/core/java/android/net/InvalidPacketException.java b/core/java/android/net/InvalidPacketException.java new file mode 100644 index 000000000000..909998d4562c --- /dev/null +++ b/core/java/android/net/InvalidPacketException.java @@ -0,0 +1,61 @@ +/* + * 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.annotation.IntDef; +import android.annotation.SystemApi; + +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; + +/** + * Thrown when a packet is invalid. + * @hide + */ +@SystemApi +public class InvalidPacketException extends Exception { + public final int error; + + // Must match SocketKeepalive#ERROR_INVALID_IP_ADDRESS. + /** Invalid IP address. */ + public static final int ERROR_INVALID_IP_ADDRESS = -21; + + // Must match SocketKeepalive#ERROR_INVALID_PORT. + /** Invalid port number. */ + public static final int ERROR_INVALID_PORT = -22; + + // Must match SocketKeepalive#ERROR_INVALID_LENGTH. + /** Invalid packet length. */ + public static final int ERROR_INVALID_LENGTH = -23; + + /** @hide */ + @Retention(RetentionPolicy.SOURCE) + @IntDef(prefix = { "ERROR_" }, value = { + ERROR_INVALID_IP_ADDRESS, + ERROR_INVALID_PORT, + ERROR_INVALID_LENGTH + }) + public @interface ErrorCode {} + + /** + * This packet is invalid. + * See the error code for details. + */ + public InvalidPacketException(@ErrorCode final int error) { + this.error = error; + } +} diff --git a/core/java/android/net/IpConfiguration.java b/core/java/android/net/IpConfiguration.java index dddb64d8cece..23d5ff7f3afe 100644 --- a/core/java/android/net/IpConfiguration.java +++ b/core/java/android/net/IpConfiguration.java @@ -20,8 +20,7 @@ import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.SuppressLint; import android.annotation.SystemApi; -import android.annotation.UnsupportedAppUsage; -import android.net.StaticIpConfiguration; +import android.compat.annotation.UnsupportedAppUsage; import android.os.Parcel; import android.os.Parcelable; diff --git a/core/java/android/net/IpSecManager.java b/core/java/android/net/IpSecManager.java index 45d0c7313fca..09ec6c35fcb9 100644 --- a/core/java/android/net/IpSecManager.java +++ b/core/java/android/net/IpSecManager.java @@ -17,7 +17,6 @@ package android.net; import static com.android.internal.util.Preconditions.checkNotNull; -import android.annotation.IntDef; import android.annotation.NonNull; import android.annotation.RequiresFeature; import android.annotation.RequiresPermission; @@ -26,6 +25,7 @@ import android.annotation.SystemService; import android.annotation.TestApi; import android.content.Context; import android.content.pm.PackageManager; +import android.net.annotations.PolicyDirection; import android.os.Binder; import android.os.ParcelFileDescriptor; import android.os.RemoteException; @@ -41,8 +41,6 @@ import dalvik.system.CloseGuard; import java.io.FileDescriptor; import java.io.IOException; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; import java.net.DatagramSocket; import java.net.InetAddress; import java.net.Socket; @@ -78,11 +76,6 @@ public final class IpSecManager { */ public static final int DIRECTION_OUT = 1; - /** @hide */ - @IntDef(value = {DIRECTION_IN, DIRECTION_OUT}) - @Retention(RetentionPolicy.SOURCE) - public @interface PolicyDirection {} - /** * The Security Parameter Index (SPI) 0 indicates an unknown or invalid index. * diff --git a/core/java/android/net/KeepalivePacketData.java b/core/java/android/net/KeepalivePacketData.java index 9b8b7322cd23..2b8b7e69dec9 100644 --- a/core/java/android/net/KeepalivePacketData.java +++ b/core/java/android/net/KeepalivePacketData.java @@ -16,13 +16,13 @@ package android.net; -import static android.net.SocketKeepalive.ERROR_INVALID_IP_ADDRESS; -import static android.net.SocketKeepalive.ERROR_INVALID_PORT; +import static android.net.InvalidPacketException.ERROR_INVALID_IP_ADDRESS; +import static android.net.InvalidPacketException.ERROR_INVALID_PORT; -import android.net.SocketKeepalive.InvalidPacketException; +import android.annotation.NonNull; +import android.annotation.SystemApi; import android.net.util.IpUtils; import android.os.Parcel; -import android.os.Parcelable; import android.util.Log; import java.net.InetAddress; @@ -33,13 +33,16 @@ import java.net.InetAddress; * * @hide */ -public class KeepalivePacketData implements Parcelable { +@SystemApi +public class KeepalivePacketData { private static final String TAG = "KeepalivePacketData"; /** Source IP address */ + @NonNull public final InetAddress srcAddress; /** Destination IP address */ + @NonNull public final InetAddress dstAddress; /** Source port */ @@ -51,13 +54,14 @@ public class KeepalivePacketData implements Parcelable { /** Packet data. A raw byte string of packet data, not including the link-layer header. */ private final byte[] mPacket; - protected static final int IPV4_HEADER_LENGTH = 20; - protected static final int UDP_HEADER_LENGTH = 8; - // This should only be constructed via static factory methods, such as - // nattKeepalivePacket - protected KeepalivePacketData(InetAddress srcAddress, int srcPort, - InetAddress dstAddress, int dstPort, byte[] data) throws InvalidPacketException { + // nattKeepalivePacket. + /** + * A holding class for data necessary to build a keepalive packet. + */ + protected KeepalivePacketData(@NonNull InetAddress srcAddress, int srcPort, + @NonNull InetAddress dstAddress, int dstPort, + @NonNull byte[] data) throws InvalidPacketException { this.srcAddress = srcAddress; this.dstAddress = dstAddress; this.srcPort = srcPort; @@ -78,16 +82,12 @@ public class KeepalivePacketData implements Parcelable { } } + @NonNull public byte[] getPacket() { return mPacket.clone(); } - /* Parcelable Implementation */ - public int describeContents() { - return 0; - } - - /** Write to parcel */ + /** @hide */ public void writeToParcel(Parcel out, int flags) { out.writeString(srcAddress.getHostAddress()); out.writeString(dstAddress.getHostAddress()); @@ -96,6 +96,7 @@ public class KeepalivePacketData implements Parcelable { out.writeByteArray(mPacket); } + /** @hide */ protected KeepalivePacketData(Parcel in) { srcAddress = NetworkUtils.numericToInetAddress(in.readString()); dstAddress = NetworkUtils.numericToInetAddress(in.readString()); @@ -103,17 +104,4 @@ public class KeepalivePacketData implements Parcelable { dstPort = in.readInt(); mPacket = in.createByteArray(); } - - /** Parcelable Creator */ - public static final @android.annotation.NonNull Parcelable.Creator<KeepalivePacketData> CREATOR = - new Parcelable.Creator<KeepalivePacketData>() { - public KeepalivePacketData createFromParcel(Parcel in) { - return new KeepalivePacketData(in); - } - - public KeepalivePacketData[] newArray(int size) { - return new KeepalivePacketData[size]; - } - }; - } diff --git a/core/java/android/net/LinkAddress.java b/core/java/android/net/LinkAddress.java index 93dd2e4d7717..bf8b38fc7f84 100644 --- a/core/java/android/net/LinkAddress.java +++ b/core/java/android/net/LinkAddress.java @@ -30,7 +30,7 @@ import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.SystemApi; import android.annotation.TestApi; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.os.Build; import android.os.Parcel; import android.os.Parcelable; diff --git a/core/java/android/net/LinkProperties.java b/core/java/android/net/LinkProperties.java index 89ec3e776d41..2792c564988a 100644 --- a/core/java/android/net/LinkProperties.java +++ b/core/java/android/net/LinkProperties.java @@ -20,7 +20,7 @@ import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.SystemApi; import android.annotation.TestApi; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.os.Build; import android.os.Parcel; import android.os.Parcelable; diff --git a/core/java/android/net/LinkQualityInfo.java b/core/java/android/net/LinkQualityInfo.java index 2e6915ff4aa5..aa56cff50f63 100644 --- a/core/java/android/net/LinkQualityInfo.java +++ b/core/java/android/net/LinkQualityInfo.java @@ -16,7 +16,7 @@ package android.net; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.os.Parcel; import android.os.Parcelable; diff --git a/core/java/android/net/LocalSocket.java b/core/java/android/net/LocalSocket.java index 6a2031b4131d..5b38f78782a8 100644 --- a/core/java/android/net/LocalSocket.java +++ b/core/java/android/net/LocalSocket.java @@ -16,7 +16,8 @@ package android.net; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; + import java.io.Closeable; import java.io.FileDescriptor; import java.io.IOException; diff --git a/core/java/android/net/LocalSocketImpl.java b/core/java/android/net/LocalSocketImpl.java index b066a15106af..e80e3a6f93ec 100644 --- a/core/java/android/net/LocalSocketImpl.java +++ b/core/java/android/net/LocalSocketImpl.java @@ -16,7 +16,7 @@ package android.net; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.system.ErrnoException; import android.system.Int32Ref; import android.system.Os; diff --git a/core/java/android/net/MacAddress.java b/core/java/android/net/MacAddress.java index 87295142bec4..74c9aac05b41 100644 --- a/core/java/android/net/MacAddress.java +++ b/core/java/android/net/MacAddress.java @@ -19,7 +19,7 @@ package android.net; import android.annotation.IntDef; import android.annotation.NonNull; import android.annotation.Nullable; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.net.wifi.WifiInfo; import android.os.Parcel; import android.os.Parcelable; diff --git a/core/java/android/net/MobileLinkQualityInfo.java b/core/java/android/net/MobileLinkQualityInfo.java index a10a14d750d8..a65de6bb2908 100644 --- a/core/java/android/net/MobileLinkQualityInfo.java +++ b/core/java/android/net/MobileLinkQualityInfo.java @@ -16,7 +16,7 @@ package android.net; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.os.Parcel; /** diff --git a/core/java/android/net/NattKeepalivePacketData.java b/core/java/android/net/NattKeepalivePacketData.java index a77c244d6b40..bd39c13ba092 100644 --- a/core/java/android/net/NattKeepalivePacketData.java +++ b/core/java/android/net/NattKeepalivePacketData.java @@ -16,10 +16,11 @@ package android.net; -import static android.net.SocketKeepalive.ERROR_INVALID_IP_ADDRESS; -import static android.net.SocketKeepalive.ERROR_INVALID_PORT; +import static android.net.InvalidPacketException.ERROR_INVALID_IP_ADDRESS; +import static android.net.InvalidPacketException.ERROR_INVALID_PORT; -import android.net.SocketKeepalive.InvalidPacketException; +import android.annotation.NonNull; +import android.annotation.SystemApi; import android.net.util.IpUtils; import android.os.Parcel; import android.os.Parcelable; @@ -31,17 +32,22 @@ import java.nio.ByteBuffer; import java.nio.ByteOrder; /** @hide */ +@SystemApi public final class NattKeepalivePacketData extends KeepalivePacketData implements Parcelable { + private static final int IPV4_HEADER_LENGTH = 20; + private static final int UDP_HEADER_LENGTH = 8; + // This should only be constructed via static factory methods, such as // nattKeepalivePacket - private NattKeepalivePacketData(InetAddress srcAddress, int srcPort, - InetAddress dstAddress, int dstPort, byte[] data) throws + public NattKeepalivePacketData(@NonNull InetAddress srcAddress, int srcPort, + @NonNull InetAddress dstAddress, int dstPort, @NonNull byte[] data) throws InvalidPacketException { super(srcAddress, srcPort, dstAddress, dstPort, data); } /** * Factory method to create Nat-T keepalive packet structure. + * @hide */ public static NattKeepalivePacketData nattKeepalivePacket( InetAddress srcAddress, int srcPort, InetAddress dstAddress, int dstPort) @@ -85,7 +91,7 @@ public final class NattKeepalivePacketData extends KeepalivePacketData implement } /** Write to parcel */ - public void writeToParcel(Parcel out, int flags) { + public void writeToParcel(@NonNull Parcel out, int flags) { out.writeString(srcAddress.getHostAddress()); out.writeString(dstAddress.getHostAddress()); out.writeInt(srcPort); @@ -93,7 +99,7 @@ public final class NattKeepalivePacketData extends KeepalivePacketData implement } /** Parcelable Creator */ - public static final Parcelable.Creator<NattKeepalivePacketData> CREATOR = + public static final @NonNull Parcelable.Creator<NattKeepalivePacketData> CREATOR = new Parcelable.Creator<NattKeepalivePacketData>() { public NattKeepalivePacketData createFromParcel(Parcel in) { final InetAddress srcAddress = diff --git a/core/java/android/net/Network.java b/core/java/android/net/Network.java index f12ba1367d98..8d1ab332ce12 100644 --- a/core/java/android/net/Network.java +++ b/core/java/android/net/Network.java @@ -19,7 +19,7 @@ package android.net; import android.annotation.NonNull; import android.annotation.SystemApi; import android.annotation.TestApi; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.os.Parcel; import android.os.Parcelable; import android.system.ErrnoException; diff --git a/core/java/android/net/NetworkAgent.java b/core/java/android/net/NetworkAgent.java index ff4bf2d3474c..5f6cc6eced5d 100644 --- a/core/java/android/net/NetworkAgent.java +++ b/core/java/android/net/NetworkAgent.java @@ -17,7 +17,7 @@ package android.net; import android.annotation.NonNull; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; import android.os.Build; import android.os.Bundle; @@ -58,7 +58,7 @@ public abstract class NetworkAgent extends Handler { private static final long BW_REFRESH_MIN_WIN_MS = 500; private boolean mPollLceScheduled = false; private AtomicBoolean mPollLcePending = new AtomicBoolean(false); - public final int mFactorySerialNumber; + public final int mProviderId; private static final int BASE = Protocol.BASE_NETWORK_AGENT; @@ -219,25 +219,25 @@ public abstract class NetworkAgent extends Handler { // the entire tree. public NetworkAgent(Looper looper, Context context, String logTag, NetworkInfo ni, NetworkCapabilities nc, LinkProperties lp, int score) { - this(looper, context, logTag, ni, nc, lp, score, null, NetworkFactory.SerialNumber.NONE); + this(looper, context, logTag, ni, nc, lp, score, null, NetworkProvider.ID_NONE); } public NetworkAgent(Looper looper, Context context, String logTag, NetworkInfo ni, NetworkCapabilities nc, LinkProperties lp, int score, NetworkMisc misc) { - this(looper, context, logTag, ni, nc, lp, score, misc, NetworkFactory.SerialNumber.NONE); + this(looper, context, logTag, ni, nc, lp, score, misc, NetworkProvider.ID_NONE); } public NetworkAgent(Looper looper, Context context, String logTag, NetworkInfo ni, - NetworkCapabilities nc, LinkProperties lp, int score, int factorySerialNumber) { - this(looper, context, logTag, ni, nc, lp, score, null, factorySerialNumber); + NetworkCapabilities nc, LinkProperties lp, int score, int providerId) { + this(looper, context, logTag, ni, nc, lp, score, null, providerId); } public NetworkAgent(Looper looper, Context context, String logTag, NetworkInfo ni, NetworkCapabilities nc, LinkProperties lp, int score, NetworkMisc misc, - int factorySerialNumber) { + int providerId) { super(looper); LOG_TAG = logTag; mContext = context; - mFactorySerialNumber = factorySerialNumber; + mProviderId = providerId; if (ni == null || nc == null || lp == null) { throw new IllegalArgumentException(); } @@ -246,8 +246,7 @@ public abstract class NetworkAgent extends Handler { ConnectivityManager cm = (ConnectivityManager)mContext.getSystemService( Context.CONNECTIVITY_SERVICE); netId = cm.registerNetworkAgent(new Messenger(this), new NetworkInfo(ni), - new LinkProperties(lp), new NetworkCapabilities(nc), score, misc, - factorySerialNumber); + new LinkProperties(lp), new NetworkCapabilities(nc), score, misc, providerId); } @Override diff --git a/core/java/android/net/NetworkCapabilities.java b/core/java/android/net/NetworkCapabilities.java index 421e61b76fab..f43385d1f2e0 100644 --- a/core/java/android/net/NetworkCapabilities.java +++ b/core/java/android/net/NetworkCapabilities.java @@ -21,7 +21,7 @@ import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.SystemApi; import android.annotation.TestApi; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.net.ConnectivityManager.NetworkCallback; import android.os.Build; import android.os.Parcel; @@ -587,15 +587,14 @@ public final class NetworkCapabilities implements Parcelable { } /** - * Removes the NET_CAPABILITY_NOT_RESTRICTED capability if all the capabilities it provides are - * typically provided by restricted networks. + * Deduces that all the capabilities it provides are typically provided by restricted networks + * or not. * - * TODO: consider: - * - Renaming it to guessRestrictedCapability and make it set the - * restricted capability bit in addition to clearing it. + * @return {@code true} if the network should be restricted. * @hide */ - public void maybeMarkCapabilitiesRestricted() { + @SystemApi + public boolean deduceRestrictedCapability() { // Check if we have any capability that forces the network to be restricted. final boolean forceRestrictedCapability = (mNetworkCapabilities & FORCE_RESTRICTED_CAPABILITIES) != 0; @@ -609,8 +608,17 @@ public final class NetworkCapabilities implements Parcelable { final boolean hasRestrictedCapabilities = (mNetworkCapabilities & RESTRICTED_CAPABILITIES) != 0; - if (forceRestrictedCapability - || (hasRestrictedCapabilities && !hasUnrestrictedCapabilities)) { + return forceRestrictedCapability + || (hasRestrictedCapabilities && !hasUnrestrictedCapabilities); + } + + /** + * Removes the NET_CAPABILITY_NOT_RESTRICTED capability if deducing the network is restricted. + * + * @hide + */ + public void maybeMarkCapabilitiesRestricted() { + if (deduceRestrictedCapability()) { removeCapability(NET_CAPABILITY_NOT_RESTRICTED); } } diff --git a/core/java/android/net/NetworkFactory.java b/core/java/android/net/NetworkFactory.java index 5b1d12c603b4..824ddb8dd260 100644 --- a/core/java/android/net/NetworkFactory.java +++ b/core/java/android/net/NetworkFactory.java @@ -16,7 +16,8 @@ package android.net; -import android.annotation.UnsupportedAppUsage; +import android.annotation.NonNull; +import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; import android.os.Build; import android.os.Handler; @@ -27,7 +28,6 @@ import android.util.Log; import android.util.SparseArray; import com.android.internal.annotations.VisibleForTesting; -import com.android.internal.util.AsyncChannel; import com.android.internal.util.IndentingPrintWriter; import com.android.internal.util.Protocol; @@ -52,7 +52,7 @@ import java.util.concurrent.atomic.AtomicInteger; * @hide **/ public class NetworkFactory extends Handler { - /** @hide */ + /* TODO: delete when all callers have migrated to NetworkProvider IDs. */ public static class SerialNumber { // Guard used by no network factory. public static final int NONE = -1; @@ -91,8 +91,8 @@ public class NetworkFactory extends Handler { * with the same NetworkRequest but an updated score. * Also, network conditions may change for this bearer * allowing for a better score in the future. - * msg.arg2 = the serial number of the factory currently responsible for the - * NetworkAgent handling this request, or SerialNumber.NONE if none. + * msg.arg2 = the ID of the NetworkProvider currently responsible for the + * NetworkAgent handling this request, or NetworkProvider.ID_NONE if none. */ public static final int CMD_REQUEST_NETWORK = BASE; @@ -124,7 +124,6 @@ public class NetworkFactory extends Handler { private final Context mContext; private final ArrayList<Message> mPreConnectedQueue = new ArrayList<Message>(); - private AsyncChannel mAsyncChannel; private final String LOG_TAG; private final SparseArray<NetworkRequestInfo> mNetworkRequests = @@ -135,7 +134,8 @@ public class NetworkFactory extends Handler { private int mRefCount = 0; private Messenger mMessenger = null; - private int mSerialNumber; + private NetworkProvider mProvider = null; + private int mProviderId; @UnsupportedAppUsage public NetworkFactory(Looper looper, Context context, String logTag, @@ -147,55 +147,43 @@ public class NetworkFactory extends Handler { } public void register() { - if (DBG) log("Registering NetworkFactory"); - if (mMessenger == null) { - mMessenger = new Messenger(this); - mSerialNumber = ConnectivityManager.from(mContext).registerNetworkFactory(mMessenger, - LOG_TAG); + if (mProvider != null) { + Log.e(LOG_TAG, "Ignoring attempt to register already-registered NetworkFactory"); + return; } + if (DBG) log("Registering NetworkFactory"); + + mProvider = new NetworkProvider(mContext, NetworkFactory.this.getLooper(), LOG_TAG) { + @Override + public void onNetworkRequested(@NonNull NetworkRequest request, int score, + int servingProviderId) { + handleAddRequest((NetworkRequest) request, score, servingProviderId); + } + + @Override + public void onRequestWithdrawn(@NonNull NetworkRequest request) { + handleRemoveRequest(request); + } + }; + + mMessenger = new Messenger(this); + mProviderId = ConnectivityManager.from(mContext).registerNetworkProvider(mProvider); } public void unregister() { - if (DBG) log("Unregistering NetworkFactory"); - if (mMessenger != null) { - ConnectivityManager.from(mContext).unregisterNetworkFactory(mMessenger); - mMessenger = null; + if (mProvider == null) { + Log.e(LOG_TAG, "Ignoring attempt to unregister unregistered NetworkFactory"); + return; } + if (DBG) log("Unregistering NetworkFactory"); + + ConnectivityManager.from(mContext).unregisterNetworkProvider(mProvider); + mProvider = null; } @Override public void handleMessage(Message msg) { switch (msg.what) { - case AsyncChannel.CMD_CHANNEL_FULL_CONNECTION: { - if (mAsyncChannel != null) { - log("Received new connection while already connected!"); - break; - } - if (VDBG) log("NetworkFactory fully connected"); - AsyncChannel ac = new AsyncChannel(); - ac.connected(null, this, msg.replyTo); - ac.replyToMessage(msg, AsyncChannel.CMD_CHANNEL_FULLY_CONNECTED, - AsyncChannel.STATUS_SUCCESSFUL); - mAsyncChannel = ac; - for (Message m : mPreConnectedQueue) { - ac.sendMessage(m); - } - mPreConnectedQueue.clear(); - break; - } - case AsyncChannel.CMD_CHANNEL_DISCONNECT: { - if (VDBG) log("CMD_CHANNEL_DISCONNECT"); - if (mAsyncChannel != null) { - mAsyncChannel.disconnect(); - mAsyncChannel = null; - } - break; - } - case AsyncChannel.CMD_CHANNEL_DISCONNECTED: { - if (DBG) log("NetworkFactory channel lost"); - mAsyncChannel = null; - break; - } case CMD_REQUEST_NETWORK: { handleAddRequest((NetworkRequest) msg.obj, msg.arg1, msg.arg2); break; @@ -219,13 +207,13 @@ public class NetworkFactory extends Handler { public final NetworkRequest request; public int score; public boolean requested; // do we have a request outstanding, limited by score - public int factorySerialNumber; + public int providerId; - NetworkRequestInfo(NetworkRequest request, int score, int factorySerialNumber) { + NetworkRequestInfo(NetworkRequest request, int score, int providerId) { this.request = request; this.score = score; this.requested = false; - this.factorySerialNumber = factorySerialNumber; + this.providerId = providerId; } @Override @@ -240,8 +228,6 @@ public class NetworkFactory extends Handler { * * @param request the request to handle. * @param score the score of the NetworkAgent currently satisfying this request. - * @param servingFactorySerialNumber the serial number of the NetworkFactory that - * created the NetworkAgent currently satisfying this request. */ // TODO : remove this method. It is a stopgap measure to help sheperding a number // of dependent changes that would conflict throughout the automerger graph. Having this @@ -249,7 +235,7 @@ public class NetworkFactory extends Handler { // the entire tree. @VisibleForTesting protected void handleAddRequest(NetworkRequest request, int score) { - handleAddRequest(request, score, SerialNumber.NONE); + handleAddRequest(request, score, NetworkProvider.ID_NONE); } /** @@ -258,27 +244,26 @@ public class NetworkFactory extends Handler { * * @param request the request to handle. * @param score the score of the NetworkAgent currently satisfying this request. - * @param servingFactorySerialNumber the serial number of the NetworkFactory that - * created the NetworkAgent currently satisfying this request. + * @param servingProviderId the ID of the NetworkProvider that created the NetworkAgent + * currently satisfying this request. */ @VisibleForTesting - protected void handleAddRequest(NetworkRequest request, int score, - int servingFactorySerialNumber) { + protected void handleAddRequest(NetworkRequest request, int score, int servingProviderId) { NetworkRequestInfo n = mNetworkRequests.get(request.requestId); if (n == null) { if (DBG) { log("got request " + request + " with score " + score - + " and serial " + servingFactorySerialNumber); + + " and providerId " + servingProviderId); } - n = new NetworkRequestInfo(request, score, servingFactorySerialNumber); + n = new NetworkRequestInfo(request, score, servingProviderId); mNetworkRequests.put(n.request.requestId, n); } else { if (VDBG) { log("new score " + score + " for exisiting request " + request - + " with serial " + servingFactorySerialNumber); + + " and providerId " + servingProviderId); } n.score = score; - n.factorySerialNumber = servingFactorySerialNumber; + n.providerId = servingProviderId; } if (VDBG) log(" my score=" + mScore + ", my filter=" + mCapabilityFilter); @@ -333,8 +318,8 @@ public class NetworkFactory extends Handler { log(" n.requests = " + n.requested); log(" n.score = " + n.score); log(" mScore = " + mScore); - log(" n.factorySerialNumber = " + n.factorySerialNumber); - log(" mSerialNumber = " + mSerialNumber); + log(" n.providerId = " + n.providerId); + log(" mProviderId = " + mProviderId); } if (shouldNeedNetworkFor(n)) { if (VDBG) log(" needNetworkFor"); @@ -355,7 +340,7 @@ public class NetworkFactory extends Handler { // If the score of this request is higher or equal to that of this factory and some // other factory is responsible for it, then this factory should not track the request // because it has no hope of satisfying it. - && (n.score < mScore || n.factorySerialNumber == mSerialNumber) + && (n.score < mScore || n.providerId == mProviderId) // If this factory can't satisfy the capability needs of this request, then it // should not be tracked. && n.request.networkCapabilities.satisfiedByNetworkCapabilities(mCapabilityFilter) @@ -373,7 +358,7 @@ public class NetworkFactory extends Handler { // assigned to the factory // - This factory can't satisfy the capability needs of the request // - The concrete implementation of the factory rejects the request - && ((n.score > mScore && n.factorySerialNumber != mSerialNumber) + && ((n.score > mScore && n.providerId != mProviderId) || !n.request.networkCapabilities.satisfiedByNetworkCapabilities( mCapabilityFilter) || !acceptRequest(n.request, n.score)); @@ -408,12 +393,7 @@ public class NetworkFactory extends Handler { protected void releaseRequestAsUnfulfillableByAnyFactory(NetworkRequest r) { post(() -> { if (DBG) log("releaseRequestAsUnfulfillableByAnyFactory: " + r); - Message msg = obtainMessage(EVENT_UNFULFILLABLE_REQUEST, r); - if (mAsyncChannel != null) { - mAsyncChannel.sendMessage(msg); - } else { - mPreConnectedQueue.add(msg); - } + ConnectivityManager.from(mContext).declareNetworkRequestUnfulfillable(r); }); } @@ -444,8 +424,13 @@ public class NetworkFactory extends Handler { return mNetworkRequests.size(); } + /* TODO: delete when all callers have migrated to NetworkProvider IDs. */ public int getSerialNumber() { - return mSerialNumber; + return mProviderId; + } + + public int getProviderId() { + return mProviderId; } protected void log(String s) { @@ -465,8 +450,8 @@ public class NetworkFactory extends Handler { @Override public String toString() { - StringBuilder sb = new StringBuilder("{").append(LOG_TAG).append(" - mSerialNumber=") - .append(mSerialNumber).append(", ScoreFilter=") + StringBuilder sb = new StringBuilder("{").append(LOG_TAG).append(" - mProviderId=") + .append(mProviderId).append(", ScoreFilter=") .append(mScore).append(", Filter=").append(mCapabilityFilter).append(", requests=") .append(mNetworkRequests.size()).append(", refCount=").append(mRefCount) .append("}"); diff --git a/core/java/android/net/NetworkInfo.java b/core/java/android/net/NetworkInfo.java index 92f105f77172..d0c536316527 100644 --- a/core/java/android/net/NetworkInfo.java +++ b/core/java/android/net/NetworkInfo.java @@ -17,7 +17,7 @@ package android.net; import android.annotation.NonNull; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.os.Parcel; import android.os.Parcelable; diff --git a/core/java/android/net/NetworkPolicy.java b/core/java/android/net/NetworkPolicy.java index 33baebbbe857..4f05c9bbb2e3 100644 --- a/core/java/android/net/NetworkPolicy.java +++ b/core/java/android/net/NetworkPolicy.java @@ -16,7 +16,7 @@ package android.net; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.os.Parcel; import android.os.Parcelable; import android.util.BackupUtils; diff --git a/core/java/android/net/NetworkPolicyManager.java b/core/java/android/net/NetworkPolicyManager.java index bf272625e713..de962f8f25e3 100644 --- a/core/java/android/net/NetworkPolicyManager.java +++ b/core/java/android/net/NetworkPolicyManager.java @@ -19,8 +19,8 @@ package android.net; import static android.content.pm.PackageManager.GET_SIGNATURES; import android.annotation.SystemService; -import android.annotation.UnsupportedAppUsage; import android.app.ActivityManager; +import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; import android.content.Intent; import android.content.pm.PackageManager; @@ -31,6 +31,7 @@ import android.net.wifi.WifiInfo; import android.os.Build; import android.os.RemoteException; import android.os.UserHandle; +import android.telephony.SubscriptionPlan; import android.util.DebugUtils; import android.util.Pair; import android.util.Range; @@ -380,6 +381,8 @@ public class NetworkPolicyManager { @Override public void onMeteredIfacesChanged(String[] meteredIfaces) { } @Override public void onRestrictBackgroundChanged(boolean restrictBackground) { } @Override public void onUidPoliciesChanged(int uid, int uidPolicies) { } - @Override public void onSubscriptionOverride(int subId, int overrideMask, int overrideValue) { } + @Override public void onSubscriptionOverride(int subId, int overrideMask, + int overrideValue) { } + @Override public void onSubscriptionPlansChanged(int subId, SubscriptionPlan[] plans) { } } } diff --git a/core/java/android/net/NetworkProvider.java b/core/java/android/net/NetworkProvider.java new file mode 100644 index 000000000000..2c0e4aa700b1 --- /dev/null +++ b/core/java/android/net/NetworkProvider.java @@ -0,0 +1,166 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR 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.annotation.NonNull; +import android.annotation.Nullable; +import android.annotation.RequiresPermission; +import android.annotation.SystemApi; +import android.content.Context; +import android.os.Handler; +import android.os.Looper; +import android.os.Message; +import android.os.Messenger; +import android.util.Log; + +/** + * Base class for network providers such as telephony or Wi-Fi. NetworkProviders connect the device + * to networks and makes them available to to the core network stack by creating + * {@link NetworkAgent}s. The networks can then provide connectivity to apps and can be interacted + * with via networking APIs such as {@link ConnectivityManager}. + * + * Subclasses should implement {@link #onNetworkRequested} and {@link #onRequestWithdrawn} to + * receive {@link NetworkRequest}s sent by the system and by apps. A network that is not the + * best (highest-scoring) network for any request is generally not used by the system, and torn + * down. + * + * @hide + */ +@SystemApi +public class NetworkProvider { + /** + * {@code providerId} value that indicates the absence of a provider. It is the providerId of + * any NetworkProvider that is not currently registered, and of any NetworkRequest that is not + * currently being satisfied by a network. + */ + public static final int ID_NONE = -1; + + /** + * A hardcoded ID for NetworkAgents representing VPNs. These agents are not created by any + * provider, so they use this constant for clarity instead of NONE. + * @hide only used by ConnectivityService. + */ + public static final int ID_VPN = -2; + + /** + * The first providerId value that will be allocated. + * @hide only used by ConnectivityService. + */ + public static final int FIRST_PROVIDER_ID = 1; + + /** @hide only used by ConnectivityService */ + public static final int CMD_REQUEST_NETWORK = 1; + /** @hide only used by ConnectivityService */ + public static final int CMD_CANCEL_REQUEST = 2; + + private final Messenger mMessenger; + private final String mName; + private final ConnectivityManager mCm; + + private int mProviderId = ID_NONE; + + /** + * Constructs a new NetworkProvider. + * + * @param looper the Looper on which to run {@link #onNetworkRequested} and + * {@link #onRequestWithdrawn}. + * @param name the name of the listener, used only for debugging. + * + * @hide + */ + @SystemApi + public NetworkProvider(@NonNull Context context, @NonNull Looper looper, @NonNull String name) { + mCm = ConnectivityManager.from(context); + + Handler handler = new Handler(looper) { + @Override + public void handleMessage(Message m) { + switch (m.what) { + case CMD_REQUEST_NETWORK: + onNetworkRequested((NetworkRequest) m.obj, m.arg1, m.arg2); + break; + case CMD_CANCEL_REQUEST: + onRequestWithdrawn((NetworkRequest) m.obj); + break; + default: + Log.e(mName, "Unhandled message: " + m.what); + } + } + }; + mMessenger = new Messenger(handler); + mName = name; + } + + // TODO: consider adding a register() method so ConnectivityManager does not need to call this. + public @Nullable Messenger getMessenger() { + return mMessenger; + } + + public @NonNull String getName() { + return mName; + } + + /** + * Returns the ID of this provider. This is known only once the provider is registered via + * {@link ConnectivityManager#registerNetworkProvider()}, otherwise the ID is {@link #ID_NONE}. + * This ID must be used when registering any {@link NetworkAgent}s. + */ + public int getProviderId() { + return mProviderId; + } + + /** @hide */ + public void setProviderId(int providerId) { + mProviderId = providerId; + } + + /** + * Called when a NetworkRequest is received. The request may be a new request or an existing + * request with a different score. + * + * @param request the NetworkRequest being received + * @param score the score of the network currently satisfying the request, or 0 if none. + * @param providerId the ID of the provider that created the network currently satisfying this + * request, or {@link #ID_NONE} if none. + * + * @hide + */ + @SystemApi + public void onNetworkRequested(@NonNull NetworkRequest request, int score, int providerId) {} + + /** + * Called when a NetworkRequest is withdrawn. + * @hide + */ + @SystemApi + public void onRequestWithdrawn(@NonNull NetworkRequest request) {} + + /** + * Asserts that no provider will ever be able to satisfy the specified request. The provider + * must only call this method if it knows that it is the only provider on the system capable of + * satisfying this request, and that the request cannot be satisfied. The application filing the + * request will receive an {@link NetworkCallback#onUnavailable()} callback. + * + * @param request the request that cannot be fulfilled + * @hide + */ + @SystemApi + @RequiresPermission(android.Manifest.permission.NETWORK_FACTORY) + public void declareNetworkRequestUnfulfillable(@NonNull NetworkRequest request) { + mCm.declareNetworkRequestUnfulfillable(request); + } +} diff --git a/core/java/android/net/NetworkQuotaInfo.java b/core/java/android/net/NetworkQuotaInfo.java index a46cddeda2dd..2e52d9cd19ab 100644 --- a/core/java/android/net/NetworkQuotaInfo.java +++ b/core/java/android/net/NetworkQuotaInfo.java @@ -16,7 +16,7 @@ package android.net; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.os.Parcel; import android.os.Parcelable; diff --git a/core/java/android/net/NetworkRequest.java b/core/java/android/net/NetworkRequest.java index 471b23e04775..3be49d530c64 100644 --- a/core/java/android/net/NetworkRequest.java +++ b/core/java/android/net/NetworkRequest.java @@ -20,7 +20,7 @@ import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.RequiresPermission; import android.annotation.SystemApi; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.net.NetworkCapabilities.NetCapability; import android.net.NetworkCapabilities.Transport; import android.os.Build; @@ -247,9 +247,8 @@ public class NetworkRequest implements Parcelable { * removing even the capabilities that are set by default when the object is constructed. * * @return The builder to facilitate chaining. - * @hide */ - @UnsupportedAppUsage + @NonNull public Builder clearCapabilities() { mNetworkCapabilities.clearAll(); return this; @@ -301,22 +300,34 @@ public class NetworkRequest implements Parcelable { * this without a single transport set will generate an exception, as will * subsequently adding or removing transports after this is set. * </p> - * The interpretation of this {@code String} is bearer specific and bearers that use - * it should document their particulars. For example, Bluetooth may use some sort of - * device id while WiFi could used ssid and/or bssid. Cellular may use carrier spn. + * If the {@code networkSpecifier} is provided, it shall be interpreted as follows: + * <ul> + * <li>If the specifier can be parsed as an integer, it will be treated as a + * {@link android.net TelephonyNetworkSpecifier}, and the provided integer will be + * interpreted as a SubscriptionId. + * <li>If the value is an ethernet interface name, it will be treated as such. + * <li>For all other cases, the behavior is undefined. + * </ul> + * + * @param networkSpecifier A {@code String} of either a SubscriptionId in cellular + * network request or an ethernet interface name in ethernet + * network request. * - * @param networkSpecifier An {@code String} of opaque format used to specify the bearer - * specific network specifier where the bearer has a choice of - * networks. + * @deprecated Use {@link #setNetworkSpecifier(NetworkSpecifier)} instead. */ + @Deprecated public Builder setNetworkSpecifier(String networkSpecifier) { - /* - * A StringNetworkSpecifier does not accept null or empty ("") strings. When network - * specifiers were strings a null string and an empty string were considered equivalent. - * Hence no meaning is attached to a null or empty ("") string. - */ - return setNetworkSpecifier(TextUtils.isEmpty(networkSpecifier) ? null - : new StringNetworkSpecifier(networkSpecifier)); + try { + int subId = Integer.parseInt(networkSpecifier); + return setNetworkSpecifier(new TelephonyNetworkSpecifier.Builder() + .setSubscriptionId(subId).build()); + } catch (NumberFormatException nfe) { + // A StringNetworkSpecifier does not accept null or empty ("") strings. When network + // specifiers were strings a null string and an empty string were considered + // equivalent. Hence no meaning is attached to a null or empty ("") string. + return setNetworkSpecifier(TextUtils.isEmpty(networkSpecifier) ? null + : new StringNetworkSpecifier(networkSpecifier)); + } } /** diff --git a/core/java/android/net/NetworkScoreManager.java b/core/java/android/net/NetworkScoreManager.java index f6dc52522cb2..c233ec0e52cf 100644 --- a/core/java/android/net/NetworkScoreManager.java +++ b/core/java/android/net/NetworkScoreManager.java @@ -163,27 +163,26 @@ public class NetworkScoreManager { public static final String EXTRA_NEW_SCORER = "newScorer"; /** @hide */ - @IntDef({CACHE_FILTER_NONE, CACHE_FILTER_CURRENT_NETWORK, CACHE_FILTER_SCAN_RESULTS}) + @IntDef({SCORE_FILTER_NONE, SCORE_FILTER_CURRENT_NETWORK, SCORE_FILTER_SCAN_RESULTS}) @Retention(RetentionPolicy.SOURCE) - public @interface CacheUpdateFilter {} + public @interface ScoreUpdateFilter {} /** - * Do not filter updates sent to the cache. - * @hide + * Do not filter updates sent to the {@link NetworkScoreCallback}]. */ - public static final int CACHE_FILTER_NONE = 0; + public static final int SCORE_FILTER_NONE = 0; /** - * Only send cache updates when the network matches the connected network. - * @hide + * Only send updates to the {@link NetworkScoreCallback} when the network matches the connected + * network. */ - public static final int CACHE_FILTER_CURRENT_NETWORK = 1; + public static final int SCORE_FILTER_CURRENT_NETWORK = 1; /** - * Only send cache updates when the network is part of the current scan result set. - * @hide + * Only send updates to the {@link NetworkScoreCallback} when the network is part of the + * current scan result set. */ - public static final int CACHE_FILTER_SCAN_RESULTS = 2; + public static final int SCORE_FILTER_SCAN_RESULTS = 2; /** @hide */ @IntDef({RECOMMENDATIONS_ENABLED_FORCED_OFF, RECOMMENDATIONS_ENABLED_OFF, @@ -404,13 +403,13 @@ public class NetworkScoreManager { * @throws SecurityException if the caller does not hold the * {@link permission#REQUEST_NETWORK_SCORES} permission. * @throws IllegalArgumentException if a score cache is already registered for this type. - * @deprecated equivalent to registering for cache updates with CACHE_FILTER_NONE. + * @deprecated equivalent to registering for cache updates with {@link #SCORE_FILTER_NONE}. * @hide */ @RequiresPermission(android.Manifest.permission.REQUEST_NETWORK_SCORES) @Deprecated // migrate to registerNetworkScoreCache(int, INetworkScoreCache, int) public void registerNetworkScoreCache(int networkType, INetworkScoreCache scoreCache) { - registerNetworkScoreCache(networkType, scoreCache, CACHE_FILTER_NONE); + registerNetworkScoreCache(networkType, scoreCache, SCORE_FILTER_NONE); } /** @@ -418,7 +417,7 @@ public class NetworkScoreManager { * * @param networkType the type of network this cache can handle. See {@link NetworkKey#type} * @param scoreCache implementation of {@link INetworkScoreCache} to store the scores - * @param filterType the {@link CacheUpdateFilter} to apply + * @param filterType the {@link ScoreUpdateFilter} to apply * @throws SecurityException if the caller does not hold the * {@link permission#REQUEST_NETWORK_SCORES} permission. * @throws IllegalArgumentException if a score cache is already registered for this type. @@ -426,7 +425,7 @@ public class NetworkScoreManager { */ @RequiresPermission(android.Manifest.permission.REQUEST_NETWORK_SCORES) public void registerNetworkScoreCache(int networkType, INetworkScoreCache scoreCache, - @CacheUpdateFilter int filterType) { + @ScoreUpdateFilter int filterType) { try { mService.registerNetworkScoreCache(networkType, scoreCache, filterType); } catch (RemoteException e) { @@ -510,7 +509,7 @@ public class NetworkScoreManager { * Register a network score callback. * * @param networkType the type of network this cache can handle. See {@link NetworkKey#type} - * @param filterType the {@link CacheUpdateFilter} to apply + * @param filterType the {@link ScoreUpdateFilter} to apply * @param callback implementation of {@link NetworkScoreCallback} that will be invoked when the * scores change. * @param executor The executor on which to execute the callbacks. @@ -522,7 +521,7 @@ public class NetworkScoreManager { @SystemApi @RequiresPermission(android.Manifest.permission.REQUEST_NETWORK_SCORES) public void registerNetworkScoreCallback(@NetworkKey.NetworkType int networkType, - @CacheUpdateFilter int filterType, + @ScoreUpdateFilter int filterType, @NonNull @CallbackExecutor Executor executor, @NonNull NetworkScoreCallback callback) throws SecurityException { if (callback == null || executor == null) { diff --git a/core/java/android/net/NetworkSpecifier.java b/core/java/android/net/NetworkSpecifier.java index 2bc3eb56ec2d..cf31d217c967 100644 --- a/core/java/android/net/NetworkSpecifier.java +++ b/core/java/android/net/NetworkSpecifier.java @@ -16,6 +16,9 @@ package android.net; +import android.annotation.Nullable; +import android.annotation.SystemApi; + /** * Describes specific properties of a requested network for use in a {@link NetworkRequest}. * @@ -31,7 +34,8 @@ public abstract class NetworkSpecifier { * * @hide */ - public abstract boolean satisfiedBy(NetworkSpecifier other); + @SystemApi + public abstract boolean satisfiedBy(@Nullable NetworkSpecifier other); /** * Optional method which can be overridden by concrete implementations of NetworkSpecifier to @@ -45,6 +49,7 @@ public abstract class NetworkSpecifier { * * @hide */ + @SystemApi public void assertValidFromUid(int requestorUid) { // empty } @@ -68,6 +73,8 @@ public abstract class NetworkSpecifier { * * @hide */ + @SystemApi + @Nullable public NetworkSpecifier redact() { // TODO (b/122160111): convert default to null once all platform NetworkSpecifiers // implement this method. diff --git a/core/java/android/net/NetworkState.java b/core/java/android/net/NetworkState.java index 292cf50ac4ae..e44961528708 100644 --- a/core/java/android/net/NetworkState.java +++ b/core/java/android/net/NetworkState.java @@ -16,7 +16,7 @@ package android.net; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.os.Build; import android.os.Parcel; import android.os.Parcelable; diff --git a/core/java/android/net/NetworkStats.java b/core/java/android/net/NetworkStats.java index 6c7aa1379fb1..96d7a80886a5 100644 --- a/core/java/android/net/NetworkStats.java +++ b/core/java/android/net/NetworkStats.java @@ -19,7 +19,10 @@ package android.net; import static android.os.Process.CLAT_UID; import android.annotation.NonNull; -import android.annotation.UnsupportedAppUsage; +import android.annotation.Nullable; +import android.annotation.SuppressLint; +import android.annotation.SystemApi; +import android.compat.annotation.UnsupportedAppUsage; import android.os.Parcel; import android.os.Parcelable; import android.os.SystemClock; @@ -48,59 +51,104 @@ import java.util.function.Predicate; * @hide */ // @NotThreadSafe -public class NetworkStats implements Parcelable { +@SystemApi +public final class NetworkStats implements Parcelable { private static final String TAG = "NetworkStats"; + /** {@link #iface} value when interface details unavailable. */ - public static final String IFACE_ALL = null; + @SuppressLint("CompileTimeConstant") + @Nullable public static final String IFACE_ALL = null; + /** + * Virtual network interface for video telephony. This is for VT data usage counting + * purpose. + */ + public static final String IFACE_VT = "vt_data0"; + /** {@link #uid} value when UID details unavailable. */ public static final int UID_ALL = -1; - /** {@link #tag} value matching any tag. */ + /** Special UID value for data usage by tethering. */ + public static final int UID_TETHERING = -5; + + /** + * {@link #tag} value matching any tag. + * @hide + */ // TODO: Rename TAG_ALL to TAG_ANY. public static final int TAG_ALL = -1; - /** {@link #set} value for all sets combined, not including debug sets. */ + /** + * {@link #set} value for all sets combined, not including debug sets. + * @hide + */ public static final int SET_ALL = -1; /** {@link #set} value where background data is accounted. */ public static final int SET_DEFAULT = 0; /** {@link #set} value where foreground data is accounted. */ public static final int SET_FOREGROUND = 1; - /** All {@link #set} value greater than SET_DEBUG_START are debug {@link #set} values. */ + /** + * All {@link #set} value greater than SET_DEBUG_START are debug {@link #set} values. + * @hide + */ public static final int SET_DEBUG_START = 1000; - /** Debug {@link #set} value when the VPN stats are moved in. */ + /** + * Debug {@link #set} value when the VPN stats are moved in. + * @hide + */ public static final int SET_DBG_VPN_IN = 1001; - /** Debug {@link #set} value when the VPN stats are moved out of a vpn UID. */ + /** + * Debug {@link #set} value when the VPN stats are moved out of a vpn UID. + * @hide + */ public static final int SET_DBG_VPN_OUT = 1002; - /** Include all interfaces when filtering */ - public static final String[] INTERFACES_ALL = null; + /** + * Include all interfaces when filtering + * @hide + */ + public @Nullable static final String[] INTERFACES_ALL = null; /** {@link #tag} value for total data across all tags. */ // TODO: Rename TAG_NONE to TAG_ALL. public static final int TAG_NONE = 0; - /** {@link #metered} value to account for all metered states. */ + /** + * {@link #metered} value to account for all metered states. + * @hide + */ public static final int METERED_ALL = -1; /** {@link #metered} value where native, unmetered data is accounted. */ public static final int METERED_NO = 0; /** {@link #metered} value where metered data is accounted. */ public static final int METERED_YES = 1; - /** {@link #roaming} value to account for all roaming states. */ + /** + * {@link #roaming} value to account for all roaming states. + * @hide + */ public static final int ROAMING_ALL = -1; /** {@link #roaming} value where native, non-roaming data is accounted. */ public static final int ROAMING_NO = 0; /** {@link #roaming} value where roaming data is accounted. */ public static final int ROAMING_YES = 1; - /** {@link #onDefaultNetwork} value to account for all default network states. */ + /** + * {@link #onDefaultNetwork} value to account for all default network states. + * @hide + */ public static final int DEFAULT_NETWORK_ALL = -1; /** {@link #onDefaultNetwork} value to account for usage while not the default network. */ public static final int DEFAULT_NETWORK_NO = 0; /** {@link #onDefaultNetwork} value to account for usage while the default network. */ public static final int DEFAULT_NETWORK_YES = 1; - /** Denotes a request for stats at the interface level. */ + /** + * Denotes a request for stats at the interface level. + * @hide + */ public static final int STATS_PER_IFACE = 0; - /** Denotes a request for stats at the interface and UID level. */ + /** + * Denotes a request for stats at the interface and UID level. + * @hide + */ public static final int STATS_PER_UID = 1; private static final String CLATD_INTERFACE_PREFIX = "v4-"; @@ -144,60 +192,78 @@ public class NetworkStats implements Parcelable { @UnsupportedAppUsage private long[] operations; + /** @hide */ + @SystemApi public static class Entry { + /** @hide */ @UnsupportedAppUsage public String iface; + /** @hide */ @UnsupportedAppUsage public int uid; + /** @hide */ @UnsupportedAppUsage public int set; + /** @hide */ @UnsupportedAppUsage public int tag; /** * Note that this is only populated w/ the default value when read from /proc or written * to disk. We merge in the correct value when reporting this value to clients of * getSummary(). + * @hide */ public int metered; /** * Note that this is only populated w/ the default value when read from /proc or written * to disk. We merge in the correct value when reporting this value to clients of * getSummary(). + * @hide */ public int roaming; /** * Note that this is only populated w/ the default value when read from /proc or written * to disk. We merge in the correct value when reporting this value to clients of * getSummary(). + * @hide */ public int defaultNetwork; + /** @hide */ @UnsupportedAppUsage public long rxBytes; + /** @hide */ @UnsupportedAppUsage public long rxPackets; + /** @hide */ @UnsupportedAppUsage public long txBytes; + /** @hide */ @UnsupportedAppUsage public long txPackets; + /** @hide */ + @UnsupportedAppUsage public long operations; + /** @hide */ @UnsupportedAppUsage public Entry() { this(IFACE_ALL, UID_ALL, SET_DEFAULT, TAG_NONE, 0L, 0L, 0L, 0L, 0L); } + /** @hide */ public Entry(long rxBytes, long rxPackets, long txBytes, long txPackets, long operations) { this(IFACE_ALL, UID_ALL, SET_DEFAULT, TAG_NONE, rxBytes, rxPackets, txBytes, txPackets, operations); } + /** @hide */ public Entry(String iface, int uid, int set, int tag, long rxBytes, long rxPackets, long txBytes, long txPackets, long operations) { this(iface, uid, set, tag, METERED_NO, ROAMING_NO, DEFAULT_NETWORK_NO, rxBytes, rxPackets, txBytes, txPackets, operations); } - public Entry(String iface, int uid, int set, int tag, int metered, int roaming, + public Entry(@Nullable String iface, int uid, int set, int tag, int metered, int roaming, int defaultNetwork, long rxBytes, long rxPackets, long txBytes, long txPackets, long operations) { this.iface = iface; @@ -214,15 +280,18 @@ public class NetworkStats implements Parcelable { this.operations = operations; } + /** @hide */ public boolean isNegative() { return rxBytes < 0 || rxPackets < 0 || txBytes < 0 || txPackets < 0 || operations < 0; } + /** @hide */ public boolean isEmpty() { return rxBytes == 0 && rxPackets == 0 && txBytes == 0 && txPackets == 0 && operations == 0; } + /** @hide */ public void add(Entry another) { this.rxBytes += another.rxBytes; this.rxPackets += another.rxPackets; @@ -249,6 +318,7 @@ public class NetworkStats implements Parcelable { return builder.toString(); } + /** @hide */ @Override public boolean equals(Object o) { if (o instanceof Entry) { @@ -262,13 +332,13 @@ public class NetworkStats implements Parcelable { return false; } + /** @hide */ @Override public int hashCode() { return Objects.hash(uid, set, tag, metered, roaming, defaultNetwork, iface); } } - @UnsupportedAppUsage public NetworkStats(long elapsedRealtime, int initialSize) { this.elapsedRealtime = elapsedRealtime; this.size = 0; @@ -292,6 +362,7 @@ public class NetworkStats implements Parcelable { } } + /** @hide */ @UnsupportedAppUsage public NetworkStats(Parcel parcel) { elapsedRealtime = parcel.readLong(); @@ -312,7 +383,7 @@ public class NetworkStats implements Parcelable { } @Override - public void writeToParcel(Parcel dest, int flags) { + public void writeToParcel(@NonNull Parcel dest, int flags) { dest.writeLong(elapsedRealtime); dest.writeInt(size); dest.writeInt(capacity); @@ -330,19 +401,23 @@ public class NetworkStats implements Parcelable { dest.writeLongArray(operations); } + /** + * @hide + */ @Override public NetworkStats clone() { final NetworkStats clone = new NetworkStats(elapsedRealtime, size); NetworkStats.Entry entry = null; for (int i = 0; i < size; i++) { entry = getValues(i, entry); - clone.addValues(entry); + clone.addEntry(entry); } return clone; } /** * Clear all data stored in this object. + * @hide */ public void clear() { this.capacity = 0; @@ -360,25 +435,28 @@ public class NetworkStats implements Parcelable { this.operations = EmptyArray.LONG; } + /** @hide */ @VisibleForTesting public NetworkStats addIfaceValues( String iface, long rxBytes, long rxPackets, long txBytes, long txPackets) { - return addValues( + return addEntry( iface, UID_ALL, SET_DEFAULT, TAG_NONE, rxBytes, rxPackets, txBytes, txPackets, 0L); } + /** @hide */ @VisibleForTesting - public NetworkStats addValues(String iface, int uid, int set, int tag, long rxBytes, + public NetworkStats addEntry(String iface, int uid, int set, int tag, long rxBytes, long rxPackets, long txBytes, long txPackets, long operations) { - return addValues(new Entry( + return addEntry(new Entry( iface, uid, set, tag, rxBytes, rxPackets, txBytes, txPackets, operations)); } + /** @hide */ @VisibleForTesting - public NetworkStats addValues(String iface, int uid, int set, int tag, int metered, int roaming, + public NetworkStats addEntry(String iface, int uid, int set, int tag, int metered, int roaming, int defaultNetwork, long rxBytes, long rxPackets, long txBytes, long txPackets, long operations) { - return addValues(new Entry( + return addEntry(new Entry( iface, uid, set, tag, metered, roaming, defaultNetwork, rxBytes, rxPackets, txBytes, txPackets, operations)); } @@ -386,8 +464,9 @@ public class NetworkStats implements Parcelable { /** * Add new stats entry, copying from given {@link Entry}. The {@link Entry} * object can be recycled across multiple calls. + * @hide */ - public NetworkStats addValues(Entry entry) { + public NetworkStats addEntry(Entry entry) { if (size >= capacity) { final int newLength = Math.max(size, 10) * 3 / 2; iface = Arrays.copyOf(iface, newLength); @@ -428,6 +507,7 @@ public class NetworkStats implements Parcelable { /** * Return specific stats entry. + * @hide */ @UnsupportedAppUsage public Entry getValues(int i, Entry recycle) { @@ -467,10 +547,12 @@ public class NetworkStats implements Parcelable { operations[dest] = operations[src]; } + /** @hide */ public long getElapsedRealtime() { return elapsedRealtime; } + /** @hide */ public void setElapsedRealtime(long time) { elapsedRealtime = time; } @@ -478,21 +560,25 @@ public class NetworkStats implements Parcelable { /** * Return age of this {@link NetworkStats} object with respect to * {@link SystemClock#elapsedRealtime()}. + * @hide */ public long getElapsedRealtimeAge() { return SystemClock.elapsedRealtime() - elapsedRealtime; } + /** @hide */ @UnsupportedAppUsage public int size() { return size; } + /** @hide */ @VisibleForTesting public int internalSize() { return capacity; } + /** @hide */ @Deprecated public NetworkStats combineValues(String iface, int uid, int tag, long rxBytes, long rxPackets, long txBytes, long txPackets, long operations) { @@ -501,6 +587,7 @@ public class NetworkStats implements Parcelable { txPackets, operations); } + /** @hide */ public NetworkStats combineValues(String iface, int uid, int set, int tag, long rxBytes, long rxPackets, long txBytes, long txPackets, long operations) { return combineValues(new Entry( @@ -509,16 +596,20 @@ public class NetworkStats implements Parcelable { /** * Combine given values with an existing row, or create a new row if - * {@link #findIndex(String, int, int, int, int)} is unable to find match. Can - * also be used to subtract values from existing rows. + * {@link #findIndex(String, int, int, int, int, int, int)} is unable to find match. Can + * also be used to subtract values from existing rows. This method mutates the referencing + * {@link NetworkStats} object. + * + * @param entry the {@link Entry} to combine. + * @return a reference to this mutated {@link NetworkStats} object. + * @hide */ - @UnsupportedAppUsage - public NetworkStats combineValues(Entry entry) { + public @NonNull NetworkStats combineValues(@NonNull Entry entry) { final int i = findIndex(entry.iface, entry.uid, entry.set, entry.tag, entry.metered, entry.roaming, entry.defaultNetwork); if (i == -1) { // only create new entry when positive contribution - addValues(entry); + addEntry(entry); } else { rxBytes[i] += entry.rxBytes; rxPackets[i] += entry.rxPackets; @@ -530,10 +621,33 @@ public class NetworkStats implements Parcelable { } /** + * Add given values with an existing row, or create a new row if + * {@link #findIndex(String, int, int, int, int, int, int)} is unable to find match. Can + * also be used to subtract values from existing rows. + * + * @param entry the {@link Entry} to add. + * @return a new constructed {@link NetworkStats} object that contains the result. + */ + public @NonNull NetworkStats addValues(@NonNull Entry entry) { + return this.clone().combineValues(entry); + } + + /** + * Add the given {@link NetworkStats} objects. + * + * @return the sum of two objects. + */ + public @NonNull NetworkStats add(@NonNull NetworkStats another) { + final NetworkStats ret = this.clone(); + ret.combineAllValues(another); + return ret; + } + + /** * Combine all values from another {@link NetworkStats} into this object. + * @hide */ - @UnsupportedAppUsage - public void combineAllValues(NetworkStats another) { + public void combineAllValues(@NonNull NetworkStats another) { NetworkStats.Entry entry = null; for (int i = 0; i < another.size; i++) { entry = another.getValues(i, entry); @@ -543,6 +657,7 @@ public class NetworkStats implements Parcelable { /** * Find first stats index that matches the requested parameters. + * @hide */ public int findIndex(String iface, int uid, int set, int tag, int metered, int roaming, int defaultNetwork) { @@ -560,6 +675,7 @@ public class NetworkStats implements Parcelable { /** * Find first stats index that matches the requested parameters, starting * search around the hinted index as an optimization. + * @hide */ @VisibleForTesting public int findIndexHinted(String iface, int uid, int set, int tag, int metered, int roaming, @@ -589,6 +705,7 @@ public class NetworkStats implements Parcelable { * Splice in {@link #operations} from the given {@link NetworkStats} based * on matching {@link #uid} and {@link #tag} rows. Ignores {@link #iface}, * since operation counts are at data layer. + * @hide */ public void spliceOperationsFrom(NetworkStats stats) { for (int i = 0; i < size; i++) { @@ -604,6 +721,7 @@ public class NetworkStats implements Parcelable { /** * Return list of unique interfaces known by this data structure. + * @hide */ public String[] getUniqueIfaces() { final HashSet<String> ifaces = new HashSet<String>(); @@ -617,6 +735,7 @@ public class NetworkStats implements Parcelable { /** * Return list of unique UIDs known by this data structure. + * @hide */ @UnsupportedAppUsage public int[] getUniqueUids() { @@ -636,6 +755,7 @@ public class NetworkStats implements Parcelable { /** * Return total bytes represented by this snapshot object, usually used when * checking if a {@link #subtract(NetworkStats)} delta passes a threshold. + * @hide */ @UnsupportedAppUsage public long getTotalBytes() { @@ -645,6 +765,7 @@ public class NetworkStats implements Parcelable { /** * Return total of all fields represented by this snapshot object. + * @hide */ @UnsupportedAppUsage public Entry getTotal(Entry recycle) { @@ -654,6 +775,7 @@ public class NetworkStats implements Parcelable { /** * Return total of all fields represented by this snapshot object matching * the requested {@link #uid}. + * @hide */ @UnsupportedAppUsage public Entry getTotal(Entry recycle, int limitUid) { @@ -663,11 +785,13 @@ public class NetworkStats implements Parcelable { /** * Return total of all fields represented by this snapshot object matching * the requested {@link #iface}. + * @hide */ public Entry getTotal(Entry recycle, HashSet<String> limitIface) { return getTotal(recycle, limitIface, UID_ALL, false); } + /** @hide */ @UnsupportedAppUsage public Entry getTotalIncludingTags(Entry recycle) { return getTotal(recycle, null, UID_ALL, true); @@ -717,6 +841,7 @@ public class NetworkStats implements Parcelable { /** * Fast path for battery stats. + * @hide */ public long getTotalPackets() { long total = 0; @@ -729,9 +854,12 @@ public class NetworkStats implements Parcelable { /** * Subtract the given {@link NetworkStats}, effectively leaving the delta * between two snapshots in time. Assumes that statistics rows collect over - * time, and that none of them have disappeared. + * time, and that none of them have disappeared. This method does not mutate + * the referencing object. + * + * @return the delta between two objects. */ - public NetworkStats subtract(NetworkStats right) { + public @NonNull NetworkStats subtract(@NonNull NetworkStats right) { return subtract(this, right, null, null); } @@ -742,6 +870,7 @@ public class NetworkStats implements Parcelable { * <p> * If counters have rolled backwards, they are clamped to {@code 0} and * reported to the given {@link NonMonotonicObserver}. + * @hide */ public static <C> NetworkStats subtract(NetworkStats left, NetworkStats right, NonMonotonicObserver<C> observer, C cookie) { @@ -759,6 +888,7 @@ public class NetworkStats implements Parcelable { * If <var>recycle</var> is supplied, this NetworkStats object will be * reused (and returned) as the result if it is large enough to contain * the data. + * @hide */ public static <C> NetworkStats subtract(NetworkStats left, NetworkStats right, NonMonotonicObserver<C> observer, C cookie, NetworkStats recycle) { @@ -817,7 +947,7 @@ public class NetworkStats implements Parcelable { entry.operations = Math.max(entry.operations, 0); } - result.addValues(entry); + result.addEntry(entry); } return result; @@ -847,6 +977,7 @@ public class NetworkStats implements Parcelable { * @param stackedTraffic Stats with traffic stacked on top of our ifaces. Will also be mutated. * @param stackedIfaces Mapping ipv6if -> ipv4if interface where traffic is counted on both. * @param useBpfStats True if eBPF is in use. + * @hide */ public static void apply464xlatAdjustments(NetworkStats baseTraffic, NetworkStats stackedTraffic, Map<String, String> stackedIfaces, boolean useBpfStats) { @@ -899,6 +1030,7 @@ public class NetworkStats implements Parcelable { * {@link #apply464xlatAdjustments(NetworkStats, NetworkStats, Map)} with {@code this} as * base and stacked traffic. * @param stackedIfaces Mapping ipv6if -> ipv4if interface where traffic is counted on both. + * @hide */ public void apply464xlatAdjustments(Map<String, String> stackedIfaces, boolean useBpfStats) { apply464xlatAdjustments(this, this, stackedIfaces, useBpfStats); @@ -907,6 +1039,7 @@ public class NetworkStats implements Parcelable { /** * Return total statistics grouped by {@link #iface}; doesn't mutate the * original structure. + * @hide */ public NetworkStats groupedByIface() { final NetworkStats stats = new NetworkStats(elapsedRealtime, 10); @@ -938,6 +1071,7 @@ public class NetworkStats implements Parcelable { /** * Return total statistics grouped by {@link #uid}; doesn't mutate the * original structure. + * @hide */ public NetworkStats groupedByUid() { final NetworkStats stats = new NetworkStats(elapsedRealtime, 10); @@ -968,6 +1102,7 @@ public class NetworkStats implements Parcelable { /** * Remove all rows that match one of specified UIDs. + * @hide */ public void removeUids(int[] uids) { int nextOutputEntry = 0; @@ -989,6 +1124,7 @@ public class NetworkStats implements Parcelable { * @param limitUid UID to filter for, or {@link #UID_ALL}. * @param limitIfaces Interfaces to filter for, or {@link #INTERFACES_ALL}. * @param limitTag Tag to filter for, or {@link #TAG_ALL}. + * @hide */ public void filter(int limitUid, String[] limitIfaces, int limitTag) { if (limitUid == UID_ALL && limitTag == TAG_ALL && limitIfaces == INTERFACES_ALL) { @@ -1004,6 +1140,7 @@ public class NetworkStats implements Parcelable { * Only keep entries with {@link #set} value less than {@link #SET_DEBUG_START}. * * <p>This mutates the original structure in place. + * @hide */ public void filterDebugEntries() { filter(e -> e.set < SET_DEBUG_START); @@ -1024,6 +1161,7 @@ public class NetworkStats implements Parcelable { size = nextOutputEntry; } + /** @hide */ public void dump(String prefix, PrintWriter pw) { pw.print(prefix); pw.print("NetworkStats: elapsedRealtime="); pw.println(elapsedRealtime); @@ -1047,6 +1185,7 @@ public class NetworkStats implements Parcelable { /** * Return text description of {@link #set} value. + * @hide */ public static String setToString(int set) { switch (set) { @@ -1067,6 +1206,7 @@ public class NetworkStats implements Parcelable { /** * Return text description of {@link #set} value. + * @hide */ public static String setToCheckinString(int set) { switch (set) { @@ -1087,6 +1227,7 @@ public class NetworkStats implements Parcelable { /** * @return true if the querySet matches the dataSet. + * @hide */ public static boolean setMatches(int querySet, int dataSet) { if (querySet == dataSet) { @@ -1098,6 +1239,7 @@ public class NetworkStats implements Parcelable { /** * Return text description of {@link #tag} value. + * @hide */ public static String tagToString(int tag) { return "0x" + Integer.toHexString(tag); @@ -1105,6 +1247,7 @@ public class NetworkStats implements Parcelable { /** * Return text description of {@link #metered} value. + * @hide */ public static String meteredToString(int metered) { switch (metered) { @@ -1121,6 +1264,7 @@ public class NetworkStats implements Parcelable { /** * Return text description of {@link #roaming} value. + * @hide */ public static String roamingToString(int roaming) { switch (roaming) { @@ -1137,6 +1281,7 @@ public class NetworkStats implements Parcelable { /** * Return text description of {@link #defaultNetwork} value. + * @hide */ public static String defaultNetworkToString(int defaultNetwork) { switch (defaultNetwork) { @@ -1151,6 +1296,7 @@ public class NetworkStats implements Parcelable { } } + /** @hide */ @Override public String toString() { final CharArrayWriter writer = new CharArrayWriter(); @@ -1163,8 +1309,7 @@ public class NetworkStats implements Parcelable { return 0; } - @UnsupportedAppUsage - public static final @android.annotation.NonNull Creator<NetworkStats> CREATOR = new Creator<NetworkStats>() { + public static final @NonNull Creator<NetworkStats> CREATOR = new Creator<NetworkStats>() { @Override public NetworkStats createFromParcel(Parcel in) { return new NetworkStats(in); @@ -1176,6 +1321,7 @@ public class NetworkStats implements Parcelable { } }; + /** @hide */ public interface NonMonotonicObserver<C> { public void foundNonMonotonic( NetworkStats left, int leftIndex, NetworkStats right, int rightIndex, C cookie); @@ -1195,6 +1341,7 @@ public class NetworkStats implements Parcelable { * @param tunUid uid of the VPN application * @param tunIface iface of the vpn tunnel * @param underlyingIfaces underlying network ifaces used by the VPN application + * @hide */ public void migrateTun(int tunUid, @NonNull String tunIface, @NonNull String[] underlyingIfaces) { diff --git a/core/java/android/net/NetworkStatsHistory.java b/core/java/android/net/NetworkStatsHistory.java index f61260ee3ed0..7b799e262419 100644 --- a/core/java/android/net/NetworkStatsHistory.java +++ b/core/java/android/net/NetworkStatsHistory.java @@ -30,7 +30,7 @@ import static android.text.format.DateUtils.SECOND_IN_MILLIS; import static com.android.internal.util.ArrayUtils.total; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.os.Parcel; import android.os.Parcelable; import android.service.NetworkStatsHistoryBucketProto; diff --git a/core/java/android/net/NetworkTemplate.java b/core/java/android/net/NetworkTemplate.java index 87c7118c0ed8..5e6c47a47a8e 100644 --- a/core/java/android/net/NetworkTemplate.java +++ b/core/java/android/net/NetworkTemplate.java @@ -34,7 +34,7 @@ import static android.net.NetworkStats.ROAMING_NO; import static android.net.NetworkStats.ROAMING_YES; import static android.net.wifi.WifiInfo.removeDoubleQuotes; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.os.Parcel; import android.os.Parcelable; import android.util.BackupUtils; diff --git a/core/java/android/net/NetworkUtils.java b/core/java/android/net/NetworkUtils.java index 01cb9883564a..08cc4e24b245 100644 --- a/core/java/android/net/NetworkUtils.java +++ b/core/java/android/net/NetworkUtils.java @@ -20,7 +20,7 @@ import static android.system.OsConstants.AF_INET; import static android.system.OsConstants.AF_INET6; import android.annotation.NonNull; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.net.shared.Inet4AddressUtils; import android.os.Build; import android.system.ErrnoException; diff --git a/core/java/android/net/Proxy.java b/core/java/android/net/Proxy.java index 4600942806a8..4ba7394a4bb2 100644 --- a/core/java/android/net/Proxy.java +++ b/core/java/android/net/Proxy.java @@ -18,7 +18,7 @@ package android.net; import android.annotation.SdkConstant; import android.annotation.SdkConstant.SdkConstantType; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; import android.text.TextUtils; import android.util.Log; diff --git a/core/java/android/net/ProxyInfo.java b/core/java/android/net/ProxyInfo.java index 9d92db448668..ffe9ae9521a8 100644 --- a/core/java/android/net/ProxyInfo.java +++ b/core/java/android/net/ProxyInfo.java @@ -18,7 +18,7 @@ package android.net; import android.annotation.NonNull; import android.annotation.Nullable; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.os.Parcel; import android.os.Parcelable; import android.text.TextUtils; diff --git a/core/java/android/net/RouteInfo.java b/core/java/android/net/RouteInfo.java index 52d3fc48a3a5..ea6002ca29e6 100644 --- a/core/java/android/net/RouteInfo.java +++ b/core/java/android/net/RouteInfo.java @@ -21,7 +21,7 @@ import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.SystemApi; import android.annotation.TestApi; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.os.Build; import android.os.Parcel; import android.os.Parcelable; diff --git a/core/java/android/net/SSLCertificateSocketFactory.java b/core/java/android/net/SSLCertificateSocketFactory.java index 39cb323d0662..8b6ac4271c30 100644 --- a/core/java/android/net/SSLCertificateSocketFactory.java +++ b/core/java/android/net/SSLCertificateSocketFactory.java @@ -16,7 +16,7 @@ package android.net; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.os.Build; import android.os.SystemProperties; import android.util.Log; diff --git a/core/java/android/net/SSLSessionCache.java b/core/java/android/net/SSLSessionCache.java index 9667e82c988c..944bc549acca 100644 --- a/core/java/android/net/SSLSessionCache.java +++ b/core/java/android/net/SSLSessionCache.java @@ -16,7 +16,7 @@ package android.net; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; import android.util.Log; diff --git a/core/java/android/net/SntpClient.java b/core/java/android/net/SntpClient.java index f9c2defc0377..8c6faf6d9970 100644 --- a/core/java/android/net/SntpClient.java +++ b/core/java/android/net/SntpClient.java @@ -16,7 +16,7 @@ package android.net; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.os.SystemClock; import android.util.Log; diff --git a/core/java/android/net/SocketKeepalive.java b/core/java/android/net/SocketKeepalive.java index ec73866a647d..fc9a8f63c131 100644 --- a/core/java/android/net/SocketKeepalive.java +++ b/core/java/android/net/SocketKeepalive.java @@ -20,6 +20,7 @@ import android.annotation.IntDef; import android.annotation.IntRange; import android.annotation.NonNull; import android.annotation.Nullable; +import android.annotation.SystemApi; import android.os.Binder; import android.os.ParcelFileDescriptor; import android.os.RemoteException; @@ -53,7 +54,11 @@ import java.util.concurrent.Executor; public abstract class SocketKeepalive implements AutoCloseable { static final String TAG = "SocketKeepalive"; - /** @hide */ + /** + * No errors. + * @hide + */ + @SystemApi public static final int SUCCESS = 0; /** @hide */ @@ -147,17 +152,6 @@ public abstract class SocketKeepalive implements AutoCloseable { } } - /** - * This packet is invalid. - * See the error code for details. - * @hide - */ - public static class InvalidPacketException extends ErrorCodeException { - public InvalidPacketException(final int error) { - super(error); - } - } - @NonNull final IConnectivityManager mService; @NonNull final Network mNetwork; @NonNull final ParcelFileDescriptor mPfd; diff --git a/core/java/android/net/StaticIpConfiguration.java b/core/java/android/net/StaticIpConfiguration.java index 990c1142284c..f24a9bd53039 100644 --- a/core/java/android/net/StaticIpConfiguration.java +++ b/core/java/android/net/StaticIpConfiguration.java @@ -20,7 +20,7 @@ import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.SystemApi; import android.annotation.TestApi; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.net.shared.InetAddressUtils; import android.os.Parcel; import android.os.Parcelable; diff --git a/core/java/android/net/TelephonyNetworkSpecifier.java b/core/java/android/net/TelephonyNetworkSpecifier.java new file mode 100644 index 000000000000..726f77059707 --- /dev/null +++ b/core/java/android/net/TelephonyNetworkSpecifier.java @@ -0,0 +1,146 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR 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.annotation.NonNull; +import android.os.Parcel; +import android.os.Parcelable; + +/** + * NetworkSpecifier object for cellular network request. Apps should use the + * {@link TelephonyNetworkSpecifier.Builder} class to create an instance. + */ +public final class TelephonyNetworkSpecifier extends NetworkSpecifier implements Parcelable { + + private final int mSubId; + + /** + * Return the subscription Id of current TelephonyNetworkSpecifier object. + * + * @return The subscription id. + */ + public int getSubscriptionId() { + return mSubId; + } + + /** + * @hide + */ + public TelephonyNetworkSpecifier(int subId) { + this.mSubId = subId; + } + + public static final @NonNull Creator<TelephonyNetworkSpecifier> CREATOR = + new Creator<TelephonyNetworkSpecifier>() { + @Override + public TelephonyNetworkSpecifier createFromParcel(Parcel in) { + int subId = in.readInt(); + return new TelephonyNetworkSpecifier(subId); + } + + @Override + public TelephonyNetworkSpecifier[] newArray(int size) { + return new TelephonyNetworkSpecifier[size]; + } + }; + + @Override + public int describeContents() { + return 0; + } + + @Override + public void writeToParcel(@NonNull Parcel dest, int flags) { + dest.writeInt(mSubId); + } + + @Override + public int hashCode() { + return mSubId; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (!(obj instanceof TelephonyNetworkSpecifier)) { + return false; + } + + TelephonyNetworkSpecifier lhs = (TelephonyNetworkSpecifier) obj; + return mSubId == lhs.mSubId; + } + + @Override + public String toString() { + return new StringBuilder() + .append("TelephonyNetworkSpecifier [") + .append("mSubId = ").append(mSubId) + .append("]") + .toString(); + } + + /** @hide */ + @Override + public boolean satisfiedBy(NetworkSpecifier other) { + // Any generic requests should be satisfied by a specific telephony network. + // For simplicity, we treat null same as MatchAllNetworkSpecifier + return equals(other) || other == null || other instanceof MatchAllNetworkSpecifier; + } + + + /** + * Builder to create {@link TelephonyNetworkSpecifier} object. + */ + public static final class Builder { + // Integer.MIN_VALUE which is not a valid subId, services as the sentinel to check if + // subId was set + private static final int SENTINEL_SUB_ID = Integer.MIN_VALUE; + + private int mSubId; + + public Builder() { + mSubId = SENTINEL_SUB_ID; + } + + /** + * Set the subscription id. + * + * @param subId The subscription Id. + * @return Instance of {@link Builder} to enable the chaining of the builder method. + */ + public @NonNull Builder setSubscriptionId(int subId) { + mSubId = subId; + return this; + } + + /** + * Create a NetworkSpecifier for the cellular network request. + * + * @return TelephonyNetworkSpecifier object. + * @throws IllegalArgumentException when subscription Id is not provided through + * {@link #setSubscriptionId(int)}. + */ + public @NonNull TelephonyNetworkSpecifier build() { + if (mSubId == SENTINEL_SUB_ID) { + throw new IllegalArgumentException("Subscription Id is not provided."); + } + return new TelephonyNetworkSpecifier(mSubId); + } + } +} diff --git a/core/java/android/net/TrafficStats.java b/core/java/android/net/TrafficStats.java index bf4884aa96a7..8108cf08d5c3 100644 --- a/core/java/android/net/TrafficStats.java +++ b/core/java/android/net/TrafficStats.java @@ -20,10 +20,10 @@ import android.annotation.NonNull; import android.annotation.SuppressLint; import android.annotation.SystemApi; import android.annotation.TestApi; -import android.annotation.UnsupportedAppUsage; import android.app.DownloadManager; import android.app.backup.BackupManager; import android.app.usage.NetworkStatsManager; +import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; import android.media.MediaPlayer; import android.os.Build; @@ -89,7 +89,7 @@ public class TrafficStats { * * @hide */ - public static final int UID_TETHERING = -5; + public static final int UID_TETHERING = NetworkStats.UID_TETHERING; /** * Tag values in this range are reserved for the network stack. The network stack is diff --git a/core/java/android/net/Uri.java b/core/java/android/net/Uri.java index c3166e91fac7..ddca4b464123 100644 --- a/core/java/android/net/Uri.java +++ b/core/java/android/net/Uri.java @@ -19,7 +19,7 @@ package android.net; import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.SystemApi; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.Intent; import android.os.Environment; import android.os.Parcel; diff --git a/core/java/android/net/VpnService.java b/core/java/android/net/VpnService.java index ed7cddcc6036..4b804b097d59 100644 --- a/core/java/android/net/VpnService.java +++ b/core/java/android/net/VpnService.java @@ -23,11 +23,11 @@ import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.RequiresPermission; import android.annotation.SystemApi; -import android.annotation.UnsupportedAppUsage; import android.app.Activity; import android.app.PendingIntent; import android.app.Service; import android.app.admin.DevicePolicyManager; +import android.compat.annotation.UnsupportedAppUsage; import android.content.ComponentName; import android.content.Context; import android.content.Intent; diff --git a/core/java/android/net/WebAddress.java b/core/java/android/net/WebAddress.java index 994c794e6997..aa3777d55342 100644 --- a/core/java/android/net/WebAddress.java +++ b/core/java/android/net/WebAddress.java @@ -20,7 +20,7 @@ import static android.util.Patterns.GOOD_IRI_CHAR; import android.annotation.NonNull; import android.annotation.SystemApi; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.os.Build; import java.util.Locale; diff --git a/core/java/android/net/annotations/PolicyDirection.java b/core/java/android/net/annotations/PolicyDirection.java new file mode 100644 index 000000000000..febd9b406111 --- /dev/null +++ b/core/java/android/net/annotations/PolicyDirection.java @@ -0,0 +1,35 @@ +/* + * 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.annotations; + +import android.annotation.IntDef; +import android.net.IpSecManager; + +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; + +/** + * IPsec traffic direction. + * + * <p>Mainline modules cannot reference hidden @IntDef. Moving this annotation to a separate class + * to allow others to statically include it. + * + * @hide + */ +@IntDef(value = {IpSecManager.DIRECTION_IN, IpSecManager.DIRECTION_OUT}) +@Retention(RetentionPolicy.SOURCE) +public @interface PolicyDirection {} diff --git a/core/java/android/net/http/SslCertificate.java b/core/java/android/net/http/SslCertificate.java index 01dd08f4ad9c..250cff29944a 100644 --- a/core/java/android/net/http/SslCertificate.java +++ b/core/java/android/net/http/SslCertificate.java @@ -17,7 +17,7 @@ package android.net.http; import android.annotation.Nullable; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; import android.os.Bundle; import android.text.format.DateFormat; diff --git a/core/java/android/net/http/SslError.java b/core/java/android/net/http/SslError.java index b3f2fb79b5c3..d43c616a4f13 100644 --- a/core/java/android/net/http/SslError.java +++ b/core/java/android/net/http/SslError.java @@ -16,8 +16,9 @@ package android.net.http; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.os.Build; + import java.security.cert.X509Certificate; /** diff --git a/core/java/android/net/metrics/ApfProgramEvent.java b/core/java/android/net/metrics/ApfProgramEvent.java index 8243be9c1355..f93907a37f3f 100644 --- a/core/java/android/net/metrics/ApfProgramEvent.java +++ b/core/java/android/net/metrics/ApfProgramEvent.java @@ -21,7 +21,7 @@ import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.SystemApi; import android.annotation.TestApi; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.os.Parcel; import android.os.Parcelable; import android.text.TextUtils; diff --git a/core/java/android/net/metrics/ApfStats.java b/core/java/android/net/metrics/ApfStats.java index eac5579f9eaa..b221cb97b28f 100644 --- a/core/java/android/net/metrics/ApfStats.java +++ b/core/java/android/net/metrics/ApfStats.java @@ -20,7 +20,7 @@ import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.SystemApi; import android.annotation.TestApi; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.os.Parcel; import android.os.Parcelable; diff --git a/core/java/android/net/metrics/DhcpClientEvent.java b/core/java/android/net/metrics/DhcpClientEvent.java index 5f9f50708a49..8fc1ef80bba9 100644 --- a/core/java/android/net/metrics/DhcpClientEvent.java +++ b/core/java/android/net/metrics/DhcpClientEvent.java @@ -20,7 +20,7 @@ import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.SystemApi; import android.annotation.TestApi; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.os.Parcel; import android.os.Parcelable; import android.text.TextUtils; diff --git a/core/java/android/net/netstats/provider/AbstractNetworkStatsProvider.java b/core/java/android/net/netstats/provider/AbstractNetworkStatsProvider.java new file mode 100644 index 000000000000..740aa92ad484 --- /dev/null +++ b/core/java/android/net/netstats/provider/AbstractNetworkStatsProvider.java @@ -0,0 +1,70 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR 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.netstats.provider; + +import android.annotation.NonNull; +import android.annotation.SystemApi; +import android.net.NetworkStats; + +/** + * A base class that allows external modules to implement a custom network statistics provider. + * @hide + */ +@SystemApi +public abstract class AbstractNetworkStatsProvider { + /** + * A value used by {@link #setLimit} and {@link #setAlert} indicates there is no limit. + */ + public static final int QUOTA_UNLIMITED = -1; + + /** + * Called by {@code NetworkStatsService} when global polling is needed. Custom + * implementation of providers MUST respond to it by calling + * {@link NetworkStatsProviderCallback#onStatsUpdated} within one minute. Responding + * later than this may cause the stats to be dropped. + * + * @param token a positive number identifying the new state of the system under which + * {@link NetworkStats} have to be gathered from now on. When this is called, + * custom implementations of providers MUST report the latest stats with the + * previous token, under which stats were being gathered so far. + */ + public abstract void requestStatsUpdate(int token); + + /** + * Called by {@code NetworkStatsService} when setting the interface quota for the specified + * upstream interface. When this is called, the custom implementation should block all egress + * packets on the {@code iface} associated with the provider when {@code quotaBytes} bytes have + * been reached, and MUST respond to it by calling + * {@link NetworkStatsProviderCallback#onLimitReached()}. + * + * @param iface the interface requiring the operation. + * @param quotaBytes the quota defined as the number of bytes, starting from zero and counting + * from now. A value of {@link #QUOTA_UNLIMITED} indicates there is no limit. + */ + public abstract void setLimit(@NonNull String iface, long quotaBytes); + + /** + * Called by {@code NetworkStatsService} when setting the alert bytes. Custom implementations + * MUST call {@link NetworkStatsProviderCallback#onAlertReached()} when {@code quotaBytes} bytes + * have been reached. Unlike {@link #setLimit(String, long)}, the custom implementation should + * not block all egress packets. + * + * @param quotaBytes the quota defined as the number of bytes, starting from zero and counting + * from now. A value of {@link #QUOTA_UNLIMITED} indicates there is no alert. + */ + public abstract void setAlert(long quotaBytes); +} diff --git a/core/java/android/net/netstats/provider/INetworkStatsProvider.aidl b/core/java/android/net/netstats/provider/INetworkStatsProvider.aidl new file mode 100644 index 000000000000..55b3d4edb157 --- /dev/null +++ b/core/java/android/net/netstats/provider/INetworkStatsProvider.aidl @@ -0,0 +1,28 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR 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.netstats.provider; + +/** + * Interface for NetworkStatsService to query network statistics and set data limits. + * + * @hide + */ +oneway interface INetworkStatsProvider { + void requestStatsUpdate(int token); + void setLimit(String iface, long quotaBytes); + void setAlert(long quotaBytes); +} diff --git a/core/java/android/net/netstats/provider/INetworkStatsProviderCallback.aidl b/core/java/android/net/netstats/provider/INetworkStatsProviderCallback.aidl new file mode 100644 index 000000000000..3ea9318f10d4 --- /dev/null +++ b/core/java/android/net/netstats/provider/INetworkStatsProviderCallback.aidl @@ -0,0 +1,31 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR 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.netstats.provider; + +import android.net.NetworkStats; + +/** + * Interface for implementor of {@link INetworkStatsProviderCallback} to push events + * such as network statistics update or notify limit reached. + * @hide + */ +oneway interface INetworkStatsProviderCallback { + void onStatsUpdated(int token, in NetworkStats ifaceStats, in NetworkStats uidStats); + void onAlertReached(); + void onLimitReached(); + void unregister(); +} diff --git a/core/java/android/net/netstats/provider/NetworkStatsProviderCallback.java b/core/java/android/net/netstats/provider/NetworkStatsProviderCallback.java new file mode 100644 index 000000000000..e17a8eee7ff0 --- /dev/null +++ b/core/java/android/net/netstats/provider/NetworkStatsProviderCallback.java @@ -0,0 +1,98 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR 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.netstats.provider; + +import android.annotation.NonNull; +import android.annotation.SuppressLint; +import android.annotation.SystemApi; +import android.net.NetworkStats; +import android.os.RemoteException; + +/** + * A callback class that allows callers to report events to the system. + * @hide + */ +@SystemApi +@SuppressLint("CallbackMethodName") +public class NetworkStatsProviderCallback { + @NonNull private final INetworkStatsProviderCallback mBinder; + + /** @hide */ + public NetworkStatsProviderCallback(@NonNull INetworkStatsProviderCallback binder) { + mBinder = binder; + } + + /** + * Notify the system of new network statistics. + * + * Send the network statistics recorded since the last call to {@link #onStatsUpdated}. Must be + * called within one minute of {@link AbstractNetworkStatsProvider#requestStatsUpdate(int)} + * being called. The provider can also call this whenever it wants to reports new stats for any + * reason. Note that the system will not necessarily immediately propagate the statistics to + * reflect the update. + * + * @param token the token under which these stats were gathered. Providers can call this method + * with the current token as often as they want, until the token changes. + * {@see AbstractNetworkStatsProvider#requestStatsUpdate()} + * @param ifaceStats the {@link NetworkStats} per interface to be reported. + * The provider should not include any traffic that is already counted by + * kernel interface counters. + * @param uidStats the same stats as above, but counts {@link NetworkStats} + * per uid. + */ + public void onStatsUpdated(int token, @NonNull NetworkStats ifaceStats, + @NonNull NetworkStats uidStats) { + try { + mBinder.onStatsUpdated(token, ifaceStats, uidStats); + } catch (RemoteException e) { + e.rethrowAsRuntimeException(); + } + } + + /** + * Notify system that the quota set by {@code setAlert} has been reached. + */ + public void onAlertReached() { + try { + mBinder.onAlertReached(); + } catch (RemoteException e) { + e.rethrowAsRuntimeException(); + } + } + + /** + * Notify system that the quota set by {@code setLimit} has been reached. + */ + public void onLimitReached() { + try { + mBinder.onLimitReached(); + } catch (RemoteException e) { + e.rethrowAsRuntimeException(); + } + } + + /** + * Unregister the provider and the referencing callback. + */ + public void unregister() { + try { + mBinder.unregister(); + } catch (RemoteException e) { + // Ignore error. + } + } +} diff --git a/core/java/android/net/netstats/provider/NetworkStatsProviderWrapper.java b/core/java/android/net/netstats/provider/NetworkStatsProviderWrapper.java new file mode 100644 index 000000000000..4bf7c9bc086e --- /dev/null +++ b/core/java/android/net/netstats/provider/NetworkStatsProviderWrapper.java @@ -0,0 +1,48 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR 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.netstats.provider; + +import android.annotation.NonNull; + +/** + * A wrapper class of {@link INetworkStatsProvider} that hides the binder interface from exposing + * to outer world. + * + * @hide + */ +public class NetworkStatsProviderWrapper extends INetworkStatsProvider.Stub { + @NonNull final AbstractNetworkStatsProvider mProvider; + + public NetworkStatsProviderWrapper(AbstractNetworkStatsProvider provider) { + mProvider = provider; + } + + @Override + public void requestStatsUpdate(int token) { + mProvider.requestStatsUpdate(token); + } + + @Override + public void setLimit(@NonNull String iface, long quotaBytes) { + mProvider.setLimit(iface, quotaBytes); + } + + @Override + public void setAlert(long quotaBytes) { + mProvider.setAlert(quotaBytes); + } +} diff --git a/core/java/android/net/nsd/NsdServiceInfo.java b/core/java/android/net/nsd/NsdServiceInfo.java index 459b1409807b..0946499f164f 100644 --- a/core/java/android/net/nsd/NsdServiceInfo.java +++ b/core/java/android/net/nsd/NsdServiceInfo.java @@ -17,13 +17,13 @@ package android.net.nsd; import android.annotation.NonNull; -import android.annotation.UnsupportedAppUsage; -import android.os.Parcelable; +import android.compat.annotation.UnsupportedAppUsage; import android.os.Parcel; +import android.os.Parcelable; import android.text.TextUtils; +import android.util.ArrayMap; import android.util.Base64; import android.util.Log; -import android.util.ArrayMap; import java.io.UnsupportedEncodingException; import java.net.InetAddress; diff --git a/core/java/android/nfc/ErrorCodes.java b/core/java/android/nfc/ErrorCodes.java index 98e31ad53be3..d2c81cd27d90 100644 --- a/core/java/android/nfc/ErrorCodes.java +++ b/core/java/android/nfc/ErrorCodes.java @@ -16,7 +16,7 @@ package android.nfc; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; /** * This class defines all the error codes that can be returned by the service diff --git a/core/java/android/nfc/NdefRecord.java b/core/java/android/nfc/NdefRecord.java index 5044a860b50c..fe316c45fb55 100644 --- a/core/java/android/nfc/NdefRecord.java +++ b/core/java/android/nfc/NdefRecord.java @@ -16,7 +16,7 @@ package android.nfc; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.Intent; import android.net.Uri; import android.os.Parcel; diff --git a/core/java/android/nfc/NfcActivityManager.java b/core/java/android/nfc/NfcActivityManager.java index abfa133a2f39..935374d15d9b 100644 --- a/core/java/android/nfc/NfcActivityManager.java +++ b/core/java/android/nfc/NfcActivityManager.java @@ -16,9 +16,9 @@ package android.nfc; -import android.annotation.UnsupportedAppUsage; import android.app.Activity; import android.app.Application; +import android.compat.annotation.UnsupportedAppUsage; import android.content.ContentProvider; import android.content.Intent; import android.net.Uri; @@ -26,7 +26,6 @@ import android.nfc.NfcAdapter.ReaderCallback; import android.os.Binder; import android.os.Bundle; import android.os.RemoteException; -import android.os.UserHandle; import android.util.Log; import java.util.ArrayList; diff --git a/core/java/android/nfc/NfcAdapter.java b/core/java/android/nfc/NfcAdapter.java index 7ab984fc9275..d320f61a3657 100644 --- a/core/java/android/nfc/NfcAdapter.java +++ b/core/java/android/nfc/NfcAdapter.java @@ -21,11 +21,11 @@ import android.annotation.RequiresPermission; import android.annotation.SdkConstant; import android.annotation.SdkConstant.SdkConstantType; import android.annotation.SystemApi; -import android.annotation.UnsupportedAppUsage; import android.app.Activity; import android.app.ActivityThread; import android.app.OnActivityPausedListener; import android.app.PendingIntent; +import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; import android.content.IntentFilter; import android.content.pm.IPackageManager; diff --git a/core/java/android/nfc/NfcManager.java b/core/java/android/nfc/NfcManager.java index 030066eb80a4..644e3122774b 100644 --- a/core/java/android/nfc/NfcManager.java +++ b/core/java/android/nfc/NfcManager.java @@ -17,7 +17,7 @@ package android.nfc; import android.annotation.SystemService; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; import android.os.Build; diff --git a/core/java/android/nfc/Tag.java b/core/java/android/nfc/Tag.java index 5a4c465f76d8..8bb2df0bba58 100644 --- a/core/java/android/nfc/Tag.java +++ b/core/java/android/nfc/Tag.java @@ -16,7 +16,7 @@ package android.nfc; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; import android.nfc.tech.IsoDep; import android.nfc.tech.MifareClassic; diff --git a/core/java/android/nfc/cardemulation/AidGroup.java b/core/java/android/nfc/cardemulation/AidGroup.java index 77b5552cd27b..c4f5e0b2ddf2 100644 --- a/core/java/android/nfc/cardemulation/AidGroup.java +++ b/core/java/android/nfc/cardemulation/AidGroup.java @@ -16,18 +16,18 @@ package android.nfc.cardemulation; -import java.io.IOException; -import java.util.ArrayList; -import java.util.List; +import android.compat.annotation.UnsupportedAppUsage; +import android.os.Parcel; +import android.os.Parcelable; +import android.util.Log; import org.xmlpull.v1.XmlPullParser; import org.xmlpull.v1.XmlPullParserException; import org.xmlpull.v1.XmlSerializer; -import android.annotation.UnsupportedAppUsage; -import android.os.Parcel; -import android.os.Parcelable; -import android.util.Log; +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; /** * The AidGroup class represents a group of Application Identifiers (AIDs). diff --git a/core/java/android/nfc/cardemulation/ApduServiceInfo.java b/core/java/android/nfc/cardemulation/ApduServiceInfo.java index d9000e43be0b..8da9db17252f 100644 --- a/core/java/android/nfc/cardemulation/ApduServiceInfo.java +++ b/core/java/android/nfc/cardemulation/ApduServiceInfo.java @@ -16,7 +16,7 @@ package android.nfc.cardemulation; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.ComponentName; import android.content.pm.PackageManager; import android.content.pm.PackageManager.NameNotFoundException; diff --git a/core/java/android/os/AsyncResult.java b/core/java/android/os/AsyncResult.java index 58a27015f2df..e80528b10aaf 100644 --- a/core/java/android/os/AsyncResult.java +++ b/core/java/android/os/AsyncResult.java @@ -16,8 +16,7 @@ package android.os; -import android.annotation.UnsupportedAppUsage; -import android.os.Message; +import android.compat.annotation.UnsupportedAppUsage; /** @hide */ public class AsyncResult diff --git a/core/java/android/os/AsyncTask.java b/core/java/android/os/AsyncTask.java index b37e176ddb6e..e1dabd345027 100644 --- a/core/java/android/os/AsyncTask.java +++ b/core/java/android/os/AsyncTask.java @@ -18,8 +18,8 @@ package android.os; import android.annotation.MainThread; import android.annotation.Nullable; -import android.annotation.UnsupportedAppUsage; import android.annotation.WorkerThread; +import android.compat.annotation.UnsupportedAppUsage; import java.util.ArrayDeque; import java.util.concurrent.Callable; diff --git a/core/java/android/os/BaseBundle.java b/core/java/android/os/BaseBundle.java index 7f63f8fb9e28..e6ad917fa019 100644 --- a/core/java/android/os/BaseBundle.java +++ b/core/java/android/os/BaseBundle.java @@ -18,7 +18,7 @@ package android.os; import android.annotation.NonNull; import android.annotation.Nullable; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.util.ArrayMap; import android.util.Log; import android.util.MathUtils; diff --git a/core/java/android/os/BatteryManager.java b/core/java/android/os/BatteryManager.java index 5ced86c9e79a..12ec0a0c21d5 100644 --- a/core/java/android/os/BatteryManager.java +++ b/core/java/android/os/BatteryManager.java @@ -21,7 +21,7 @@ import android.annotation.RequiresPermission; import android.annotation.SystemApi; import android.annotation.SystemService; import android.annotation.TestApi; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; import android.content.Intent; import android.hardware.health.V1_0.Constants; diff --git a/core/java/android/os/BatteryStats.java b/core/java/android/os/BatteryStats.java index 6efe1de4ac45..44f7fa35727c 100644 --- a/core/java/android/os/BatteryStats.java +++ b/core/java/android/os/BatteryStats.java @@ -19,9 +19,9 @@ package android.os; import static android.app.ActivityManager.PROCESS_STATE_BOUND_TOP; import static android.app.ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE_LOCATION; -import android.annotation.UnsupportedAppUsage; import android.app.ActivityManager; import android.app.job.JobParameters; +import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; import android.content.pm.ApplicationInfo; import android.server.ServerProtoEnums; diff --git a/core/java/android/os/Binder.java b/core/java/android/os/Binder.java index 2e6d2cc4a66a..9c4a36f1c965 100644 --- a/core/java/android/os/Binder.java +++ b/core/java/android/os/Binder.java @@ -19,7 +19,7 @@ package android.os; import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.SystemApi; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.util.ExceptionUtils; import android.util.Log; import android.util.Slog; diff --git a/core/java/android/os/Broadcaster.java b/core/java/android/os/Broadcaster.java index 6ac7f1a9c970..d1a953f23f7f 100644 --- a/core/java/android/os/Broadcaster.java +++ b/core/java/android/os/Broadcaster.java @@ -16,7 +16,7 @@ package android.os; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; /** @hide */ public class Broadcaster diff --git a/core/java/android/os/Build.java b/core/java/android/os/Build.java index 1d25bc1db6bc..6750fc77e705 100755 --- a/core/java/android/os/Build.java +++ b/core/java/android/os/Build.java @@ -22,9 +22,9 @@ import android.annotation.RequiresPermission; import android.annotation.SuppressAutoDoc; import android.annotation.SystemApi; import android.annotation.TestApi; -import android.annotation.UnsupportedAppUsage; import android.app.ActivityThread; import android.app.Application; +import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; import android.sysprop.TelephonyProperties; import android.text.TextUtils; @@ -161,7 +161,7 @@ public class Build { try { Application application = ActivityThread.currentApplication(); String callingPackage = application != null ? application.getPackageName() : null; - return service.getSerialForPackage(callingPackage); + return service.getSerialForPackage(callingPackage, null); } catch (RemoteException e) { e.rethrowFromSystemServer(); } diff --git a/core/java/android/os/Bundle.java b/core/java/android/os/Bundle.java index b82e517c08ae..a2071e0b0dc8 100644 --- a/core/java/android/os/Bundle.java +++ b/core/java/android/os/Bundle.java @@ -17,7 +17,7 @@ package android.os; import android.annotation.Nullable; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.util.ArrayMap; import android.util.Size; import android.util.SizeF; diff --git a/core/java/android/os/CancellationSignal.java b/core/java/android/os/CancellationSignal.java index 99fb9982e706..260f7ade8ab7 100644 --- a/core/java/android/os/CancellationSignal.java +++ b/core/java/android/os/CancellationSignal.java @@ -16,9 +16,7 @@ package android.os; -import android.os.ICancellationSignal; - -import dalvik.annotation.compat.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; /** * Provides the ability to cancel an operation in progress. diff --git a/core/java/android/os/Debug.java b/core/java/android/os/Debug.java index d7ed05577697..50379222f1a9 100644 --- a/core/java/android/os/Debug.java +++ b/core/java/android/os/Debug.java @@ -18,8 +18,8 @@ package android.os; import android.annotation.NonNull; import android.annotation.Nullable; -import android.annotation.UnsupportedAppUsage; import android.app.AppGlobals; +import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; import android.util.Log; diff --git a/core/java/android/os/DropBoxManager.java b/core/java/android/os/DropBoxManager.java index b7cccc66294a..18ba5a8a4a34 100644 --- a/core/java/android/os/DropBoxManager.java +++ b/core/java/android/os/DropBoxManager.java @@ -24,7 +24,7 @@ import android.annotation.RequiresPermission; import android.annotation.SdkConstant; import android.annotation.SdkConstant.SdkConstantType; import android.annotation.SystemService; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; import android.util.Log; diff --git a/core/java/android/os/Environment.java b/core/java/android/os/Environment.java index 7a131e5680a8..6639d57a189c 100644 --- a/core/java/android/os/Environment.java +++ b/core/java/android/os/Environment.java @@ -20,10 +20,10 @@ import android.Manifest; import android.annotation.NonNull; import android.annotation.SystemApi; import android.annotation.TestApi; -import android.annotation.UnsupportedAppUsage; import android.app.AppGlobals; import android.app.AppOpsManager; import android.app.admin.DevicePolicyManager; +import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; import android.content.Intent; import android.content.pm.PackageManager; diff --git a/core/java/android/os/FileObserver.java b/core/java/android/os/FileObserver.java index 4d9ebc2b5923..4628910bfd52 100644 --- a/core/java/android/os/FileObserver.java +++ b/core/java/android/os/FileObserver.java @@ -19,7 +19,7 @@ package android.os; import android.annotation.IntDef; import android.annotation.NonNull; import android.annotation.Nullable; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.util.Log; import java.io.File; diff --git a/core/java/android/os/FileUtils.java b/core/java/android/os/FileUtils.java index 2ac3def3a3f9..a47fbbaab9dd 100644 --- a/core/java/android/os/FileUtils.java +++ b/core/java/android/os/FileUtils.java @@ -40,7 +40,7 @@ import static android.system.OsConstants.W_OK; import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.TestApi; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.ContentResolver; import android.provider.DocumentsContract.Document; import android.system.ErrnoException; diff --git a/core/java/android/os/Handler.java b/core/java/android/os/Handler.java index a99bdabee137..fa7404c5b139 100644 --- a/core/java/android/os/Handler.java +++ b/core/java/android/os/Handler.java @@ -18,7 +18,7 @@ package android.os; import android.annotation.NonNull; import android.annotation.Nullable; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.util.Log; import android.util.Printer; diff --git a/core/java/android/os/HwBinder.java b/core/java/android/os/HwBinder.java index 09afdc7f934e..7c42c36e7747 100644 --- a/core/java/android/os/HwBinder.java +++ b/core/java/android/os/HwBinder.java @@ -18,7 +18,7 @@ package android.os; import android.annotation.SystemApi; import android.annotation.TestApi; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import libcore.util.NativeAllocationRegistry; diff --git a/core/java/android/os/HwParcel.java b/core/java/android/os/HwParcel.java index 9786f16bebaa..fb36e6f6978f 100644 --- a/core/java/android/os/HwParcel.java +++ b/core/java/android/os/HwParcel.java @@ -21,7 +21,7 @@ import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.SystemApi; import android.annotation.TestApi; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import dalvik.annotation.optimization.FastNative; diff --git a/core/java/android/os/HwRemoteBinder.java b/core/java/android/os/HwRemoteBinder.java index 72ec958ca6d6..756202e88518 100644 --- a/core/java/android/os/HwRemoteBinder.java +++ b/core/java/android/os/HwRemoteBinder.java @@ -16,7 +16,8 @@ package android.os; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; + import libcore.util.NativeAllocationRegistry; /** @hide */ diff --git a/core/java/android/os/IBinder.java b/core/java/android/os/IBinder.java index 83f88ad41cfc..d9ed32799ea5 100644 --- a/core/java/android/os/IBinder.java +++ b/core/java/android/os/IBinder.java @@ -18,7 +18,7 @@ package android.os; import android.annotation.NonNull; import android.annotation.Nullable; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import java.io.FileDescriptor; diff --git a/core/java/android/os/IDeviceIdentifiersPolicyService.aidl b/core/java/android/os/IDeviceIdentifiersPolicyService.aidl index 87d358f50e74..d11aa0c0bac6 100644 --- a/core/java/android/os/IDeviceIdentifiersPolicyService.aidl +++ b/core/java/android/os/IDeviceIdentifiersPolicyService.aidl @@ -21,5 +21,5 @@ package android.os; */ interface IDeviceIdentifiersPolicyService { String getSerial(); - String getSerialForPackage(in String callingPackage); -}
\ No newline at end of file + String getSerialForPackage(in String callingPackage, String callingFeatureId); +} diff --git a/core/java/android/os/IVibratorService.aidl b/core/java/android/os/IVibratorService.aidl index 6b881fecad56..264ab6038ea6 100644 --- a/core/java/android/os/IVibratorService.aidl +++ b/core/java/android/os/IVibratorService.aidl @@ -24,7 +24,8 @@ interface IVibratorService { boolean hasVibrator(); boolean hasAmplitudeControl(); - boolean setAlwaysOnEffect(int id, in VibrationEffect effect, in AudioAttributes attributes); + boolean setAlwaysOnEffect(int uid, String opPkg, int alwaysOnId, in VibrationEffect effect, + in AudioAttributes attributes); void vibrate(int uid, String opPkg, in VibrationEffect effect, in AudioAttributes attributes, String reason, IBinder token); void cancelVibrate(IBinder token); diff --git a/core/java/android/os/LocaleList.java b/core/java/android/os/LocaleList.java index 0de09efad8ea..0bf387e6d0a6 100644 --- a/core/java/android/os/LocaleList.java +++ b/core/java/android/os/LocaleList.java @@ -20,7 +20,7 @@ import android.annotation.IntRange; import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.Size; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.icu.util.ULocale; import com.android.internal.annotations.GuardedBy; diff --git a/core/java/android/os/Looper.java b/core/java/android/os/Looper.java index d468972df413..5dc64d5b8d51 100644 --- a/core/java/android/os/Looper.java +++ b/core/java/android/os/Looper.java @@ -18,7 +18,7 @@ package android.os; import android.annotation.NonNull; import android.annotation.Nullable; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.util.Log; import android.util.Printer; import android.util.Slog; diff --git a/core/java/android/os/MemoryFile.java b/core/java/android/os/MemoryFile.java index 5a1e3d429830..f84f9f05b13e 100644 --- a/core/java/android/os/MemoryFile.java +++ b/core/java/android/os/MemoryFile.java @@ -16,7 +16,7 @@ package android.os; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.system.ErrnoException; import java.io.FileDescriptor; diff --git a/core/java/android/os/Message.java b/core/java/android/os/Message.java index 6055befa15d5..8ac245b894bb 100644 --- a/core/java/android/os/Message.java +++ b/core/java/android/os/Message.java @@ -16,7 +16,7 @@ package android.os; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.util.TimeUtils; import android.util.proto.ProtoOutputStream; diff --git a/core/java/android/os/MessageQueue.java b/core/java/android/os/MessageQueue.java index f98fdc393de3..4e910577dd49 100644 --- a/core/java/android/os/MessageQueue.java +++ b/core/java/android/os/MessageQueue.java @@ -19,8 +19,7 @@ package android.os; import android.annotation.IntDef; import android.annotation.NonNull; import android.annotation.TestApi; -import android.annotation.UnsupportedAppUsage; -import android.os.MessageQueueProto; +import android.compat.annotation.UnsupportedAppUsage; import android.util.Log; import android.util.Printer; import android.util.SparseArray; diff --git a/core/java/android/os/Parcel.java b/core/java/android/os/Parcel.java index 041f31d67a3e..382c838447b2 100644 --- a/core/java/android/os/Parcel.java +++ b/core/java/android/os/Parcel.java @@ -19,7 +19,7 @@ package android.os; import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.TestApi; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.text.TextUtils; import android.util.ArrayMap; import android.util.ArraySet; diff --git a/core/java/android/os/ParcelFileDescriptor.java b/core/java/android/os/ParcelFileDescriptor.java index 2a4576adf192..214b3bb91af6 100644 --- a/core/java/android/os/ParcelFileDescriptor.java +++ b/core/java/android/os/ParcelFileDescriptor.java @@ -32,7 +32,7 @@ import static android.system.OsConstants.S_ISREG; import static android.system.OsConstants.S_IWOTH; import android.annotation.TestApi; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.BroadcastReceiver; import android.content.ContentProvider; import android.os.MessageQueue.OnFileDescriptorEventListener; diff --git a/core/java/android/os/ParcelUuid.java b/core/java/android/os/ParcelUuid.java index cc50c8996ba7..0b52c7501d5b 100644 --- a/core/java/android/os/ParcelUuid.java +++ b/core/java/android/os/ParcelUuid.java @@ -16,7 +16,7 @@ package android.os; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import java.util.UUID; diff --git a/core/java/android/os/ParcelableParcel.java b/core/java/android/os/ParcelableParcel.java index 61f39686c9e6..38d980ecb0f1 100644 --- a/core/java/android/os/ParcelableParcel.java +++ b/core/java/android/os/ParcelableParcel.java @@ -16,7 +16,7 @@ package android.os; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.util.MathUtils; /** diff --git a/core/java/android/os/PerformanceCollector.java b/core/java/android/os/PerformanceCollector.java index 33c86b8b05b9..27de48d40188 100644 --- a/core/java/android/os/PerformanceCollector.java +++ b/core/java/android/os/PerformanceCollector.java @@ -17,7 +17,8 @@ package android.os; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; + import java.util.ArrayList; /** diff --git a/core/java/android/os/PersistableBundle.java b/core/java/android/os/PersistableBundle.java index 6f1bf71f187b..29aaf534eda1 100644 --- a/core/java/android/os/PersistableBundle.java +++ b/core/java/android/os/PersistableBundle.java @@ -16,17 +16,24 @@ package android.os; +import static java.nio.charset.StandardCharsets.UTF_8; + +import android.annotation.NonNull; import android.annotation.Nullable; import android.util.ArrayMap; import android.util.proto.ProtoOutputStream; +import com.android.internal.util.FastXmlSerializer; import com.android.internal.util.XmlUtils; import org.xmlpull.v1.XmlPullParser; import org.xmlpull.v1.XmlPullParserException; +import org.xmlpull.v1.XmlPullParserFactory; import org.xmlpull.v1.XmlSerializer; import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; import java.util.ArrayList; /** @@ -339,4 +346,44 @@ public final class PersistableBundle extends BaseBundle implements Cloneable, Pa proto.end(token); } + + /** + * Writes the content of the {@link PersistableBundle} to a {@link OutputStream}. + * + * <p>The content can be read by a {@link #readFromStream}. + * + * @see #readFromStream + */ + public void writeToStream(@NonNull OutputStream outputStream) throws IOException { + FastXmlSerializer serializer = new FastXmlSerializer(); + serializer.setOutput(outputStream, UTF_8.name()); + serializer.startTag(null, "bundle"); + try { + saveToXml(serializer); + } catch (XmlPullParserException e) { + throw new IOException(e); + } + serializer.endTag(null, "bundle"); + serializer.flush(); + } + + /** + * Reads a {@link PersistableBundle} from an {@link InputStream}. + * + * <p>The stream must be generated by {@link #writeToStream}. + * + * @see #writeToStream + */ + @NonNull + public static PersistableBundle readFromStream(@NonNull InputStream inputStream) + throws IOException { + try { + XmlPullParser parser = XmlPullParserFactory.newInstance().newPullParser(); + parser.setInput(inputStream, UTF_8.name()); + parser.next(); + return PersistableBundle.restoreFromXml(parser); + } catch (XmlPullParserException e) { + throw new IOException(e); + } + } } diff --git a/core/java/android/os/PowerManager.java b/core/java/android/os/PowerManager.java index c618dbc2b551..febc36cbe47b 100644 --- a/core/java/android/os/PowerManager.java +++ b/core/java/android/os/PowerManager.java @@ -26,7 +26,7 @@ import android.annotation.SdkConstant; import android.annotation.SystemApi; import android.annotation.SystemService; import android.annotation.TestApi; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; import android.service.dreams.Sandman; import android.util.ArrayMap; diff --git a/core/java/android/os/Process.java b/core/java/android/os/Process.java index 1130f1db6256..6f4f30c4981a 100644 --- a/core/java/android/os/Process.java +++ b/core/java/android/os/Process.java @@ -19,7 +19,7 @@ package android.os; import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.TestApi; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.system.Os; import android.system.OsConstants; import android.webkit.WebViewZygote; @@ -740,11 +740,12 @@ public class Process { /** * Set the priority of a thread, based on Linux priorities. - * - * @param tid The identifier of the thread/process to change. + * + * @param tid The identifier of the thread/process to change. It should be + * the native thread id but not the managed id of {@link java.lang.Thread}. * @param priority A Linux priority level, from -20 for highest scheduling * priority to 19 for lowest scheduling priority. - * + * * @throws IllegalArgumentException Throws IllegalArgumentException if * <var>tid</var> does not exist. * @throws SecurityException Throws SecurityException if your process does diff --git a/core/java/android/os/RecoverySystem.java b/core/java/android/os/RecoverySystem.java index e3f6e120d9c6..190182072356 100644 --- a/core/java/android/os/RecoverySystem.java +++ b/core/java/android/os/RecoverySystem.java @@ -22,8 +22,8 @@ import android.annotation.RequiresPermission; import android.annotation.SuppressLint; import android.annotation.SystemApi; import android.annotation.SystemService; -import android.annotation.UnsupportedAppUsage; import android.app.PendingIntent; +import android.compat.annotation.UnsupportedAppUsage; import android.content.BroadcastReceiver; import android.content.ContentResolver; import android.content.Context; diff --git a/core/java/android/os/Registrant.java b/core/java/android/os/Registrant.java index 572b975fbafd..d6afd049f156 100644 --- a/core/java/android/os/Registrant.java +++ b/core/java/android/os/Registrant.java @@ -16,9 +16,7 @@ package android.os; -import android.annotation.UnsupportedAppUsage; -import android.os.Handler; -import android.os.Message; +import android.compat.annotation.UnsupportedAppUsage; import java.lang.ref.WeakReference; diff --git a/core/java/android/os/RegistrantList.java b/core/java/android/os/RegistrantList.java index 9c017dfff967..98f949bbfd84 100644 --- a/core/java/android/os/RegistrantList.java +++ b/core/java/android/os/RegistrantList.java @@ -16,7 +16,7 @@ package android.os; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import java.util.ArrayList; diff --git a/core/java/android/os/RemoteCallback.java b/core/java/android/os/RemoteCallback.java index da58d0fac160..373060f4ff4b 100644 --- a/core/java/android/os/RemoteCallback.java +++ b/core/java/android/os/RemoteCallback.java @@ -20,8 +20,7 @@ import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.SystemApi; import android.annotation.TestApi; - -import dalvik.annotation.compat.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; /** * @hide diff --git a/core/java/android/os/RemoteCallbackList.java b/core/java/android/os/RemoteCallbackList.java index 6165146ece0a..df4ade09753b 100644 --- a/core/java/android/os/RemoteCallbackList.java +++ b/core/java/android/os/RemoteCallbackList.java @@ -16,7 +16,7 @@ package android.os; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.util.ArrayMap; import android.util.Slog; diff --git a/core/java/android/os/RemoteException.java b/core/java/android/os/RemoteException.java index 2e673a857a93..c2f7f1bf2099 100644 --- a/core/java/android/os/RemoteException.java +++ b/core/java/android/os/RemoteException.java @@ -16,7 +16,7 @@ package android.os; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.util.AndroidException; /** diff --git a/core/java/android/os/SELinux.java b/core/java/android/os/SELinux.java index 34809e76c91b..f64a81177ce2 100644 --- a/core/java/android/os/SELinux.java +++ b/core/java/android/os/SELinux.java @@ -16,7 +16,7 @@ package android.os; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.util.Slog; import java.io.File; diff --git a/core/java/android/os/ServiceManager.java b/core/java/android/os/ServiceManager.java index bf9225a2780a..c008f4d37b90 100644 --- a/core/java/android/os/ServiceManager.java +++ b/core/java/android/os/ServiceManager.java @@ -16,7 +16,7 @@ package android.os; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.util.ArrayMap; import android.util.Log; diff --git a/core/java/android/os/ServiceManagerNative.java b/core/java/android/os/ServiceManagerNative.java index 94671c8f317d..39ddcb2af3c2 100644 --- a/core/java/android/os/ServiceManagerNative.java +++ b/core/java/android/os/ServiceManagerNative.java @@ -16,7 +16,7 @@ package android.os; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; /** * Native implementation of the service manager. Most clients will only diff --git a/core/java/android/os/SharedMemory.java b/core/java/android/os/SharedMemory.java index 57a88012a31a..26d9c7d687eb 100644 --- a/core/java/android/os/SharedMemory.java +++ b/core/java/android/os/SharedMemory.java @@ -18,7 +18,7 @@ package android.os; import android.annotation.NonNull; import android.annotation.Nullable; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.system.ErrnoException; import android.system.Os; import android.system.OsConstants; diff --git a/core/java/android/os/ShellCommand.java b/core/java/android/os/ShellCommand.java index 2fe8726a0915..814aac4116e1 100644 --- a/core/java/android/os/ShellCommand.java +++ b/core/java/android/os/ShellCommand.java @@ -16,7 +16,7 @@ package android.os; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.util.Slog; import com.android.internal.util.FastPrintWriter; diff --git a/core/java/android/os/StatFs.java b/core/java/android/os/StatFs.java index 881d0b4d9c8e..6d1a1164abb4 100644 --- a/core/java/android/os/StatFs.java +++ b/core/java/android/os/StatFs.java @@ -16,7 +16,7 @@ package android.os; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.system.ErrnoException; import android.system.Os; import android.system.StructStatVfs; diff --git a/core/java/android/os/StrictMode.java b/core/java/android/os/StrictMode.java index 0bf634e799cd..3faaff73a0ea 100644 --- a/core/java/android/os/StrictMode.java +++ b/core/java/android/os/StrictMode.java @@ -20,10 +20,10 @@ import android.annotation.IntDef; import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.TestApi; -import android.annotation.UnsupportedAppUsage; import android.app.ActivityManager; import android.app.ActivityThread; import android.app.IActivityManager; +import android.compat.annotation.UnsupportedAppUsage; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; diff --git a/core/java/android/os/SystemClock.java b/core/java/android/os/SystemClock.java index 210f5d7b5dab..29852a872f5d 100644 --- a/core/java/android/os/SystemClock.java +++ b/core/java/android/os/SystemClock.java @@ -17,8 +17,8 @@ package android.os; import android.annotation.NonNull; -import android.annotation.UnsupportedAppUsage; import android.app.IAlarmManager; +import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; import android.location.ILocationManager; import android.location.LocationTime; diff --git a/core/java/android/os/SystemProperties.java b/core/java/android/os/SystemProperties.java index f08e1ff16999..a681ec06c19f 100644 --- a/core/java/android/os/SystemProperties.java +++ b/core/java/android/os/SystemProperties.java @@ -20,7 +20,7 @@ import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.SystemApi; import android.annotation.TestApi; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.util.Log; import android.util.MutableInt; diff --git a/core/java/android/os/SystemService.java b/core/java/android/os/SystemService.java index 968c761c5ff0..5871d2d9b58f 100644 --- a/core/java/android/os/SystemService.java +++ b/core/java/android/os/SystemService.java @@ -16,9 +16,10 @@ package android.os; +import android.compat.annotation.UnsupportedAppUsage; + import com.google.android.collect.Maps; -import android.annotation.UnsupportedAppUsage; import java.util.HashMap; import java.util.concurrent.TimeoutException; diff --git a/core/java/android/os/SystemVibrator.java b/core/java/android/os/SystemVibrator.java index fbd11ca62a0c..11a425d54621 100644 --- a/core/java/android/os/SystemVibrator.java +++ b/core/java/android/os/SystemVibrator.java @@ -16,7 +16,7 @@ package android.os; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; import android.media.AudioAttributes; import android.util.Log; @@ -70,13 +70,14 @@ public class SystemVibrator extends Vibrator { } @Override - public boolean setAlwaysOnEffect(int id, VibrationEffect effect, AudioAttributes attributes) { + public boolean setAlwaysOnEffect(int uid, String opPkg, int alwaysOnId, VibrationEffect effect, + AudioAttributes attributes) { if (mService == null) { Log.w(TAG, "Failed to set always-on effect; no vibrator service."); return false; } try { - return mService.setAlwaysOnEffect(id, effect, attributes); + return mService.setAlwaysOnEffect(uid, opPkg, alwaysOnId, effect, attributes); } catch (RemoteException e) { Log.w(TAG, "Failed to set always-on effect.", e); } diff --git a/core/java/android/util/TimestampedValue.java b/core/java/android/os/TimestampedValue.java index 45056730b08b..f4c87ac9dfc9 100644 --- a/core/java/android/util/TimestampedValue.java +++ b/core/java/android/os/TimestampedValue.java @@ -14,13 +14,11 @@ * limitations under the License. */ -package android.util; +package android.os; import android.annotation.NonNull; import android.annotation.Nullable; -import android.os.Parcel; -import android.os.Parcelable; -import android.os.SystemClock; +import android.annotation.SystemApi; import java.util.Objects; @@ -38,19 +36,27 @@ import java.util.Objects; * @param <T> the type of the value with an associated timestamp * @hide */ +@SystemApi(client = SystemApi.Client.MODULE_LIBRARIES) public final class TimestampedValue<T> implements Parcelable { private final long mReferenceTimeMillis; + @Nullable private final T mValue; - public TimestampedValue(long referenceTimeMillis, T value) { + public TimestampedValue(long referenceTimeMillis, @Nullable T value) { mReferenceTimeMillis = referenceTimeMillis; mValue = value; } + /** Returns the reference time value. See {@link TimestampedValue} for more information. */ public long getReferenceTimeMillis() { return mReferenceTimeMillis; } + /** + * Returns the value associated with the timestamp. See {@link TimestampedValue} for more + * information. + */ + @Nullable public T getValue() { return mValue; } @@ -89,6 +95,8 @@ public final class TimestampedValue<T> implements Parcelable { return one.mReferenceTimeMillis - two.mReferenceTimeMillis; } + /** @hide */ + @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES) public static final @NonNull Parcelable.Creator<TimestampedValue<?>> CREATOR = new Parcelable.ClassLoaderCreator<TimestampedValue<?>>() { diff --git a/core/java/android/os/Trace.java b/core/java/android/os/Trace.java index e132c11d6c8e..25584f156084 100644 --- a/core/java/android/os/Trace.java +++ b/core/java/android/os/Trace.java @@ -17,9 +17,7 @@ package android.os; import android.annotation.NonNull; -import android.annotation.UnsupportedAppUsage; - -import com.android.internal.os.Zygote; +import android.compat.annotation.UnsupportedAppUsage; import dalvik.annotation.optimization.CriticalNative; import dalvik.annotation.optimization.FastNative; diff --git a/core/java/android/os/UEventObserver.java b/core/java/android/os/UEventObserver.java index dc98c4267a37..fa30e509f8cc 100644 --- a/core/java/android/os/UEventObserver.java +++ b/core/java/android/os/UEventObserver.java @@ -16,7 +16,7 @@ package android.os; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.util.Log; import java.util.ArrayList; diff --git a/core/java/android/os/UpdateEngine.java b/core/java/android/os/UpdateEngine.java index a9ddffe7d55c..73e1adf134f2 100644 --- a/core/java/android/os/UpdateEngine.java +++ b/core/java/android/os/UpdateEngine.java @@ -16,8 +16,10 @@ package android.os; +import android.annotation.IntDef; import android.annotation.NonNull; import android.annotation.SystemApi; +import android.content.res.AssetFileDescriptor; import android.os.IUpdateEngine; import android.os.IUpdateEngineCallback; import android.os.RemoteException; @@ -140,8 +142,43 @@ public class UpdateEngine { * {@code SWITCH_SLOT_ON_REBOOT=0}. See {@link #applyPayload}. */ public static final int UPDATED_BUT_NOT_ACTIVE = 52; + + /** + * Error code: there is not enough space on the device to apply the update. User should + * be prompted to free up space and re-try the update. + * + * <p>See {@link UpdateEngine#allocateSpace}. + */ + public static final int NOT_ENOUGH_SPACE = 60; + + /** + * Error code: the device is corrupted and no further updates may be applied. + * + * <p>See {@link UpdateEngine#cleanupAppliedPayload}. + */ + public static final int DEVICE_CORRUPTED = 61; } + /** @hide */ + @IntDef(value = { + ErrorCodeConstants.SUCCESS, + ErrorCodeConstants.ERROR, + ErrorCodeConstants.FILESYSTEM_COPIER_ERROR, + ErrorCodeConstants.POST_INSTALL_RUNNER_ERROR, + ErrorCodeConstants.PAYLOAD_MISMATCHED_TYPE_ERROR, + ErrorCodeConstants.INSTALL_DEVICE_OPEN_ERROR, + ErrorCodeConstants.KERNEL_DEVICE_OPEN_ERROR, + ErrorCodeConstants.DOWNLOAD_TRANSFER_ERROR, + ErrorCodeConstants.PAYLOAD_HASH_MISMATCH_ERROR, + ErrorCodeConstants.PAYLOAD_SIZE_MISMATCH_ERROR, + ErrorCodeConstants.DOWNLOAD_PAYLOAD_VERIFICATION_ERROR, + ErrorCodeConstants.PAYLOAD_TIMESTAMP_ERROR, + ErrorCodeConstants.UPDATED_BUT_NOT_ACTIVE, + ErrorCodeConstants.NOT_ENOUGH_SPACE, + ErrorCodeConstants.DEVICE_CORRUPTED, + }) + public @interface ErrorCode {} + /** * Status codes for update engine. Values must agree with the ones in * {@code system/update_engine/client_library/include/update_engine/update_status.h}. @@ -313,16 +350,17 @@ public class UpdateEngine { } /** - * Applies the payload passed as ParcelFileDescriptor {@code pfd} instead of - * using the {@code file://} scheme. + * Applies the payload passed as AssetFileDescriptor {@code assetFd} + * instead of using the {@code file://} scheme. * * <p>See {@link #applyPayload(String)} for {@code offset}, {@code size} and * {@code headerKeyValuePairs} parameters. */ - public void applyPayload(@NonNull ParcelFileDescriptor pfd, long offset, long size, + public void applyPayload(@NonNull AssetFileDescriptor assetFd, @NonNull String[] headerKeyValuePairs) { try { - mUpdateEngine.applyPayloadFd(pfd, offset, size, headerKeyValuePairs); + mUpdateEngine.applyPayloadFd(assetFd.getParcelFileDescriptor(), + assetFd.getStartOffset(), assetFd.getLength(), headerKeyValuePairs); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } @@ -419,4 +457,138 @@ public class UpdateEngine { throw e.rethrowFromSystemServer(); } } + + /** + * Return value of {@link #allocateSpace.} + */ + public static final class AllocateSpaceResult { + private @ErrorCode int mErrorCode = ErrorCodeConstants.SUCCESS; + private long mFreeSpaceRequired = 0; + private AllocateSpaceResult() {} + /** + * Error code. + * + * @return The following error codes: + * <ul> + * <li>{@link ErrorCodeConstants#SUCCESS} if space has been allocated + * successfully.</li> + * <li>{@link ErrorCodeConstants#NOT_ENOUGH_SPACE} if insufficient + * space.</li> + * <li>Other {@link ErrorCodeConstants} for other errors.</li> + * </ul> + */ + @ErrorCode + public int errorCode() { + return mErrorCode; + } + + /** + * Estimated total space that needs to be available on the userdata partition to apply the + * payload (in bytes). + * + * <p> + * Note that in practice, more space needs to be made available before applying the payload + * to keep the device working. + * + * @return The following values: + * <ul> + * <li>zero if {@link #errorCode} returns {@link ErrorCodeConstants#SUCCESS}</li> + * <li>non-zero if {@link #errorCode} returns {@link ErrorCodeConstants#NOT_ENOUGH_SPACE}. + * Value is the estimated total space required on userdata partition.</li> + * </ul> + * @throws IllegalStateException if {@link #errorCode} is not one of the above. + * + */ + public long freeSpaceRequired() { + if (mErrorCode == ErrorCodeConstants.SUCCESS) { + return 0; + } + if (mErrorCode == ErrorCodeConstants.NOT_ENOUGH_SPACE) { + return mFreeSpaceRequired; + } + throw new IllegalStateException(String.format( + "freeSpaceRequired() is not available when error code is %d", mErrorCode)); + } + } + + /** + * Initialize partitions for a payload associated with the given payload + * metadata {@code payloadMetadataFilename} by preallocating required space. + * + * <p>This function should be called after payload has been verified after + * {@link #verifyPayloadMetadata}. This function does not verify whether + * the given payload is applicable or not. + * + * <p>Implementation of {@code allocateSpace} uses + * {@code headerKeyValuePairs} to determine whether space has been allocated + * for a different or same payload previously. If space has been allocated + * for a different payload before, space will be reallocated for the given + * payload. If space has been allocated for the same payload, no actions to + * storage devices are taken. + * + * <p>This function is synchronous and may take a non-trivial amount of + * time. Callers should call this function in a background thread. + * + * @param payloadMetadataFilename See {@link #verifyPayloadMetadata}. + * @param headerKeyValuePairs See {@link #applyPayload}. + * @return See {@link AllocateSpaceResult}. + */ + @NonNull + public AllocateSpaceResult allocateSpace( + @NonNull String payloadMetadataFilename, + @NonNull String[] headerKeyValuePairs) { + AllocateSpaceResult result = new AllocateSpaceResult(); + try { + result.mFreeSpaceRequired = mUpdateEngine.allocateSpaceForPayload( + payloadMetadataFilename, + headerKeyValuePairs); + result.mErrorCode = result.mFreeSpaceRequired == 0 + ? ErrorCodeConstants.SUCCESS + : ErrorCodeConstants.NOT_ENOUGH_SPACE; + return result; + } catch (ServiceSpecificException e) { + result.mErrorCode = e.errorCode; + result.mFreeSpaceRequired = 0; + return result; + } catch (RemoteException e) { + throw e.rethrowFromSystemServer(); + } + } + + /** + * Cleanup files used by the previous update and free up space after the + * device has been booted successfully into the new build. + * + * <p>In particular, this function waits until delta files for snapshots for + * Virtual A/B update are merged to OS partitions, then delete these delta + * files. + * + * <p>This function is synchronous and may take a non-trivial amount of + * time. Callers should call this function in a background thread. + * + * <p>This function does not delete payload binaries downloaded for a + * non-streaming OTA update. + * + * @return One of the following: + * <ul> + * <li>{@link ErrorCodeConstants#SUCCESS} if execution is successful.</li> + * <li>{@link ErrorCodeConstants#ERROR} if a transient error has occurred. + * The device should be able to recover after a reboot. The function should + * be retried after the reboot.</li> + * <li>{@link ErrorCodeConstants#DEVICE_CORRUPTED} if a permanent error is + * encountered. Device is corrupted, and future updates must not be applied. + * The device cannot recover without flashing and factory resets. + * </ul> + * + * @throws ServiceSpecificException if other transient errors has occurred. + * A reboot may or may not help resolving the issue. + */ + @ErrorCode + public int cleanupAppliedPayload() { + try { + return mUpdateEngine.cleanupSuccessfulUpdate(); + } catch (RemoteException e) { + throw e.rethrowFromSystemServer(); + } + } } diff --git a/core/java/android/os/UpdateEngineCallback.java b/core/java/android/os/UpdateEngineCallback.java index f07294e222e2..7fe7024f25b3 100644 --- a/core/java/android/os/UpdateEngineCallback.java +++ b/core/java/android/os/UpdateEngineCallback.java @@ -44,5 +44,6 @@ public abstract class UpdateEngineCallback { * unsuccessfully. The value of {@code errorCode} will be one of the * values from {@link UpdateEngine.ErrorCodeConstants}. */ - public abstract void onPayloadApplicationComplete(int errorCode); + public abstract void onPayloadApplicationComplete( + @UpdateEngine.ErrorCode int errorCode); } diff --git a/core/java/android/os/UpdateLock.java b/core/java/android/os/UpdateLock.java index ea273cea8835..036d0951c19a 100644 --- a/core/java/android/os/UpdateLock.java +++ b/core/java/android/os/UpdateLock.java @@ -16,7 +16,7 @@ package android.os; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; import android.util.Log; diff --git a/core/java/android/os/UserHandle.java b/core/java/android/os/UserHandle.java index 45ee4efa27f7..0ec8658556d0 100644 --- a/core/java/android/os/UserHandle.java +++ b/core/java/android/os/UserHandle.java @@ -20,8 +20,8 @@ import android.annotation.AppIdInt; import android.annotation.NonNull; import android.annotation.SystemApi; import android.annotation.TestApi; -import android.annotation.UnsupportedAppUsage; import android.annotation.UserIdInt; +import android.compat.annotation.UnsupportedAppUsage; import java.io.PrintWriter; diff --git a/core/java/android/os/UserManager.java b/core/java/android/os/UserManager.java index c15618bdaa78..a507e2576df9 100644 --- a/core/java/android/os/UserManager.java +++ b/core/java/android/os/UserManager.java @@ -25,12 +25,12 @@ import android.annotation.RequiresPermission; import android.annotation.SystemApi; import android.annotation.SystemService; import android.annotation.TestApi; -import android.annotation.UnsupportedAppUsage; import android.annotation.UserIdInt; import android.annotation.WorkerThread; import android.app.Activity; import android.app.ActivityManager; import android.app.admin.DevicePolicyManager; +import android.compat.annotation.UnsupportedAppUsage; import android.content.ComponentName; import android.content.Context; import android.content.Intent; diff --git a/core/java/android/os/VibrationEffect.java b/core/java/android/os/VibrationEffect.java index 5769c34c6d20..75b4724c7d26 100644 --- a/core/java/android/os/VibrationEffect.java +++ b/core/java/android/os/VibrationEffect.java @@ -20,6 +20,7 @@ import android.annotation.IntDef; import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.TestApi; +import android.compat.annotation.UnsupportedAppUsage; import android.content.ContentResolver; import android.content.Context; import android.hardware.vibrator.V1_0.EffectStrength; @@ -27,8 +28,6 @@ import android.hardware.vibrator.V1_3.Effect; import android.net.Uri; import android.util.MathUtils; -import dalvik.annotation.compat.UnsupportedAppUsage; - import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.util.Arrays; diff --git a/core/java/android/os/Vibrator.java b/core/java/android/os/Vibrator.java index 6456d72a4a6f..ae75f3d0d7e6 100644 --- a/core/java/android/os/Vibrator.java +++ b/core/java/android/os/Vibrator.java @@ -20,8 +20,8 @@ import android.annotation.IntDef; import android.annotation.Nullable; import android.annotation.RequiresPermission; import android.annotation.SystemService; -import android.annotation.UnsupportedAppUsage; import android.app.ActivityThread; +import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; import android.media.AudioAttributes; import android.util.Log; @@ -155,7 +155,7 @@ public abstract class Vibrator { /** * Configure an always-on haptics effect. * - * @param id The board-specific always-on ID to configure. + * @param alwaysOnId The board-specific always-on ID to configure. * @param effect Vibration effect to assign to always-on id. Passing null will disable it. * @param attributes {@link AudioAttributes} corresponding to the vibration. For example, * specify {@link AudioAttributes#USAGE_ALARM} for alarm vibrations or @@ -164,8 +164,17 @@ public abstract class Vibrator { * @hide */ @RequiresPermission(android.Manifest.permission.VIBRATE_ALWAYS_ON) - public boolean setAlwaysOnEffect(int id, @Nullable VibrationEffect effect, - @Nullable AudioAttributes attributes) { + public boolean setAlwaysOnEffect(int alwaysOnId, @Nullable VibrationEffect effect, + @Nullable AudioAttributes attributes) { + return setAlwaysOnEffect(Process.myUid(), mPackageName, alwaysOnId, effect, attributes); + } + + /** + * @hide + */ + @RequiresPermission(android.Manifest.permission.VIBRATE_ALWAYS_ON) + public boolean setAlwaysOnEffect(int uid, String opPkg, int alwaysOnId, + @Nullable VibrationEffect effect, @Nullable AudioAttributes attributes) { Log.w(TAG, "Always-on effects aren't supported"); return false; } diff --git a/core/java/android/os/WorkSource.java b/core/java/android/os/WorkSource.java index 825fc64df5cc..684603514f00 100644 --- a/core/java/android/os/WorkSource.java +++ b/core/java/android/os/WorkSource.java @@ -4,9 +4,8 @@ import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.SystemApi; import android.annotation.TestApi; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; -import android.os.WorkSourceProto; import android.provider.Settings; import android.provider.Settings.Global; import android.util.Log; diff --git a/core/java/android/os/ZygoteProcess.java b/core/java/android/os/ZygoteProcess.java index c2d3eccfa3b1..016823e1a07d 100644 --- a/core/java/android/os/ZygoteProcess.java +++ b/core/java/android/os/ZygoteProcess.java @@ -18,7 +18,7 @@ package android.os; import android.annotation.NonNull; import android.annotation.Nullable; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.pm.ApplicationInfo; import android.net.LocalSocket; import android.net.LocalSocketAddress; diff --git a/core/java/android/os/health/HealthStatsParceler.java b/core/java/android/os/health/HealthStatsParceler.java index 384342c894d5..f28a9747bc44 100644 --- a/core/java/android/os/health/HealthStatsParceler.java +++ b/core/java/android/os/health/HealthStatsParceler.java @@ -17,11 +17,10 @@ package android.os.health; import android.annotation.TestApi; +import android.compat.annotation.UnsupportedAppUsage; import android.os.Parcel; import android.os.Parcelable; -import dalvik.annotation.compat.UnsupportedAppUsage; - /** * Class to allow sending the HealthStats through aidl generated glue. * diff --git a/core/java/android/os/health/SystemHealthManager.java b/core/java/android/os/health/SystemHealthManager.java index a92e28a47660..6e259ea2642c 100644 --- a/core/java/android/os/health/SystemHealthManager.java +++ b/core/java/android/os/health/SystemHealthManager.java @@ -17,14 +17,13 @@ package android.os.health; import android.annotation.SystemService; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; import android.os.BatteryStats; import android.os.Build; import android.os.Process; import android.os.RemoteException; import android.os.ServiceManager; -import android.os.ServiceManager.ServiceNotFoundException; import com.android.internal.app.IBatteryStats; diff --git a/core/java/android/os/image/DynamicSystemClient.java b/core/java/android/os/image/DynamicSystemClient.java index 921f0f2ab1e2..5cb33615fe22 100644 --- a/core/java/android/os/image/DynamicSystemClient.java +++ b/core/java/android/os/image/DynamicSystemClient.java @@ -256,9 +256,13 @@ public class DynamicSystemClient { mService.send(msg); } catch (RemoteException e) { Slog.e(TAG, "Unable to get status from installation service"); - mExecutor.execute(() -> { + if (mExecutor != null) { + mExecutor.execute(() -> { + mListener.onStatusChanged(STATUS_UNKNOWN, CAUSE_ERROR_IPC, 0, e); + }); + } else { mListener.onStatusChanged(STATUS_UNKNOWN, CAUSE_ERROR_IPC, 0, e); - }); + } } } diff --git a/core/java/android/os/image/DynamicSystemManager.java b/core/java/android/os/image/DynamicSystemManager.java index 4c92c28c1bfa..cbf531c5730a 100644 --- a/core/java/android/os/image/DynamicSystemManager.java +++ b/core/java/android/os/image/DynamicSystemManager.java @@ -106,9 +106,9 @@ public class DynamicSystemManager { * @return true if the call succeeds */ @RequiresPermission(android.Manifest.permission.MANAGE_DYNAMIC_SYSTEM) - public boolean startInstallation() { + public boolean startInstallation(String dsuSlot) { try { - return mService.startInstallation(); + return mService.startInstallation(dsuSlot); } catch (RemoteException e) { throw new RuntimeException(e.toString()); } diff --git a/core/java/android/os/image/IDynamicSystemService.aidl b/core/java/android/os/image/IDynamicSystemService.aidl index 69cbab2c68ad..cc32f998d0c2 100644 --- a/core/java/android/os/image/IDynamicSystemService.aidl +++ b/core/java/android/os/image/IDynamicSystemService.aidl @@ -22,9 +22,10 @@ interface IDynamicSystemService { /** * Start DynamicSystem installation. + * @param dsuSlot Name used to identify this installation * @return true if the call succeeds */ - boolean startInstallation(); + boolean startInstallation(@utf8InCpp String dsuSlot); /** * Create a DSU partition. This call may take 60~90 seconds. The caller diff --git a/core/java/android/os/storage/DiskInfo.java b/core/java/android/os/storage/DiskInfo.java index b797324c8007..df3c4d55d979 100644 --- a/core/java/android/os/storage/DiskInfo.java +++ b/core/java/android/os/storage/DiskInfo.java @@ -18,7 +18,7 @@ package android.os.storage; import android.annotation.NonNull; import android.annotation.Nullable; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.res.Resources; import android.os.Build; import android.os.Parcel; diff --git a/core/java/android/os/storage/StorageEventListener.java b/core/java/android/os/storage/StorageEventListener.java index 39d5b4529745..9fd9e4e4067d 100644 --- a/core/java/android/os/storage/StorageEventListener.java +++ b/core/java/android/os/storage/StorageEventListener.java @@ -16,7 +16,7 @@ package android.os.storage; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; /** * Used for receiving notifications from the StorageManager diff --git a/core/java/android/os/storage/StorageManager.java b/core/java/android/os/storage/StorageManager.java index 69c1295df4f9..c7709b988e49 100644 --- a/core/java/android/os/storage/StorageManager.java +++ b/core/java/android/os/storage/StorageManager.java @@ -40,12 +40,12 @@ import android.annotation.SuppressLint; import android.annotation.SystemApi; import android.annotation.SystemService; import android.annotation.TestApi; -import android.annotation.UnsupportedAppUsage; import android.annotation.WorkerThread; import android.app.Activity; import android.app.ActivityThread; import android.app.AppGlobals; import android.app.AppOpsManager; +import android.compat.annotation.UnsupportedAppUsage; import android.content.ContentResolver; import android.content.Context; import android.content.Intent; diff --git a/core/java/android/os/storage/StorageVolume.java b/core/java/android/os/storage/StorageVolume.java index aefe8430f9de..05b45fa7943c 100644 --- a/core/java/android/os/storage/StorageVolume.java +++ b/core/java/android/os/storage/StorageVolume.java @@ -19,7 +19,7 @@ package android.os.storage; import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.TestApi; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; import android.content.Intent; import android.net.Uri; diff --git a/core/java/android/os/storage/VolumeInfo.java b/core/java/android/os/storage/VolumeInfo.java index 7699a0529826..ff82982bc68b 100644 --- a/core/java/android/os/storage/VolumeInfo.java +++ b/core/java/android/os/storage/VolumeInfo.java @@ -18,7 +18,7 @@ package android.os.storage; import android.annotation.NonNull; import android.annotation.Nullable; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; import android.content.Intent; import android.content.res.Resources; diff --git a/core/java/android/os/storage/VolumeRecord.java b/core/java/android/os/storage/VolumeRecord.java index 1a794ebf2a59..c497c8b4fb02 100644 --- a/core/java/android/os/storage/VolumeRecord.java +++ b/core/java/android/os/storage/VolumeRecord.java @@ -16,7 +16,7 @@ package android.os.storage; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.os.Parcel; import android.os.Parcelable; import android.util.DebugUtils; diff --git a/core/java/android/preference/DialogPreference.java b/core/java/android/preference/DialogPreference.java index 32511e9afbea..dfdb57c4e3f8 100644 --- a/core/java/android/preference/DialogPreference.java +++ b/core/java/android/preference/DialogPreference.java @@ -21,9 +21,9 @@ import android.annotation.CallSuper; import android.annotation.DrawableRes; import android.annotation.Nullable; import android.annotation.StringRes; -import android.annotation.UnsupportedAppUsage; import android.app.AlertDialog; import android.app.Dialog; +import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; import android.content.DialogInterface; import android.content.SharedPreferences; diff --git a/core/java/android/preference/EditTextPreference.java b/core/java/android/preference/EditTextPreference.java index 74c5e3e49d63..af6f18416870 100644 --- a/core/java/android/preference/EditTextPreference.java +++ b/core/java/android/preference/EditTextPreference.java @@ -17,7 +17,7 @@ package android.preference; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; import android.content.SharedPreferences; import android.content.res.TypedArray; diff --git a/core/java/android/preference/ListPreference.java b/core/java/android/preference/ListPreference.java index 830de52576d8..0b648094150f 100644 --- a/core/java/android/preference/ListPreference.java +++ b/core/java/android/preference/ListPreference.java @@ -17,8 +17,8 @@ package android.preference; import android.annotation.ArrayRes; -import android.annotation.UnsupportedAppUsage; import android.app.AlertDialog.Builder; +import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; import android.content.DialogInterface; import android.content.res.TypedArray; diff --git a/core/java/android/preference/Preference.java b/core/java/android/preference/Preference.java index e82e60dfe1c4..f508dda00c55 100644 --- a/core/java/android/preference/Preference.java +++ b/core/java/android/preference/Preference.java @@ -21,7 +21,7 @@ import android.annotation.DrawableRes; import android.annotation.LayoutRes; import android.annotation.Nullable; import android.annotation.StringRes; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; import android.content.Intent; import android.content.SharedPreferences; diff --git a/core/java/android/preference/PreferenceActivity.java b/core/java/android/preference/PreferenceActivity.java index 47509713d335..ae4a626cdd5d 100644 --- a/core/java/android/preference/PreferenceActivity.java +++ b/core/java/android/preference/PreferenceActivity.java @@ -19,13 +19,13 @@ package android.preference; import android.animation.LayoutTransition; import android.annotation.Nullable; import android.annotation.StringRes; -import android.annotation.UnsupportedAppUsage; import android.annotation.XmlRes; import android.app.Fragment; import android.app.FragmentBreadCrumbs; import android.app.FragmentManager; import android.app.FragmentTransaction; import android.app.ListActivity; +import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; import android.content.Intent; import android.content.res.Resources; diff --git a/core/java/android/preference/PreferenceFragment.java b/core/java/android/preference/PreferenceFragment.java index d6c069f07d22..3f6e5051a3f8 100644 --- a/core/java/android/preference/PreferenceFragment.java +++ b/core/java/android/preference/PreferenceFragment.java @@ -17,10 +17,10 @@ package android.preference; import android.annotation.Nullable; -import android.annotation.UnsupportedAppUsage; import android.annotation.XmlRes; import android.app.Activity; import android.app.Fragment; +import android.compat.annotation.UnsupportedAppUsage; import android.content.Intent; import android.content.SharedPreferences; import android.content.res.TypedArray; diff --git a/core/java/android/preference/PreferenceGroupAdapter.java b/core/java/android/preference/PreferenceGroupAdapter.java index dcc5d4c58784..b263f5041fd6 100644 --- a/core/java/android/preference/PreferenceGroupAdapter.java +++ b/core/java/android/preference/PreferenceGroupAdapter.java @@ -16,7 +16,7 @@ package android.preference; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.graphics.drawable.Drawable; import android.os.Handler; import android.preference.Preference.OnPreferenceChangeInternalListener; diff --git a/core/java/android/preference/PreferenceManager.java b/core/java/android/preference/PreferenceManager.java index f741bd686beb..9d3f349320ad 100644 --- a/core/java/android/preference/PreferenceManager.java +++ b/core/java/android/preference/PreferenceManager.java @@ -18,9 +18,9 @@ package android.preference; import android.annotation.Nullable; import android.annotation.SystemApi; -import android.annotation.UnsupportedAppUsage; import android.annotation.XmlRes; import android.app.Activity; +import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; import android.content.DialogInterface; import android.content.Intent; diff --git a/core/java/android/preference/PreferenceScreen.java b/core/java/android/preference/PreferenceScreen.java index a353dbc8af1b..01fe2f3f6b3a 100644 --- a/core/java/android/preference/PreferenceScreen.java +++ b/core/java/android/preference/PreferenceScreen.java @@ -16,8 +16,8 @@ package android.preference; -import android.annotation.UnsupportedAppUsage; import android.app.Dialog; +import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; import android.content.DialogInterface; import android.content.res.TypedArray; diff --git a/core/java/android/preference/RingtonePreference.java b/core/java/android/preference/RingtonePreference.java index 025aad0fcaac..c6d8c08c9141 100644 --- a/core/java/android/preference/RingtonePreference.java +++ b/core/java/android/preference/RingtonePreference.java @@ -16,7 +16,7 @@ package android.preference; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; import android.content.Intent; import android.content.res.TypedArray; diff --git a/core/java/android/preference/SeekBarDialogPreference.java b/core/java/android/preference/SeekBarDialogPreference.java index 32ef82103f6c..46be12211fe4 100644 --- a/core/java/android/preference/SeekBarDialogPreference.java +++ b/core/java/android/preference/SeekBarDialogPreference.java @@ -16,7 +16,7 @@ package android.preference; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; import android.graphics.drawable.Drawable; import android.util.AttributeSet; diff --git a/core/java/android/preference/SeekBarPreference.java b/core/java/android/preference/SeekBarPreference.java index 99ab9dbeb280..a2852bc2cce3 100644 --- a/core/java/android/preference/SeekBarPreference.java +++ b/core/java/android/preference/SeekBarPreference.java @@ -16,7 +16,7 @@ package android.preference; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; import android.content.res.TypedArray; import android.os.Parcel; diff --git a/core/java/android/preference/SeekBarVolumizer.java b/core/java/android/preference/SeekBarVolumizer.java index 2b3a2ab05e82..5ff98f9d0697 100644 --- a/core/java/android/preference/SeekBarVolumizer.java +++ b/core/java/android/preference/SeekBarVolumizer.java @@ -17,8 +17,8 @@ package android.preference; import android.annotation.NonNull; -import android.annotation.UnsupportedAppUsage; import android.app.NotificationManager; +import android.compat.annotation.UnsupportedAppUsage; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; diff --git a/core/java/android/preference/SwitchPreference.java b/core/java/android/preference/SwitchPreference.java index 9dea1c829713..baa023e41aad 100644 --- a/core/java/android/preference/SwitchPreference.java +++ b/core/java/android/preference/SwitchPreference.java @@ -17,7 +17,7 @@ package android.preference; import android.annotation.StringRes; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; import android.content.res.TypedArray; import android.util.AttributeSet; diff --git a/core/java/android/preference/TwoStatePreference.java b/core/java/android/preference/TwoStatePreference.java index bb771d721d83..5eb5d17d9bc8 100644 --- a/core/java/android/preference/TwoStatePreference.java +++ b/core/java/android/preference/TwoStatePreference.java @@ -17,7 +17,7 @@ package android.preference; import android.annotation.StringRes; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; import android.content.SharedPreferences; import android.content.res.TypedArray; diff --git a/core/java/android/preference/VolumePreference.java b/core/java/android/preference/VolumePreference.java index a2d5a2312047..6eb524a3886c 100644 --- a/core/java/android/preference/VolumePreference.java +++ b/core/java/android/preference/VolumePreference.java @@ -16,8 +16,8 @@ package android.preference; -import android.annotation.UnsupportedAppUsage; import android.app.Dialog; +import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; import android.content.res.TypedArray; import android.os.Parcel; diff --git a/core/java/android/print/PrintDocumentAdapter.java b/core/java/android/print/PrintDocumentAdapter.java index d1b6efc70a2a..7ea5655169e9 100644 --- a/core/java/android/print/PrintDocumentAdapter.java +++ b/core/java/android/print/PrintDocumentAdapter.java @@ -16,7 +16,7 @@ package android.print; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.os.Bundle; import android.os.CancellationSignal; import android.os.ParcelFileDescriptor; diff --git a/core/java/android/print/PrintJobInfo.java b/core/java/android/print/PrintJobInfo.java index 25f383c09ad1..63f38f8a7b4c 100644 --- a/core/java/android/print/PrintJobInfo.java +++ b/core/java/android/print/PrintJobInfo.java @@ -23,7 +23,7 @@ import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.StringRes; import android.annotation.TestApi; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.pm.PackageManager; import android.content.res.Resources; import android.os.Bundle; diff --git a/core/java/android/print/PrintManager.java b/core/java/android/print/PrintManager.java index e1ede93a9ac5..9abce5d46ac6 100644 --- a/core/java/android/print/PrintManager.java +++ b/core/java/android/print/PrintManager.java @@ -22,9 +22,9 @@ import android.annotation.RequiresFeature; import android.annotation.RequiresPermission; import android.annotation.SystemApi; import android.annotation.SystemService; -import android.annotation.UnsupportedAppUsage; import android.app.Activity; import android.app.Application.ActivityLifecycleCallbacks; +import android.compat.annotation.UnsupportedAppUsage; import android.content.ComponentName; import android.content.Context; import android.content.IntentSender; diff --git a/core/java/android/print/PrinterId.java b/core/java/android/print/PrinterId.java index 42570c69650f..75ca7507450f 100644 --- a/core/java/android/print/PrinterId.java +++ b/core/java/android/print/PrinterId.java @@ -17,7 +17,7 @@ package android.print; import android.annotation.NonNull; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.ComponentName; import android.os.Parcel; import android.os.Parcelable; diff --git a/core/java/android/provider/Browser.java b/core/java/android/provider/Browser.java index 30021b488dc5..afa7b80f58a0 100644 --- a/core/java/android/provider/Browser.java +++ b/core/java/android/provider/Browser.java @@ -16,10 +16,8 @@ package android.provider; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.ContentResolver; -import android.content.ContentUris; -import android.content.ContentValues; import android.content.Context; import android.content.Intent; import android.database.Cursor; @@ -30,8 +28,6 @@ import android.net.Uri; import android.provider.BrowserContract.Bookmarks; import android.provider.BrowserContract.Combined; import android.provider.BrowserContract.History; -import android.provider.BrowserContract.Searches; -import android.util.Log; import android.webkit.WebIconDatabase; public class Browser { diff --git a/core/java/android/provider/BrowserContract.java b/core/java/android/provider/BrowserContract.java index 57dde6693001..5083b8b254ab 100644 --- a/core/java/android/provider/BrowserContract.java +++ b/core/java/android/provider/BrowserContract.java @@ -17,7 +17,7 @@ package android.provider; import android.accounts.Account; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.ContentProviderClient; import android.content.ContentProviderOperation; import android.content.ContentResolver; diff --git a/core/java/android/provider/CalendarContract.java b/core/java/android/provider/CalendarContract.java index 7285166cdd5f..9c6c92ace483 100644 --- a/core/java/android/provider/CalendarContract.java +++ b/core/java/android/provider/CalendarContract.java @@ -20,11 +20,11 @@ import android.annotation.NonNull; import android.annotation.SdkConstant; import android.annotation.SdkConstant.SdkConstantType; import android.annotation.TestApi; -import android.annotation.UnsupportedAppUsage; import android.app.Activity; import android.app.AlarmManager; import android.app.PendingIntent; import android.app.admin.DevicePolicyManager; +import android.compat.annotation.UnsupportedAppUsage; import android.content.ComponentName; import android.content.ContentProviderClient; import android.content.ContentResolver; diff --git a/core/java/android/provider/CallLog.java b/core/java/android/provider/CallLog.java index 391f3a2fd135..9ffeff99e153 100644 --- a/core/java/android/provider/CallLog.java +++ b/core/java/android/provider/CallLog.java @@ -17,7 +17,7 @@ package android.provider; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.ContentProvider; import android.content.ContentResolver; import android.content.ContentValues; diff --git a/core/java/android/provider/ContactsContract.java b/core/java/android/provider/ContactsContract.java index f10e184ccf5a..524731197cd7 100644 --- a/core/java/android/provider/ContactsContract.java +++ b/core/java/android/provider/ContactsContract.java @@ -21,8 +21,8 @@ import android.annotation.SdkConstant; import android.annotation.SdkConstant.SdkConstantType; import android.annotation.SystemApi; import android.annotation.TestApi; -import android.annotation.UnsupportedAppUsage; import android.app.Activity; +import android.compat.annotation.UnsupportedAppUsage; import android.content.BroadcastReceiver; import android.content.ComponentName; import android.content.ContentProviderClient; diff --git a/core/java/android/provider/ContactsInternal.java b/core/java/android/provider/ContactsInternal.java index 69c4b9b9abf2..aa2a89cfd612 100644 --- a/core/java/android/provider/ContactsInternal.java +++ b/core/java/android/provider/ContactsInternal.java @@ -15,15 +15,14 @@ */ package android.provider; -import android.annotation.UnsupportedAppUsage; import android.app.admin.DevicePolicyManager; +import android.compat.annotation.UnsupportedAppUsage; import android.content.ActivityNotFoundException; import android.content.ContentUris; import android.content.Context; import android.content.Intent; import android.content.UriMatcher; import android.net.Uri; -import android.os.Process; import android.os.UserHandle; import android.text.TextUtils; import android.widget.Toast; diff --git a/core/java/android/provider/DocumentsContract.java b/core/java/android/provider/DocumentsContract.java index fd81178d2cfb..4bbd213753c2 100644 --- a/core/java/android/provider/DocumentsContract.java +++ b/core/java/android/provider/DocumentsContract.java @@ -22,7 +22,7 @@ import static com.android.internal.util.Preconditions.checkCollectionNotEmpty; import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.SystemApi; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.ContentInterface; import android.content.ContentResolver; import android.content.Context; diff --git a/core/java/android/provider/Downloads.java b/core/java/android/provider/Downloads.java index 9a384c6d9d79..48410a748766 100644 --- a/core/java/android/provider/Downloads.java +++ b/core/java/android/provider/Downloads.java @@ -16,8 +16,8 @@ package android.provider; -import android.annotation.UnsupportedAppUsage; import android.app.DownloadManager; +import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; import android.net.NetworkPolicyManager; import android.net.Uri; diff --git a/core/java/android/provider/MediaStore.java b/core/java/android/provider/MediaStore.java index 2299aad6f79a..f6cf1d294765 100644 --- a/core/java/android/provider/MediaStore.java +++ b/core/java/android/provider/MediaStore.java @@ -27,9 +27,9 @@ import android.annotation.RequiresPermission; import android.annotation.SdkConstant; import android.annotation.SdkConstant.SdkConstantType; import android.annotation.TestApi; -import android.annotation.UnsupportedAppUsage; import android.app.Activity; import android.app.AppGlobals; +import android.compat.annotation.UnsupportedAppUsage; import android.content.ClipData; import android.content.ContentProviderClient; import android.content.ContentResolver; diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java index e348b5f63a46..1f3ae09e9216 100644 --- a/core/java/android/provider/Settings.java +++ b/core/java/android/provider/Settings.java @@ -37,7 +37,6 @@ import android.annotation.SdkConstant; import android.annotation.SdkConstant.SdkConstantType; import android.annotation.SystemApi; import android.annotation.TestApi; -import android.annotation.UnsupportedAppUsage; import android.annotation.UserIdInt; import android.app.ActivityThread; import android.app.AppOpsManager; @@ -46,6 +45,7 @@ import android.app.NotificationChannel; import android.app.NotificationManager; import android.app.SearchManager; import android.app.WallpaperManager; +import android.compat.annotation.UnsupportedAppUsage; import android.content.ComponentName; import android.content.ContentResolver; import android.content.ContentValues; @@ -231,7 +231,9 @@ public final class Settings { * @hide */ @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION) - public static final String ACTION_TETHER_PROVISIONING = + @SystemApi + @TestApi + public static final String ACTION_TETHER_PROVISIONING_UI = "android.settings.TETHER_PROVISIONING_UI"; /** @@ -10441,6 +10443,8 @@ public final class Settings { * is interpreted as |false|. * @hide */ + @SystemApi + @TestApi public static final String TETHER_OFFLOAD_DISABLED = "tether_offload_disabled"; /** @@ -15264,8 +15268,9 @@ public final class Settings { * current time. * @hide */ - public static boolean checkAndNoteWriteSettingsOperation(Context context, int uid, - String callingPackage, boolean throwException) { + @SystemApi + public static boolean checkAndNoteWriteSettingsOperation(@NonNull Context context, int uid, + @NonNull String callingPackage, boolean throwException) { return isCallingPackageAllowedToPerformAppOpsProtectedOperation(context, uid, callingPackage, throwException, AppOpsManager.OP_WRITE_SETTINGS, PM_WRITE_SETTINGS, true); diff --git a/core/java/android/provider/Telephony.java b/core/java/android/provider/Telephony.java index 13d167d5e99a..90ac821363b2 100644 --- a/core/java/android/provider/Telephony.java +++ b/core/java/android/provider/Telephony.java @@ -24,7 +24,7 @@ import android.annotation.SdkConstant; import android.annotation.SdkConstant.SdkConstantType; import android.annotation.SystemApi; import android.annotation.TestApi; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.ComponentName; import android.content.ContentResolver; import android.content.ContentValues; @@ -35,6 +35,7 @@ import android.database.Cursor; import android.database.sqlite.SqliteWrapper; import android.net.Uri; import android.os.Build; +import android.os.Bundle; import android.os.Parcel; import android.telephony.Rlog; import android.telephony.ServiceState; @@ -4058,6 +4059,108 @@ public final class Telephony { public static final Uri MESSAGE_HISTORY_URI = Uri.parse("content://cellbroadcasts/history"); /** + * The authority for the legacy cellbroadcast provider. + * This is used for OEM data migration. OEMs want to migrate message history or + * sharepreference data to mainlined cellbroadcastreceiver app, should have a + * contentprovider with authority: cellbroadcast-legacy. Mainlined cellbroadcastreceiver + * will interact with this URI to retrieve data and persists to mainlined cellbroadcast app. + * + * @hide + */ + @SystemApi + public static final @NonNull String AUTHORITY_LEGACY = "cellbroadcast-legacy"; + + /** + * A content:// style uri to the authority for the legacy cellbroadcast provider. + * @hide + */ + @SystemApi + public static final @NonNull Uri AUTHORITY_LEGACY_URI = + Uri.parse("content://cellbroadcast-legacy"); + + /** + * Method name to {@link android.content.ContentProvider#call(String, String, Bundle) + * for {@link #AUTHORITY_LEGACY}. Used to query cellbroadcast {@link Preference}, + * containing following supported entries + * <ul> + * <li>{@link #ENABLE_AREA_UPDATE_INFO_PREF}</li> + * <li>{@link #ENABLE_TEST_ALERT_PREF}</li> + * <li>{@link #ENABLE_STATE_LOCAL_TEST_PREF}</li> + * <li>{@link #ENABLE_PUBLIC_SAFETY_PREF}</li> + * <li>{@link #ENABLE_CMAS_AMBER_PREF}</li> + * <li>{@link #ENABLE_CMAS_SEVERE_THREAT_PREF}</li> + * <li>{@link #ENABLE_CMAS_EXTREME_THREAT_PREF}</li> + * <li>{@link #ENABLE_CMAS_PRESIDENTIAL_PREF}</li> + * <li>{@link #ENABLE_ALERT_VIBRATION_PREF}</li> + * <li>{@link #ENABLE_EMERGENCY_PERF}</li> + * <li>{@link #ENABLE_CMAS_IN_SECOND_LANGUAGE_PREF}</li> + * </ul> + * @hide + */ + @SystemApi + public static final @NonNull String CALL_METHOD_GET_PREFERENCE = "get_preference"; + + /** + * Arg name to {@link android.content.ContentProvider#call(String, String, Bundle)} + * for {@link #AUTHORITY_LEGACY}. + * Contains all supported shared preferences for cellbroadcast. + * + * @hide + */ + @SystemApi + public static final class Preference { + /** + * Not Instantiatable. + * @hide + */ + private Preference() {} + + /** Preference to enable area update info alert */ + public static final @NonNull String ENABLE_AREA_UPDATE_INFO_PREF = + "enable_area_update_info_alerts"; + + /** Preference to enable test alert */ + public static final @NonNull String ENABLE_TEST_ALERT_PREF = + "enable_test_alerts"; + + /** Preference to enable state local test alert */ + public static final @NonNull String ENABLE_STATE_LOCAL_TEST_PREF + = "enable_state_local_test_alerts"; + + /** Preference to enable public safety alert */ + public static final @NonNull String ENABLE_PUBLIC_SAFETY_PREF + = "enable_public_safety_messages"; + + /** Preference to enable amber alert */ + public static final @NonNull String ENABLE_CMAS_AMBER_PREF + = "enable_cmas_amber_alerts"; + + /** Preference to enable severe threat alert */ + public static final @NonNull String ENABLE_CMAS_SEVERE_THREAT_PREF + = "enable_cmas_severe_threat_alerts"; + + /** Preference to enable extreme threat alert */ + public static final @NonNull String ENABLE_CMAS_EXTREME_THREAT_PREF = + "enable_cmas_extreme_threat_alerts"; + + /** Preference to enable presidential alert */ + public static final @NonNull String ENABLE_CMAS_PRESIDENTIAL_PREF = + "enable_cmas_presidential_alerts"; + + /** Preference to enable alert vibration */ + public static final @NonNull String ENABLE_ALERT_VIBRATION_PREF = + "enable_alert_vibrate"; + + /** Preference to enable emergency alert */ + public static final @NonNull String ENABLE_EMERGENCY_PERF = + "enable_emergency_alerts"; + + /** Preference to enable receive alerts in second language */ + public static final @NonNull String ENABLE_CMAS_IN_SECOND_LANGUAGE_PREF = + "receive_cmas_in_second_language"; + } + + /** * The subscription which received this cell broadcast message. * <P>Type: INTEGER</P> */ diff --git a/core/java/android/se/omapi/SEService.java b/core/java/android/se/omapi/SEService.java index d646e23d230a..00060ab8ef4a 100644 --- a/core/java/android/se/omapi/SEService.java +++ b/core/java/android/se/omapi/SEService.java @@ -22,14 +22,11 @@ package android.se.omapi; -import android.app.ActivityThread; import android.annotation.NonNull; import android.content.ComponentName; import android.content.Context; import android.content.Intent; import android.content.ServiceConnection; -import android.content.pm.IPackageManager; -import android.content.pm.PackageManager; import android.os.IBinder; import android.os.RemoteException; import android.util.Log; @@ -143,10 +140,6 @@ public final class SEService { throw new NullPointerException("Arguments must not be null"); } - if (!hasOMAPIReaders()) { - throw new UnsupportedOperationException("Device does not support any OMAPI reader"); - } - mContext = context; mSEListener.mListener = listener; mSEListener.mExecutor = executor; @@ -277,23 +270,4 @@ public final class SEService { throw new IllegalStateException(e.getMessage()); } } - - /** - * Helper to check if this device support any OMAPI readers - */ - private static boolean hasOMAPIReaders() { - IPackageManager pm = ActivityThread.getPackageManager(); - if (pm == null) { - Log.e(TAG, "Cannot get package manager, assuming OMAPI readers supported"); - return true; - } - try { - return pm.hasSystemFeature(PackageManager.FEATURE_SE_OMAPI_UICC, 0) - || pm.hasSystemFeature(PackageManager.FEATURE_SE_OMAPI_ESE, 0) - || pm.hasSystemFeature(PackageManager.FEATURE_SE_OMAPI_SD, 0); - } catch (RemoteException e) { - Log.e(TAG, "Package manager query failed, assuming OMAPI readers supported", e); - return true; - } - } } diff --git a/core/java/android/security/KeystoreArguments.java b/core/java/android/security/KeystoreArguments.java index e634234493e3..a59c4e04285d 100644 --- a/core/java/android/security/KeystoreArguments.java +++ b/core/java/android/security/KeystoreArguments.java @@ -16,7 +16,7 @@ package android.security; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.os.Parcel; import android.os.Parcelable; diff --git a/core/java/android/security/keymaster/ExportResult.java b/core/java/android/security/keymaster/ExportResult.java index 1be5ae90d911..037b85270306 100644 --- a/core/java/android/security/keymaster/ExportResult.java +++ b/core/java/android/security/keymaster/ExportResult.java @@ -16,7 +16,7 @@ package android.security.keymaster; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.os.Parcel; import android.os.Parcelable; diff --git a/core/java/android/security/keymaster/KeyCharacteristics.java b/core/java/android/security/keymaster/KeyCharacteristics.java index 2eb2cefc3617..d8382fa8f969 100644 --- a/core/java/android/security/keymaster/KeyCharacteristics.java +++ b/core/java/android/security/keymaster/KeyCharacteristics.java @@ -16,7 +16,7 @@ package android.security.keymaster; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.os.Parcel; import android.os.Parcelable; diff --git a/core/java/android/security/keymaster/KeymasterArguments.java b/core/java/android/security/keymaster/KeymasterArguments.java index d2dbdec7f726..e009e128bfea 100644 --- a/core/java/android/security/keymaster/KeymasterArguments.java +++ b/core/java/android/security/keymaster/KeymasterArguments.java @@ -16,7 +16,7 @@ package android.security.keymaster; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.os.Parcel; import android.os.Parcelable; diff --git a/core/java/android/security/keymaster/KeymasterBlob.java b/core/java/android/security/keymaster/KeymasterBlob.java index 6a2024f0feb6..68365bfe603f 100644 --- a/core/java/android/security/keymaster/KeymasterBlob.java +++ b/core/java/android/security/keymaster/KeymasterBlob.java @@ -16,7 +16,7 @@ package android.security.keymaster; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.os.Parcel; import android.os.Parcelable; diff --git a/core/java/android/security/keymaster/KeymasterBlobArgument.java b/core/java/android/security/keymaster/KeymasterBlobArgument.java index fc562bd2174e..81b08c5b5b0a 100644 --- a/core/java/android/security/keymaster/KeymasterBlobArgument.java +++ b/core/java/android/security/keymaster/KeymasterBlobArgument.java @@ -16,7 +16,7 @@ package android.security.keymaster; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.os.Parcel; /** diff --git a/core/java/android/security/keymaster/KeymasterBooleanArgument.java b/core/java/android/security/keymaster/KeymasterBooleanArgument.java index 4286aa0d4ae3..25b2ac409d97 100644 --- a/core/java/android/security/keymaster/KeymasterBooleanArgument.java +++ b/core/java/android/security/keymaster/KeymasterBooleanArgument.java @@ -16,7 +16,7 @@ package android.security.keymaster; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.os.Parcel; /** diff --git a/core/java/android/security/keymaster/KeymasterDateArgument.java b/core/java/android/security/keymaster/KeymasterDateArgument.java index 3e04c1543117..218f4880b289 100644 --- a/core/java/android/security/keymaster/KeymasterDateArgument.java +++ b/core/java/android/security/keymaster/KeymasterDateArgument.java @@ -16,8 +16,9 @@ package android.security.keymaster; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.os.Parcel; + import java.util.Date; /** diff --git a/core/java/android/security/keymaster/KeymasterIntArgument.java b/core/java/android/security/keymaster/KeymasterIntArgument.java index 4aadce458395..01d38c799d9c 100644 --- a/core/java/android/security/keymaster/KeymasterIntArgument.java +++ b/core/java/android/security/keymaster/KeymasterIntArgument.java @@ -16,7 +16,7 @@ package android.security.keymaster; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.os.Parcel; /** diff --git a/core/java/android/security/keymaster/KeymasterLongArgument.java b/core/java/android/security/keymaster/KeymasterLongArgument.java index bc2255e22a69..3ac27ccef295 100644 --- a/core/java/android/security/keymaster/KeymasterLongArgument.java +++ b/core/java/android/security/keymaster/KeymasterLongArgument.java @@ -16,7 +16,7 @@ package android.security.keymaster; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.os.Parcel; /** diff --git a/core/java/android/security/keymaster/OperationResult.java b/core/java/android/security/keymaster/OperationResult.java index c278eb3b85fd..b4e155a527de 100644 --- a/core/java/android/security/keymaster/OperationResult.java +++ b/core/java/android/security/keymaster/OperationResult.java @@ -16,7 +16,7 @@ package android.security.keymaster; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.os.IBinder; import android.os.Parcel; import android.os.Parcelable; diff --git a/core/java/android/security/net/config/RootTrustManager.java b/core/java/android/security/net/config/RootTrustManager.java index d8936d948ead..58dc4ba8df21 100644 --- a/core/java/android/security/net/config/RootTrustManager.java +++ b/core/java/android/security/net/config/RootTrustManager.java @@ -16,15 +16,16 @@ package android.security.net.config; +import android.compat.annotation.UnsupportedAppUsage; + import java.net.Socket; import java.security.cert.CertificateException; import java.security.cert.X509Certificate; import java.util.List; -import android.annotation.UnsupportedAppUsage; -import javax.net.ssl.SSLSocket; import javax.net.ssl.SSLEngine; import javax.net.ssl.SSLSession; +import javax.net.ssl.SSLSocket; import javax.net.ssl.X509ExtendedTrustManager; /** diff --git a/core/java/android/service/dreams/DreamService.java b/core/java/android/service/dreams/DreamService.java index 38de79456bee..de4a5511fcdb 100644 --- a/core/java/android/service/dreams/DreamService.java +++ b/core/java/android/service/dreams/DreamService.java @@ -21,9 +21,9 @@ import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.SdkConstant; import android.annotation.SdkConstant.SdkConstantType; -import android.annotation.UnsupportedAppUsage; import android.app.AlarmManager; import android.app.Service; +import android.compat.annotation.UnsupportedAppUsage; import android.content.Intent; import android.graphics.PixelFormat; import android.graphics.drawable.ColorDrawable; diff --git a/core/java/android/service/notification/NotificationListenerService.java b/core/java/android/service/notification/NotificationListenerService.java index b44c9d59ebe5..5da34a343513 100644 --- a/core/java/android/service/notification/NotificationListenerService.java +++ b/core/java/android/service/notification/NotificationListenerService.java @@ -22,7 +22,6 @@ import android.annotation.NonNull; import android.annotation.SdkConstant; import android.annotation.SystemApi; import android.annotation.TestApi; -import android.annotation.UnsupportedAppUsage; import android.app.ActivityManager; import android.app.INotificationManager; import android.app.Notification; @@ -33,6 +32,7 @@ import android.app.NotificationManager; import android.app.Person; import android.app.Service; import android.companion.CompanionDeviceManager; +import android.compat.annotation.UnsupportedAppUsage; import android.content.ComponentName; import android.content.Context; import android.content.Intent; diff --git a/core/java/android/service/notification/StatusBarNotification.java b/core/java/android/service/notification/StatusBarNotification.java index 905c7811e457..d8ea971ced29 100644 --- a/core/java/android/service/notification/StatusBarNotification.java +++ b/core/java/android/service/notification/StatusBarNotification.java @@ -17,10 +17,10 @@ package android.service.notification; import android.annotation.NonNull; -import android.annotation.UnsupportedAppUsage; import android.app.Notification; import android.app.NotificationManager; import android.app.Person; +import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; import android.content.pm.ApplicationInfo; import android.content.pm.PackageManager; diff --git a/core/java/android/service/notification/ZenModeConfig.java b/core/java/android/service/notification/ZenModeConfig.java index 93bcdbffd133..9e7af1f41a87 100644 --- a/core/java/android/service/notification/ZenModeConfig.java +++ b/core/java/android/service/notification/ZenModeConfig.java @@ -20,11 +20,11 @@ import static android.app.NotificationManager.Policy.SUPPRESSED_EFFECT_FULL_SCRE import static android.app.NotificationManager.Policy.SUPPRESSED_EFFECT_LIGHTS; import static android.app.NotificationManager.Policy.SUPPRESSED_EFFECT_PEEK; -import android.annotation.UnsupportedAppUsage; import android.app.ActivityManager; import android.app.AlarmManager; import android.app.NotificationManager; import android.app.NotificationManager.Policy; +import android.compat.annotation.UnsupportedAppUsage; import android.content.ComponentName; import android.content.Context; import android.content.pm.ApplicationInfo; diff --git a/core/java/android/service/voice/AlwaysOnHotwordDetector.java b/core/java/android/service/voice/AlwaysOnHotwordDetector.java index bd953cad2b75..e6b19224cce4 100644 --- a/core/java/android/service/voice/AlwaysOnHotwordDetector.java +++ b/core/java/android/service/voice/AlwaysOnHotwordDetector.java @@ -19,8 +19,8 @@ package android.service.voice; import android.annotation.IntDef; import android.annotation.NonNull; import android.annotation.Nullable; -import android.annotation.UnsupportedAppUsage; import android.app.Activity; +import android.compat.annotation.UnsupportedAppUsage; import android.content.Intent; import android.hardware.soundtrigger.IRecognitionStatusCallback; import android.hardware.soundtrigger.KeyphraseEnrollmentInfo; @@ -32,7 +32,6 @@ import android.hardware.soundtrigger.SoundTrigger.KeyphraseRecognitionExtra; import android.hardware.soundtrigger.SoundTrigger.KeyphraseSoundModel; import android.hardware.soundtrigger.SoundTrigger.ModuleProperties; import android.hardware.soundtrigger.SoundTrigger.RecognitionConfig; -import android.hardware.soundtrigger.SoundTrigger.RecognitionEvent; import android.media.AudioFormat; import android.os.AsyncTask; import android.os.Handler; diff --git a/core/java/android/service/voice/VoiceInteractionService.java b/core/java/android/service/voice/VoiceInteractionService.java index 0de17ca3b960..36e057f4a97d 100644 --- a/core/java/android/service/voice/VoiceInteractionService.java +++ b/core/java/android/service/voice/VoiceInteractionService.java @@ -18,8 +18,8 @@ package android.service.voice; import android.annotation.NonNull; import android.annotation.SdkConstant; -import android.annotation.UnsupportedAppUsage; import android.app.Service; +import android.compat.annotation.UnsupportedAppUsage; import android.content.ComponentName; import android.content.Context; import android.content.Intent; diff --git a/core/java/android/service/vr/VrListenerService.java b/core/java/android/service/vr/VrListenerService.java index 3c384955a578..2758ace8d00b 100644 --- a/core/java/android/service/vr/VrListenerService.java +++ b/core/java/android/service/vr/VrListenerService.java @@ -18,9 +18,9 @@ package android.service.vr; import android.annotation.NonNull; import android.annotation.SdkConstant; -import android.annotation.UnsupportedAppUsage; import android.app.ActivityManager; import android.app.Service; +import android.compat.annotation.UnsupportedAppUsage; import android.content.ComponentName; import android.content.Context; import android.content.Intent; diff --git a/core/java/android/service/wallpaper/Android.bp b/core/java/android/service/wallpaper/Android.bp index aa6123f5a983..ffbdb035c36c 100644 --- a/core/java/android/service/wallpaper/Android.bp +++ b/core/java/android/service/wallpaper/Android.bp @@ -6,6 +6,8 @@ android_library { "I*.aidl", ], + libs: ["unsupportedappusage"], + // Enforce that the library is built against java 8 so that there are // no compatibility issues with launcher java_version: "1.8", diff --git a/core/java/android/service/wallpaper/WallpaperService.java b/core/java/android/service/wallpaper/WallpaperService.java index d645e3f746d7..3cb3ec3e25f5 100644 --- a/core/java/android/service/wallpaper/WallpaperService.java +++ b/core/java/android/service/wallpaper/WallpaperService.java @@ -20,11 +20,11 @@ import android.annotation.Nullable; import android.annotation.SdkConstant; import android.annotation.SdkConstant.SdkConstantType; import android.annotation.SystemApi; -import android.annotation.UnsupportedAppUsage; import android.app.Service; import android.app.WallpaperColors; import android.app.WallpaperInfo; import android.app.WallpaperManager; +import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; import android.content.Intent; import android.content.res.TypedArray; diff --git a/core/java/android/speech/tts/TextToSpeech.java b/core/java/android/speech/tts/TextToSpeech.java index 100774c896ca..f3650d6834c8 100644 --- a/core/java/android/speech/tts/TextToSpeech.java +++ b/core/java/android/speech/tts/TextToSpeech.java @@ -20,7 +20,7 @@ import android.annotation.Nullable; import android.annotation.RawRes; import android.annotation.SdkConstant; import android.annotation.SdkConstant.SdkConstantType; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.ComponentName; import android.content.ContentResolver; import android.content.Context; diff --git a/core/java/android/speech/tts/TtsEngines.java b/core/java/android/speech/tts/TtsEngines.java index 2fab40472bd5..a8aea7c1eb59 100644 --- a/core/java/android/speech/tts/TtsEngines.java +++ b/core/java/android/speech/tts/TtsEngines.java @@ -18,7 +18,7 @@ package android.speech.tts; import static android.provider.Settings.Secure.getString; import android.annotation.NonNull; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; import android.content.Intent; import android.content.pm.ApplicationInfo; diff --git a/core/java/android/telephony/PhoneStateListener.java b/core/java/android/telephony/PhoneStateListener.java index 146c1c3b6123..e08a06abad45 100644 --- a/core/java/android/telephony/PhoneStateListener.java +++ b/core/java/android/telephony/PhoneStateListener.java @@ -21,10 +21,9 @@ import android.annotation.NonNull; import android.annotation.RequiresPermission; import android.annotation.SystemApi; import android.annotation.TestApi; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.os.Binder; import android.os.Build; -import android.os.Bundle; import android.os.Handler; import android.os.HandlerExecutor; import android.os.Looper; @@ -370,6 +369,21 @@ public class PhoneStateListener { @RequiresPermission(Manifest.permission.READ_ACTIVE_EMERGENCY_SESSION) public static final int LISTEN_OUTGOING_EMERGENCY_SMS = 0x20000000; + /** + * Listen for Registration Failures. + * + * Listen for indications that a registration procedure has failed in either the CS or PS + * domain. This indication does not necessarily indicate a change of service state, which should + * be tracked via {@link #LISTEN_SERVICE_STATE}. + * + * <p>Requires permission {@link android.Manifest.permission#READ_PHONE_STATE} or the calling + * app has carrier privileges (see {@link TelephonyManager#hasCarrierPrivileges}). + * + * @see #onRegistrationFailed() + */ + @RequiresPermission(Manifest.permission.READ_PHONE_STATE) + public static final int LISTEN_REGISTRATION_FAILURE = 0x40000000; + /* * Subscription used to listen to the phone state changes * @hide @@ -933,6 +947,38 @@ public class PhoneStateListener { } /** + * Report that Registration or a Location/Routing/Tracking Area update has failed. + * + * <p>Indicate whenever a registration procedure, including a location, routing, or tracking + * area update fails. This includes procedures that do not necessarily result in a change of + * the modem's registration status. If the modem's registration status changes, that is + * reflected in the onNetworkStateChanged() and subsequent get{Voice/Data}RegistrationState(). + * + * <p>Because registration failures are ephemeral, this callback is not sticky. + * Registrants will not receive the most recent past value when registering. + * + * @param cellIdentity the CellIdentity, which must include the globally unique identifier + * for the cell (for example, all components of the CGI or ECGI). + * @param chosenPlmn a 5 or 6 digit alphanumeric PLMN (MCC|MNC) among those broadcast by the + * cell that was chosen for the failed registration attempt. + * @param domain DOMAIN_CS, DOMAIN_PS or both in case of a combined procedure. + * @param causeCode the primary failure cause code of the procedure. + * For GSM/UMTS (MM), values are in TS 24.008 Sec 10.5.95 + * For GSM/UMTS (GMM), values are in TS 24.008 Sec 10.5.147 + * For LTE (EMM), cause codes are TS 24.301 Sec 9.9.3.9 + * For NR (5GMM), cause codes are TS 24.501 Sec 9.11.3.2 + * Integer.MAX_VALUE if this value is unused. + * @param additionalCauseCode the cause code of any secondary/combined procedure if appropriate. + * For UMTS, if a combined attach succeeds for PS only, then the GMM cause code shall be + * included as an additionalCauseCode. For LTE (ESM), cause codes are in + * TS 24.301 9.9.4.4. Integer.MAX_VALUE if this value is unused. + */ + public void onRegistrationFailed(@NonNull CellIdentity cellIdentity, @NonNull String chosenPlmn, + @NetworkRegistrationInfo.Domain int domain, int causeCode, int additionalCauseCode) { + // default implementation empty + } + + /** * The callback methods need to be called on the handler thread where * this object was created. If the binder did that for us it'd be nice. * @@ -984,8 +1030,11 @@ public class PhoneStateListener { () -> mExecutor.execute(() -> psl.onCallForwardingIndicatorChanged(cfi))); } - public void onCellLocationChanged(Bundle bundle) { - CellLocation location = CellLocation.newFromBundle(bundle); + public void onCellLocationChanged(CellIdentity cellIdentity) { + // There is no system/public API to create an CellIdentity in system server, + // so the server pass a null to indicate an empty initial location. + CellLocation location = + cellIdentity == null ? CellLocation.getEmpty() : cellIdentity.asCellLocation(); PhoneStateListener psl = mPhoneStateListenerWeakRef.get(); if (psl == null) return; @@ -1201,6 +1250,18 @@ public class PhoneStateListener { () -> psl.onImsCallDisconnectCauseChanged(disconnectCause))); } + + public void onRegistrationFailed(@NonNull CellIdentity cellIdentity, + @NonNull String chosenPlmn, @NetworkRegistrationInfo.Domain int domain, + int causeCode, int additionalCauseCode) { + PhoneStateListener psl = mPhoneStateListenerWeakRef.get(); + if (psl == null) return; + + Binder.withCleanCallingIdentity( + () -> mExecutor.execute(() -> psl.onRegistrationFailed( + cellIdentity, chosenPlmn, domain, causeCode, additionalCauseCode))); + // default implementation empty + } } diff --git a/core/java/android/telephony/Rlog.java b/core/java/android/telephony/Rlog.java index cdab2dc54dd2..2afdd339e80b 100644 --- a/core/java/android/telephony/Rlog.java +++ b/core/java/android/telephony/Rlog.java @@ -16,12 +16,11 @@ package android.telephony; +import android.compat.annotation.UnsupportedAppUsage; import android.os.Build; import android.text.TextUtils; -import android.util.Log; - -import android.annotation.UnsupportedAppUsage; import android.util.Base64; +import android.util.Log; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; diff --git a/core/java/android/telephony/SubscriptionPlan.java b/core/java/android/telephony/SubscriptionPlan.java index ec2050fb1a44..28a5c2086ede 100644 --- a/core/java/android/telephony/SubscriptionPlan.java +++ b/core/java/android/telephony/SubscriptionPlan.java @@ -24,6 +24,7 @@ import android.annotation.Nullable; import android.annotation.SystemApi; import android.os.Parcel; import android.os.Parcelable; +import android.telephony.Annotation.NetworkType; import android.util.Range; import android.util.RecurrenceRule; @@ -33,6 +34,7 @@ import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.time.Period; import java.time.ZonedDateTime; +import java.util.Arrays; import java.util.Iterator; import java.util.Objects; @@ -42,6 +44,14 @@ import java.util.Objects; * as explaining how much mobile data they have remaining, and what will happen * when they run out. * + * If specifying network types, the developer must supply at least one plan + * that applies to all network types (default), and all additional plans + * may not include a particular network type more than once. + * This is enforced by {@link SubscriptionManager} when setting the plans. + * + * Plan selection will prefer plans that have specific network types defined + * over plans that apply to all network types. + * * @see SubscriptionManager#setSubscriptionPlans(int, java.util.List) * @see SubscriptionManager#getSubscriptionPlans(int) */ @@ -80,6 +90,8 @@ public final class SubscriptionPlan implements Parcelable { private int dataLimitBehavior = LIMIT_BEHAVIOR_UNKNOWN; private long dataUsageBytes = BYTES_UNKNOWN; private long dataUsageTime = TIME_UNKNOWN; + private @NetworkType int[] networkTypes; + private long networkTypesBitMask; private SubscriptionPlan(RecurrenceRule cycleRule) { this.cycleRule = Preconditions.checkNotNull(cycleRule); @@ -93,6 +105,7 @@ public final class SubscriptionPlan implements Parcelable { dataLimitBehavior = source.readInt(); dataUsageBytes = source.readLong(); dataUsageTime = source.readLong(); + networkTypes = source.createIntArray(); } @Override @@ -109,6 +122,7 @@ public final class SubscriptionPlan implements Parcelable { dest.writeInt(dataLimitBehavior); dest.writeLong(dataUsageBytes); dest.writeLong(dataUsageTime); + dest.writeIntArray(networkTypes); } @Override @@ -121,13 +135,14 @@ public final class SubscriptionPlan implements Parcelable { .append(" dataLimitBehavior=").append(dataLimitBehavior) .append(" dataUsageBytes=").append(dataUsageBytes) .append(" dataUsageTime=").append(dataUsageTime) + .append(" networkTypes=").append(Arrays.toString(networkTypes)) .append("}").toString(); } @Override public int hashCode() { return Objects.hash(cycleRule, title, summary, dataLimitBytes, dataLimitBehavior, - dataUsageBytes, dataUsageTime); + dataUsageBytes, dataUsageTime, Arrays.hashCode(networkTypes)); } @Override @@ -140,7 +155,8 @@ public final class SubscriptionPlan implements Parcelable { && dataLimitBytes == other.dataLimitBytes && dataLimitBehavior == other.dataLimitBehavior && dataUsageBytes == other.dataUsageBytes - && dataUsageTime == other.dataUsageTime; + && dataUsageTime == other.dataUsageTime + && Arrays.equals(networkTypes, other.networkTypes); } return false; } @@ -204,6 +220,32 @@ public final class SubscriptionPlan implements Parcelable { } /** + * Return an array containing all {@link NetworkType}s this SubscriptionPlan applies to. + * A null value means this SubscriptionPlan applies to all network types. + */ + public @Nullable @NetworkType int[] getNetworkTypes() { + return networkTypes; + } + + /** + * Return the networkTypes array converted to a {@link TelephonyManager.NetworkTypeBitMask} + * @hide + */ + public long getNetworkTypesBitMask() { + // calculate bitmask the first time and save for future calls + if (networkTypesBitMask == 0) { + if (networkTypes == null) { + networkTypesBitMask = ~0; + } else { + for (int networkType : networkTypes) { + networkTypesBitMask |= TelephonyManager.getBitMaskForNetworkType(networkType); + } + } + } + return networkTypesBitMask; + } + + /** * Return an iterator that will return all valid data usage cycles based on * any recurrence rules. The iterator starts from the currently active cycle * and walks backwards through time. @@ -335,5 +377,17 @@ public final class SubscriptionPlan implements Parcelable { plan.dataUsageTime = dataUsageTime; return this; } + + /** + * Set the network types this SubscriptionPlan applies to. + * + * @param networkTypes a set of all {@link NetworkType}s that apply to this plan. + * A null value means the plan applies to all network types, + * and an empty array means the plan applies to no network types. + */ + public @NonNull Builder setNetworkTypes(@Nullable @NetworkType int[] networkTypes) { + plan.networkTypes = networkTypes; + return this; + } } } diff --git a/core/java/android/telephony/TelephonyRegistryManager.java b/core/java/android/telephony/TelephonyRegistryManager.java index c11a99d231d5..a2422948ca86 100644 --- a/core/java/android/telephony/TelephonyRegistryManager.java +++ b/core/java/android/telephony/TelephonyRegistryManager.java @@ -22,7 +22,6 @@ import android.annotation.SystemApi; import android.annotation.TestApi; import android.content.Context; import android.os.Binder; -import android.os.Bundle; import android.os.RemoteException; import android.os.ServiceManager; import android.telephony.Annotation.CallState; @@ -116,7 +115,8 @@ public class TelephonyRegistryManager { }; mSubscriptionChangedListenerMap.put(listener, callback); try { - sRegistry.addOnSubscriptionsChangedListener(mContext.getOpPackageName(), callback); + sRegistry.addOnSubscriptionsChangedListener(mContext.getOpPackageName(), + null, callback); } catch (RemoteException ex) { // system server crash } @@ -175,7 +175,7 @@ public class TelephonyRegistryManager { mOpportunisticSubscriptionChangedListenerMap.put(listener, callback); try { sRegistry.addOnOpportunisticSubscriptionsChangedListener(mContext.getOpPackageName(), - callback); + null, callback); } catch (RemoteException ex) { // system server crash } @@ -621,9 +621,9 @@ public class TelephonyRegistryManager { * Notify call disconnect causes which contains {@link DisconnectCause} and {@link * android.telephony.PreciseDisconnectCause}. * - * @param subId for which call disconnected. * @param slotIndex for which call disconnected. Can be derived from subId except when subId is * invalid. + * @param subId for which call disconnected. * @param cause {@link DisconnectCause} for the disconnected call. * @param preciseCause {@link android.telephony.PreciseDisconnectCause} for the disconnected * call. @@ -639,10 +639,14 @@ public class TelephonyRegistryManager { } /** - * TODO change from bundle to CellLocation? + * Notify {@link android.telephony.CellLocation} changed. + * + * <p>To be compatible with {@link TelephonyRegistry}, use {@link CellIdentity} which is + * parcelable, and convert to CellLocation in client code. + * * @hide */ - public void notifyCellLocation(int subId, Bundle cellLocation) { + public void notifyCellLocation(int subId, CellIdentity cellLocation) { try { sRegistry.notifyCellLocationForSubscriber(subId, cellLocation); } catch (RemoteException ex) { @@ -678,4 +682,36 @@ public class TelephonyRegistryManager { } } + + /** + * Report that Registration or a Location/Routing/Tracking Area update has failed. + * + * @param slotIndex for which call disconnected. Can be derived from subId except when subId is + * invalid. + * @param subId for which cellinfo changed. + * @param cellIdentity the CellIdentity, which must include the globally unique identifier + * for the cell (for example, all components of the CGI or ECGI). + * @param chosenPlmn a 5 or 6 digit alphanumeric PLMN (MCC|MNC) among those broadcast by the + * cell that was chosen for the failed registration attempt. + * @param domain DOMAIN_CS, DOMAIN_PS or both in case of a combined procedure. + * @param causeCode the primary failure cause code of the procedure. + * For GSM/UMTS (MM), values are in TS 24.008 Sec 10.5.95 + * For GSM/UMTS (GMM), values are in TS 24.008 Sec 10.5.147 + * For LTE (EMM), cause codes are TS 24.301 Sec 9.9.3.9 + * For NR (5GMM), cause codes are TS 24.501 Sec 9.11.3.2 + * Integer.MAX_VALUE if this value is unused. + * @param additionalCauseCode the cause code of any secondary/combined procedure if appropriate. + * For UMTS, if a combined attach succeeds for PS only, then the GMM cause code shall be + * included as an additionalCauseCode. For LTE (ESM), cause codes are in + * TS 24.301 9.9.4.4. Integer.MAX_VALUE if this value is unused. + */ + public void notifyRegistrationFailed(int slotIndex, int subId, + @NonNull CellIdentity cellIdentity, @NonNull String chosenPlmn, + @NetworkRegistrationInfo.Domain int domain, int causeCode, int additionalCauseCode) { + try { + sRegistry.notifyRegistrationFailed(slotIndex, subId, cellIdentity, + chosenPlmn, domain, causeCode, additionalCauseCode); + } catch (RemoteException ex) { + } + } } diff --git a/core/java/android/text/AndroidBidi.java b/core/java/android/text/AndroidBidi.java index bb7fb446d40c..f1e2181a8538 100644 --- a/core/java/android/text/AndroidBidi.java +++ b/core/java/android/text/AndroidBidi.java @@ -16,7 +16,7 @@ package android.text; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.icu.lang.UCharacter; import android.icu.lang.UCharacterDirection; import android.icu.lang.UProperty; diff --git a/core/java/android/text/BoringLayout.java b/core/java/android/text/BoringLayout.java index cf6987c6d123..3ee1a9000188 100644 --- a/core/java/android/text/BoringLayout.java +++ b/core/java/android/text/BoringLayout.java @@ -16,7 +16,7 @@ package android.text; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.graphics.Canvas; import android.graphics.Paint; import android.graphics.Path; diff --git a/core/java/android/text/DynamicLayout.java b/core/java/android/text/DynamicLayout.java index 32982f9df15d..c60d446d921d 100644 --- a/core/java/android/text/DynamicLayout.java +++ b/core/java/android/text/DynamicLayout.java @@ -20,7 +20,7 @@ import android.annotation.FloatRange; import android.annotation.IntRange; import android.annotation.NonNull; import android.annotation.Nullable; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.graphics.Paint; import android.graphics.Rect; import android.os.Build; diff --git a/core/java/android/text/FontConfig.java b/core/java/android/text/FontConfig.java index 19c55d5f497d..b5688a48344e 100644 --- a/core/java/android/text/FontConfig.java +++ b/core/java/android/text/FontConfig.java @@ -21,7 +21,7 @@ import static java.lang.annotation.RetentionPolicy.SOURCE; import android.annotation.IntDef; import android.annotation.NonNull; import android.annotation.Nullable; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.graphics.fonts.FontVariationAxis; import android.net.Uri; diff --git a/core/java/android/text/Html.java b/core/java/android/text/Html.java index 18f8db23db74..55af087ca5b8 100644 --- a/core/java/android/text/Html.java +++ b/core/java/android/text/Html.java @@ -16,9 +16,9 @@ package android.text; -import android.annotation.UnsupportedAppUsage; import android.app.ActivityThread; import android.app.Application; +import android.compat.annotation.UnsupportedAppUsage; import android.content.res.Resources; import android.graphics.Color; import android.graphics.Typeface; diff --git a/core/java/android/text/InputFilter.java b/core/java/android/text/InputFilter.java index a9a7b2f2fa7a..96e7bd0fef4c 100644 --- a/core/java/android/text/InputFilter.java +++ b/core/java/android/text/InputFilter.java @@ -17,7 +17,7 @@ package android.text; import android.annotation.NonNull; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import com.android.internal.util.Preconditions; diff --git a/core/java/android/text/Layout.java b/core/java/android/text/Layout.java index 2c2c2953ed51..8a4497a0f0ce 100644 --- a/core/java/android/text/Layout.java +++ b/core/java/android/text/Layout.java @@ -18,7 +18,7 @@ package android.text; import android.annotation.IntDef; import android.annotation.IntRange; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.graphics.Canvas; import android.graphics.Paint; import android.graphics.Path; diff --git a/core/java/android/text/Selection.java b/core/java/android/text/Selection.java index 68199a4f622e..57c1d237d4ed 100644 --- a/core/java/android/text/Selection.java +++ b/core/java/android/text/Selection.java @@ -17,7 +17,7 @@ package android.text; import android.annotation.TestApi; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import java.text.BreakIterator; diff --git a/core/java/android/text/SpanSet.java b/core/java/android/text/SpanSet.java index 362825a005e9..81bdd65974a8 100644 --- a/core/java/android/text/SpanSet.java +++ b/core/java/android/text/SpanSet.java @@ -16,7 +16,8 @@ package android.text; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; + import java.lang.reflect.Array; import java.util.Arrays; diff --git a/core/java/android/text/SpannableStringBuilder.java b/core/java/android/text/SpannableStringBuilder.java index 0d29da00f7c9..ac27e3d10c4f 100644 --- a/core/java/android/text/SpannableStringBuilder.java +++ b/core/java/android/text/SpannableStringBuilder.java @@ -17,7 +17,7 @@ package android.text; import android.annotation.Nullable; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.graphics.BaseCanvas; import android.graphics.Paint; import android.util.Log; diff --git a/core/java/android/text/SpannableStringInternal.java b/core/java/android/text/SpannableStringInternal.java index a9866335f271..b85ef76bd2d5 100644 --- a/core/java/android/text/SpannableStringInternal.java +++ b/core/java/android/text/SpannableStringInternal.java @@ -16,7 +16,7 @@ package android.text; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import com.android.internal.util.ArrayUtils; import com.android.internal.util.GrowingArrayUtils; diff --git a/core/java/android/text/StaticLayout.java b/core/java/android/text/StaticLayout.java index 69cfc03a7ff8..85e2d98e93c0 100644 --- a/core/java/android/text/StaticLayout.java +++ b/core/java/android/text/StaticLayout.java @@ -20,7 +20,7 @@ import android.annotation.FloatRange; import android.annotation.IntRange; import android.annotation.NonNull; import android.annotation.Nullable; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.graphics.Paint; import android.graphics.text.LineBreaker; import android.os.Build; diff --git a/core/java/android/text/TextLine.java b/core/java/android/text/TextLine.java index 1c50d73c4953..3c51fa765263 100644 --- a/core/java/android/text/TextLine.java +++ b/core/java/android/text/TextLine.java @@ -19,7 +19,7 @@ package android.text; import android.annotation.IntRange; import android.annotation.NonNull; import android.annotation.Nullable; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.graphics.Canvas; import android.graphics.Paint; import android.graphics.Paint.FontMetricsInt; diff --git a/core/java/android/text/TextPaint.java b/core/java/android/text/TextPaint.java index d5aad33a85e7..73825b13cb6b 100644 --- a/core/java/android/text/TextPaint.java +++ b/core/java/android/text/TextPaint.java @@ -18,7 +18,7 @@ package android.text; import android.annotation.ColorInt; import android.annotation.Px; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.graphics.Paint; /** diff --git a/core/java/android/text/TextUtils.java b/core/java/android/text/TextUtils.java index 81643e90428f..788d98bbf3eb 100644 --- a/core/java/android/text/TextUtils.java +++ b/core/java/android/text/TextUtils.java @@ -24,7 +24,7 @@ import android.annotation.IntRange; import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.PluralsRes; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; import android.content.res.Resources; import android.icu.lang.UCharacter; diff --git a/core/java/android/text/format/DateFormat.java b/core/java/android/text/format/DateFormat.java index 3c8de94c05f2..0863a813543c 100755 --- a/core/java/android/text/format/DateFormat.java +++ b/core/java/android/text/format/DateFormat.java @@ -17,9 +17,8 @@ package android.text.format; import android.annotation.NonNull; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; -import android.os.UserHandle; import android.provider.Settings; import android.text.SpannableStringBuilder; import android.text.Spanned; diff --git a/core/java/android/text/format/DateUtils.java b/core/java/android/text/format/DateUtils.java index 906251837ade..f236f19e973f 100644 --- a/core/java/android/text/format/DateUtils.java +++ b/core/java/android/text/format/DateUtils.java @@ -16,7 +16,7 @@ package android.text.format; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; import android.content.res.Configuration; import android.content.res.Resources; diff --git a/core/java/android/text/format/Formatter.java b/core/java/android/text/format/Formatter.java index d7baa1086b2f..17d3ae4a7ff0 100644 --- a/core/java/android/text/format/Formatter.java +++ b/core/java/android/text/format/Formatter.java @@ -18,7 +18,7 @@ package android.text.format; import android.annotation.NonNull; import android.annotation.Nullable; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; import android.content.res.Resources; import android.icu.text.MeasureFormat; diff --git a/core/java/android/text/method/AllCapsTransformationMethod.java b/core/java/android/text/method/AllCapsTransformationMethod.java index 5a7c98d7ccdf..305b056aee72 100644 --- a/core/java/android/text/method/AllCapsTransformationMethod.java +++ b/core/java/android/text/method/AllCapsTransformationMethod.java @@ -17,7 +17,7 @@ package android.text.method; import android.annotation.NonNull; import android.annotation.Nullable; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; import android.graphics.Rect; import android.text.Spanned; diff --git a/core/java/android/text/method/HideReturnsTransformationMethod.java b/core/java/android/text/method/HideReturnsTransformationMethod.java index 440a4b187173..40ce8714cf38 100644 --- a/core/java/android/text/method/HideReturnsTransformationMethod.java +++ b/core/java/android/text/method/HideReturnsTransformationMethod.java @@ -16,7 +16,7 @@ package android.text.method; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.os.Build; /** diff --git a/core/java/android/text/method/LinkMovementMethod.java b/core/java/android/text/method/LinkMovementMethod.java index a0c44a8b6bdc..c544c41c38a9 100644 --- a/core/java/android/text/method/LinkMovementMethod.java +++ b/core/java/android/text/method/LinkMovementMethod.java @@ -16,7 +16,7 @@ package android.text.method; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.os.Build; import android.text.Layout; import android.text.NoCopySpan; diff --git a/core/java/android/text/method/MetaKeyKeyListener.java b/core/java/android/text/method/MetaKeyKeyListener.java index ec7ed34bb5ba..d1d7c968411f 100644 --- a/core/java/android/text/method/MetaKeyKeyListener.java +++ b/core/java/android/text/method/MetaKeyKeyListener.java @@ -16,7 +16,7 @@ package android.text.method; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.text.Editable; import android.text.NoCopySpan; import android.text.Spannable; diff --git a/core/java/android/text/method/PasswordTransformationMethod.java b/core/java/android/text/method/PasswordTransformationMethod.java index c96fc5de0845..53553be6e5a8 100644 --- a/core/java/android/text/method/PasswordTransformationMethod.java +++ b/core/java/android/text/method/PasswordTransformationMethod.java @@ -16,7 +16,7 @@ package android.text.method; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.graphics.Rect; import android.os.Build; import android.os.Handler; diff --git a/core/java/android/text/method/TransformationMethod2.java b/core/java/android/text/method/TransformationMethod2.java index 0bf401a84df0..8d5ec246640e 100644 --- a/core/java/android/text/method/TransformationMethod2.java +++ b/core/java/android/text/method/TransformationMethod2.java @@ -15,7 +15,7 @@ */ package android.text.method; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; /** * TransformationMethod2 extends the TransformationMethod interface diff --git a/core/java/android/text/method/WordIterator.java b/core/java/android/text/method/WordIterator.java index 313567acb51f..d766186c13b0 100644 --- a/core/java/android/text/method/WordIterator.java +++ b/core/java/android/text/method/WordIterator.java @@ -17,7 +17,7 @@ package android.text.method; import android.annotation.NonNull; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.icu.lang.UCharacter; import android.icu.lang.UProperty; import android.icu.text.BreakIterator; diff --git a/core/java/android/text/style/BulletSpan.java b/core/java/android/text/style/BulletSpan.java index 9b1dfbfc95e6..ad617889cd56 100644 --- a/core/java/android/text/style/BulletSpan.java +++ b/core/java/android/text/style/BulletSpan.java @@ -21,7 +21,7 @@ import android.annotation.IntRange; import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.Px; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.graphics.Canvas; import android.graphics.Paint; import android.os.Build; diff --git a/core/java/android/text/style/DynamicDrawableSpan.java b/core/java/android/text/style/DynamicDrawableSpan.java index 1a508a1f6c6d..f37e4238a1c6 100644 --- a/core/java/android/text/style/DynamicDrawableSpan.java +++ b/core/java/android/text/style/DynamicDrawableSpan.java @@ -22,7 +22,7 @@ import android.annotation.IntDef; import android.annotation.IntRange; import android.annotation.NonNull; import android.annotation.Nullable; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.graphics.Canvas; import android.graphics.Paint; import android.graphics.Rect; diff --git a/core/java/android/text/style/EasyEditSpan.java b/core/java/android/text/style/EasyEditSpan.java index bfb2873b5112..b23c2b7da6ac 100644 --- a/core/java/android/text/style/EasyEditSpan.java +++ b/core/java/android/text/style/EasyEditSpan.java @@ -17,8 +17,8 @@ package android.text.style; import android.annotation.NonNull; -import android.annotation.UnsupportedAppUsage; import android.app.PendingIntent; +import android.compat.annotation.UnsupportedAppUsage; import android.os.Parcel; import android.text.ParcelableSpan; import android.text.TextUtils; diff --git a/core/java/android/text/style/ImageSpan.java b/core/java/android/text/style/ImageSpan.java index 98f58bef5932..ec55aebfb0ac 100644 --- a/core/java/android/text/style/ImageSpan.java +++ b/core/java/android/text/style/ImageSpan.java @@ -19,7 +19,7 @@ package android.text.style; import android.annotation.DrawableRes; import android.annotation.NonNull; import android.annotation.Nullable; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; import android.graphics.Bitmap; import android.graphics.BitmapFactory; diff --git a/core/java/android/text/style/SpellCheckSpan.java b/core/java/android/text/style/SpellCheckSpan.java index 6ffde38a3b75..e8ec3c6fb55c 100644 --- a/core/java/android/text/style/SpellCheckSpan.java +++ b/core/java/android/text/style/SpellCheckSpan.java @@ -16,7 +16,7 @@ package android.text.style; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.os.Parcel; import android.text.ParcelableSpan; import android.text.TextUtils; diff --git a/core/java/android/text/style/SuggestionRangeSpan.java b/core/java/android/text/style/SuggestionRangeSpan.java index d958ddebaf5a..2b04a7ac2ab8 100644 --- a/core/java/android/text/style/SuggestionRangeSpan.java +++ b/core/java/android/text/style/SuggestionRangeSpan.java @@ -16,7 +16,7 @@ package android.text.style; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.os.Parcel; import android.text.ParcelableSpan; import android.text.TextPaint; diff --git a/core/java/android/text/style/SuggestionSpan.java b/core/java/android/text/style/SuggestionSpan.java index c000ae3f6b2a..be01bfb94f21 100644 --- a/core/java/android/text/style/SuggestionSpan.java +++ b/core/java/android/text/style/SuggestionSpan.java @@ -19,7 +19,7 @@ package android.text.style; import android.annotation.ColorInt; import android.annotation.NonNull; import android.annotation.Nullable; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; import android.content.res.TypedArray; import android.graphics.Color; diff --git a/core/java/android/text/util/Linkify.java b/core/java/android/text/util/Linkify.java index df54209bc043..6931a323f195 100644 --- a/core/java/android/text/util/Linkify.java +++ b/core/java/android/text/util/Linkify.java @@ -19,7 +19,7 @@ package android.text.util; import android.annotation.IntDef; import android.annotation.NonNull; import android.annotation.Nullable; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; import android.telephony.PhoneNumberUtils; import android.telephony.TelephonyManager; diff --git a/core/java/android/timezone/CountryTimeZones.java b/core/java/android/timezone/CountryTimeZones.java new file mode 100644 index 000000000000..ada59d6d7d55 --- /dev/null +++ b/core/java/android/timezone/CountryTimeZones.java @@ -0,0 +1,265 @@ +/* + * 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.timezone; + +import android.annotation.NonNull; +import android.annotation.Nullable; +import android.annotation.SuppressLint; +import android.annotation.SystemApi; +import android.icu.util.TimeZone; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.Objects; + +/** + * Information about a country's time zones. + * + * @hide + */ +@SystemApi(client = SystemApi.Client.MODULE_LIBRARIES) +public final class CountryTimeZones { + + /** + * A mapping to a time zone ID with some associated metadata. + * + * @hide + */ + @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES) + public static final class TimeZoneMapping { + + private libcore.timezone.CountryTimeZones.TimeZoneMapping mDelegate; + + TimeZoneMapping(libcore.timezone.CountryTimeZones.TimeZoneMapping delegate) { + this.mDelegate = Objects.requireNonNull(delegate); + } + + /** + * Returns the ID for this mapping. See also {@link #getTimeZone()} which handles when the + * ID is unrecognized. + */ + @NonNull + public String getTimeZoneId() { + return mDelegate.timeZoneId; + } + + /** + * Returns a {@link TimeZone} object for this mapping, or {@code null} if the ID is + * unrecognized. + */ + @Nullable + public TimeZone getTimeZone() { + return mDelegate.getTimeZone(); + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + TimeZoneMapping that = (TimeZoneMapping) o; + return this.mDelegate.equals(that.mDelegate); + } + + @Override + public int hashCode() { + return this.mDelegate.hashCode(); + } + + @Override + public String toString() { + return mDelegate.toString(); + } + } + + /** + * The result of lookup up a time zone using offset information (and possibly more). + * + * @hide + */ + @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES) + public static final class OffsetResult { + + private final TimeZone mTimeZone; + private final boolean mIsOnlyMatch; + + /** Creates an instance with the supplied information. */ + public OffsetResult(@NonNull TimeZone timeZone, boolean isOnlyMatch) { + mTimeZone = Objects.requireNonNull(timeZone); + mIsOnlyMatch = isOnlyMatch; + } + + /** + * Returns a time zone that matches the supplied criteria. + */ + @NonNull + public TimeZone getTimeZone() { + return mTimeZone; + } + + /** + * Returns {@code true} if there is only one matching time zone for the supplied criteria. + */ + public boolean isOnlyMatch() { + return mIsOnlyMatch; + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + OffsetResult that = (OffsetResult) o; + return mIsOnlyMatch == that.mIsOnlyMatch + && mTimeZone.getID().equals(that.mTimeZone.getID()); + } + + @Override + public int hashCode() { + return Objects.hash(mTimeZone, mIsOnlyMatch); + } + + @Override + public String toString() { + return "OffsetResult{" + + "mTimeZone=" + mTimeZone + + ", mIsOnlyMatch=" + mIsOnlyMatch + + '}'; + } + } + + @NonNull + private final libcore.timezone.CountryTimeZones mDelegate; + + CountryTimeZones(libcore.timezone.CountryTimeZones delegate) { + mDelegate = delegate; + } + + /** + * Returns true if the ISO code for the country is a match for the one specified. + */ + public boolean isForCountryCode(@NonNull String countryIso) { + return mDelegate.isForCountryCode(countryIso); + } + + /** + * Returns the default time zone ID for the country. Can return {@code null} in cases when no + * data is available or the time zone ID was not recognized. + */ + @Nullable + public String getDefaultTimeZoneId() { + return mDelegate.getDefaultTimeZoneId(); + } + + /** + * Returns the default time zone for the country. Can return {@code null} in cases when no data + * is available or the time zone ID was not recognized. + */ + @Nullable + public TimeZone getDefaultTimeZone() { + return mDelegate.getDefaultTimeZone(); + } + + /** + * Qualifier for a country's default time zone. {@code true} indicates whether the default + * would be a good choice <em>generally</em> when there's no other information available. + */ + public boolean isDefaultTimeZoneBoosted() { + return mDelegate.getDefaultTimeZoneBoost(); + } + + /** + * Returns true if the country has at least one zone that is the same as UTC at the given time. + */ + public boolean hasUtcZone(long whenMillis) { + return mDelegate.hasUtcZone(whenMillis); + } + + /** + * Returns a time zone for the country, if there is one, that matches the desired properties. If + * there are multiple matches and the {@code bias} is one of them then it is returned, otherwise + * an arbitrary match is returned based on the {@link #getEffectiveTimeZoneMappingsAt(long)} + * ordering. + * + * @param totalOffsetMillis the offset from UTC at {@code whenMillis} + * @param isDst the Daylight Savings Time state at {@code whenMillis}. {@code true} means DST, + * {@code false} means not DST, {@code null} means unknown + * @param dstOffsetMillis the part of {@code totalOffsetMillis} contributed by DST, only used if + * {@code isDst} is {@code true}. The value can be {@code null} if the DST offset is + * unknown + * @param whenMillis the UTC time to match against + * @param bias the time zone to prefer, can be {@code null} + */ + @Nullable + public OffsetResult lookupByOffsetWithBias(int totalOffsetMillis, @Nullable Boolean isDst, + @SuppressLint("AutoBoxing") @Nullable Integer dstOffsetMillis, long whenMillis, + @Nullable TimeZone bias) { + libcore.timezone.CountryTimeZones.OffsetResult delegateOffsetResult = + mDelegate.lookupByOffsetWithBias( + totalOffsetMillis, isDst, dstOffsetMillis, whenMillis, bias); + return delegateOffsetResult == null ? null : + new OffsetResult(delegateOffsetResult.mTimeZone, delegateOffsetResult.mOneMatch); + } + + /** + * Returns an immutable, ordered list of time zone mappings for the country in an undefined but + * "priority" order, filtered so that only "effective" time zone IDs are returned. An + * "effective" time zone is one that differs from another time zone used in the country after + * {@code whenMillis}. The list can be empty if there were no zones configured or the configured + * zone IDs were not recognized. + */ + @NonNull + public List<TimeZoneMapping> getEffectiveTimeZoneMappingsAt(long whenMillis) { + List<libcore.timezone.CountryTimeZones.TimeZoneMapping> delegateList = + mDelegate.getEffectiveTimeZoneMappingsAt(whenMillis); + + List<TimeZoneMapping> toReturn = new ArrayList<>(delegateList.size()); + for (libcore.timezone.CountryTimeZones.TimeZoneMapping delegateMapping : delegateList) { + toReturn.add(new TimeZoneMapping(delegateMapping)); + } + return Collections.unmodifiableList(toReturn); + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + CountryTimeZones that = (CountryTimeZones) o; + return mDelegate.equals(that.mDelegate); + } + + @Override + public int hashCode() { + return Objects.hash(mDelegate); + } + + @Override + public String toString() { + return mDelegate.toString(); + } +} diff --git a/core/java/android/timezone/TelephonyLookup.java b/core/java/android/timezone/TelephonyLookup.java new file mode 100644 index 000000000000..39dbe85cb485 --- /dev/null +++ b/core/java/android/timezone/TelephonyLookup.java @@ -0,0 +1,71 @@ +/* + * 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.timezone; + +import android.annotation.NonNull; +import android.annotation.Nullable; +import android.annotation.SystemApi; + +import com.android.internal.annotations.GuardedBy; + +import java.util.Objects; + +/** + * A class that can find time zone-related information about telephony networks. + * + * @hide + */ +@SystemApi(client = SystemApi.Client.MODULE_LIBRARIES) +public class TelephonyLookup { + + private static Object sLock = new Object(); + @GuardedBy("sLock") + private static TelephonyLookup sInstance; + + @NonNull + private final libcore.timezone.TelephonyLookup mDelegate; + + /** + * Obtains an instance for use when resolving telephony time zone information. This method never + * returns {@code null}. + */ + @NonNull + public static TelephonyLookup getInstance() { + synchronized (sLock) { + if (sInstance == null) { + sInstance = new TelephonyLookup(libcore.timezone.TelephonyLookup.getInstance()); + } + return sInstance; + } + } + + private TelephonyLookup(@NonNull libcore.timezone.TelephonyLookup delegate) { + mDelegate = Objects.requireNonNull(delegate); + } + + /** + * Returns an object capable of querying telephony network information. This method can return + * {@code null} in the event of an error while reading the underlying data files. + */ + @Nullable + public TelephonyNetworkFinder getTelephonyNetworkFinder() { + libcore.timezone.TelephonyNetworkFinder telephonyNetworkFinderDelegate = + mDelegate.getTelephonyNetworkFinder(); + return telephonyNetworkFinderDelegate != null + ? new TelephonyNetworkFinder(telephonyNetworkFinderDelegate) : null; + } +} diff --git a/core/java/android/timezone/TelephonyNetwork.java b/core/java/android/timezone/TelephonyNetwork.java new file mode 100644 index 000000000000..ae39fbddfa1c --- /dev/null +++ b/core/java/android/timezone/TelephonyNetwork.java @@ -0,0 +1,86 @@ +/* + * 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.timezone; + +import android.annotation.NonNull; +import android.annotation.SystemApi; + +import java.util.Objects; + +/** + * Information about a telephony network. + * + * @hide + */ +@SystemApi(client = SystemApi.Client.MODULE_LIBRARIES) +public class TelephonyNetwork { + + @NonNull + private final libcore.timezone.TelephonyNetwork mDelegate; + + TelephonyNetwork(@NonNull libcore.timezone.TelephonyNetwork delegate) { + mDelegate = Objects.requireNonNull(delegate); + } + + /** + * Returns the Mobile Country Code of the network. + */ + @NonNull + public String getMcc() { + return mDelegate.getMcc(); + } + + /** + * Returns the Mobile Network Code of the network. + */ + @NonNull + public String getMnc() { + return mDelegate.getMnc(); + } + + /** + * Returns the country in which the network operates as an ISO 3166 alpha-2 (lower case). + */ + @NonNull + public String getCountryIsoCode() { + return mDelegate.getCountryIsoCode(); + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + TelephonyNetwork that = (TelephonyNetwork) o; + return mDelegate.equals(that.mDelegate); + } + + @Override + public int hashCode() { + return Objects.hash(mDelegate); + } + + @Override + public String toString() { + return "TelephonyNetwork{" + + "mDelegate=" + mDelegate + + '}'; + } +} diff --git a/core/java/android/timezone/TelephonyNetworkFinder.java b/core/java/android/timezone/TelephonyNetworkFinder.java new file mode 100644 index 000000000000..a81a516c4b33 --- /dev/null +++ b/core/java/android/timezone/TelephonyNetworkFinder.java @@ -0,0 +1,55 @@ +/* + * 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.timezone; + +import android.annotation.NonNull; +import android.annotation.Nullable; +import android.annotation.SystemApi; + +import java.util.Objects; + +/** + * A class that can find telephony networks loaded via {@link TelephonyLookup}. + * + * @hide + */ +@SystemApi(client = SystemApi.Client.MODULE_LIBRARIES) +public class TelephonyNetworkFinder { + + @NonNull + private final libcore.timezone.TelephonyNetworkFinder mDelegate; + + TelephonyNetworkFinder(libcore.timezone.TelephonyNetworkFinder delegate) { + mDelegate = Objects.requireNonNull(delegate); + } + + /** + * Returns information held about a specific MCC + MNC combination. It is expected for this + * method to return {@code null}. Only known, unusual networks will typically have information + * returned, e.g. if they operate in countries other than the one suggested by their MCC. + */ + @Nullable + public TelephonyNetwork findNetworkByMccMnc(@NonNull String mcc, @NonNull String mnc) { + Objects.requireNonNull(mcc); + Objects.requireNonNull(mnc); + + libcore.timezone.TelephonyNetwork telephonyNetworkDelegate = + mDelegate.findNetworkByMccMnc(mcc, mnc); + return telephonyNetworkDelegate != null + ? new TelephonyNetwork(telephonyNetworkDelegate) : null; + } +} diff --git a/core/java/android/timezone/TimeZoneFinder.java b/core/java/android/timezone/TimeZoneFinder.java new file mode 100644 index 000000000000..15dfe62bb789 --- /dev/null +++ b/core/java/android/timezone/TimeZoneFinder.java @@ -0,0 +1,67 @@ +/* + * 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.timezone; + +import android.annotation.NonNull; +import android.annotation.Nullable; +import android.annotation.SystemApi; + +import com.android.internal.annotations.GuardedBy; + +/** + * A class that can be used to find time zones. + * + * @hide + */ +@SystemApi(client = SystemApi.Client.MODULE_LIBRARIES) +public final class TimeZoneFinder { + + private static Object sLock = new Object(); + @GuardedBy("sLock") + private static TimeZoneFinder sInstance; + + private final libcore.timezone.TimeZoneFinder mDelegate; + + private TimeZoneFinder(libcore.timezone.TimeZoneFinder delegate) { + mDelegate = delegate; + } + + /** + * Obtains an instance for use when resolving telephony time zone information. This method never + * returns {@code null}. + */ + @NonNull + public static TimeZoneFinder getInstance() { + synchronized (sLock) { + if (sInstance == null) { + sInstance = new TimeZoneFinder(libcore.timezone.TimeZoneFinder.getInstance()); + } + } + return sInstance; + } + + /** + * Returns a {@link CountryTimeZones} object associated with the specified country code. + * Caching is handled as needed. If the country code is not recognized or there is an error + * during lookup this method can return null. + */ + @Nullable + public CountryTimeZones lookupCountryTimeZones(@NonNull String countryIso) { + libcore.timezone.CountryTimeZones delegate = mDelegate.lookupCountryTimeZones(countryIso); + return delegate == null ? null : new CountryTimeZones(delegate); + } +} diff --git a/core/java/android/transition/ChangeBounds.java b/core/java/android/transition/ChangeBounds.java index de182daaeb53..59a05ac3c493 100644 --- a/core/java/android/transition/ChangeBounds.java +++ b/core/java/android/transition/ChangeBounds.java @@ -22,7 +22,7 @@ import android.animation.AnimatorSet; import android.animation.ObjectAnimator; import android.animation.PropertyValuesHolder; import android.animation.RectEvaluator; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; import android.content.res.TypedArray; import android.graphics.Bitmap; diff --git a/core/java/android/transition/Scene.java b/core/java/android/transition/Scene.java index 8d4db54ab7b1..52a97e31e081 100644 --- a/core/java/android/transition/Scene.java +++ b/core/java/android/transition/Scene.java @@ -18,7 +18,7 @@ package android.transition; import android.annotation.NonNull; import android.annotation.Nullable; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; import android.os.Build; import android.util.SparseArray; diff --git a/core/java/android/transition/Transition.java b/core/java/android/transition/Transition.java index 0feab4d027a9..e5115846013f 100644 --- a/core/java/android/transition/Transition.java +++ b/core/java/android/transition/Transition.java @@ -20,7 +20,7 @@ import android.animation.Animator; import android.animation.AnimatorListenerAdapter; import android.animation.TimeInterpolator; import android.annotation.Nullable; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; import android.content.res.TypedArray; import android.graphics.Path; diff --git a/core/java/android/transition/TransitionManager.java b/core/java/android/transition/TransitionManager.java index 0e5252e21a64..1b0612e87202 100644 --- a/core/java/android/transition/TransitionManager.java +++ b/core/java/android/transition/TransitionManager.java @@ -17,7 +17,7 @@ package android.transition; import android.annotation.TestApi; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; import android.util.ArrayMap; import android.util.Log; diff --git a/core/java/android/util/ArrayMap.java b/core/java/android/util/ArrayMap.java index d899dde9ef59..5643d5ad24b2 100644 --- a/core/java/android/util/ArrayMap.java +++ b/core/java/android/util/ArrayMap.java @@ -16,7 +16,7 @@ package android.util; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import com.android.internal.util.ArrayUtils; diff --git a/core/java/android/util/ArraySet.java b/core/java/android/util/ArraySet.java index d6a35e1b96fc..489d579365ba 100644 --- a/core/java/android/util/ArraySet.java +++ b/core/java/android/util/ArraySet.java @@ -18,7 +18,7 @@ package android.util; import android.annotation.Nullable; import android.annotation.TestApi; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import libcore.util.EmptyArray; diff --git a/core/java/android/util/Base64.java b/core/java/android/util/Base64.java index ecc0c9cc9de3..92abd7c15f5f 100644 --- a/core/java/android/util/Base64.java +++ b/core/java/android/util/Base64.java @@ -16,7 +16,8 @@ package android.util; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; + import java.io.UnsupportedEncodingException; /** diff --git a/core/java/android/util/Base64OutputStream.java b/core/java/android/util/Base64OutputStream.java index 230a3a58d5b5..48fadeb2a5af 100644 --- a/core/java/android/util/Base64OutputStream.java +++ b/core/java/android/util/Base64OutputStream.java @@ -16,7 +16,8 @@ package android.util; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; + import java.io.FilterOutputStream; import java.io.IOException; import java.io.OutputStream; diff --git a/core/java/android/util/DebugUtils.java b/core/java/android/util/DebugUtils.java index 55d114b224f2..1b4905ad06b6 100644 --- a/core/java/android/util/DebugUtils.java +++ b/core/java/android/util/DebugUtils.java @@ -16,7 +16,7 @@ package android.util; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.os.Build; import java.io.PrintWriter; diff --git a/core/java/android/util/DisplayMetrics.java b/core/java/android/util/DisplayMetrics.java index 7c7223c04b59..4c08b596ee1f 100755 --- a/core/java/android/util/DisplayMetrics.java +++ b/core/java/android/util/DisplayMetrics.java @@ -16,7 +16,7 @@ package android.util; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.os.SystemProperties; diff --git a/core/java/android/util/EventLog.java b/core/java/android/util/EventLog.java index 65d825a71d81..c9dc05b5aeb5 100644 --- a/core/java/android/util/EventLog.java +++ b/core/java/android/util/EventLog.java @@ -17,7 +17,7 @@ package android.util; import android.annotation.SystemApi; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import java.io.BufferedReader; import java.io.FileReader; diff --git a/core/java/android/util/IconDrawableFactory.java b/core/java/android/util/IconDrawableFactory.java index d90b65e22171..be10d941bf5e 100644 --- a/core/java/android/util/IconDrawableFactory.java +++ b/core/java/android/util/IconDrawableFactory.java @@ -15,8 +15,8 @@ */ package android.util; -import android.annotation.UnsupportedAppUsage; import android.annotation.UserIdInt; +import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; import android.content.pm.ApplicationInfo; import android.content.pm.PackageItemInfo; diff --git a/core/java/android/util/LocalLog.java b/core/java/android/util/LocalLog.java index 0203430134c4..63fe61ff0926 100644 --- a/core/java/android/util/LocalLog.java +++ b/core/java/android/util/LocalLog.java @@ -16,7 +16,7 @@ package android.util; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.os.SystemClock; import java.io.FileDescriptor; diff --git a/core/java/android/util/Log.java b/core/java/android/util/Log.java index 507790313bc2..3077b7987034 100644 --- a/core/java/android/util/Log.java +++ b/core/java/android/util/Log.java @@ -19,7 +19,7 @@ package android.util; import android.annotation.IntDef; import android.annotation.NonNull; import android.annotation.Nullable; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.os.DeadSystemException; import com.android.internal.os.RuntimeInit; @@ -387,6 +387,25 @@ public final class Log { public static native int println_native(int bufID, int priority, String tag, String msg); /** + * Send a log message to the "radio" log buffer, which can be dumped with + * {@code adb logcat -b radio}. + * + * <p>Only the telephony mainline module should use it. + * + * <p>Note ART will protect {@code MODULE_LIBRARIES} system APIs from regular app code. + * + * @param priority Log priority. + * @param tag Used to identify the source of a log message. It usually identifies + * the class or activity where the log call occurs. + * @param message The message you would like logged. + * @hide + */ + public static int logToRadioBuffer(@Level int priority, @Nullable String tag, + @Nullable String message) { + return println_native(LOG_ID_RADIO, priority, tag, message); + } + + /** * Return the maximum payload the log daemon accepts without truncation. * @return LOGGER_ENTRY_MAX_PAYLOAD. */ diff --git a/core/java/android/util/LogWriter.java b/core/java/android/util/LogWriter.java index b062ace05700..a674ae166d63 100644 --- a/core/java/android/util/LogWriter.java +++ b/core/java/android/util/LogWriter.java @@ -16,7 +16,8 @@ package android.util; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; + import java.io.Writer; /** @hide */ diff --git a/core/java/android/util/LongArray.java b/core/java/android/util/LongArray.java index 6f4aa5211dea..93bcd6b8d4a1 100644 --- a/core/java/android/util/LongArray.java +++ b/core/java/android/util/LongArray.java @@ -17,7 +17,7 @@ package android.util; import android.annotation.Nullable; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import com.android.internal.util.ArrayUtils; import com.android.internal.util.Preconditions; diff --git a/core/java/android/util/LongSparseLongArray.java b/core/java/android/util/LongSparseLongArray.java index 7b7eea09e884..75f41350fa55 100644 --- a/core/java/android/util/LongSparseLongArray.java +++ b/core/java/android/util/LongSparseLongArray.java @@ -16,7 +16,7 @@ package android.util; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import com.android.internal.util.ArrayUtils; import com.android.internal.util.GrowingArrayUtils; diff --git a/core/java/android/util/LruCache.java b/core/java/android/util/LruCache.java index f04e7cbc9e8f..d35c82bfa158 100644 --- a/core/java/android/util/LruCache.java +++ b/core/java/android/util/LruCache.java @@ -16,7 +16,8 @@ package android.util; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; + import java.util.LinkedHashMap; import java.util.Map; diff --git a/core/java/android/util/MathUtils.java b/core/java/android/util/MathUtils.java index 0eeef70a79a6..971e16185815 100644 --- a/core/java/android/util/MathUtils.java +++ b/core/java/android/util/MathUtils.java @@ -16,7 +16,7 @@ package android.util; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.graphics.Rect; /** diff --git a/core/java/android/util/NtpTrustedTime.java b/core/java/android/util/NtpTrustedTime.java index ea294f010791..0892c94d5bec 100644 --- a/core/java/android/util/NtpTrustedTime.java +++ b/core/java/android/util/NtpTrustedTime.java @@ -16,7 +16,9 @@ package android.util; -import android.annotation.UnsupportedAppUsage; +import android.annotation.NonNull; +import android.annotation.Nullable; +import android.compat.annotation.UnsupportedAppUsage; import android.content.ContentResolver; import android.content.Context; import android.content.res.Resources; @@ -28,168 +30,267 @@ import android.os.SystemClock; import android.provider.Settings; import android.text.TextUtils; +import com.android.internal.annotations.GuardedBy; + +import java.util.Objects; +import java.util.function.Supplier; + /** - * {@link TrustedTime} that connects with a remote NTP server as its trusted - * time source. + * A singleton that connects with a remote NTP server as its trusted time source. This class + * is thread-safe. The {@link #forceRefresh()} method is synchronous, i.e. it may occupy the + * current thread while performing an NTP request. All other threads calling {@link #forceRefresh()} + * will block during that request. * * @hide */ public class NtpTrustedTime implements TrustedTime { + + /** + * The result of a successful NTP query. + * + * @hide + */ + public static class TimeResult { + private final long mTimeMillis; + private final long mElapsedRealtimeMillis; + private final long mCertaintyMillis; + + public TimeResult(long timeMillis, long elapsedRealtimeMillis, long certaintyMillis) { + mTimeMillis = timeMillis; + mElapsedRealtimeMillis = elapsedRealtimeMillis; + mCertaintyMillis = certaintyMillis; + } + + public long getTimeMillis() { + return mTimeMillis; + } + + public long getElapsedRealtimeMillis() { + return mElapsedRealtimeMillis; + } + + public long getCertaintyMillis() { + return mCertaintyMillis; + } + + /** Calculates and returns the current time accounting for the age of this result. */ + public long currentTimeMillis() { + return mTimeMillis + getAgeMillis(); + } + + /** Calculates and returns the age of this result. */ + public long getAgeMillis() { + return SystemClock.elapsedRealtime() - mElapsedRealtimeMillis; + } + + @Override + public String toString() { + return "TimeResult{" + + "mTimeMillis=" + mTimeMillis + + ", mElapsedRealtimeMillis=" + mElapsedRealtimeMillis + + ", mCertaintyMillis=" + mCertaintyMillis + + '}'; + } + } + private static final String TAG = "NtpTrustedTime"; private static final boolean LOGD = false; private static NtpTrustedTime sSingleton; - private static Context sContext; - private final String mServer; - private final long mTimeout; + @NonNull + private final Context mContext; + + /** + * A supplier that returns the ConnectivityManager. The Supplier can return null if + * ConnectivityService isn't running yet. + */ + private final Supplier<ConnectivityManager> mConnectivityManagerSupplier = + new Supplier<ConnectivityManager>() { + private ConnectivityManager mConnectivityManager; - private ConnectivityManager mCM; + @Nullable + @Override + public synchronized ConnectivityManager get() { + // We can't do this at initialization time: ConnectivityService might not be running + // yet. + if (mConnectivityManager == null) { + mConnectivityManager = mContext.getSystemService(ConnectivityManager.class); + } + return mConnectivityManager; + } + }; - private boolean mHasCache; - private long mCachedNtpTime; - private long mCachedNtpElapsedRealtime; - private long mCachedNtpCertainty; + // Declared volatile and accessed outside of synchronized blocks to avoid blocking reads during + // forceRefresh(). + private volatile TimeResult mTimeResult; - private NtpTrustedTime(String server, long timeout) { - if (LOGD) Log.d(TAG, "creating NtpTrustedTime using " + server); - mServer = server; - mTimeout = timeout; + private NtpTrustedTime(Context context) { + mContext = Objects.requireNonNull(context); } @UnsupportedAppUsage public static synchronized NtpTrustedTime getInstance(Context context) { if (sSingleton == null) { - final Resources res = context.getResources(); - final ContentResolver resolver = context.getContentResolver(); - - final String defaultServer = res.getString( - com.android.internal.R.string.config_ntpServer); - final long defaultTimeout = res.getInteger( - com.android.internal.R.integer.config_ntpTimeout); - - final String secureServer = Settings.Global.getString( - resolver, Settings.Global.NTP_SERVER); - final long timeout = Settings.Global.getLong( - resolver, Settings.Global.NTP_TIMEOUT, defaultTimeout); - - final String server = secureServer != null ? secureServer : defaultServer; - sSingleton = new NtpTrustedTime(server, timeout); - sContext = context; + Context appContext = context.getApplicationContext(); + sSingleton = new NtpTrustedTime(appContext); } - return sSingleton; } - @Override @UnsupportedAppUsage public boolean forceRefresh() { - // We can't do this at initialization time: ConnectivityService might not be running yet. synchronized (this) { - if (mCM == null) { - mCM = sContext.getSystemService(ConnectivityManager.class); + NtpConnectionInfo connectionInfo = getNtpConnectionInfo(); + if (connectionInfo == null) { + // missing server config, so no trusted time available + if (LOGD) Log.d(TAG, "forceRefresh: invalid server config"); + return false; } - } - final Network network = mCM == null ? null : mCM.getActiveNetwork(); - return forceRefresh(network); - } - - public boolean forceRefresh(Network network) { - if (TextUtils.isEmpty(mServer)) { - // missing server, so no trusted time available - return false; - } - - // We can't do this at initialization time: ConnectivityService might not be running yet. - synchronized (this) { - if (mCM == null) { - mCM = sContext.getSystemService(ConnectivityManager.class); + ConnectivityManager connectivityManager = mConnectivityManagerSupplier.get(); + if (connectivityManager == null) { + if (LOGD) Log.d(TAG, "forceRefresh: no ConnectivityManager"); + return false; + } + final Network network = connectivityManager.getActiveNetwork(); + final NetworkInfo ni = connectivityManager.getNetworkInfo(network); + if (ni == null || !ni.isConnected()) { + if (LOGD) Log.d(TAG, "forceRefresh: no connectivity"); + return false; } - } - - final NetworkInfo ni = mCM == null ? null : mCM.getNetworkInfo(network); - if (ni == null || !ni.isConnected()) { - if (LOGD) Log.d(TAG, "forceRefresh: no connectivity"); - return false; - } - - if (LOGD) Log.d(TAG, "forceRefresh() from cache miss"); - final SntpClient client = new SntpClient(); - if (client.requestTime(mServer, (int) mTimeout, network)) { - mHasCache = true; - mCachedNtpTime = client.getNtpTime(); - mCachedNtpElapsedRealtime = client.getNtpTimeReference(); - mCachedNtpCertainty = client.getRoundTripTime() / 2; - return true; - } else { - return false; + if (LOGD) Log.d(TAG, "forceRefresh() from cache miss"); + final SntpClient client = new SntpClient(); + final String serverName = connectionInfo.getServer(); + final int timeoutMillis = connectionInfo.getTimeoutMillis(); + if (client.requestTime(serverName, timeoutMillis, network)) { + long ntpCertainty = client.getRoundTripTime() / 2; + mTimeResult = new TimeResult( + client.getNtpTime(), client.getNtpTimeReference(), ntpCertainty); + return true; + } else { + return false; + } } } - @Override + /** + * Only kept for UnsupportedAppUsage. + * + * @deprecated Use {@link #getCachedTimeResult()} to obtain a {@link TimeResult} atomically. + */ + @Deprecated @UnsupportedAppUsage public boolean hasCache() { - return mHasCache; + return mTimeResult != null; } + /** + * Only kept for UnsupportedAppUsage. + * + * @deprecated Use {@link #getCachedTimeResult()} to obtain a {@link TimeResult} atomically. + */ + @Deprecated @Override public long getCacheAge() { - if (mHasCache) { - return SystemClock.elapsedRealtime() - mCachedNtpElapsedRealtime; + TimeResult timeResult = mTimeResult; + if (timeResult != null) { + return SystemClock.elapsedRealtime() - timeResult.getElapsedRealtimeMillis(); } else { return Long.MAX_VALUE; } } - @Override - public long getCacheCertainty() { - if (mHasCache) { - return mCachedNtpCertainty; - } else { - return Long.MAX_VALUE; - } - } - - @Override + /** + * Only kept for UnsupportedAppUsage. + * + * @deprecated Use {@link #getCachedTimeResult()} to obtain a {@link TimeResult} atomically. + */ + @Deprecated @UnsupportedAppUsage public long currentTimeMillis() { - if (!mHasCache) { + TimeResult timeResult = mTimeResult; + if (timeResult == null) { throw new IllegalStateException("Missing authoritative time source"); } if (LOGD) Log.d(TAG, "currentTimeMillis() cache hit"); // current time is age after the last ntp cache; callers who - // want fresh values will hit makeAuthoritative() first. - return mCachedNtpTime + getCacheAge(); + // want fresh values will hit forceRefresh() first. + return timeResult.currentTimeMillis(); } + /** + * Only kept for UnsupportedAppUsage. + * + * @deprecated Use {@link #getCachedTimeResult()} to obtain a {@link TimeResult} atomically. + */ + @Deprecated @UnsupportedAppUsage public long getCachedNtpTime() { if (LOGD) Log.d(TAG, "getCachedNtpTime() cache hit"); - return mCachedNtpTime; + TimeResult timeResult = mTimeResult; + return timeResult == null ? 0 : timeResult.getTimeMillis(); } + /** + * Only kept for UnsupportedAppUsage. + * + * @deprecated Use {@link #getCachedTimeResult()} to obtain a {@link TimeResult} atomically. + */ + @Deprecated @UnsupportedAppUsage public long getCachedNtpTimeReference() { - return mCachedNtpElapsedRealtime; + TimeResult timeResult = mTimeResult; + return timeResult == null ? 0 : timeResult.getElapsedRealtimeMillis(); } /** - * Returns the combination of {@link #getCachedNtpTime()} and {@link - * #getCachedNtpTimeReference()} as a {@link TimestampedValue}. This method is useful when - * passing the time to another component that will adjust for elapsed time. - * - * @throws IllegalStateException if there is no cached value + * Returns an object containing the latest NTP information available. Can return {@code null} if + * no information is available. */ - public TimestampedValue<Long> getCachedNtpTimeSignal() { - if (!mHasCache) { - throw new IllegalStateException("Missing authoritative time source"); + @Nullable + public TimeResult getCachedTimeResult() { + return mTimeResult; + } + + private static class NtpConnectionInfo { + + @NonNull private final String mServer; + private final int mTimeoutMillis; + + NtpConnectionInfo(@NonNull String server, int timeoutMillis) { + mServer = Objects.requireNonNull(server); + mTimeoutMillis = timeoutMillis; } - if (LOGD) Log.d(TAG, "getCachedNtpTimeSignal() cache hit"); - return new TimestampedValue<>(mCachedNtpElapsedRealtime, mCachedNtpTime); + @NonNull + public String getServer() { + return mServer; + } + + int getTimeoutMillis() { + return mTimeoutMillis; + } } + @GuardedBy("this") + private NtpConnectionInfo getNtpConnectionInfo() { + final ContentResolver resolver = mContext.getContentResolver(); + + final Resources res = mContext.getResources(); + final String defaultServer = res.getString( + com.android.internal.R.string.config_ntpServer); + final int defaultTimeoutMillis = res.getInteger( + com.android.internal.R.integer.config_ntpTimeout); + + final String secureServer = Settings.Global.getString( + resolver, Settings.Global.NTP_SERVER); + final int timeoutMillis = Settings.Global.getInt( + resolver, Settings.Global.NTP_TIMEOUT, defaultTimeoutMillis); + + final String server = secureServer != null ? secureServer : defaultServer; + return TextUtils.isEmpty(server) ? null : new NtpConnectionInfo(server, timeoutMillis); + } } diff --git a/core/java/android/util/PathParser.java b/core/java/android/util/PathParser.java index 5342d5dfc81d..1e5ec0b1c5c3 100644 --- a/core/java/android/util/PathParser.java +++ b/core/java/android/util/PathParser.java @@ -14,7 +14,7 @@ package android.util; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.graphics.Path; import dalvik.annotation.optimization.FastNative; diff --git a/core/java/android/util/Pools.java b/core/java/android/util/Pools.java index e242fe5cfca3..7ae32441ef60 100644 --- a/core/java/android/util/Pools.java +++ b/core/java/android/util/Pools.java @@ -16,7 +16,7 @@ package android.util; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; /** * Helper class for crating pools of objects. An example use looks like this: diff --git a/core/java/android/util/Rational.java b/core/java/android/util/Rational.java index 39e8b14689da..593000002cf7 100644 --- a/core/java/android/util/Rational.java +++ b/core/java/android/util/Rational.java @@ -15,9 +15,10 @@ */ package android.util; -import static com.android.internal.util.Preconditions.*; +import static com.android.internal.util.Preconditions.checkNotNull; + +import android.compat.annotation.UnsupportedAppUsage; -import android.annotation.UnsupportedAppUsage; import java.io.IOException; import java.io.InvalidObjectException; diff --git a/core/java/android/util/RecurrenceRule.java b/core/java/android/util/RecurrenceRule.java index 9c60228b4f87..a570e5e00b1c 100644 --- a/core/java/android/util/RecurrenceRule.java +++ b/core/java/android/util/RecurrenceRule.java @@ -16,7 +16,7 @@ package android.util; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.os.Parcel; import android.os.Parcelable; diff --git a/core/java/android/util/Singleton.java b/core/java/android/util/Singleton.java index 15c6b5b5d7f8..92646b47cef2 100644 --- a/core/java/android/util/Singleton.java +++ b/core/java/android/util/Singleton.java @@ -16,7 +16,7 @@ package android.util; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; /** * Singleton helper class for lazily initialization. diff --git a/core/java/android/util/Slog.java b/core/java/android/util/Slog.java index a85120f67f8d..2c8bbbfcf8de 100644 --- a/core/java/android/util/Slog.java +++ b/core/java/android/util/Slog.java @@ -16,7 +16,7 @@ package android.util; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.os.Build; /** diff --git a/core/java/android/util/SparseArray.java b/core/java/android/util/SparseArray.java index 0a15db227823..3a0d1f5a6cc8 100644 --- a/core/java/android/util/SparseArray.java +++ b/core/java/android/util/SparseArray.java @@ -16,7 +16,7 @@ package android.util; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import com.android.internal.util.ArrayUtils; import com.android.internal.util.GrowingArrayUtils; diff --git a/core/java/android/util/SparseBooleanArray.java b/core/java/android/util/SparseBooleanArray.java index d6e0e53a210d..846df397aa6d 100644 --- a/core/java/android/util/SparseBooleanArray.java +++ b/core/java/android/util/SparseBooleanArray.java @@ -16,7 +16,7 @@ package android.util; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import com.android.internal.util.ArrayUtils; import com.android.internal.util.GrowingArrayUtils; diff --git a/core/java/android/util/SparseIntArray.java b/core/java/android/util/SparseIntArray.java index 1ca1717828fa..d4f6685e4347 100644 --- a/core/java/android/util/SparseIntArray.java +++ b/core/java/android/util/SparseIntArray.java @@ -16,7 +16,7 @@ package android.util; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import com.android.internal.util.ArrayUtils; import com.android.internal.util.GrowingArrayUtils; diff --git a/core/java/android/util/StatsEvent.java b/core/java/android/util/StatsEvent.java new file mode 100644 index 000000000000..c7659457bdf9 --- /dev/null +++ b/core/java/android/util/StatsEvent.java @@ -0,0 +1,829 @@ +/* + * 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.os.SystemClock; + +import com.android.internal.annotations.GuardedBy; +import com.android.internal.annotations.VisibleForTesting; + +/** + * 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 + **/ +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; + + // 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_PAYLOAD_SIZE = LOGGER_ENTRY_MAX_PAYLOAD - 4; + + 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. + **/ + 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); + + // Set mPos to after atom id's location in the buffer. + // First 2 elements in the buffer are event timestamp followed by the atom id. + mPos = POS_ATOM_ID + Byte.BYTES + Integer.BYTES; + mPosLastField = 0; + mLastType = 0; + } + + /** + * Sets the atom id for this StatsEvent. + **/ + @NonNull + public Builder setAtomId(final int atomId) { + mAtomId = atomId; + return this; + } + + /** + * Sets the timestamp in nanos for this StatsEvent. + **/ + @VisibleForTesting + @NonNull + public Builder setTimestampNs(final long timestampNs) { + mTimestampNs = timestampNs; + 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( + @NonNull final SparseIntArray intMap, + @NonNull final SparseLongArray longMap, + @NonNull final SparseArray<String> stringMap, + @NonNull final SparseArray<Float> floatMap) { + final int intMapSize = intMap.size(); + final int longMapSize = longMap.size(); + final int stringMapSize = stringMap.size(); + final int floatMapSize = 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 (0 == mPosLastField) { + 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 (0 == mPosLastField) { + 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; + 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; + } + + int size = mPos; + mPos = POS_TIMESTAMP_NS; + writeLong(mTimestampNs); + writeInt(mAtomId); + if (0 == mErrorMask) { + mBuffer.putByte(POS_NUM_ELEMENTS, (byte) mNumElements); + } else { + mPos += mBuffer.putByte(mPos, TYPE_ERRORS); + mPos += mBuffer.putInt(mPos, mErrorMask); + mBuffer.putByte(POS_NUM_ELEMENTS, (byte) 3); + 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 final byte[] mBytes = new byte[MAX_PAYLOAD_SIZE]; + private boolean mOverflow = false; + + @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() { + synchronized (sLock) { + if (null == sPool) { + sPool = this; + } + } + } + + private void reset() { + mOverflow = false; + } + + 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 boolean result = index + numBytes < MAX_PAYLOAD_SIZE; + if (!result) { + mOverflow = true; + } + return result; + } + + /** + * 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/core/java/android/util/StatsLog.java b/core/java/android/util/StatsLog.java index ae9966b7b934..23fd4f2f61d3 100644 --- a/core/java/android/util/StatsLog.java +++ b/core/java/android/util/StatsLog.java @@ -244,6 +244,19 @@ public final class StatsLog extends StatsLogInternal { */ 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 + */ + 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."); } diff --git a/core/java/android/util/TimeUtils.java b/core/java/android/util/TimeUtils.java index 74cff205dabc..8439f5aad0b1 100644 --- a/core/java/android/util/TimeUtils.java +++ b/core/java/android/util/TimeUtils.java @@ -19,7 +19,7 @@ package android.util; import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.TestApi; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.os.Build; import android.os.SystemClock; diff --git a/core/java/android/util/TrustedTime.java b/core/java/android/util/TrustedTime.java index c78665d06e75..f41fe85fa8bb 100644 --- a/core/java/android/util/TrustedTime.java +++ b/core/java/android/util/TrustedTime.java @@ -16,46 +16,52 @@ package android.util; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; /** * Interface that provides trusted time information, possibly coming from an NTP - * server. Implementations may cache answers until {@link #forceRefresh()}. + * server. * * @hide + * @deprecated Only kept for UnsupportedAppUsage. Do not use. See {@link NtpTrustedTime} */ public interface TrustedTime { /** * Force update with an external trusted time source, returning {@code true} * when successful. + * + * @deprecated Only kept for UnsupportedAppUsage. Do not use. See {@link NtpTrustedTime} */ + @Deprecated @UnsupportedAppUsage public boolean forceRefresh(); /** * Check if this instance has cached a response from a trusted time source. + * + * @deprecated Only kept for UnsupportedAppUsage. Do not use. See {@link NtpTrustedTime} */ + @Deprecated @UnsupportedAppUsage - public boolean hasCache(); + boolean hasCache(); /** * Return time since last trusted time source contact, or * {@link Long#MAX_VALUE} if never contacted. + * + * @deprecated Only kept for UnsupportedAppUsage. Do not use. See {@link NtpTrustedTime} */ + @Deprecated @UnsupportedAppUsage public long getCacheAge(); /** - * Return certainty of cached trusted time in milliseconds, or - * {@link Long#MAX_VALUE} if never contacted. Smaller values are more - * precise. - */ - public long getCacheCertainty(); - - /** * Return current time similar to {@link System#currentTimeMillis()}, * possibly using a cached authoritative time source. + * + * @deprecated Only kept for UnsupportedAppUsage. Do not use. See {@link NtpTrustedTime} */ + @Deprecated @UnsupportedAppUsage - public long currentTimeMillis(); + long currentTimeMillis(); } diff --git a/core/java/android/util/XmlPullAttributes.java b/core/java/android/util/XmlPullAttributes.java index 32fe16fcb2b1..d83b355d81a6 100644 --- a/core/java/android/util/XmlPullAttributes.java +++ b/core/java/android/util/XmlPullAttributes.java @@ -16,13 +16,12 @@ package android.util; -import org.xmlpull.v1.XmlPullParser; - -import android.annotation.UnsupportedAppUsage; -import android.util.AttributeSet; +import android.compat.annotation.UnsupportedAppUsage; import com.android.internal.util.XmlUtils; +import org.xmlpull.v1.XmlPullParser; + /** * Provides an implementation of AttributeSet on top of an XmlPullParser. */ diff --git a/core/java/android/view/AccessibilityIterators.java b/core/java/android/view/AccessibilityIterators.java index 5f9bf39fb3dd..bee04f4d8036 100644 --- a/core/java/android/view/AccessibilityIterators.java +++ b/core/java/android/view/AccessibilityIterators.java @@ -16,7 +16,7 @@ package android.view; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.res.Configuration; import java.text.BreakIterator; diff --git a/core/java/android/view/ActionMode.java b/core/java/android/view/ActionMode.java index 6b200e1af39a..d9f9d039f507 100644 --- a/core/java/android/view/ActionMode.java +++ b/core/java/android/view/ActionMode.java @@ -19,10 +19,9 @@ package android.view; import android.annotation.StringRes; import android.annotation.TestApi; +import android.compat.annotation.UnsupportedAppUsage; import android.graphics.Rect; -import dalvik.annotation.compat.UnsupportedAppUsage; - /** * Represents a contextual mode of the user interface. Action modes can be used to provide * alternative interaction modes and replace parts of the normal UI until finished. diff --git a/core/java/android/view/ActionProvider.java b/core/java/android/view/ActionProvider.java index cd7e67e61b61..e1be0fe8d6d2 100644 --- a/core/java/android/view/ActionProvider.java +++ b/core/java/android/view/ActionProvider.java @@ -16,7 +16,7 @@ package android.view; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; import android.util.Log; diff --git a/core/java/android/view/AppTransitionAnimationSpec.java b/core/java/android/view/AppTransitionAnimationSpec.java index 4c0ed52946bd..330061f068f8 100644 --- a/core/java/android/view/AppTransitionAnimationSpec.java +++ b/core/java/android/view/AppTransitionAnimationSpec.java @@ -1,6 +1,6 @@ package android.view; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.graphics.GraphicBuffer; import android.graphics.Rect; import android.os.Parcel; diff --git a/core/java/android/view/BatchedInputEventReceiver.java b/core/java/android/view/BatchedInputEventReceiver.java index 61ccac991eea..95b2c7019dbc 100644 --- a/core/java/android/view/BatchedInputEventReceiver.java +++ b/core/java/android/view/BatchedInputEventReceiver.java @@ -16,7 +16,7 @@ package android.view; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.os.Looper; /** diff --git a/core/java/android/view/Choreographer.java b/core/java/android/view/Choreographer.java index 28eb79ae1f2a..5b4ff52376b3 100644 --- a/core/java/android/view/Choreographer.java +++ b/core/java/android/view/Choreographer.java @@ -16,12 +16,11 @@ package android.view; -import static android.view.DisplayEventReceiver.CONFIG_CHANGED_EVENT_SUPPRESS; import static android.view.DisplayEventReceiver.VSYNC_SOURCE_APP; import static android.view.DisplayEventReceiver.VSYNC_SOURCE_SURFACE_FLINGER; import android.annotation.TestApi; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.graphics.FrameInfo; import android.hardware.display.DisplayManagerGlobal; import android.os.Build; diff --git a/core/java/android/view/ContextThemeWrapper.java b/core/java/android/view/ContextThemeWrapper.java index 696e048ffed8..876331b5c57f 100644 --- a/core/java/android/view/ContextThemeWrapper.java +++ b/core/java/android/view/ContextThemeWrapper.java @@ -18,7 +18,7 @@ package android.view; import android.annotation.Nullable; import android.annotation.StyleRes; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; import android.content.ContextWrapper; import android.content.res.AssetManager; diff --git a/core/java/android/view/Display.java b/core/java/android/view/Display.java index b3d98b8de0a3..7a818ce78568 100644 --- a/core/java/android/view/Display.java +++ b/core/java/android/view/Display.java @@ -22,8 +22,8 @@ import android.annotation.IntDef; import android.annotation.Nullable; import android.annotation.RequiresPermission; import android.annotation.TestApi; -import android.annotation.UnsupportedAppUsage; import android.app.KeyguardManager; +import android.compat.annotation.UnsupportedAppUsage; import android.content.res.CompatibilityInfo; import android.content.res.Configuration; import android.content.res.Resources; diff --git a/core/java/android/view/DisplayAdjustments.java b/core/java/android/view/DisplayAdjustments.java index da4d92fa0c94..834dd7b6e7d8 100644 --- a/core/java/android/view/DisplayAdjustments.java +++ b/core/java/android/view/DisplayAdjustments.java @@ -16,7 +16,7 @@ package android.view; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.res.CompatibilityInfo; import android.content.res.Configuration; diff --git a/core/java/android/view/DisplayEventReceiver.java b/core/java/android/view/DisplayEventReceiver.java index 91acc4638c26..eaf297cc05d8 100644 --- a/core/java/android/view/DisplayEventReceiver.java +++ b/core/java/android/view/DisplayEventReceiver.java @@ -16,7 +16,7 @@ package android.view; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.os.Looper; import android.os.MessageQueue; import android.util.Log; diff --git a/core/java/android/view/DisplayInfo.java b/core/java/android/view/DisplayInfo.java index 2efebf6457ab..f3b2800eef39 100644 --- a/core/java/android/view/DisplayInfo.java +++ b/core/java/android/view/DisplayInfo.java @@ -23,7 +23,7 @@ import static android.view.DisplayInfoProto.LOGICAL_WIDTH; import static android.view.DisplayInfoProto.NAME; import android.annotation.Nullable; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.res.CompatibilityInfo; import android.content.res.Configuration; import android.graphics.Rect; diff --git a/core/java/android/view/DisplayListCanvas.java b/core/java/android/view/DisplayListCanvas.java index 8e6e99a6d949..6035cbebb032 100644 --- a/core/java/android/view/DisplayListCanvas.java +++ b/core/java/android/view/DisplayListCanvas.java @@ -16,7 +16,7 @@ package android.view; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.graphics.BaseRecordingCanvas; import android.graphics.CanvasProperty; import android.graphics.Paint; diff --git a/core/java/android/view/DragEvent.java b/core/java/android/view/DragEvent.java index 2a43bcc00daf..35af0f252d2d 100644 --- a/core/java/android/view/DragEvent.java +++ b/core/java/android/view/DragEvent.java @@ -16,7 +16,7 @@ package android.view; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.ClipData; import android.content.ClipDescription; import android.os.Parcel; diff --git a/core/java/android/view/FrameMetrics.java b/core/java/android/view/FrameMetrics.java index dcdef3eaa275..de4112cbf1e1 100644 --- a/core/java/android/view/FrameMetrics.java +++ b/core/java/android/view/FrameMetrics.java @@ -17,7 +17,7 @@ package android.view; import android.annotation.IntDef; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; diff --git a/core/java/android/view/FrameMetricsObserver.java b/core/java/android/view/FrameMetricsObserver.java index 0f38e847f4bd..e4197abf8088 100644 --- a/core/java/android/view/FrameMetricsObserver.java +++ b/core/java/android/view/FrameMetricsObserver.java @@ -17,7 +17,7 @@ package android.view; import android.annotation.NonNull; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.os.Looper; import android.os.MessageQueue; diff --git a/core/java/android/view/GestureDetector.java b/core/java/android/view/GestureDetector.java index 8fbbcf4b88c6..0fdbc9cf9e33 100644 --- a/core/java/android/view/GestureDetector.java +++ b/core/java/android/view/GestureDetector.java @@ -23,7 +23,7 @@ import static android.util.StatsLog.TOUCH_GESTURE_CLASSIFIED__CLASSIFICATION__SC import static android.util.StatsLog.TOUCH_GESTURE_CLASSIFIED__CLASSIFICATION__SINGLE_TAP; import static android.util.StatsLog.TOUCH_GESTURE_CLASSIFIED__CLASSIFICATION__UNKNOWN_CLASSIFICATION; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; import android.os.Build; import android.os.Handler; diff --git a/core/java/android/view/GhostView.java b/core/java/android/view/GhostView.java index 3286bd623694..a72832760f96 100644 --- a/core/java/android/view/GhostView.java +++ b/core/java/android/view/GhostView.java @@ -15,7 +15,7 @@ */ package android.view; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.graphics.Canvas; import android.graphics.Matrix; import android.graphics.RecordingCanvas; diff --git a/core/java/android/view/InputChannel.java b/core/java/android/view/InputChannel.java index ecb727c79016..67c8b15b2ca5 100644 --- a/core/java/android/view/InputChannel.java +++ b/core/java/android/view/InputChannel.java @@ -16,7 +16,7 @@ package android.view; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.os.IBinder; import android.os.Parcel; import android.os.Parcelable; diff --git a/core/java/android/view/InputDevice.java b/core/java/android/view/InputDevice.java index e723f91887c1..360deddf544d 100644 --- a/core/java/android/view/InputDevice.java +++ b/core/java/android/view/InputDevice.java @@ -18,7 +18,7 @@ package android.view; import android.annotation.RequiresPermission; import android.annotation.TestApi; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; import android.hardware.input.InputDeviceIdentifier; import android.hardware.input.InputManager; diff --git a/core/java/android/view/InputEvent.java b/core/java/android/view/InputEvent.java index 4b88a6a54efe..5f9c4801ee66 100644 --- a/core/java/android/view/InputEvent.java +++ b/core/java/android/view/InputEvent.java @@ -16,7 +16,7 @@ package android.view; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.os.Parcel; import android.os.Parcelable; diff --git a/core/java/android/view/InputEventConsistencyVerifier.java b/core/java/android/view/InputEventConsistencyVerifier.java index e4b1a8d855ec..c0a3cec4547a 100644 --- a/core/java/android/view/InputEventConsistencyVerifier.java +++ b/core/java/android/view/InputEventConsistencyVerifier.java @@ -16,7 +16,7 @@ package android.view; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.os.Build; import android.util.Log; diff --git a/core/java/android/view/InputEventReceiver.java b/core/java/android/view/InputEventReceiver.java index 7260a658a027..cab8bc549af6 100644 --- a/core/java/android/view/InputEventReceiver.java +++ b/core/java/android/view/InputEventReceiver.java @@ -16,7 +16,7 @@ package android.view; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.os.Looper; import android.os.MessageQueue; import android.util.Log; diff --git a/core/java/android/view/InputEventSender.java b/core/java/android/view/InputEventSender.java index c5f4c23b7b15..86a309e3ed79 100644 --- a/core/java/android/view/InputEventSender.java +++ b/core/java/android/view/InputEventSender.java @@ -16,7 +16,7 @@ package android.view; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.os.Looper; import android.os.MessageQueue; import android.util.Log; diff --git a/core/java/android/view/InputFilter.java b/core/java/android/view/InputFilter.java index 3aaf31ef406f..36d558630da9 100644 --- a/core/java/android/view/InputFilter.java +++ b/core/java/android/view/InputFilter.java @@ -16,7 +16,7 @@ package android.view; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.os.Handler; import android.os.Looper; import android.os.Message; diff --git a/core/java/android/view/InputQueue.java b/core/java/android/view/InputQueue.java index 69ebc46cb456..74ce6ac02db3 100644 --- a/core/java/android/view/InputQueue.java +++ b/core/java/android/view/InputQueue.java @@ -16,7 +16,7 @@ package android.view; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.os.Looper; import android.os.MessageQueue; import android.util.LongSparseArray; diff --git a/core/java/android/view/KeyCharacterMap.java b/core/java/android/view/KeyCharacterMap.java index bd033480ea87..90e0f3f89a0f 100644 --- a/core/java/android/view/KeyCharacterMap.java +++ b/core/java/android/view/KeyCharacterMap.java @@ -16,7 +16,7 @@ package android.view; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.hardware.input.InputManager; import android.os.Parcel; import android.os.Parcelable; diff --git a/core/java/android/view/KeyEvent.java b/core/java/android/view/KeyEvent.java index 60db6a57d187..c638717b13c0 100644 --- a/core/java/android/view/KeyEvent.java +++ b/core/java/android/view/KeyEvent.java @@ -20,7 +20,7 @@ import static android.view.Display.INVALID_DISPLAY; import android.annotation.NonNull; import android.annotation.TestApi; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.os.Build; import android.os.Parcel; import android.os.Parcelable; diff --git a/core/java/android/view/LayoutInflater.java b/core/java/android/view/LayoutInflater.java index 1fc7f0e36095..bf646c7cddb6 100644 --- a/core/java/android/view/LayoutInflater.java +++ b/core/java/android/view/LayoutInflater.java @@ -21,7 +21,7 @@ import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.SystemService; import android.annotation.TestApi; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; import android.content.pm.ApplicationInfo; import android.content.res.Resources; @@ -31,10 +31,7 @@ import android.graphics.Canvas; import android.os.Build; import android.os.Handler; import android.os.Message; -import android.os.SystemProperties; import android.os.Trace; -import android.provider.DeviceConfig; -import android.text.TextUtils; import android.util.AttributeSet; import android.util.Log; import android.util.TypedValue; diff --git a/core/java/android/view/MotionEvent.java b/core/java/android/view/MotionEvent.java index 833e78ff5c71..70873d7db92a 100644 --- a/core/java/android/view/MotionEvent.java +++ b/core/java/android/view/MotionEvent.java @@ -22,7 +22,7 @@ import static java.lang.annotation.RetentionPolicy.SOURCE; import android.annotation.IntDef; import android.annotation.TestApi; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.graphics.Matrix; import android.os.Build; import android.os.Parcel; diff --git a/core/java/android/view/NotificationHeaderView.java b/core/java/android/view/NotificationHeaderView.java index b2f3f5edcd20..232e0f6f9a14 100644 --- a/core/java/android/view/NotificationHeaderView.java +++ b/core/java/android/view/NotificationHeaderView.java @@ -17,9 +17,9 @@ package android.view; import android.annotation.Nullable; -import android.annotation.UnsupportedAppUsage; import android.app.AppOpsManager; import android.app.Notification; +import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; import android.content.res.Resources; import android.content.res.TypedArray; diff --git a/core/java/android/view/PointerIcon.java b/core/java/android/view/PointerIcon.java index dfe34c80bb8f..18d0d7b98a42 100644 --- a/core/java/android/view/PointerIcon.java +++ b/core/java/android/view/PointerIcon.java @@ -17,8 +17,8 @@ package android.view; import android.annotation.NonNull; -import android.annotation.UnsupportedAppUsage; import android.annotation.XmlRes; +import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; import android.content.res.Resources; import android.content.res.TypedArray; diff --git a/core/java/android/view/RemoteAnimationAdapter.java b/core/java/android/view/RemoteAnimationAdapter.java index c686440171a2..166d3baa2fdf 100644 --- a/core/java/android/view/RemoteAnimationAdapter.java +++ b/core/java/android/view/RemoteAnimationAdapter.java @@ -16,8 +16,8 @@ package android.view; -import android.annotation.UnsupportedAppUsage; import android.app.ActivityOptions; +import android.compat.annotation.UnsupportedAppUsage; import android.os.Parcel; import android.os.Parcelable; diff --git a/core/java/android/view/RemoteAnimationDefinition.java b/core/java/android/view/RemoteAnimationDefinition.java index da599efb6eee..c9bd92ae84ba 100644 --- a/core/java/android/view/RemoteAnimationDefinition.java +++ b/core/java/android/view/RemoteAnimationDefinition.java @@ -19,9 +19,9 @@ package android.view; import static android.app.WindowConfiguration.ACTIVITY_TYPE_UNDEFINED; import android.annotation.Nullable; -import android.annotation.UnsupportedAppUsage; import android.app.WindowConfiguration; import android.app.WindowConfiguration.ActivityType; +import android.compat.annotation.UnsupportedAppUsage; import android.os.Parcel; import android.os.Parcelable; import android.util.ArraySet; diff --git a/core/java/android/view/RemoteAnimationTarget.java b/core/java/android/view/RemoteAnimationTarget.java index ae3e1d0a9691..2249966a6b2d 100644 --- a/core/java/android/view/RemoteAnimationTarget.java +++ b/core/java/android/view/RemoteAnimationTarget.java @@ -30,8 +30,8 @@ import static android.view.RemoteAnimationTargetProto.TASK_ID; import static android.view.RemoteAnimationTargetProto.WINDOW_CONFIGURATION; import android.annotation.IntDef; -import android.annotation.UnsupportedAppUsage; import android.app.WindowConfiguration; +import android.compat.annotation.UnsupportedAppUsage; import android.graphics.Point; import android.graphics.Rect; import android.os.Parcel; diff --git a/core/java/android/view/RenderNodeAnimator.java b/core/java/android/view/RenderNodeAnimator.java index 93f52a04d626..06cb51927ba8 100644 --- a/core/java/android/view/RenderNodeAnimator.java +++ b/core/java/android/view/RenderNodeAnimator.java @@ -19,7 +19,7 @@ package android.view; import android.animation.Animator; import android.animation.TimeInterpolator; import android.animation.ValueAnimator; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.graphics.CanvasProperty; import android.graphics.Paint; import android.graphics.RecordingCanvas; diff --git a/core/java/android/view/ScaleGestureDetector.java b/core/java/android/view/ScaleGestureDetector.java index 1d721516a979..346f76cace7d 100644 --- a/core/java/android/view/ScaleGestureDetector.java +++ b/core/java/android/view/ScaleGestureDetector.java @@ -16,7 +16,7 @@ package android.view; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; import android.os.Build; import android.os.Handler; diff --git a/core/java/android/view/Surface.java b/core/java/android/view/Surface.java index 17f07b5a2ad4..3a6c8dd3720f 100644 --- a/core/java/android/view/Surface.java +++ b/core/java/android/view/Surface.java @@ -18,7 +18,7 @@ package android.view; import android.annotation.IntDef; import android.annotation.NonNull; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.res.CompatibilityInfo.Translator; import android.graphics.Canvas; import android.graphics.ColorSpace; diff --git a/core/java/android/view/SurfaceControl.java b/core/java/android/view/SurfaceControl.java index 2313b13befad..2c48af04aa18 100644 --- a/core/java/android/view/SurfaceControl.java +++ b/core/java/android/view/SurfaceControl.java @@ -32,7 +32,7 @@ import android.annotation.IntRange; import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.Size; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.graphics.Bitmap; import android.graphics.ColorSpace; import android.graphics.GraphicBuffer; diff --git a/core/java/android/view/SurfaceSession.java b/core/java/android/view/SurfaceSession.java index 361ac932758e..0f851c1881f5 100644 --- a/core/java/android/view/SurfaceSession.java +++ b/core/java/android/view/SurfaceSession.java @@ -16,7 +16,7 @@ package android.view; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; /** * An instance of this class represents a connection to the surface diff --git a/core/java/android/view/SurfaceView.java b/core/java/android/view/SurfaceView.java index d11548d687b1..ec2ab6a5a4be 100644 --- a/core/java/android/view/SurfaceView.java +++ b/core/java/android/view/SurfaceView.java @@ -20,7 +20,7 @@ import static android.view.WindowManagerPolicyConstants.APPLICATION_MEDIA_OVERLA import static android.view.WindowManagerPolicyConstants.APPLICATION_MEDIA_SUBLAYER; import static android.view.WindowManagerPolicyConstants.APPLICATION_PANEL_SUBLAYER; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; import android.content.res.CompatibilityInfo.Translator; import android.graphics.BlendMode; diff --git a/core/java/android/view/TextureView.java b/core/java/android/view/TextureView.java index 0175ba201dd1..2062bb0bc87f 100644 --- a/core/java/android/view/TextureView.java +++ b/core/java/android/view/TextureView.java @@ -17,7 +17,7 @@ package android.view; import android.annotation.Nullable; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; import android.graphics.Bitmap; import android.graphics.Canvas; diff --git a/core/java/android/view/TouchDelegate.java b/core/java/android/view/TouchDelegate.java index 2ea95e90a8bf..de0f9e5c5cf6 100644 --- a/core/java/android/view/TouchDelegate.java +++ b/core/java/android/view/TouchDelegate.java @@ -17,7 +17,7 @@ package android.view; import android.annotation.NonNull; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.graphics.Rect; import android.graphics.Region; import android.util.ArrayMap; diff --git a/core/java/android/view/VelocityTracker.java b/core/java/android/view/VelocityTracker.java index 7154f2bdee42..a56633e3c5fa 100644 --- a/core/java/android/view/VelocityTracker.java +++ b/core/java/android/view/VelocityTracker.java @@ -16,7 +16,7 @@ package android.view; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.util.Pools.SynchronizedPool; /** diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java index 9d2040c5bdb4..3313537965c4 100644 --- a/core/java/android/view/View.java +++ b/core/java/android/view/View.java @@ -43,7 +43,7 @@ import android.annotation.Size; import android.annotation.StyleRes; import android.annotation.TestApi; import android.annotation.UiThread; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.AutofillOptions; import android.content.ClipData; import android.content.Context; diff --git a/core/java/android/view/ViewConfiguration.java b/core/java/android/view/ViewConfiguration.java index 9e914d4e7d41..774a2dea6311 100644 --- a/core/java/android/view/ViewConfiguration.java +++ b/core/java/android/view/ViewConfiguration.java @@ -18,8 +18,8 @@ package android.view; import android.annotation.FloatRange; import android.annotation.TestApi; -import android.annotation.UnsupportedAppUsage; import android.app.AppGlobals; +import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; import android.content.res.Configuration; import android.content.res.Resources; diff --git a/core/java/android/view/ViewDebug.java b/core/java/android/view/ViewDebug.java index 8a1fd62c0201..dda7b260533e 100644 --- a/core/java/android/view/ViewDebug.java +++ b/core/java/android/view/ViewDebug.java @@ -19,7 +19,7 @@ package android.view; import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.TestApi; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; import android.content.res.Resources; import android.graphics.Bitmap; @@ -870,6 +870,94 @@ public class ViewDebug { return null; } + private static class StreamingPictureCallbackHandler implements AutoCloseable, + HardwareRenderer.PictureCapturedCallback, Runnable { + private final HardwareRenderer mRenderer; + private final Callable<OutputStream> mCallback; + private final Executor mExecutor; + private final ReentrantLock mLock = new ReentrantLock(false); + private final ArrayDeque<byte[]> mQueue = new ArrayDeque<>(3); + private final ByteArrayOutputStream mByteStream = new ByteArrayOutputStream(); + private boolean mStopListening; + private Thread mRenderThread; + + private StreamingPictureCallbackHandler(HardwareRenderer renderer, + Callable<OutputStream> callback, Executor executor) { + mRenderer = renderer; + mCallback = callback; + mExecutor = executor; + mRenderer.setPictureCaptureCallback(this); + } + + @Override + public void close() { + mLock.lock(); + mStopListening = true; + mLock.unlock(); + mRenderer.setPictureCaptureCallback(null); + } + + @Override + public void onPictureCaptured(Picture picture) { + mLock.lock(); + if (mStopListening) { + mLock.unlock(); + mRenderer.setPictureCaptureCallback(null); + return; + } + if (mRenderThread == null) { + mRenderThread = Thread.currentThread(); + } + boolean needsInvoke = true; + if (mQueue.size() == 3) { + mQueue.removeLast(); + needsInvoke = false; + } + picture.writeToStream(mByteStream); + mQueue.add(mByteStream.toByteArray()); + mByteStream.reset(); + mLock.unlock(); + + if (needsInvoke) { + mExecutor.execute(this); + } + } + + @Override + public void run() { + mLock.lock(); + final byte[] picture = mQueue.poll(); + final boolean isStopped = mStopListening; + mLock.unlock(); + if (Thread.currentThread() == mRenderThread) { + close(); + throw new IllegalStateException( + "ViewDebug#startRenderingCommandsCapture must be given an executor that " + + "invokes asynchronously"); + } + if (isStopped) { + return; + } + OutputStream stream = null; + try { + stream = mCallback.call(); + } catch (Exception ex) { + Log.w("ViewDebug", "Aborting rendering commands capture " + + "because callback threw exception", ex); + } + if (stream != null) { + try { + stream.write(picture); + } catch (IOException ex) { + Log.w("ViewDebug", "Aborting rendering commands capture " + + "due to IOException writing to output stream", ex); + } + } else { + close(); + } + } + } + /** * Begins capturing the entire rendering commands for the view tree referenced by the given * view. The view passed may be any View in the tree as long as it is attached. That is, @@ -915,18 +1003,7 @@ public class ViewDebug { } final HardwareRenderer renderer = attachInfo.mThreadedRenderer; if (renderer != null) { - return new PictureCallbackHandler(renderer, (picture -> { - try { - OutputStream stream = callback.call(); - if (stream != null) { - picture.writeToStream(stream); - return true; - } - } catch (Exception ex) { - // fall through - } - return false; - }), executor); + return new StreamingPictureCallbackHandler(renderer, callback, executor); } return null; } diff --git a/core/java/android/view/ViewGroup.java b/core/java/android/view/ViewGroup.java index 937bd1b34e61..6125aadc57b6 100644 --- a/core/java/android/view/ViewGroup.java +++ b/core/java/android/view/ViewGroup.java @@ -24,7 +24,7 @@ import android.annotation.IdRes; import android.annotation.NonNull; import android.annotation.TestApi; import android.annotation.UiThread; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.ClipData; import android.content.Context; import android.content.Intent; diff --git a/core/java/android/view/ViewHierarchyEncoder.java b/core/java/android/view/ViewHierarchyEncoder.java index d5716bfaaf00..b0e0524a0d85 100644 --- a/core/java/android/view/ViewHierarchyEncoder.java +++ b/core/java/android/view/ViewHierarchyEncoder.java @@ -2,7 +2,7 @@ package android.view; import android.annotation.NonNull; import android.annotation.Nullable; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import java.io.ByteArrayOutputStream; import java.io.DataOutputStream; diff --git a/core/java/android/view/ViewOverlay.java b/core/java/android/view/ViewOverlay.java index e23c687af49b..7830c57e53ec 100644 --- a/core/java/android/view/ViewOverlay.java +++ b/core/java/android/view/ViewOverlay.java @@ -17,7 +17,7 @@ package android.view; import android.animation.LayoutTransition; import android.annotation.NonNull; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; import android.graphics.Canvas; import android.graphics.Rect; diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java index 57a01a32e1b8..1ab3d3ab4974 100644 --- a/core/java/android/view/ViewRootImpl.java +++ b/core/java/android/view/ViewRootImpl.java @@ -32,10 +32,10 @@ import android.animation.LayoutTransition; import android.annotation.AnyThread; import android.annotation.NonNull; import android.annotation.Nullable; -import android.annotation.UnsupportedAppUsage; import android.app.ActivityManager; import android.app.ActivityThread; import android.app.ResourcesManager; +import android.compat.annotation.UnsupportedAppUsage; import android.content.ClipData; import android.content.ClipDescription; import android.content.Context; diff --git a/core/java/android/view/ViewTreeObserver.java b/core/java/android/view/ViewTreeObserver.java index c72baca0b93b..d7b0afc89eaa 100644 --- a/core/java/android/view/ViewTreeObserver.java +++ b/core/java/android/view/ViewTreeObserver.java @@ -18,7 +18,7 @@ package android.view; import android.annotation.NonNull; import android.annotation.Nullable; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; import android.graphics.Rect; import android.graphics.Region; diff --git a/core/java/android/view/Window.java b/core/java/android/view/Window.java index 73e0e4b2eb8b..cdafa470a542 100644 --- a/core/java/android/view/Window.java +++ b/core/java/android/view/Window.java @@ -26,8 +26,8 @@ import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.StyleRes; import android.annotation.SystemApi; -import android.annotation.UnsupportedAppUsage; import android.app.WindowConfiguration; +import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; import android.content.pm.ActivityInfo; import android.content.res.Configuration; diff --git a/core/java/android/view/WindowAnimationFrameStats.java b/core/java/android/view/WindowAnimationFrameStats.java index 399dfba64461..dfc4f0cd4dc6 100644 --- a/core/java/android/view/WindowAnimationFrameStats.java +++ b/core/java/android/view/WindowAnimationFrameStats.java @@ -16,7 +16,7 @@ package android.view; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.os.Parcel; import android.os.Parcelable; diff --git a/core/java/android/view/WindowContentFrameStats.java b/core/java/android/view/WindowContentFrameStats.java index 9fa5a005055d..217197c96793 100644 --- a/core/java/android/view/WindowContentFrameStats.java +++ b/core/java/android/view/WindowContentFrameStats.java @@ -16,7 +16,7 @@ package android.view; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.os.Parcel; import android.os.Parcelable; diff --git a/core/java/android/view/WindowInsets.java b/core/java/android/view/WindowInsets.java index bcc6a552f569..87bc534da92f 100644 --- a/core/java/android/view/WindowInsets.java +++ b/core/java/android/view/WindowInsets.java @@ -34,7 +34,7 @@ import android.annotation.IntDef; import android.annotation.IntRange; import android.annotation.NonNull; import android.annotation.Nullable; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.Intent; import android.graphics.Insets; import android.graphics.Rect; diff --git a/core/java/android/view/WindowManager.java b/core/java/android/view/WindowManager.java index 7433b6c8ce87..d9d92788a434 100644 --- a/core/java/android/view/WindowManager.java +++ b/core/java/android/view/WindowManager.java @@ -50,9 +50,9 @@ import android.annotation.RequiresPermission; import android.annotation.SystemApi; import android.annotation.SystemService; import android.annotation.TestApi; -import android.annotation.UnsupportedAppUsage; import android.app.KeyguardManager; import android.app.Presentation; +import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; import android.content.pm.ActivityInfo; import android.graphics.PixelFormat; diff --git a/core/java/android/view/WindowManagerGlobal.java b/core/java/android/view/WindowManagerGlobal.java index 379acbecb613..a930abe40341 100644 --- a/core/java/android/view/WindowManagerGlobal.java +++ b/core/java/android/view/WindowManagerGlobal.java @@ -18,8 +18,8 @@ package android.view; import android.animation.ValueAnimator; import android.annotation.NonNull; -import android.annotation.UnsupportedAppUsage; import android.app.ActivityManager; +import android.compat.annotation.UnsupportedAppUsage; import android.content.ComponentCallbacks2; import android.content.Context; import android.content.pm.ApplicationInfo; diff --git a/core/java/android/view/WindowManagerImpl.java b/core/java/android/view/WindowManagerImpl.java index c3494432ebcb..cdeeaa438acb 100644 --- a/core/java/android/view/WindowManagerImpl.java +++ b/core/java/android/view/WindowManagerImpl.java @@ -17,7 +17,7 @@ package android.view; import android.annotation.NonNull; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; import android.graphics.Region; import android.os.Bundle; diff --git a/core/java/android/view/accessibility/AccessibilityEvent.java b/core/java/android/view/accessibility/AccessibilityEvent.java index 2ac44d2fac22..2ba9f94869e4 100644 --- a/core/java/android/view/accessibility/AccessibilityEvent.java +++ b/core/java/android/view/accessibility/AccessibilityEvent.java @@ -17,7 +17,7 @@ package android.view.accessibility; import android.annotation.IntDef; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.os.Build; import android.os.Parcel; import android.os.Parcelable; diff --git a/core/java/android/view/accessibility/AccessibilityInteractionClient.java b/core/java/android/view/accessibility/AccessibilityInteractionClient.java index 4db6f4f808f2..723da77b6f7d 100644 --- a/core/java/android/view/accessibility/AccessibilityInteractionClient.java +++ b/core/java/android/view/accessibility/AccessibilityInteractionClient.java @@ -17,7 +17,7 @@ package android.view.accessibility; import android.accessibilityservice.IAccessibilityServiceConnection; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.os.Binder; import android.os.Build; import android.os.Bundle; diff --git a/core/java/android/view/accessibility/AccessibilityManager.java b/core/java/android/view/accessibility/AccessibilityManager.java index 2e9d881f72f9..747bd706f316 100644 --- a/core/java/android/view/accessibility/AccessibilityManager.java +++ b/core/java/android/view/accessibility/AccessibilityManager.java @@ -29,7 +29,7 @@ import android.annotation.SdkConstant; import android.annotation.SystemApi; import android.annotation.SystemService; import android.annotation.TestApi; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.ComponentName; import android.content.Context; import android.content.pm.PackageManager; diff --git a/core/java/android/view/accessibility/AccessibilityNodeInfo.java b/core/java/android/view/accessibility/AccessibilityNodeInfo.java index 3b310fc13ee3..8e61a5e7c44b 100644 --- a/core/java/android/view/accessibility/AccessibilityNodeInfo.java +++ b/core/java/android/view/accessibility/AccessibilityNodeInfo.java @@ -26,7 +26,7 @@ import android.accessibilityservice.AccessibilityServiceInfo; import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.TestApi; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.graphics.Rect; import android.graphics.Region; import android.os.Bundle; diff --git a/core/java/android/view/accessibility/AccessibilityRecord.java b/core/java/android/view/accessibility/AccessibilityRecord.java index b382a1863af3..37c3a1361de1 100644 --- a/core/java/android/view/accessibility/AccessibilityRecord.java +++ b/core/java/android/view/accessibility/AccessibilityRecord.java @@ -19,7 +19,7 @@ package android.view.accessibility; import static com.android.internal.util.CollectionUtils.isEmpty; import android.annotation.Nullable; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.os.Parcelable; import android.view.View; diff --git a/core/java/android/view/accessibility/CaptioningManager.java b/core/java/android/view/accessibility/CaptioningManager.java index c42e9fec91bf..3d68692a3b5c 100644 --- a/core/java/android/view/accessibility/CaptioningManager.java +++ b/core/java/android/view/accessibility/CaptioningManager.java @@ -19,7 +19,7 @@ package android.view.accessibility; import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.SystemService; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.ContentResolver; import android.content.Context; import android.database.ContentObserver; diff --git a/core/java/android/view/animation/Animation.java b/core/java/android/view/animation/Animation.java index 3b60aee8f604..43dcafc9b9ce 100644 --- a/core/java/android/view/animation/Animation.java +++ b/core/java/android/view/animation/Animation.java @@ -19,7 +19,7 @@ package android.view.animation; import android.annotation.AnimRes; import android.annotation.ColorInt; import android.annotation.InterpolatorRes; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; import android.content.res.TypedArray; import android.graphics.RectF; diff --git a/core/java/android/view/animation/AnimationUtils.java b/core/java/android/view/animation/AnimationUtils.java index c877b9cec812..075b0ab728fa 100644 --- a/core/java/android/view/animation/AnimationUtils.java +++ b/core/java/android/view/animation/AnimationUtils.java @@ -19,7 +19,7 @@ package android.view.animation; import android.annotation.AnimRes; import android.annotation.InterpolatorRes; import android.annotation.TestApi; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; import android.content.res.Resources; import android.content.res.Resources.NotFoundException; diff --git a/core/java/android/view/animation/Transformation.java b/core/java/android/view/animation/Transformation.java index 58da04d8d38f..cfc6e39da876 100644 --- a/core/java/android/view/animation/Transformation.java +++ b/core/java/android/view/animation/Transformation.java @@ -17,7 +17,7 @@ package android.view.animation; import android.annotation.FloatRange; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.graphics.Matrix; import android.graphics.Rect; diff --git a/core/java/android/view/animation/TranslateAnimation.java b/core/java/android/view/animation/TranslateAnimation.java index 6c040d4c61aa..ec55a0273999 100644 --- a/core/java/android/view/animation/TranslateAnimation.java +++ b/core/java/android/view/animation/TranslateAnimation.java @@ -16,7 +16,7 @@ package android.view.animation; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; import android.content.res.TypedArray; import android.util.AttributeSet; diff --git a/core/java/android/view/animation/TranslateYAnimation.java b/core/java/android/view/animation/TranslateYAnimation.java index a6e0ccb18805..1a1dfbfd6f05 100644 --- a/core/java/android/view/animation/TranslateYAnimation.java +++ b/core/java/android/view/animation/TranslateYAnimation.java @@ -16,7 +16,7 @@ package android.view.animation; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.graphics.Matrix; /** diff --git a/core/java/android/view/inputmethod/InputMethodInfo.java b/core/java/android/view/inputmethod/InputMethodInfo.java index fe07feef3bfa..34005ac02735 100644 --- a/core/java/android/view/inputmethod/InputMethodInfo.java +++ b/core/java/android/view/inputmethod/InputMethodInfo.java @@ -17,7 +17,7 @@ package android.view.inputmethod; import android.annotation.NonNull; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.ComponentName; import android.content.Context; import android.content.pm.ApplicationInfo; diff --git a/core/java/android/view/inputmethod/InputMethodManager.java b/core/java/android/view/inputmethod/InputMethodManager.java index 032af1c5c7b5..d395f5294d6c 100644 --- a/core/java/android/view/inputmethod/InputMethodManager.java +++ b/core/java/android/view/inputmethod/InputMethodManager.java @@ -26,9 +26,9 @@ import android.annotation.RequiresFeature; import android.annotation.RequiresPermission; import android.annotation.SystemService; import android.annotation.TestApi; -import android.annotation.UnsupportedAppUsage; import android.annotation.UserIdInt; import android.app.ActivityThread; +import android.compat.annotation.UnsupportedAppUsage; import android.content.ComponentName; import android.content.ContentResolver; import android.content.Context; @@ -2830,7 +2830,7 @@ public final class InputMethodManager { } /** - * This is kept due to {@link android.annotation.UnsupportedAppUsage}. + * This is kept due to {@link android.compat.annotation.UnsupportedAppUsage}. * * <p>TODO(Bug 113914148): Check if we can remove this. We have accidentally exposed * WindowManagerInternal#getInputMethodWindowVisibleHeight to app developers and some of them diff --git a/core/java/android/view/inputmethod/InputMethodSubtypeArray.java b/core/java/android/view/inputmethod/InputMethodSubtypeArray.java index 8dd0dcd45a1c..50e95c80cfed 100644 --- a/core/java/android/view/inputmethod/InputMethodSubtypeArray.java +++ b/core/java/android/view/inputmethod/InputMethodSubtypeArray.java @@ -16,7 +16,7 @@ package android.view.inputmethod; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.os.Parcel; import android.util.Slog; diff --git a/core/java/android/view/textclassifier/TextClassificationManager.java b/core/java/android/view/textclassifier/TextClassificationManager.java index 95ca9deb2871..526ac6fd3570 100644 --- a/core/java/android/view/textclassifier/TextClassificationManager.java +++ b/core/java/android/view/textclassifier/TextClassificationManager.java @@ -19,8 +19,8 @@ package android.view.textclassifier; import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.SystemService; -import android.annotation.UnsupportedAppUsage; import android.app.ActivityThread; +import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; import android.database.ContentObserver; import android.os.ServiceManager; diff --git a/core/java/android/view/textclassifier/logging/SmartSelectionEventTracker.java b/core/java/android/view/textclassifier/logging/SmartSelectionEventTracker.java index b530ddfe86d6..05d12ce17d8c 100644 --- a/core/java/android/view/textclassifier/logging/SmartSelectionEventTracker.java +++ b/core/java/android/view/textclassifier/logging/SmartSelectionEventTracker.java @@ -19,7 +19,7 @@ package android.view.textclassifier.logging; import android.annotation.IntDef; import android.annotation.NonNull; import android.annotation.Nullable; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; import android.metrics.LogMaker; import android.util.Log; diff --git a/core/java/android/view/textservice/SpellCheckerSession.java b/core/java/android/view/textservice/SpellCheckerSession.java index f553ca512881..afddaa2ff58a 100644 --- a/core/java/android/view/textservice/SpellCheckerSession.java +++ b/core/java/android/view/textservice/SpellCheckerSession.java @@ -16,7 +16,7 @@ package android.view.textservice; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.os.Binder; import android.os.Handler; import android.os.HandlerThread; diff --git a/core/java/android/view/textservice/TextServicesManager.java b/core/java/android/view/textservice/TextServicesManager.java index 9ff64d9b268a..acb35d63df9d 100644 --- a/core/java/android/view/textservice/TextServicesManager.java +++ b/core/java/android/view/textservice/TextServicesManager.java @@ -18,8 +18,8 @@ package android.view.textservice; import android.annotation.NonNull; import android.annotation.SystemService; -import android.annotation.UnsupportedAppUsage; import android.annotation.UserIdInt; +import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; import android.os.Bundle; import android.os.RemoteException; diff --git a/core/java/android/webkit/CacheManager.java b/core/java/android/webkit/CacheManager.java index 7e067197ced8..fafe81393888 100644 --- a/core/java/android/webkit/CacheManager.java +++ b/core/java/android/webkit/CacheManager.java @@ -17,7 +17,7 @@ package android.webkit; import android.annotation.Nullable; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import java.io.File; import java.io.IOException; diff --git a/core/java/android/webkit/ConsoleMessage.java b/core/java/android/webkit/ConsoleMessage.java index e54849772f9a..5474557c9998 100644 --- a/core/java/android/webkit/ConsoleMessage.java +++ b/core/java/android/webkit/ConsoleMessage.java @@ -16,7 +16,7 @@ package android.webkit; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.os.Build; /** diff --git a/core/java/android/webkit/JsResult.java b/core/java/android/webkit/JsResult.java index 5bf6aab3225d..448db58e2658 100644 --- a/core/java/android/webkit/JsResult.java +++ b/core/java/android/webkit/JsResult.java @@ -17,7 +17,7 @@ package android.webkit; import android.annotation.SystemApi; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; /** * An instance of this class is passed as a parameter in various {@link WebChromeClient} action diff --git a/core/java/android/webkit/PluginData.java b/core/java/android/webkit/PluginData.java index 8aeeb1c53241..c9a196017a75 100644 --- a/core/java/android/webkit/PluginData.java +++ b/core/java/android/webkit/PluginData.java @@ -16,7 +16,8 @@ package android.webkit; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; + import java.io.InputStream; import java.util.Map; diff --git a/core/java/android/webkit/URLUtil.java b/core/java/android/webkit/URLUtil.java index 5d704cb09dcb..844b156b84d3 100644 --- a/core/java/android/webkit/URLUtil.java +++ b/core/java/android/webkit/URLUtil.java @@ -17,7 +17,7 @@ package android.webkit; import android.annotation.Nullable; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.net.ParseException; import android.net.Uri; import android.net.WebAddress; diff --git a/core/java/android/webkit/UrlInterceptHandler.java b/core/java/android/webkit/UrlInterceptHandler.java index f23aae6be8c2..a48e10799be7 100644 --- a/core/java/android/webkit/UrlInterceptHandler.java +++ b/core/java/android/webkit/UrlInterceptHandler.java @@ -17,9 +17,8 @@ package android.webkit; import android.annotation.Nullable; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.webkit.CacheManager.CacheResult; -import android.webkit.PluginData; import java.util.Map; diff --git a/core/java/android/webkit/UrlInterceptRegistry.java b/core/java/android/webkit/UrlInterceptRegistry.java index eeb28d73be85..c9dee00942c3 100644 --- a/core/java/android/webkit/UrlInterceptRegistry.java +++ b/core/java/android/webkit/UrlInterceptRegistry.java @@ -17,10 +17,8 @@ package android.webkit; import android.annotation.Nullable; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.webkit.CacheManager.CacheResult; -import android.webkit.PluginData; -import android.webkit.UrlInterceptHandler; import java.util.Iterator; import java.util.LinkedList; diff --git a/core/java/android/webkit/WebResourceResponse.java b/core/java/android/webkit/WebResourceResponse.java index 7c8f33e181d6..219523b15ab0 100644 --- a/core/java/android/webkit/WebResourceResponse.java +++ b/core/java/android/webkit/WebResourceResponse.java @@ -18,7 +18,7 @@ package android.webkit; import android.annotation.NonNull; import android.annotation.SystemApi; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import java.io.InputStream; import java.io.StringBufferInputStream; diff --git a/core/java/android/webkit/WebSettings.java b/core/java/android/webkit/WebSettings.java index 7282008f7e3a..8a5b64d95f19 100644 --- a/core/java/android/webkit/WebSettings.java +++ b/core/java/android/webkit/WebSettings.java @@ -19,7 +19,7 @@ package android.webkit; import android.annotation.IntDef; import android.annotation.Nullable; import android.annotation.SystemApi; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; import java.lang.annotation.ElementType; diff --git a/core/java/android/webkit/WebSyncManager.java b/core/java/android/webkit/WebSyncManager.java index e44d6ebf37d1..7046c5108783 100644 --- a/core/java/android/webkit/WebSyncManager.java +++ b/core/java/android/webkit/WebSyncManager.java @@ -16,7 +16,7 @@ package android.webkit; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; /** diff --git a/core/java/android/webkit/WebView.java b/core/java/android/webkit/WebView.java index 721ac2d9a6dc..271d5be3864e 100644 --- a/core/java/android/webkit/WebView.java +++ b/core/java/android/webkit/WebView.java @@ -21,8 +21,8 @@ import android.annotation.IntDef; import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.SystemApi; -import android.annotation.UnsupportedAppUsage; import android.annotation.Widget; +import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; import android.content.Intent; import android.content.pm.PackageInfo; diff --git a/core/java/android/webkit/WebViewDelegate.java b/core/java/android/webkit/WebViewDelegate.java index f5657dff538f..df86926a95dc 100644 --- a/core/java/android/webkit/WebViewDelegate.java +++ b/core/java/android/webkit/WebViewDelegate.java @@ -19,10 +19,10 @@ package android.webkit; import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.SystemApi; -import android.annotation.UnsupportedAppUsage; import android.app.ActivityThread; import android.app.Application; import android.app.ResourcesManager; +import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; import android.content.pm.ApplicationInfo; import android.content.res.Resources; diff --git a/core/java/android/webkit/WebViewFactory.java b/core/java/android/webkit/WebViewFactory.java index 678a25223ef5..941af6ef1d7a 100644 --- a/core/java/android/webkit/WebViewFactory.java +++ b/core/java/android/webkit/WebViewFactory.java @@ -17,10 +17,10 @@ package android.webkit; import android.annotation.SystemApi; -import android.annotation.UnsupportedAppUsage; import android.app.ActivityManager; import android.app.AppGlobals; import android.app.Application; +import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; import android.content.pm.ApplicationInfo; import android.content.pm.PackageInfo; diff --git a/core/java/android/webkit/WebViewProviderInfo.java b/core/java/android/webkit/WebViewProviderInfo.java index 7e00cded2c5a..6629fdc4cdee 100644 --- a/core/java/android/webkit/WebViewProviderInfo.java +++ b/core/java/android/webkit/WebViewProviderInfo.java @@ -17,7 +17,7 @@ package android.webkit; import android.annotation.SystemApi; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.pm.Signature; import android.os.Parcel; import android.os.Parcelable; diff --git a/core/java/android/webkit/WebViewProviderResponse.java b/core/java/android/webkit/WebViewProviderResponse.java index 5622abe0e99f..b58cc4bb1577 100644 --- a/core/java/android/webkit/WebViewProviderResponse.java +++ b/core/java/android/webkit/WebViewProviderResponse.java @@ -16,7 +16,7 @@ package android.webkit; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.pm.PackageInfo; import android.os.Parcel; import android.os.Parcelable; diff --git a/core/java/android/webkit/WebViewUpdateService.java b/core/java/android/webkit/WebViewUpdateService.java index 12d3221fb7b5..9152b438618f 100644 --- a/core/java/android/webkit/WebViewUpdateService.java +++ b/core/java/android/webkit/WebViewUpdateService.java @@ -17,7 +17,7 @@ package android.webkit; import android.annotation.SystemApi; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.os.RemoteException; /** diff --git a/core/java/android/widget/AbsListView.java b/core/java/android/widget/AbsListView.java index 85e9e4950cba..2d99eab88dfc 100644 --- a/core/java/android/widget/AbsListView.java +++ b/core/java/android/widget/AbsListView.java @@ -20,7 +20,7 @@ import android.annotation.ColorInt; import android.annotation.DrawableRes; import android.annotation.NonNull; import android.annotation.TestApi; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; import android.content.Intent; import android.content.res.Configuration; diff --git a/core/java/android/widget/AbsSeekBar.java b/core/java/android/widget/AbsSeekBar.java index bbcba2e12a2c..11a6acf5b934 100644 --- a/core/java/android/widget/AbsSeekBar.java +++ b/core/java/android/widget/AbsSeekBar.java @@ -18,7 +18,7 @@ package android.widget; import android.annotation.NonNull; import android.annotation.Nullable; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; import android.content.res.ColorStateList; import android.content.res.TypedArray; diff --git a/core/java/android/widget/ActionMenuPresenter.java b/core/java/android/widget/ActionMenuPresenter.java index cfb93ec2321f..aa3590aaff0a 100644 --- a/core/java/android/widget/ActionMenuPresenter.java +++ b/core/java/android/widget/ActionMenuPresenter.java @@ -22,7 +22,7 @@ import android.animation.ObjectAnimator; import android.animation.PropertyValuesHolder; import android.annotation.NonNull; import android.annotation.Nullable; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; import android.content.res.Configuration; import android.content.res.Resources; diff --git a/core/java/android/widget/ActionMenuView.java b/core/java/android/widget/ActionMenuView.java index 7e58622db3b8..3a743562110f 100644 --- a/core/java/android/widget/ActionMenuView.java +++ b/core/java/android/widget/ActionMenuView.java @@ -18,7 +18,7 @@ package android.widget; import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.StyleRes; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; import android.content.res.Configuration; import android.graphics.drawable.Drawable; diff --git a/core/java/android/widget/ActivityChooserModel.java b/core/java/android/widget/ActivityChooserModel.java index f5bf7598aa5a..d87bdf482e43 100644 --- a/core/java/android/widget/ActivityChooserModel.java +++ b/core/java/android/widget/ActivityChooserModel.java @@ -16,8 +16,8 @@ package android.widget; -import android.annotation.UnsupportedAppUsage; import android.app.ActivityManager; +import android.compat.annotation.UnsupportedAppUsage; import android.content.ComponentName; import android.content.Context; import android.content.Intent; diff --git a/core/java/android/widget/ActivityChooserView.java b/core/java/android/widget/ActivityChooserView.java index 89ea0747b532..aa18d576c8f4 100644 --- a/core/java/android/widget/ActivityChooserView.java +++ b/core/java/android/widget/ActivityChooserView.java @@ -17,7 +17,7 @@ package android.widget; import android.annotation.StringRes; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; import android.content.Intent; import android.content.pm.PackageManager; diff --git a/core/java/android/widget/AdapterView.java b/core/java/android/widget/AdapterView.java index c55f7d654548..52658404548c 100644 --- a/core/java/android/widget/AdapterView.java +++ b/core/java/android/widget/AdapterView.java @@ -18,7 +18,7 @@ package android.widget; import android.annotation.NonNull; import android.annotation.Nullable; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; import android.database.DataSetObserver; import android.os.Build; diff --git a/core/java/android/widget/AnalogClock.java b/core/java/android/widget/AnalogClock.java index 67a70b48b534..d165bd0f0fa7 100644 --- a/core/java/android/widget/AnalogClock.java +++ b/core/java/android/widget/AnalogClock.java @@ -16,7 +16,7 @@ package android.widget; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; diff --git a/core/java/android/widget/ArrayAdapter.java b/core/java/android/widget/ArrayAdapter.java index 2bf1ba5cf017..6c38c8b9a0f5 100644 --- a/core/java/android/widget/ArrayAdapter.java +++ b/core/java/android/widget/ArrayAdapter.java @@ -21,7 +21,7 @@ import android.annotation.IdRes; import android.annotation.LayoutRes; import android.annotation.NonNull; import android.annotation.Nullable; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; import android.content.res.Resources; import android.util.Log; diff --git a/core/java/android/widget/AutoCompleteTextView.java b/core/java/android/widget/AutoCompleteTextView.java index 8785251b0a64..8d9ae58be290 100644 --- a/core/java/android/widget/AutoCompleteTextView.java +++ b/core/java/android/widget/AutoCompleteTextView.java @@ -18,7 +18,7 @@ package android.widget; import android.annotation.DrawableRes; import android.annotation.IntDef; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; import android.content.res.Resources.Theme; import android.content.res.TypedArray; diff --git a/core/java/android/widget/BaseAdapter.java b/core/java/android/widget/BaseAdapter.java index 7b9365b08a41..27cf9a64a8d5 100644 --- a/core/java/android/widget/BaseAdapter.java +++ b/core/java/android/widget/BaseAdapter.java @@ -17,7 +17,7 @@ package android.widget; import android.annotation.Nullable; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.database.DataSetObservable; import android.database.DataSetObserver; import android.view.View; diff --git a/core/java/android/widget/CalendarView.java b/core/java/android/widget/CalendarView.java index b552aa6c85c4..4b2f738ef7ab 100644 --- a/core/java/android/widget/CalendarView.java +++ b/core/java/android/widget/CalendarView.java @@ -23,8 +23,8 @@ import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.StyleRes; import android.annotation.TestApi; -import android.annotation.UnsupportedAppUsage; import android.annotation.Widget; +import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; import android.content.res.Configuration; import android.content.res.TypedArray; diff --git a/core/java/android/widget/CheckedTextView.java b/core/java/android/widget/CheckedTextView.java index 8b70f41f050c..422d2d37321c 100644 --- a/core/java/android/widget/CheckedTextView.java +++ b/core/java/android/widget/CheckedTextView.java @@ -19,7 +19,7 @@ package android.widget; import android.annotation.DrawableRes; import android.annotation.NonNull; import android.annotation.Nullable; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; import android.content.res.ColorStateList; import android.content.res.TypedArray; diff --git a/core/java/android/widget/CompoundButton.java b/core/java/android/widget/CompoundButton.java index 2674ca4d159a..52e983ec487d 100644 --- a/core/java/android/widget/CompoundButton.java +++ b/core/java/android/widget/CompoundButton.java @@ -19,7 +19,7 @@ package android.widget; import android.annotation.DrawableRes; import android.annotation.NonNull; import android.annotation.Nullable; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; import android.content.res.ColorStateList; import android.content.res.TypedArray; diff --git a/core/java/android/widget/CursorAdapter.java b/core/java/android/widget/CursorAdapter.java index e250f63bbc65..600a34c33eb9 100644 --- a/core/java/android/widget/CursorAdapter.java +++ b/core/java/android/widget/CursorAdapter.java @@ -16,8 +16,8 @@ package android.widget; -import android.annotation.UnsupportedAppUsage; import android.annotation.WorkerThread; +import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; import android.content.res.Resources; import android.database.ContentObserver; diff --git a/core/java/android/widget/DatePicker.java b/core/java/android/widget/DatePicker.java index 0c593be1ee7d..c1c1a6e88b50 100644 --- a/core/java/android/widget/DatePicker.java +++ b/core/java/android/widget/DatePicker.java @@ -19,8 +19,8 @@ package android.widget; import android.annotation.IntDef; import android.annotation.Nullable; import android.annotation.TestApi; -import android.annotation.UnsupportedAppUsage; import android.annotation.Widget; +import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; import android.content.res.Configuration; import android.content.res.TypedArray; diff --git a/core/java/android/widget/DatePickerSpinnerDelegate.java b/core/java/android/widget/DatePickerSpinnerDelegate.java index 5f151105622e..096e6ea52c8a 100644 --- a/core/java/android/widget/DatePickerSpinnerDelegate.java +++ b/core/java/android/widget/DatePickerSpinnerDelegate.java @@ -16,7 +16,7 @@ package android.widget; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; import android.content.res.Configuration; import android.content.res.TypedArray; diff --git a/core/java/android/widget/DateTimeView.java b/core/java/android/widget/DateTimeView.java index 2864ad0b7932..20a53c03bed1 100644 --- a/core/java/android/widget/DateTimeView.java +++ b/core/java/android/widget/DateTimeView.java @@ -21,8 +21,8 @@ import static android.text.format.DateUtils.HOUR_IN_MILLIS; import static android.text.format.DateUtils.MINUTE_IN_MILLIS; import static android.text.format.DateUtils.YEAR_IN_MILLIS; -import android.annotation.UnsupportedAppUsage; import android.app.ActivityThread; +import android.compat.annotation.UnsupportedAppUsage; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; diff --git a/core/java/android/widget/EdgeEffect.java b/core/java/android/widget/EdgeEffect.java index fa0af78694ab..32f3acd387b0 100644 --- a/core/java/android/widget/EdgeEffect.java +++ b/core/java/android/widget/EdgeEffect.java @@ -18,7 +18,7 @@ package android.widget; import android.annotation.ColorInt; import android.annotation.Nullable; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; import android.content.res.TypedArray; import android.graphics.BlendMode; diff --git a/core/java/android/widget/Editor.java b/core/java/android/widget/Editor.java index cac75cfd8432..b6338f7b0e7a 100644 --- a/core/java/android/widget/Editor.java +++ b/core/java/android/widget/Editor.java @@ -21,10 +21,10 @@ import android.animation.ValueAnimator; import android.annotation.IntDef; import android.annotation.NonNull; import android.annotation.Nullable; -import android.annotation.UnsupportedAppUsage; import android.app.PendingIntent; import android.app.PendingIntent.CanceledException; import android.app.RemoteAction; +import android.compat.annotation.UnsupportedAppUsage; import android.content.ClipData; import android.content.ClipData.Item; import android.content.Context; diff --git a/core/java/android/widget/ExpandableListView.java b/core/java/android/widget/ExpandableListView.java index cae91fce64a3..bdfb5503946d 100644 --- a/core/java/android/widget/ExpandableListView.java +++ b/core/java/android/widget/ExpandableListView.java @@ -18,7 +18,7 @@ package android.widget; import static android.os.Build.VERSION_CODES.JELLY_BEAN_MR1; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; import android.content.res.TypedArray; import android.graphics.Canvas; diff --git a/core/java/android/widget/FastScroller.java b/core/java/android/widget/FastScroller.java index 2c09185fdf62..0c0b3491a854 100644 --- a/core/java/android/widget/FastScroller.java +++ b/core/java/android/widget/FastScroller.java @@ -23,7 +23,7 @@ import android.animation.AnimatorSet; import android.animation.ObjectAnimator; import android.animation.PropertyValuesHolder; import android.annotation.StyleRes; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; import android.content.res.ColorStateList; import android.content.res.TypedArray; diff --git a/core/java/android/widget/Filter.java b/core/java/android/widget/Filter.java index 16f4ee2b51d6..06e6a5ac694f 100644 --- a/core/java/android/widget/Filter.java +++ b/core/java/android/widget/Filter.java @@ -16,7 +16,7 @@ package android.widget; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.os.Handler; import android.os.HandlerThread; import android.os.Looper; diff --git a/core/java/android/widget/FrameLayout.java b/core/java/android/widget/FrameLayout.java index 69da9112ca01..92e9a96e4897 100644 --- a/core/java/android/widget/FrameLayout.java +++ b/core/java/android/widget/FrameLayout.java @@ -20,7 +20,7 @@ import android.annotation.AttrRes; import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.StyleRes; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; import android.content.res.TypedArray; import android.graphics.Rect; diff --git a/core/java/android/widget/Gallery.java b/core/java/android/widget/Gallery.java index 64192aaff1cf..8c0061d6e750 100644 --- a/core/java/android/widget/Gallery.java +++ b/core/java/android/widget/Gallery.java @@ -17,8 +17,8 @@ package android.widget; import android.annotation.NonNull; -import android.annotation.UnsupportedAppUsage; import android.annotation.Widget; +import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; import android.content.res.TypedArray; import android.graphics.Rect; diff --git a/core/java/android/widget/GridLayout.java b/core/java/android/widget/GridLayout.java index 8cda47dae39b..f1321979e2de 100644 --- a/core/java/android/widget/GridLayout.java +++ b/core/java/android/widget/GridLayout.java @@ -31,7 +31,7 @@ import static java.lang.Math.max; import static java.lang.Math.min; import android.annotation.IntDef; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; import android.content.res.TypedArray; import android.graphics.Canvas; diff --git a/core/java/android/widget/GridView.java b/core/java/android/widget/GridView.java index 4e39a559c6ea..4a5e95e492e5 100644 --- a/core/java/android/widget/GridView.java +++ b/core/java/android/widget/GridView.java @@ -18,7 +18,7 @@ package android.widget; import android.annotation.IntDef; import android.annotation.NonNull; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; import android.content.Intent; import android.content.res.TypedArray; diff --git a/core/java/android/widget/HeaderViewListAdapter.java b/core/java/android/widget/HeaderViewListAdapter.java index 10d50b811289..eda7580949b1 100644 --- a/core/java/android/widget/HeaderViewListAdapter.java +++ b/core/java/android/widget/HeaderViewListAdapter.java @@ -16,7 +16,7 @@ package android.widget; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.database.DataSetObserver; import android.view.View; import android.view.ViewGroup; diff --git a/core/java/android/widget/HorizontalScrollView.java b/core/java/android/widget/HorizontalScrollView.java index 5921feb7a758..f5f64c033692 100644 --- a/core/java/android/widget/HorizontalScrollView.java +++ b/core/java/android/widget/HorizontalScrollView.java @@ -18,7 +18,7 @@ package android.widget; import android.annotation.ColorInt; import android.annotation.NonNull; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; import android.content.res.Configuration; import android.content.res.TypedArray; diff --git a/core/java/android/widget/ImageView.java b/core/java/android/widget/ImageView.java index d62b979a2ed3..c20773848759 100644 --- a/core/java/android/widget/ImageView.java +++ b/core/java/android/widget/ImageView.java @@ -20,7 +20,7 @@ import android.annotation.DrawableRes; import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.TestApi; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.ContentResolver; import android.content.Context; import android.content.res.ColorStateList; diff --git a/core/java/android/widget/LinearLayout.java b/core/java/android/widget/LinearLayout.java index a83e82699938..a796ba545d8f 100644 --- a/core/java/android/widget/LinearLayout.java +++ b/core/java/android/widget/LinearLayout.java @@ -19,7 +19,7 @@ package android.widget; import android.annotation.IntDef; import android.annotation.NonNull; import android.annotation.Nullable; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; import android.content.res.TypedArray; import android.graphics.Canvas; diff --git a/core/java/android/widget/ListPopupWindow.java b/core/java/android/widget/ListPopupWindow.java index 16b903d4da9e..001eb2728fec 100644 --- a/core/java/android/widget/ListPopupWindow.java +++ b/core/java/android/widget/ListPopupWindow.java @@ -20,7 +20,7 @@ import android.annotation.AttrRes; import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.StyleRes; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; import android.content.res.TypedArray; import android.database.DataSetObserver; diff --git a/core/java/android/widget/ListView.java b/core/java/android/widget/ListView.java index 2f44d6ee88b1..72603444f5ff 100644 --- a/core/java/android/widget/ListView.java +++ b/core/java/android/widget/ListView.java @@ -19,7 +19,7 @@ package android.widget; import android.annotation.IdRes; import android.annotation.NonNull; import android.annotation.Nullable; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; import android.content.Intent; import android.content.res.TypedArray; diff --git a/core/java/android/widget/MediaController.java b/core/java/android/widget/MediaController.java index 65925b446bbe..9c9baf35949b 100644 --- a/core/java/android/widget/MediaController.java +++ b/core/java/android/widget/MediaController.java @@ -16,7 +16,7 @@ package android.widget; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; import android.content.res.Resources; import android.graphics.PixelFormat; diff --git a/core/java/android/widget/NumberPicker.java b/core/java/android/widget/NumberPicker.java index b385534f1850..b2fedf7a3a7f 100644 --- a/core/java/android/widget/NumberPicker.java +++ b/core/java/android/widget/NumberPicker.java @@ -23,8 +23,8 @@ import android.annotation.IntDef; import android.annotation.IntRange; import android.annotation.Px; import android.annotation.TestApi; -import android.annotation.UnsupportedAppUsage; import android.annotation.Widget; +import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; import android.content.res.ColorStateList; import android.content.res.TypedArray; diff --git a/core/java/android/widget/OverScroller.java b/core/java/android/widget/OverScroller.java index e7a96bea18fe..1c33d80fd4ca 100644 --- a/core/java/android/widget/OverScroller.java +++ b/core/java/android/widget/OverScroller.java @@ -16,7 +16,7 @@ package android.widget; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; import android.hardware.SensorManager; import android.util.Log; diff --git a/core/java/android/widget/PopupMenu.java b/core/java/android/widget/PopupMenu.java index b0c0c12e907a..0ce964666a2b 100644 --- a/core/java/android/widget/PopupMenu.java +++ b/core/java/android/widget/PopupMenu.java @@ -18,7 +18,7 @@ package android.widget; import android.annotation.MenuRes; import android.annotation.TestApi; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; import android.view.Gravity; import android.view.Menu; diff --git a/core/java/android/widget/PopupWindow.java b/core/java/android/widget/PopupWindow.java index 3779779e9f21..bf696f5a7c53 100644 --- a/core/java/android/widget/PopupWindow.java +++ b/core/java/android/widget/PopupWindow.java @@ -18,13 +18,12 @@ package android.widget; import static android.view.ViewGroup.LayoutParams.MATCH_PARENT; import static android.view.ViewGroup.LayoutParams.WRAP_CONTENT; -import static android.view.WindowManager.LayoutParams - .PRIVATE_FLAG_LAYOUT_CHILD_WINDOW_IN_PARENT_FRAME; +import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_LAYOUT_CHILD_WINDOW_IN_PARENT_FRAME; import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_WILL_NOT_REPLACE_ON_RELAUNCH; import android.annotation.NonNull; import android.annotation.Nullable; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; import android.content.res.TypedArray; import android.graphics.PixelFormat; diff --git a/core/java/android/widget/ProgressBar.java b/core/java/android/widget/ProgressBar.java index 2e9574345692..9cbb03508d67 100644 --- a/core/java/android/widget/ProgressBar.java +++ b/core/java/android/widget/ProgressBar.java @@ -21,7 +21,7 @@ import android.annotation.InterpolatorRes; import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.Px; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; import android.content.res.ColorStateList; import android.content.res.TypedArray; diff --git a/core/java/android/widget/QuickContactBadge.java b/core/java/android/widget/QuickContactBadge.java index c1a217c6dc89..ea39f6d71573 100644 --- a/core/java/android/widget/QuickContactBadge.java +++ b/core/java/android/widget/QuickContactBadge.java @@ -16,7 +16,7 @@ package android.widget; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.AsyncQueryHandler; import android.content.ContentResolver; import android.content.Context; diff --git a/core/java/android/widget/RadioGroup.java b/core/java/android/widget/RadioGroup.java index c62c16c7e719..69c3cdad2dbf 100644 --- a/core/java/android/widget/RadioGroup.java +++ b/core/java/android/widget/RadioGroup.java @@ -18,7 +18,7 @@ package android.widget; import android.annotation.IdRes; import android.annotation.NonNull; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; import android.content.res.TypedArray; import android.util.AttributeSet; diff --git a/core/java/android/widget/RatingBar.java b/core/java/android/widget/RatingBar.java index 3cf3d9102d21..f946fe6d8314 100644 --- a/core/java/android/widget/RatingBar.java +++ b/core/java/android/widget/RatingBar.java @@ -16,7 +16,7 @@ package android.widget; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; import android.content.res.TypedArray; import android.graphics.drawable.shapes.RectShape; diff --git a/core/java/android/widget/RelativeLayout.java b/core/java/android/widget/RelativeLayout.java index b9da3071d895..521922df97e0 100644 --- a/core/java/android/widget/RelativeLayout.java +++ b/core/java/android/widget/RelativeLayout.java @@ -19,7 +19,7 @@ package android.widget; import static android.os.Build.VERSION_CODES.JELLY_BEAN_MR1; import android.annotation.NonNull; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; import android.content.res.ResourceId; import android.content.res.TypedArray; diff --git a/core/java/android/widget/RemoteViews.java b/core/java/android/widget/RemoteViews.java index 86cec5e0f0a2..82e03e26b41f 100644 --- a/core/java/android/widget/RemoteViews.java +++ b/core/java/android/widget/RemoteViews.java @@ -22,7 +22,6 @@ import android.annotation.IntDef; import android.annotation.LayoutRes; import android.annotation.NonNull; import android.annotation.StyleRes; -import android.annotation.UnsupportedAppUsage; import android.app.Activity; import android.app.ActivityOptions; import android.app.ActivityThread; @@ -30,6 +29,7 @@ import android.app.Application; import android.app.PendingIntent; import android.app.RemoteInput; import android.appwidget.AppWidgetHostView; +import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; import android.content.ContextWrapper; import android.content.Intent; diff --git a/core/java/android/widget/RemoteViewsAdapter.java b/core/java/android/widget/RemoteViewsAdapter.java index efc5eb373e00..e58f08a79965 100644 --- a/core/java/android/widget/RemoteViewsAdapter.java +++ b/core/java/android/widget/RemoteViewsAdapter.java @@ -19,11 +19,11 @@ package android.widget; import static android.widget.RemoteViews.EXTRA_REMOTEADAPTER_APPWIDGET_ID; import static android.widget.RemoteViews.EXTRA_REMOTEADAPTER_ON_LIGHT_BACKGROUND; -import android.annotation.UnsupportedAppUsage; import android.annotation.WorkerThread; import android.app.IServiceConnection; import android.appwidget.AppWidgetHostView; import android.appwidget.AppWidgetManager; +import android.compat.annotation.UnsupportedAppUsage; import android.content.ComponentName; import android.content.Context; import android.content.Intent; diff --git a/core/java/android/widget/ScrollBarDrawable.java b/core/java/android/widget/ScrollBarDrawable.java index a5d3e45323a4..80e17b5e8217 100644 --- a/core/java/android/widget/ScrollBarDrawable.java +++ b/core/java/android/widget/ScrollBarDrawable.java @@ -18,7 +18,7 @@ package android.widget; import android.annotation.NonNull; import android.annotation.Nullable; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.graphics.Canvas; import android.graphics.ColorFilter; import android.graphics.PixelFormat; diff --git a/core/java/android/widget/ScrollView.java b/core/java/android/widget/ScrollView.java index 51b0950a7544..6c2e7a956ab9 100644 --- a/core/java/android/widget/ScrollView.java +++ b/core/java/android/widget/ScrollView.java @@ -18,7 +18,7 @@ package android.widget; import android.annotation.ColorInt; import android.annotation.NonNull; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; import android.content.res.Configuration; import android.content.res.TypedArray; diff --git a/core/java/android/widget/Scroller.java b/core/java/android/widget/Scroller.java index 229eaf0f8ff6..6ed5b7ebf4d0 100644 --- a/core/java/android/widget/Scroller.java +++ b/core/java/android/widget/Scroller.java @@ -16,7 +16,7 @@ package android.widget; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; import android.hardware.SensorManager; import android.os.Build; diff --git a/core/java/android/widget/SearchView.java b/core/java/android/widget/SearchView.java index 89d9e97bddad..15959c221ffc 100644 --- a/core/java/android/widget/SearchView.java +++ b/core/java/android/widget/SearchView.java @@ -19,10 +19,10 @@ package android.widget; import static android.widget.SuggestionsAdapter.getColumnString; import android.annotation.Nullable; -import android.annotation.UnsupportedAppUsage; import android.app.PendingIntent; import android.app.SearchManager; import android.app.SearchableInfo; +import android.compat.annotation.UnsupportedAppUsage; import android.content.ActivityNotFoundException; import android.content.ComponentName; import android.content.Context; diff --git a/core/java/android/widget/SeekBar.java b/core/java/android/widget/SeekBar.java index e8cf1e855a33..5676881cee76 100644 --- a/core/java/android/widget/SeekBar.java +++ b/core/java/android/widget/SeekBar.java @@ -16,7 +16,7 @@ package android.widget; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; import android.util.AttributeSet; import android.view.accessibility.AccessibilityNodeInfo; diff --git a/core/java/android/widget/SimpleAdapter.java b/core/java/android/widget/SimpleAdapter.java index 15e1ffa7bc31..404b81795823 100644 --- a/core/java/android/widget/SimpleAdapter.java +++ b/core/java/android/widget/SimpleAdapter.java @@ -18,7 +18,7 @@ package android.widget; import android.annotation.IdRes; import android.annotation.LayoutRes; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; import android.content.res.Resources; import android.net.Uri; diff --git a/core/java/android/widget/SimpleCursorAdapter.java b/core/java/android/widget/SimpleCursorAdapter.java index 77fe5d1a9302..6277d5b84913 100644 --- a/core/java/android/widget/SimpleCursorAdapter.java +++ b/core/java/android/widget/SimpleCursorAdapter.java @@ -16,7 +16,7 @@ package android.widget; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; import android.database.Cursor; import android.net.Uri; diff --git a/core/java/android/widget/SlidingDrawer.java b/core/java/android/widget/SlidingDrawer.java index 2ab2b2407a50..9a4cfa192854 100644 --- a/core/java/android/widget/SlidingDrawer.java +++ b/core/java/android/widget/SlidingDrawer.java @@ -17,7 +17,7 @@ package android.widget; import android.R; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; import android.content.res.TypedArray; import android.graphics.Bitmap; diff --git a/core/java/android/widget/Spinner.java b/core/java/android/widget/Spinner.java index 92fcea348b1a..46fc09f4c3b3 100644 --- a/core/java/android/widget/Spinner.java +++ b/core/java/android/widget/Spinner.java @@ -19,9 +19,9 @@ package android.widget; import android.annotation.DrawableRes; import android.annotation.Nullable; import android.annotation.TestApi; -import android.annotation.UnsupportedAppUsage; import android.annotation.Widget; import android.app.AlertDialog; +import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; import android.content.DialogInterface; import android.content.DialogInterface.OnClickListener; diff --git a/core/java/android/widget/Switch.java b/core/java/android/widget/Switch.java index d57b3bc7ad3b..f1f393973fed 100644 --- a/core/java/android/widget/Switch.java +++ b/core/java/android/widget/Switch.java @@ -21,7 +21,7 @@ import android.annotation.DrawableRes; import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.StyleRes; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; import android.content.res.ColorStateList; import android.content.res.Resources; diff --git a/core/java/android/widget/TabHost.java b/core/java/android/widget/TabHost.java index 481704c80287..fd8dbf5c86f7 100644 --- a/core/java/android/widget/TabHost.java +++ b/core/java/android/widget/TabHost.java @@ -18,8 +18,8 @@ package android.widget; import android.annotation.NonNull; import android.annotation.Nullable; -import android.annotation.UnsupportedAppUsage; import android.app.LocalActivityManager; +import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; import android.content.Intent; import android.content.res.TypedArray; diff --git a/core/java/android/widget/TabWidget.java b/core/java/android/widget/TabWidget.java index 4c67b080252a..945cef3e5791 100644 --- a/core/java/android/widget/TabWidget.java +++ b/core/java/android/widget/TabWidget.java @@ -18,7 +18,7 @@ package android.widget; import android.annotation.DrawableRes; import android.annotation.Nullable; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; import android.content.res.TypedArray; import android.graphics.Canvas; diff --git a/core/java/android/widget/TextClock.java b/core/java/android/widget/TextClock.java index b7dd88bcedc6..88a67625d615 100644 --- a/core/java/android/widget/TextClock.java +++ b/core/java/android/widget/TextClock.java @@ -21,8 +21,8 @@ import static android.widget.RemoteViews.RemoteView; import android.annotation.NonNull; import android.annotation.TestApi; -import android.annotation.UnsupportedAppUsage; import android.app.ActivityManager; +import android.compat.annotation.UnsupportedAppUsage; import android.content.BroadcastReceiver; import android.content.ContentResolver; import android.content.Context; diff --git a/core/java/android/widget/TextView.java b/core/java/android/widget/TextView.java index 0918c5fdefa8..6f697cd65686 100644 --- a/core/java/android/widget/TextView.java +++ b/core/java/android/widget/TextView.java @@ -36,11 +36,11 @@ import android.annotation.RequiresPermission; import android.annotation.Size; import android.annotation.StringRes; import android.annotation.StyleRes; -import android.annotation.UnsupportedAppUsage; import android.annotation.XmlRes; import android.app.Activity; import android.app.PendingIntent; import android.app.assist.AssistStructure; +import android.compat.annotation.UnsupportedAppUsage; import android.content.ClipData; import android.content.ClipDescription; import android.content.ClipboardManager; diff --git a/core/java/android/widget/TimePicker.java b/core/java/android/widget/TimePicker.java index 8a5d5312bd7b..51b18473f1ac 100644 --- a/core/java/android/widget/TimePicker.java +++ b/core/java/android/widget/TimePicker.java @@ -20,8 +20,8 @@ import android.annotation.IntDef; import android.annotation.IntRange; import android.annotation.NonNull; import android.annotation.TestApi; -import android.annotation.UnsupportedAppUsage; import android.annotation.Widget; +import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; import android.content.res.TypedArray; import android.icu.util.Calendar; diff --git a/core/java/android/widget/Toast.java b/core/java/android/widget/Toast.java index d037337d4546..e6dcd9ef5817 100644 --- a/core/java/android/widget/Toast.java +++ b/core/java/android/widget/Toast.java @@ -20,9 +20,9 @@ import android.annotation.IntDef; import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.StringRes; -import android.annotation.UnsupportedAppUsage; import android.app.INotificationManager; import android.app.ITransientNotification; +import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; import android.content.res.Configuration; import android.content.res.Resources; diff --git a/core/java/android/widget/Toolbar.java b/core/java/android/widget/Toolbar.java index a21fb41b7c99..ea3f06b7f3e2 100644 --- a/core/java/android/widget/Toolbar.java +++ b/core/java/android/widget/Toolbar.java @@ -24,8 +24,8 @@ import android.annotation.Nullable; import android.annotation.StringRes; import android.annotation.StyleRes; import android.annotation.TestApi; -import android.annotation.UnsupportedAppUsage; import android.app.ActionBar; +import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; import android.content.res.TypedArray; import android.graphics.drawable.Drawable; diff --git a/core/java/android/widget/VideoView.java b/core/java/android/widget/VideoView.java index 40b0f13c596b..36dafd5c0a05 100644 --- a/core/java/android/widget/VideoView.java +++ b/core/java/android/widget/VideoView.java @@ -17,8 +17,8 @@ package android.widget; import android.annotation.NonNull; -import android.annotation.UnsupportedAppUsage; import android.app.AlertDialog; +import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; import android.content.DialogInterface; import android.content.res.Resources; diff --git a/core/java/android/widget/ViewAnimator.java b/core/java/android/widget/ViewAnimator.java index 80ea363a6ad6..909404b42f1d 100644 --- a/core/java/android/widget/ViewAnimator.java +++ b/core/java/android/widget/ViewAnimator.java @@ -18,7 +18,7 @@ package android.widget; import android.annotation.AnimRes; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; import android.content.res.TypedArray; import android.util.AttributeSet; diff --git a/core/java/android/widget/ViewFlipper.java b/core/java/android/widget/ViewFlipper.java index b962298e3d46..2df9a785450b 100644 --- a/core/java/android/widget/ViewFlipper.java +++ b/core/java/android/widget/ViewFlipper.java @@ -17,7 +17,7 @@ package android.widget; import android.annotation.IntRange; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; diff --git a/core/java/android/widget/ZoomControls.java b/core/java/android/widget/ZoomControls.java index 7a5b7e8058f3..f435533291d6 100644 --- a/core/java/android/widget/ZoomControls.java +++ b/core/java/android/widget/ZoomControls.java @@ -16,8 +16,8 @@ package android.widget; -import android.annotation.UnsupportedAppUsage; import android.annotation.Widget; +import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; import android.util.AttributeSet; import android.view.LayoutInflater; diff --git a/core/java/com/android/ims/internal/uce/common/CapInfo.java b/core/java/com/android/ims/internal/uce/common/CapInfo.java index a9847ba61cf6..2bb3f1fed927 100644 --- a/core/java/com/android/ims/internal/uce/common/CapInfo.java +++ b/core/java/com/android/ims/internal/uce/common/CapInfo.java @@ -16,10 +16,9 @@ package com.android.ims.internal.uce.common; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.os.Parcel; import android.os.Parcelable; -import android.util.Log; /** Class for capability discovery information. * @hide */ @@ -65,6 +64,20 @@ public class CapInfo implements Parcelable { private boolean mRcsIpVideoCallSupported = false; /** RCS IP Video call support . */ private boolean mRcsIpVideoOnlyCallSupported = false; + /** IP Geo location Push using SMS. */ + private boolean mGeoSmsSupported = false; + /** RCS call composer support. */ + private boolean mCallComposerSupported = false; + /** RCS post-call support. */ + private boolean mPostCallSupported = false; + /** Shared map support. */ + private boolean mSharedMapSupported = false; + /** Shared Sketch supported. */ + private boolean mSharedSketchSupported = false; + /** Chatbot communication support. */ + private boolean mChatbotSupported = false; + /** Chatbot role support. */ + private boolean mChatbotRoleSupported = false; /** List of supported extensions. */ private String[] mExts = new String[10]; /** Time used to compute when to query again. */ @@ -387,6 +400,104 @@ public class CapInfo implements Parcelable { this.mRcsIpVideoOnlyCallSupported = rcsIpVideoOnlyCallSupported; } + /** + * Checks whether Geo Push via SMS is supported. + */ + public boolean isGeoSmsSupported() { + return mGeoSmsSupported; + } + + /** + * Sets Geolocation Push via SMS as supported or not supported. + */ + public void setGeoSmsSupported(boolean geoSmsSupported) { + this.mGeoSmsSupported = geoSmsSupported; + } + + /** + * Checks whether RCS call composer is supported. + */ + public boolean isCallComposerSupported() { + return mCallComposerSupported; + } + + /** + * Sets call composer as supported or not supported. + */ + public void setCallComposerSupported(boolean callComposerSupported) { + this.mCallComposerSupported = callComposerSupported; + } + + /** + * Checks whether post call is supported. + */ + public boolean isPostCallSupported(){ + return mPostCallSupported; + } + + /** + * Sets post call as supported or not supported. + */ + public void setPostCallSupported(boolean postCallSupported) { + this.mPostCallSupported = postCallSupported; + } + + /** + * Checks whether shared map is supported. + */ + public boolean isSharedMapSupported() { + return mSharedMapSupported; + } + + /** + * Sets shared map as supported or not supported. + */ + public void setSharedMapSupported(boolean sharedMapSupported) { + this.mSharedMapSupported = sharedMapSupported; + } + + /** + * Checks whether shared sketch is supported. + */ + public boolean isSharedSketchSupported() { + return mSharedSketchSupported; + } + + /** + * Sets shared sketch as supported or not supported. + */ + public void setSharedSketchSupported(boolean sharedSketchSupported) { + this.mSharedSketchSupported = sharedSketchSupported; + } + + /** + * Checks whether chatbot communication is supported. + */ + public boolean isChatbotSupported() { + return mChatbotSupported; + } + + /** + * Sets chatbot communication as supported or not supported. + */ + public void setChatbotSupported(boolean chatbotSupported) { + this.mChatbotSupported = chatbotSupported; + } + + /** + * Checks whether chatbot role is supported. + */ + public boolean isChatbotRoleSupported() { + return mChatbotRoleSupported; + } + + /** + * Sets chatbot role as supported or not supported. + */ + public void setChatbotRoleSupported(boolean chatbotRoleSupported) { + this.mChatbotRoleSupported = chatbotRoleSupported; + } + /** Gets the list of supported extensions. */ public String[] getExts() { return mExts; @@ -435,6 +546,13 @@ public class CapInfo implements Parcelable { dest.writeInt(mGeoPushSupported ? 1 : 0); dest.writeInt(mSmSupported ? 1 : 0); dest.writeInt(mFullSnFGroupChatSupported ? 1 : 0); + dest.writeInt(mGeoSmsSupported ? 1 : 0); + dest.writeInt(mCallComposerSupported ? 1 : 0); + dest.writeInt(mPostCallSupported ? 1 : 0); + dest.writeInt(mSharedMapSupported ? 1 : 0); + dest.writeInt(mSharedSketchSupported ? 1 : 0); + dest.writeInt(mChatbotSupported ? 1 : 0); + dest.writeInt(mChatbotRoleSupported ? 1 : 0); dest.writeInt(mRcsIpVoiceCallSupported ? 1 : 0); dest.writeInt(mRcsIpVideoCallSupported ? 1 : 0); @@ -477,6 +595,13 @@ public class CapInfo implements Parcelable { mGeoPushSupported = (source.readInt() == 0) ? false : true; mSmSupported = (source.readInt() == 0) ? false : true; mFullSnFGroupChatSupported = (source.readInt() == 0) ? false : true; + mGeoSmsSupported = (source.readInt() == 0) ? false : true; + mCallComposerSupported = (source.readInt() == 0) ? false : true; + mPostCallSupported = (source.readInt() == 0) ? false : true; + mSharedMapSupported = (source.readInt() == 0) ? false : true; + mSharedSketchSupported = (source.readInt() == 0) ? false : true; + mChatbotSupported = (source.readInt() == 0) ? false : true; + mChatbotRoleSupported = (source.readInt() == 0) ? false : true; mRcsIpVoiceCallSupported = (source.readInt() == 0) ? false : true; mRcsIpVideoCallSupported = (source.readInt() == 0) ? false : true; diff --git a/core/java/com/android/ims/internal/uce/common/StatusCode.java b/core/java/com/android/ims/internal/uce/common/StatusCode.java index 7250eee70ecb..7f69493aa284 100644 --- a/core/java/com/android/ims/internal/uce/common/StatusCode.java +++ b/core/java/com/android/ims/internal/uce/common/StatusCode.java @@ -16,10 +16,9 @@ package com.android.ims.internal.uce.common; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.os.Parcel; import android.os.Parcelable; -import android.util.Log; /** Class for UCE status codes. diff --git a/core/java/com/android/ims/internal/uce/common/UceLong.java b/core/java/com/android/ims/internal/uce/common/UceLong.java index 720789918e45..bf514471b506 100644 --- a/core/java/com/android/ims/internal/uce/common/UceLong.java +++ b/core/java/com/android/ims/internal/uce/common/UceLong.java @@ -16,10 +16,9 @@ package com.android.ims.internal.uce.common; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.os.Parcel; import android.os.Parcelable; -import android.util.Log; /** Simple object wrapper for a long type. diff --git a/core/java/com/android/ims/internal/uce/options/OptionsCapInfo.java b/core/java/com/android/ims/internal/uce/options/OptionsCapInfo.java index bcb9f2d6284d..1da5a2439f02 100644 --- a/core/java/com/android/ims/internal/uce/options/OptionsCapInfo.java +++ b/core/java/com/android/ims/internal/uce/options/OptionsCapInfo.java @@ -15,11 +15,11 @@ */ package com.android.ims.internal.uce.options; -import android.annotation.UnsupportedAppUsage; -import com.android.ims.internal.uce.common.CapInfo; +import android.compat.annotation.UnsupportedAppUsage; import android.os.Parcel; import android.os.Parcelable; -import android.util.Log; + +import com.android.ims.internal.uce.common.CapInfo; /** @hide */ public class OptionsCapInfo implements Parcelable { diff --git a/core/java/com/android/ims/internal/uce/options/OptionsCmdId.java b/core/java/com/android/ims/internal/uce/options/OptionsCmdId.java index 14c64ac105bb..401ca2fa24ea 100644 --- a/core/java/com/android/ims/internal/uce/options/OptionsCmdId.java +++ b/core/java/com/android/ims/internal/uce/options/OptionsCmdId.java @@ -17,7 +17,7 @@ package com.android.ims.internal.uce.options; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.os.Parcel; import android.os.Parcelable; diff --git a/core/java/com/android/ims/internal/uce/options/OptionsCmdStatus.java b/core/java/com/android/ims/internal/uce/options/OptionsCmdStatus.java index 4af3e6e3cea4..70a7a84d3820 100644 --- a/core/java/com/android/ims/internal/uce/options/OptionsCmdStatus.java +++ b/core/java/com/android/ims/internal/uce/options/OptionsCmdStatus.java @@ -16,13 +16,13 @@ package com.android.ims.internal.uce.options; -import com.android.ims.internal.uce.common.StatusCode; -import com.android.ims.internal.uce.common.CapInfo; - -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.os.Parcel; import android.os.Parcelable; +import com.android.ims.internal.uce.common.CapInfo; +import com.android.ims.internal.uce.common.StatusCode; + /** @hide */ public class OptionsCmdStatus implements Parcelable { diff --git a/core/java/com/android/ims/internal/uce/options/OptionsSipResponse.java b/core/java/com/android/ims/internal/uce/options/OptionsSipResponse.java index c5f333d35ba5..5afddf0c42c0 100644 --- a/core/java/com/android/ims/internal/uce/options/OptionsSipResponse.java +++ b/core/java/com/android/ims/internal/uce/options/OptionsSipResponse.java @@ -16,7 +16,7 @@ package com.android.ims.internal.uce.options; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.os.Parcel; import android.os.Parcelable; diff --git a/core/java/com/android/ims/internal/uce/presence/PresCapInfo.java b/core/java/com/android/ims/internal/uce/presence/PresCapInfo.java index 745df5b71aa7..1a3a028713f6 100644 --- a/core/java/com/android/ims/internal/uce/presence/PresCapInfo.java +++ b/core/java/com/android/ims/internal/uce/presence/PresCapInfo.java @@ -16,12 +16,12 @@ package com.android.ims.internal.uce.presence; -import com.android.ims.internal.uce.common.CapInfo; - -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.os.Parcel; import android.os.Parcelable; +import com.android.ims.internal.uce.common.CapInfo; + /** @hide */ public class PresCapInfo implements Parcelable { diff --git a/core/java/com/android/ims/internal/uce/presence/PresCmdId.java b/core/java/com/android/ims/internal/uce/presence/PresCmdId.java index 41020ec5b49b..fba0c77e8dbf 100644 --- a/core/java/com/android/ims/internal/uce/presence/PresCmdId.java +++ b/core/java/com/android/ims/internal/uce/presence/PresCmdId.java @@ -16,7 +16,7 @@ package com.android.ims.internal.uce.presence; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.os.Parcel; import android.os.Parcelable; diff --git a/core/java/com/android/ims/internal/uce/presence/PresCmdStatus.java b/core/java/com/android/ims/internal/uce/presence/PresCmdStatus.java index ff8069c569ff..fbc64b83a360 100644 --- a/core/java/com/android/ims/internal/uce/presence/PresCmdStatus.java +++ b/core/java/com/android/ims/internal/uce/presence/PresCmdStatus.java @@ -16,12 +16,12 @@ package com.android.ims.internal.uce.presence; -import com.android.ims.internal.uce.common.StatusCode; - -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.os.Parcel; import android.os.Parcelable; +import com.android.ims.internal.uce.common.StatusCode; + /** @hide */ public class PresCmdStatus implements Parcelable{ diff --git a/core/java/com/android/ims/internal/uce/presence/PresPublishTriggerType.java b/core/java/com/android/ims/internal/uce/presence/PresPublishTriggerType.java index 87193e36ce90..fdff86f9669f 100644 --- a/core/java/com/android/ims/internal/uce/presence/PresPublishTriggerType.java +++ b/core/java/com/android/ims/internal/uce/presence/PresPublishTriggerType.java @@ -16,7 +16,7 @@ package com.android.ims.internal.uce.presence; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.os.Parcel; import android.os.Parcelable; @@ -47,6 +47,10 @@ public class PresPublishTriggerType implements Parcelable { public static final int UCE_PRES_PUBLISH_TRIGGER_MOVE_TO_IWLAN = 8; /** Trigger is unknown. */ public static final int UCE_PRES_PUBLISH_TRIGGER_UNKNOWN = 9; + /** Move to 5G NR with VoPS disabled. */ + public static final int UCE_PRES_PUBLISH_TRIGGER_MOVE_TO_NR5G_VOPS_DISABLED = 10; + /** Move to 5G NR with VoPS enabled. */ + public static final int UCE_PRES_PUBLISH_TRIGGER_MOVE_TO_NR5G_VOPS_ENABLED = 11; @@ -113,4 +117,4 @@ public class PresPublishTriggerType implements Parcelable { public void readFromParcel(Parcel source) { mPublishTriggerType = source.readInt(); } -}
\ No newline at end of file +} diff --git a/core/java/com/android/ims/internal/uce/presence/PresResInfo.java b/core/java/com/android/ims/internal/uce/presence/PresResInfo.java index 237c9994451a..af9b0568d29b 100644 --- a/core/java/com/android/ims/internal/uce/presence/PresResInfo.java +++ b/core/java/com/android/ims/internal/uce/presence/PresResInfo.java @@ -16,7 +16,7 @@ package com.android.ims.internal.uce.presence; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.os.Parcel; import android.os.Parcelable; diff --git a/core/java/com/android/ims/internal/uce/presence/PresResInstanceInfo.java b/core/java/com/android/ims/internal/uce/presence/PresResInstanceInfo.java index 29699ea6c802..9f3725133452 100644 --- a/core/java/com/android/ims/internal/uce/presence/PresResInstanceInfo.java +++ b/core/java/com/android/ims/internal/uce/presence/PresResInstanceInfo.java @@ -16,9 +16,10 @@ package com.android.ims.internal.uce.presence; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.os.Parcel; import android.os.Parcelable; + import java.util.Arrays; /** @hide */ diff --git a/core/java/com/android/ims/internal/uce/presence/PresRlmiInfo.java b/core/java/com/android/ims/internal/uce/presence/PresRlmiInfo.java index ab46e4b6295e..65b9fdbbeb18 100644 --- a/core/java/com/android/ims/internal/uce/presence/PresRlmiInfo.java +++ b/core/java/com/android/ims/internal/uce/presence/PresRlmiInfo.java @@ -16,7 +16,7 @@ package com.android.ims.internal.uce.presence; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.os.Parcel; import android.os.Parcelable; diff --git a/core/java/com/android/ims/internal/uce/presence/PresServiceInfo.java b/core/java/com/android/ims/internal/uce/presence/PresServiceInfo.java index 83ba722fe2f1..5eafa0fde8cc 100644 --- a/core/java/com/android/ims/internal/uce/presence/PresServiceInfo.java +++ b/core/java/com/android/ims/internal/uce/presence/PresServiceInfo.java @@ -16,7 +16,7 @@ package com.android.ims.internal.uce.presence; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.os.Parcel; import android.os.Parcelable; diff --git a/core/java/com/android/ims/internal/uce/presence/PresSipResponse.java b/core/java/com/android/ims/internal/uce/presence/PresSipResponse.java index 5e4259297d74..45b02f31eddc 100644 --- a/core/java/com/android/ims/internal/uce/presence/PresSipResponse.java +++ b/core/java/com/android/ims/internal/uce/presence/PresSipResponse.java @@ -16,7 +16,7 @@ package com.android.ims.internal.uce.presence; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.os.Parcel; import android.os.Parcelable; diff --git a/core/java/com/android/ims/internal/uce/presence/PresSubscriptionState.java b/core/java/com/android/ims/internal/uce/presence/PresSubscriptionState.java index bee928c3280a..ab1e17c48e75 100644 --- a/core/java/com/android/ims/internal/uce/presence/PresSubscriptionState.java +++ b/core/java/com/android/ims/internal/uce/presence/PresSubscriptionState.java @@ -16,7 +16,7 @@ package com.android.ims.internal.uce.presence; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.os.Parcel; import android.os.Parcelable; diff --git a/core/java/com/android/ims/internal/uce/presence/PresTupleInfo.java b/core/java/com/android/ims/internal/uce/presence/PresTupleInfo.java index 7a47786b5af6..3608eb6a5e8a 100644 --- a/core/java/com/android/ims/internal/uce/presence/PresTupleInfo.java +++ b/core/java/com/android/ims/internal/uce/presence/PresTupleInfo.java @@ -16,7 +16,7 @@ package com.android.ims.internal.uce.presence; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.os.Parcel; import android.os.Parcelable; diff --git a/core/java/com/android/ims/internal/uce/uceservice/ImsUceManager.java b/core/java/com/android/ims/internal/uce/uceservice/ImsUceManager.java index 4b0b098d4e5b..9aee879f21da 100644 --- a/core/java/com/android/ims/internal/uce/uceservice/ImsUceManager.java +++ b/core/java/com/android/ims/internal/uce/uceservice/ImsUceManager.java @@ -18,16 +18,9 @@ package com.android.ims.internal.uce.uceservice; import android.content.Context; import android.content.Intent; - -import android.os.Handler; -import android.os.HandlerThread; import android.os.IBinder; -import android.os.Message; -import android.os.ServiceManager; import android.os.RemoteException; - -import java.util.HashMap; -import android.util.Log; +import android.os.ServiceManager; /** * ImsUceManager Declaration @@ -49,55 +42,25 @@ public class ImsUceManager { private IUceService mUceService = null; private UceServiceDeathRecipient mDeathReceipient = new UceServiceDeathRecipient(); private Context mContext; - private int mPhoneId; - /** - * Stores the UceManager instaces of Clients identified by - * phoneId - * @hide - */ - private static HashMap<Integer, ImsUceManager> sUceManagerInstances = - new HashMap<Integer, ImsUceManager>(); + private static final Object sLock = new Object(); + private static ImsUceManager sUceManager; public static final String ACTION_UCE_SERVICE_UP = "com.android.ims.internal.uce.UCE_SERVICE_UP"; public static final String ACTION_UCE_SERVICE_DOWN = "com.android.ims.internal.uce.UCE_SERVICE_DOWN"; - /** Uce Service status received in IUceListener.setStatus() - * callback - * @hide - */ - public static final int UCE_SERVICE_STATUS_FAILURE = 0; - /** indicate UI to call Presence/Options API. */ - public static final int UCE_SERVICE_STATUS_ON = 1; - /** Indicate UI destroy Presence/Options */ - public static final int UCE_SERVICE_STATUS_CLOSED = 2; - /** Service up and trying to register for network events */ - public static final int UCE_SERVICE_STATUS_READY = 3; - - /** - * Part of the ACTION_UCE_SERVICE_UP or _DOWN intents. A long - * value; the phone ID corresponding to the IMS service coming up or down. - * Internal use only. - * @hide - */ - public static final String EXTRA_PHONE_ID = "android:phone_id"; - /** * Gets the instance of UCE Manager * @hide */ - public static ImsUceManager getInstance(Context context, int phoneId) { - //if (DBG) Log.d (LOG_TAG, "GetInstance Called"); - synchronized (sUceManagerInstances) { - if (sUceManagerInstances.containsKey(phoneId)) { - return sUceManagerInstances.get(phoneId); - } else { - ImsUceManager uceMgr = new ImsUceManager(context, phoneId); - sUceManagerInstances.put(phoneId, uceMgr); - return uceMgr; + public static ImsUceManager getInstance(Context context) { + synchronized (sLock) { + if (sUceManager == null && context != null) { + sUceManager = new ImsUceManager(context); } + return sUceManager; } } @@ -105,10 +68,9 @@ public class ImsUceManager { * Constructor * @hide */ - private ImsUceManager(Context context, int phoneId) { + private ImsUceManager(Context context) { //if (DBG) Log.d (LOG_TAG, "Constructor"); mContext = context; - mPhoneId = phoneId; createUceService(true); } @@ -129,7 +91,7 @@ public class ImsUceManager { * Gets the UCE service name * @hide */ - private String getUceServiceName(int phoneId) { + private String getUceServiceName() { return UCE_SERVICE; } @@ -143,14 +105,14 @@ public class ImsUceManager { public void createUceService(boolean checkService) { //if (DBG) Log.d (LOG_TAG, "CreateUceService Called"); if (checkService) { - IBinder binder = ServiceManager.checkService(getUceServiceName(mPhoneId)); + IBinder binder = ServiceManager.checkService(getUceServiceName()); if (binder == null) { //if (DBG)Log.d (LOG_TAG, "Unable to find IBinder"); return; } } - IBinder b = ServiceManager.getService(getUceServiceName(mPhoneId)); + IBinder b = ServiceManager.getService(getUceServiceName()); if (b != null) { try { @@ -174,12 +136,10 @@ public class ImsUceManager { private class UceServiceDeathRecipient implements IBinder.DeathRecipient { @Override public void binderDied() { - //if (DBG) Log.d (LOG_TAG, "found IBinder/IUceService Service Died"); mUceService = null; if (mContext != null) { Intent intent = new Intent(ACTION_UCE_SERVICE_DOWN); - intent.putExtra(EXTRA_PHONE_ID, mPhoneId); mContext.sendBroadcast(new Intent(intent)); } } diff --git a/core/java/com/android/internal/app/AlertActivity.java b/core/java/com/android/internal/app/AlertActivity.java index 7307de5146f8..cfbb273acf31 100644 --- a/core/java/com/android/internal/app/AlertActivity.java +++ b/core/java/com/android/internal/app/AlertActivity.java @@ -16,9 +16,9 @@ package com.android.internal.app; -import android.annotation.UnsupportedAppUsage; import android.app.Activity; import android.app.Dialog; +import android.compat.annotation.UnsupportedAppUsage; import android.content.DialogInterface; import android.os.Bundle; import android.view.KeyEvent; diff --git a/core/java/com/android/internal/app/AlertController.java b/core/java/com/android/internal/app/AlertController.java index 3462e08a4c6a..a08bf9983924 100644 --- a/core/java/com/android/internal/app/AlertController.java +++ b/core/java/com/android/internal/app/AlertController.java @@ -18,14 +18,11 @@ package com.android.internal.app; import static android.view.ViewGroup.LayoutParams.MATCH_PARENT; -import com.android.internal.R; - import android.annotation.Nullable; -import android.annotation.UnsupportedAppUsage; import android.app.AlertDialog; +import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; import android.content.DialogInterface; -import android.content.res.Configuration; import android.content.res.TypedArray; import android.database.Cursor; import android.graphics.drawable.Drawable; @@ -33,7 +30,6 @@ import android.os.Handler; import android.os.Message; import android.text.Layout; import android.text.TextUtils; -import android.text.method.LinkMovementMethod; import android.text.method.MovementMethod; import android.util.AttributeSet; import android.util.TypedValue; @@ -46,7 +42,6 @@ import android.view.ViewGroup.LayoutParams; import android.view.ViewParent; import android.view.ViewStub; import android.view.Window; -import android.view.WindowInsets; import android.view.WindowManager; import android.widget.AdapterView; import android.widget.AdapterView.OnItemClickListener; @@ -63,6 +58,8 @@ import android.widget.ScrollView; import android.widget.SimpleCursorAdapter; import android.widget.TextView; +import com.android.internal.R; + import java.lang.ref.WeakReference; public class AlertController { diff --git a/core/java/com/android/internal/app/AssistUtils.java b/core/java/com/android/internal/app/AssistUtils.java index f8483091ba21..22a25646c99d 100644 --- a/core/java/com/android/internal/app/AssistUtils.java +++ b/core/java/com/android/internal/app/AssistUtils.java @@ -17,7 +17,7 @@ package com.android.internal.app; import android.annotation.NonNull; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.ComponentName; import android.content.Context; import android.content.pm.ApplicationInfo; diff --git a/core/java/com/android/internal/app/ChooserActivity.java b/core/java/com/android/internal/app/ChooserActivity.java index 102ba5c2ec5e..c0c9dd32a52a 100644 --- a/core/java/com/android/internal/app/ChooserActivity.java +++ b/core/java/com/android/internal/app/ChooserActivity.java @@ -26,7 +26,6 @@ import android.animation.ValueAnimator; import android.annotation.IntDef; import android.annotation.NonNull; import android.annotation.Nullable; -import android.annotation.UnsupportedAppUsage; import android.app.Activity; import android.app.ActivityManager; import android.app.prediction.AppPredictionContext; @@ -34,6 +33,7 @@ import android.app.prediction.AppPredictionManager; import android.app.prediction.AppPredictor; import android.app.prediction.AppTarget; import android.app.prediction.AppTargetEvent; +import android.compat.annotation.UnsupportedAppUsage; import android.content.ClipData; import android.content.ClipboardManager; import android.content.ComponentName; diff --git a/core/java/com/android/internal/app/IntentForwarderActivity.java b/core/java/com/android/internal/app/IntentForwarderActivity.java index a5f055f09562..9488e4f3b297 100644 --- a/core/java/com/android/internal/app/IntentForwarderActivity.java +++ b/core/java/com/android/internal/app/IntentForwarderActivity.java @@ -20,12 +20,12 @@ import static android.content.pm.PackageManager.MATCH_DEFAULT_ONLY; import android.annotation.Nullable; import android.annotation.StringRes; -import android.annotation.UnsupportedAppUsage; import android.app.Activity; import android.app.ActivityTaskManager; import android.app.ActivityThread; import android.app.AppGlobals; import android.app.admin.DevicePolicyManager; +import android.compat.annotation.UnsupportedAppUsage; import android.content.Intent; import android.content.pm.ActivityInfo; import android.content.pm.IPackageManager; diff --git a/core/java/com/android/internal/app/LocaleHelper.java b/core/java/com/android/internal/app/LocaleHelper.java index e3d07aaa8fe8..d418770e00bf 100644 --- a/core/java/com/android/internal/app/LocaleHelper.java +++ b/core/java/com/android/internal/app/LocaleHelper.java @@ -17,7 +17,7 @@ package com.android.internal.app; import android.annotation.IntRange; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.icu.text.ListFormatter; import android.icu.util.ULocale; import android.os.LocaleList; diff --git a/core/java/com/android/internal/app/LocalePicker.java b/core/java/com/android/internal/app/LocalePicker.java index 75174246cd99..3343593f2bc3 100644 --- a/core/java/com/android/internal/app/LocalePicker.java +++ b/core/java/com/android/internal/app/LocalePicker.java @@ -16,13 +16,11 @@ package com.android.internal.app; -import com.android.internal.R; - -import android.annotation.UnsupportedAppUsage; import android.app.ActivityManager; import android.app.IActivityManager; import android.app.ListFragment; import android.app.backup.BackupManager; +import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; import android.content.res.Configuration; import android.content.res.Resources; @@ -38,11 +36,13 @@ import android.widget.ArrayAdapter; import android.widget.ListView; import android.widget.TextView; +import com.android.internal.R; + import java.text.Collator; +import java.util.ArrayList; import java.util.Collections; import java.util.List; import java.util.Locale; -import java.util.ArrayList; public class LocalePicker extends ListFragment { private static final String TAG = "LocalePicker"; diff --git a/core/java/com/android/internal/app/LocaleStore.java b/core/java/com/android/internal/app/LocaleStore.java index 49f77e11cf80..1c5ca593ebba 100644 --- a/core/java/com/android/internal/app/LocaleStore.java +++ b/core/java/com/android/internal/app/LocaleStore.java @@ -16,7 +16,7 @@ package com.android.internal.app; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; import android.os.LocaleList; import android.provider.Settings; diff --git a/core/java/com/android/internal/app/NetInitiatedActivity.java b/core/java/com/android/internal/app/NetInitiatedActivity.java index 9a802a9c0fa9..89aa770d7f1c 100644 --- a/core/java/com/android/internal/app/NetInitiatedActivity.java +++ b/core/java/com/android/internal/app/NetInitiatedActivity.java @@ -16,19 +16,19 @@ package com.android.internal.app; -import android.annotation.UnsupportedAppUsage; import android.app.AlertDialog; +import android.compat.annotation.UnsupportedAppUsage; import android.content.BroadcastReceiver; import android.content.Context; import android.content.DialogInterface; import android.content.Intent; import android.content.IntentFilter; +import android.location.LocationManager; import android.os.Bundle; import android.os.Handler; import android.os.Message; -import android.widget.Toast; import android.util.Log; -import android.location.LocationManager; +import android.widget.Toast; import com.android.internal.R; import com.android.internal.location.GpsNetInitiatedHandler; diff --git a/core/java/com/android/internal/app/ResolverActivity.java b/core/java/com/android/internal/app/ResolverActivity.java index 7d19eb6f54cd..871e4f84f3b6 100644 --- a/core/java/com/android/internal/app/ResolverActivity.java +++ b/core/java/com/android/internal/app/ResolverActivity.java @@ -21,7 +21,6 @@ import static android.content.Intent.FLAG_ACTIVITY_NEW_TASK; import android.annotation.Nullable; import android.annotation.StringRes; import android.annotation.UiThread; -import android.annotation.UnsupportedAppUsage; import android.app.Activity; import android.app.ActivityManager; import android.app.ActivityTaskManager; @@ -29,6 +28,7 @@ import android.app.ActivityThread; import android.app.VoiceInteractor.PickOptionRequest; import android.app.VoiceInteractor.PickOptionRequest.Option; import android.app.VoiceInteractor.Prompt; +import android.compat.annotation.UnsupportedAppUsage; import android.content.ComponentName; import android.content.Context; import android.content.Intent; diff --git a/core/java/com/android/internal/app/WindowDecorActionBar.java b/core/java/com/android/internal/app/WindowDecorActionBar.java index e71ee66c677c..0cd12022e17d 100644 --- a/core/java/com/android/internal/app/WindowDecorActionBar.java +++ b/core/java/com/android/internal/app/WindowDecorActionBar.java @@ -16,28 +16,17 @@ package com.android.internal.app; -import com.android.internal.R; -import com.android.internal.view.ActionBarPolicy; -import com.android.internal.view.menu.MenuBuilder; -import com.android.internal.view.menu.MenuPopupHelper; -import com.android.internal.view.menu.SubMenuBuilder; -import com.android.internal.widget.ActionBarContainer; -import com.android.internal.widget.ActionBarContextView; -import com.android.internal.widget.ActionBarOverlayLayout; -import com.android.internal.widget.DecorToolbar; -import com.android.internal.widget.ScrollingTabContainerView; - import android.animation.Animator; import android.animation.Animator.AnimatorListener; import android.animation.AnimatorListenerAdapter; import android.animation.AnimatorSet; import android.animation.ObjectAnimator; import android.animation.ValueAnimator; -import android.annotation.UnsupportedAppUsage; import android.app.ActionBar; import android.app.Activity; import android.app.Dialog; import android.app.FragmentTransaction; +import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; import android.content.res.Configuration; import android.content.res.Resources; @@ -58,6 +47,17 @@ import android.view.animation.AnimationUtils; import android.widget.SpinnerAdapter; import android.widget.Toolbar; +import com.android.internal.R; +import com.android.internal.view.ActionBarPolicy; +import com.android.internal.view.menu.MenuBuilder; +import com.android.internal.view.menu.MenuPopupHelper; +import com.android.internal.view.menu.SubMenuBuilder; +import com.android.internal.widget.ActionBarContainer; +import com.android.internal.widget.ActionBarContextView; +import com.android.internal.widget.ActionBarOverlayLayout; +import com.android.internal.widget.DecorToolbar; +import com.android.internal.widget.ScrollingTabContainerView; + import java.lang.ref.WeakReference; import java.util.ArrayList; diff --git a/core/java/com/android/internal/compat/AndroidBuildClassifier.java b/core/java/com/android/internal/compat/AndroidBuildClassifier.java new file mode 100644 index 000000000000..0b937fad7df1 --- /dev/null +++ b/core/java/com/android/internal/compat/AndroidBuildClassifier.java @@ -0,0 +1,34 @@ +/* + * 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.compat; + +import android.os.Build; + +/** + * Platform private class for determining the type of Android build installed. + * + */ +public class AndroidBuildClassifier { + + public boolean isDebuggableBuild() { + return Build.IS_DEBUGGABLE; + } + + public boolean isFinalBuild() { + return "REL".equals(Build.VERSION.CODENAME); + } +} diff --git a/core/java/com/android/internal/compat/IOverrideValidator.aidl b/core/java/com/android/internal/compat/IOverrideValidator.aidl new file mode 100644 index 000000000000..add4708863aa --- /dev/null +++ b/core/java/com/android/internal/compat/IOverrideValidator.aidl @@ -0,0 +1,38 @@ +/* + * 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.compat; + +import android.content.pm.ApplicationInfo; + +import com.android.internal.compat.OverrideAllowedState; + +/** + * Platform private API for determining whether a changeId can be overridden. + * + * {@hide} + */ +interface IOverrideValidator +{ + /** + * Validation function. + * @param changeId id of the change to be toggled on or off. + * @param packageName package of the app for which the change should be overridden. + * @return {@link OverrideAllowedState} specifying whether the change can be overridden for + * the given package or a reason why not. + */ + OverrideAllowedState getOverrideAllowedState(long changeId, String packageName); +} diff --git a/core/java/com/android/internal/compat/IPlatformCompat.aidl b/core/java/com/android/internal/compat/IPlatformCompat.aidl index 7dcb12c9e72b..4c203d394759 100644 --- a/core/java/com/android/internal/compat/IPlatformCompat.aidl +++ b/core/java/com/android/internal/compat/IPlatformCompat.aidl @@ -17,6 +17,7 @@ package com.android.internal.compat; import android.content.pm.ApplicationInfo; +import com.android.internal.compat.IOverrideValidator; import java.util.Map; parcelable CompatibilityChangeConfig; @@ -195,4 +196,9 @@ interface IPlatformCompat * @return An array of {@link CompatChangeInfo} known to the service. */ CompatibilityChangeInfo[] listAllChanges(); + + /** + * Get an instance that can determine whether a changeid can be overridden for a package name. + */ + IOverrideValidator getOverrideValidator(); } diff --git a/core/java/com/android/internal/compat/OverrideAllowedState.aidl b/core/java/com/android/internal/compat/OverrideAllowedState.aidl new file mode 100644 index 000000000000..10ceac786841 --- /dev/null +++ b/core/java/com/android/internal/compat/OverrideAllowedState.aidl @@ -0,0 +1,19 @@ +/* + * 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.compat; + +parcelable OverrideAllowedState;
\ No newline at end of file diff --git a/core/java/com/android/internal/compat/OverrideAllowedState.java b/core/java/com/android/internal/compat/OverrideAllowedState.java new file mode 100644 index 000000000000..56216c251070 --- /dev/null +++ b/core/java/com/android/internal/compat/OverrideAllowedState.java @@ -0,0 +1,153 @@ +/* + * 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.compat; + +import android.annotation.IntDef; +import android.annotation.NonNull; +import android.os.Parcel; +import android.os.Parcelable; + +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; + +/** + * This class contains all the possible override allowed states. + */ +public final class OverrideAllowedState implements Parcelable { + @IntDef({ + ALLOWED, + DISABLED_NOT_DEBUGGABLE, + DISABLED_NON_TARGET_SDK, + DISABLED_TARGET_SDK_TOO_HIGH, + PACKAGE_DOES_NOT_EXIST + }) + @Retention(RetentionPolicy.SOURCE) + public @interface State { + } + + /** + * Change can be overridden. + */ + public static final int ALLOWED = 0; + /** + * Change cannot be overridden, due to the app not being debuggable. + */ + public static final int DISABLED_NOT_DEBUGGABLE = 1; + /** + * Change cannot be overridden, due to the build being non-debuggable and the change being + * non-targetSdk. + */ + public static final int DISABLED_NON_TARGET_SDK = 2; + /** + * Change cannot be overridden, due to the app's targetSdk being above the change's targetSdk. + */ + public static final int DISABLED_TARGET_SDK_TOO_HIGH = 3; + /** + * Package does not exist. + */ + public static final int PACKAGE_DOES_NOT_EXIST = 4; + + @State + public final int state; + public final int appTargetSdk; + public final int changeIdTargetSdk; + + private OverrideAllowedState(Parcel parcel) { + state = parcel.readInt(); + appTargetSdk = parcel.readInt(); + changeIdTargetSdk = parcel.readInt(); + } + + public OverrideAllowedState(@State int state, int appTargetSdk, int changeIdTargetSdk) { + this.state = state; + this.appTargetSdk = appTargetSdk; + this.changeIdTargetSdk = changeIdTargetSdk; + } + + @Override + public int describeContents() { + return 0; + } + + @Override + public void writeToParcel(Parcel out, int flags) { + out.writeInt(state); + out.writeInt(appTargetSdk); + out.writeInt(changeIdTargetSdk); + } + + /** + * Enforces the policy for overriding compat changes. + * + * @param changeId the change id that was attempted to be overridden. + * @param packageName the package for which the attempt was made. + * @throws SecurityException if the policy forbids this operation. + */ + public void enforce(long changeId, String packageName) + throws SecurityException { + switch (state) { + case ALLOWED: + return; + case DISABLED_NOT_DEBUGGABLE: + throw new SecurityException( + "Cannot override a change on a non-debuggable app and user build."); + case DISABLED_NON_TARGET_SDK: + throw new SecurityException( + "Cannot override a default enabled/disabled change on a user build."); + case DISABLED_TARGET_SDK_TOO_HIGH: + throw new SecurityException(String.format( + "Cannot override %1$d for %2$s because the app's targetSdk (%3$d) is " + + "above the change's targetSdk threshold (%4$d)", + changeId, packageName, appTargetSdk, changeIdTargetSdk)); + case PACKAGE_DOES_NOT_EXIST: + throw new SecurityException(String.format( + "Cannot override %1$d for %2$s because the package does not exist, and " + + "the change is targetSdk gated.", + changeId, packageName)); + } + } + + public static final @NonNull + Parcelable.Creator<OverrideAllowedState> CREATOR = + new Parcelable.Creator<OverrideAllowedState>() { + public OverrideAllowedState createFromParcel(Parcel parcel) { + OverrideAllowedState info = new OverrideAllowedState(parcel); + return info; + } + + public OverrideAllowedState[] newArray(int size) { + return new OverrideAllowedState[size]; + } + }; + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj == null) { + return false; + } + if (!(obj instanceof OverrideAllowedState)) { + return false; + } + OverrideAllowedState otherState = (OverrideAllowedState) obj; + return state == otherState.state + && appTargetSdk == otherState.appTargetSdk + && changeIdTargetSdk == otherState.changeIdTargetSdk; + } +} diff --git a/core/java/com/android/internal/content/PackageMonitor.java b/core/java/com/android/internal/content/PackageMonitor.java index 5d7d3af8750a..9baa6fbb9217 100644 --- a/core/java/com/android/internal/content/PackageMonitor.java +++ b/core/java/com/android/internal/content/PackageMonitor.java @@ -16,8 +16,8 @@ package com.android.internal.content; -import android.annotation.UnsupportedAppUsage; import android.app.Activity; +import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; diff --git a/core/java/com/android/internal/content/ReferrerIntent.java b/core/java/com/android/internal/content/ReferrerIntent.java index 6d05f7e72a7a..6af03dd29899 100644 --- a/core/java/com/android/internal/content/ReferrerIntent.java +++ b/core/java/com/android/internal/content/ReferrerIntent.java @@ -16,7 +16,7 @@ package com.android.internal.content; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.Intent; import android.os.Parcel; diff --git a/core/java/com/android/internal/database/SortCursor.java b/core/java/com/android/internal/database/SortCursor.java index 7fe809ee319b..230a9b87727a 100644 --- a/core/java/com/android/internal/database/SortCursor.java +++ b/core/java/com/android/internal/database/SortCursor.java @@ -16,7 +16,7 @@ package com.android.internal.database; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.database.AbstractCursor; import android.database.Cursor; import android.database.DataSetObserver; diff --git a/core/java/com/android/internal/logging/MetricsLogger.java b/core/java/com/android/internal/logging/MetricsLogger.java index f916cf64564d..ed04fd83a515 100644 --- a/core/java/com/android/internal/logging/MetricsLogger.java +++ b/core/java/com/android/internal/logging/MetricsLogger.java @@ -15,7 +15,7 @@ */ package com.android.internal.logging; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; import android.metrics.LogMaker; import android.os.Build; diff --git a/core/java/com/android/internal/net/LegacyVpnInfo.java b/core/java/com/android/internal/net/LegacyVpnInfo.java index 2ad9759b1f68..4eb7dede7769 100644 --- a/core/java/com/android/internal/net/LegacyVpnInfo.java +++ b/core/java/com/android/internal/net/LegacyVpnInfo.java @@ -16,8 +16,8 @@ package com.android.internal.net; -import android.annotation.UnsupportedAppUsage; import android.app.PendingIntent; +import android.compat.annotation.UnsupportedAppUsage; import android.net.NetworkInfo; import android.os.Parcel; import android.os.Parcelable; diff --git a/core/java/com/android/internal/net/VpnConfig.java b/core/java/com/android/internal/net/VpnConfig.java index e6be54964705..f5a19fe73a86 100644 --- a/core/java/com/android/internal/net/VpnConfig.java +++ b/core/java/com/android/internal/net/VpnConfig.java @@ -16,8 +16,8 @@ package com.android.internal.net; -import android.annotation.UnsupportedAppUsage; import android.app.PendingIntent; +import android.compat.annotation.UnsupportedAppUsage; import android.content.ComponentName; import android.content.Context; import android.content.Intent; diff --git a/core/java/com/android/internal/net/VpnProfile.java b/core/java/com/android/internal/net/VpnProfile.java index 940cc363f742..4bb012aac769 100644 --- a/core/java/com/android/internal/net/VpnProfile.java +++ b/core/java/com/android/internal/net/VpnProfile.java @@ -16,10 +16,9 @@ package com.android.internal.net; -import android.annotation.UnsupportedAppUsage; -import android.os.Build; +import android.compat.annotation.UnsupportedAppUsage; import android.net.ProxyInfo; -import android.net.Uri; +import android.os.Build; import android.os.Parcel; import android.os.Parcelable; import android.text.TextUtils; diff --git a/core/java/com/android/internal/os/AndroidPrintStream.java b/core/java/com/android/internal/os/AndroidPrintStream.java index fe2341144d28..a6e41ff02d12 100644 --- a/core/java/com/android/internal/os/AndroidPrintStream.java +++ b/core/java/com/android/internal/os/AndroidPrintStream.java @@ -16,7 +16,7 @@ package com.android.internal.os; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.util.Log; /** diff --git a/core/java/com/android/internal/os/AtomicFile.java b/core/java/com/android/internal/os/AtomicFile.java index a72a2f5e1be3..80b3314bf3d3 100644 --- a/core/java/com/android/internal/os/AtomicFile.java +++ b/core/java/com/android/internal/os/AtomicFile.java @@ -16,7 +16,7 @@ package com.android.internal.os; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.os.Build; import android.os.FileUtils; import android.util.Log; diff --git a/core/java/com/android/internal/os/BaseCommand.java b/core/java/com/android/internal/os/BaseCommand.java index 5ba662913529..db87f51cf6db 100644 --- a/core/java/com/android/internal/os/BaseCommand.java +++ b/core/java/com/android/internal/os/BaseCommand.java @@ -17,7 +17,7 @@ package com.android.internal.os; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.os.ShellCommand; import java.io.PrintStream; diff --git a/core/java/com/android/internal/os/BatterySipper.java b/core/java/com/android/internal/os/BatterySipper.java index b1fc369835c6..b3ea118d9c73 100644 --- a/core/java/com/android/internal/os/BatterySipper.java +++ b/core/java/com/android/internal/os/BatterySipper.java @@ -15,7 +15,7 @@ */ package com.android.internal.os; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.os.BatteryStats.Uid; import java.util.List; diff --git a/core/java/com/android/internal/os/BatteryStatsHelper.java b/core/java/com/android/internal/os/BatteryStatsHelper.java index e85508ed7891..b131ab83cc79 100644 --- a/core/java/com/android/internal/os/BatteryStatsHelper.java +++ b/core/java/com/android/internal/os/BatteryStatsHelper.java @@ -16,7 +16,7 @@ package com.android.internal.os; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; diff --git a/core/java/com/android/internal/os/BatteryStatsImpl.java b/core/java/com/android/internal/os/BatteryStatsImpl.java index 3bd0fd29c3f9..183c0fb70e27 100644 --- a/core/java/com/android/internal/os/BatteryStatsImpl.java +++ b/core/java/com/android/internal/os/BatteryStatsImpl.java @@ -18,10 +18,10 @@ package com.android.internal.os; import android.annotation.NonNull; import android.annotation.Nullable; -import android.annotation.UnsupportedAppUsage; import android.app.ActivityManager; import android.bluetooth.BluetoothActivityEnergyInfo; import android.bluetooth.UidTraffic; +import android.compat.annotation.UnsupportedAppUsage; import android.content.BroadcastReceiver; import android.content.ContentResolver; import android.content.Context; diff --git a/core/java/com/android/internal/os/BinderInternal.java b/core/java/com/android/internal/os/BinderInternal.java index 4901e1f67d92..95c36ca8429e 100644 --- a/core/java/com/android/internal/os/BinderInternal.java +++ b/core/java/com/android/internal/os/BinderInternal.java @@ -17,7 +17,7 @@ package com.android.internal.os; import android.annotation.NonNull; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.os.Binder; import android.os.Handler; import android.os.IBinder; diff --git a/core/java/com/android/internal/os/ClassLoaderFactory.java b/core/java/com/android/internal/os/ClassLoaderFactory.java index d32349834dd8..a18943c264f5 100644 --- a/core/java/com/android/internal/os/ClassLoaderFactory.java +++ b/core/java/com/android/internal/os/ClassLoaderFactory.java @@ -16,7 +16,7 @@ package com.android.internal.os; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.os.Trace; import dalvik.system.DelegateLastClassLoader; diff --git a/core/java/com/android/internal/os/FuseAppLoop.java b/core/java/com/android/internal/os/FuseAppLoop.java index d08930b007ff..f8f9fa9d0e70 100644 --- a/core/java/com/android/internal/os/FuseAppLoop.java +++ b/core/java/com/android/internal/os/FuseAppLoop.java @@ -18,17 +18,19 @@ package com.android.internal.os; import android.annotation.NonNull; import android.annotation.Nullable; -import android.annotation.UnsupportedAppUsage; -import android.os.ProxyFileDescriptorCallback; +import android.compat.annotation.UnsupportedAppUsage; import android.os.Handler; import android.os.Message; import android.os.ParcelFileDescriptor; +import android.os.ProxyFileDescriptorCallback; import android.system.ErrnoException; import android.system.OsConstants; import android.util.Log; import android.util.SparseArray; + import com.android.internal.annotations.GuardedBy; import com.android.internal.util.Preconditions; + import java.util.HashMap; import java.util.LinkedList; import java.util.Map; diff --git a/core/java/com/android/internal/os/HandlerCaller.java b/core/java/com/android/internal/os/HandlerCaller.java index c8bfa1b02e22..a11c815a94bc 100644 --- a/core/java/com/android/internal/os/HandlerCaller.java +++ b/core/java/com/android/internal/os/HandlerCaller.java @@ -16,7 +16,7 @@ package com.android.internal.os; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; import android.os.Handler; import android.os.Looper; diff --git a/core/java/com/android/internal/os/PowerProfile.java b/core/java/com/android/internal/os/PowerProfile.java index 8338d78af3a1..d3fe582ab4bd 100644 --- a/core/java/com/android/internal/os/PowerProfile.java +++ b/core/java/com/android/internal/os/PowerProfile.java @@ -17,7 +17,7 @@ package com.android.internal.os; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; import android.content.res.Resources; import android.content.res.XmlResourceParser; diff --git a/core/java/com/android/internal/os/ProcessCpuTracker.java b/core/java/com/android/internal/os/ProcessCpuTracker.java index dcf8d285eca9..f7b77422cdce 100644 --- a/core/java/com/android/internal/os/ProcessCpuTracker.java +++ b/core/java/com/android/internal/os/ProcessCpuTracker.java @@ -16,9 +16,14 @@ package com.android.internal.os; -import static android.os.Process.*; - -import android.annotation.UnsupportedAppUsage; +import static android.os.Process.PROC_COMBINE; +import static android.os.Process.PROC_OUT_FLOAT; +import static android.os.Process.PROC_OUT_LONG; +import static android.os.Process.PROC_OUT_STRING; +import static android.os.Process.PROC_PARENS; +import static android.os.Process.PROC_SPACE_TERM; + +import android.compat.annotation.UnsupportedAppUsage; import android.os.Process; import android.os.StrictMode; import android.os.SystemClock; diff --git a/core/java/com/android/internal/os/RuntimeInit.java b/core/java/com/android/internal/os/RuntimeInit.java index c230754a874c..13d0c5c831b6 100644 --- a/core/java/com/android/internal/os/RuntimeInit.java +++ b/core/java/com/android/internal/os/RuntimeInit.java @@ -16,10 +16,10 @@ package com.android.internal.os; -import android.annotation.UnsupportedAppUsage; import android.app.ActivityManager; import android.app.ActivityThread; import android.app.ApplicationErrorReport; +import android.compat.annotation.UnsupportedAppUsage; import android.content.type.DefaultMimeMapFactory; import android.os.Build; import android.os.DeadObjectException; diff --git a/core/java/com/android/internal/os/SomeArgs.java b/core/java/com/android/internal/os/SomeArgs.java index d78bfac1f878..003f61079dcf 100644 --- a/core/java/com/android/internal/os/SomeArgs.java +++ b/core/java/com/android/internal/os/SomeArgs.java @@ -16,7 +16,7 @@ package com.android.internal.os; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; /** * Helper class for passing more arguments though a message diff --git a/core/java/com/android/internal/os/Zygote.java b/core/java/com/android/internal/os/Zygote.java index 33adec106d97..fd9f025ce9ba 100644 --- a/core/java/com/android/internal/os/Zygote.java +++ b/core/java/com/android/internal/os/Zygote.java @@ -49,9 +49,9 @@ import java.io.InputStreamReader; /** @hide */ public final class Zygote { /* - * Bit values for "runtimeFlags" argument. The definitions are duplicated - * in the native code. - */ + * Bit values for "runtimeFlags" argument. The definitions are duplicated + * in the native code. + */ /** enable debugging over JDWP */ public static final int DEBUG_ENABLE_JDWP = 1; @@ -187,6 +187,11 @@ public final class Zygote { */ public static final int SOCKET_BUFFER_SIZE = 256; + /** + * @hide for internal use only + */ + private static final int PRIORITY_MAX = -20; + /** a prototype instance for a future List.toArray() */ protected static final int[][] INT_ARRAY_2D = new int[0][0]; @@ -251,8 +256,7 @@ public final class Zygote { int[] fdsToIgnore, boolean startChildZygote, String instructionSet, String appDataDir, int targetSdkVersion) { ZygoteHooks.preFork(); - // Resets nice priority for zygote process. - resetNicePriority(); + int pid = nativeForkAndSpecialize( uid, gid, gids, runtimeFlags, rlimits, mountExternal, seInfo, niceName, fdsToClose, fdsToIgnore, startChildZygote, instructionSet, appDataDir); @@ -264,6 +268,10 @@ public final class Zygote { // Note that this event ends at the end of handleChildProc, Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "PostFork"); } + + // Set the Java Language thread priority to the default value for new apps. + Thread.currentThread().setPriority(Thread.NORM_PRIORITY); + ZygoteHooks.postForkCommon(); return pid; } @@ -298,7 +306,7 @@ public final class Zygote { int[][] rlimits, int mountExternal, String seInfo, String niceName, boolean startChildZygote, String instructionSet, String appDataDir) { nativeSpecializeAppProcess(uid, gid, gids, runtimeFlags, rlimits, mountExternal, seInfo, - niceName, startChildZygote, instructionSet, appDataDir); + niceName, startChildZygote, instructionSet, appDataDir); // Enable tracing as soon as possible for the child process. Trace.setTracingEnabled(true, runtimeFlags); @@ -306,6 +314,9 @@ public final class Zygote { // Note that this event ends at the end of handleChildProc. Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "PostFork"); + // Set the Java Language thread priority to the default value for new apps. + Thread.currentThread().setPriority(Thread.NORM_PRIORITY); + /* * This is called here (instead of after the fork but before the specialize) to maintain * consistancy with the code paths for forkAndSpecialize. @@ -350,15 +361,19 @@ public final class Zygote { public static int forkSystemServer(int uid, int gid, int[] gids, int runtimeFlags, int[][] rlimits, long permittedCapabilities, long effectiveCapabilities) { ZygoteHooks.preFork(); - // Resets nice priority for zygote process. - resetNicePriority(); + int pid = nativeForkSystemServer( uid, gid, gids, runtimeFlags, rlimits, permittedCapabilities, effectiveCapabilities); + // Enable tracing as soon as we enter the system_server. if (pid == 0) { Trace.setTracingEnabled(true, runtimeFlags); } + + // Set the Java Language thread priority to the default value for new apps. + Thread.currentThread().setPriority(Thread.NORM_PRIORITY); + ZygoteHooks.postForkCommon(); return pid; } @@ -476,13 +491,16 @@ public final class Zygote { /** * Fork a new unspecialized app process from the zygote * + * @param usapPoolSocket The server socket the USAP will call accept on * @param sessionSocketRawFDs Anonymous session sockets that are currently open + * @param isPriorityFork Value controlling the process priority level until accept is called * @return In the Zygote process this function will always return null; in unspecialized app * processes this function will return a Runnable object representing the new * application that is passed up from usapMain. */ static Runnable forkUsap(LocalServerSocket usapPoolSocket, - int[] sessionSocketRawFDs) { + int[] sessionSocketRawFDs, + boolean isPriorityFork) { FileDescriptor[] pipeFDs = null; try { @@ -492,7 +510,8 @@ public final class Zygote { } int pid = - nativeForkUsap(pipeFDs[0].getInt$(), pipeFDs[1].getInt$(), sessionSocketRawFDs); + nativeForkUsap(pipeFDs[0].getInt$(), pipeFDs[1].getInt$(), + sessionSocketRawFDs, isPriorityFork); if (pid == 0) { IoUtils.closeQuietly(pipeFDs[0]); @@ -506,8 +525,9 @@ public final class Zygote { } private static native int nativeForkUsap(int readPipeFD, - int writePipeFD, - int[] sessionSocketRawFDs); + int writePipeFD, + int[] sessionSocketRawFDs, + boolean isPriorityFork); /** * This function is used by unspecialized app processes to wait for specialization requests from @@ -518,7 +538,7 @@ public final class Zygote { * @return A runnable oject representing the new application. */ private static Runnable usapMain(LocalServerSocket usapPoolSocket, - FileDescriptor writePipe) { + FileDescriptor writePipe) { final int pid = Process.myPid(); Process.setArgV0(Process.is64Bit() ? "usap64" : "usap32"); @@ -527,6 +547,11 @@ public final class Zygote { Credentials peerCredentials = null; ZygoteArguments args = null; + // Change the priority to max before calling accept so we can respond to new specialization + // requests as quickly as possible. This will be reverted to the default priority in the + // native specialization code. + boostUsapPriority(); + while (true) { try { sessionSocket = usapPoolSocket.accept(); @@ -568,6 +593,7 @@ public final class Zygote { try { // SIGTERM is blocked on loop exit. This prevents a USAP that is specializing from // being killed during a pool flush. + setAppProcessName(args, "USAP"); applyUidSecurityPolicy(args, peerCredentials); applyDebuggerSystemProperty(args); @@ -628,23 +654,18 @@ public final class Zygote { } specializeAppProcess(args.mUid, args.mGid, args.mGids, - args.mRuntimeFlags, rlimits, args.mMountExternal, - args.mSeInfo, args.mNiceName, args.mStartChildZygote, - args.mInstructionSet, args.mAppDataDir); + args.mRuntimeFlags, rlimits, args.mMountExternal, + args.mSeInfo, args.mNiceName, args.mStartChildZygote, + args.mInstructionSet, args.mAppDataDir); disableExecuteOnly(args.mTargetSdkVersion); - if (args.mNiceName != null) { - Process.setArgV0(args.mNiceName); - } - - // End of the postFork event. Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER); return ZygoteInit.zygoteInit(args.mTargetSdkVersion, - args.mDisabledCompatChanges, - args.mRemainingArgs, - null /* classLoader */); + args.mDisabledCompatChanges, + args.mRemainingArgs, + null /* classLoader */); } finally { // Unblock SIGTERM to restore the process to default behavior. unblockSigTerm(); @@ -663,6 +684,22 @@ public final class Zygote { private static native void nativeUnblockSigTerm(); + private static void boostUsapPriority() { + nativeBoostUsapPriority(); + } + + private static native void nativeBoostUsapPriority(); + + static void setAppProcessName(ZygoteArguments args, String loggingTag) { + if (args.mNiceName != null) { + Process.setArgV0(args.mNiceName); + } else if (args.mPackageName != null) { + Process.setArgV0(args.mPackageName); + } else { + Log.w(loggingTag, "Unable to set package name."); + } + } + private static final String USAP_ERROR_PREFIX = "Invalid command to USAP: "; /** @@ -685,7 +722,7 @@ public final class Zygote { throw new IllegalArgumentException(USAP_ERROR_PREFIX + "--start-child-zygote"); } else if (args.mApiBlacklistExemptions != null) { throw new IllegalArgumentException( - USAP_ERROR_PREFIX + "--set-api-blacklist-exemptions"); + USAP_ERROR_PREFIX + "--set-api-blacklist-exemptions"); } else if (args.mHiddenApiAccessLogSampleRate != -1) { throw new IllegalArgumentException( USAP_ERROR_PREFIX + "--hidden-api-log-sampling-rate="); @@ -696,8 +733,8 @@ public final class Zygote { throw new IllegalArgumentException(USAP_ERROR_PREFIX + "--invoke-with"); } else if (args.mPermittedCapabilities != 0 || args.mEffectiveCapabilities != 0) { throw new ZygoteSecurityException("Client may not specify capabilities: " - + "permitted=0x" + Long.toHexString(args.mPermittedCapabilities) - + ", effective=0x" + Long.toHexString(args.mEffectiveCapabilities)); + + "permitted=0x" + Long.toHexString(args.mPermittedCapabilities) + + ", effective=0x" + Long.toHexString(args.mEffectiveCapabilities)); } } @@ -754,7 +791,7 @@ public final class Zygote { if (uidRestricted && args.mUidSpecified && (args.mUid < Process.SYSTEM_UID)) { throw new ZygoteSecurityException( "System UID may not launch process with UID < " - + Process.SYSTEM_UID); + + Process.SYSTEM_UID); } } @@ -804,8 +841,8 @@ public final class Zygote { if (args.mInvokeWith != null && peerUid != 0 && (args.mRuntimeFlags & Zygote.DEBUG_ENABLE_JDWP) == 0) { throw new ZygoteSecurityException("Peer is permitted to specify an " - + "explicit invoke-with wrapper command only for debuggable " - + "applications."); + + "explicit invoke-with wrapper command only for debuggable " + + "applications."); } } @@ -888,7 +925,7 @@ public final class Zygote { return new LocalServerSocket(fd); } catch (IOException ex) { throw new RuntimeException( - "Error building socket from file descriptor: " + fileDesc, ex); + "Error building socket from file descriptor: " + fileDesc, ex); } } @@ -903,15 +940,6 @@ public final class Zygote { } /** - * Resets the calling thread priority to the default value (Thread.NORM_PRIORITY - * or nice value 0). This updates both the priority value in java.lang.Thread and - * the nice value (setpriority). - */ - static void resetNicePriority() { - Thread.currentThread().setPriority(Thread.NORM_PRIORITY); - } - - /** * Executes "/system/bin/sh -c <command>" using the exec() system call. * This method throws a runtime exception if exec() failed, otherwise, this * method never returns. diff --git a/core/java/com/android/internal/os/ZygoteConnection.java b/core/java/com/android/internal/os/ZygoteConnection.java index 4c37591d4a66..2666d5278a90 100644 --- a/core/java/com/android/internal/os/ZygoteConnection.java +++ b/core/java/com/android/internal/os/ZygoteConnection.java @@ -23,7 +23,7 @@ import static android.system.OsConstants.POLLIN; import static com.android.internal.os.ZygoteConnectionConstants.CONNECTION_TIMEOUT_MILLIS; import static com.android.internal.os.ZygoteConnectionConstants.WRAPPED_PID_TIMEOUT_MILLIS; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.pm.ApplicationInfo; import android.net.Credentials; import android.net.LocalSocket; @@ -346,7 +346,7 @@ class ZygoteConnection { if (zygoteServer.isUsapPoolEnabled()) { Runnable fpResult = zygoteServer.fillUsapPool( - new int[]{mSocket.getFileDescriptor().getInt$()}); + new int[]{mSocket.getFileDescriptor().getInt$()}, false); if (fpResult != null) { zygoteServer.setForkChild(); @@ -485,9 +485,7 @@ class ZygoteConnection { closeSocket(); - if (parsedArgs.mNiceName != null) { - Process.setArgV0(parsedArgs.mNiceName); - } + Zygote.setAppProcessName(parsedArgs, TAG); // End of the postFork event. Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER); diff --git a/core/java/com/android/internal/os/ZygoteInit.java b/core/java/com/android/internal/os/ZygoteInit.java index 7b77a92e3d3a..348262e1a9d3 100644 --- a/core/java/com/android/internal/os/ZygoteInit.java +++ b/core/java/com/android/internal/os/ZygoteInit.java @@ -19,8 +19,8 @@ package com.android.internal.os; import static android.system.OsConstants.S_IRWXG; import static android.system.OsConstants.S_IRWXO; -import android.annotation.UnsupportedAppUsage; import android.app.ApplicationLoaders; +import android.compat.annotation.UnsupportedAppUsage; import android.content.pm.SharedLibraryInfo; import android.content.res.Resources; import android.content.res.TypedArray; @@ -825,6 +825,18 @@ public class ZygoteInit { return result; } + /** + * This is the entry point for a Zygote process. It creates the Zygote server, loads resources, + * and handles other tasks related to preparing the process for forking into applications. + * + * This process is started with a nice value of -20 (highest priority). All paths that flow + * into new processes are required to either set the priority to the default value or terminate + * before executing any non-system code. The native side of this occurs in SpecializeCommon, + * while the Java Language priority is changed in ZygoteInit.handleSystemServerProcess, + * ZygoteConnection.handleChildProc, and Zygote.usapMain. + * + * @param argv Command line arguments used to specify the Zygote's configuration. + */ @UnsupportedAppUsage public static void main(String argv[]) { ZygoteServer zygoteServer = null; @@ -888,8 +900,6 @@ public class ZygoteInit { EventLog.writeEvent(LOG_BOOT_PROGRESS_PRELOAD_END, SystemClock.uptimeMillis()); bootTimingsTraceLog.traceEnd(); // ZygotePreload - } else { - Zygote.resetNicePriority(); } // Do an initial gc to clean up after startup diff --git a/core/java/com/android/internal/os/ZygoteSecurityException.java b/core/java/com/android/internal/os/ZygoteSecurityException.java index 7e50cb885324..8111483b4a0f 100644 --- a/core/java/com/android/internal/os/ZygoteSecurityException.java +++ b/core/java/com/android/internal/os/ZygoteSecurityException.java @@ -16,7 +16,7 @@ package com.android.internal.os; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; /** * Exception thrown when a security policy is violated. diff --git a/core/java/com/android/internal/os/ZygoteServer.java b/core/java/com/android/internal/os/ZygoteServer.java index 1fd6e269348f..8d281b7ce9a0 100644 --- a/core/java/com/android/internal/os/ZygoteServer.java +++ b/core/java/com/android/internal/os/ZygoteServer.java @@ -66,6 +66,12 @@ class ZygoteServer { /** The default value used for the USAP_POOL_SIZE_MIN device property */ private static final String USAP_POOL_SIZE_MIN_DEFAULT = "1"; + /** The default value used for the USAP_REFILL_DELAY_MS device property */ + private static final String USAP_POOL_REFILL_DELAY_MS_DEFAULT = "3000"; + + /** The "not a timestamp" value for the refill delay timestamp mechanism. */ + private static final int INVALID_TIMESTAMP = -1; + /** * Indicates if this Zygote server can support a unspecialized app process pool. Currently this * should only be true for the primary and secondary Zygotes, and not the App Zygotes or the @@ -131,6 +137,24 @@ class ZygoteServer { */ private int mUsapPoolRefillThreshold = 0; + /** + * Number of milliseconds to delay before refilling the pool if it hasn't reached its + * minimum value. + */ + private int mUsapPoolRefillDelayMs = -1; + + /** + * If and when we should refill the USAP pool. + */ + private UsapPoolRefillAction mUsapPoolRefillAction; + private long mUsapPoolRefillTriggerTimestamp; + + private enum UsapPoolRefillAction { + DELAYED, + IMMEDIATE, + NONE + } + ZygoteServer() { mUsapPoolEventFD = null; mZygoteSocket = null; @@ -160,9 +184,8 @@ class ZygoteServer { Zygote.USAP_POOL_SECONDARY_SOCKET_NAME); } - fetchUsapPoolPolicyProps(); - mUsapPoolSupported = true; + fetchUsapPoolPolicyProps(); } void setForkChild() { @@ -267,6 +290,13 @@ class ZygoteServer { mUsapPoolSizeMax); } + final String usapPoolRefillDelayMsPropString = Zygote.getConfigurationProperty( + ZygoteConfig.USAP_POOL_REFILL_DELAY_MS, USAP_POOL_REFILL_DELAY_MS_DEFAULT); + + if (!usapPoolRefillDelayMsPropString.isEmpty()) { + mUsapPoolRefillDelayMs = Integer.parseInt(usapPoolRefillDelayMsPropString); + } + // Sanity check if (mUsapPoolSizeMin >= mUsapPoolSizeMax) { Log.w(TAG, "The max size of the USAP pool must be greater than the minimum size." @@ -293,9 +323,16 @@ class ZygoteServer { } } + private void fetchUsapPoolPolicyPropsIfUnfetched() { + if (mIsFirstPropertyCheck) { + mIsFirstPropertyCheck = false; + fetchUsapPoolPolicyProps(); + } + } + /** - * Checks to see if the current policy says that pool should be refilled, and spawns new USAPs - * if necessary. + * Refill the USAP Pool to the appropriate level, determined by whether this is a priority + * refill event or not. * * @param sessionSocketRawFDs Anonymous session sockets that are currently open * @return In the Zygote process this function will always return null; in unspecialized app @@ -303,38 +340,47 @@ class ZygoteServer { * application that is passed up from usapMain. */ - Runnable fillUsapPool(int[] sessionSocketRawFDs) { + Runnable fillUsapPool(int[] sessionSocketRawFDs, boolean isPriorityRefill) { Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "Zygote:FillUsapPool"); // Ensure that the pool properties have been fetched. - fetchUsapPoolPolicyPropsWithMinInterval(); + fetchUsapPoolPolicyPropsIfUnfetched(); int usapPoolCount = Zygote.getUsapPoolCount(); - int numUsapsToSpawn = mUsapPoolSizeMax - usapPoolCount; + int numUsapsToSpawn; + + if (isPriorityRefill) { + // Refill to min + numUsapsToSpawn = mUsapPoolSizeMin - usapPoolCount; + + Log.i("zygote", + "Priority USAP Pool refill. New USAPs: " + numUsapsToSpawn); + } else { + // Refill up to max + numUsapsToSpawn = mUsapPoolSizeMax - usapPoolCount; - if (usapPoolCount < mUsapPoolSizeMin - || numUsapsToSpawn >= mUsapPoolRefillThreshold) { + Log.i("zygote", + "Delayed USAP Pool refill. New USAPs: " + numUsapsToSpawn); + } - // Disable some VM functionality and reset some system values - // before forking. - ZygoteHooks.preFork(); - Zygote.resetNicePriority(); + // Disable some VM functionality and reset some system values + // before forking. + ZygoteHooks.preFork(); - while (usapPoolCount++ < mUsapPoolSizeMax) { - Runnable caller = Zygote.forkUsap(mUsapPoolSocket, sessionSocketRawFDs); + while (--numUsapsToSpawn >= 0) { + Runnable caller = + Zygote.forkUsap(mUsapPoolSocket, sessionSocketRawFDs, isPriorityRefill); - if (caller != null) { - return caller; - } + if (caller != null) { + return caller; } + } - // Re-enable runtime services for the Zygote. Services for unspecialized app process - // are re-enabled in specializeAppProcess. - ZygoteHooks.postForkCommon(); + // Re-enable runtime services for the Zygote. Services for unspecialized app process + // are re-enabled in specializeAppProcess. + ZygoteHooks.postForkCommon(); - Log.i("zygote", - "Filled the USAP pool. New USAPs: " + numUsapsToSpawn); - } + resetUsapRefillState(); Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER); @@ -358,13 +404,18 @@ class ZygoteServer { mUsapPoolEnabled = newStatus; if (newStatus) { - return fillUsapPool(new int[]{ sessionSocket.getFileDescriptor().getInt$() }); + return fillUsapPool(new int[]{ sessionSocket.getFileDescriptor().getInt$() }, false); } else { Zygote.emptyUsapPool(); return null; } } + void resetUsapRefillState() { + mUsapPoolRefillAction = UsapPoolRefillAction.NONE; + mUsapPoolRefillTriggerTimestamp = INVALID_TIMESTAMP; + } + /** * Runs the zygote process's select loop. Accepts new connections as * they happen, and reads commands from connections one spawn-request's @@ -377,8 +428,11 @@ class ZygoteServer { socketFDs.add(mZygoteSocket.getFileDescriptor()); peers.add(null); + mUsapPoolRefillTriggerTimestamp = INVALID_TIMESTAMP; + while (true) { fetchUsapPoolPolicyPropsWithMinInterval(); + mUsapPoolRefillAction = UsapPoolRefillAction.NONE; int[] usapPipeFDs = null; StructPollfd[] pollFDs; @@ -430,140 +484,199 @@ class ZygoteServer { } } + int pollTimeoutMs; + + if (mUsapPoolRefillTriggerTimestamp == INVALID_TIMESTAMP) { + pollTimeoutMs = -1; + } else { + long elapsedTimeMs = System.currentTimeMillis() - mUsapPoolRefillTriggerTimestamp; + + if (elapsedTimeMs >= mUsapPoolRefillDelayMs) { + // Normalize the poll timeout value when the time between one poll event and the + // next pushes us over the delay value. This prevents poll receiving a 0 + // timeout value, which would result in it returning immediately. + pollTimeoutMs = -1; + + } else if (elapsedTimeMs <= 0) { + // This can occur if the clock used by currentTimeMillis is reset, which is + // possible because it is not guaranteed to be monotonic. Because we can't tell + // how far back the clock was set the best way to recover is to simply re-start + // the respawn delay countdown. + pollTimeoutMs = mUsapPoolRefillDelayMs; + + } else { + pollTimeoutMs = (int) (mUsapPoolRefillDelayMs - elapsedTimeMs); + } + } + + int pollReturnValue; try { - Os.poll(pollFDs, -1); + pollReturnValue = Os.poll(pollFDs, pollTimeoutMs); } catch (ErrnoException ex) { throw new RuntimeException("poll failed", ex); } - boolean usapPoolFDRead = false; - - while (--pollIndex >= 0) { - if ((pollFDs[pollIndex].revents & POLLIN) == 0) { - continue; - } - - if (pollIndex == 0) { - // Zygote server socket + if (pollReturnValue == 0) { + // The poll timeout has been exceeded. This only occurs when we have finished the + // USAP pool refill delay period. - ZygoteConnection newPeer = acceptCommandPeer(abiList); - peers.add(newPeer); - socketFDs.add(newPeer.getFileDescriptor()); + mUsapPoolRefillTriggerTimestamp = INVALID_TIMESTAMP; + mUsapPoolRefillAction = UsapPoolRefillAction.DELAYED; - } else if (pollIndex < usapPoolEventFDIndex) { - // Session socket accepted from the Zygote server socket + } else { + boolean usapPoolFDRead = false; - try { - ZygoteConnection connection = peers.get(pollIndex); - final Runnable command = connection.processOneCommand(this); + while (--pollIndex >= 0) { + if ((pollFDs[pollIndex].revents & POLLIN) == 0) { + continue; + } - // TODO (chriswailes): Is this extra check necessary? - if (mIsForkChild) { - // We're in the child. We should always have a command to run at this - // stage if processOneCommand hasn't called "exec". - if (command == null) { - throw new IllegalStateException("command == null"); + if (pollIndex == 0) { + // Zygote server socket + + ZygoteConnection newPeer = acceptCommandPeer(abiList); + peers.add(newPeer); + socketFDs.add(newPeer.getFileDescriptor()); + + } else if (pollIndex < usapPoolEventFDIndex) { + // Session socket accepted from the Zygote server socket + + try { + ZygoteConnection connection = peers.get(pollIndex); + final Runnable command = connection.processOneCommand(this); + + // TODO (chriswailes): Is this extra check necessary? + if (mIsForkChild) { + // We're in the child. We should always have a command to run at + // this stage if processOneCommand hasn't called "exec". + if (command == null) { + throw new IllegalStateException("command == null"); + } + + return command; + } else { + // We're in the server - we should never have any commands to run. + if (command != null) { + throw new IllegalStateException("command != null"); + } + + // We don't know whether the remote side of the socket was closed or + // not until we attempt to read from it from processOneCommand. This + // shows up as a regular POLLIN event in our regular processing + // loop. + if (connection.isClosedByPeer()) { + connection.closeSocket(); + peers.remove(pollIndex); + socketFDs.remove(pollIndex); + } } + } catch (Exception e) { + if (!mIsForkChild) { + // We're in the server so any exception here is one that has taken + // place pre-fork while processing commands or reading / writing + // from the control socket. Make a loud noise about any such + // exceptions so that we know exactly what failed and why. - return command; - } else { - // We're in the server - we should never have any commands to run. - if (command != null) { - throw new IllegalStateException("command != null"); - } + Slog.e(TAG, "Exception executing zygote command: ", e); + + // Make sure the socket is closed so that the other end knows + // immediately that something has gone wrong and doesn't time out + // waiting for a response. + ZygoteConnection conn = peers.remove(pollIndex); + conn.closeSocket(); - // We don't know whether the remote side of the socket was closed or - // not until we attempt to read from it from processOneCommand. This - // shows up as a regular POLLIN event in our regular processing loop. - if (connection.isClosedByPeer()) { - connection.closeSocket(); - peers.remove(pollIndex); socketFDs.remove(pollIndex); + } else { + // We're in the child so any exception caught here has happened post + // fork and before we execute ActivityThread.main (or any other + // main() method). Log the details of the exception and bring down + // the process. + Log.e(TAG, "Caught post-fork exception in child process.", e); + throw e; } + } finally { + // Reset the child flag, in the event that the child process is a child- + // zygote. The flag will not be consulted this loop pass after the + // Runnable is returned. + mIsForkChild = false; } - } catch (Exception e) { - if (!mIsForkChild) { - // We're in the server so any exception here is one that has taken place - // pre-fork while processing commands or reading / writing from the - // control socket. Make a loud noise about any such exceptions so that - // we know exactly what failed and why. - - Slog.e(TAG, "Exception executing zygote command: ", e); - - // Make sure the socket is closed so that the other end knows - // immediately that something has gone wrong and doesn't time out - // waiting for a response. - ZygoteConnection conn = peers.remove(pollIndex); - conn.closeSocket(); - - socketFDs.remove(pollIndex); - } else { - // We're in the child so any exception caught here has happened post - // fork and before we execute ActivityThread.main (or any other main() - // method). Log the details of the exception and bring down the process. - Log.e(TAG, "Caught post-fork exception in child process.", e); - throw e; - } - } finally { - // Reset the child flag, in the event that the child process is a child- - // zygote. The flag will not be consulted this loop pass after the Runnable - // is returned. - mIsForkChild = false; - } - } else { - // Either the USAP pool event FD or a USAP reporting pipe. - - // If this is the event FD the payload will be the number of USAPs removed. - // If this is a reporting pipe FD the payload will be the PID of the USAP - // that was just specialized. - long messagePayload = -1; - - try { - byte[] buffer = new byte[Zygote.USAP_MANAGEMENT_MESSAGE_BYTES]; - int readBytes = Os.read(pollFDs[pollIndex].fd, buffer, 0, buffer.length); - if (readBytes == Zygote.USAP_MANAGEMENT_MESSAGE_BYTES) { - DataInputStream inputStream = - new DataInputStream(new ByteArrayInputStream(buffer)); + } else { + // Either the USAP pool event FD or a USAP reporting pipe. + + // If this is the event FD the payload will be the number of USAPs removed. + // If this is a reporting pipe FD the payload will be the PID of the USAP + // that was just specialized. The `continue` statements below ensure that + // the messagePayload will always be valid if we complete the try block + // without an exception. + long messagePayload; + + try { + byte[] buffer = new byte[Zygote.USAP_MANAGEMENT_MESSAGE_BYTES]; + int readBytes = + Os.read(pollFDs[pollIndex].fd, buffer, 0, buffer.length); + + if (readBytes == Zygote.USAP_MANAGEMENT_MESSAGE_BYTES) { + DataInputStream inputStream = + new DataInputStream(new ByteArrayInputStream(buffer)); + + messagePayload = inputStream.readLong(); + } else { + Log.e(TAG, "Incomplete read from USAP management FD of size " + + readBytes); + continue; + } + } catch (Exception ex) { + if (pollIndex == usapPoolEventFDIndex) { + Log.e(TAG, "Failed to read from USAP pool event FD: " + + ex.getMessage()); + } else { + Log.e(TAG, "Failed to read from USAP reporting pipe: " + + ex.getMessage()); + } - messagePayload = inputStream.readLong(); - } else { - Log.e(TAG, "Incomplete read from USAP management FD of size " - + readBytes); continue; } - } catch (Exception ex) { - if (pollIndex == usapPoolEventFDIndex) { - Log.e(TAG, "Failed to read from USAP pool event FD: " - + ex.getMessage()); - } else { - Log.e(TAG, "Failed to read from USAP reporting pipe: " - + ex.getMessage()); + + if (pollIndex > usapPoolEventFDIndex) { + Zygote.removeUsapTableEntry((int) messagePayload); } - continue; + usapPoolFDRead = true; } + } - if (pollIndex > usapPoolEventFDIndex) { - Zygote.removeUsapTableEntry((int) messagePayload); - } + if (usapPoolFDRead) { + int usapPoolCount = Zygote.getUsapPoolCount(); - usapPoolFDRead = true; + if (usapPoolCount < mUsapPoolSizeMin) { + // Immediate refill + mUsapPoolRefillAction = UsapPoolRefillAction.IMMEDIATE; + } else if (mUsapPoolSizeMax - usapPoolCount >= mUsapPoolRefillThreshold) { + // Delayed refill + mUsapPoolRefillTriggerTimestamp = System.currentTimeMillis(); + } } } - // Check to see if the USAP pool needs to be refilled. - if (usapPoolFDRead) { + if (mUsapPoolRefillAction != UsapPoolRefillAction.NONE) { int[] sessionSocketRawFDs = socketFDs.subList(1, socketFDs.size()) .stream() .mapToInt(FileDescriptor::getInt$) .toArray(); - final Runnable command = fillUsapPool(sessionSocketRawFDs); + final boolean isPriorityRefill = + mUsapPoolRefillAction == UsapPoolRefillAction.IMMEDIATE; + + final Runnable command = + fillUsapPool(sessionSocketRawFDs, isPriorityRefill); if (command != null) { return command; + } else if (isPriorityRefill) { + // Schedule a delayed refill to finish refilling the pool. + mUsapPoolRefillTriggerTimestamp = System.currentTimeMillis(); } } } diff --git a/core/java/com/android/internal/policy/DecorView.java b/core/java/com/android/internal/policy/DecorView.java index 07002d788908..81db4412cf8f 100644 --- a/core/java/com/android/internal/policy/DecorView.java +++ b/core/java/com/android/internal/policy/DecorView.java @@ -46,8 +46,8 @@ import android.animation.AnimatorListenerAdapter; import android.animation.ObjectAnimator; import android.annotation.Nullable; import android.annotation.TestApi; -import android.annotation.UnsupportedAppUsage; import android.app.WindowConfiguration; +import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; import android.content.res.Configuration; import android.content.res.Resources; diff --git a/core/java/com/android/internal/policy/PhoneFallbackEventHandler.java b/core/java/com/android/internal/policy/PhoneFallbackEventHandler.java index 791c2d7aa4b2..f07f667f269f 100644 --- a/core/java/com/android/internal/policy/PhoneFallbackEventHandler.java +++ b/core/java/com/android/internal/policy/PhoneFallbackEventHandler.java @@ -16,9 +16,9 @@ package com.android.internal.policy; -import android.annotation.UnsupportedAppUsage; import android.app.KeyguardManager; import android.app.SearchManager; +import android.compat.annotation.UnsupportedAppUsage; import android.content.ActivityNotFoundException; import android.content.Context; import android.content.Intent; @@ -33,7 +33,6 @@ import android.view.FallbackEventHandler; import android.view.HapticFeedbackConstants; import android.view.KeyEvent; import android.view.View; -import com.android.internal.policy.PhoneWindow; /** * @hide diff --git a/core/java/com/android/internal/policy/PhoneWindow.java b/core/java/com/android/internal/policy/PhoneWindow.java index daa57e05aef6..a785ede3bcb2 100644 --- a/core/java/com/android/internal/policy/PhoneWindow.java +++ b/core/java/com/android/internal/policy/PhoneWindow.java @@ -34,10 +34,10 @@ import static android.view.WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_M import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_FORCE_DRAW_BAR_BACKGROUNDS; import android.annotation.NonNull; -import android.annotation.UnsupportedAppUsage; import android.app.ActivityManager; import android.app.KeyguardManager; import android.app.SearchManager; +import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; import android.content.Intent; import android.content.pm.PackageManager; diff --git a/core/java/com/android/internal/preference/YesNoPreference.java b/core/java/com/android/internal/preference/YesNoPreference.java index 94ef619f286a..f8780542f2fe 100644 --- a/core/java/com/android/internal/preference/YesNoPreference.java +++ b/core/java/com/android/internal/preference/YesNoPreference.java @@ -16,6 +16,7 @@ package com.android.internal.preference; +import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; import android.content.res.TypedArray; import android.os.Parcel; @@ -23,8 +24,6 @@ import android.os.Parcelable; import android.preference.DialogPreference; import android.util.AttributeSet; -import dalvik.annotation.compat.UnsupportedAppUsage; - /** * The {@link YesNoPreference} is a preference to show a dialog with Yes and No * buttons. diff --git a/core/java/com/android/internal/telephony/IPhoneStateListener.aidl b/core/java/com/android/internal/telephony/IPhoneStateListener.aidl index cb67309ce74f..6fd271c5490f 100644 --- a/core/java/com/android/internal/telephony/IPhoneStateListener.aidl +++ b/core/java/com/android/internal/telephony/IPhoneStateListener.aidl @@ -16,8 +16,8 @@ package com.android.internal.telephony; -import android.os.Bundle; import android.telephony.CallAttributes; +import android.telephony.CellIdentity; import android.telephony.CellInfo; import android.telephony.DataConnectionRealTimeInfo; import android.telephony.PhoneCapability; @@ -37,8 +37,8 @@ oneway interface IPhoneStateListener { void onMessageWaitingIndicatorChanged(boolean mwi); void onCallForwardingIndicatorChanged(boolean cfi); - // we use bundle here instead of CellLocation so it can get the right subclass - void onCellLocationChanged(in Bundle location); + // Uses CellIdentity which is Parcelable here; will convert to CellLocation in client. + void onCellLocationChanged(in CellIdentity location); void onCallStateChanged(int state, String incomingNumber); void onDataConnectionStateChanged(int state, int networkType); void onDataActivity(int direction); @@ -62,5 +62,6 @@ oneway interface IPhoneStateListener { void onOutgoingEmergencySms(in EmergencyNumber sentEmergencyNumber); void onCallDisconnectCauseChanged(in int disconnectCause, in int preciseDisconnectCause); void onImsCallDisconnectCauseChanged(in ImsReasonInfo imsReasonInfo); + void onRegistrationFailed(in CellIdentity cellIdentity, + String chosenPlmn, int domain, int causeCode, int additionalCauseCode); } - diff --git a/core/java/com/android/internal/telephony/ITelephonyRegistry.aidl b/core/java/com/android/internal/telephony/ITelephonyRegistry.aidl index b1bc2d9b510a..64b23610e4f9 100644 --- a/core/java/com/android/internal/telephony/ITelephonyRegistry.aidl +++ b/core/java/com/android/internal/telephony/ITelephonyRegistry.aidl @@ -19,8 +19,8 @@ package com.android.internal.telephony; import android.content.Intent; import android.net.LinkProperties; import android.net.NetworkCapabilities; -import android.os.Bundle; import android.telephony.CallQuality; +import android.telephony.CellIdentity; import android.telephony.CellInfo; import android.telephony.ims.ImsReasonInfo; import android.telephony.PhoneCapability; @@ -33,16 +33,22 @@ import com.android.internal.telephony.IPhoneStateListener; import com.android.internal.telephony.IOnSubscriptionsChangedListener; interface ITelephonyRegistry { - void addOnSubscriptionsChangedListener(String pkg, + void addOnSubscriptionsChangedListener(String pkg, String featureId, IOnSubscriptionsChangedListener callback); - void addOnOpportunisticSubscriptionsChangedListener(String pkg, + void addOnOpportunisticSubscriptionsChangedListener(String pkg, String featureId, IOnSubscriptionsChangedListener callback); void removeOnSubscriptionsChangedListener(String pkg, IOnSubscriptionsChangedListener callback); + /** + * @deprecated Use {@link #listenWithFeature(String, String, IPhoneStateListener, int, + * boolean) instead + */ @UnsupportedAppUsage void listen(String pkg, IPhoneStateListener callback, int events, boolean notifyNow); - void listenForSubscriber(in int subId, String pkg, IPhoneStateListener callback, int events, + void listenWithFeature(String pkg, String featureId, IPhoneStateListener callback, int events, boolean notifyNow); + void listenForSubscriber(in int subId, String pkg, String featureId, + IPhoneStateListener callback, int events, boolean notifyNow); @UnsupportedAppUsage void notifyCallStateForAllSubs(int state, String incomingNumber); void notifyCallState(in int phoneId, in int subId, int state, String incomingNumber); @@ -61,9 +67,9 @@ interface ITelephonyRegistry { @UnsupportedAppUsage void notifyDataConnectionFailed(String apnType); void notifyDataConnectionFailedForSubscriber(int phoneId, int subId, String apnType); - @UnsupportedAppUsage(maxTargetSdk = 28) - void notifyCellLocation(in Bundle cellLocation); - void notifyCellLocationForSubscriber(in int subId, in Bundle cellLocation); + // Uses CellIdentity which is Parcelable here; will convert to CellLocation in client. + void notifyCellLocation(in CellIdentity cellLocation); + void notifyCellLocationForSubscriber(in int subId, in CellIdentity cellLocation); @UnsupportedAppUsage void notifyCellInfo(in List<CellInfo> cellInfo); void notifyPreciseCallState(int phoneId, int subId, int ringingCallState, @@ -92,4 +98,6 @@ interface ITelephonyRegistry { void notifyCallQualityChanged(in CallQuality callQuality, int phoneId, int subId, int callNetworkType); void notifyImsDisconnectCause(int subId, in ImsReasonInfo imsReasonInfo); + void notifyRegistrationFailed(int slotIndex, int subId, in CellIdentity cellIdentity, + String chosenPlmn, int domain, int causeCode, int additionalCauseCode); } diff --git a/core/java/com/android/internal/util/ArrayUtils.java b/core/java/com/android/internal/util/ArrayUtils.java index b73ecd1974aa..5a9188018472 100644 --- a/core/java/com/android/internal/util/ArrayUtils.java +++ b/core/java/com/android/internal/util/ArrayUtils.java @@ -18,7 +18,7 @@ package com.android.internal.util; import android.annotation.NonNull; import android.annotation.Nullable; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.util.ArraySet; import dalvik.system.VMRuntime; diff --git a/core/java/com/android/internal/util/AsyncChannel.java b/core/java/com/android/internal/util/AsyncChannel.java index b0888f2c8df9..f08771818873 100644 --- a/core/java/com/android/internal/util/AsyncChannel.java +++ b/core/java/com/android/internal/util/AsyncChannel.java @@ -16,7 +16,7 @@ package com.android.internal.util; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.ComponentName; import android.content.Context; import android.content.Intent; diff --git a/core/java/com/android/internal/util/BitwiseInputStream.java b/core/java/com/android/internal/util/BitwiseInputStream.java index 6ff67e9b9718..ffae3ce89ce4 100644 --- a/core/java/com/android/internal/util/BitwiseInputStream.java +++ b/core/java/com/android/internal/util/BitwiseInputStream.java @@ -16,7 +16,7 @@ package com.android.internal.util; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; /** * An object that provides bitwise incremental read access to a byte array. diff --git a/core/java/com/android/internal/util/BitwiseOutputStream.java b/core/java/com/android/internal/util/BitwiseOutputStream.java index cdd6f173484c..9f4150860887 100644 --- a/core/java/com/android/internal/util/BitwiseOutputStream.java +++ b/core/java/com/android/internal/util/BitwiseOutputStream.java @@ -16,7 +16,7 @@ package com.android.internal.util; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; /** * An object that provides bitwise incremental write access to a byte array. diff --git a/core/java/com/android/internal/util/CharSequences.java b/core/java/com/android/internal/util/CharSequences.java index 6b6c43ce8195..82ef200a73f1 100644 --- a/core/java/com/android/internal/util/CharSequences.java +++ b/core/java/com/android/internal/util/CharSequences.java @@ -16,7 +16,7 @@ package com.android.internal.util; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; /** * {@link CharSequence} utility methods. diff --git a/core/java/com/android/internal/util/ConnectivityUtil.java b/core/java/com/android/internal/util/ConnectivityUtil.java new file mode 100644 index 000000000000..b1d4fa0d3fd3 --- /dev/null +++ b/core/java/com/android/internal/util/ConnectivityUtil.java @@ -0,0 +1,202 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES 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.util; + +import android.Manifest; +import android.annotation.Nullable; +import android.app.ActivityManager; +import android.app.AppOpsManager; +import android.content.Context; +import android.content.pm.PackageManager; +import android.location.LocationManager; +import android.os.Binder; +import android.os.Build; +import android.os.UserHandle; +import android.os.UserManager; +import android.util.Log; + +import com.android.internal.annotations.VisibleForTesting; + + +/** + * Utility methods for common functionality using by different networks. + * + * @hide + */ +public class ConnectivityUtil { + + private static final String TAG = "ConnectivityUtil"; + + private final Context mContext; + private final AppOpsManager mAppOps; + private final UserManager mUserManager; + + public ConnectivityUtil(Context context) { + mContext = context; + mAppOps = (AppOpsManager) mContext.getSystemService(Context.APP_OPS_SERVICE); + mUserManager = (UserManager) mContext.getSystemService(Context.USER_SERVICE); + } + + /** + * API to determine if the caller has fine/coarse location permission (depending on + * config/targetSDK level) and the location mode is enabled for the user. SecurityException is + * thrown if the caller has no permission or the location mode is disabled. + * @param pkgName package name of the application requesting access + * @param featureId The feature in the package + * @param uid The uid of the package + * @param message A message describing why the permission was checked. Only needed if this is + * not inside of a two-way binder call from the data receiver + */ + public void enforceLocationPermission(String pkgName, @Nullable String featureId, int uid, + @Nullable String message) + throws SecurityException { + checkPackage(uid, pkgName); + + // Location mode must be enabled + if (!isLocationModeEnabled()) { + // Location mode is disabled, scan results cannot be returned + throw new SecurityException("Location mode is disabled for the device"); + } + + // LocationAccess by App: caller must have Coarse/Fine Location permission to have access to + // location information. + boolean canAppPackageUseLocation = checkCallersLocationPermission(pkgName, featureId, + uid, /* coarseForTargetSdkLessThanQ */ true, message); + + // If neither caller or app has location access, there is no need to check + // any other permissions. Deny access to scan results. + if (!canAppPackageUseLocation) { + throw new SecurityException("UID " + uid + " has no location permission"); + } + // If the User or profile is current, permission is granted + // Otherwise, uid must have INTERACT_ACROSS_USERS_FULL permission. + if (!isCurrentProfile(uid) && !checkInteractAcrossUsersFull(uid)) { + throw new SecurityException("UID " + uid + " profile not permitted"); + } + } + + /** + * Checks that calling process has android.Manifest.permission.ACCESS_FINE_LOCATION or + * android.Manifest.permission.ACCESS_COARSE_LOCATION (depending on config/targetSDK level) + * and a corresponding app op is allowed for this package and uid. + * + * @param pkgName PackageName of the application requesting access + * @param featureId The feature in the package + * @param uid The uid of the package + * @param coarseForTargetSdkLessThanQ If true and the targetSDK < Q then will check for COARSE + * else (false or targetSDK >= Q) then will check for FINE + * @param message A message describing why the permission was checked. Only needed if this is + * not inside of a two-way binder call from the data receiver + */ + public boolean checkCallersLocationPermission(String pkgName, @Nullable String featureId, + int uid, boolean coarseForTargetSdkLessThanQ, @Nullable String message) { + boolean isTargetSdkLessThanQ = isTargetSdkLessThan(pkgName, Build.VERSION_CODES.Q, uid); + + String permissionType = Manifest.permission.ACCESS_FINE_LOCATION; + if (coarseForTargetSdkLessThanQ && isTargetSdkLessThanQ) { + // Having FINE permission implies having COARSE permission (but not the reverse) + permissionType = Manifest.permission.ACCESS_COARSE_LOCATION; + } + if (getUidPermission(permissionType, uid) + == PackageManager.PERMISSION_DENIED) { + return false; + } + + // Always checking FINE - even if will not enforce. This will record the request for FINE + // so that a location request by the app is surfaced to the user. + boolean isFineLocationAllowed = noteAppOpAllowed( + AppOpsManager.OPSTR_FINE_LOCATION, pkgName, featureId, uid, message); + if (isFineLocationAllowed) { + return true; + } + if (coarseForTargetSdkLessThanQ && isTargetSdkLessThanQ) { + return noteAppOpAllowed(AppOpsManager.OPSTR_COARSE_LOCATION, pkgName, featureId, uid, + message); + } + return false; + } + + /** + * Retrieves a handle to LocationManager (if not already done) and check if location is enabled. + */ + public boolean isLocationModeEnabled() { + LocationManager locationManager = + (LocationManager) mContext.getSystemService(Context.LOCATION_SERVICE); + try { + return locationManager.isLocationEnabledForUser(UserHandle.of( + getCurrentUser())); + } catch (Exception e) { + Log.e(TAG, "Failure to get location mode via API, falling back to settings", e); + return false; + } + } + + private boolean isTargetSdkLessThan(String packageName, int versionCode, int callingUid) { + long ident = Binder.clearCallingIdentity(); + try { + if (mContext.getPackageManager().getApplicationInfoAsUser( + packageName, 0, + UserHandle.getUserHandleForUid(callingUid)).targetSdkVersion + < versionCode) { + return true; + } + } catch (PackageManager.NameNotFoundException e) { + // In case of exception, assume unknown app (more strict checking) + // Note: This case will never happen since checkPackage is + // called to verify validity before checking App's version. + } finally { + Binder.restoreCallingIdentity(ident); + } + return false; + } + + private boolean noteAppOpAllowed(String op, String pkgName, @Nullable String featureId, + int uid, @Nullable String message) { + return mAppOps.noteOp(op, uid, pkgName) == AppOpsManager.MODE_ALLOWED; + } + + private void checkPackage(int uid, String pkgName) throws SecurityException { + if (pkgName == null) { + throw new SecurityException("Checking UID " + uid + " but Package Name is Null"); + } + mAppOps.checkPackage(uid, pkgName); + } + + private boolean isCurrentProfile(int uid) { + UserHandle currentUser = UserHandle.of(getCurrentUser()); + UserHandle callingUser = UserHandle.getUserHandleForUid(uid); + return currentUser.equals(callingUser) + || mUserManager.isSameProfileGroup( + currentUser.getIdentifier(), callingUser.getIdentifier()); + } + + private boolean checkInteractAcrossUsersFull(int uid) { + return getUidPermission( + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, uid) + == PackageManager.PERMISSION_GRANTED; + } + + @VisibleForTesting + protected int getCurrentUser() { + return ActivityManager.getCurrentUser(); + } + + private int getUidPermission(String permissionType, int uid) { + // We don't care about pid, pass in -1 + return mContext.checkPermission(permissionType, -1, uid); + } +} diff --git a/core/java/com/android/internal/util/FastMath.java b/core/java/com/android/internal/util/FastMath.java index 35efe708795e..b7dbee53a4be 100644 --- a/core/java/com/android/internal/util/FastMath.java +++ b/core/java/com/android/internal/util/FastMath.java @@ -16,7 +16,7 @@ package com.android.internal.util; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; /** * Fast and loose math routines. diff --git a/core/java/com/android/internal/util/FastPrintWriter.java b/core/java/com/android/internal/util/FastPrintWriter.java index 981fbaaa9880..63124def6d2f 100644 --- a/core/java/com/android/internal/util/FastPrintWriter.java +++ b/core/java/com/android/internal/util/FastPrintWriter.java @@ -16,7 +16,7 @@ package com.android.internal.util; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.util.Log; import android.util.Printer; diff --git a/core/java/com/android/internal/util/FastXmlSerializer.java b/core/java/com/android/internal/util/FastXmlSerializer.java index 9f76aeb663c5..94e07a85867e 100644 --- a/core/java/com/android/internal/util/FastXmlSerializer.java +++ b/core/java/com/android/internal/util/FastXmlSerializer.java @@ -16,9 +16,10 @@ package com.android.internal.util; +import android.compat.annotation.UnsupportedAppUsage; + import org.xmlpull.v1.XmlSerializer; -import android.annotation.UnsupportedAppUsage; import java.io.IOException; import java.io.OutputStream; import java.io.OutputStreamWriter; diff --git a/core/java/com/android/internal/util/GrowingArrayUtils.java b/core/java/com/android/internal/util/GrowingArrayUtils.java index 9f563667e019..597fe6b53d11 100644 --- a/core/java/com/android/internal/util/GrowingArrayUtils.java +++ b/core/java/com/android/internal/util/GrowingArrayUtils.java @@ -16,7 +16,7 @@ package com.android.internal.util; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; /** * A helper class that aims to provide comparable growth performance to ArrayList, but on primitive diff --git a/core/java/com/android/internal/util/HexDump.java b/core/java/com/android/internal/util/HexDump.java index 6ffc92853b08..ad88dd6deec6 100644 --- a/core/java/com/android/internal/util/HexDump.java +++ b/core/java/com/android/internal/util/HexDump.java @@ -17,7 +17,7 @@ package com.android.internal.util; import android.annotation.Nullable; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; public class HexDump { diff --git a/core/java/com/android/internal/util/IState.java b/core/java/com/android/internal/util/IState.java index eb66e2ce94d7..07837bf8f587 100644 --- a/core/java/com/android/internal/util/IState.java +++ b/core/java/com/android/internal/util/IState.java @@ -16,7 +16,7 @@ package com.android.internal.util; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.os.Message; /** diff --git a/core/java/com/android/internal/util/IndentingPrintWriter.java b/core/java/com/android/internal/util/IndentingPrintWriter.java index 03a555edf4a8..34c6a055d5bd 100644 --- a/core/java/com/android/internal/util/IndentingPrintWriter.java +++ b/core/java/com/android/internal/util/IndentingPrintWriter.java @@ -16,7 +16,8 @@ package com.android.internal.util; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; + import java.io.PrintWriter; import java.io.Writer; import java.util.Arrays; diff --git a/core/java/com/android/internal/util/JournaledFile.java b/core/java/com/android/internal/util/JournaledFile.java index 065cc5b2416b..a9d8f7239d03 100644 --- a/core/java/com/android/internal/util/JournaledFile.java +++ b/core/java/com/android/internal/util/JournaledFile.java @@ -16,7 +16,7 @@ package com.android.internal.util; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.os.Build; import java.io.File; diff --git a/core/java/com/android/internal/util/MemInfoReader.java b/core/java/com/android/internal/util/MemInfoReader.java index 580c2fa66de2..5de77d9b0545 100644 --- a/core/java/com/android/internal/util/MemInfoReader.java +++ b/core/java/com/android/internal/util/MemInfoReader.java @@ -16,7 +16,7 @@ package com.android.internal.util; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.os.Debug; import android.os.StrictMode; diff --git a/core/java/com/android/internal/util/Preconditions.java b/core/java/com/android/internal/util/Preconditions.java index 3fff5c233890..408a7a8e139a 100644 --- a/core/java/com/android/internal/util/Preconditions.java +++ b/core/java/com/android/internal/util/Preconditions.java @@ -18,7 +18,7 @@ package com.android.internal.util; import android.annotation.IntRange; import android.annotation.NonNull; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.text.TextUtils; import java.util.Collection; @@ -126,7 +126,9 @@ public class Preconditions { * @param reference an object reference * @return the non-null reference that was validated * @throws NullPointerException if {@code reference} is null + * @deprecated - use {@link java.util.Objects.requireNonNull} instead. */ + @Deprecated @UnsupportedAppUsage public static @NonNull <T> T checkNotNull(final T reference) { if (reference == null) { @@ -144,7 +146,9 @@ public class Preconditions { * be converted to a string using {@link String#valueOf(Object)} * @return the non-null reference that was validated * @throws NullPointerException if {@code reference} is null + * @deprecated - use {@link java.util.Objects.requireNonNull} instead. */ + @Deprecated @UnsupportedAppUsage public static @NonNull <T> T checkNotNull(final T reference, final Object errorMessage) { if (reference == null) { @@ -154,26 +158,6 @@ public class Preconditions { } /** - * Ensures that an object reference passed as a parameter to the calling - * method is not null. - * - * @param reference an object reference - * @param messageTemplate a printf-style message template to use if the check fails; will - * be converted to a string using {@link String#format(String, Object...)} - * @param messageArgs arguments for {@code messageTemplate} - * @return the non-null reference that was validated - * @throws NullPointerException if {@code reference} is null - */ - public static @NonNull <T> T checkNotNull(final T reference, - final String messageTemplate, - final Object... messageArgs) { - if (reference == null) { - throw new NullPointerException(String.format(messageTemplate, messageArgs)); - } - return reference; - } - - /** * Ensures the truth of an expression involving the state of the calling * instance, but not involving any parameters to the calling method. * diff --git a/core/java/com/android/internal/util/State.java b/core/java/com/android/internal/util/State.java index 3c61e035e886..636378e32091 100644 --- a/core/java/com/android/internal/util/State.java +++ b/core/java/com/android/internal/util/State.java @@ -16,7 +16,7 @@ package com.android.internal.util; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.os.Message; /** diff --git a/core/java/com/android/internal/util/StateMachine.java b/core/java/com/android/internal/util/StateMachine.java index 6c217e5a37bf..0c2406559dcc 100644 --- a/core/java/com/android/internal/util/StateMachine.java +++ b/core/java/com/android/internal/util/StateMachine.java @@ -16,7 +16,7 @@ package com.android.internal.util; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.os.Handler; import android.os.HandlerThread; import android.os.Looper; diff --git a/core/java/com/android/internal/util/XmlUtils.java b/core/java/com/android/internal/util/XmlUtils.java index 8799e3d4c6bf..c1be33a215b8 100644 --- a/core/java/com/android/internal/util/XmlUtils.java +++ b/core/java/com/android/internal/util/XmlUtils.java @@ -16,10 +16,10 @@ package com.android.internal.util; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.graphics.Bitmap; -import android.graphics.BitmapFactory; import android.graphics.Bitmap.CompressFormat; +import android.graphics.BitmapFactory; import android.net.Uri; import android.text.TextUtils; import android.util.ArrayMap; diff --git a/core/java/com/android/internal/view/ActionBarPolicy.java b/core/java/com/android/internal/view/ActionBarPolicy.java index d18c35e703da..d16cb4362f1b 100644 --- a/core/java/com/android/internal/view/ActionBarPolicy.java +++ b/core/java/com/android/internal/view/ActionBarPolicy.java @@ -16,15 +16,15 @@ package com.android.internal.view; -import com.android.internal.R; - -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; import android.content.res.Configuration; import android.content.res.Resources; import android.content.res.TypedArray; import android.os.Build; +import com.android.internal.R; + /** * Allows components to query for various configuration policy decisions * about how the action bar should lay out and behave on the current device. diff --git a/core/java/com/android/internal/view/BaseIWindow.java b/core/java/com/android/internal/view/BaseIWindow.java index f5a9fde97159..adf56bf8a434 100644 --- a/core/java/com/android/internal/view/BaseIWindow.java +++ b/core/java/com/android/internal/view/BaseIWindow.java @@ -16,7 +16,7 @@ package com.android.internal.view; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.graphics.Point; import android.graphics.Rect; import android.hardware.input.InputManager; diff --git a/core/java/com/android/internal/view/IInputConnectionWrapper.java b/core/java/com/android/internal/view/IInputConnectionWrapper.java index ececba13c760..6278d4a35329 100644 --- a/core/java/com/android/internal/view/IInputConnectionWrapper.java +++ b/core/java/com/android/internal/view/IInputConnectionWrapper.java @@ -18,7 +18,7 @@ package com.android.internal.view; import android.annotation.NonNull; import android.annotation.Nullable; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.os.Build; import android.os.Bundle; import android.os.Handler; diff --git a/core/java/com/android/internal/view/InputBindResult.java b/core/java/com/android/internal/view/InputBindResult.java index 1b133d2a8393..a5964b509b3c 100644 --- a/core/java/com/android/internal/view/InputBindResult.java +++ b/core/java/com/android/internal/view/InputBindResult.java @@ -20,7 +20,7 @@ import static java.lang.annotation.RetentionPolicy.SOURCE; import android.annotation.IntDef; import android.annotation.Nullable; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.ComponentName; import android.content.Intent; import android.content.ServiceConnection; diff --git a/core/java/com/android/internal/view/InputConnectionWrapper.java b/core/java/com/android/internal/view/InputConnectionWrapper.java index 0c057ea6df59..a41048c0f426 100644 --- a/core/java/com/android/internal/view/InputConnectionWrapper.java +++ b/core/java/com/android/internal/view/InputConnectionWrapper.java @@ -19,7 +19,7 @@ package com.android.internal.view; import android.annotation.AnyThread; import android.annotation.BinderThread; import android.annotation.NonNull; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.inputmethodservice.AbstractInputMethodService; import android.os.Bundle; import android.os.Handler; diff --git a/core/java/com/android/internal/view/WindowManagerPolicyThread.java b/core/java/com/android/internal/view/WindowManagerPolicyThread.java index b009a2d8ca30..6d691fce4fb0 100644 --- a/core/java/com/android/internal/view/WindowManagerPolicyThread.java +++ b/core/java/com/android/internal/view/WindowManagerPolicyThread.java @@ -16,7 +16,7 @@ package com.android.internal.view; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.os.Looper; /** diff --git a/core/java/com/android/internal/view/menu/ActionMenu.java b/core/java/com/android/internal/view/menu/ActionMenu.java index 977c1f6fda7b..648262965ab1 100644 --- a/core/java/com/android/internal/view/menu/ActionMenu.java +++ b/core/java/com/android/internal/view/menu/ActionMenu.java @@ -16,10 +16,7 @@ package com.android.internal.view.menu; -import java.util.ArrayList; -import java.util.List; - -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.ComponentName; import android.content.Context; import android.content.Intent; @@ -30,6 +27,9 @@ import android.view.Menu; import android.view.MenuItem; import android.view.SubMenu; +import java.util.ArrayList; +import java.util.List; + /** * @hide */ diff --git a/core/java/com/android/internal/view/menu/ActionMenuItem.java b/core/java/com/android/internal/view/menu/ActionMenuItem.java index ed253d58fb82..bd8bcb9cf81e 100644 --- a/core/java/com/android/internal/view/menu/ActionMenuItem.java +++ b/core/java/com/android/internal/view/menu/ActionMenuItem.java @@ -17,7 +17,7 @@ package com.android.internal.view.menu; import android.annotation.Nullable; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; import android.content.Intent; import android.content.res.ColorStateList; diff --git a/core/java/com/android/internal/view/menu/ActionMenuItemView.java b/core/java/com/android/internal/view/menu/ActionMenuItemView.java index eb94db33ba1a..7622b939b6eb 100644 --- a/core/java/com/android/internal/view/menu/ActionMenuItemView.java +++ b/core/java/com/android/internal/view/menu/ActionMenuItemView.java @@ -16,7 +16,7 @@ package com.android.internal.view.menu; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; import android.content.res.Configuration; import android.content.res.Resources; diff --git a/core/java/com/android/internal/view/menu/ContextMenuBuilder.java b/core/java/com/android/internal/view/menu/ContextMenuBuilder.java index 3d3aceb4a85f..a9f5e47fc83f 100644 --- a/core/java/com/android/internal/view/menu/ContextMenuBuilder.java +++ b/core/java/com/android/internal/view/menu/ContextMenuBuilder.java @@ -16,7 +16,7 @@ package com.android.internal.view.menu; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; import android.graphics.drawable.Drawable; import android.os.IBinder; diff --git a/core/java/com/android/internal/view/menu/IconMenuItemView.java b/core/java/com/android/internal/view/menu/IconMenuItemView.java index 3d888d347d65..539c71e5c473 100644 --- a/core/java/com/android/internal/view/menu/IconMenuItemView.java +++ b/core/java/com/android/internal/view/menu/IconMenuItemView.java @@ -16,13 +16,12 @@ package com.android.internal.view.menu; -import com.android.internal.view.menu.MenuBuilder.ItemInvoker; - -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; import android.content.res.TypedArray; import android.graphics.Rect; import android.graphics.drawable.Drawable; +import android.text.Layout; import android.text.TextUtils; import android.util.AttributeSet; import android.view.Gravity; @@ -30,7 +29,8 @@ import android.view.SoundEffectConstants; import android.view.View; import android.view.ViewDebug; import android.widget.TextView; -import android.text.Layout; + +import com.android.internal.view.menu.MenuBuilder.ItemInvoker; /** * The item view for each item in the {@link IconMenuView}. diff --git a/core/java/com/android/internal/view/menu/IconMenuView.java b/core/java/com/android/internal/view/menu/IconMenuView.java index 6f264341f7b4..9e240dbd8a21 100644 --- a/core/java/com/android/internal/view/menu/IconMenuView.java +++ b/core/java/com/android/internal/view/menu/IconMenuView.java @@ -16,9 +16,7 @@ package com.android.internal.view.menu; -import com.android.internal.view.menu.MenuBuilder.ItemInvoker; - -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; import android.content.res.Resources; import android.content.res.TypedArray; @@ -29,10 +27,12 @@ import android.os.Parcel; import android.os.Parcelable; import android.util.AttributeSet; import android.view.KeyEvent; +import android.view.LayoutInflater; import android.view.View; import android.view.ViewConfiguration; import android.view.ViewGroup; -import android.view.LayoutInflater; + +import com.android.internal.view.menu.MenuBuilder.ItemInvoker; import java.util.ArrayList; diff --git a/core/java/com/android/internal/view/menu/MenuBuilder.java b/core/java/com/android/internal/view/menu/MenuBuilder.java index 0e07ca79faf7..b31ae38b4566 100644 --- a/core/java/com/android/internal/view/menu/MenuBuilder.java +++ b/core/java/com/android/internal/view/menu/MenuBuilder.java @@ -18,7 +18,7 @@ package com.android.internal.view.menu; import android.annotation.NonNull; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.ComponentName; import android.content.Context; import android.content.Intent; diff --git a/core/java/com/android/internal/view/menu/MenuDialogHelper.java b/core/java/com/android/internal/view/menu/MenuDialogHelper.java index 88d0a03bd55f..d02b8f6ceb63 100644 --- a/core/java/com/android/internal/view/menu/MenuDialogHelper.java +++ b/core/java/com/android/internal/view/menu/MenuDialogHelper.java @@ -16,9 +16,9 @@ package com.android.internal.view.menu; -import android.annotation.UnsupportedAppUsage; import android.app.AlertDialog; import android.app.Dialog; +import android.compat.annotation.UnsupportedAppUsage; import android.content.DialogInterface; import android.os.IBinder; import android.view.KeyEvent; diff --git a/core/java/com/android/internal/view/menu/MenuItemImpl.java b/core/java/com/android/internal/view/menu/MenuItemImpl.java index 994a9c117ce9..218f5185ec47 100644 --- a/core/java/com/android/internal/view/menu/MenuItemImpl.java +++ b/core/java/com/android/internal/view/menu/MenuItemImpl.java @@ -16,10 +16,8 @@ package com.android.internal.view.menu; -import com.android.internal.view.menu.MenuView.ItemView; - import android.annotation.Nullable; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.ActivityNotFoundException; import android.content.Context; import android.content.Intent; @@ -39,6 +37,8 @@ import android.view.ViewConfiguration; import android.view.ViewDebug; import android.widget.LinearLayout; +import com.android.internal.view.menu.MenuView.ItemView; + /** * @hide */ diff --git a/core/java/com/android/internal/view/menu/MenuPopupHelper.java b/core/java/com/android/internal/view/menu/MenuPopupHelper.java index d00108edefd0..bac602509148 100644 --- a/core/java/com/android/internal/view/menu/MenuPopupHelper.java +++ b/core/java/com/android/internal/view/menu/MenuPopupHelper.java @@ -20,7 +20,7 @@ import android.annotation.AttrRes; import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.StyleRes; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; import android.graphics.Point; import android.graphics.Rect; diff --git a/core/java/com/android/internal/view/menu/MenuPresenter.java b/core/java/com/android/internal/view/menu/MenuPresenter.java index c5df8ad6edc6..35b8fefe75ab 100644 --- a/core/java/com/android/internal/view/menu/MenuPresenter.java +++ b/core/java/com/android/internal/view/menu/MenuPresenter.java @@ -18,7 +18,7 @@ package com.android.internal.view.menu; import android.annotation.NonNull; import android.annotation.Nullable; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; import android.os.Parcelable; import android.view.ViewGroup; diff --git a/core/java/com/android/internal/view/menu/MenuView.java b/core/java/com/android/internal/view/menu/MenuView.java index 67a55308938d..a31c820cd2a6 100644 --- a/core/java/com/android/internal/view/menu/MenuView.java +++ b/core/java/com/android/internal/view/menu/MenuView.java @@ -16,10 +16,7 @@ package com.android.internal.view.menu; -import com.android.internal.view.menu.MenuBuilder; -import com.android.internal.view.menu.MenuItemImpl; - -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.graphics.drawable.Drawable; /** diff --git a/core/java/com/android/internal/view/menu/SubMenuBuilder.java b/core/java/com/android/internal/view/menu/SubMenuBuilder.java index cf6d9746bb93..6eb215e94093 100644 --- a/core/java/com/android/internal/view/menu/SubMenuBuilder.java +++ b/core/java/com/android/internal/view/menu/SubMenuBuilder.java @@ -16,7 +16,7 @@ package com.android.internal.view.menu; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; import android.graphics.drawable.Drawable; import android.view.Menu; diff --git a/core/java/com/android/internal/widget/AbsActionBarView.java b/core/java/com/android/internal/widget/AbsActionBarView.java index 9ccee7fc32ff..0f0c1a3de3a2 100644 --- a/core/java/com/android/internal/widget/AbsActionBarView.java +++ b/core/java/com/android/internal/widget/AbsActionBarView.java @@ -15,26 +15,25 @@ */ package com.android.internal.widget; -import com.android.internal.R; - -import android.util.TypedValue; -import android.view.ContextThemeWrapper; -import android.view.MotionEvent; -import android.widget.ActionMenuPresenter; -import android.widget.ActionMenuView; - import android.animation.Animator; import android.animation.AnimatorSet; import android.animation.ObjectAnimator; import android.animation.TimeInterpolator; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; import android.content.res.Configuration; import android.content.res.TypedArray; import android.util.AttributeSet; +import android.util.TypedValue; +import android.view.ContextThemeWrapper; +import android.view.MotionEvent; import android.view.View; import android.view.ViewGroup; import android.view.animation.DecelerateInterpolator; +import android.widget.ActionMenuPresenter; +import android.widget.ActionMenuView; + +import com.android.internal.R; public abstract class AbsActionBarView extends ViewGroup { private static final TimeInterpolator sAlphaInterpolator = new DecelerateInterpolator(); diff --git a/core/java/com/android/internal/widget/ActionBarContextView.java b/core/java/com/android/internal/widget/ActionBarContextView.java index 78ed53fa918c..051526ef2da7 100644 --- a/core/java/com/android/internal/widget/ActionBarContextView.java +++ b/core/java/com/android/internal/widget/ActionBarContextView.java @@ -15,13 +15,7 @@ */ package com.android.internal.widget; -import com.android.internal.R; - -import android.widget.ActionMenuPresenter; -import android.widget.ActionMenuView; -import com.android.internal.view.menu.MenuBuilder; - -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; import android.content.res.TypedArray; import android.graphics.drawable.Drawable; @@ -32,9 +26,14 @@ import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.view.accessibility.AccessibilityEvent; +import android.widget.ActionMenuPresenter; +import android.widget.ActionMenuView; import android.widget.LinearLayout; import android.widget.TextView; +import com.android.internal.R; +import com.android.internal.view.menu.MenuBuilder; + /** * @hide */ diff --git a/core/java/com/android/internal/widget/ActionBarOverlayLayout.java b/core/java/com/android/internal/widget/ActionBarOverlayLayout.java index e9e3cdab7a10..aca0b713686f 100644 --- a/core/java/com/android/internal/widget/ActionBarOverlayLayout.java +++ b/core/java/com/android/internal/widget/ActionBarOverlayLayout.java @@ -18,7 +18,7 @@ package com.android.internal.widget; import android.animation.Animator; import android.animation.AnimatorListenerAdapter; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; import android.content.pm.ActivityInfo; import android.content.res.Configuration; @@ -41,6 +41,7 @@ import android.view.Window; import android.view.WindowInsets; import android.widget.OverScroller; import android.widget.Toolbar; + import com.android.internal.view.menu.MenuPresenter; /** diff --git a/core/java/com/android/internal/widget/AlertDialogLayout.java b/core/java/com/android/internal/widget/AlertDialogLayout.java index 7a0174946671..d879b6d569f3 100644 --- a/core/java/com/android/internal/widget/AlertDialogLayout.java +++ b/core/java/com/android/internal/widget/AlertDialogLayout.java @@ -18,8 +18,8 @@ package com.android.internal.widget; import android.annotation.AttrRes; import android.annotation.Nullable; -import android.annotation.UnsupportedAppUsage; import android.annotation.StyleRes; +import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; import android.graphics.drawable.Drawable; import android.util.AttributeSet; diff --git a/core/java/com/android/internal/widget/ButtonBarLayout.java b/core/java/com/android/internal/widget/ButtonBarLayout.java index 0ca67438c5c3..ff131071efef 100644 --- a/core/java/com/android/internal/widget/ButtonBarLayout.java +++ b/core/java/com/android/internal/widget/ButtonBarLayout.java @@ -16,7 +16,7 @@ package com.android.internal.widget; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; import android.content.res.TypedArray; import android.util.AttributeSet; diff --git a/core/java/com/android/internal/widget/CachingIconView.java b/core/java/com/android/internal/widget/CachingIconView.java index 35bff6d7c430..74ad81566ef4 100644 --- a/core/java/com/android/internal/widget/CachingIconView.java +++ b/core/java/com/android/internal/widget/CachingIconView.java @@ -18,7 +18,7 @@ package com.android.internal.widget; import android.annotation.DrawableRes; import android.annotation.Nullable; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; import android.content.res.Configuration; import android.graphics.Bitmap; diff --git a/core/java/com/android/internal/widget/DialogTitle.java b/core/java/com/android/internal/widget/DialogTitle.java index 405436c53ff0..0bfd684317fd 100644 --- a/core/java/com/android/internal/widget/DialogTitle.java +++ b/core/java/com/android/internal/widget/DialogTitle.java @@ -16,7 +16,7 @@ package com.android.internal.widget; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; import android.content.res.TypedArray; import android.text.Layout; diff --git a/core/java/com/android/internal/widget/EditableInputConnection.java b/core/java/com/android/internal/widget/EditableInputConnection.java index 2b648e90f7dd..ff3543c837eb 100644 --- a/core/java/com/android/internal/widget/EditableInputConnection.java +++ b/core/java/com/android/internal/widget/EditableInputConnection.java @@ -16,7 +16,7 @@ package com.android.internal.widget; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.os.Bundle; import android.text.Editable; import android.text.method.KeyListener; diff --git a/core/java/com/android/internal/widget/LinearLayoutWithDefaultTouchRecepient.java b/core/java/com/android/internal/widget/LinearLayoutWithDefaultTouchRecepient.java index cc7911da0b96..9ef9f697c46c 100644 --- a/core/java/com/android/internal/widget/LinearLayoutWithDefaultTouchRecepient.java +++ b/core/java/com/android/internal/widget/LinearLayoutWithDefaultTouchRecepient.java @@ -16,12 +16,12 @@ package com.android.internal.widget; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; import android.graphics.Rect; import android.util.AttributeSet; -import android.view.View; import android.view.MotionEvent; +import android.view.View; import android.widget.LinearLayout; diff --git a/core/java/com/android/internal/widget/LockPatternChecker.java b/core/java/com/android/internal/widget/LockPatternChecker.java index 09bc28c1f5ec..d78b26ab6dcb 100644 --- a/core/java/com/android/internal/widget/LockPatternChecker.java +++ b/core/java/com/android/internal/widget/LockPatternChecker.java @@ -1,6 +1,6 @@ package com.android.internal.widget; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.os.AsyncTask; import com.android.internal.widget.LockPatternUtils.RequestThrottledException; diff --git a/core/java/com/android/internal/widget/LockPatternUtils.java b/core/java/com/android/internal/widget/LockPatternUtils.java index dc45f7834748..8ecee6271f83 100644 --- a/core/java/com/android/internal/widget/LockPatternUtils.java +++ b/core/java/com/android/internal/widget/LockPatternUtils.java @@ -27,11 +27,11 @@ import static android.app.admin.DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED import android.annotation.IntDef; import android.annotation.Nullable; -import android.annotation.UnsupportedAppUsage; import android.app.admin.DevicePolicyManager; import android.app.admin.PasswordMetrics; import android.app.trust.IStrongAuthTracker; import android.app.trust.TrustManager; +import android.compat.annotation.UnsupportedAppUsage; import android.content.ComponentName; import android.content.ContentResolver; import android.content.Context; @@ -58,10 +58,10 @@ import android.util.SparseLongArray; import com.android.internal.annotations.VisibleForTesting; import com.android.server.LocalServices; -import com.google.android.collect.Lists; - import libcore.util.HexEncoding; +import com.google.android.collect.Lists; + import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.security.MessageDigest; diff --git a/core/java/com/android/internal/widget/LockPatternView.java b/core/java/com/android/internal/widget/LockPatternView.java index 3f6c4d4f5634..591a5e82d5e4 100644 --- a/core/java/com/android/internal/widget/LockPatternView.java +++ b/core/java/com/android/internal/widget/LockPatternView.java @@ -19,7 +19,7 @@ package com.android.internal.widget; import android.animation.Animator; import android.animation.AnimatorListenerAdapter; import android.animation.ValueAnimator; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; import android.content.res.Resources; import android.content.res.TypedArray; diff --git a/core/java/com/android/internal/widget/NumericTextView.java b/core/java/com/android/internal/widget/NumericTextView.java index d2156704a655..c8f901133be6 100644 --- a/core/java/com/android/internal/widget/NumericTextView.java +++ b/core/java/com/android/internal/widget/NumericTextView.java @@ -16,7 +16,7 @@ package com.android.internal.widget; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; import android.graphics.Rect; import android.util.AttributeSet; diff --git a/core/java/com/android/internal/widget/PointerLocationView.java b/core/java/com/android/internal/widget/PointerLocationView.java index 1f5b0701d2a7..37365111b0c5 100644 --- a/core/java/com/android/internal/widget/PointerLocationView.java +++ b/core/java/com/android/internal/widget/PointerLocationView.java @@ -16,7 +16,7 @@ package com.android.internal.widget; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; import android.graphics.Canvas; import android.graphics.Paint; diff --git a/core/java/com/android/internal/widget/PreferenceImageView.java b/core/java/com/android/internal/widget/PreferenceImageView.java index 02a0b8d436b9..43b6b5a169c5 100644 --- a/core/java/com/android/internal/widget/PreferenceImageView.java +++ b/core/java/com/android/internal/widget/PreferenceImageView.java @@ -16,7 +16,7 @@ package com.android.internal.widget; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; import android.util.AttributeSet; import android.widget.ImageView; diff --git a/core/java/com/android/internal/widget/RecyclerView.java b/core/java/com/android/internal/widget/RecyclerView.java index b66a7b44f05d..43a227a32346 100644 --- a/core/java/com/android/internal/widget/RecyclerView.java +++ b/core/java/com/android/internal/widget/RecyclerView.java @@ -20,7 +20,7 @@ import android.annotation.CallSuper; import android.annotation.IntDef; import android.annotation.NonNull; import android.annotation.Nullable; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; import android.content.res.TypedArray; import android.database.Observable; diff --git a/core/java/com/android/internal/widget/ScrollBarUtils.java b/core/java/com/android/internal/widget/ScrollBarUtils.java index 982e3152fc7c..3e9d697a0ace 100644 --- a/core/java/com/android/internal/widget/ScrollBarUtils.java +++ b/core/java/com/android/internal/widget/ScrollBarUtils.java @@ -16,7 +16,7 @@ package com.android.internal.widget; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; public class ScrollBarUtils { diff --git a/core/java/com/android/internal/widget/ScrollingTabContainerView.java b/core/java/com/android/internal/widget/ScrollingTabContainerView.java index 5d48ab910439..aa0b0bbd4c19 100644 --- a/core/java/com/android/internal/widget/ScrollingTabContainerView.java +++ b/core/java/com/android/internal/widget/ScrollingTabContainerView.java @@ -15,13 +15,11 @@ */ package com.android.internal.widget; -import com.android.internal.view.ActionBarPolicy; - import android.animation.Animator; import android.animation.ObjectAnimator; import android.animation.TimeInterpolator; -import android.annotation.UnsupportedAppUsage; import android.app.ActionBar; +import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; import android.content.res.Configuration; import android.graphics.drawable.Drawable; @@ -42,6 +40,8 @@ import android.widget.ListView; import android.widget.Spinner; import android.widget.TextView; +import com.android.internal.view.ActionBarPolicy; + /** * This widget implements the dynamic action bar tab behavior that can change * across different configurations or circumstances. diff --git a/core/java/com/android/internal/widget/SlidingTab.java b/core/java/com/android/internal/widget/SlidingTab.java index 4b5d62467af0..5e6f3a46de7d 100644 --- a/core/java/com/android/internal/widget/SlidingTab.java +++ b/core/java/com/android/internal/widget/SlidingTab.java @@ -16,7 +16,7 @@ package com.android.internal.widget; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; import android.content.res.Resources; import android.content.res.TypedArray; @@ -34,12 +34,12 @@ import android.view.View; import android.view.ViewGroup; import android.view.animation.AlphaAnimation; import android.view.animation.Animation; +import android.view.animation.Animation.AnimationListener; import android.view.animation.LinearInterpolator; import android.view.animation.TranslateAnimation; -import android.view.animation.Animation.AnimationListener; import android.widget.ImageView; -import android.widget.TextView; import android.widget.ImageView.ScaleType; +import android.widget.TextView; import com.android.internal.R; diff --git a/core/java/com/android/internal/widget/TextViewInputDisabler.java b/core/java/com/android/internal/widget/TextViewInputDisabler.java index 8d8f0fe52d64..57806eb21dcf 100644 --- a/core/java/com/android/internal/widget/TextViewInputDisabler.java +++ b/core/java/com/android/internal/widget/TextViewInputDisabler.java @@ -16,7 +16,7 @@ package com.android.internal.widget; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.text.InputFilter; import android.text.Spanned; import android.widget.TextView; diff --git a/core/java/com/android/internal/widget/ViewPager.java b/core/java/com/android/internal/widget/ViewPager.java index 7d36b02d4157..c8a86d108134 100644 --- a/core/java/com/android/internal/widget/ViewPager.java +++ b/core/java/com/android/internal/widget/ViewPager.java @@ -18,7 +18,7 @@ package com.android.internal.widget; import android.annotation.DrawableRes; import android.annotation.NonNull; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; import android.content.res.Resources; import android.content.res.TypedArray; diff --git a/core/java/com/android/server/ResettableTimeout.java b/core/java/com/android/server/ResettableTimeout.java index 64083f72aff5..511af941bf76 100644 --- a/core/java/com/android/server/ResettableTimeout.java +++ b/core/java/com/android/server/ResettableTimeout.java @@ -16,10 +16,9 @@ package com.android.server; -import android.os.SystemClock; - -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.os.ConditionVariable; +import android.os.SystemClock; /** * Utility class that you can call on with a timeout, and get called back diff --git a/core/java/com/android/server/net/BaseNetworkObserver.java b/core/java/com/android/server/net/BaseNetworkObserver.java index e1a10a5805f5..2a9c0b44b45e 100644 --- a/core/java/com/android/server/net/BaseNetworkObserver.java +++ b/core/java/com/android/server/net/BaseNetworkObserver.java @@ -16,7 +16,7 @@ package com.android.server.net; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.net.INetworkManagementEventObserver; import android.net.LinkAddress; import android.net.RouteInfo; diff --git a/core/java/com/android/server/net/NetlinkTracker.java b/core/java/com/android/server/net/NetlinkTracker.java index 647fb5b9d079..b57397f46a7e 100644 --- a/core/java/com/android/server/net/NetlinkTracker.java +++ b/core/java/com/android/server/net/NetlinkTracker.java @@ -16,7 +16,7 @@ package com.android.server.net; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.net.LinkAddress; import android.net.LinkProperties; import android.net.RouteInfo; diff --git a/core/java/com/google/android/collect/Lists.java b/core/java/com/google/android/collect/Lists.java index 8f6594aefb0a..585847da566c 100644 --- a/core/java/com/google/android/collect/Lists.java +++ b/core/java/com/google/android/collect/Lists.java @@ -16,7 +16,8 @@ package com.google.android.collect; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; + import java.util.ArrayList; import java.util.Collections; diff --git a/core/java/com/google/android/collect/Maps.java b/core/java/com/google/android/collect/Maps.java index 6ba33207631a..cd4c1280545e 100644 --- a/core/java/com/google/android/collect/Maps.java +++ b/core/java/com/google/android/collect/Maps.java @@ -16,7 +16,7 @@ package com.google.android.collect; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.util.ArrayMap; import java.util.HashMap; diff --git a/core/java/com/google/android/collect/Sets.java b/core/java/com/google/android/collect/Sets.java index 09b5e51ae2c6..c67a88a19080 100644 --- a/core/java/com/google/android/collect/Sets.java +++ b/core/java/com/google/android/collect/Sets.java @@ -16,7 +16,7 @@ package com.google.android.collect; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.util.ArraySet; import java.util.Collections; diff --git a/core/java/com/google/android/util/AbstractMessageParser.java b/core/java/com/google/android/util/AbstractMessageParser.java index 00fcb16f6d3a..b41ac1f36a91 100644 --- a/core/java/com/google/android/util/AbstractMessageParser.java +++ b/core/java/com/google/android/util/AbstractMessageParser.java @@ -16,7 +16,7 @@ package com.google.android.util; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import java.util.ArrayList; import java.util.HashMap; diff --git a/core/java/org/apache/http/conn/ssl/AbstractVerifier.java b/core/java/org/apache/http/conn/ssl/AbstractVerifier.java index 36d6e22ca847..2848ad7796af 100644 --- a/core/java/org/apache/http/conn/ssl/AbstractVerifier.java +++ b/core/java/org/apache/http/conn/ssl/AbstractVerifier.java @@ -31,7 +31,7 @@ package org.apache.http.conn.ssl; -import java.util.regex.Pattern; +import android.compat.annotation.UnsupportedAppUsage; import java.io.IOException; import java.security.cert.Certificate; @@ -43,10 +43,10 @@ import java.util.Iterator; import java.util.LinkedList; import java.util.List; import java.util.Locale; -import java.util.logging.Logger; import java.util.logging.Level; +import java.util.logging.Logger; +import java.util.regex.Pattern; -import android.annotation.UnsupportedAppUsage; import javax.net.ssl.SSLException; import javax.net.ssl.SSLSession; import javax.net.ssl.SSLSocket; diff --git a/core/java/org/apache/http/conn/ssl/SSLSocketFactory.java b/core/java/org/apache/http/conn/ssl/SSLSocketFactory.java index b2e8b5e7af05..ffae7570ea79 100644 --- a/core/java/org/apache/http/conn/ssl/SSLSocketFactory.java +++ b/core/java/org/apache/http/conn/ssl/SSLSocketFactory.java @@ -31,20 +31,14 @@ package org.apache.http.conn.ssl; +import android.compat.annotation.UnsupportedAppUsage; +import android.os.Build; + import org.apache.http.conn.scheme.HostNameResolver; import org.apache.http.conn.scheme.LayeredSocketFactory; import org.apache.http.params.HttpConnectionParams; import org.apache.http.params.HttpParams; -import android.annotation.UnsupportedAppUsage; -import android.os.Build; -import javax.net.ssl.HttpsURLConnection; -import javax.net.ssl.KeyManager; -import javax.net.ssl.KeyManagerFactory; -import javax.net.ssl.SSLContext; -import javax.net.ssl.SSLSocket; -import javax.net.ssl.TrustManager; -import javax.net.ssl.TrustManagerFactory; import java.io.IOException; import java.net.InetAddress; import java.net.InetSocketAddress; @@ -57,6 +51,14 @@ import java.security.NoSuchAlgorithmException; import java.security.SecureRandom; import java.security.UnrecoverableKeyException; +import javax.net.ssl.HttpsURLConnection; +import javax.net.ssl.KeyManager; +import javax.net.ssl.KeyManagerFactory; +import javax.net.ssl.SSLContext; +import javax.net.ssl.SSLSocket; +import javax.net.ssl.TrustManager; +import javax.net.ssl.TrustManagerFactory; + /** * Layered socket factory for TLS/SSL connections, based on JSSE. *. diff --git a/core/jni/com_android_internal_os_Zygote.cpp b/core/jni/com_android_internal_os_Zygote.cpp index 58fd9c0ab85e..8cff0fde11f7 100644 --- a/core/jni/com_android_internal_os_Zygote.cpp +++ b/core/jni/com_android_internal_os_Zygote.cpp @@ -169,6 +169,15 @@ static int gUsapPoolEventFD = -1; */ static constexpr int USAP_POOL_SIZE_MAX_LIMIT = 100; +/** The numeric value for the maximum priority a process may possess. */ +static constexpr int PROCESS_PRIORITY_MAX = -20; + +/** The numeric value for the minimum priority a process may possess. */ +static constexpr int PROCESS_PRIORITY_MIN = 19; + +/** The numeric value for the normal priority a process should have. */ +static constexpr int PROCESS_PRIORITY_DEFAULT = 0; + /** * A helper class containing accounting information for USAPs. */ @@ -903,7 +912,8 @@ static void ClearUsapTable() { // Utility routine to fork a process from the zygote. static pid_t ForkCommon(JNIEnv* env, bool is_system_server, const std::vector<int>& fds_to_close, - const std::vector<int>& fds_to_ignore) { + const std::vector<int>& fds_to_ignore, + bool is_priority_fork) { SetSignalHandlers(); // Curry a failure function. @@ -936,6 +946,12 @@ static pid_t ForkCommon(JNIEnv* env, bool is_system_server, pid_t pid = fork(); if (pid == 0) { + if (is_priority_fork) { + setpriority(PRIO_PROCESS, 0, PROCESS_PRIORITY_MAX); + } else { + setpriority(PRIO_PROCESS, 0, PROCESS_PRIORITY_MIN); + } + // The child process. PreApplicationInit(); @@ -1133,6 +1149,9 @@ static void SpecializeCommon(JNIEnv* env, uid_t uid, gid_t gid, jintArray gids, env->CallStaticVoidMethod(gZygoteClass, gCallPostForkChildHooks, runtime_flags, is_system_server, is_child_zygote, managed_instruction_set); + // Reset the process priority to the default value. + setpriority(PRIO_PROCESS, 0, PROCESS_PRIORITY_DEFAULT); + if (env->ExceptionCheck()) { fail_fn("Error calling post fork hooks."); } @@ -1372,7 +1391,7 @@ static jint com_android_internal_os_Zygote_nativeForkAndSpecialize( fds_to_ignore.push_back(gUsapPoolEventFD); } - pid_t pid = ForkCommon(env, false, fds_to_close, fds_to_ignore); + pid_t pid = ForkCommon(env, false, fds_to_close, fds_to_ignore, true); if (pid == 0) { SpecializeCommon(env, uid, gid, gids, runtime_flags, rlimits, @@ -1399,7 +1418,8 @@ static jint com_android_internal_os_Zygote_nativeForkSystemServer( pid_t pid = ForkCommon(env, true, fds_to_close, - fds_to_ignore); + fds_to_ignore, + true); if (pid == 0) { SpecializeCommon(env, uid, gid, gids, runtime_flags, rlimits, permitted_capabilities, effective_capabilities, @@ -1441,13 +1461,15 @@ static jint com_android_internal_os_Zygote_nativeForkSystemServer( * zygote in managed code. * @param managed_session_socket_fds A list of anonymous session sockets that must be ignored by * the FD hygiene code and automatically "closed" in the new USAP. + * @param is_priority_fork Controls the nice level assigned to the newly created process * @return */ static jint com_android_internal_os_Zygote_nativeForkUsap(JNIEnv* env, jclass, jint read_pipe_fd, jint write_pipe_fd, - jintArray managed_session_socket_fds) { + jintArray managed_session_socket_fds, + jboolean is_priority_fork) { std::vector<int> fds_to_close(MakeUsapPipeReadFDVector()), fds_to_ignore(fds_to_close); @@ -1469,7 +1491,8 @@ static jint com_android_internal_os_Zygote_nativeForkUsap(JNIEnv* env, fds_to_ignore.push_back(write_pipe_fd); fds_to_ignore.insert(fds_to_ignore.end(), session_socket_fds.begin(), session_socket_fds.end()); - pid_t usap_pid = ForkCommon(env, /* is_system_server= */ false, fds_to_close, fds_to_ignore); + pid_t usap_pid = ForkCommon(env, /* is_system_server= */ false, fds_to_close, fds_to_ignore, + is_priority_fork == JNI_TRUE); if (usap_pid != 0) { ++gUsapPoolCount; @@ -1706,6 +1729,10 @@ static void com_android_internal_os_Zygote_nativeUnblockSigTerm(JNIEnv* env, jcl UnblockSignal(SIGTERM, fail_fn); } +static void com_android_internal_os_Zygote_nativeBoostUsapPriority(JNIEnv* env, jclass) { + setpriority(PRIO_PROCESS, 0, PROCESS_PRIORITY_MAX); +} + static const JNINativeMethod gMethods[] = { { "nativeForkAndSpecialize", "(II[II[[IILjava/lang/String;Ljava/lang/String;[I[IZLjava/lang/String;Ljava/lang/String;)I", @@ -1718,7 +1745,7 @@ static const JNINativeMethod gMethods[] = { (void *) com_android_internal_os_Zygote_nativePreApplicationInit }, { "nativeInstallSeccompUidGidFilter", "(II)V", (void *) com_android_internal_os_Zygote_nativeInstallSeccompUidGidFilter }, - { "nativeForkUsap", "(II[I)I", + { "nativeForkUsap", "(II[IZ)I", (void *) com_android_internal_os_Zygote_nativeForkUsap }, { "nativeSpecializeAppProcess", "(II[II[[IILjava/lang/String;Ljava/lang/String;ZLjava/lang/String;Ljava/lang/String;)V", @@ -1740,7 +1767,9 @@ static const JNINativeMethod gMethods[] = { { "nativeBlockSigTerm", "()V", (void* ) com_android_internal_os_Zygote_nativeBlockSigTerm }, { "nativeUnblockSigTerm", "()V", - (void* ) com_android_internal_os_Zygote_nativeUnblockSigTerm } + (void* ) com_android_internal_os_Zygote_nativeUnblockSigTerm }, + { "nativeBoostUsapPriority", "()V", + (void* ) com_android_internal_os_Zygote_nativeBoostUsapPriority } }; int register_com_android_internal_os_Zygote(JNIEnv* env) { diff --git a/core/jni/fd_utils.cpp b/core/jni/fd_utils.cpp index ee74f6d7ab94..1b6d622e917e 100644 --- a/core/jni/fd_utils.cpp +++ b/core/jni/fd_utils.cpp @@ -33,23 +33,23 @@ // Static whitelist of open paths that the zygote is allowed to keep open. static const char* kPathWhitelist[] = { - "/apex/com.android.conscrypt/javalib/conscrypt.jar", - "/apex/com.android.ipsec/javalib/ike.jar", - "/apex/com.android.media/javalib/updatable-media.jar", - "/apex/com.android.sdkext/javalib/framework-sdkext.jar", - "/apex/com.android.tethering/javalib/framework-tethering.jar", - "/dev/null", - "/dev/socket/zygote", - "/dev/socket/zygote_secondary", - "/dev/socket/usap_pool_primary", - "/dev/socket/usap_pool_secondary", - "/dev/socket/webview_zygote", - "/dev/socket/heapprofd", - "/sys/kernel/debug/tracing/trace_marker", - "/system/framework/framework-res.apk", - "/dev/urandom", - "/dev/ion", - "/dev/dri/renderD129", // Fixes b/31172436 + "/apex/com.android.conscrypt/javalib/conscrypt.jar", + "/apex/com.android.ipsec/javalib/ike.jar", + "/apex/com.android.media/javalib/updatable-media.jar", + "/apex/com.android.sdkext/javalib/framework-sdkextensions.jar", + "/apex/com.android.tethering/javalib/framework-tethering.jar", + "/dev/null", + "/dev/socket/zygote", + "/dev/socket/zygote_secondary", + "/dev/socket/usap_pool_primary", + "/dev/socket/usap_pool_secondary", + "/dev/socket/webview_zygote", + "/dev/socket/heapprofd", + "/sys/kernel/debug/tracing/trace_marker", + "/system/framework/framework-res.apk", + "/dev/urandom", + "/dev/ion", + "/dev/dri/renderD129", // Fixes b/31172436 }; static const char kFdPath[] = "/proc/self/fd"; diff --git a/core/proto/android/server/jobscheduler.proto b/core/proto/android/server/jobscheduler.proto index 28733798b9ad..7452f809a14d 100644 --- a/core/proto/android/server/jobscheduler.proto +++ b/core/proto/android/server/jobscheduler.proto @@ -232,6 +232,8 @@ message ConstantsProto { // Whether or not TimeController should skip setting wakeup alarms for jobs that aren't // ready now. optional bool skip_not_ready_jobs = 1; + // Whether or not TimeController will use a non-wakeup alarm for delay constraints. + optional bool use_non_wakeup_alarm_for_delay = 2; } optional TimeController time_controller = 25; diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml index 6d71c508bf1c..9aa42ff9fff3 100644 --- a/core/res/AndroidManifest.xml +++ b/core/res/AndroidManifest.xml @@ -451,7 +451,6 @@ <protected-broadcast android:name="android.intent.action.internal_sim_state_changed" /> <protected-broadcast android:name="android.intent.action.LOCKED_BOOT_COMPLETED" /> <protected-broadcast android:name="android.intent.action.PRECISE_CALL_STATE" /> - <protected-broadcast android:name="android.intent.action.PRECISE_DATA_CONNECTION_STATE_CHANGED" /> <protected-broadcast android:name="android.intent.action.SUBSCRIPTION_PHONE_STATE" /> <protected-broadcast android:name="android.intent.action.USER_INFO_CHANGED" /> <protected-broadcast android:name="android.intent.action.USER_UNLOCKED" /> @@ -634,10 +633,6 @@ <protected-broadcast android:name="android.intent.action.DEVICE_CUSTOMIZATION_READY" /> - <!-- NETWORK_SET_TIME moved from com.android.phone to system server. It should ultimately be - removed. --> - <protected-broadcast android:name="android.telephony.action.NETWORK_SET_TIME" /> - <!-- For tether entitlement recheck--> <protected-broadcast android:name="com.android.server.connectivity.tethering.PROVISIONING_RECHECK_ALARM" /> @@ -721,6 +716,11 @@ <!-- ====================================================================== --> <eat-comment /> + <!-- @SystemApi Allows accessing the messages on ICC + @hide Used internally. --> + <permission android:name="android.permission.ACCESS_MESSAGES_ON_ICC" + android:protectionLevel="signature|telephony" /> + <!-- Used for runtime permissions related to user's SMS messages. --> <permission-group android:name="android.permission-group.SMS" android:icon="@drawable/perm_group_sms" @@ -1778,6 +1778,11 @@ android:label="@string/permlab_preferredPaymentInfo" android:protectionLevel="normal" /> + <!-- @SystemApi Allows an internal user to use privileged SecureElement APIs. + @hide --> + <permission android:name="android.permission.SECURE_ELEMENT_PRIVILEGED" + android:protectionLevel="signature|privileged" /> + <!-- @deprecated This permission used to allow too broad access to sensitive methods and all its uses have been replaced by a more appropriate permission. Most uses have been replaced with a NETWORK_STACK or NETWORK_SETTINGS check. Please look up the documentation of the @@ -2058,8 +2063,10 @@ android:protectionLevel="signature|privileged" /> <!-- Allows read only access to precise phone state. - @hide Pending API council approval --> + Allows reading of detailed information about phone state for special-use applications + such as dialers, carrier applications, or ims applications. --> <permission android:name="android.permission.READ_PRECISE_PHONE_STATE" + android:permissionGroup="android.permission-group.UNDEFINED" android:protectionLevel="signature|privileged" /> <!-- @SystemApi Allows read access to privileged phone state. @@ -2544,7 +2551,7 @@ <!-- Allows telephony to suggest the time / time zone. <p>Not for use by third-party applications. - @hide + @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES) @hide --> <permission android:name="android.permission.SUGGEST_PHONE_TIME_AND_ZONE" android:protectionLevel="signature|telephony" /> diff --git a/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/WifiConfigurationHelper.java b/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/WifiConfigurationHelper.java index f0a83678f70b..a296ca27e268 100644 --- a/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/WifiConfigurationHelper.java +++ b/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/WifiConfigurationHelper.java @@ -16,6 +16,7 @@ package com.android.connectivitymanagertest; +import android.net.IpConfiguration; import android.net.IpConfiguration.IpAssignment; import android.net.IpConfiguration.ProxySettings; import android.net.LinkAddress; @@ -136,7 +137,7 @@ public class WifiConfigurationHelper { config.enterpriseConfig.setPhase2Method(phase2); config.enterpriseConfig.setIdentity(identity); config.enterpriseConfig.setAnonymousIdentity(anonymousIdentity); - config.enterpriseConfig.setCaCertificateAlias(caCert); + config.enterpriseConfig.setCaCertificateAliases(new String[] {caCert}); config.enterpriseConfig.setClientCertificateAlias(clientCert); return config; } @@ -147,8 +148,12 @@ public class WifiConfigurationHelper { private static WifiConfiguration createGenericConfig(String ssid) { WifiConfiguration config = new WifiConfiguration(); config.SSID = quotedString(ssid); - config.setIpAssignment(IpAssignment.DHCP); - config.setProxySettings(ProxySettings.NONE); + + IpConfiguration ipConfiguration = config.getIpConfiguration(); + ipConfiguration.setIpAssignment(IpAssignment.DHCP); + ipConfiguration.setProxySettings(ProxySettings.NONE); + config.setIpConfiguration(ipConfiguration); + return config; } @@ -237,6 +242,7 @@ public class WifiConfigurationHelper { throw new IllegalArgumentException(); } + IpConfiguration ipConfiguration = config.getIpConfiguration(); if (jsonConfig.has("ip")) { StaticIpConfiguration staticIpConfig = new StaticIpConfiguration(); @@ -247,13 +253,14 @@ public class WifiConfigurationHelper { staticIpConfig.dnsServers.add(getInetAddress(jsonConfig.getString("dns1"))); staticIpConfig.dnsServers.add(getInetAddress(jsonConfig.getString("dns2"))); - config.setIpAssignment(IpAssignment.STATIC); - config.setStaticIpConfiguration(staticIpConfig); + ipConfiguration.setIpAssignment(IpAssignment.STATIC); + ipConfiguration.setStaticIpConfiguration(staticIpConfig); } else { - config.setIpAssignment(IpAssignment.DHCP); + ipConfiguration.setIpAssignment(IpAssignment.DHCP); } + ipConfiguration.setProxySettings(ProxySettings.NONE); + config.setIpConfiguration(ipConfiguration); - config.setProxySettings(ProxySettings.NONE); return config; } diff --git a/core/tests/bandwidthtests/src/com/android/bandwidthtest/BandwidthTest.java b/core/tests/bandwidthtests/src/com/android/bandwidthtest/BandwidthTest.java index 2989df83866c..5d42915fc82b 100644 --- a/core/tests/bandwidthtests/src/com/android/bandwidthtest/BandwidthTest.java +++ b/core/tests/bandwidthtests/src/com/android/bandwidthtest/BandwidthTest.java @@ -268,7 +268,7 @@ public class BandwidthTest extends InstrumentationTestCase { File snd_stat = new File (root_filepath + "tcp_snd"); int tx = BandwidthTestUtil.parseIntValueFromFile(snd_stat); NetworkStats stats = new NetworkStats(SystemClock.elapsedRealtime(), 1); - stats.addValues(NetworkStats.IFACE_ALL, uid, NetworkStats.SET_DEFAULT, + stats.addEntry(NetworkStats.IFACE_ALL, uid, NetworkStats.SET_DEFAULT, NetworkStats.TAG_NONE, rx, 0, tx, 0, 0); return stats; } diff --git a/core/tests/benchmarks/src/android/net/NetworkStatsBenchmark.java b/core/tests/benchmarks/src/android/net/NetworkStatsBenchmark.java index 707d7b30e09b..239f971664e9 100644 --- a/core/tests/benchmarks/src/android/net/NetworkStatsBenchmark.java +++ b/core/tests/benchmarks/src/android/net/NetworkStatsBenchmark.java @@ -54,7 +54,7 @@ public class NetworkStatsBenchmark { recycle.txBytes = 150000; recycle.txPackets = 1500; recycle.operations = 0; - mNetworkStats.addValues(recycle); + mNetworkStats.addEntry(recycle); if (recycle.set == 1) { uid++; } @@ -70,7 +70,7 @@ public class NetworkStatsBenchmark { recycle.txBytes = 180000 * mSize; recycle.txPackets = 1200 * mSize; recycle.operations = 0; - mNetworkStats.addValues(recycle); + mNetworkStats.addEntry(recycle); } } diff --git a/core/tests/coretests/src/android/app/DownloadManagerBaseTest.java b/core/tests/coretests/src/android/app/DownloadManagerBaseTest.java index 68b9b0079761..f4709ff0bc00 100644 --- a/core/tests/coretests/src/android/app/DownloadManagerBaseTest.java +++ b/core/tests/coretests/src/android/app/DownloadManagerBaseTest.java @@ -33,14 +33,15 @@ import android.os.ParcelFileDescriptor.AutoCloseInputStream; import android.os.SystemClock; import android.os.UserHandle; import android.provider.Settings; +import android.support.test.uiautomator.UiDevice; import android.test.InstrumentationTestCase; import android.util.Log; -import libcore.io.Streams; - import com.google.mockwebserver.MockResponse; import com.google.mockwebserver.MockWebServer; +import libcore.io.Streams; + import java.io.DataInputStream; import java.io.DataOutputStream; import java.io.File; @@ -63,6 +64,7 @@ public class DownloadManagerBaseTest extends InstrumentationTestCase { private static final String TAG = "DownloadManagerBaseTest"; protected DownloadManager mDownloadManager = null; private MockWebServer mServer = null; + private UiDevice mUiDevice = null; protected String mFileType = "text/plain"; protected Context mContext = null; protected MultipleDownloadsCompletedReceiver mReceiver = null; @@ -234,6 +236,7 @@ public class DownloadManagerBaseTest extends InstrumentationTestCase { @Override public void setUp() throws Exception { mContext = getInstrumentation().getContext(); + mUiDevice = UiDevice.getInstance(getInstrumentation()); mDownloadManager = (DownloadManager)mContext.getSystemService(Context.DOWNLOAD_SERVICE); mServer = new MockWebServer(); mServer.play(); @@ -512,7 +515,7 @@ public class DownloadManagerBaseTest extends InstrumentationTestCase { Log.i(LOG_TAG, "Setting WiFi State to: " + enable); WifiManager manager = (WifiManager)mContext.getSystemService(Context.WIFI_SERVICE); - manager.setWifiEnabled(enable); + mUiDevice.executeShellCommand("svc wifi " + (enable ? "enable" : "disable")); String timeoutMessage = "Timed out waiting for Wifi to be " + (enable ? "enabled!" : "disabled!"); diff --git a/core/tests/coretests/src/android/app/timedetector/ManualTimeSuggestionTest.java b/core/tests/coretests/src/android/app/timedetector/ManualTimeSuggestionTest.java index de6f8f7231fa..750ffa1c9a54 100644 --- a/core/tests/coretests/src/android/app/timedetector/ManualTimeSuggestionTest.java +++ b/core/tests/coretests/src/android/app/timedetector/ManualTimeSuggestionTest.java @@ -22,7 +22,7 @@ import static android.app.timezonedetector.ParcelableTestSupport.roundTripParcel import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotEquals; -import android.util.TimestampedValue; +import android.os.TimestampedValue; import org.junit.Test; diff --git a/core/tests/coretests/src/android/app/timedetector/NetworkTimeSuggestionTest.java b/core/tests/coretests/src/android/app/timedetector/NetworkTimeSuggestionTest.java index 9b3d0c9eaff6..b88c36f20bc6 100644 --- a/core/tests/coretests/src/android/app/timedetector/NetworkTimeSuggestionTest.java +++ b/core/tests/coretests/src/android/app/timedetector/NetworkTimeSuggestionTest.java @@ -22,7 +22,7 @@ import static android.app.timezonedetector.ParcelableTestSupport.roundTripParcel import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotEquals; -import android.util.TimestampedValue; +import android.os.TimestampedValue; import org.junit.Test; diff --git a/core/tests/coretests/src/android/app/timedetector/PhoneTimeSuggestionTest.java b/core/tests/coretests/src/android/app/timedetector/PhoneTimeSuggestionTest.java index bee270e5f5c9..ba29a97b55ab 100644 --- a/core/tests/coretests/src/android/app/timedetector/PhoneTimeSuggestionTest.java +++ b/core/tests/coretests/src/android/app/timedetector/PhoneTimeSuggestionTest.java @@ -22,7 +22,7 @@ import static android.app.timezonedetector.ParcelableTestSupport.roundTripParcel import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotEquals; -import android.util.TimestampedValue; +import android.os.TimestampedValue; import org.junit.Test; diff --git a/core/tests/coretests/src/android/net/NetworkKeyTest.java b/core/tests/coretests/src/android/net/NetworkKeyTest.java index c6c0b46d0505..b13bcd1311f6 100644 --- a/core/tests/coretests/src/android/net/NetworkKeyTest.java +++ b/core/tests/coretests/src/android/net/NetworkKeyTest.java @@ -18,6 +18,7 @@ package android.net; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNull; +import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; import android.net.wifi.ScanResult; @@ -107,7 +108,7 @@ public class NetworkKeyTest { @Test public void createFromScanResult_nullSsid() { - ScanResult scanResult = new ScanResult(); + ScanResult scanResult = mock(ScanResult.class); scanResult.BSSID = VALID_BSSID; assertNull(NetworkKey.createFromScanResult(scanResult)); @@ -115,7 +116,7 @@ public class NetworkKeyTest { @Test public void createFromScanResult_emptySsid() { - ScanResult scanResult = new ScanResult(); + ScanResult scanResult = mock(ScanResult.class); scanResult.SSID = ""; scanResult.BSSID = VALID_BSSID; @@ -124,7 +125,7 @@ public class NetworkKeyTest { @Test public void createFromScanResult_noneSsid() { - ScanResult scanResult = new ScanResult(); + ScanResult scanResult = mock(ScanResult.class); scanResult.SSID = WifiManager.UNKNOWN_SSID; scanResult.BSSID = VALID_BSSID; @@ -133,7 +134,7 @@ public class NetworkKeyTest { @Test public void createFromScanResult_nullBssid() { - ScanResult scanResult = new ScanResult(); + ScanResult scanResult = mock(ScanResult.class); scanResult.SSID = VALID_UNQUOTED_SSID; assertNull(NetworkKey.createFromScanResult(scanResult)); @@ -141,7 +142,7 @@ public class NetworkKeyTest { @Test public void createFromScanResult_emptyBssid() { - ScanResult scanResult = new ScanResult(); + ScanResult scanResult = mock(ScanResult.class); scanResult.SSID = VALID_UNQUOTED_SSID; scanResult.BSSID = ""; @@ -150,7 +151,7 @@ public class NetworkKeyTest { @Test public void createFromScanResult_invalidBssid() { - ScanResult scanResult = new ScanResult(); + ScanResult scanResult = mock(ScanResult.class); scanResult.SSID = VALID_UNQUOTED_SSID; scanResult.BSSID = INVALID_BSSID; @@ -159,7 +160,7 @@ public class NetworkKeyTest { @Test public void createFromScanResult_validSsid() { - ScanResult scanResult = new ScanResult(); + ScanResult scanResult = mock(ScanResult.class); scanResult.SSID = VALID_UNQUOTED_SSID; scanResult.BSSID = VALID_BSSID; diff --git a/core/tests/coretests/src/android/util/TimestampedValueTest.java b/core/tests/coretests/src/android/os/TimestampedValueTest.java index 6fc2400316c2..f36d9e6b1eff 100644 --- a/core/tests/coretests/src/android/util/TimestampedValueTest.java +++ b/core/tests/coretests/src/android/os/TimestampedValueTest.java @@ -14,14 +14,12 @@ * limitations under the License. */ -package android.util; +package android.os; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotEquals; import static org.junit.Assert.fail; -import android.os.Parcel; - import androidx.test.runner.AndroidJUnit4; import org.junit.Test; diff --git a/core/tests/coretests/src/android/util/StatsEventTest.java b/core/tests/coretests/src/android/util/StatsEventTest.java new file mode 100644 index 000000000000..ac25e2734ac9 --- /dev/null +++ b/core/tests/coretests/src/android/util/StatsEventTest.java @@ -0,0 +1,474 @@ +/* + * 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; + +/** + * 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 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(); + } + + 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/core/tests/utiltests/src/com/android/internal/util/ConnectivityUtilTest.java b/core/tests/utiltests/src/com/android/internal/util/ConnectivityUtilTest.java new file mode 100644 index 000000000000..556471260141 --- /dev/null +++ b/core/tests/utiltests/src/com/android/internal/util/ConnectivityUtilTest.java @@ -0,0 +1,286 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES 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.util; + +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.Mockito.doAnswer; +import static org.mockito.Mockito.doThrow; +import static org.mockito.Mockito.never; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +import android.Manifest; +import android.app.AppOpsManager; +import android.content.Context; +import android.content.pm.ApplicationInfo; +import android.content.pm.PackageManager; +import android.location.LocationManager; +import android.os.Binder; +import android.os.Build; +import android.os.UserHandle; +import android.os.UserManager; + +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; +import org.mockito.invocation.InvocationOnMock; +import org.mockito.stubbing.Answer; + +import java.util.HashMap; + +/** Unit tests for {@link ConnectivityUtil}. */ +public class ConnectivityUtilTest { + + public static final String TAG = "ConnectivityUtilTest"; + + // Mock objects for testing + @Mock private Context mMockContext; + @Mock private PackageManager mMockPkgMgr; + @Mock private ApplicationInfo mMockApplInfo; + @Mock private AppOpsManager mMockAppOps; + @Mock private UserManager mMockUserManager; + @Mock private LocationManager mLocationManager; + + private static final String TEST_PKG_NAME = "com.google.somePackage"; + private static final String TEST_FEATURE_ID = "com.google.someFeature"; + private static final int MANAGED_PROFILE_UID = 1100000; + private static final int OTHER_USER_UID = 1200000; + + private final String mInteractAcrossUsersFullPermission = + "android.permission.INTERACT_ACROSS_USERS_FULL"; + private final String mManifestStringCoarse = + Manifest.permission.ACCESS_COARSE_LOCATION; + private final String mManifestStringFine = + Manifest.permission.ACCESS_FINE_LOCATION; + + // Test variables + private int mWifiScanAllowApps; + private int mUid; + private int mCoarseLocationPermission; + private int mAllowCoarseLocationApps; + private int mFineLocationPermission; + private int mAllowFineLocationApps; + private int mCurrentUser; + private boolean mIsLocationEnabled; + private boolean mThrowSecurityException; + private Answer<Integer> mReturnPermission; + private HashMap<String, Integer> mPermissionsList = new HashMap<String, Integer>(); + + private class TestConnectivityUtil extends ConnectivityUtil { + + TestConnectivityUtil(Context context) { + super(context); + } + + @Override + protected int getCurrentUser() { + return mCurrentUser; + } + } + + @Before + public void setUp() { + MockitoAnnotations.initMocks(this); + initTestVars(); + } + + private void setupMocks() throws Exception { + when(mMockPkgMgr.getApplicationInfoAsUser(eq(TEST_PKG_NAME), eq(0), any())) + .thenReturn(mMockApplInfo); + when(mMockContext.getPackageManager()).thenReturn(mMockPkgMgr); + when(mMockAppOps.noteOp(AppOpsManager.OPSTR_WIFI_SCAN, mUid, TEST_PKG_NAME)) + .thenReturn(mWifiScanAllowApps); + when(mMockAppOps.noteOp(eq(AppOpsManager.OPSTR_COARSE_LOCATION), eq(mUid), + eq(TEST_PKG_NAME))) + .thenReturn(mAllowCoarseLocationApps); + when(mMockAppOps.noteOp(eq(AppOpsManager.OPSTR_FINE_LOCATION), eq(mUid), + eq(TEST_PKG_NAME))) + .thenReturn(mAllowFineLocationApps); + if (mThrowSecurityException) { + doThrow(new SecurityException("Package " + TEST_PKG_NAME + " doesn't belong" + + " to application bound to user " + mUid)) + .when(mMockAppOps).checkPackage(mUid, TEST_PKG_NAME); + } + when(mMockContext.getSystemService(Context.APP_OPS_SERVICE)) + .thenReturn(mMockAppOps); + when(mMockContext.getSystemService(Context.USER_SERVICE)) + .thenReturn(mMockUserManager); + when(mMockContext.getSystemService(Context.LOCATION_SERVICE)).thenReturn(mLocationManager); + } + + private void setupTestCase() throws Exception { + setupMocks(); + setupMockInterface(); + } + + private void initTestVars() { + mPermissionsList.clear(); + mReturnPermission = createPermissionAnswer(); + mWifiScanAllowApps = AppOpsManager.MODE_ERRORED; + mUid = OTHER_USER_UID; + mThrowSecurityException = true; + mMockApplInfo.targetSdkVersion = Build.VERSION_CODES.M; + mIsLocationEnabled = false; + mCurrentUser = UserHandle.USER_SYSTEM; + mCoarseLocationPermission = PackageManager.PERMISSION_DENIED; + mFineLocationPermission = PackageManager.PERMISSION_DENIED; + mAllowCoarseLocationApps = AppOpsManager.MODE_ERRORED; + mAllowFineLocationApps = AppOpsManager.MODE_ERRORED; + } + + private void setupMockInterface() { + Binder.restoreCallingIdentity((((long) mUid) << 32) | Binder.getCallingPid()); + doAnswer(mReturnPermission).when(mMockContext).checkPermission( + anyString(), anyInt(), anyInt()); + when(mMockUserManager.isSameProfileGroup(UserHandle.SYSTEM.getIdentifier(), + UserHandle.getUserHandleForUid(MANAGED_PROFILE_UID).getIdentifier())) + .thenReturn(true); + when(mMockContext.checkPermission(mManifestStringCoarse, -1, mUid)) + .thenReturn(mCoarseLocationPermission); + when(mMockContext.checkPermission(mManifestStringFine, -1, mUid)) + .thenReturn(mFineLocationPermission); + when(mLocationManager.isLocationEnabledForUser(any())).thenReturn(mIsLocationEnabled); + } + + private Answer<Integer> createPermissionAnswer() { + return new Answer<Integer>() { + @Override + public Integer answer(InvocationOnMock invocation) { + int myUid = (int) invocation.getArguments()[1]; + String myPermission = (String) invocation.getArguments()[0]; + mPermissionsList.get(myPermission); + if (mPermissionsList.containsKey(myPermission)) { + int uid = mPermissionsList.get(myPermission); + if (myUid == uid) { + return PackageManager.PERMISSION_GRANTED; + } + } + return PackageManager.PERMISSION_DENIED; + } + }; + } + + @Test + public void testEnforceLocationPermission_HasAllPermissions_BeforeQ() throws Exception { + mIsLocationEnabled = true; + mThrowSecurityException = false; + mCoarseLocationPermission = PackageManager.PERMISSION_GRANTED; + mAllowCoarseLocationApps = AppOpsManager.MODE_ALLOWED; + mWifiScanAllowApps = AppOpsManager.MODE_ALLOWED; + mUid = mCurrentUser; + setupTestCase(); + new TestConnectivityUtil(mMockContext) + .enforceLocationPermission(TEST_PKG_NAME, TEST_FEATURE_ID, mUid, null); + } + + @Test + public void testEnforceLocationPermission_HasAllPermissions_AfterQ() throws Exception { + mMockApplInfo.targetSdkVersion = Build.VERSION_CODES.Q; + mIsLocationEnabled = true; + mThrowSecurityException = false; + mUid = mCurrentUser; + mFineLocationPermission = PackageManager.PERMISSION_GRANTED; + mAllowFineLocationApps = AppOpsManager.MODE_ALLOWED; + mWifiScanAllowApps = AppOpsManager.MODE_ALLOWED; + setupTestCase(); + new TestConnectivityUtil(mMockContext) + .enforceLocationPermission(TEST_PKG_NAME, TEST_FEATURE_ID, mUid, null); + } + + @Test + public void testEnforceLocationPermission_PkgNameAndUidMismatch() throws Exception { + mThrowSecurityException = true; + mIsLocationEnabled = true; + mFineLocationPermission = PackageManager.PERMISSION_GRANTED; + mAllowFineLocationApps = AppOpsManager.MODE_ALLOWED; + mWifiScanAllowApps = AppOpsManager.MODE_ALLOWED; + setupTestCase(); + + assertThrows(SecurityException.class, + () -> new TestConnectivityUtil(mMockContext) + .enforceLocationPermission(TEST_PKG_NAME, TEST_FEATURE_ID, mUid, null)); + } + + @Test + public void testenforceCanAccessScanResults_UserOrProfileNotCurrent() throws Exception { + mIsLocationEnabled = true; + mThrowSecurityException = false; + mCoarseLocationPermission = PackageManager.PERMISSION_GRANTED; + mAllowCoarseLocationApps = AppOpsManager.MODE_ALLOWED; + mWifiScanAllowApps = AppOpsManager.MODE_ALLOWED; + setupTestCase(); + + assertThrows(SecurityException.class, + () -> new TestConnectivityUtil(mMockContext) + .enforceLocationPermission(TEST_PKG_NAME, TEST_FEATURE_ID, mUid, null)); + } + + @Test + public void testenforceCanAccessScanResults_NoCoarseLocationPermission() throws Exception { + mThrowSecurityException = false; + mIsLocationEnabled = true; + setupTestCase(); + assertThrows(SecurityException.class, + () -> new TestConnectivityUtil(mMockContext) + .enforceLocationPermission(TEST_PKG_NAME, TEST_FEATURE_ID, mUid, null)); + } + + @Test + public void testenforceCanAccessScanResults_NoFineLocationPermission() throws Exception { + mThrowSecurityException = false; + mMockApplInfo.targetSdkVersion = Build.VERSION_CODES.Q; + mIsLocationEnabled = true; + mCoarseLocationPermission = PackageManager.PERMISSION_GRANTED; + mAllowFineLocationApps = AppOpsManager.MODE_ERRORED; + mUid = MANAGED_PROFILE_UID; + setupTestCase(); + + assertThrows(SecurityException.class, + () -> new TestConnectivityUtil(mMockContext) + .enforceLocationPermission(TEST_PKG_NAME, TEST_FEATURE_ID, mUid, null)); + verify(mMockAppOps, never()).noteOp(anyInt(), anyInt(), anyString()); + } + + @Test + public void testenforceCanAccessScanResults_LocationModeDisabled() throws Exception { + mThrowSecurityException = false; + mUid = MANAGED_PROFILE_UID; + mWifiScanAllowApps = AppOpsManager.MODE_ALLOWED; + mPermissionsList.put(mInteractAcrossUsersFullPermission, mUid); + mIsLocationEnabled = false; + + setupTestCase(); + + assertThrows(SecurityException.class, + () -> new TestConnectivityUtil(mMockContext) + .enforceLocationPermission(TEST_PKG_NAME, TEST_FEATURE_ID, mUid, null)); + } + + private static void assertThrows(Class<? extends Exception> exceptionClass, Runnable r) { + try { + r.run(); + Assert.fail("Expected " + exceptionClass + " to be thrown."); + } catch (Exception exception) { + assertTrue(exceptionClass.isInstance(exception)); + } + } +} diff --git a/data/etc/Android.bp b/data/etc/Android.bp index 4493f3a8dddc..0d12e1f7f83d 100644 --- a/data/etc/Android.bp +++ b/data/etc/Android.bp @@ -43,7 +43,7 @@ prebuilt_etc { prebuilt_etc { name: "privapp_whitelist_com.android.carrierconfig", - product_specific: true, + system_ext_specific: true, sub_dir: "permissions", src: "com.android.carrierconfig.xml", filename_from_src: true, @@ -67,7 +67,7 @@ prebuilt_etc { prebuilt_etc { name: "privapp_whitelist_com.android.emergency", - product_specific: true, + system_ext_specific: true, sub_dir: "permissions", src: "com.android.emergency.xml", filename_from_src: true, @@ -82,7 +82,7 @@ prebuilt_etc { prebuilt_etc { name: "privapp_whitelist_com.android.launcher3", - product_specific: true, + system_ext_specific: true, sub_dir: "permissions", src: "com.android.launcher3.xml", filename_from_src: true, @@ -90,7 +90,7 @@ prebuilt_etc { prebuilt_etc { name: "privapp_whitelist_com.android.provision", - product_specific: true, + system_ext_specific: true, sub_dir: "permissions", src: "com.android.provision.xml", filename_from_src: true, @@ -98,7 +98,7 @@ prebuilt_etc { prebuilt_etc { name: "privapp_whitelist_com.android.settings", - product_specific: true, + system_ext_specific: true, sub_dir: "permissions", src: "com.android.settings.xml", filename_from_src: true, @@ -114,7 +114,7 @@ prebuilt_etc { prebuilt_etc { name: "privapp_whitelist_com.android.storagemanager", - product_specific: true, + system_ext_specific: true, sub_dir: "permissions", src: "com.android.storagemanager.xml", filename_from_src: true, @@ -122,7 +122,7 @@ prebuilt_etc { prebuilt_etc { name: "privapp_whitelist_com.android.systemui", - product_specific: true, + system_ext_specific: true, sub_dir: "permissions", src: "com.android.systemui.xml", filename_from_src: true, diff --git a/data/etc/CleanSpec.mk b/data/etc/CleanSpec.mk new file mode 100644 index 000000000000..783a7edadeb7 --- /dev/null +++ b/data/etc/CleanSpec.mk @@ -0,0 +1,60 @@ +# 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. +# + +# If you don't need to do a full clean build but would like to touch +# a file or delete some intermediate files, add a clean step to the end +# of the list. These steps will only be run once, if they haven't been +# run before. +# +# E.g.: +# $(call add-clean-step, touch -c external/sqlite/sqlite3.h) +# $(call add-clean-step, rm -rf $(PRODUCT_OUT)/obj/STATIC_LIBRARIES/libz_intermediates) +# +# Always use "touch -c" and "rm -f" or "rm -rf" to gracefully deal with +# files that are missing or have been moved. +# +# Use $(PRODUCT_OUT) to get to the "out/target/product/blah/" directory. +# Use $(OUT_DIR) to refer to the "out" directory. +# +# If you need to re-do something that's already mentioned, just copy +# the command and add it to the bottom of the list. E.g., if a change +# that you made last week required touching a file and a change you +# made today requires touching the same file, just copy the old +# touch step and add it to the end of the list. +# +# ***************************************************************** +# NEWER CLEAN STEPS MUST BE AT THE END OF THE LIST ABOVE THE BANNER +# ***************************************************************** + +# For example: +#$(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/APPS/AndroidTests_intermediates) +#$(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/JAVA_LIBRARIES/core_intermediates) +#$(call add-clean-step, find $(OUT_DIR) -type f -name "IGTalkSession*" -print0 | xargs -0 rm -f) +#$(call add-clean-step, rm -rf $(PRODUCT_OUT)/data/*) +$(call add-clean-step, rm -rf $(PRODUCT_OUT)/system/product/etc/permissions/com.android.carrierconfig.xml) +$(call add-clean-step, rm -rf $(PRODUCT_OUT)/product/etc/permissions/com.android.carrierconfig.xml) +$(call add-clean-step, rm -rf $(PRODUCT_OUT)/system/product/etc/permissions/com.android.emergency.xml) +$(call add-clean-step, rm -rf $(PRODUCT_OUT)/product/etc/permissions/com.android.emergency.xml) +$(call add-clean-step, rm -rf $(PRODUCT_OUT)/system/product/etc/permissions/com.android.provision.xml) +$(call add-clean-step, rm -rf $(PRODUCT_OUT)/product/etc/permissions/com.android.provision.xml) +$(call add-clean-step, rm -rf $(PRODUCT_OUT)/system/product/etc/permissions/com.android.settings.xml) +$(call add-clean-step, rm -rf $(PRODUCT_OUT)/product/etc/permissions/com.android.settings.xml) +$(call add-clean-step, rm -rf $(PRODUCT_OUT)/system/product/etc/permissions/com.android.launcher3.xml) +$(call add-clean-step, rm -rf $(PRODUCT_OUT)/product/etc/permissions/com.android.launcher3.xml) +$(call add-clean-step, rm -rf $(PRODUCT_OUT)/system/product/etc/permissions/com.android.systemui.xml) +$(call add-clean-step, rm -rf $(PRODUCT_OUT)/product/etc/permissions/com.android.systemui.xml) +# ****************************************************************** +# NEWER CLEAN STEPS MUST BE AT THE END OF THE LIST ABOVE THIS BANNER +# ****************************************************************** diff --git a/data/etc/OWNERS b/data/etc/OWNERS index ea66ee373785..70d467829269 100644 --- a/data/etc/OWNERS +++ b/data/etc/OWNERS @@ -1 +1 @@ -per-file privapp-permissions-platform.xml = hackbod@android.com, jsharkey@android.com, svetoslavganov@google.com, toddke@google.com, yamasani@google.com, cbrubaker@google.com, jeffv@google.com, moltmann@google.com +per-file privapp-permissions-platform.xml = hackbod@android.com, jsharkey@android.com, svetoslavganov@google.com, toddke@google.com, yamasani@google.com, cbrubaker@google.com, jeffv@google.com, moltmann@google.com, lorenzo@google.com diff --git a/data/etc/car/Android.bp b/data/etc/car/Android.bp index 9272ea5e584b..7faf4cdcf66d 100644 --- a/data/etc/car/Android.bp +++ b/data/etc/car/Android.bp @@ -126,5 +126,5 @@ prebuilt_etc { sub_dir: "permissions", src: "com.android.car.developeroptions.xml", filename_from_src: true, - product_specific: true, + system_ext_specific: true, } diff --git a/data/etc/car/CleanSpec.mk b/data/etc/car/CleanSpec.mk new file mode 100644 index 000000000000..18f7d343676b --- /dev/null +++ b/data/etc/car/CleanSpec.mk @@ -0,0 +1,50 @@ +# 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. +# + +# If you don't need to do a full clean build but would like to touch +# a file or delete some intermediate files, add a clean step to the end +# of the list. These steps will only be run once, if they haven't been +# run before. +# +# E.g.: +# $(call add-clean-step, touch -c external/sqlite/sqlite3.h) +# $(call add-clean-step, rm -rf $(PRODUCT_OUT)/obj/STATIC_LIBRARIES/libz_intermediates) +# +# Always use "touch -c" and "rm -f" or "rm -rf" to gracefully deal with +# files that are missing or have been moved. +# +# Use $(PRODUCT_OUT) to get to the "out/target/product/blah/" directory. +# Use $(OUT_DIR) to refer to the "out" directory. +# +# If you need to re-do something that's already mentioned, just copy +# the command and add it to the bottom of the list. E.g., if a change +# that you made last week required touching a file and a change you +# made today requires touching the same file, just copy the old +# touch step and add it to the end of the list. +# +# ***************************************************************** +# NEWER CLEAN STEPS MUST BE AT THE END OF THE LIST ABOVE THE BANNER +# ***************************************************************** + +# For example: +#$(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/APPS/AndroidTests_intermediates) +#$(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/JAVA_LIBRARIES/core_intermediates) +#$(call add-clean-step, find $(OUT_DIR) -type f -name "IGTalkSession*" -print0 | xargs -0 rm -f) +#$(call add-clean-step, rm -rf $(PRODUCT_OUT)/data/*) +$(call add-clean-step, rm -rf $(PRODUCT_OUT)/system/product/etc/permissions/com.android.car.developeroptions.xml) +$(call add-clean-step, rm -rf $(PRODUCT_OUT)/product/etc/permissions/com.android.car.developeroptions.xml) +# ****************************************************************** +# NEWER CLEAN STEPS MUST BE AT THE END OF THE LIST ABOVE THIS BANNER +# ****************************************************************** diff --git a/data/etc/com.android.systemui.xml b/data/etc/com.android.systemui.xml index a305d48c4633..1d735674d72d 100644 --- a/data/etc/com.android.systemui.xml +++ b/data/etc/com.android.systemui.xml @@ -22,7 +22,6 @@ <permission name="android.permission.CHANGE_COMPONENT_ENABLED_STATE"/> <permission name="android.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST"/> <permission name="android.permission.CHANGE_OVERLAY_PACKAGES"/> - <permission name="android.permission.CONNECTIVITY_INTERNAL"/> <permission name="android.permission.CONTROL_KEYGUARD_SECURE_NOTIFICATIONS"/> <permission name="android.permission.CONTROL_REMOTE_APP_TRANSITION_ANIMATIONS"/> <permission name="android.permission.CONTROL_VPN"/> @@ -38,6 +37,7 @@ <permission name="android.permission.MODIFY_DAY_NIGHT_MODE"/> <permission name="android.permission.MODIFY_PHONE_STATE"/> <permission name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"/> + <permission name="android.permission.OBSERVE_NETWORK_POLICY"/> <permission name="android.permission.OVERRIDE_WIFI_CONFIG"/> <permission name="android.permission.READ_DREAM_STATE"/> <permission name="android.permission.READ_FRAME_BUFFER"/> diff --git a/data/etc/privapp-permissions-platform.xml b/data/etc/privapp-permissions-platform.xml index 0756647d5774..a818119f8103 100644 --- a/data/etc/privapp-permissions-platform.xml +++ b/data/etc/privapp-permissions-platform.xml @@ -238,7 +238,9 @@ applications that come with the platform <permission name="android.permission.MANAGE_USB"/> <permission name="android.permission.MODIFY_PHONE_STATE"/> <permission name="android.permission.READ_NETWORK_USAGE_HISTORY"/> + <permission name="android.permission.TETHER_PRIVILEGED"/> <permission name="android.permission.UPDATE_APP_OPS_STATS"/> + <permission name="android.permission.UPDATE_DEVICE_STATS"/> </privapp-permissions> <privapp-permissions package="com.android.server.telecom"> diff --git a/graphics/java/android/graphics/BaseCanvas.java b/graphics/java/android/graphics/BaseCanvas.java index 6e7f286d19a7..bee8d5efc933 100644 --- a/graphics/java/android/graphics/BaseCanvas.java +++ b/graphics/java/android/graphics/BaseCanvas.java @@ -21,7 +21,7 @@ import android.annotation.ColorLong; import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.Size; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.graphics.Canvas.VertexMode; import android.graphics.text.MeasuredText; import android.text.GraphicsOperations; diff --git a/graphics/java/android/graphics/Bitmap.java b/graphics/java/android/graphics/Bitmap.java index 44710178da5e..a8b7e1fa0113 100644 --- a/graphics/java/android/graphics/Bitmap.java +++ b/graphics/java/android/graphics/Bitmap.java @@ -21,8 +21,8 @@ import android.annotation.ColorInt; import android.annotation.ColorLong; import android.annotation.NonNull; import android.annotation.Nullable; -import android.annotation.UnsupportedAppUsage; import android.annotation.WorkerThread; +import android.compat.annotation.UnsupportedAppUsage; import android.content.res.ResourcesImpl; import android.hardware.HardwareBuffer; import android.os.Build; diff --git a/graphics/java/android/graphics/BitmapFactory.java b/graphics/java/android/graphics/BitmapFactory.java index 5623a8a49b35..bad487b47682 100644 --- a/graphics/java/android/graphics/BitmapFactory.java +++ b/graphics/java/android/graphics/BitmapFactory.java @@ -20,7 +20,7 @@ import static android.graphics.BitmapFactory.Options.validate; import android.annotation.NonNull; import android.annotation.Nullable; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.res.AssetManager; import android.content.res.Resources; import android.os.Trace; diff --git a/graphics/java/android/graphics/BitmapRegionDecoder.java b/graphics/java/android/graphics/BitmapRegionDecoder.java index 629d8c131b68..34eba97819aa 100644 --- a/graphics/java/android/graphics/BitmapRegionDecoder.java +++ b/graphics/java/android/graphics/BitmapRegionDecoder.java @@ -15,7 +15,7 @@ package android.graphics; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.res.AssetManager; import android.os.Build; diff --git a/graphics/java/android/graphics/BitmapShader.java b/graphics/java/android/graphics/BitmapShader.java index 198d1e7bc956..edf53c491311 100644 --- a/graphics/java/android/graphics/BitmapShader.java +++ b/graphics/java/android/graphics/BitmapShader.java @@ -17,7 +17,7 @@ package android.graphics; import android.annotation.NonNull; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; /** * Shader used to draw a bitmap as a texture. The bitmap can be repeated or diff --git a/graphics/java/android/graphics/Camera.java b/graphics/java/android/graphics/Camera.java index cbd4eadca30a..80a3740d2f4e 100644 --- a/graphics/java/android/graphics/Camera.java +++ b/graphics/java/android/graphics/Camera.java @@ -16,7 +16,7 @@ package android.graphics; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; /** * A camera instance can be used to compute 3D transformations and diff --git a/graphics/java/android/graphics/Canvas.java b/graphics/java/android/graphics/Canvas.java index 5648b854db40..d03472856cf4 100644 --- a/graphics/java/android/graphics/Canvas.java +++ b/graphics/java/android/graphics/Canvas.java @@ -22,7 +22,7 @@ import android.annotation.IntDef; import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.Size; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.graphics.text.MeasuredText; import android.os.Build; diff --git a/graphics/java/android/graphics/CanvasProperty.java b/graphics/java/android/graphics/CanvasProperty.java index 1275e0827580..4263772c1c2c 100644 --- a/graphics/java/android/graphics/CanvasProperty.java +++ b/graphics/java/android/graphics/CanvasProperty.java @@ -16,7 +16,8 @@ package android.graphics; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; + import com.android.internal.util.VirtualRefBasePtr; /** diff --git a/graphics/java/android/graphics/ColorMatrixColorFilter.java b/graphics/java/android/graphics/ColorMatrixColorFilter.java index 0f7980cc32e4..a8b18a9fcb1f 100644 --- a/graphics/java/android/graphics/ColorMatrixColorFilter.java +++ b/graphics/java/android/graphics/ColorMatrixColorFilter.java @@ -18,7 +18,7 @@ package android.graphics; import android.annotation.NonNull; import android.annotation.Nullable; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; /** * A color filter that transforms colors through a 4x5 color matrix. This filter diff --git a/graphics/java/android/graphics/FontFamily.java b/graphics/java/android/graphics/FontFamily.java index 5af0da85bb39..254892013d51 100644 --- a/graphics/java/android/graphics/FontFamily.java +++ b/graphics/java/android/graphics/FontFamily.java @@ -17,7 +17,7 @@ package android.graphics; import android.annotation.Nullable; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.res.AssetManager; import android.graphics.fonts.FontVariationAxis; import android.text.TextUtils; diff --git a/graphics/java/android/graphics/FontListParser.java b/graphics/java/android/graphics/FontListParser.java index 21cc3757a40e..c146bbd4441b 100644 --- a/graphics/java/android/graphics/FontListParser.java +++ b/graphics/java/android/graphics/FontListParser.java @@ -16,7 +16,7 @@ package android.graphics; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.graphics.fonts.FontVariationAxis; import android.text.FontConfig; import android.util.Xml; diff --git a/graphics/java/android/graphics/GraphicBuffer.java b/graphics/java/android/graphics/GraphicBuffer.java index 3b1fc70397ea..99fa5eef7bbd 100644 --- a/graphics/java/android/graphics/GraphicBuffer.java +++ b/graphics/java/android/graphics/GraphicBuffer.java @@ -16,7 +16,7 @@ package android.graphics; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.os.Parcel; import android.os.Parcelable; diff --git a/graphics/java/android/graphics/ImageDecoder.java b/graphics/java/android/graphics/ImageDecoder.java index 2d5babc5ebdb..dbdb6971c6c5 100644 --- a/graphics/java/android/graphics/ImageDecoder.java +++ b/graphics/java/android/graphics/ImageDecoder.java @@ -28,8 +28,8 @@ import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.Px; import android.annotation.TestApi; -import android.annotation.UnsupportedAppUsage; import android.annotation.WorkerThread; +import android.compat.annotation.UnsupportedAppUsage; import android.content.ContentResolver; import android.content.res.AssetFileDescriptor; import android.content.res.AssetManager; diff --git a/graphics/java/android/graphics/LightingColorFilter.java b/graphics/java/android/graphics/LightingColorFilter.java index 62a890ff4f0b..221dfa192795 100644 --- a/graphics/java/android/graphics/LightingColorFilter.java +++ b/graphics/java/android/graphics/LightingColorFilter.java @@ -22,7 +22,7 @@ package android.graphics; import android.annotation.ColorInt; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; /** * A color filter that can be used to simulate simple lighting effects. diff --git a/graphics/java/android/graphics/LinearGradient.java b/graphics/java/android/graphics/LinearGradient.java index 12e63c09d76b..3f3ad967fe97 100644 --- a/graphics/java/android/graphics/LinearGradient.java +++ b/graphics/java/android/graphics/LinearGradient.java @@ -20,7 +20,7 @@ import android.annotation.ColorInt; import android.annotation.ColorLong; import android.annotation.NonNull; import android.annotation.Nullable; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; public class LinearGradient extends Shader { diff --git a/graphics/java/android/graphics/Matrix.java b/graphics/java/android/graphics/Matrix.java index 22b6401fdc2e..cf914c2c3eae 100644 --- a/graphics/java/android/graphics/Matrix.java +++ b/graphics/java/android/graphics/Matrix.java @@ -16,7 +16,7 @@ package android.graphics; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import dalvik.annotation.optimization.CriticalNative; import dalvik.annotation.optimization.FastNative; diff --git a/graphics/java/android/graphics/Movie.java b/graphics/java/android/graphics/Movie.java index 6f030ffac2df..4b3924f0d55f 100644 --- a/graphics/java/android/graphics/Movie.java +++ b/graphics/java/android/graphics/Movie.java @@ -16,7 +16,7 @@ package android.graphics; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.res.AssetManager; import android.os.Build; diff --git a/graphics/java/android/graphics/NinePatch.java b/graphics/java/android/graphics/NinePatch.java index c4c1eaceb4fc..ff3239348240 100644 --- a/graphics/java/android/graphics/NinePatch.java +++ b/graphics/java/android/graphics/NinePatch.java @@ -16,7 +16,7 @@ package android.graphics; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; /** * The NinePatch class permits drawing a bitmap in nine or more sections. diff --git a/graphics/java/android/graphics/Outline.java b/graphics/java/android/graphics/Outline.java index 1fc056c3652f..91a60c327bf0 100644 --- a/graphics/java/android/graphics/Outline.java +++ b/graphics/java/android/graphics/Outline.java @@ -19,7 +19,7 @@ package android.graphics; import android.annotation.FloatRange; import android.annotation.IntDef; import android.annotation.NonNull; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.graphics.drawable.Drawable; import java.lang.annotation.Retention; diff --git a/graphics/java/android/graphics/Paint.java b/graphics/java/android/graphics/Paint.java index b7316ab03618..dcb669d84272 100644 --- a/graphics/java/android/graphics/Paint.java +++ b/graphics/java/android/graphics/Paint.java @@ -24,7 +24,7 @@ import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.Px; import android.annotation.Size; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.graphics.fonts.FontVariationAxis; import android.os.Build; import android.os.LocaleList; diff --git a/graphics/java/android/graphics/Path.java b/graphics/java/android/graphics/Path.java index 7282d52d6e23..1362fd864d29 100644 --- a/graphics/java/android/graphics/Path.java +++ b/graphics/java/android/graphics/Path.java @@ -20,7 +20,7 @@ import android.annotation.FloatRange; import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.Size; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import dalvik.annotation.optimization.CriticalNative; import dalvik.annotation.optimization.FastNative; diff --git a/graphics/java/android/graphics/Picture.java b/graphics/java/android/graphics/Picture.java index 8d12cbffc793..390d3d414346 100644 --- a/graphics/java/android/graphics/Picture.java +++ b/graphics/java/android/graphics/Picture.java @@ -17,7 +17,7 @@ package android.graphics; import android.annotation.NonNull; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import java.io.InputStream; import java.io.OutputStream; diff --git a/graphics/java/android/graphics/PorterDuff.java b/graphics/java/android/graphics/PorterDuff.java index bc1f66fdd5c0..1275cb9ca4f9 100644 --- a/graphics/java/android/graphics/PorterDuff.java +++ b/graphics/java/android/graphics/PorterDuff.java @@ -16,7 +16,7 @@ package android.graphics; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; /** * <p>This class contains the list of alpha compositing and blending modes diff --git a/graphics/java/android/graphics/PorterDuffColorFilter.java b/graphics/java/android/graphics/PorterDuffColorFilter.java index cc2d3a8969fc..50ecb62e7fcc 100644 --- a/graphics/java/android/graphics/PorterDuffColorFilter.java +++ b/graphics/java/android/graphics/PorterDuffColorFilter.java @@ -18,7 +18,7 @@ package android.graphics; import android.annotation.ColorInt; import android.annotation.NonNull; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; /** * A color filter that can be used to tint the source pixels using a single diff --git a/graphics/java/android/graphics/RadialGradient.java b/graphics/java/android/graphics/RadialGradient.java index acbe3da75247..96b7b9a78ba8 100644 --- a/graphics/java/android/graphics/RadialGradient.java +++ b/graphics/java/android/graphics/RadialGradient.java @@ -20,7 +20,7 @@ import android.annotation.ColorInt; import android.annotation.ColorLong; import android.annotation.NonNull; import android.annotation.Nullable; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; public class RadialGradient extends Shader { @UnsupportedAppUsage diff --git a/graphics/java/android/graphics/Rect.java b/graphics/java/android/graphics/Rect.java index d47f682ec2d3..270725ab9805 100644 --- a/graphics/java/android/graphics/Rect.java +++ b/graphics/java/android/graphics/Rect.java @@ -19,7 +19,7 @@ package android.graphics; import android.annotation.CheckResult; import android.annotation.NonNull; import android.annotation.Nullable; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.os.Parcel; import android.os.Parcelable; import android.text.TextUtils; diff --git a/graphics/java/android/graphics/Region.java b/graphics/java/android/graphics/Region.java index ec7f7a05b685..d8d96413a93d 100644 --- a/graphics/java/android/graphics/Region.java +++ b/graphics/java/android/graphics/Region.java @@ -17,7 +17,7 @@ package android.graphics; import android.annotation.NonNull; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.os.Parcel; import android.os.Parcelable; import android.util.Pools.SynchronizedPool; diff --git a/graphics/java/android/graphics/Shader.java b/graphics/java/android/graphics/Shader.java index 3050d1dae5e4..5335aa4725ad 100644 --- a/graphics/java/android/graphics/Shader.java +++ b/graphics/java/android/graphics/Shader.java @@ -20,7 +20,7 @@ import android.annotation.ColorInt; import android.annotation.ColorLong; import android.annotation.NonNull; import android.annotation.Nullable; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import libcore.util.NativeAllocationRegistry; diff --git a/graphics/java/android/graphics/SurfaceTexture.java b/graphics/java/android/graphics/SurfaceTexture.java index 99f440d599cb..697daa8b7b70 100644 --- a/graphics/java/android/graphics/SurfaceTexture.java +++ b/graphics/java/android/graphics/SurfaceTexture.java @@ -17,7 +17,7 @@ package android.graphics; import android.annotation.Nullable; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.os.Handler; import android.os.Looper; import android.os.Message; diff --git a/graphics/java/android/graphics/SweepGradient.java b/graphics/java/android/graphics/SweepGradient.java index 667f45afe500..08520048b787 100644 --- a/graphics/java/android/graphics/SweepGradient.java +++ b/graphics/java/android/graphics/SweepGradient.java @@ -20,7 +20,7 @@ import android.annotation.ColorInt; import android.annotation.ColorLong; import android.annotation.NonNull; import android.annotation.Nullable; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; public class SweepGradient extends Shader { @UnsupportedAppUsage diff --git a/graphics/java/android/graphics/TableMaskFilter.java b/graphics/java/android/graphics/TableMaskFilter.java index d81c491e07e0..204f9705852a 100644 --- a/graphics/java/android/graphics/TableMaskFilter.java +++ b/graphics/java/android/graphics/TableMaskFilter.java @@ -16,7 +16,7 @@ package android.graphics; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; /** * @hide diff --git a/graphics/java/android/graphics/TemporaryBuffer.java b/graphics/java/android/graphics/TemporaryBuffer.java index 0ae2c703c21c..ef3f7f704e0d 100644 --- a/graphics/java/android/graphics/TemporaryBuffer.java +++ b/graphics/java/android/graphics/TemporaryBuffer.java @@ -16,7 +16,8 @@ package android.graphics; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; + import com.android.internal.util.ArrayUtils; /** diff --git a/graphics/java/android/graphics/Typeface.java b/graphics/java/android/graphics/Typeface.java index 6d20ec32cdc4..a2dd9a8322b6 100644 --- a/graphics/java/android/graphics/Typeface.java +++ b/graphics/java/android/graphics/Typeface.java @@ -25,7 +25,7 @@ import android.annotation.IntDef; import android.annotation.IntRange; import android.annotation.NonNull; import android.annotation.Nullable; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.res.AssetManager; import android.graphics.fonts.Font; import android.graphics.fonts.FontFamily; diff --git a/graphics/java/android/graphics/Xfermode.java b/graphics/java/android/graphics/Xfermode.java index 6f4adfde7ff9..e79fb76d806e 100644 --- a/graphics/java/android/graphics/Xfermode.java +++ b/graphics/java/android/graphics/Xfermode.java @@ -21,7 +21,7 @@ package android.graphics; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; /** * Xfermode is the base class for objects that are called to implement custom diff --git a/graphics/java/android/graphics/drawable/AnimatedImageDrawable.java b/graphics/java/android/graphics/drawable/AnimatedImageDrawable.java index 82f587086428..d8946009483c 100644 --- a/graphics/java/android/graphics/drawable/AnimatedImageDrawable.java +++ b/graphics/java/android/graphics/drawable/AnimatedImageDrawable.java @@ -19,7 +19,7 @@ package android.graphics.drawable; import android.annotation.IntRange; import android.annotation.NonNull; import android.annotation.Nullable; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.res.AssetFileDescriptor; import android.content.res.Resources; import android.content.res.Resources.Theme; diff --git a/graphics/java/android/graphics/drawable/AnimatedRotateDrawable.java b/graphics/java/android/graphics/drawable/AnimatedRotateDrawable.java index b29fd4db5803..686f146e9c18 100644 --- a/graphics/java/android/graphics/drawable/AnimatedRotateDrawable.java +++ b/graphics/java/android/graphics/drawable/AnimatedRotateDrawable.java @@ -18,23 +18,23 @@ package android.graphics.drawable; import android.annotation.NonNull; import android.annotation.Nullable; -import android.annotation.UnsupportedAppUsage; -import android.graphics.Canvas; -import android.graphics.Rect; +import android.compat.annotation.UnsupportedAppUsage; import android.content.res.Resources; -import android.content.res.TypedArray; import android.content.res.Resources.Theme; +import android.content.res.TypedArray; +import android.graphics.Canvas; +import android.graphics.Rect; +import android.os.SystemClock; import android.util.AttributeSet; import android.util.TypedValue; -import android.os.SystemClock; + +import com.android.internal.R; import org.xmlpull.v1.XmlPullParser; import org.xmlpull.v1.XmlPullParserException; import java.io.IOException; -import com.android.internal.R; - /** * @hide */ diff --git a/graphics/java/android/graphics/drawable/AnimatedStateListDrawable.java b/graphics/java/android/graphics/drawable/AnimatedStateListDrawable.java index 11a46c4ba9b9..06159d8a0558 100644 --- a/graphics/java/android/graphics/drawable/AnimatedStateListDrawable.java +++ b/graphics/java/android/graphics/drawable/AnimatedStateListDrawable.java @@ -20,7 +20,7 @@ import android.animation.ObjectAnimator; import android.animation.TimeInterpolator; import android.annotation.NonNull; import android.annotation.Nullable; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.res.Resources; import android.content.res.Resources.Theme; import android.content.res.TypedArray; diff --git a/graphics/java/android/graphics/drawable/AnimatedVectorDrawable.java b/graphics/java/android/graphics/drawable/AnimatedVectorDrawable.java index 66947da9166f..1acf6c512fbd 100644 --- a/graphics/java/android/graphics/drawable/AnimatedVectorDrawable.java +++ b/graphics/java/android/graphics/drawable/AnimatedVectorDrawable.java @@ -25,9 +25,9 @@ import android.animation.TimeInterpolator; import android.animation.ValueAnimator; import android.annotation.NonNull; import android.annotation.Nullable; -import android.annotation.UnsupportedAppUsage; import android.app.ActivityThread; import android.app.Application; +import android.compat.annotation.UnsupportedAppUsage; import android.content.pm.ActivityInfo.Config; import android.content.res.ColorStateList; import android.content.res.Resources; diff --git a/graphics/java/android/graphics/drawable/AnimationDrawable.java b/graphics/java/android/graphics/drawable/AnimationDrawable.java index 57764c2cb693..8c3fa441cbb0 100644 --- a/graphics/java/android/graphics/drawable/AnimationDrawable.java +++ b/graphics/java/android/graphics/drawable/AnimationDrawable.java @@ -16,21 +16,21 @@ package android.graphics.drawable; -import com.android.internal.R; - -import java.io.IOException; - -import org.xmlpull.v1.XmlPullParser; -import org.xmlpull.v1.XmlPullParserException; - import android.annotation.NonNull; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.res.Resources; -import android.content.res.TypedArray; import android.content.res.Resources.Theme; +import android.content.res.TypedArray; import android.os.SystemClock; import android.util.AttributeSet; +import com.android.internal.R; + +import org.xmlpull.v1.XmlPullParser; +import org.xmlpull.v1.XmlPullParserException; + +import java.io.IOException; + /** * An object used to create frame-by-frame animations, defined by a series of * Drawable objects, which can be used as a View object's background. diff --git a/graphics/java/android/graphics/drawable/BitmapDrawable.java b/graphics/java/android/graphics/drawable/BitmapDrawable.java index e4aa774fd434..4e768c9eddfb 100644 --- a/graphics/java/android/graphics/drawable/BitmapDrawable.java +++ b/graphics/java/android/graphics/drawable/BitmapDrawable.java @@ -17,7 +17,7 @@ package android.graphics.drawable; import android.annotation.NonNull; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.pm.ActivityInfo.Config; import android.content.res.ColorStateList; import android.content.res.Resources; diff --git a/graphics/java/android/graphics/drawable/ClipDrawable.java b/graphics/java/android/graphics/drawable/ClipDrawable.java index 31fdb025bbc5..69ed9b423d48 100644 --- a/graphics/java/android/graphics/drawable/ClipDrawable.java +++ b/graphics/java/android/graphics/drawable/ClipDrawable.java @@ -16,20 +16,22 @@ package android.graphics.drawable; -import com.android.internal.R; - -import org.xmlpull.v1.XmlPullParser; -import org.xmlpull.v1.XmlPullParserException; - import android.annotation.NonNull; import android.annotation.Nullable; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.res.Resources; -import android.content.res.TypedArray; import android.content.res.Resources.Theme; -import android.graphics.*; -import android.view.Gravity; +import android.content.res.TypedArray; +import android.graphics.Canvas; +import android.graphics.PixelFormat; +import android.graphics.Rect; import android.util.AttributeSet; +import android.view.Gravity; + +import com.android.internal.R; + +import org.xmlpull.v1.XmlPullParser; +import org.xmlpull.v1.XmlPullParserException; import java.io.IOException; diff --git a/graphics/java/android/graphics/drawable/ColorDrawable.java b/graphics/java/android/graphics/drawable/ColorDrawable.java index f5fa8c546bed..e93e7dfbe22c 100644 --- a/graphics/java/android/graphics/drawable/ColorDrawable.java +++ b/graphics/java/android/graphics/drawable/ColorDrawable.java @@ -20,7 +20,7 @@ import android.annotation.ColorInt; import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.TestApi; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.pm.ActivityInfo.Config; import android.content.res.ColorStateList; import android.content.res.Resources; diff --git a/graphics/java/android/graphics/drawable/Drawable.java b/graphics/java/android/graphics/drawable/Drawable.java index 08409869c626..e70529b6cd1a 100644 --- a/graphics/java/android/graphics/drawable/Drawable.java +++ b/graphics/java/android/graphics/drawable/Drawable.java @@ -22,7 +22,7 @@ import android.annotation.IntRange; import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.TestApi; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.pm.ActivityInfo.Config; import android.content.res.ColorStateList; import android.content.res.Resources; diff --git a/graphics/java/android/graphics/drawable/DrawableContainer.java b/graphics/java/android/graphics/drawable/DrawableContainer.java index 090d915a2f67..51b299c9ee5e 100644 --- a/graphics/java/android/graphics/drawable/DrawableContainer.java +++ b/graphics/java/android/graphics/drawable/DrawableContainer.java @@ -17,7 +17,7 @@ package android.graphics.drawable; import android.annotation.NonNull; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.pm.ActivityInfo.Config; import android.content.res.ColorStateList; import android.content.res.Resources; diff --git a/graphics/java/android/graphics/drawable/DrawableInflater.java b/graphics/java/android/graphics/drawable/DrawableInflater.java index bad3791a9c24..3408b64e7536 100644 --- a/graphics/java/android/graphics/drawable/DrawableInflater.java +++ b/graphics/java/android/graphics/drawable/DrawableInflater.java @@ -16,19 +16,19 @@ package android.graphics.drawable; -import org.xmlpull.v1.XmlPullParser; -import org.xmlpull.v1.XmlPullParserException; - import android.annotation.DrawableRes; import android.annotation.NonNull; import android.annotation.Nullable; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; import android.content.res.Resources; import android.content.res.Resources.Theme; import android.util.AttributeSet; import android.view.InflateException; +import org.xmlpull.v1.XmlPullParser; +import org.xmlpull.v1.XmlPullParserException; + import java.io.IOException; import java.lang.reflect.Constructor; import java.util.HashMap; diff --git a/graphics/java/android/graphics/drawable/DrawableWrapper.java b/graphics/java/android/graphics/drawable/DrawableWrapper.java index 64fc7042dfc7..e8cb42e75ea2 100644 --- a/graphics/java/android/graphics/drawable/DrawableWrapper.java +++ b/graphics/java/android/graphics/drawable/DrawableWrapper.java @@ -18,7 +18,7 @@ package android.graphics.drawable; import android.annotation.NonNull; import android.annotation.Nullable; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.pm.ActivityInfo.Config; import android.content.res.ColorStateList; import android.content.res.Resources; diff --git a/graphics/java/android/graphics/drawable/GradientDrawable.java b/graphics/java/android/graphics/drawable/GradientDrawable.java index b9945cc735d8..b50ec0d5e3fd 100644 --- a/graphics/java/android/graphics/drawable/GradientDrawable.java +++ b/graphics/java/android/graphics/drawable/GradientDrawable.java @@ -22,7 +22,7 @@ import android.annotation.IntDef; import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.Px; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.pm.ActivityInfo.Config; import android.content.res.ColorStateList; import android.content.res.Resources; diff --git a/graphics/java/android/graphics/drawable/Icon.java b/graphics/java/android/graphics/drawable/Icon.java index 3658f89abae1..63662099c4c8 100644 --- a/graphics/java/android/graphics/drawable/Icon.java +++ b/graphics/java/android/graphics/drawable/Icon.java @@ -21,7 +21,7 @@ import android.annotation.DrawableRes; import android.annotation.IdRes; import android.annotation.IntDef; import android.annotation.NonNull; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.ContentResolver; import android.content.Context; import android.content.pm.ApplicationInfo; diff --git a/graphics/java/android/graphics/drawable/InsetDrawable.java b/graphics/java/android/graphics/drawable/InsetDrawable.java index bc8a4cbd7e9d..005a4d175fd5 100644 --- a/graphics/java/android/graphics/drawable/InsetDrawable.java +++ b/graphics/java/android/graphics/drawable/InsetDrawable.java @@ -18,7 +18,7 @@ package android.graphics.drawable; import android.annotation.NonNull; import android.annotation.Nullable; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.res.Resources; import android.content.res.Resources.Theme; import android.content.res.TypedArray; diff --git a/graphics/java/android/graphics/drawable/LayerDrawable.java b/graphics/java/android/graphics/drawable/LayerDrawable.java index 760d554888ee..fb4146f04bc9 100644 --- a/graphics/java/android/graphics/drawable/LayerDrawable.java +++ b/graphics/java/android/graphics/drawable/LayerDrawable.java @@ -18,7 +18,7 @@ package android.graphics.drawable; import android.annotation.NonNull; import android.annotation.Nullable; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.pm.ActivityInfo.Config; import android.content.res.ColorStateList; import android.content.res.Resources; diff --git a/graphics/java/android/graphics/drawable/NinePatchDrawable.java b/graphics/java/android/graphics/drawable/NinePatchDrawable.java index 8561d95ddd88..99d27ba4c469 100644 --- a/graphics/java/android/graphics/drawable/NinePatchDrawable.java +++ b/graphics/java/android/graphics/drawable/NinePatchDrawable.java @@ -18,7 +18,7 @@ package android.graphics.drawable; import android.annotation.NonNull; import android.annotation.Nullable; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.pm.ActivityInfo.Config; import android.content.res.ColorStateList; import android.content.res.Resources; diff --git a/graphics/java/android/graphics/drawable/RippleDrawable.java b/graphics/java/android/graphics/drawable/RippleDrawable.java index 1540cc22e295..e5e4d4527fca 100644 --- a/graphics/java/android/graphics/drawable/RippleDrawable.java +++ b/graphics/java/android/graphics/drawable/RippleDrawable.java @@ -18,7 +18,7 @@ package android.graphics.drawable; import android.annotation.NonNull; import android.annotation.Nullable; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.pm.ActivityInfo.Config; import android.content.res.ColorStateList; import android.content.res.Resources; diff --git a/graphics/java/android/graphics/drawable/RotateDrawable.java b/graphics/java/android/graphics/drawable/RotateDrawable.java index db5f082bd853..43766b636adb 100644 --- a/graphics/java/android/graphics/drawable/RotateDrawable.java +++ b/graphics/java/android/graphics/drawable/RotateDrawable.java @@ -16,22 +16,22 @@ package android.graphics.drawable; -import com.android.internal.R; - -import org.xmlpull.v1.XmlPullParser; -import org.xmlpull.v1.XmlPullParserException; - import android.annotation.NonNull; import android.annotation.Nullable; -import android.annotation.UnsupportedAppUsage; -import android.graphics.Canvas; -import android.graphics.Rect; +import android.compat.annotation.UnsupportedAppUsage; import android.content.res.Resources; -import android.content.res.TypedArray; import android.content.res.Resources.Theme; +import android.content.res.TypedArray; +import android.graphics.Canvas; +import android.graphics.Rect; +import android.util.AttributeSet; import android.util.MathUtils; import android.util.TypedValue; -import android.util.AttributeSet; + +import com.android.internal.R; + +import org.xmlpull.v1.XmlPullParser; +import org.xmlpull.v1.XmlPullParserException; import java.io.IOException; diff --git a/graphics/java/android/graphics/drawable/ScaleDrawable.java b/graphics/java/android/graphics/drawable/ScaleDrawable.java index 91ed061e511d..af7eed4b3897 100644 --- a/graphics/java/android/graphics/drawable/ScaleDrawable.java +++ b/graphics/java/android/graphics/drawable/ScaleDrawable.java @@ -16,14 +16,9 @@ package android.graphics.drawable; -import com.android.internal.R; - -import org.xmlpull.v1.XmlPullParser; -import org.xmlpull.v1.XmlPullParserException; - import android.annotation.NonNull; import android.annotation.Nullable; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.res.Resources; import android.content.res.Resources.Theme; import android.content.res.TypedArray; @@ -34,6 +29,11 @@ import android.util.AttributeSet; import android.util.TypedValue; import android.view.Gravity; +import com.android.internal.R; + +import org.xmlpull.v1.XmlPullParser; +import org.xmlpull.v1.XmlPullParserException; + import java.io.IOException; /** diff --git a/graphics/java/android/graphics/drawable/StateListDrawable.java b/graphics/java/android/graphics/drawable/StateListDrawable.java index f67188c22609..2920acbe514c 100644 --- a/graphics/java/android/graphics/drawable/StateListDrawable.java +++ b/graphics/java/android/graphics/drawable/StateListDrawable.java @@ -18,7 +18,7 @@ package android.graphics.drawable; import android.annotation.NonNull; import android.annotation.Nullable; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.res.Resources; import android.content.res.Resources.Theme; import android.content.res.TypedArray; diff --git a/graphics/java/android/graphics/drawable/TransitionDrawable.java b/graphics/java/android/graphics/drawable/TransitionDrawable.java index 276f3662189b..401e05ffc139 100644 --- a/graphics/java/android/graphics/drawable/TransitionDrawable.java +++ b/graphics/java/android/graphics/drawable/TransitionDrawable.java @@ -16,7 +16,7 @@ package android.graphics.drawable; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.pm.ActivityInfo.Config; import android.content.res.Resources; import android.graphics.Canvas; diff --git a/graphics/java/android/graphics/drawable/VectorDrawable.java b/graphics/java/android/graphics/drawable/VectorDrawable.java index aa19b2a0e94c..e6fa866df3ab 100644 --- a/graphics/java/android/graphics/drawable/VectorDrawable.java +++ b/graphics/java/android/graphics/drawable/VectorDrawable.java @@ -16,7 +16,7 @@ package android.graphics.drawable; import android.annotation.NonNull; import android.annotation.Nullable; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.pm.ActivityInfo.Config; import android.content.res.ColorStateList; import android.content.res.ComplexColor; diff --git a/graphics/java/android/graphics/fonts/FontVariationAxis.java b/graphics/java/android/graphics/fonts/FontVariationAxis.java index bcee559d8291..4e6580ea5f53 100644 --- a/graphics/java/android/graphics/fonts/FontVariationAxis.java +++ b/graphics/java/android/graphics/fonts/FontVariationAxis.java @@ -18,7 +18,7 @@ package android.graphics.fonts; import android.annotation.NonNull; import android.annotation.Nullable; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.os.Build; import android.text.TextUtils; diff --git a/graphics/java/android/graphics/pdf/PdfRenderer.java b/graphics/java/android/graphics/pdf/PdfRenderer.java index bd1a49205fd5..54710e58687c 100644 --- a/graphics/java/android/graphics/pdf/PdfRenderer.java +++ b/graphics/java/android/graphics/pdf/PdfRenderer.java @@ -19,7 +19,7 @@ package android.graphics.pdf; import android.annotation.IntDef; import android.annotation.NonNull; import android.annotation.Nullable; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.graphics.Bitmap; import android.graphics.Bitmap.Config; import android.graphics.Matrix; @@ -29,7 +29,9 @@ import android.os.ParcelFileDescriptor; import android.system.ErrnoException; import android.system.Os; import android.system.OsConstants; + import com.android.internal.util.Preconditions; + import dalvik.system.CloseGuard; import libcore.io.IoUtils; diff --git a/keystore/java/android/security/Credentials.java b/keystore/java/android/security/Credentials.java index fad7d8062a22..7282bcfe4445 100644 --- a/keystore/java/android/security/Credentials.java +++ b/keystore/java/android/security/Credentials.java @@ -16,7 +16,7 @@ package android.security; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import com.android.org.bouncycastle.util.io.pem.PemObject; import com.android.org.bouncycastle.util.io.pem.PemReader; diff --git a/keystore/java/android/security/GateKeeper.java b/keystore/java/android/security/GateKeeper.java index a50ff7984341..af188a95c929 100644 --- a/keystore/java/android/security/GateKeeper.java +++ b/keystore/java/android/security/GateKeeper.java @@ -16,7 +16,7 @@ package android.security; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; import android.os.RemoteException; import android.os.ServiceManager; diff --git a/keystore/java/android/security/KeyStore.java b/keystore/java/android/security/KeyStore.java index c0a04220cfe7..e9bc8026d25e 100644 --- a/keystore/java/android/security/KeyStore.java +++ b/keystore/java/android/security/KeyStore.java @@ -16,10 +16,10 @@ package android.security; -import android.annotation.UnsupportedAppUsage; import android.app.ActivityThread; import android.app.Application; import android.app.KeyguardManager; +import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; import android.content.pm.PackageManager; import android.hardware.face.FaceManager; @@ -31,7 +31,6 @@ import android.os.Process; import android.os.RemoteException; import android.os.ServiceManager; import android.os.UserHandle; -import android.security.KeyStoreException; import android.security.keymaster.ExportResult; import android.security.keymaster.KeyCharacteristics; import android.security.keymaster.KeymasterArguments; diff --git a/keystore/java/android/security/keystore/AndroidKeyStoreProvider.java b/keystore/java/android/security/keystore/AndroidKeyStoreProvider.java index 234615d9c81d..8be85d6827f4 100644 --- a/keystore/java/android/security/keystore/AndroidKeyStoreProvider.java +++ b/keystore/java/android/security/keystore/AndroidKeyStoreProvider.java @@ -17,7 +17,7 @@ package android.security.keystore; import android.annotation.NonNull; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.security.KeyStore; import android.security.keymaster.ExportResult; import android.security.keymaster.KeyCharacteristics; diff --git a/keystore/java/android/security/keystore/KeyGenParameterSpec.java b/keystore/java/android/security/keystore/KeyGenParameterSpec.java index e3f43efff72b..630a6dd081a3 100644 --- a/keystore/java/android/security/keystore/KeyGenParameterSpec.java +++ b/keystore/java/android/security/keystore/KeyGenParameterSpec.java @@ -20,8 +20,8 @@ import android.annotation.IntRange; import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.TestApi; -import android.annotation.UnsupportedAppUsage; import android.app.KeyguardManager; +import android.compat.annotation.UnsupportedAppUsage; import android.hardware.biometrics.BiometricManager; import android.hardware.biometrics.BiometricPrompt; import android.security.GateKeeper; diff --git a/libs/hwui/Android.bp b/libs/hwui/Android.bp index 4c08a3829934..98de9c3ea88e 100644 --- a/libs/hwui/Android.bp +++ b/libs/hwui/Android.bp @@ -25,11 +25,6 @@ cc_defaults { // GCC false-positives on this warning, and since we -Werror that's // a problem "-Wno-free-nonheap-object", - - // Clang is producing non-determistic binary when the new pass manager is - // enabled. Disable the new PM as a temporary workaround. - // b/142372146 - "-fno-experimental-new-pass-manager", ], include_dirs: [ diff --git a/libs/hwui/hwui/Bitmap.cpp b/libs/hwui/hwui/Bitmap.cpp index 219d04055eae..c21bdca3db77 100644 --- a/libs/hwui/hwui/Bitmap.cpp +++ b/libs/hwui/hwui/Bitmap.cpp @@ -219,7 +219,7 @@ Bitmap::Bitmap(void* address, int fd, size_t mappedSize, const SkImageInfo& info Bitmap::Bitmap(GraphicBuffer* buffer, const SkImageInfo& info, BitmapPalette palette) : SkPixelRef(info.width(), info.height(), nullptr, - bytesPerPixel(buffer->getPixelFormat()) * buffer->getStride()) + bytesPerPixel(buffer->getPixelFormat()) * (buffer->getStride() > 0 ? buffer->getStride() : buffer->getWidth())) , mInfo(validateAlpha(info)) , mPixelStorageType(PixelStorageType::Hardware) , mPalette(palette) diff --git a/location/java/android/location/Country.java b/location/java/android/location/Country.java index f3c2a1684cda..8c40338e80fc 100644 --- a/location/java/android/location/Country.java +++ b/location/java/android/location/Country.java @@ -16,7 +16,7 @@ package android.location; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.os.Parcel; import android.os.Parcelable; import android.os.SystemClock; diff --git a/location/java/android/location/CountryDetector.java b/location/java/android/location/CountryDetector.java index ae139499eeb2..e344b820ca2a 100644 --- a/location/java/android/location/CountryDetector.java +++ b/location/java/android/location/CountryDetector.java @@ -16,10 +16,8 @@ package android.location; -import java.util.HashMap; - import android.annotation.SystemService; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; import android.os.Build; import android.os.Handler; @@ -27,6 +25,8 @@ import android.os.Looper; import android.os.RemoteException; import android.util.Log; +import java.util.HashMap; + /** * This class provides access to the system country detector service. This * service allows applications to obtain the country that the user is in. diff --git a/location/java/android/location/CountryListener.java b/location/java/android/location/CountryListener.java index 70a83c5acdd9..eb67205f4de9 100644 --- a/location/java/android/location/CountryListener.java +++ b/location/java/android/location/CountryListener.java @@ -16,7 +16,7 @@ package android.location; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; /** * The listener for receiving the notification when the country is detected or diff --git a/location/java/android/location/GeocoderParams.java b/location/java/android/location/GeocoderParams.java index 45d92ee7cc34..1c6e9b6e1836 100644 --- a/location/java/android/location/GeocoderParams.java +++ b/location/java/android/location/GeocoderParams.java @@ -16,7 +16,7 @@ package android.location; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; import android.os.Parcel; import android.os.Parcelable; diff --git a/location/java/android/location/Geofence.java b/location/java/android/location/Geofence.java index 9570b26452e4..af57bfd30984 100644 --- a/location/java/android/location/Geofence.java +++ b/location/java/android/location/Geofence.java @@ -16,7 +16,7 @@ package android.location; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.os.Parcel; import android.os.Parcelable; diff --git a/location/java/android/location/GpsStatus.java b/location/java/android/location/GpsStatus.java index 609a15e1be7e..8a5edc41a774 100644 --- a/location/java/android/location/GpsStatus.java +++ b/location/java/android/location/GpsStatus.java @@ -16,7 +16,7 @@ package android.location; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.os.Build; import android.util.SparseArray; diff --git a/location/java/android/location/Location.java b/location/java/android/location/Location.java index 9c36d76cf370..6f12c78e8621 100644 --- a/location/java/android/location/Location.java +++ b/location/java/android/location/Location.java @@ -18,7 +18,7 @@ package android.location; import android.annotation.SystemApi; import android.annotation.TestApi; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.os.Build; import android.os.Bundle; import android.os.Parcel; diff --git a/location/java/android/location/LocationManager.java b/location/java/android/location/LocationManager.java index 7b24f44823d0..f17f7483a838 100644 --- a/location/java/android/location/LocationManager.java +++ b/location/java/android/location/LocationManager.java @@ -30,8 +30,8 @@ import android.annotation.SuppressLint; import android.annotation.SystemApi; import android.annotation.SystemService; import android.annotation.TestApi; -import android.annotation.UnsupportedAppUsage; import android.app.PendingIntent; +import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; import android.content.Intent; import android.content.pm.PackageManager; diff --git a/location/java/android/location/LocationRequest.java b/location/java/android/location/LocationRequest.java index 0902acf176d4..adea73d25922 100644 --- a/location/java/android/location/LocationRequest.java +++ b/location/java/android/location/LocationRequest.java @@ -22,7 +22,7 @@ import android.annotation.Nullable; import android.annotation.RequiresPermission; import android.annotation.SystemApi; import android.annotation.TestApi; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.os.Build; import android.os.Parcel; import android.os.Parcelable; diff --git a/location/java/com/android/internal/location/GpsNetInitiatedHandler.java b/location/java/com/android/internal/location/GpsNetInitiatedHandler.java index f9b2fe057995..9846436b3ac8 100644 --- a/location/java/com/android/internal/location/GpsNetInitiatedHandler.java +++ b/location/java/com/android/internal/location/GpsNetInitiatedHandler.java @@ -19,6 +19,7 @@ package com.android.internal.location; import android.app.Notification; import android.app.NotificationManager; import android.app.PendingIntent; +import android.compat.annotation.UnsupportedAppUsage; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; @@ -37,8 +38,6 @@ import com.android.internal.R; import com.android.internal.notification.SystemNotificationChannels; import com.android.internal.telephony.GsmAlphabet; -import dalvik.annotation.compat.UnsupportedAppUsage; - import java.io.UnsupportedEncodingException; import java.util.concurrent.TimeUnit; @@ -126,7 +125,7 @@ public class GpsNetInitiatedHandler { public static class GpsNiNotification { - @android.annotation.UnsupportedAppUsage + @android.compat.annotation.UnsupportedAppUsage public GpsNiNotification() { } public int notificationId; diff --git a/location/java/com/android/internal/location/ProviderRequest.java b/location/java/com/android/internal/location/ProviderRequest.java index 155f788cb33e..c23f49976799 100644 --- a/location/java/com/android/internal/location/ProviderRequest.java +++ b/location/java/com/android/internal/location/ProviderRequest.java @@ -16,7 +16,7 @@ package com.android.internal.location; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.location.LocationRequest; import android.os.Parcel; import android.os.Parcelable; diff --git a/media/OWNERS b/media/OWNERS index 8bd037a14150..be605831a24b 100644 --- a/media/OWNERS +++ b/media/OWNERS @@ -5,6 +5,7 @@ elaurent@google.com etalvala@google.com gkasten@google.com hdmoon@google.com +hkuang@google.com hunga@google.com insun@google.com jaewan@google.com diff --git a/media/java/android/media/AmrInputStream.java b/media/java/android/media/AmrInputStream.java index 5088798a2910..3cb224dd58cd 100644 --- a/media/java/android/media/AmrInputStream.java +++ b/media/java/android/media/AmrInputStream.java @@ -16,14 +16,14 @@ package android.media; -import java.io.InputStream; -import java.io.IOException; -import java.nio.ByteBuffer; - -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.media.MediaCodec.BufferInfo; import android.util.Log; +import java.io.IOException; +import java.io.InputStream; +import java.nio.ByteBuffer; + /** * DO NOT USE diff --git a/media/java/android/media/AsyncPlayer.java b/media/java/android/media/AsyncPlayer.java index 8ac26553bab4..c3dc118fec7e 100644 --- a/media/java/android/media/AsyncPlayer.java +++ b/media/java/android/media/AsyncPlayer.java @@ -17,9 +17,8 @@ package android.media; import android.annotation.NonNull; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; -import android.media.PlayerBase; import android.net.Uri; import android.os.PowerManager; import android.os.SystemClock; diff --git a/media/java/android/media/AudioAttributes.java b/media/java/android/media/AudioAttributes.java index 820d82dd3bd1..bb874045817e 100644 --- a/media/java/android/media/AudioAttributes.java +++ b/media/java/android/media/AudioAttributes.java @@ -19,7 +19,7 @@ package android.media; import android.annotation.IntDef; import android.annotation.NonNull; import android.annotation.SystemApi; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.media.audiopolicy.AudioProductStrategy; import android.os.Build; import android.os.Bundle; diff --git a/media/java/android/media/AudioDeviceAddress.aidl b/media/java/android/media/AudioDeviceAddress.aidl new file mode 100644 index 000000000000..6a1a7f79247c --- /dev/null +++ b/media/java/android/media/AudioDeviceAddress.aidl @@ -0,0 +1,18 @@ +/* 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. +*/ + +package android.media; + +parcelable AudioDeviceAddress; diff --git a/media/java/android/media/AudioDeviceAddress.java b/media/java/android/media/AudioDeviceAddress.java new file mode 100644 index 000000000000..415e77dc4049 --- /dev/null +++ b/media/java/android/media/AudioDeviceAddress.java @@ -0,0 +1,181 @@ +/* + * 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.media; + +import android.annotation.IntDef; +import android.annotation.NonNull; +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; + +/** + * @hide + * Class to represent device type (speaker, headset...), address and role (input, output) + * of an audio device. + * <p>Unlike {@link AudioDeviceInfo}, the device + * doesn't need to be connected to be uniquely identified, it can + * for instance represent a specific A2DP headset even after a + * disconnection, whereas the corresponding <code>AudioDeviceInfo</code> + * would then be invalid. + * <p>While creating / obtaining an instance is not protected by a + * permission, APIs using one rely on MODIFY_AUDIO_ROUTING. + */ +@SystemApi +public final class AudioDeviceAddress implements Parcelable { + + /** + * A role identifying input devices, such as microphones. + */ + public static final int ROLE_INPUT = AudioPort.ROLE_SOURCE; + /** + * A role identifying output devices, such as speakers or headphones. + */ + public static final int ROLE_OUTPUT = AudioPort.ROLE_SINK; + + /** @hide */ + @IntDef(flag = false, prefix = "ROLE_", value = { + ROLE_INPUT, ROLE_OUTPUT } + ) + @Retention(RetentionPolicy.SOURCE) + public @interface Role {} + + /** + * The audio device type, as defined in {@link AudioDeviceInfo} + */ + private final @AudioDeviceInfo.AudioDeviceType int mType; + /** + * The unique address of the device. Some devices don't have addresses, only an empty string. + */ + private final @NonNull String mAddress; + + /** + * Is input or output device + */ + private final @Role int mRole; + + /** + * Constructor from a valid {@link AudioDeviceInfo} + * @param deviceInfo the connected audio device from which to obtain the device-identifying + * type and address. + */ + public AudioDeviceAddress(@NonNull AudioDeviceInfo deviceInfo) { + Objects.requireNonNull(deviceInfo); + mRole = deviceInfo.isSink() ? ROLE_OUTPUT : ROLE_INPUT; + mType = deviceInfo.getType(); + mAddress = deviceInfo.getAddress(); + } + + public AudioDeviceAddress(@Role int role, @AudioDeviceInfo.AudioDeviceType int type, + @NonNull String address) { + Objects.requireNonNull(address); + if (role != ROLE_OUTPUT && role != ROLE_INPUT) { + throw new IllegalArgumentException("Invalid role " + role); + } + if (role == ROLE_OUTPUT && !AudioDeviceInfo.isValidAudioDeviceTypeOut(type)) { + throw new IllegalArgumentException("Invalid output device type " + type); + } + if (role == ROLE_INPUT && !AudioDeviceInfo.isValidAudioDeviceTypeIn(type)) { + throw new IllegalArgumentException("Invalid input device type " + type); + } + + mRole = role; + mType = type; + mAddress = address; + } + + public @Role int getRole() { + return mRole; + } + + public @AudioDeviceInfo.AudioDeviceType int getType() { + return mType; + } + + public @NonNull String getAddress() { + return mAddress; + } + + @Override + public int hashCode() { + return Objects.hash(mRole, mType, mAddress); + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + AudioDeviceAddress that = (AudioDeviceAddress) o; + return ((mRole == that.mRole) + && (mType == that.mType) + && mAddress.equals(that.mAddress)); + } + + /** @hide */ + public static String roleToString(@Role int role) { + return (role == ROLE_OUTPUT ? "output" : "input"); + } + + @Override + public String toString() { + return new String("AudioDeviceAddress:" + + " role:" + roleToString(mRole) + + " type:" + (mRole == ROLE_OUTPUT ? AudioSystem.getOutputDeviceName( + AudioDeviceInfo.convertDeviceTypeToInternalDevice(mType)) + : AudioSystem.getInputDeviceName( + AudioDeviceInfo.convertDeviceTypeToInternalDevice(mType))) + + " addr:" + mAddress); + } + + @Override + public int describeContents() { + return 0; + } + + @Override + public void writeToParcel(@NonNull Parcel dest, int flags) { + dest.writeInt(mRole); + dest.writeInt(mType); + dest.writeString(mAddress); + } + + private AudioDeviceAddress(@NonNull Parcel in) { + mRole = in.readInt(); + mType = in.readInt(); + mAddress = in.readString(); + } + + public static final @NonNull Parcelable.Creator<AudioDeviceAddress> CREATOR = + new Parcelable.Creator<AudioDeviceAddress>() { + /** + * Rebuilds an AudioDeviceAddress previously stored with writeToParcel(). + * @param p Parcel object to read the AudioDeviceAddress from + * @return a new AudioDeviceAddress created from the data in the parcel + */ + public AudioDeviceAddress createFromParcel(Parcel p) { + return new AudioDeviceAddress(p); + } + + public AudioDeviceAddress[] newArray(int size) { + return new AudioDeviceAddress[size]; + } + }; +} diff --git a/media/java/android/media/AudioDeviceInfo.java b/media/java/android/media/AudioDeviceInfo.java index ca895fcdfc4a..a39bc51acb24 100644 --- a/media/java/android/media/AudioDeviceInfo.java +++ b/media/java/android/media/AudioDeviceInfo.java @@ -149,6 +149,55 @@ public final class AudioDeviceInfo { TYPE_AUX_LINE, TYPE_IP, TYPE_BUS, + TYPE_HEARING_AID, + TYPE_BUILTIN_MIC, + TYPE_FM_TUNER, + TYPE_TV_TUNER } + ) + @Retention(RetentionPolicy.SOURCE) + public @interface AudioDeviceType {} /** @hide */ + @IntDef(flag = false, prefix = "TYPE", value = { + TYPE_BUILTIN_MIC, + TYPE_BLUETOOTH_SCO, + TYPE_BLUETOOTH_A2DP, + TYPE_WIRED_HEADSET, + TYPE_HDMI, + TYPE_TELEPHONY, + TYPE_DOCK, + TYPE_USB_ACCESSORY, + TYPE_USB_DEVICE, + TYPE_USB_HEADSET, + TYPE_FM_TUNER, + TYPE_TV_TUNER, + TYPE_LINE_ANALOG, + TYPE_LINE_DIGITAL, + TYPE_IP, + TYPE_BUS } + ) + @Retention(RetentionPolicy.SOURCE) + public @interface AudioDeviceTypeIn {} + + /** @hide */ + @IntDef(flag = false, prefix = "TYPE", value = { + TYPE_BUILTIN_EARPIECE, + TYPE_BUILTIN_SPEAKER, + TYPE_WIRED_HEADSET, + TYPE_WIRED_HEADPHONES, + TYPE_BLUETOOTH_SCO, + TYPE_BLUETOOTH_A2DP, + TYPE_HDMI, + TYPE_DOCK, + TYPE_USB_ACCESSORY, + TYPE_USB_DEVICE, + TYPE_USB_HEADSET, + TYPE_TELEPHONY, + TYPE_LINE_ANALOG, + TYPE_HDMI_ARC, + TYPE_LINE_DIGITAL, + TYPE_FM, + TYPE_AUX_LINE, + TYPE_IP, + TYPE_BUS, TYPE_HEARING_AID } ) @Retention(RetentionPolicy.SOURCE) @@ -183,6 +232,31 @@ public final class AudioDeviceInfo { } } + /** @hide */ + /*package*/ static boolean isValidAudioDeviceTypeIn(int type) { + switch (type) { + case TYPE_BUILTIN_MIC: + case TYPE_BLUETOOTH_SCO: + case TYPE_BLUETOOTH_A2DP: + case TYPE_WIRED_HEADSET: + case TYPE_HDMI: + case TYPE_TELEPHONY: + case TYPE_DOCK: + case TYPE_USB_ACCESSORY: + case TYPE_USB_DEVICE: + case TYPE_USB_HEADSET: + case TYPE_FM_TUNER: + case TYPE_TV_TUNER: + case TYPE_LINE_ANALOG: + case TYPE_LINE_DIGITAL: + case TYPE_IP: + case TYPE_BUS: + return true; + default: + return false; + } + } + @Override public boolean equals(Object o) { if (this == o) return true; diff --git a/media/java/android/media/AudioDevicePort.java b/media/java/android/media/AudioDevicePort.java index 62b18cbafcb1..51909db11a09 100644 --- a/media/java/android/media/AudioDevicePort.java +++ b/media/java/android/media/AudioDevicePort.java @@ -16,8 +16,7 @@ package android.media; -import android.annotation.UnsupportedAppUsage; -import android.media.AudioSystem; +import android.compat.annotation.UnsupportedAppUsage; /** * The AudioDevicePort is a specialized type of AudioPort diff --git a/media/java/android/media/AudioDevicePortConfig.java b/media/java/android/media/AudioDevicePortConfig.java index 0c647ea85c60..51b8037b82f8 100644 --- a/media/java/android/media/AudioDevicePortConfig.java +++ b/media/java/android/media/AudioDevicePortConfig.java @@ -16,7 +16,7 @@ package android.media; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; /** * An AudioDevicePortConfig describes a possible configuration of an output or input device diff --git a/media/java/android/media/AudioFormat.java b/media/java/android/media/AudioFormat.java index e55585ada6eb..7ff15df2d65e 100644 --- a/media/java/android/media/AudioFormat.java +++ b/media/java/android/media/AudioFormat.java @@ -20,7 +20,7 @@ import android.annotation.IntDef; import android.annotation.IntRange; import android.annotation.NonNull; import android.annotation.TestApi; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.os.Parcel; import android.os.Parcelable; diff --git a/media/java/android/media/AudioGain.java b/media/java/android/media/AudioGain.java index dd129a26ee59..cae1b59d46a7 100644 --- a/media/java/android/media/AudioGain.java +++ b/media/java/android/media/AudioGain.java @@ -16,7 +16,7 @@ package android.media; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; /** * The AudioGain describes a gain controller. Gain controllers are exposed by diff --git a/media/java/android/media/AudioGainConfig.java b/media/java/android/media/AudioGainConfig.java index f5ebef85d302..dfefa8621ef8 100644 --- a/media/java/android/media/AudioGainConfig.java +++ b/media/java/android/media/AudioGainConfig.java @@ -16,7 +16,7 @@ package android.media; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; /** * The AudioGainConfig is used by APIs setting or getting values on a given gain diff --git a/media/java/android/media/AudioHandle.java b/media/java/android/media/AudioHandle.java index 24f81f918af2..8fc834f8d0a9 100644 --- a/media/java/android/media/AudioHandle.java +++ b/media/java/android/media/AudioHandle.java @@ -16,7 +16,7 @@ package android.media; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; /** * The AudioHandle is used by the audio framework implementation to diff --git a/media/java/android/media/AudioManager.java b/media/java/android/media/AudioManager.java index f797da70e7d1..32eec0054d9b 100644 --- a/media/java/android/media/AudioManager.java +++ b/media/java/android/media/AudioManager.java @@ -27,12 +27,12 @@ import android.annotation.SuppressLint; import android.annotation.SystemApi; import android.annotation.SystemService; import android.annotation.TestApi; -import android.annotation.UnsupportedAppUsage; import android.app.NotificationManager; import android.app.PendingIntent; import android.bluetooth.BluetoothCodecConfig; import android.bluetooth.BluetoothDevice; import android.bluetooth.BluetoothProfile; +import android.compat.annotation.UnsupportedAppUsage; import android.content.ComponentName; import android.content.Context; import android.content.Intent; diff --git a/media/java/android/media/AudioMixPort.java b/media/java/android/media/AudioMixPort.java index c4a5c4d86a41..33d603f0b9da 100644 --- a/media/java/android/media/AudioMixPort.java +++ b/media/java/android/media/AudioMixPort.java @@ -16,7 +16,7 @@ package android.media; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; /** * The AudioMixPort is a specialized type of AudioPort diff --git a/media/java/android/media/AudioMixPortConfig.java b/media/java/android/media/AudioMixPortConfig.java index 315e46b725ad..9d8120624a45 100644 --- a/media/java/android/media/AudioMixPortConfig.java +++ b/media/java/android/media/AudioMixPortConfig.java @@ -16,7 +16,7 @@ package android.media; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; /** * An AudioMixPortConfig describes a possible configuration of an output or input mixer. diff --git a/media/java/android/media/AudioPatch.java b/media/java/android/media/AudioPatch.java index d1f800694f50..e5107d4e3309 100644 --- a/media/java/android/media/AudioPatch.java +++ b/media/java/android/media/AudioPatch.java @@ -16,7 +16,7 @@ package android.media; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; /** diff --git a/media/java/android/media/AudioPort.java b/media/java/android/media/AudioPort.java index 83eb240be743..7c3ca24e1c9a 100644 --- a/media/java/android/media/AudioPort.java +++ b/media/java/android/media/AudioPort.java @@ -16,7 +16,7 @@ package android.media; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; /** * An audio port is a node of the audio framework or hardware that can be connected to or diff --git a/media/java/android/media/AudioPortConfig.java b/media/java/android/media/AudioPortConfig.java index ac19bb167905..16fb5b80eb3e 100644 --- a/media/java/android/media/AudioPortConfig.java +++ b/media/java/android/media/AudioPortConfig.java @@ -16,7 +16,7 @@ package android.media; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; /** * An AudioPortConfig contains a possible configuration of an audio port chosen diff --git a/media/java/android/media/AudioPortEventHandler.java b/media/java/android/media/AudioPortEventHandler.java index 6d9d6265f5e7..14249cbe8945 100644 --- a/media/java/android/media/AudioPortEventHandler.java +++ b/media/java/android/media/AudioPortEventHandler.java @@ -16,7 +16,7 @@ package android.media; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.os.Handler; import android.os.HandlerThread; import android.os.Message; diff --git a/media/java/android/media/AudioRecord.java b/media/java/android/media/AudioRecord.java index ce9b07dd0c0e..306999cef7e7 100644 --- a/media/java/android/media/AudioRecord.java +++ b/media/java/android/media/AudioRecord.java @@ -23,8 +23,8 @@ import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.SystemApi; import android.annotation.TestApi; -import android.annotation.UnsupportedAppUsage; import android.app.ActivityThread; +import android.compat.annotation.UnsupportedAppUsage; import android.media.MediaRecorder.Source; import android.media.audiopolicy.AudioMix; import android.media.audiopolicy.AudioPolicy; diff --git a/media/java/android/media/AudioRecordingConfiguration.java b/media/java/android/media/AudioRecordingConfiguration.java index 874a215e4975..5f32c0f3f4a8 100644 --- a/media/java/android/media/AudioRecordingConfiguration.java +++ b/media/java/android/media/AudioRecordingConfiguration.java @@ -19,7 +19,7 @@ package android.media; import android.annotation.IntDef; import android.annotation.NonNull; import android.annotation.TestApi; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.media.audiofx.AudioEffect; import android.os.Parcel; import android.os.Parcelable; diff --git a/media/java/android/media/AudioSystem.java b/media/java/android/media/AudioSystem.java index 1033e56776b9..1ad61983904c 100644 --- a/media/java/android/media/AudioSystem.java +++ b/media/java/android/media/AudioSystem.java @@ -19,8 +19,8 @@ package android.media; import android.annotation.IntDef; import android.annotation.NonNull; import android.annotation.TestApi; -import android.annotation.UnsupportedAppUsage; import android.bluetooth.BluetoothCodecConfig; +import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; import android.content.pm.PackageManager; import android.media.audiofx.AudioEffect; diff --git a/media/java/android/media/AudioTrack.java b/media/java/android/media/AudioTrack.java index 7cd09de41346..0ced68ef8695 100644 --- a/media/java/android/media/AudioTrack.java +++ b/media/java/android/media/AudioTrack.java @@ -23,7 +23,7 @@ import android.annotation.IntRange; import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.TestApi; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.os.Binder; import android.os.Handler; import android.os.HandlerThread; diff --git a/media/java/android/media/CamcorderProfile.java b/media/java/android/media/CamcorderProfile.java index 963b1d1504e2..e4bab7466a70 100644 --- a/media/java/android/media/CamcorderProfile.java +++ b/media/java/android/media/CamcorderProfile.java @@ -16,7 +16,7 @@ package android.media; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.hardware.Camera; import android.hardware.Camera.CameraInfo; import android.os.Build; diff --git a/media/java/android/media/DecoderCapabilities.java b/media/java/android/media/DecoderCapabilities.java index df5e918ba8d5..ebfc63bd9bcd 100644 --- a/media/java/android/media/DecoderCapabilities.java +++ b/media/java/android/media/DecoderCapabilities.java @@ -16,9 +16,10 @@ package android.media; -import android.annotation.UnsupportedAppUsage; -import java.util.List; +import android.compat.annotation.UnsupportedAppUsage; + import java.util.ArrayList; +import java.util.List; /** * {@hide} diff --git a/media/java/android/media/EncoderCapabilities.java b/media/java/android/media/EncoderCapabilities.java index c09c5fae1213..67ce0f7cc0b9 100644 --- a/media/java/android/media/EncoderCapabilities.java +++ b/media/java/android/media/EncoderCapabilities.java @@ -16,9 +16,10 @@ package android.media; -import android.annotation.UnsupportedAppUsage; -import java.util.List; +import android.compat.annotation.UnsupportedAppUsage; + import java.util.ArrayList; +import java.util.List; /** * The EncoderCapabilities class is used to retrieve the diff --git a/media/java/android/media/ExifInterface.java b/media/java/android/media/ExifInterface.java index 5645ba5d7dac..b41792710cbf 100644 --- a/media/java/android/media/ExifInterface.java +++ b/media/java/android/media/ExifInterface.java @@ -20,7 +20,7 @@ import android.annotation.CurrentTimeMillisLong; import android.annotation.IntDef; import android.annotation.NonNull; import android.annotation.Nullable; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.res.AssetManager; import android.graphics.Bitmap; import android.graphics.BitmapFactory; diff --git a/media/java/android/media/Image.java b/media/java/android/media/Image.java index 70a343f4de01..b5acbd457db0 100644 --- a/media/java/android/media/Image.java +++ b/media/java/android/media/Image.java @@ -16,14 +16,13 @@ package android.media; -import java.nio.ByteBuffer; -import java.lang.AutoCloseable; - import android.annotation.Nullable; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.graphics.Rect; import android.hardware.HardwareBuffer; +import java.nio.ByteBuffer; + /** * <p>A single complete image buffer to use with a media source such as a * {@link MediaCodec} or a diff --git a/media/java/android/media/JetPlayer.java b/media/java/android/media/JetPlayer.java index e85b3ff99104..84ee09b35b81 100644 --- a/media/java/android/media/JetPlayer.java +++ b/media/java/android/media/JetPlayer.java @@ -17,7 +17,7 @@ package android.media; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.res.AssetFileDescriptor; import android.os.Handler; import android.os.Looper; diff --git a/media/java/android/media/MediaCodec.java b/media/java/android/media/MediaCodec.java index c9d79784004c..e702f19903d0 100644 --- a/media/java/android/media/MediaCodec.java +++ b/media/java/android/media/MediaCodec.java @@ -19,7 +19,7 @@ package android.media; import android.annotation.IntDef; import android.annotation.NonNull; import android.annotation.Nullable; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.graphics.ImageFormat; import android.graphics.Rect; import android.graphics.SurfaceTexture; diff --git a/media/java/android/media/MediaCodecInfo.java b/media/java/android/media/MediaCodecInfo.java index f304f7cc5981..f3752d56ea0f 100644 --- a/media/java/android/media/MediaCodecInfo.java +++ b/media/java/android/media/MediaCodecInfo.java @@ -22,7 +22,7 @@ import static android.media.Utils.sortDistinctRanges; import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.TestApi; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.os.Build; import android.os.SystemProperties; import android.util.Log; diff --git a/media/java/android/media/MediaDrm.java b/media/java/android/media/MediaDrm.java index a08aec3ed20c..ea9a373a19f2 100644 --- a/media/java/android/media/MediaDrm.java +++ b/media/java/android/media/MediaDrm.java @@ -21,17 +21,17 @@ import android.annotation.IntDef; import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.StringDef; -import android.annotation.SystemApi; -import android.annotation.UnsupportedAppUsage; import android.app.ActivityThread; +import android.compat.annotation.UnsupportedAppUsage; import android.os.Handler; import android.os.HandlerExecutor; import android.os.Looper; -import android.os.Message; import android.os.Parcel; import android.os.PersistableBundle; import android.util.Log; + import dalvik.system.CloseGuard; + import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.ref.WeakReference; diff --git a/media/java/android/media/MediaFile.java b/media/java/android/media/MediaFile.java index c4eb0310f292..9908e042c6a4 100644 --- a/media/java/android/media/MediaFile.java +++ b/media/java/android/media/MediaFile.java @@ -20,7 +20,7 @@ import static android.content.ContentResolver.MIME_TYPE_DEFAULT; import android.annotation.NonNull; import android.annotation.Nullable; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.mtp.MtpConstants; import libcore.content.type.MimeMap; diff --git a/media/java/android/media/MediaFormat.java b/media/java/android/media/MediaFormat.java index 8b667f772867..841799a58aa4 100644 --- a/media/java/android/media/MediaFormat.java +++ b/media/java/android/media/MediaFormat.java @@ -19,7 +19,7 @@ package android.media; import android.annotation.IntDef; import android.annotation.NonNull; import android.annotation.Nullable; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; diff --git a/media/java/android/media/MediaHTTPConnection.java b/media/java/android/media/MediaHTTPConnection.java index 8ee929e77899..a17ff825e21b 100644 --- a/media/java/android/media/MediaHTTPConnection.java +++ b/media/java/android/media/MediaHTTPConnection.java @@ -18,13 +18,14 @@ package android.media; import static android.media.MediaPlayer.MEDIA_ERROR_UNSUPPORTED; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.net.NetworkUtils; import android.os.IBinder; import android.os.StrictMode; import android.util.Log; import com.android.internal.annotations.GuardedBy; + import java.io.BufferedInputStream; import java.io.IOException; import java.io.InputStream; diff --git a/media/java/android/media/MediaHTTPService.java b/media/java/android/media/MediaHTTPService.java index 97a0df799101..3008067daefb 100644 --- a/media/java/android/media/MediaHTTPService.java +++ b/media/java/android/media/MediaHTTPService.java @@ -17,7 +17,7 @@ package android.media; import android.annotation.Nullable; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.os.IBinder; import android.util.Log; diff --git a/media/java/android/media/MediaInserter.java b/media/java/android/media/MediaInserter.java index 0749f58e460d..ca7a01cb990d 100644 --- a/media/java/android/media/MediaInserter.java +++ b/media/java/android/media/MediaInserter.java @@ -16,7 +16,7 @@ package android.media; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.ContentProviderClient; import android.content.ContentValues; import android.net.Uri; diff --git a/media/java/android/media/MediaMetadata.java b/media/java/android/media/MediaMetadata.java index 8512dbe8d224..a23191f36efc 100644 --- a/media/java/android/media/MediaMetadata.java +++ b/media/java/android/media/MediaMetadata.java @@ -17,7 +17,7 @@ package android.media; import android.annotation.NonNull; import android.annotation.StringDef; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.ContentResolver; import android.graphics.Bitmap; import android.graphics.BitmapFactory; diff --git a/media/java/android/media/MediaMetadataRetriever.java b/media/java/android/media/MediaMetadataRetriever.java index c43b78cf4fc7..a21a630e200a 100644 --- a/media/java/android/media/MediaMetadataRetriever.java +++ b/media/java/android/media/MediaMetadataRetriever.java @@ -19,7 +19,7 @@ package android.media; import android.annotation.IntDef; import android.annotation.NonNull; import android.annotation.Nullable; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.ContentResolver; import android.content.Context; import android.content.res.AssetFileDescriptor; diff --git a/media/java/android/media/MediaMuxer.java b/media/java/android/media/MediaMuxer.java index 0fb392bfc0fe..14a48d72f9bb 100644 --- a/media/java/android/media/MediaMuxer.java +++ b/media/java/android/media/MediaMuxer.java @@ -18,8 +18,7 @@ package android.media; import android.annotation.IntDef; import android.annotation.NonNull; -import android.annotation.UnsupportedAppUsage; -import android.media.MediaCodec; +import android.compat.annotation.UnsupportedAppUsage; import android.media.MediaCodec.BufferInfo; import dalvik.system.CloseGuard; diff --git a/media/java/android/media/MediaPlayer.java b/media/java/android/media/MediaPlayer.java index 353e58e98efa..6b953ae932f0 100644 --- a/media/java/android/media/MediaPlayer.java +++ b/media/java/android/media/MediaPlayer.java @@ -19,8 +19,8 @@ package android.media; import android.annotation.IntDef; import android.annotation.NonNull; import android.annotation.Nullable; -import android.annotation.UnsupportedAppUsage; import android.app.ActivityThread; +import android.compat.annotation.UnsupportedAppUsage; import android.content.ContentProvider; import android.content.ContentResolver; import android.content.Context; diff --git a/media/java/android/media/MediaRecorder.java b/media/java/android/media/MediaRecorder.java index 63b22df12953..c957a883be1a 100644 --- a/media/java/android/media/MediaRecorder.java +++ b/media/java/android/media/MediaRecorder.java @@ -23,8 +23,8 @@ import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.RequiresPermission; import android.annotation.SystemApi; -import android.annotation.UnsupportedAppUsage; import android.app.ActivityThread; +import android.compat.annotation.UnsupportedAppUsage; import android.hardware.Camera; import android.os.Build; import android.os.Handler; diff --git a/media/java/android/media/MediaRouter.java b/media/java/android/media/MediaRouter.java index d72231f40dcf..9837e1cc62b3 100644 --- a/media/java/android/media/MediaRouter.java +++ b/media/java/android/media/MediaRouter.java @@ -22,8 +22,8 @@ import android.annotation.IntDef; import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.SystemService; -import android.annotation.UnsupportedAppUsage; import android.app.ActivityThread; +import android.compat.annotation.UnsupportedAppUsage; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; diff --git a/media/java/android/media/MediaScanner.java b/media/java/android/media/MediaScanner.java index 771628cf7b1e..317502d760a8 100644 --- a/media/java/android/media/MediaScanner.java +++ b/media/java/android/media/MediaScanner.java @@ -16,7 +16,7 @@ package android.media; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.ContentProviderClient; import android.content.ContentResolver; import android.content.ContentUris; diff --git a/media/java/android/media/Metadata.java b/media/java/android/media/Metadata.java index 792a2ba678fd..ef17073654a6 100644 --- a/media/java/android/media/Metadata.java +++ b/media/java/android/media/Metadata.java @@ -16,7 +16,7 @@ package android.media; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.os.Parcel; import android.util.Log; import android.util.MathUtils; diff --git a/media/java/android/media/MicrophoneInfo.java b/media/java/android/media/MicrophoneInfo.java index f805975d53b0..876628fefff4 100644 --- a/media/java/android/media/MicrophoneInfo.java +++ b/media/java/android/media/MicrophoneInfo.java @@ -18,7 +18,7 @@ package android.media; import android.annotation.IntDef; import android.annotation.NonNull; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.util.Pair; import java.lang.annotation.Retention; diff --git a/media/java/android/media/PlaybackParams.java b/media/java/android/media/PlaybackParams.java index b4325b6ea53d..f24f831d0333 100644 --- a/media/java/android/media/PlaybackParams.java +++ b/media/java/android/media/PlaybackParams.java @@ -18,7 +18,7 @@ package android.media; import android.annotation.IntDef; import android.annotation.TestApi; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.os.Build; import android.os.Parcel; import android.os.Parcelable; diff --git a/media/java/android/media/RemoteControlClient.java b/media/java/android/media/RemoteControlClient.java index 325420b06122..c5fd3c30236d 100644 --- a/media/java/android/media/RemoteControlClient.java +++ b/media/java/android/media/RemoteControlClient.java @@ -16,8 +16,8 @@ package android.media; -import android.annotation.UnsupportedAppUsage; import android.app.PendingIntent; +import android.compat.annotation.UnsupportedAppUsage; import android.content.ComponentName; import android.content.Intent; import android.graphics.Bitmap; diff --git a/media/java/android/media/RemoteController.java b/media/java/android/media/RemoteController.java index f70963a982e4..9e48f1e05391 100644 --- a/media/java/android/media/RemoteController.java +++ b/media/java/android/media/RemoteController.java @@ -16,8 +16,8 @@ package android.media; -import android.annotation.UnsupportedAppUsage; import android.app.ActivityManager; +import android.compat.annotation.UnsupportedAppUsage; import android.content.ComponentName; import android.content.Context; import android.graphics.Bitmap; diff --git a/media/java/android/media/RemoteDisplay.java b/media/java/android/media/RemoteDisplay.java index 2be206f2f462..e529af9da935 100644 --- a/media/java/android/media/RemoteDisplay.java +++ b/media/java/android/media/RemoteDisplay.java @@ -16,12 +16,12 @@ package android.media; -import dalvik.system.CloseGuard; - -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.os.Handler; import android.view.Surface; +import dalvik.system.CloseGuard; + /** * Listens for Wifi remote display connections managed by the media server. * diff --git a/media/java/android/media/RemoteDisplayState.java b/media/java/android/media/RemoteDisplayState.java index 2f4ace0c8fdd..fed361a960e6 100644 --- a/media/java/android/media/RemoteDisplayState.java +++ b/media/java/android/media/RemoteDisplayState.java @@ -16,7 +16,7 @@ package android.media; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.os.Parcel; import android.os.Parcelable; import android.text.TextUtils; diff --git a/media/java/android/media/Ringtone.java b/media/java/android/media/Ringtone.java index eb680c8377f4..d35bc4176cb3 100644 --- a/media/java/android/media/Ringtone.java +++ b/media/java/android/media/Ringtone.java @@ -17,7 +17,7 @@ package android.media; import android.annotation.Nullable; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.ContentProvider; import android.content.ContentResolver; import android.content.Context; diff --git a/media/java/android/media/RingtoneManager.java b/media/java/android/media/RingtoneManager.java index 435d8d766149..6fd47c42bcba 100644 --- a/media/java/android/media/RingtoneManager.java +++ b/media/java/android/media/RingtoneManager.java @@ -22,9 +22,9 @@ import android.annotation.Nullable; import android.annotation.RequiresPermission; import android.annotation.SdkConstant; import android.annotation.SdkConstant.SdkConstantType; -import android.annotation.UnsupportedAppUsage; import android.annotation.WorkerThread; import android.app.Activity; +import android.compat.annotation.UnsupportedAppUsage; import android.content.ContentProvider; import android.content.ContentResolver; import android.content.ContentUris; diff --git a/media/java/android/media/SubtitleController.java b/media/java/android/media/SubtitleController.java index 1a241af7345d..48657a6c810f 100644 --- a/media/java/android/media/SubtitleController.java +++ b/media/java/android/media/SubtitleController.java @@ -16,10 +16,7 @@ package android.media; -import java.util.Locale; -import java.util.Vector; - -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; import android.media.MediaPlayer.TrackInfo; import android.media.SubtitleTrack.RenderingWidget; @@ -28,6 +25,9 @@ import android.os.Looper; import android.os.Message; import android.view.accessibility.CaptioningManager; +import java.util.Locale; +import java.util.Vector; + /** * The subtitle controller provides the architecture to display subtitles for a * media source. It allows specifying which tracks to display, on which anchor diff --git a/media/java/android/media/SubtitleTrack.java b/media/java/android/media/SubtitleTrack.java index 0705d97a9edf..10669f466fe5 100644 --- a/media/java/android/media/SubtitleTrack.java +++ b/media/java/android/media/SubtitleTrack.java @@ -16,7 +16,7 @@ package android.media; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.graphics.Canvas; import android.media.MediaPlayer.TrackInfo; import android.os.Handler; diff --git a/media/java/android/media/ThumbnailUtils.java b/media/java/android/media/ThumbnailUtils.java index 534d63b4cca0..cbdf9adfd0e1 100644 --- a/media/java/android/media/ThumbnailUtils.java +++ b/media/java/android/media/ThumbnailUtils.java @@ -24,7 +24,7 @@ import static android.os.Environment.MEDIA_UNKNOWN; import android.annotation.NonNull; import android.annotation.Nullable; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.ContentResolver; import android.graphics.Bitmap; import android.graphics.BitmapFactory; diff --git a/media/java/android/media/TimedText.java b/media/java/android/media/TimedText.java index d8cdf9c12e09..120642a8e7cb 100644 --- a/media/java/android/media/TimedText.java +++ b/media/java/android/media/TimedText.java @@ -16,14 +16,15 @@ package android.media; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.graphics.Rect; import android.os.Parcel; import android.util.Log; + +import java.util.ArrayList; import java.util.HashMap; -import java.util.Set; import java.util.List; -import java.util.ArrayList; +import java.util.Set; /** * Class to hold the timed text's metadata, including: diff --git a/media/java/android/media/ToneGenerator.java b/media/java/android/media/ToneGenerator.java index c6d5ba3f9953..cc114a9092e1 100644 --- a/media/java/android/media/ToneGenerator.java +++ b/media/java/android/media/ToneGenerator.java @@ -16,7 +16,7 @@ package android.media; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; diff --git a/media/java/android/media/TtmlRenderer.java b/media/java/android/media/TtmlRenderer.java index 34154ce93a8c..e5782642f4eb 100644 --- a/media/java/android/media/TtmlRenderer.java +++ b/media/java/android/media/TtmlRenderer.java @@ -16,7 +16,7 @@ package android.media; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; import android.text.TextUtils; import android.util.AttributeSet; @@ -27,6 +27,10 @@ import android.view.accessibility.CaptioningManager; import android.widget.LinearLayout; import android.widget.TextView; +import org.xmlpull.v1.XmlPullParser; +import org.xmlpull.v1.XmlPullParserException; +import org.xmlpull.v1.XmlPullParserFactory; + import java.io.IOException; import java.io.StringReader; import java.util.ArrayList; @@ -37,10 +41,6 @@ import java.util.Vector; import java.util.regex.Matcher; import java.util.regex.Pattern; -import org.xmlpull.v1.XmlPullParser; -import org.xmlpull.v1.XmlPullParserException; -import org.xmlpull.v1.XmlPullParserFactory; - /** @hide */ public class TtmlRenderer extends SubtitleController.Renderer { private final Context mContext; diff --git a/media/java/android/media/VolumeShaper.java b/media/java/android/media/VolumeShaper.java index 663d564af23e..99dfe1e8e32f 100644 --- a/media/java/android/media/VolumeShaper.java +++ b/media/java/android/media/VolumeShaper.java @@ -19,13 +19,12 @@ import android.annotation.IntDef; import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.TestApi; -import android.annotation.UnsupportedAppUsage; +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.lang.AutoCloseable; import java.lang.ref.WeakReference; import java.util.Arrays; import java.util.Objects; diff --git a/media/java/android/media/WebVttRenderer.java b/media/java/android/media/WebVttRenderer.java index 36458d7e1746..bc1429499e70 100644 --- a/media/java/android/media/WebVttRenderer.java +++ b/media/java/android/media/WebVttRenderer.java @@ -16,7 +16,7 @@ package android.media; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; import android.text.Layout.Alignment; import android.text.SpannableStringBuilder; diff --git a/media/java/android/media/audiofx/AudioEffect.java b/media/java/android/media/audiofx/AudioEffect.java index 5b4bbce91784..cad5aa6aaa3c 100644 --- a/media/java/android/media/audiofx/AudioEffect.java +++ b/media/java/android/media/audiofx/AudioEffect.java @@ -16,11 +16,18 @@ package android.media.audiofx; +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.TestApi; -import android.annotation.UnsupportedAppUsage; import android.app.ActivityThread; +import android.compat.annotation.UnsupportedAppUsage; +import android.media.AudioDeviceAddress; +import android.media.AudioDeviceInfo; +import android.media.AudioSystem; import android.os.Build; import android.os.Handler; import android.os.Looper; @@ -448,12 +455,46 @@ public class AudioEffect { public AudioEffect(UUID type, UUID uuid, int priority, int audioSession) throws IllegalArgumentException, UnsupportedOperationException, RuntimeException { + this(type, uuid, priority, audioSession, null); + } + + /** + * Constructs an AudioEffect attached to a particular audio device. + * The device does not have to be attached when the effect is created. The effect will only + * be applied when the device is actually selected for playback or capture. + * @param uuid unique identifier of a particular effect implementation. + * @param device the device the effect must be attached to. + * + * @throws java.lang.IllegalArgumentException + * @throws java.lang.UnsupportedOperationException + * @throws java.lang.RuntimeException + * @hide + */ + @SystemApi + @RequiresPermission(android.Manifest.permission.MODIFY_DEFAULT_AUDIO_EFFECTS) + public AudioEffect(@NonNull UUID uuid, @NonNull AudioDeviceAddress device) { + this(EFFECT_TYPE_NULL, Objects.requireNonNull(uuid), 0, -2, Objects.requireNonNull(device)); + } + + private AudioEffect(UUID type, UUID uuid, int priority, + int audioSession, @Nullable AudioDeviceAddress device) + throws IllegalArgumentException, UnsupportedOperationException, + RuntimeException { int[] id = new int[1]; Descriptor[] desc = new Descriptor[1]; + + int deviceType = AudioSystem.DEVICE_NONE; + String deviceAddress = ""; + if (device != null) { + deviceType = AudioDeviceInfo.convertDeviceTypeToInternalDevice(device.getType()); + deviceAddress = device.getAddress(); + } + // native initialization int initResult = native_setup(new WeakReference<AudioEffect>(this), - type.toString(), uuid.toString(), priority, audioSession, id, - desc, ActivityThread.currentOpPackageName()); + type.toString(), uuid.toString(), priority, audioSession, + deviceType, deviceAddress, + id, desc, ActivityThread.currentOpPackageName()); if (initResult != SUCCESS && initResult != ALREADY_EXISTS) { Log.e(TAG, "Error code " + initResult + " when initializing AudioEffect."); @@ -1293,7 +1334,8 @@ public class AudioEffect { private static native final void native_init(); private native final int native_setup(Object audioeffect_this, String type, - String uuid, int priority, int audioSession, int[] id, Object[] desc, + String uuid, int priority, int audioSession, + int deviceType, String deviceAddress, int[] id, Object[] desc, String opPackageName); private native final void native_finalize(); diff --git a/media/java/android/media/audiofx/Visualizer.java b/media/java/android/media/audiofx/Visualizer.java index 89a509f64a1b..392e8fe7543f 100644 --- a/media/java/android/media/audiofx/Visualizer.java +++ b/media/java/android/media/audiofx/Visualizer.java @@ -16,8 +16,8 @@ package android.media.audiofx; -import android.annotation.UnsupportedAppUsage; import android.app.ActivityThread; +import android.compat.annotation.UnsupportedAppUsage; import android.os.Handler; import android.os.Looper; import android.os.Message; diff --git a/media/java/android/media/audiopolicy/AudioMix.java b/media/java/android/media/audiopolicy/AudioMix.java index a82c78fad271..dd9877a9c706 100644 --- a/media/java/android/media/audiopolicy/AudioMix.java +++ b/media/java/android/media/audiopolicy/AudioMix.java @@ -20,7 +20,7 @@ import android.annotation.IntDef; import android.annotation.NonNull; import android.annotation.SystemApi; import android.annotation.TestApi; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.media.AudioDeviceInfo; import android.media.AudioFormat; import android.media.AudioSystem; diff --git a/media/java/android/media/audiopolicy/AudioMixingRule.java b/media/java/android/media/audiopolicy/AudioMixingRule.java index c4afd95be9ac..8c204d222cd4 100644 --- a/media/java/android/media/audiopolicy/AudioMixingRule.java +++ b/media/java/android/media/audiopolicy/AudioMixingRule.java @@ -19,7 +19,7 @@ package android.media.audiopolicy; import android.annotation.NonNull; import android.annotation.SystemApi; import android.annotation.TestApi; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.media.AudioAttributes; import android.os.Parcel; import android.util.Log; diff --git a/media/java/android/media/session/MediaController.java b/media/java/android/media/session/MediaController.java index 1fc4f7d59ca5..a856653e8bc9 100644 --- a/media/java/android/media/session/MediaController.java +++ b/media/java/android/media/session/MediaController.java @@ -18,8 +18,8 @@ package android.media.session; import android.annotation.NonNull; import android.annotation.Nullable; -import android.annotation.UnsupportedAppUsage; import android.app.PendingIntent; +import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; import android.content.pm.ParceledListSlice; import android.media.AudioAttributes; diff --git a/media/java/android/media/session/MediaSession.java b/media/java/android/media/session/MediaSession.java index e11715ff7299..5db4e8c1e3f7 100644 --- a/media/java/android/media/session/MediaSession.java +++ b/media/java/android/media/session/MediaSession.java @@ -19,9 +19,9 @@ package android.media.session; import android.annotation.IntDef; import android.annotation.NonNull; import android.annotation.Nullable; -import android.annotation.UnsupportedAppUsage; import android.app.Activity; import android.app.PendingIntent; +import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; import android.content.Intent; import android.content.pm.ParceledListSlice; diff --git a/media/java/android/media/session/MediaSessionLegacyHelper.java b/media/java/android/media/session/MediaSessionLegacyHelper.java index 123c4f75d5b6..0d506f0eb52c 100644 --- a/media/java/android/media/session/MediaSessionLegacyHelper.java +++ b/media/java/android/media/session/MediaSessionLegacyHelper.java @@ -16,9 +16,9 @@ package android.media.session; -import android.annotation.UnsupportedAppUsage; import android.app.PendingIntent; import android.app.PendingIntent.CanceledException; +import android.compat.annotation.UnsupportedAppUsage; import android.content.ComponentName; import android.content.Context; import android.content.Intent; @@ -26,7 +26,6 @@ import android.graphics.Bitmap; import android.graphics.Canvas; import android.graphics.Paint; import android.graphics.RectF; -import android.media.AudioManager; import android.media.MediaMetadata; import android.media.MediaMetadataEditor; import android.media.MediaMetadataRetriever; diff --git a/media/java/android/media/session/MediaSessionManager.java b/media/java/android/media/session/MediaSessionManager.java index a89dc5f1d2af..aff725734ee1 100644 --- a/media/java/android/media/session/MediaSessionManager.java +++ b/media/java/android/media/session/MediaSessionManager.java @@ -22,7 +22,7 @@ import android.annotation.Nullable; import android.annotation.RequiresPermission; import android.annotation.SystemApi; import android.annotation.SystemService; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.ComponentName; import android.content.Context; import android.content.pm.ParceledListSlice; diff --git a/media/java/android/media/soundtrigger/SoundTriggerDetector.java b/media/java/android/media/soundtrigger/SoundTriggerDetector.java index 56e5566df29c..77596a5de815 100644 --- a/media/java/android/media/soundtrigger/SoundTriggerDetector.java +++ b/media/java/android/media/soundtrigger/SoundTriggerDetector.java @@ -22,7 +22,7 @@ import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.RequiresPermission; import android.annotation.SystemApi; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.hardware.soundtrigger.IRecognitionStatusCallback; import android.hardware.soundtrigger.SoundTrigger; import android.hardware.soundtrigger.SoundTrigger.RecognitionConfig; diff --git a/media/java/android/media/soundtrigger/SoundTriggerManager.java b/media/java/android/media/soundtrigger/SoundTriggerManager.java index ada77c53bb34..3f0aec63283c 100644 --- a/media/java/android/media/soundtrigger/SoundTriggerManager.java +++ b/media/java/android/media/soundtrigger/SoundTriggerManager.java @@ -23,7 +23,7 @@ import android.annotation.Nullable; import android.annotation.RequiresPermission; import android.annotation.SystemApi; import android.annotation.SystemService; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.ComponentName; import android.content.Context; import android.hardware.soundtrigger.SoundTrigger; diff --git a/media/java/android/media/tv/TvInputInfo.java b/media/java/android/media/tv/TvInputInfo.java index 1b9cac0c8c99..377b2bc19c6b 100644 --- a/media/java/android/media/tv/TvInputInfo.java +++ b/media/java/android/media/tv/TvInputInfo.java @@ -20,7 +20,7 @@ import android.annotation.IntDef; import android.annotation.NonNull; import android.annotation.StringRes; import android.annotation.SystemApi; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.ComponentName; import android.content.Context; import android.content.Intent; diff --git a/media/java/android/media/tv/TvInputService.java b/media/java/android/media/tv/TvInputService.java index 5c11ed9bb7b4..7fbb3376d5fb 100755 --- a/media/java/android/media/tv/TvInputService.java +++ b/media/java/android/media/tv/TvInputService.java @@ -22,9 +22,9 @@ import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.SuppressLint; import android.annotation.SystemApi; -import android.annotation.UnsupportedAppUsage; import android.app.ActivityManager; import android.app.Service; +import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; import android.content.Intent; import android.graphics.PixelFormat; diff --git a/media/java/android/media/tv/TvTrackInfo.java b/media/java/android/media/tv/TvTrackInfo.java index ab7bbca1d01c..4318a0ae7d06 100644 --- a/media/java/android/media/tv/TvTrackInfo.java +++ b/media/java/android/media/tv/TvTrackInfo.java @@ -62,6 +62,8 @@ public final class TvTrackInfo implements Parcelable { private final int mAudioChannelCount; private final int mAudioSampleRate; private final boolean mAudioDescription; + private final boolean mHardOfHearing; + private final boolean mSpokenSubtitle; private final int mVideoWidth; private final int mVideoHeight; private final float mVideoFrameRate; @@ -72,8 +74,9 @@ public final class TvTrackInfo implements Parcelable { private TvTrackInfo(int type, String id, String language, CharSequence description, boolean encrypted, int audioChannelCount, int audioSampleRate, boolean audioDescription, - int videoWidth, int videoHeight, float videoFrameRate, float videoPixelAspectRatio, - byte videoActiveFormatDescription, Bundle extra) { + boolean hardOfHearing, boolean spokenSubtitle, int videoWidth, int videoHeight, + float videoFrameRate, float videoPixelAspectRatio, byte videoActiveFormatDescription, + Bundle extra) { mType = type; mId = id; mLanguage = language; @@ -82,6 +85,8 @@ public final class TvTrackInfo implements Parcelable { mAudioChannelCount = audioChannelCount; mAudioSampleRate = audioSampleRate; mAudioDescription = audioDescription; + mHardOfHearing = hardOfHearing; + mSpokenSubtitle = spokenSubtitle; mVideoWidth = videoWidth; mVideoHeight = videoHeight; mVideoFrameRate = videoFrameRate; @@ -99,6 +104,8 @@ public final class TvTrackInfo implements Parcelable { mAudioChannelCount = in.readInt(); mAudioSampleRate = in.readInt(); mAudioDescription = in.readInt() != 0; + mHardOfHearing = in.readInt() != 0; + mSpokenSubtitle = in.readInt() != 0; mVideoWidth = in.readInt(); mVideoHeight = in.readInt(); mVideoFrameRate = in.readFloat(); @@ -192,6 +199,39 @@ public final class TvTrackInfo implements Parcelable { } /** + * Returns {@code true} if the track is intended for people with hearing impairment, {@code + * false} otherwise. Valid only for {@link #TYPE_AUDIO} and {@link #TYPE_SUBTITLE} tracks. + * + * <p>For example of broadcast, hard of hearing information may be referred to broadcast + * standard (e.g. ISO 639 Language Descriptor of ISO/IEC 13818-1, Supplementary Audio Language + * Descriptor, AC-3 Descriptor, Enhanced AC-3 Descriptor, AAC Descriptor of ETSI EN 300 468). + * + * @throws IllegalStateException if not called on an audio track or a subtitle track + */ + public boolean isHardOfHearing() { + if (mType != TYPE_AUDIO && mType != TYPE_SUBTITLE) { + throw new IllegalStateException("Not an audio or a subtitle track"); + } + return mHardOfHearing; + } + + /** + * Returns {@code true} if the track is a spoken subtitle for people with visual impairment, + * {@code false} otherwise. Valid only for {@link #TYPE_AUDIO} tracks. + * + * <p>For example of broadcast, spoken subtitle information may be referred to broadcast + * standard (e.g. Supplementary Audio Language Descriptor of ETSI EN 300 468). + * + * @throws IllegalStateException if not called on an audio track + */ + public boolean isSpokenSubtitle() { + if (mType != TYPE_AUDIO) { + throw new IllegalStateException("Not an audio track"); + } + return mSpokenSubtitle; + } + + /** * Returns the width of the video, in the unit of pixels. Valid only for {@link #TYPE_VIDEO} * tracks. * @@ -287,6 +327,8 @@ public final class TvTrackInfo implements Parcelable { dest.writeInt(mAudioChannelCount); dest.writeInt(mAudioSampleRate); dest.writeInt(mAudioDescription ? 1 : 0); + dest.writeInt(mHardOfHearing ? 1 : 0); + dest.writeInt(mSpokenSubtitle ? 1 : 0); dest.writeInt(mVideoWidth); dest.writeInt(mVideoHeight); dest.writeFloat(mVideoFrameRate); @@ -310,6 +352,7 @@ public final class TvTrackInfo implements Parcelable { if (!TextUtils.equals(mId, obj.mId) || mType != obj.mType || !TextUtils.equals(mLanguage, obj.mLanguage) || !TextUtils.equals(mDescription, obj.mDescription) + || mEncrypted != obj.mEncrypted || !Objects.equals(mExtra, obj.mExtra)) { return false; } @@ -318,7 +361,9 @@ public final class TvTrackInfo implements Parcelable { case TYPE_AUDIO: return mAudioChannelCount == obj.mAudioChannelCount && mAudioSampleRate == obj.mAudioSampleRate - && mAudioDescription == obj.mAudioDescription; + && mAudioDescription == obj.mAudioDescription + && mHardOfHearing == obj.mHardOfHearing + && mSpokenSubtitle == obj.mSpokenSubtitle; case TYPE_VIDEO: return mVideoWidth == obj.mVideoWidth @@ -326,6 +371,9 @@ public final class TvTrackInfo implements Parcelable { && mVideoFrameRate == obj.mVideoFrameRate && mVideoPixelAspectRatio == obj.mVideoPixelAspectRatio && mVideoActiveFormatDescription == obj.mVideoActiveFormatDescription; + + case TYPE_SUBTITLE: + return mHardOfHearing == obj.mHardOfHearing; } return true; @@ -361,6 +409,8 @@ public final class TvTrackInfo implements Parcelable { private int mAudioChannelCount; private int mAudioSampleRate; private boolean mAudioDescription; + private boolean mHardOfHearing; + private boolean mSpokenSubtitle; private int mVideoWidth; private int mVideoHeight; private float mVideoFrameRate; @@ -474,6 +524,46 @@ public final class TvTrackInfo implements Parcelable { } /** + * Sets the hard of hearing attribute of the track. Valid only for {@link #TYPE_AUDIO} and + * {@link #TYPE_SUBTITLE} tracks. + * + * <p>For example of broadcast, hard of hearing information may be referred to broadcast + * standard (e.g. ISO 639 Language Descriptor of ISO/IEC 13818-1, Supplementary Audio + * Language Descriptor, AC-3 Descriptor, Enhanced AC-3 Descriptor, AAC Descriptor of ETSI EN + * 300 468). + * + * @param hardOfHearing The hard of hearing attribute of the track. + * @throws IllegalStateException if not called on an audio track or a subtitle track + */ + @NonNull + public Builder setHardOfHearing(boolean hardOfHearing) { + if (mType != TYPE_AUDIO && mType != TYPE_SUBTITLE) { + throw new IllegalStateException("Not an audio track or a subtitle track"); + } + mHardOfHearing = hardOfHearing; + return this; + } + + /** + * Sets the spoken subtitle attribute of the audio. Valid only for {@link #TYPE_AUDIO} + * tracks. + * + * <p>For example of broadcast, spoken subtitle information may be referred to broadcast + * standard (e.g. Supplementary Audio Language Descriptor of ETSI EN 300 468). + * + * @param spokenSubtitle The spoken subtitle attribute of the audio. + * @throws IllegalStateException if not called on an audio track + */ + @NonNull + public Builder setSpokenSubtitle(boolean spokenSubtitle) { + if (mType != TYPE_AUDIO) { + throw new IllegalStateException("Not an audio track"); + } + mSpokenSubtitle = spokenSubtitle; + return this; + } + + /** * Sets the width of the video, in the unit of pixels. Valid only for {@link #TYPE_VIDEO} * tracks. * @@ -575,9 +665,9 @@ public final class TvTrackInfo implements Parcelable { */ public TvTrackInfo build() { return new TvTrackInfo(mType, mId, mLanguage, mDescription, mEncrypted, - mAudioChannelCount, mAudioSampleRate, mAudioDescription, mVideoWidth, - mVideoHeight, mVideoFrameRate, mVideoPixelAspectRatio, - mVideoActiveFormatDescription, mExtra); + mAudioChannelCount, mAudioSampleRate, mAudioDescription, mHardOfHearing, + mSpokenSubtitle, mVideoWidth, mVideoHeight, mVideoFrameRate, + mVideoPixelAspectRatio, mVideoActiveFormatDescription, mExtra); } } } diff --git a/media/java/android/mtp/MtpPropertyList.java b/media/java/android/mtp/MtpPropertyList.java index 557f099c25c1..53d838d84518 100644 --- a/media/java/android/mtp/MtpPropertyList.java +++ b/media/java/android/mtp/MtpPropertyList.java @@ -16,7 +16,8 @@ package android.mtp; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; + import java.util.ArrayList; import java.util.List; diff --git a/media/java/android/mtp/MtpStorage.java b/media/java/android/mtp/MtpStorage.java index 65d0fef74b25..d385816c6f86 100644 --- a/media/java/android/mtp/MtpStorage.java +++ b/media/java/android/mtp/MtpStorage.java @@ -16,7 +16,7 @@ package android.mtp; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.os.storage.StorageVolume; import android.provider.MediaStore; diff --git a/media/java/android/service/media/MediaBrowserService.java b/media/java/android/service/media/MediaBrowserService.java index 86a1076af122..06adf30a8303 100644 --- a/media/java/android/service/media/MediaBrowserService.java +++ b/media/java/android/service/media/MediaBrowserService.java @@ -21,8 +21,8 @@ import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.SdkConstant; import android.annotation.SdkConstant.SdkConstantType; -import android.annotation.UnsupportedAppUsage; import android.app.Service; +import android.compat.annotation.UnsupportedAppUsage; import android.content.Intent; import android.content.pm.PackageManager; import android.content.pm.ParceledListSlice; diff --git a/media/jni/audioeffect/Android.bp b/media/jni/audioeffect/Android.bp index 41ab6703a579..5ba5c0159275 100644 --- a/media/jni/audioeffect/Android.bp +++ b/media/jni/audioeffect/Android.bp @@ -17,6 +17,7 @@ cc_library_shared { "libnativehelper", "libaudioclient", "libaudioutils", + "libaudiofoundation", ], version_script: "exports.lds", diff --git a/media/jni/audioeffect/android_media_AudioEffect.cpp b/media/jni/audioeffect/android_media_AudioEffect.cpp index 747d4c01867e..007dd10aba1f 100644 --- a/media/jni/audioeffect/android_media_AudioEffect.cpp +++ b/media/jni/audioeffect/android_media_AudioEffect.cpp @@ -268,8 +268,9 @@ android_media_AudioEffect_native_init(JNIEnv *env) static jint android_media_AudioEffect_native_setup(JNIEnv *env, jobject thiz, jobject weak_this, - jstring type, jstring uuid, jint priority, jint sessionId, jintArray jId, - jobjectArray javadesc, jstring opPackageName) + jstring type, jstring uuid, jint priority, jint sessionId, + jint deviceType, jstring deviceAddress, + jintArray jId, jobjectArray javadesc, jstring opPackageName) { ALOGV("android_media_AudioEffect_native_setup"); AudioEffectJniStorage* lpJniStorage = NULL; @@ -280,6 +281,7 @@ android_media_AudioEffect_native_setup(JNIEnv *env, jobject thiz, jobject weak_t const char *uuidStr = NULL; effect_descriptor_t desc; jobject jdesc; + AudioDeviceTypeAddr device; ScopedUtfChars opPackageNameStr(env, opPackageName); @@ -328,6 +330,12 @@ android_media_AudioEffect_native_setup(JNIEnv *env, jobject thiz, jobject weak_t goto setup_failure; } + if (deviceType != AUDIO_DEVICE_NONE) { + device.mType = deviceType; + ScopedUtfChars address(env, deviceAddress); + device.mAddress = address.c_str(); + } + // create the native AudioEffect object lpAudioEffect = new AudioEffect(typeStr, String16(opPackageNameStr.c_str()), @@ -336,7 +344,8 @@ android_media_AudioEffect_native_setup(JNIEnv *env, jobject thiz, jobject weak_t effectCallback, &lpJniStorage->mCallbackData, (audio_session_t) sessionId, - AUDIO_IO_HANDLE_NONE); + AUDIO_IO_HANDLE_NONE, + device); if (lpAudioEffect == 0) { ALOGE("Error creating AudioEffect"); goto setup_failure; @@ -757,7 +766,7 @@ android_media_AudioEffect_native_queryPreProcessings(JNIEnv *env, jclass clazz _ // Dalvik VM type signatures static const JNINativeMethod gMethods[] = { {"native_init", "()V", (void *)android_media_AudioEffect_native_init}, - {"native_setup", "(Ljava/lang/Object;Ljava/lang/String;Ljava/lang/String;II[I[Ljava/lang/Object;Ljava/lang/String;)I", + {"native_setup", "(Ljava/lang/Object;Ljava/lang/String;Ljava/lang/String;IIILjava/lang/String;[I[Ljava/lang/Object;Ljava/lang/String;)I", (void *)android_media_AudioEffect_native_setup}, {"native_finalize", "()V", (void *)android_media_AudioEffect_native_finalize}, {"native_release", "()V", (void *)android_media_AudioEffect_native_release}, diff --git a/media/mca/effect/java/android/media/effect/SingleFilterEffect.java b/media/mca/effect/java/android/media/effect/SingleFilterEffect.java index dfbf5d20e074..121443f56285 100644 --- a/media/mca/effect/java/android/media/effect/SingleFilterEffect.java +++ b/media/mca/effect/java/android/media/effect/SingleFilterEffect.java @@ -17,12 +17,11 @@ package android.media.effect; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.filterfw.core.Filter; import android.filterfw.core.FilterFactory; import android.filterfw.core.FilterFunction; import android.filterfw.core.Frame; -import android.media.effect.EffectContext; /** * Effect subclass for effects based on a single Filter. Subclasses need only invoke the diff --git a/media/mca/filterfw/java/android/filterfw/GraphEnvironment.java b/media/mca/filterfw/java/android/filterfw/GraphEnvironment.java index 52615bf09faa..3a7f1ed4f7ec 100644 --- a/media/mca/filterfw/java/android/filterfw/GraphEnvironment.java +++ b/media/mca/filterfw/java/android/filterfw/GraphEnvironment.java @@ -17,11 +17,11 @@ package android.filterfw; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; import android.filterfw.core.AsyncRunner; -import android.filterfw.core.FilterGraph; import android.filterfw.core.FilterContext; +import android.filterfw.core.FilterGraph; import android.filterfw.core.FrameManager; import android.filterfw.core.GraphRunner; import android.filterfw.core.RoundRobinScheduler; diff --git a/media/mca/filterfw/java/android/filterfw/core/Filter.java b/media/mca/filterfw/java/android/filterfw/core/Filter.java index 4f56b923f6ed..a608ef5be3f4 100644 --- a/media/mca/filterfw/java/android/filterfw/core/Filter.java +++ b/media/mca/filterfw/java/android/filterfw/core/Filter.java @@ -17,19 +17,15 @@ package android.filterfw.core; -import android.annotation.UnsupportedAppUsage; -import android.filterfw.core.FilterContext; -import android.filterfw.core.FilterPort; -import android.filterfw.core.KeyValueMap; -import android.filterfw.io.TextGraphReader; -import android.filterfw.io.GraphIOException; +import android.compat.annotation.UnsupportedAppUsage; import android.filterfw.format.ObjectFormat; +import android.filterfw.io.GraphIOException; +import android.filterfw.io.TextGraphReader; import android.util.Log; import java.io.Serializable; import java.lang.annotation.Annotation; import java.lang.reflect.Field; -import java.lang.Thread; import java.util.Collection; import java.util.HashMap; import java.util.HashSet; diff --git a/media/mca/filterfw/java/android/filterfw/core/FilterContext.java b/media/mca/filterfw/java/android/filterfw/core/FilterContext.java index a19220ef85f8..6b0a2193dceb 100644 --- a/media/mca/filterfw/java/android/filterfw/core/FilterContext.java +++ b/media/mca/filterfw/java/android/filterfw/core/FilterContext.java @@ -17,11 +17,7 @@ package android.filterfw.core; -import android.annotation.UnsupportedAppUsage; -import android.filterfw.core.Filter; -import android.filterfw.core.Frame; -import android.filterfw.core.FrameManager; -import android.filterfw.core.GLEnvironment; +import android.compat.annotation.UnsupportedAppUsage; import java.util.HashMap; import java.util.HashSet; diff --git a/media/mca/filterfw/java/android/filterfw/core/FilterGraph.java b/media/mca/filterfw/java/android/filterfw/core/FilterGraph.java index e6ca11ffca3c..35a298fd6dfb 100644 --- a/media/mca/filterfw/java/android/filterfw/core/FilterGraph.java +++ b/media/mca/filterfw/java/android/filterfw/core/FilterGraph.java @@ -17,6 +17,11 @@ package android.filterfw.core; +import android.compat.annotation.UnsupportedAppUsage; +import android.filterpacks.base.FrameBranch; +import android.filterpacks.base.NullFilter; +import android.util.Log; + import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; @@ -25,14 +30,6 @@ import java.util.Map.Entry; import java.util.Set; import java.util.Stack; -import android.filterfw.core.FilterContext; -import android.filterfw.core.KeyValueMap; -import android.filterpacks.base.FrameBranch; -import android.filterpacks.base.NullFilter; - -import android.annotation.UnsupportedAppUsage; -import android.util.Log; - /** * @hide */ diff --git a/media/mca/filterfw/java/android/filterfw/core/Frame.java b/media/mca/filterfw/java/android/filterfw/core/Frame.java index e880783247a3..c4d935ae4873 100644 --- a/media/mca/filterfw/java/android/filterfw/core/Frame.java +++ b/media/mca/filterfw/java/android/filterfw/core/Frame.java @@ -17,9 +17,7 @@ package android.filterfw.core; -import android.annotation.UnsupportedAppUsage; -import android.filterfw.core.FrameFormat; -import android.filterfw.core.FrameManager; +import android.compat.annotation.UnsupportedAppUsage; import android.graphics.Bitmap; import java.nio.ByteBuffer; diff --git a/media/mca/filterfw/java/android/filterfw/core/FrameFormat.java b/media/mca/filterfw/java/android/filterfw/core/FrameFormat.java index eb0ff0a32c3f..a87e9b9ffbcf 100644 --- a/media/mca/filterfw/java/android/filterfw/core/FrameFormat.java +++ b/media/mca/filterfw/java/android/filterfw/core/FrameFormat.java @@ -17,9 +17,7 @@ package android.filterfw.core; -import android.annotation.UnsupportedAppUsage; -import android.filterfw.core.KeyValueMap; -import android.filterfw.core.MutableFrameFormat; +import android.compat.annotation.UnsupportedAppUsage; import java.util.Arrays; import java.util.Map.Entry; diff --git a/media/mca/filterfw/java/android/filterfw/core/FrameManager.java b/media/mca/filterfw/java/android/filterfw/core/FrameManager.java index 85c8fcd9787d..e49aaf1d6fad 100644 --- a/media/mca/filterfw/java/android/filterfw/core/FrameManager.java +++ b/media/mca/filterfw/java/android/filterfw/core/FrameManager.java @@ -17,10 +17,7 @@ package android.filterfw.core; -import android.annotation.UnsupportedAppUsage; -import android.filterfw.core.Frame; -import android.filterfw.core.FrameFormat; -import android.filterfw.core.MutableFrameFormat; +import android.compat.annotation.UnsupportedAppUsage; /** * @hide diff --git a/media/mca/filterfw/java/android/filterfw/core/GLEnvironment.java b/media/mca/filterfw/java/android/filterfw/core/GLEnvironment.java index e25d6a7d70ab..7e4e8a64a81f 100644 --- a/media/mca/filterfw/java/android/filterfw/core/GLEnvironment.java +++ b/media/mca/filterfw/java/android/filterfw/core/GLEnvironment.java @@ -17,13 +17,12 @@ package android.filterfw.core; -import android.annotation.UnsupportedAppUsage; -import android.filterfw.core.NativeAllocatorTag; +import android.compat.annotation.UnsupportedAppUsage; import android.graphics.SurfaceTexture; +import android.media.MediaRecorder; import android.os.Looper; import android.util.Log; import android.view.Surface; -import android.media.MediaRecorder; /** * @hide diff --git a/media/mca/filterfw/java/android/filterfw/core/GLFrame.java b/media/mca/filterfw/java/android/filterfw/core/GLFrame.java index 9e3025fafb6e..1ccd7feaa7c3 100644 --- a/media/mca/filterfw/java/android/filterfw/core/GLFrame.java +++ b/media/mca/filterfw/java/android/filterfw/core/GLFrame.java @@ -17,15 +17,10 @@ package android.filterfw.core; -import android.annotation.UnsupportedAppUsage; -import android.filterfw.core.Frame; -import android.filterfw.core.FrameFormat; -import android.filterfw.core.FrameManager; -import android.filterfw.core.NativeFrame; -import android.filterfw.core.StopWatchMap; +import android.compat.annotation.UnsupportedAppUsage; import android.graphics.Bitmap; -import android.opengl.GLES20; import android.graphics.Rect; +import android.opengl.GLES20; import java.nio.ByteBuffer; diff --git a/media/mca/filterfw/java/android/filterfw/core/GraphRunner.java b/media/mca/filterfw/java/android/filterfw/core/GraphRunner.java index 250cfaaba9d4..b57e8bb7262e 100644 --- a/media/mca/filterfw/java/android/filterfw/core/GraphRunner.java +++ b/media/mca/filterfw/java/android/filterfw/core/GraphRunner.java @@ -17,7 +17,7 @@ package android.filterfw.core; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; /** * @hide diff --git a/media/mca/filterfw/java/android/filterfw/core/MutableFrameFormat.java b/media/mca/filterfw/java/android/filterfw/core/MutableFrameFormat.java index ae2ad99899f0..da00b1ffb180 100644 --- a/media/mca/filterfw/java/android/filterfw/core/MutableFrameFormat.java +++ b/media/mca/filterfw/java/android/filterfw/core/MutableFrameFormat.java @@ -17,9 +17,7 @@ package android.filterfw.core; -import android.annotation.UnsupportedAppUsage; -import android.filterfw.core.FrameFormat; -import android.filterfw.core.KeyValueMap; +import android.compat.annotation.UnsupportedAppUsage; import java.util.Arrays; diff --git a/media/mca/filterfw/java/android/filterfw/core/Program.java b/media/mca/filterfw/java/android/filterfw/core/Program.java index 376c08554eb2..145388e4437e 100644 --- a/media/mca/filterfw/java/android/filterfw/core/Program.java +++ b/media/mca/filterfw/java/android/filterfw/core/Program.java @@ -17,8 +17,7 @@ package android.filterfw.core; -import android.annotation.UnsupportedAppUsage; -import android.filterfw.core.Frame; +import android.compat.annotation.UnsupportedAppUsage; /** * @hide diff --git a/media/mca/filterfw/java/android/filterfw/core/ShaderProgram.java b/media/mca/filterfw/java/android/filterfw/core/ShaderProgram.java index f41636e7cf76..e043be0e27bd 100644 --- a/media/mca/filterfw/java/android/filterfw/core/ShaderProgram.java +++ b/media/mca/filterfw/java/android/filterfw/core/ShaderProgram.java @@ -17,12 +17,7 @@ package android.filterfw.core; -import android.annotation.UnsupportedAppUsage; -import android.filterfw.core.Frame; -import android.filterfw.core.NativeAllocatorTag; -import android.filterfw.core.Program; -import android.filterfw.core.StopWatchMap; -import android.filterfw.core.VertexFrame; +import android.compat.annotation.UnsupportedAppUsage; import android.filterfw.geometry.Quad; import android.opengl.GLES20; diff --git a/media/mca/filterfw/java/android/filterfw/format/ImageFormat.java b/media/mca/filterfw/java/android/filterfw/format/ImageFormat.java index ac087305287f..0e05092d0cdd 100644 --- a/media/mca/filterfw/java/android/filterfw/format/ImageFormat.java +++ b/media/mca/filterfw/java/android/filterfw/format/ImageFormat.java @@ -17,7 +17,7 @@ package android.filterfw.format; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.filterfw.core.FrameFormat; import android.filterfw.core.MutableFrameFormat; import android.graphics.Bitmap; diff --git a/media/mca/filterfw/java/android/filterfw/geometry/Point.java b/media/mca/filterfw/java/android/filterfw/geometry/Point.java index d7acf12dd1de..96d2d7b08b74 100644 --- a/media/mca/filterfw/java/android/filterfw/geometry/Point.java +++ b/media/mca/filterfw/java/android/filterfw/geometry/Point.java @@ -17,8 +17,7 @@ package android.filterfw.geometry; -import android.annotation.UnsupportedAppUsage; -import java.lang.Math; +import android.compat.annotation.UnsupportedAppUsage; /** * @hide diff --git a/media/mca/filterfw/java/android/filterfw/geometry/Quad.java b/media/mca/filterfw/java/android/filterfw/geometry/Quad.java index 610e5b80399d..2b308a91576f 100644 --- a/media/mca/filterfw/java/android/filterfw/geometry/Quad.java +++ b/media/mca/filterfw/java/android/filterfw/geometry/Quad.java @@ -17,10 +17,8 @@ package android.filterfw.geometry; -import android.annotation.UnsupportedAppUsage; -import android.filterfw.geometry.Point; +import android.compat.annotation.UnsupportedAppUsage; -import java.lang.Float; import java.util.Arrays; import java.util.Collections; import java.util.List; diff --git a/mms/OWNERS b/mms/OWNERS index ba00d5d75010..befc320b949c 100644 --- a/mms/OWNERS +++ b/mms/OWNERS @@ -12,3 +12,5 @@ satk@google.com shuoq@google.com refuhoo@google.com nazaninb@google.com +sarahchin@google.com +dbright@google.com
\ No newline at end of file diff --git a/opengl/java/android/opengl/EGL14.java b/opengl/java/android/opengl/EGL14.java index 728e6e18cc31..90b46fd5901a 100644 --- a/opengl/java/android/opengl/EGL14.java +++ b/opengl/java/android/opengl/EGL14.java @@ -18,11 +18,11 @@ package android.opengl; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.graphics.SurfaceTexture; import android.view.Surface; -import android.view.SurfaceView; import android.view.SurfaceHolder; +import android.view.SurfaceView; /** * EGL 1.4 diff --git a/opengl/java/android/opengl/GLES20.java b/opengl/java/android/opengl/GLES20.java index d66e7ac84a3b..e853e4447daa 100644 --- a/opengl/java/android/opengl/GLES20.java +++ b/opengl/java/android/opengl/GLES20.java @@ -19,7 +19,7 @@ package android.opengl; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; /** OpenGL ES 2.0 */ diff --git a/opengl/java/android/opengl/GLSurfaceView.java b/opengl/java/android/opengl/GLSurfaceView.java index 8a3e6a0b0fd5..75131b0f6b9c 100644 --- a/opengl/java/android/opengl/GLSurfaceView.java +++ b/opengl/java/android/opengl/GLSurfaceView.java @@ -16,7 +16,7 @@ package android.opengl; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; import android.os.Trace; import android.util.AttributeSet; diff --git a/opengl/java/com/google/android/gles_jni/EGLImpl.java b/opengl/java/com/google/android/gles_jni/EGLImpl.java index f94f69f0fd3f..b4ea0a6132a5 100644 --- a/opengl/java/com/google/android/gles_jni/EGLImpl.java +++ b/opengl/java/com/google/android/gles_jni/EGLImpl.java @@ -16,13 +16,12 @@ package com.google.android.gles_jni; +import android.compat.annotation.UnsupportedAppUsage; import android.graphics.SurfaceTexture; import android.view.Surface; import android.view.SurfaceHolder; import android.view.SurfaceView; -import dalvik.annotation.compat.UnsupportedAppUsage; - import javax.microedition.khronos.egl.EGL10; import javax.microedition.khronos.egl.EGLConfig; import javax.microedition.khronos.egl.EGLContext; diff --git a/opengl/java/com/google/android/gles_jni/GLImpl.java b/opengl/java/com/google/android/gles_jni/GLImpl.java index 2a8d07f03148..3c808a6ada48 100644 --- a/opengl/java/com/google/android/gles_jni/GLImpl.java +++ b/opengl/java/com/google/android/gles_jni/GLImpl.java @@ -20,14 +20,13 @@ package com.google.android.gles_jni; import android.app.AppGlobals; +import android.compat.annotation.UnsupportedAppUsage; import android.content.pm.ApplicationInfo; import android.content.pm.IPackageManager; import android.os.Build; import android.os.UserHandle; import android.util.Log; -import dalvik.annotation.compat.UnsupportedAppUsage; - import java.nio.Buffer; import javax.microedition.khronos.opengles.GL10; diff --git a/opengl/java/javax/microedition/khronos/egl/EGL10.java b/opengl/java/javax/microedition/khronos/egl/EGL10.java index 8a2517062d4d..ea571c7311a1 100644 --- a/opengl/java/javax/microedition/khronos/egl/EGL10.java +++ b/opengl/java/javax/microedition/khronos/egl/EGL10.java @@ -16,8 +16,7 @@ package javax.microedition.khronos.egl; -import android.annotation.UnsupportedAppUsage; -import java.lang.String; +import android.compat.annotation.UnsupportedAppUsage; public interface EGL10 extends EGL { int EGL_SUCCESS = 0x3000; diff --git a/packages/CarSystemUI/Android.bp b/packages/CarSystemUI/Android.bp index 672879ae6e9d..68da999ae786 100644 --- a/packages/CarSystemUI/Android.bp +++ b/packages/CarSystemUI/Android.bp @@ -82,7 +82,7 @@ android_app { ], platform_apis: true, - product_specific: true, + system_ext_specific: true, certificate: "platform", privileged: true, diff --git a/packages/CarSystemUI/CleanSpec.mk b/packages/CarSystemUI/CleanSpec.mk new file mode 100644 index 000000000000..ceac67c55f09 --- /dev/null +++ b/packages/CarSystemUI/CleanSpec.mk @@ -0,0 +1,50 @@ +# 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. +# + +# If you don't need to do a full clean build but would like to touch +# a file or delete some intermediate files, add a clean step to the end +# of the list. These steps will only be run once, if they haven't been +# run before. +# +# E.g.: +# $(call add-clean-step, touch -c external/sqlite/sqlite3.h) +# $(call add-clean-step, rm -rf $(PRODUCT_OUT)/obj/STATIC_LIBRARIES/libz_intermediates) +# +# Always use "touch -c" and "rm -f" or "rm -rf" to gracefully deal with +# files that are missing or have been moved. +# +# Use $(PRODUCT_OUT) to get to the "out/target/product/blah/" directory. +# Use $(OUT_DIR) to refer to the "out" directory. +# +# If you need to re-do something that's already mentioned, just copy +# the command and add it to the bottom of the list. E.g., if a change +# that you made last week required touching a file and a change you +# made today requires touching the same file, just copy the old +# touch step and add it to the end of the list. +# +# ***************************************************************** +# NEWER CLEAN STEPS MUST BE AT THE END OF THE LIST ABOVE THE BANNER +# ***************************************************************** + +# For example: +#$(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/APPS/AndroidTests_intermediates) +#$(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/JAVA_LIBRARIES/core_intermediates) +#$(call add-clean-step, find $(OUT_DIR) -type f -name "IGTalkSession*" -print0 | xargs -0 rm -f) +#$(call add-clean-step, rm -rf $(PRODUCT_OUT)/data/*) +$(call add-clean-step, rm -rf $(PRODUCT_OUT)/system/product/priv-app/CarSystemUI) +$(call add-clean-step, rm -rf $(PRODUCT_OUT)/product/priv-app/CarSystemUI) +# ****************************************************************** +# NEWER CLEAN STEPS MUST BE AT THE END OF THE LIST ABOVE THIS BANNER +# ****************************************************************** diff --git a/packages/DynamicSystemInstallationService/src/com/android/dynsystem/DynamicSystemInstallationService.java b/packages/DynamicSystemInstallationService/src/com/android/dynsystem/DynamicSystemInstallationService.java index c2ce84023869..9ccb837cf613 100644 --- a/packages/DynamicSystemInstallationService/src/com/android/dynsystem/DynamicSystemInstallationService.java +++ b/packages/DynamicSystemInstallationService/src/com/android/dynsystem/DynamicSystemInstallationService.java @@ -56,6 +56,7 @@ import android.os.PowerManager; import android.os.RemoteException; import android.os.image.DynamicSystemClient; import android.os.image.DynamicSystemManager; +import android.text.TextUtils; import android.util.Log; import android.widget.Toast; @@ -74,6 +75,8 @@ public class DynamicSystemInstallationService extends Service // TODO (b/131866826): This is currently for test only. Will move this to System API. static final String KEY_ENABLE_WHEN_COMPLETED = "KEY_ENABLE_WHEN_COMPLETED"; + static final String KEY_DSU_SLOT = "KEY_DSU_SLOT"; + static final String DEFAULT_DSU_SLOT = "dsu"; /* * Intent actions @@ -244,10 +247,15 @@ public class DynamicSystemInstallationService extends Service long systemSize = intent.getLongExtra(DynamicSystemClient.KEY_SYSTEM_SIZE, 0); long userdataSize = intent.getLongExtra(DynamicSystemClient.KEY_USERDATA_SIZE, 0); mEnableWhenCompleted = intent.getBooleanExtra(KEY_ENABLE_WHEN_COMPLETED, false); + String dsuSlot = intent.getStringExtra(KEY_DSU_SLOT); + if (TextUtils.isEmpty(dsuSlot)) { + dsuSlot = DEFAULT_DSU_SLOT; + } // TODO: better constructor or builder - mInstallTask = new InstallationAsyncTask( - url, systemSize, userdataSize, this, mDynSystem, this); + mInstallTask = + new InstallationAsyncTask( + url, dsuSlot, systemSize, userdataSize, this, mDynSystem, this); mInstallTask.execute(); @@ -409,7 +417,9 @@ public class DynamicSystemInstallationService extends Service break; case STATUS_READY: - builder.setContentText(getString(R.string.notification_install_completed)); + String msgCompleted = getString(R.string.notification_install_completed); + builder.setContentText(msgCompleted) + .setStyle(new Notification.BigTextStyle().bigText(msgCompleted)); builder.addAction(new Notification.Action.Builder( null, getString(R.string.notification_action_discard), @@ -422,7 +432,9 @@ public class DynamicSystemInstallationService extends Service break; case STATUS_IN_USE: - builder.setContentText(getString(R.string.notification_dynsystem_in_use)); + String msgInUse = getString(R.string.notification_dynsystem_in_use); + builder.setContentText(msgInUse) + .setStyle(new Notification.BigTextStyle().bigText(msgInUse)); builder.addAction(new Notification.Action.Builder( null, getString(R.string.notification_action_uninstall), @@ -452,7 +464,49 @@ public class DynamicSystemInstallationService extends Service } private void postStatus(int status, int cause, Throwable detail) { - Log.d(TAG, "postStatus(): statusCode=" + status + ", causeCode=" + cause); + String statusString; + String causeString; + + switch (status) { + case STATUS_NOT_STARTED: + statusString = "NOT_STARTED"; + break; + case STATUS_IN_PROGRESS: + statusString = "IN_PROGRESS"; + break; + case STATUS_READY: + statusString = "READY"; + break; + case STATUS_IN_USE: + statusString = "IN_USE"; + break; + default: + statusString = "UNKNOWN"; + break; + } + + switch (cause) { + case CAUSE_INSTALL_COMPLETED: + causeString = "INSTALL_COMPLETED"; + break; + case CAUSE_INSTALL_CANCELLED: + causeString = "INSTALL_CANCELLED"; + break; + case CAUSE_ERROR_IO: + causeString = "ERROR_IO"; + break; + case CAUSE_ERROR_INVALID_URL: + causeString = "ERROR_INVALID_URL"; + break; + case CAUSE_ERROR_EXCEPTION: + causeString = "ERROR_EXCEPTION"; + break; + default: + causeString = "CAUSE_NOT_SPECIFIED"; + break; + } + + Log.d(TAG, "status=" + statusString + ", cause=" + causeString); boolean notifyOnNotificationBar = true; diff --git a/packages/DynamicSystemInstallationService/src/com/android/dynsystem/InstallationAsyncTask.java b/packages/DynamicSystemInstallationService/src/com/android/dynsystem/InstallationAsyncTask.java index b206a1fccba4..9aea0e713179 100644 --- a/packages/DynamicSystemInstallationService/src/com/android/dynsystem/InstallationAsyncTask.java +++ b/packages/DynamicSystemInstallationService/src/com/android/dynsystem/InstallationAsyncTask.java @@ -89,10 +89,12 @@ class InstallationAsyncTask extends AsyncTask<String, InstallationAsyncTask.Prog interface ProgressListener { void onProgressUpdate(Progress progress); + void onResult(int resultCode, Throwable detail); } private final String mUrl; + private final String mDsuSlot; private final long mSystemSize; private final long mUserdataSize; private final Context mContext; @@ -106,9 +108,16 @@ class InstallationAsyncTask extends AsyncTask<String, InstallationAsyncTask.Prog private InputStream mStream; private ZipFile mZipFile; - InstallationAsyncTask(String url, long systemSize, long userdataSize, Context context, - DynamicSystemManager dynSystem, ProgressListener listener) { + InstallationAsyncTask( + String url, + String dsuSlot, + long systemSize, + long userdataSize, + Context context, + DynamicSystemManager dynSystem, + ProgressListener listener) { mUrl = url; + mDsuSlot = dsuSlot; mSystemSize = systemSize; mUserdataSize = userdataSize; mContext = context; @@ -126,14 +135,17 @@ class InstallationAsyncTask extends AsyncTask<String, InstallationAsyncTask.Prog verifyAndPrepare(); - mDynSystem.startInstallation(); + mDynSystem.startInstallation(mDsuSlot); installUserdata(); if (isCancelled()) { mDynSystem.remove(); return null; } - + if (mUrl == null) { + mDynSystem.finishInstallation(); + return null; + } installImages(); if (isCancelled()) { mDynSystem.remove(); @@ -194,6 +206,9 @@ class InstallationAsyncTask extends AsyncTask<String, InstallationAsyncTask.Prog } private void verifyAndPrepare() throws Exception { + if (mUrl == null) { + return; + } String extension = mUrl.substring(mUrl.lastIndexOf('.') + 1); if ("gz".equals(extension) || "gzip".equals(extension)) { diff --git a/packages/DynamicSystemInstallationService/src/com/android/dynsystem/VerificationActivity.java b/packages/DynamicSystemInstallationService/src/com/android/dynsystem/VerificationActivity.java index 3b3933b7db10..e42ded74acd0 100644 --- a/packages/DynamicSystemInstallationService/src/com/android/dynsystem/VerificationActivity.java +++ b/packages/DynamicSystemInstallationService/src/com/android/dynsystem/VerificationActivity.java @@ -28,11 +28,9 @@ import android.os.image.DynamicSystemClient; import android.util.FeatureFlagUtils; import android.util.Log; - /** - * This Activity starts KeyguardManager and ask the user to confirm - * before any installation request. If the device is not protected by - * a password, it approves the request by default. + * This Activity starts KeyguardManager and ask the user to confirm before any installation request. + * If the device is not protected by a password, it approves the request by default. */ public class VerificationActivity extends Activity { @@ -88,11 +86,15 @@ public class VerificationActivity extends Activity { Uri url = callingIntent.getData(); Bundle extras = callingIntent.getExtras(); - sVerifiedUrl = url.toString(); + if (url != null) { + sVerifiedUrl = url.toString(); + } // start service Intent intent = new Intent(this, DynamicSystemInstallationService.class); - intent.setData(url); + if (url != null) { + intent.setData(url); + } intent.setAction(DynamicSystemClient.ACTION_START_INSTALL); intent.putExtras(extras); @@ -106,6 +108,7 @@ public class VerificationActivity extends Activity { } static boolean isVerified(String url) { + if (url == null) return true; return sVerifiedUrl != null && sVerifiedUrl.equals(url); } } diff --git a/packages/SettingsLib/res/values/arrays.xml b/packages/SettingsLib/res/values/arrays.xml index 39c55fd1925c..413211d93fdc 100644 --- a/packages/SettingsLib/res/values/arrays.xml +++ b/packages/SettingsLib/res/values/arrays.xml @@ -132,6 +132,20 @@ <item>avrcp16</item> </string-array> + <!-- Titles for Bluetooth MAP Versions --> + <string-array name="bluetooth_map_versions"> + <item>MAP 1.2 (Default)</item> + <item>MAP 1.3</item> + <item>MAP 1.4</item> + </string-array> + + <!-- Values for Bluetooth MAP Versions --> + <string-array name="bluetooth_map_version_values"> + <item>map12</item> + <item>map13</item> + <item>map14</item> + </string-array> + <!-- Titles for Bluetooth Audio Codec selection preference. [CHAR LIMIT=50] --> <string-array name="bluetooth_a2dp_codec_titles"> <item>Use System Selection (Default)</item> diff --git a/packages/SettingsLib/res/values/strings.xml b/packages/SettingsLib/res/values/strings.xml index bdfa21742854..8c2ff2ced17d 100644 --- a/packages/SettingsLib/res/values/strings.xml +++ b/packages/SettingsLib/res/values/strings.xml @@ -597,6 +597,11 @@ <!-- UI debug setting: Select Bluetooth AVRCP Version --> <string name="bluetooth_select_avrcp_version_dialog_title">Select Bluetooth AVRCP Version</string> + <!-- UI debug setting: Select Bluetooth MAP Version [CHAR LIMIT=NONE] --> + <string name="bluetooth_select_map_version_string">Bluetooth MAP Version</string> + <!-- UI debug setting: Select Bluetooth MAP Version [CHAR LIMIT=NONE] --> + <string name="bluetooth_select_map_version_dialog_title">Select Bluetooth MAP Version</string> + <!-- UI debug setting: Trigger Bluetooth Audio Codec Selection --> <string name="bluetooth_select_a2dp_codec_type">Bluetooth Audio Codec</string> <!-- UI debug setting: Trigger Bluetooth Audio Codec Selection --> diff --git a/packages/SettingsLib/src/com/android/settingslib/DeviceInfoUtils.java b/packages/SettingsLib/src/com/android/settingslib/DeviceInfoUtils.java index 69bd0ed0c59c..ff00fb3282b1 100644 --- a/packages/SettingsLib/src/com/android/settingslib/DeviceInfoUtils.java +++ b/packages/SettingsLib/src/com/android/settingslib/DeviceInfoUtils.java @@ -16,8 +16,6 @@ package com.android.settingslib; -import static android.content.Context.TELEPHONY_SERVICE; - import android.content.Context; import android.content.Intent; import android.content.pm.ApplicationInfo; @@ -172,36 +170,38 @@ public class DeviceInfoUtils { } } - public static String getFormattedPhoneNumber(Context context, SubscriptionInfo subscriptionInfo) { + /** + * Format a phone number. + * @param subscriptionInfo {@link SubscriptionInfo} subscription information. + * @return Returns formatted phone number. + */ + public static String getFormattedPhoneNumber(Context context, + SubscriptionInfo subscriptionInfo) { String formattedNumber = null; if (subscriptionInfo != null) { - final TelephonyManager telephonyManager = - (TelephonyManager) context.getSystemService(TELEPHONY_SERVICE); - final String rawNumber = - telephonyManager.getLine1Number(subscriptionInfo.getSubscriptionId()); + final TelephonyManager telephonyManager = context.getSystemService( + TelephonyManager.class); + final String rawNumber = telephonyManager.createForSubscriptionId( + subscriptionInfo.getSubscriptionId()).getLine1Number(); if (!TextUtils.isEmpty(rawNumber)) { formattedNumber = PhoneNumberUtils.formatNumber(rawNumber); } - } return formattedNumber; } public static String getFormattedPhoneNumbers(Context context, - List<SubscriptionInfo> subscriptionInfo) { + List<SubscriptionInfo> subscriptionInfoList) { StringBuilder sb = new StringBuilder(); - if (subscriptionInfo != null) { - final TelephonyManager telephonyManager = - (TelephonyManager) context.getSystemService(TELEPHONY_SERVICE); - final int count = subscriptionInfo.size(); - for (int i = 0; i < count; i++) { - final String rawNumber = telephonyManager.getLine1Number( - subscriptionInfo.get(i).getSubscriptionId()); + if (subscriptionInfoList != null) { + final TelephonyManager telephonyManager = context.getSystemService( + TelephonyManager.class); + final int count = subscriptionInfoList.size(); + for (SubscriptionInfo subscriptionInfo : subscriptionInfoList) { + final String rawNumber = telephonyManager.createForSubscriptionId( + subscriptionInfo.getSubscriptionId()).getLine1Number(); if (!TextUtils.isEmpty(rawNumber)) { - sb.append(PhoneNumberUtils.formatNumber(rawNumber)); - if (i < count - 1) { - sb.append("\n"); - } + sb.append(PhoneNumberUtils.formatNumber(rawNumber)).append("\n"); } } } diff --git a/packages/SettingsLib/src/com/android/settingslib/Utils.java b/packages/SettingsLib/src/com/android/settingslib/Utils.java index ee44d0a606aa..1141daa94e6d 100644 --- a/packages/SettingsLib/src/com/android/settingslib/Utils.java +++ b/packages/SettingsLib/src/com/android/settingslib/Utils.java @@ -421,7 +421,7 @@ public class Utils { // is not available. Note that we ignore the IWLAN service state // because that state indicates the use of VoWIFI and not cell service final int state = serviceState.getState(); - final int dataState = serviceState.getDataRegState(); + final int dataState = serviceState.getDataRegistrationState(); if (state == ServiceState.STATE_OUT_OF_SERVICE || state == ServiceState.STATE_EMERGENCY_ONLY) { diff --git a/packages/SettingsLib/src/com/android/settingslib/net/DataUsageUtils.java b/packages/SettingsLib/src/com/android/settingslib/net/DataUsageUtils.java index 23e2949372aa..d5ff1ee6512a 100644 --- a/packages/SettingsLib/src/com/android/settingslib/net/DataUsageUtils.java +++ b/packages/SettingsLib/src/com/android/settingslib/net/DataUsageUtils.java @@ -38,7 +38,7 @@ public class DataUsageUtils { final SubscriptionManager subscriptionManager = context.getSystemService( SubscriptionManager.class); final NetworkTemplate mobileAll = NetworkTemplate.buildTemplateMobileAll( - telephonyManager.getSubscriberId(subId)); + telephonyManager.createForSubscriptionId(subId).getSubscriberId()); if (!subscriptionManager.isActiveSubId(subId)) { Log.i(TAG, "Subscription is not active: " + subId); diff --git a/packages/SettingsLib/src/com/android/settingslib/wifi/WifiStatusTracker.java b/packages/SettingsLib/src/com/android/settingslib/wifi/WifiStatusTracker.java index b11585a73946..8bd5f57f9b71 100644 --- a/packages/SettingsLib/src/com/android/settingslib/wifi/WifiStatusTracker.java +++ b/packages/SettingsLib/src/com/android/settingslib/wifi/WifiStatusTracker.java @@ -90,7 +90,7 @@ public class WifiStatusTracker extends ConnectivityManager.NetworkCallback { public void setListening(boolean listening) { if (listening) { mNetworkScoreManager.registerNetworkScoreCache(NetworkKey.TYPE_WIFI, - mWifiNetworkScoreCache, NetworkScoreManager.CACHE_FILTER_CURRENT_NETWORK); + mWifiNetworkScoreCache, NetworkScoreManager.SCORE_FILTER_CURRENT_NETWORK); mWifiNetworkScoreCache.registerListener(mCacheListener); mConnectivityManager.registerNetworkCallback( mNetworkRequest, mNetworkCallback, mHandler); diff --git a/packages/SettingsLib/src/com/android/settingslib/wifi/WifiTracker.java b/packages/SettingsLib/src/com/android/settingslib/wifi/WifiTracker.java index 3e359d216234..f7131392c68c 100644 --- a/packages/SettingsLib/src/com/android/settingslib/wifi/WifiTracker.java +++ b/packages/SettingsLib/src/com/android/settingslib/wifi/WifiTracker.java @@ -359,7 +359,7 @@ public class WifiTracker implements LifecycleObserver, OnStart, OnStop, OnDestro mNetworkScoreManager.registerNetworkScoreCache( NetworkKey.TYPE_WIFI, mScoreCache, - NetworkScoreManager.CACHE_FILTER_SCAN_RESULTS); + NetworkScoreManager.SCORE_FILTER_SCAN_RESULTS); } private void requestScoresForNetworkKeys(Collection<NetworkKey> keys) { diff --git a/packages/SettingsLib/tests/integ/src/com/android/settingslib/wifi/OWNER b/packages/SettingsLib/tests/integ/src/com/android/settingslib/wifi/OWNER new file mode 100644 index 000000000000..5c2a7b892f8f --- /dev/null +++ b/packages/SettingsLib/tests/integ/src/com/android/settingslib/wifi/OWNER @@ -0,0 +1,4 @@ +# People who can approve changes for submission +arcwang@google.com +govenliu@google.com +qal@google.com diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/UtilsTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/UtilsTest.java index 51806e0d3c03..4948987cac96 100644 --- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/UtilsTest.java +++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/UtilsTest.java @@ -227,7 +227,7 @@ public class UtilsTest { @Test public void isInService_voiceOutOfServiceDataInService_returnTrue() { when(mServiceState.getState()).thenReturn(ServiceState.STATE_OUT_OF_SERVICE); - when(mServiceState.getDataRegState()).thenReturn(ServiceState.STATE_IN_SERVICE); + when(mServiceState.getDataRegistrationState()).thenReturn(ServiceState.STATE_IN_SERVICE); when(mServiceState.getNetworkRegistrationInfo(NetworkRegistrationInfo.DOMAIN_PS, AccessNetworkConstants.TRANSPORT_TYPE_WLAN)).thenReturn(mNetworkRegistrationInfo); when(mNetworkRegistrationInfo.getRegistrationState()).thenReturn( @@ -243,7 +243,7 @@ public class UtilsTest { AccessNetworkConstants.TRANSPORT_TYPE_WLAN)).thenReturn(mNetworkRegistrationInfo); when(mNetworkRegistrationInfo.getRegistrationState()).thenReturn( NetworkRegistrationInfo.REGISTRATION_STATE_HOME); - when(mServiceState.getDataRegState()).thenReturn(ServiceState.STATE_IN_SERVICE); + when(mServiceState.getDataRegistrationState()).thenReturn(ServiceState.STATE_IN_SERVICE); assertThat(Utils.isInService(mServiceState)).isFalse(); } @@ -251,7 +251,8 @@ public class UtilsTest { @Test public void isInService_voiceOutOfServiceDataOutOfService_returnFalse() { when(mServiceState.getState()).thenReturn(ServiceState.STATE_OUT_OF_SERVICE); - when(mServiceState.getDataRegState()).thenReturn(ServiceState.STATE_OUT_OF_SERVICE); + when(mServiceState.getDataRegistrationState()).thenReturn( + ServiceState.STATE_OUT_OF_SERVICE); assertThat(Utils.isInService(mServiceState)).isFalse(); } @@ -288,7 +289,7 @@ public class UtilsTest { @Test public void getCombinedServiceState_voiceOutOfServiceDataInService_returnInService() { when(mServiceState.getState()).thenReturn(ServiceState.STATE_OUT_OF_SERVICE); - when(mServiceState.getDataRegState()).thenReturn(ServiceState.STATE_IN_SERVICE); + when(mServiceState.getDataRegistrationState()).thenReturn(ServiceState.STATE_IN_SERVICE); when(mServiceState.getNetworkRegistrationInfo(NetworkRegistrationInfo.DOMAIN_PS, AccessNetworkConstants.TRANSPORT_TYPE_WLAN)).thenReturn(mNetworkRegistrationInfo); when(mNetworkRegistrationInfo.getRegistrationState()).thenReturn( @@ -301,7 +302,7 @@ public class UtilsTest { @Test public void getCombinedServiceState_voiceOutOfServiceDataInServiceOnIwLan_returnOutOfService() { when(mServiceState.getState()).thenReturn(ServiceState.STATE_OUT_OF_SERVICE); - when(mServiceState.getDataRegState()).thenReturn(ServiceState.STATE_IN_SERVICE); + when(mServiceState.getDataRegistrationState()).thenReturn(ServiceState.STATE_IN_SERVICE); when(mServiceState.getNetworkRegistrationInfo(NetworkRegistrationInfo.DOMAIN_PS, AccessNetworkConstants.TRANSPORT_TYPE_WLAN)).thenReturn(mNetworkRegistrationInfo); when(mNetworkRegistrationInfo.getRegistrationState()).thenReturn( @@ -314,7 +315,8 @@ public class UtilsTest { @Test public void getCombinedServiceState_voiceOutOfServiceDataOutOfService_returnOutOfService() { when(mServiceState.getState()).thenReturn(ServiceState.STATE_OUT_OF_SERVICE); - when(mServiceState.getDataRegState()).thenReturn(ServiceState.STATE_OUT_OF_SERVICE); + when(mServiceState.getDataRegistrationState()).thenReturn( + ServiceState.STATE_OUT_OF_SERVICE); assertThat(Utils.getCombinedServiceState(mServiceState)).isEqualTo( ServiceState.STATE_OUT_OF_SERVICE); diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/wifi/OWNER b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/wifi/OWNER new file mode 100644 index 000000000000..5c2a7b892f8f --- /dev/null +++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/wifi/OWNER @@ -0,0 +1,4 @@ +# People who can approve changes for submission +arcwang@google.com +govenliu@google.com +qal@google.com diff --git a/packages/Shell/AndroidManifest.xml b/packages/Shell/AndroidManifest.xml index efd31ca6a86e..af2569dcb1f2 100644 --- a/packages/Shell/AndroidManifest.xml +++ b/packages/Shell/AndroidManifest.xml @@ -186,6 +186,9 @@ <uses-permission android:name="android.permission.MANAGE_APPOPS" /> + <!-- Permission required for storage tests - FuseDaemonHostTest --> + <uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE"/> + <!-- Permission needed to run network tests in CTS --> <uses-permission android:name="android.permission.MANAGE_TEST_NETWORKS" /> <!-- Permission needed to test tcp keepalive offload. --> diff --git a/packages/SystemUI/Android.bp b/packages/SystemUI/Android.bp index d674be4c8fc0..dbfaca0b6b80 100644 --- a/packages/SystemUI/Android.bp +++ b/packages/SystemUI/Android.bp @@ -142,7 +142,7 @@ android_app { resource_dirs: [], platform_apis: true, - product_specific: true, + system_ext_specific: true, certificate: "platform", privileged: true, diff --git a/packages/SystemUI/AndroidManifest.xml b/packages/SystemUI/AndroidManifest.xml index 403e894a68e4..262365da3a06 100644 --- a/packages/SystemUI/AndroidManifest.xml +++ b/packages/SystemUI/AndroidManifest.xml @@ -72,7 +72,7 @@ <uses-permission android:name="android.permission.CHANGE_WIFI_STATE" /> <uses-permission android:name="android.permission.OVERRIDE_WIFI_CONFIG" /> <uses-permission android:name="android.permission.MANAGE_NETWORK_POLICY" /> - <uses-permission android:name="android.permission.CONNECTIVITY_INTERNAL" /> + <uses-permission android:name="android.permission.OBSERVE_NETWORK_POLICY" /> <uses-permission android:name="android.permission.NETWORK_SETTINGS" /> <uses-permission android:name="android.permission.TETHER_PRIVILEGED" /> <uses-permission android:name="android.permission.READ_NETWORK_USAGE_HISTORY" /> diff --git a/packages/SystemUI/CleanSpec.mk b/packages/SystemUI/CleanSpec.mk new file mode 100644 index 000000000000..2a2e4e44e834 --- /dev/null +++ b/packages/SystemUI/CleanSpec.mk @@ -0,0 +1,50 @@ +# 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. +# + +# If you don't need to do a full clean build but would like to touch +# a file or delete some intermediate files, add a clean step to the end +# of the list. These steps will only be run once, if they haven't been +# run before. +# +# E.g.: +# $(call add-clean-step, touch -c external/sqlite/sqlite3.h) +# $(call add-clean-step, rm -rf $(PRODUCT_OUT)/obj/STATIC_LIBRARIES/libz_intermediates) +# +# Always use "touch -c" and "rm -f" or "rm -rf" to gracefully deal with +# files that are missing or have been moved. +# +# Use $(PRODUCT_OUT) to get to the "out/target/product/blah/" directory. +# Use $(OUT_DIR) to refer to the "out" directory. +# +# If you need to re-do something that's already mentioned, just copy +# the command and add it to the bottom of the list. E.g., if a change +# that you made last week required touching a file and a change you +# made today requires touching the same file, just copy the old +# touch step and add it to the end of the list. +# +# ***************************************************************** +# NEWER CLEAN STEPS MUST BE AT THE END OF THE LIST ABOVE THE BANNER +# ***************************************************************** + +# For example: +#$(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/APPS/AndroidTests_intermediates) +#$(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/JAVA_LIBRARIES/core_intermediates) +#$(call add-clean-step, find $(OUT_DIR) -type f -name "IGTalkSession*" -print0 | xargs -0 rm -f) +#$(call add-clean-step, rm -rf $(PRODUCT_OUT)/data/*) +$(call add-clean-step, rm -rf $(PRODUCT_OUT)/system/product/priv-app/SystemUI) +$(call add-clean-step, rm -rf $(PRODUCT_OUT)/product/priv-app/SystemUI) +# ****************************************************************** +# NEWER CLEAN STEPS MUST BE AT THE END OF THE LIST ABOVE THIS BANNER +# ****************************************************************** diff --git a/packages/SystemUI/res/layout-land/global_actions_grid_item.xml b/packages/SystemUI/res/layout-land/global_actions_grid_item.xml index bc1233828b4d..0f9deaa3c569 100644 --- a/packages/SystemUI/res/layout-land/global_actions_grid_item.xml +++ b/packages/SystemUI/res/layout-land/global_actions_grid_item.xml @@ -57,15 +57,5 @@ android:textColor="@color/global_actions_text" android:textAppearance="?android:attr/textAppearanceSmall" /> - - <TextView - android:visibility="gone" - android:id="@*android:id/status" - android:layout_width="match_parent" - android:layout_height="wrap_content" - android:gravity="center" - android:textColor="@color/global_actions_text" - android:textAppearance="?android:attr/textAppearanceSmall" - /> </LinearLayout> </LinearLayout> diff --git a/packages/SystemUI/res/layout/global_actions_grid_item.xml b/packages/SystemUI/res/layout/global_actions_grid_item.xml index 4404c87432fe..31c7cbf6ff1b 100644 --- a/packages/SystemUI/res/layout/global_actions_grid_item.xml +++ b/packages/SystemUI/res/layout/global_actions_grid_item.xml @@ -56,15 +56,5 @@ android:textColor="@color/global_actions_text" android:textAppearance="?android:attr/textAppearanceSmall" /> - - <TextView - android:visibility="gone" - android:id="@*android:id/status" - android:layout_width="match_parent" - android:layout_height="wrap_content" - android:gravity="center" - android:textColor="@color/global_actions_text" - android:textAppearance="?android:attr/textAppearanceSmall" - /> </LinearLayout> </LinearLayout> diff --git a/packages/SystemUI/src/com/android/keyguard/CarrierTextController.java b/packages/SystemUI/src/com/android/keyguard/CarrierTextController.java index 9d9cad825444..8631e860e0a6 100644 --- a/packages/SystemUI/src/com/android/keyguard/CarrierTextController.java +++ b/packages/SystemUI/src/com/android/keyguard/CarrierTextController.java @@ -348,7 +348,7 @@ public class CarrierTextController { } if (simState == IccCardConstants.State.READY) { ServiceState ss = mKeyguardUpdateMonitor.mServiceStates.get(subId); - if (ss != null && ss.getDataRegState() == ServiceState.STATE_IN_SERVICE) { + if (ss != null && ss.getDataRegistrationState() == ServiceState.STATE_IN_SERVICE) { // hack for WFC (IWLAN) not turning off immediately once // Wi-Fi is disassociated or disabled if (ss.getRilDataRadioTechnology() != ServiceState.RIL_RADIO_TECHNOLOGY_IWLAN diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardSimPinView.java b/packages/SystemUI/src/com/android/keyguard/KeyguardSimPinView.java index 367a7bd4aed7..0ffe05de1357 100644 --- a/packages/SystemUI/src/com/android/keyguard/KeyguardSimPinView.java +++ b/packages/SystemUI/src/com/android/keyguard/KeyguardSimPinView.java @@ -26,8 +26,6 @@ import android.content.res.Configuration; import android.content.res.Resources; import android.content.res.TypedArray; import android.graphics.Color; -import android.os.RemoteException; -import android.os.ServiceManager; import android.telephony.SubscriptionInfo; import android.telephony.SubscriptionManager; import android.telephony.TelephonyManager; @@ -37,7 +35,6 @@ import android.view.View; import android.view.WindowManager; import android.widget.ImageView; -import com.android.internal.telephony.ITelephony; import com.android.internal.telephony.IccCardConstants; import com.android.internal.telephony.IccCardConstants.State; import com.android.internal.telephony.PhoneConstants; @@ -254,27 +251,29 @@ public class KeyguardSimPinView extends KeyguardPinBasedInputView { @Override public void run() { - try { - if (DEBUG) { - Log.v(TAG, "call supplyPinReportResultForSubscriber(subid=" + mSubId + ")"); - } - final int[] result = ITelephony.Stub.asInterface(ServiceManager - .checkService("phone")).supplyPinReportResultForSubscriber(mSubId, mPin); - if (DEBUG) { - Log.v(TAG, "supplyPinReportResult returned: " + result[0] + " " + result[1]); - } + if (DEBUG) { + Log.v(TAG, "call supplyPinReportResultForSubscriber(subid=" + mSubId + ")"); + } + TelephonyManager telephonyManager = + ((TelephonyManager) mContext.getSystemService(Context.TELEPHONY_SERVICE)) + .createForSubscriptionId(mSubId); + final int[] result = telephonyManager.supplyPinReportResult(mPin); + if (result == null || result.length == 0) { + Log.e(TAG, "Error result for supplyPinReportResult."); post(new Runnable() { @Override public void run() { - onSimCheckResponse(result[0], result[1]); + onSimCheckResponse(PhoneConstants.PIN_GENERAL_FAILURE, -1); } }); - } catch (RemoteException e) { - Log.e(TAG, "RemoteException for supplyPinReportResult:", e); + } else { + if (DEBUG) { + Log.v(TAG, "supplyPinReportResult returned: " + result[0] + " " + result[1]); + } post(new Runnable() { @Override public void run() { - onSimCheckResponse(PhoneConstants.PIN_GENERAL_FAILURE, -1); + onSimCheckResponse(result[0], result[1]); } }); } diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardSimPukView.java b/packages/SystemUI/src/com/android/keyguard/KeyguardSimPukView.java index 81f8c67605fe..abadcfd60a38 100644 --- a/packages/SystemUI/src/com/android/keyguard/KeyguardSimPukView.java +++ b/packages/SystemUI/src/com/android/keyguard/KeyguardSimPukView.java @@ -25,8 +25,6 @@ import android.content.res.ColorStateList; import android.content.res.Resources; import android.content.res.TypedArray; import android.graphics.Color; -import android.os.RemoteException; -import android.os.ServiceManager; import android.telephony.SubscriptionInfo; import android.telephony.SubscriptionManager; import android.telephony.TelephonyManager; @@ -36,7 +34,6 @@ import android.view.View; import android.view.WindowManager; import android.widget.ImageView; -import com.android.internal.telephony.ITelephony; import com.android.internal.telephony.IccCardConstants; import com.android.internal.telephony.IccCardConstants.State; import com.android.internal.telephony.PhoneConstants; @@ -314,25 +311,27 @@ public class KeyguardSimPukView extends KeyguardPinBasedInputView { @Override public void run() { - try { - if (DEBUG) Log.v(TAG, "call supplyPukReportResult()"); - final int[] result = ITelephony.Stub.asInterface(ServiceManager - .checkService("phone")).supplyPukReportResultForSubscriber(mSubId, mPuk, mPin); - if (DEBUG) { - Log.v(TAG, "supplyPukReportResult returned: " + result[0] + " " + result[1]); - } + if (DEBUG) Log.v(TAG, "call supplyPukReportResult()"); + TelephonyManager telephonyManager = + ((TelephonyManager) mContext.getSystemService(Context.TELEPHONY_SERVICE)) + .createForSubscriptionId(mSubId); + final int[] result = telephonyManager.supplyPukReportResult(mPuk, mPin); + if (result == null || result.length == 0) { + Log.e(TAG, "Error result for supplyPukReportResult."); post(new Runnable() { @Override public void run() { - onSimLockChangedResponse(result[0], result[1]); + onSimLockChangedResponse(PhoneConstants.PIN_GENERAL_FAILURE, -1); } }); - } catch (RemoteException e) { - Log.e(TAG, "RemoteException for supplyPukReportResult:", e); + } else { + if (DEBUG) { + Log.v(TAG, "supplyPukReportResult returned: " + result[0] + " " + result[1]); + } post(new Runnable() { @Override public void run() { - onSimLockChangedResponse(PhoneConstants.PIN_GENERAL_FAILURE, -1); + onSimLockChangedResponse(result[0], result[1]); } }); } diff --git a/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsDialog.java b/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsDialog.java index ff02e71147fd..589b24a04f8c 100644 --- a/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsDialog.java +++ b/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsDialog.java @@ -1145,13 +1145,6 @@ public class GlobalActionsDialog implements DialogInterface.OnDismissListener, TextView messageView = (TextView) v.findViewById(R.id.message); messageView.setSelected(true); // necessary for marquee to work - TextView statusView = (TextView) v.findViewById(R.id.status); - final String status = getStatus(); - if (!TextUtils.isEmpty(status)) { - statusView.setText(status); - } else { - statusView.setVisibility(View.GONE); - } if (mIcon != null) { icon.setImageDrawable(mIcon); icon.setScaleType(ScaleType.CENTER_CROP); @@ -1236,32 +1229,26 @@ public class GlobalActionsDialog implements DialogInterface.OnDismissListener, LayoutInflater inflater) { willCreate(); - View v = inflater.inflate(R - .layout.global_actions_item, parent, false); + View v = inflater.inflate(com.android.systemui.R + .layout.global_actions_grid_item, parent, false); ImageView icon = (ImageView) v.findViewById(R.id.icon); TextView messageView = (TextView) v.findViewById(R.id.message); - TextView statusView = (TextView) v.findViewById(R.id.status); final boolean enabled = isEnabled(); + boolean on = ((mState == State.On) || (mState == State.TurningOn)); if (messageView != null) { - messageView.setText(mMessageResId); + messageView.setText(on ? mEnabledStatusMessageResId : mDisabledStatusMessageResId); messageView.setEnabled(enabled); messageView.setSelected(true); // necessary for marquee to work } - boolean on = ((mState == State.On) || (mState == State.TurningOn)); if (icon != null) { icon.setImageDrawable(context.getDrawable( (on ? mEnabledIconResId : mDisabledIconResid))); icon.setEnabled(enabled); } - if (statusView != null) { - statusView.setText(on ? mEnabledStatusMessageResId : mDisabledStatusMessageResId); - statusView.setVisibility(View.VISIBLE); - statusView.setEnabled(enabled); - } v.setEnabled(enabled); return v; diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationGuts.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationGuts.java index 4700baae8fab..18d436ff7659 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationGuts.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationGuts.java @@ -421,7 +421,7 @@ public class NotificationGuts extends FrameLayout { } /** Listener for animations executed in {@link #animateClose(int, int, boolean)}. */ - private static class AnimateCloseListener extends AnimatorListenerAdapter { + private class AnimateCloseListener extends AnimatorListenerAdapter { final View mView; private final GutsContent mGutsContent; @@ -433,8 +433,10 @@ public class NotificationGuts extends FrameLayout { @Override public void onAnimationEnd(Animator animation) { super.onAnimationEnd(animation); - mView.setVisibility(View.GONE); - mGutsContent.onFinishedClosing(); + if (!isExposed()) { + mView.setVisibility(View.GONE); + mGutsContent.onFinishedClosing(); + } } } } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationGutsManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationGutsManager.java index 8f7671a5dd96..719ec3215d42 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationGutsManager.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationGutsManager.java @@ -100,6 +100,7 @@ public class NotificationGutsManager implements Dumpable, NotificationLifetimeEx protected String mKeyToRemoveOnGutsClosed; private StatusBar mStatusBar; + private Runnable mOpenRunnable; @Inject public NotificationGutsManager( @@ -343,6 +344,7 @@ public class NotificationGutsManager implements Dumpable, NotificationLifetimeEx public void closeAndSaveGuts(boolean removeLeavebehinds, boolean force, boolean removeControls, int x, int y, boolean resetMenu) { if (mNotificationGutsExposed != null) { + mNotificationGutsExposed.removeCallbacks(mOpenRunnable); mNotificationGutsExposed.closeControls(removeLeavebehinds, removeControls, x, y, force); } if (resetMenu) { @@ -445,7 +447,7 @@ public class NotificationGutsManager implements Dumpable, NotificationLifetimeEx // ensure that it's laid but not visible until actually laid out guts.setVisibility(View.INVISIBLE); // Post to ensure the the guts are properly laid out. - guts.post(new Runnable() { + mOpenRunnable = new Runnable() { @Override public void run() { if (row.getWindowToken() == null) { @@ -470,7 +472,8 @@ public class NotificationGutsManager implements Dumpable, NotificationLifetimeEx mListContainer.onHeightChanged(row, true /* needsAnimation */); mGutsMenuItem = menuItem; } - }); + }; + guts.post(mOpenRunnable); return true; } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardLiftController.kt b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardLiftController.kt index f4635d1270a8..f7b8a2e29129 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardLiftController.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardLiftController.kt @@ -67,6 +67,9 @@ class KeyguardLiftController constructor( } private fun updateListeningState() { + if (pickupSensor == null) { + return + } val onKeyguard = keyguardUpdateMonitor.isKeyguardVisible && !statusBarStateController.isDozing diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java index 0c47d1468a7f..68ee8bbbb69b 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java @@ -62,6 +62,8 @@ import com.android.systemui.statusbar.policy.KeyguardMonitorImpl; import java.io.PrintWriter; import java.util.ArrayList; +import androidx.annotation.VisibleForTesting; + /** * Manages creating, showing, hiding and resetting the keyguard within the status bar. Calls back * via {@link ViewMediatorCallback} to poke the wake lock and report that the keyguard is done, @@ -161,6 +163,7 @@ public class StatusBarKeyguardViewManager implements RemoteInputController.Callb private boolean mLastLockVisible; private OnDismissAction mAfterKeyguardGoneAction; + private Runnable mKeyguardGoneCancelAction; private final ArrayList<Runnable> mAfterKeyguardGoneRunnables = new ArrayList<>(); // Dismiss action to be launched when we stop dozing or the keyguard is gone. @@ -328,10 +331,20 @@ public class StatusBarKeyguardViewManager implements RemoteInputController.Callb return false; } - private void hideBouncer(boolean destroyView) { + @VisibleForTesting + void hideBouncer(boolean destroyView) { if (mBouncer == null) { return; } + if (mShowing) { + // If we were showing the bouncer and then aborting, we need to also clear out any + // potential actions unless we actually unlocked. + mAfterKeyguardGoneAction = null; + if (mKeyguardGoneCancelAction != null) { + mKeyguardGoneCancelAction.run(); + mKeyguardGoneCancelAction = null; + } + } mBouncer.hide(destroyView); cancelPendingWakeupAction(); } @@ -364,6 +377,7 @@ public class StatusBarKeyguardViewManager implements RemoteInputController.Callb mBouncer.showWithDismissAction(r, cancelAction); } else { mAfterKeyguardGoneAction = r; + mKeyguardGoneCancelAction = cancelAction; mBouncer.show(false /* resetSecuritySelection */); } } @@ -671,6 +685,7 @@ public class StatusBarKeyguardViewManager implements RemoteInputController.Callb mAfterKeyguardGoneAction.onDismiss(); mAfterKeyguardGoneAction = null; } + mKeyguardGoneCancelAction = null; for (int i = 0; i < mAfterKeyguardGoneRunnables.size(); i++) { mAfterKeyguardGoneRunnables.get(i).run(); } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/MobileSignalController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/MobileSignalController.java index 582775eaa888..1c646b2d4ee2 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/MobileSignalController.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/MobileSignalController.java @@ -15,6 +15,9 @@ */ package com.android.systemui.statusbar.policy; +import static android.telephony.AccessNetworkConstants.TRANSPORT_TYPE_WWAN; +import static android.telephony.NetworkRegistrationInfo.DOMAIN_PS; + import android.content.Context; import android.content.Intent; import android.database.ContentObserver; @@ -703,12 +706,16 @@ public class MobileSignalController extends SignalController< @Override public void onServiceStateChanged(ServiceState state) { if (DEBUG) { - Log.d(mTag, "onServiceStateChanged voiceState=" + state.getVoiceRegState() - + " dataState=" + state.getDataRegState()); + Log.d(mTag, "onServiceStateChanged voiceState=" + state.getState() + + " dataState=" + state.getDataRegistrationState()); } mServiceState = state; if (mServiceState != null) { - updateDataNetType(mServiceState.getDataNetworkType()); + NetworkRegistrationInfo regInfo = mServiceState.getNetworkRegistrationInfo( + DOMAIN_PS, TRANSPORT_TYPE_WWAN); + if (regInfo != null) { + updateDataNetType(regInfo.getAccessNetworkTechnology()); + } } updateTelephony(); } diff --git a/packages/SystemUI/tests/AndroidManifest.xml b/packages/SystemUI/tests/AndroidManifest.xml index efb4ff008b23..a897b0098bb7 100644 --- a/packages/SystemUI/tests/AndroidManifest.xml +++ b/packages/SystemUI/tests/AndroidManifest.xml @@ -35,7 +35,6 @@ <uses-permission android:name="android.permission.STATUS_BAR_SERVICE" /> <uses-permission android:name="android.permission.ACCESS_VR_MANAGER" /> <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> - <uses-permission android:name="android.permission.CONNECTIVITY_INTERNAL" /> <uses-permission android:name="android.permission.MANAGE_NETWORK_POLICY" /> <uses-permission android:name="android.permission.REQUEST_NETWORK_SCORES" /> <uses-permission android:name="android.permission.CONTROL_VPN" /> diff --git a/packages/SystemUI/tests/src/com/android/keyguard/CarrierTextControllerTest.java b/packages/SystemUI/tests/src/com/android/keyguard/CarrierTextControllerTest.java index cfa56451d515..4d9ea29e9496 100644 --- a/packages/SystemUI/tests/src/com/android/keyguard/CarrierTextControllerTest.java +++ b/packages/SystemUI/tests/src/com/android/keyguard/CarrierTextControllerTest.java @@ -339,7 +339,7 @@ public class CarrierTextControllerTest extends SysuiTestCase { mKeyguardUpdateMonitor.mServiceStates = new HashMap<>(); ServiceState ss = mock(ServiceState.class); - when(ss.getDataRegState()).thenReturn(ServiceState.STATE_IN_SERVICE); + when(ss.getDataRegistrationState()).thenReturn(ServiceState.STATE_IN_SERVICE); mKeyguardUpdateMonitor.mServiceStates.put(TEST_SUBSCRIPTION_NULL.getSubscriptionId(), ss); ArgumentCaptor<CarrierTextController.CarrierTextCallbackInfo> captor = diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManagerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManagerTest.java index 63f653b0b303..0da0e7647707 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManagerTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManagerTest.java @@ -221,6 +221,31 @@ public class StatusBarKeyguardViewManagerTest extends SysuiTestCase { verify(mStatusBar, never()).animateKeyguardUnoccluding(); } + @Test + public void testHiding_cancelsGoneRunnable() { + OnDismissAction action = mock(OnDismissAction.class); + Runnable cancelAction = mock(Runnable.class); + mStatusBarKeyguardViewManager.dismissWithAction(action, cancelAction, + true /* afterKeyguardGone */); + + mStatusBarKeyguardViewManager.hideBouncer(true); + mStatusBarKeyguardViewManager.hide(0, 30); + verify(action, never()).onDismiss(); + verify(cancelAction).run(); + } + + @Test + public void testHiding_doesntCancelWhenShowing() { + OnDismissAction action = mock(OnDismissAction.class); + Runnable cancelAction = mock(Runnable.class); + mStatusBarKeyguardViewManager.dismissWithAction(action, cancelAction, + true /* afterKeyguardGone */); + + mStatusBarKeyguardViewManager.hide(0, 30); + verify(action).onDismiss(); + verify(cancelAction, never()).run(); + } + private class TestableStatusBarKeyguardViewManager extends StatusBarKeyguardViewManager { public TestableStatusBarKeyguardViewManager(Context context, diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerBaseTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerBaseTest.java index 354aa835179c..59270d86844b 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerBaseTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerBaseTest.java @@ -16,6 +16,9 @@ package com.android.systemui.statusbar.policy; +import static android.telephony.AccessNetworkConstants.TRANSPORT_TYPE_WWAN; +import static android.telephony.NetworkRegistrationInfo.DOMAIN_PS; + import static junit.framework.Assert.assertEquals; import static junit.framework.Assert.assertNotNull; @@ -39,6 +42,7 @@ import android.net.wifi.WifiManager; import android.os.Handler; import android.provider.Settings; import android.provider.Settings.Global; +import android.telephony.NetworkRegistrationInfo; import android.telephony.PhoneStateListener; import android.telephony.ServiceState; import android.telephony.SignalStrength; @@ -298,12 +302,12 @@ public class NetworkControllerBaseTest extends SysuiTestCase { } public void setVoiceRegState(int voiceRegState) { - when(mServiceState.getVoiceRegState()).thenReturn(voiceRegState); + when(mServiceState.getState()).thenReturn(voiceRegState); updateServiceState(); } public void setDataRegState(int dataRegState) { - when(mServiceState.getDataRegState()).thenReturn(dataRegState); + when(mServiceState.getDataRegistrationState()).thenReturn(dataRegState); updateServiceState(); } @@ -347,7 +351,13 @@ public class NetworkControllerBaseTest extends SysuiTestCase { } public void updateDataConnectionState(int dataState, int dataNetType) { - when(mServiceState.getDataNetworkType()).thenReturn(dataNetType); + NetworkRegistrationInfo fakeRegInfo = new NetworkRegistrationInfo.Builder() + .setTransportType(TRANSPORT_TYPE_WWAN) + .setDomain(DOMAIN_PS) + .setAccessNetworkTechnology(dataNetType) + .build(); + when(mServiceState.getNetworkRegistrationInfo(DOMAIN_PS, TRANSPORT_TYPE_WWAN)) + .thenReturn(fakeRegInfo); mPhoneStateListener.onDataConnectionStateChanged(dataState, dataNetType); } diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerDataTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerDataTest.java index 99e5a76b3a11..47e0c3c1600d 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerDataTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerDataTest.java @@ -1,5 +1,8 @@ package com.android.systemui.statusbar.policy; +import static android.telephony.AccessNetworkConstants.TRANSPORT_TYPE_WWAN; +import static android.telephony.NetworkRegistrationInfo.DOMAIN_PS; + import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; import static org.mockito.Matchers.anyInt; @@ -418,7 +421,13 @@ public class NetworkControllerDataTest extends NetworkControllerBaseTest { // State from NR_5G to NONE NR_STATE_RESTRICTED, showing corresponding icon doReturn(NetworkRegistrationInfo.NR_STATE_RESTRICTED).when(mServiceState).getNrState(); - doReturn(TelephonyManager.NETWORK_TYPE_LTE).when(mServiceState).getDataNetworkType(); + NetworkRegistrationInfo fakeRegInfo = new NetworkRegistrationInfo.Builder() + .setTransportType(TRANSPORT_TYPE_WWAN) + .setDomain(DOMAIN_PS) + .setAccessNetworkTechnology(TelephonyManager.NETWORK_TYPE_LTE) + .build(); + doReturn(fakeRegInfo).when(mServiceState) + .getNetworkRegistrationInfo(DOMAIN_PS, TRANSPORT_TYPE_WWAN); mPhoneStateListener.onDataConnectionStateChanged(TelephonyManager.DATA_CONNECTED, TelephonyManager.NETWORK_TYPE_LTE); @@ -480,8 +489,13 @@ public class NetworkControllerDataTest extends NetworkControllerBaseTest { verifyDataIndicators(TelephonyIcons.ICON_LTE); - when(mServiceState.getDataNetworkType()) - .thenReturn(TelephonyManager.NETWORK_TYPE_HSPA); + NetworkRegistrationInfo fakeRegInfo = new NetworkRegistrationInfo.Builder() + .setTransportType(TRANSPORT_TYPE_WWAN) + .setDomain(DOMAIN_PS) + .setAccessNetworkTechnology(TelephonyManager.NETWORK_TYPE_HSPA) + .build(); + when(mServiceState.getNetworkRegistrationInfo(DOMAIN_PS, TRANSPORT_TYPE_WWAN)) + .thenReturn(fakeRegInfo); updateServiceState(); verifyDataIndicators(TelephonyIcons.ICON_H); } diff --git a/packages/Tethering/Android.bp b/packages/Tethering/Android.bp index 596f62fad23e..1315ed08464a 100644 --- a/packages/Tethering/Android.bp +++ b/packages/Tethering/Android.bp @@ -20,7 +20,7 @@ java_defaults { srcs: [ "src/**/*.java", ":framework-tethering-shared-srcs", - ":net-module-utils-srcs", + ":tethering-module-utils-srcs", ":services-tethering-shared-srcs", ], static_libs: [ @@ -32,8 +32,9 @@ java_defaults { ], libs: [ "framework-tethering", + "unsupportedappusage", ], - + plugins: ["java_api_finder"], manifest: "AndroidManifestBase.xml", } @@ -122,4 +123,5 @@ android_app { use_embedded_native_libs: true, // The permission configuration *must* be included to ensure security of the device required: ["NetworkPermissionConfig"], + apex_available: ["com.android.tethering"], } diff --git a/packages/Tethering/AndroidManifest.xml b/packages/Tethering/AndroidManifest.xml index 87a8c3f5c68a..c71d0d7bc543 100644 --- a/packages/Tethering/AndroidManifest.xml +++ b/packages/Tethering/AndroidManifest.xml @@ -32,8 +32,11 @@ <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.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" /> <application diff --git a/packages/Tethering/common/TetheringLib/Android.bp b/packages/Tethering/common/TetheringLib/Android.bp index 5785707cb9c5..264ce440f59f 100644 --- a/packages/Tethering/common/TetheringLib/Android.bp +++ b/packages/Tethering/common/TetheringLib/Android.bp @@ -47,6 +47,16 @@ java_library { libs: [ "android_system_stubs_current", ], + + hostdex: true, // for hiddenapi check + visibility: [ + "//frameworks/base/packages/Tethering:__subpackages__", + //TODO(b/147200698) remove below lines when the platform is built with stubs + "//frameworks/base", + "//frameworks/base/services", + "//frameworks/base/services/core", + ], + apex_available: ["com.android.tethering"], } filegroup { diff --git a/packages/Tethering/common/TetheringLib/src/android/net/TetheringManager.java b/packages/Tethering/common/TetheringLib/src/android/net/TetheringManager.java index a49ab85d2faf..11e57186c666 100644 --- a/packages/Tethering/common/TetheringLib/src/android/net/TetheringManager.java +++ b/packages/Tethering/common/TetheringLib/src/android/net/TetheringManager.java @@ -15,8 +15,6 @@ */ package android.net; -import static android.net.ConnectivityManager.TETHER_ERROR_NO_ERROR; - import android.annotation.NonNull; import android.content.Context; import android.net.ConnectivityManager.OnTetheringEventCallback; @@ -52,6 +50,103 @@ public class TetheringManager { private TetheringConfigurationParcel mTetheringConfiguration; private 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 = "localOnlyArray"; + + /** + * 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"; + + /** + * 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; + + /** + * Extra used for communicating with the TetherService. 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. Contains the {@link ResultReceiver} + * which will receive provisioning results. Can be left empty. + */ + public static final String EXTRA_PROVISION_CALLBACK = "extraProvisionCallback"; + 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; @@ -470,7 +565,7 @@ public class TetheringManager { * 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 ConnectivityManager#getLastTetherError} can be used to get more + * {@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 diff --git a/packages/Tethering/jarjar-rules.txt b/packages/Tethering/jarjar-rules.txt index d93531bac58e..c6efa41e580a 100644 --- a/packages/Tethering/jarjar-rules.txt +++ b/packages/Tethering/jarjar-rules.txt @@ -11,6 +11,7 @@ rule com.android.internal.util.MessageUtils* com.android.networkstack.tethering. rule com.android.internal.util.Preconditions* com.android.networkstack.tethering.util.Preconditions@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.net.LocalLog* com.android.networkstack.tethering.LocalLog@1 diff --git a/packages/Tethering/res/values/config.xml b/packages/Tethering/res/values/config.xml index 37e679dbeb63..6fa1f77bdd38 100644 --- a/packages/Tethering/res/values/config.xml +++ b/packages/Tethering/res/values/config.xml @@ -1,7 +1,152 @@ <?xml version="1.0" encoding="utf-8"?> +<!-- Copyright (C) 2020 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES 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 + 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 + 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.*" --> + <string-array translatable="false" name="config_tether_wifi_p2p_regexs"> + </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 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> + + <!-- 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.server.connectivity.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> </resources> diff --git a/packages/Tethering/res/values/overlayable.xml b/packages/Tethering/res/values/overlayable.xml new file mode 100644 index 000000000000..e089d9d19950 --- /dev/null +++ b/packages/Tethering/res/values/overlayable.xml @@ -0,0 +1,35 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- Copyright (C) 2020 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + 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"> + <item type="array" name="config_tether_usb_regexs"/> + <item type="array" name="config_tether_wifi_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"/> + <item type="bool" name="config_tether_enable_legacy_dhcp_server"/> + <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"/> + </policy> + </overlayable> +</resources> diff --git a/packages/Tethering/res/values/strings.xml b/packages/Tethering/res/values/strings.xml index ca866a946ea2..792bce9fc334 100644 --- a/packages/Tethering/res/values/strings.xml +++ b/packages/Tethering/res/values/strings.xml @@ -1,4 +1,18 @@ <?xml version="1.0" encoding="utf-8"?> +<!-- Copyright (C) 2020 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> <resources> <!-- Shown when the device is tethered --> <!-- Strings for tethered notification title [CHAR LIMIT=200] --> @@ -9,8 +23,11 @@ <!-- 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." --> - <!-- Strings for tether disabling notification title [CHAR LIMIT=200] --> + <!-- Strings for tether disabling notification title [CHAR LIMIT=200] --> <string name="disable_tether_notification_title">Tethering is disabled</string> - <!-- Strings for tether disabling notification message [CHAR LIMIT=200] --> + <!-- Strings for tether disabling notification message [CHAR LIMIT=200] --> <string name="disable_tether_notification_message">Contact your admin for details</string> + + <!-- Strings for tether notification channel name [CHAR LIMIT=200] --> + <string name="notification_channel_tethering_status">Hotspot & tethering status</string> </resources>
\ No newline at end of file diff --git a/packages/Tethering/src/android/net/ip/IpServer.java b/packages/Tethering/src/android/net/ip/IpServer.java index abfb33c7af9e..0491ad7c3413 100644 --- a/packages/Tethering/src/android/net/ip/IpServer.java +++ b/packages/Tethering/src/android/net/ip/IpServer.java @@ -24,25 +24,23 @@ import static android.net.util.NetworkConstants.RFC7421_PREFIX_LENGTH; import static android.net.util.NetworkConstants.asByte; import static android.net.util.TetheringMessageBase.BASE_IPSERVER; -import android.net.ConnectivityManager; import android.net.INetd; import android.net.INetworkStackStatusCallback; -import android.net.INetworkStatsService; -import android.net.InterfaceConfiguration; import android.net.IpPrefix; import android.net.LinkAddress; import android.net.LinkProperties; import android.net.RouteInfo; +import android.net.TetheringManager; import android.net.dhcp.DhcpServerCallbacks; import android.net.dhcp.DhcpServingParamsParcel; import android.net.dhcp.DhcpServingParamsParcelExt; import android.net.dhcp.IDhcpServer; 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.NetdService; import android.net.util.SharedLog; -import android.os.INetworkManagementService; import android.os.Looper; import android.os.Message; import android.os.RemoteException; @@ -119,7 +117,7 @@ public class IpServer extends StateMachine { * * @param who the calling instance of IpServer * @param state one of STATE_* - * @param lastError one of ConnectivityManager.TETHER_ERROR_* + * @param lastError one of TetheringManager.TETHER_ERROR_* */ public void updateInterfaceState(IpServer who, int state, int lastError) { } @@ -144,10 +142,6 @@ public class IpServer extends StateMachine { return InterfaceParams.getByName(ifName); } - public INetd getNetdService() { - return NetdService.getInstance(); - } - /** Create a DhcpServer instance to be used by IpServer. */ public abstract void makeDhcpServer(String ifName, DhcpServingParamsParcel params, DhcpServerCallbacks cb); @@ -180,9 +174,7 @@ public class IpServer extends StateMachine { private final State mUnavailableState; private final SharedLog mLog; - private final INetworkManagementService mNMService; private final INetd mNetd; - private final INetworkStatsService mStatsService; private final Callback mCallback; private final InterfaceController mInterfaceCtrl; @@ -210,16 +202,14 @@ public class IpServer extends StateMachine { private int mDhcpServerStartIndex = 0; private IDhcpServer mDhcpServer; private RaParams mLastRaParams; + private LinkAddress mIpv4Address; public IpServer( String ifaceName, Looper looper, int interfaceType, SharedLog log, - INetworkManagementService nMService, INetworkStatsService statsService, - Callback callback, boolean usingLegacyDhcp, Dependencies deps) { + INetd netd, Callback callback, boolean usingLegacyDhcp, Dependencies deps) { super(ifaceName, looper); mLog = log.forSubComponent(ifaceName); - mNMService = nMService; - mNetd = deps.getNetdService(); - mStatsService = statsService; + mNetd = netd; mCallback = callback; mInterfaceCtrl = new InterfaceController(ifaceName, mNetd, mLog); mIfaceName = ifaceName; @@ -228,7 +218,7 @@ public class IpServer extends StateMachine { mUsingLegacyDhcp = usingLegacyDhcp; mDeps = deps; resetLinkProperties(); - mLastError = ConnectivityManager.TETHER_ERROR_NO_ERROR; + mLastError = TetheringManager.TETHER_ERROR_NO_ERROR; mServingMode = STATE_AVAILABLE; mInitialState = new InitialState(); @@ -249,7 +239,7 @@ public class IpServer extends StateMachine { } /** - * Tethering downstream type. It would be one of ConnectivityManager#TETHERING_*. + * Tethering downstream type. It would be one of TetheringManager#TETHERING_*. */ public int interfaceType() { return mInterfaceType; @@ -347,13 +337,13 @@ public class IpServer extends StateMachine { } }); } catch (RemoteException e) { - e.rethrowFromSystemServer(); + throw new IllegalStateException(e); } }); } private void handleError() { - mLastError = ConnectivityManager.TETHER_ERROR_DHCPSERVER_ERROR; + mLastError = TetheringManager.TETHER_ERROR_DHCPSERVER_ERROR; transitionTo(mInitialState); } } @@ -388,14 +378,15 @@ public class IpServer extends StateMachine { public void callback(int statusCode) { if (statusCode != STATUS_SUCCESS) { mLog.e("Error stopping DHCP server: " + statusCode); - mLastError = ConnectivityManager.TETHER_ERROR_DHCPSERVER_ERROR; + mLastError = TetheringManager.TETHER_ERROR_DHCPSERVER_ERROR; // Not much more we can do here } } }); mDhcpServer = null; } catch (RemoteException e) { - e.rethrowFromSystemServer(); + mLog.e("Error stopping DHCP", e); + // Not much more we can do here } } } @@ -414,85 +405,70 @@ public class IpServer extends StateMachine { // NOTE: All of configureIPv4() will be refactored out of existence // into calls to InterfaceController, shared with startIPv4(). mInterfaceCtrl.clearIPv4Address(); + mIpv4Address = null; } - // TODO: Refactor this in terms of calls to InterfaceController. private boolean configureIPv4(boolean enabled) { if (VDBG) Log.d(TAG, "configureIPv4(" + enabled + ")"); // TODO: Replace this hard-coded information with dynamically selected // config passed down to us by a higher layer IP-coordinating element. - String ipAsString = null; + final Inet4Address srvAddr; int prefixLen = 0; - if (mInterfaceType == ConnectivityManager.TETHERING_USB) { - ipAsString = USB_NEAR_IFACE_ADDR; - prefixLen = USB_PREFIX_LENGTH; - } else if (mInterfaceType == ConnectivityManager.TETHERING_WIFI) { - ipAsString = getRandomWifiIPv4Address(); - prefixLen = WIFI_HOST_IFACE_PREFIX_LENGTH; - } else if (mInterfaceType == ConnectivityManager.TETHERING_WIFI_P2P) { - ipAsString = WIFI_P2P_IFACE_ADDR; - prefixLen = WIFI_P2P_IFACE_PREFIX_LENGTH; - } else { - // BT configures the interface elsewhere: only start DHCP. - final Inet4Address srvAddr = (Inet4Address) parseNumericAddress(BLUETOOTH_IFACE_ADDR); - return configureDhcp(enabled, srvAddr, BLUETOOTH_DHCP_PREFIX_LENGTH); - } - - final LinkAddress linkAddr; try { - final InterfaceConfiguration ifcg = mNMService.getInterfaceConfig(mIfaceName); - if (ifcg == null) { - mLog.e("Received null interface config"); - return false; - } - - InetAddress addr = parseNumericAddress(ipAsString); - linkAddr = new LinkAddress(addr, prefixLen); - ifcg.setLinkAddress(linkAddr); - if (mInterfaceType == ConnectivityManager.TETHERING_WIFI) { - // The WiFi stack has ownership of the interface up/down state. - // It is unclear whether the Bluetooth or USB stacks will manage their own - // state. - ifcg.ignoreInterfaceUpDownStatus(); + if (mInterfaceType == TetheringManager.TETHERING_USB) { + srvAddr = (Inet4Address) parseNumericAddress(USB_NEAR_IFACE_ADDR); + prefixLen = USB_PREFIX_LENGTH; + } else if (mInterfaceType == TetheringManager.TETHERING_WIFI) { + srvAddr = (Inet4Address) parseNumericAddress(getRandomWifiIPv4Address()); + prefixLen = WIFI_HOST_IFACE_PREFIX_LENGTH; + } else if (mInterfaceType == TetheringManager.TETHERING_WIFI_P2P) { + srvAddr = (Inet4Address) parseNumericAddress(WIFI_P2P_IFACE_ADDR); + prefixLen = WIFI_P2P_IFACE_PREFIX_LENGTH; } else { - if (enabled) { - ifcg.setInterfaceUp(); - } else { - ifcg.setInterfaceDown(); - } + // 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. + srvAddr = (Inet4Address) parseNumericAddress(BLUETOOTH_IFACE_ADDR); + mIpv4Address = new LinkAddress(srvAddr, BLUETOOTH_DHCP_PREFIX_LENGTH); + return configureDhcp(enabled, srvAddr, BLUETOOTH_DHCP_PREFIX_LENGTH); } - ifcg.clearFlag("running"); + mIpv4Address = new LinkAddress(srvAddr, prefixLen); + } catch (IllegalArgumentException e) { + mLog.e("Error selecting ipv4 address", e); + if (!enabled) stopDhcp(); + return false; + } - // TODO: this may throw if the interface is already gone. Do proper handling and - // simplify the DHCP server start/stop. - mNMService.setInterfaceConfig(mIfaceName, ifcg); + final Boolean setIfaceUp; + if (mInterfaceType == TetheringManager.TETHERING_WIFI + || mInterfaceType == TetheringManager.TETHERING_WIFI_P2P) { + // The WiFi 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 (!configureDhcp(enabled, (Inet4Address) addr, prefixLen)) { - return false; - } - } catch (Exception e) { - mLog.e("Error configuring interface " + e); - if (!enabled) { - try { - // Calling stopDhcp several times is fine - stopDhcp(); - } catch (Exception dhcpError) { - mLog.e("Error stopping DHCP", dhcpError); - } - } + if (!configureDhcp(enabled, srvAddr, prefixLen)) { return false; } // Directly-connected route. - final IpPrefix ipv4Prefix = new IpPrefix(linkAddr.getAddress(), - linkAddr.getPrefixLength()); + final IpPrefix ipv4Prefix = new IpPrefix(mIpv4Address.getAddress(), + mIpv4Address.getPrefixLength()); final RouteInfo route = new RouteInfo(ipv4Prefix, null, null, RTN_UNICAST); if (enabled) { - mLinkProperties.addLinkAddress(linkAddr); + mLinkProperties.addLinkAddress(mIpv4Address); mLinkProperties.addRoute(route); } else { - mLinkProperties.removeLinkAddress(linkAddr); + mLinkProperties.removeLinkAddress(mIpv4Address); mLinkProperties.removeRoute(route); } return true; @@ -584,14 +560,12 @@ public class IpServer extends StateMachine { if (!deprecatedPrefixes.isEmpty()) { final ArrayList<RouteInfo> toBeRemoved = getLocalRoutesFor(mIfaceName, deprecatedPrefixes); - try { - final int removalFailures = mNMService.removeRoutesFromLocalNetwork(toBeRemoved); - if (removalFailures > 0) { - mLog.e(String.format("Failed to remove %d IPv6 routes from local table.", - removalFailures)); - } - } catch (RemoteException e) { - mLog.e("Failed to remove IPv6 routes from local table: " + e); + // Remove routes from local network. + 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); @@ -608,13 +582,18 @@ public class IpServer extends StateMachine { final ArrayList<RouteInfo> toBeAdded = getLocalRoutesFor(mIfaceName, addedPrefixes); try { - // It's safe to call addInterfaceToLocalNetwork() even if - // the interface is already in the local_network. Note also - // that adding routes that already exist does not cause an - // error (EEXIST is silently ignored). - mNMService.addInterfaceToLocalNetwork(mIfaceName, toBeAdded); - } catch (Exception e) { - mLog.e("Failed to add IPv6 routes to local table: " + e); + // 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 IPv6 routes to local table: " + e); + } + } catch (ServiceSpecificException | RemoteException e) { + mLog.e("Failed to add " + mIfaceName + " to local table: ", e); } for (RouteInfo route : toBeAdded) mLinkProperties.addRoute(route); @@ -728,7 +707,7 @@ public class IpServer extends StateMachine { logMessage(this, message.what); switch (message.what) { case CMD_TETHER_REQUESTED: - mLastError = ConnectivityManager.TETHER_ERROR_NO_ERROR; + mLastError = TetheringManager.TETHER_ERROR_NO_ERROR; switch (message.arg1) { case STATE_LOCAL_ONLY: transitionTo(mLocalHotspotState); @@ -757,15 +736,17 @@ public class IpServer extends StateMachine { @Override public void enter() { if (!startIPv4()) { - mLastError = ConnectivityManager.TETHER_ERROR_IFACE_CFG_ERROR; + mLastError = TetheringManager.TETHER_ERROR_IFACE_CFG_ERROR; return; } try { - mNMService.tetherInterface(mIfaceName); - } catch (Exception e) { + final IpPrefix ipv4Prefix = new IpPrefix(mIpv4Address.getAddress(), + mIpv4Address.getPrefixLength()); + NetdUtils.tetherInterface(mNetd, mIfaceName, ipv4Prefix); + } catch (RemoteException | ServiceSpecificException e) { mLog.e("Error Tethering: " + e); - mLastError = ConnectivityManager.TETHER_ERROR_TETHER_IFACE_ERROR; + mLastError = TetheringManager.TETHER_ERROR_TETHER_IFACE_ERROR; return; } @@ -784,9 +765,9 @@ public class IpServer extends StateMachine { stopIPv6(); try { - mNMService.untetherInterface(mIfaceName); - } catch (Exception e) { - mLastError = ConnectivityManager.TETHER_ERROR_UNTETHER_IFACE_ERROR; + NetdUtils.untetherInterface(mNetd, mIfaceName); + } catch (RemoteException | ServiceSpecificException e) { + mLastError = TetheringManager.TETHER_ERROR_UNTETHER_IFACE_ERROR; mLog.e("Failed to untether interface: " + e); } @@ -816,7 +797,7 @@ public class IpServer extends StateMachine { case CMD_START_TETHERING_ERROR: case CMD_STOP_TETHERING_ERROR: case CMD_SET_DNS_FORWARDERS_ERROR: - mLastError = ConnectivityManager.TETHER_ERROR_MASTER_ERROR; + mLastError = TetheringManager.TETHER_ERROR_MASTER_ERROR; transitionTo(mInitialState); break; default: @@ -835,7 +816,7 @@ public class IpServer extends StateMachine { @Override public void enter() { super.enter(); - if (mLastError != ConnectivityManager.TETHER_ERROR_NO_ERROR) { + if (mLastError != TetheringManager.TETHER_ERROR_NO_ERROR) { transitionTo(mInitialState); } @@ -871,7 +852,7 @@ public class IpServer extends StateMachine { @Override public void enter() { super.enter(); - if (mLastError != ConnectivityManager.TETHER_ERROR_NO_ERROR) { + if (mLastError != TetheringManager.TETHER_ERROR_NO_ERROR) { transitionTo(mInitialState); } @@ -898,20 +879,14 @@ public class IpServer extends StateMachine { // to remove their rules, which generates errors. // Just do the best we can. try { - // About to tear down NAT; gather remaining statistics. - mStatsService.forceUpdate(); - } catch (Exception e) { - if (VDBG) Log.e(TAG, "Exception in forceUpdate: " + e.toString()); - } - try { - mNMService.stopInterfaceForwarding(mIfaceName, upstreamIface); - } catch (Exception e) { - if (VDBG) Log.e(TAG, "Exception in removeInterfaceForward: " + e.toString()); + mNetd.ipfwdRemoveInterfaceForward(mIfaceName, upstreamIface); + } catch (RemoteException | ServiceSpecificException e) { + mLog.e("Exception in ipfwdRemoveInterfaceForward: " + e.toString()); } try { - mNMService.disableNat(mIfaceName, upstreamIface); - } catch (Exception e) { - if (VDBG) Log.e(TAG, "Exception in disableNat: " + e.toString()); + mNetd.tetherRemoveForward(mIfaceName, upstreamIface); + } catch (RemoteException | ServiceSpecificException e) { + mLog.e("Exception in disableNat: " + e.toString()); } } @@ -947,12 +922,12 @@ public class IpServer extends StateMachine { for (String ifname : added) { try { - mNMService.enableNat(mIfaceName, ifname); - mNMService.startInterfaceForwarding(mIfaceName, ifname); - } catch (Exception e) { - mLog.e("Exception enabling NAT: " + e); + mNetd.tetherAddForward(mIfaceName, ifname); + mNetd.ipfwdAddInterfaceForward(mIfaceName, ifname); + } catch (RemoteException | ServiceSpecificException e) { + mLog.e("Exception enabling NAT: " + e.toString()); cleanupUpstream(); - mLastError = ConnectivityManager.TETHER_ERROR_ENABLE_NAT_ERROR; + mLastError = TetheringManager.TETHER_ERROR_ENABLE_NAT_ERROR; transitionTo(mInitialState); return true; } @@ -997,7 +972,7 @@ public class IpServer extends StateMachine { class UnavailableState extends State { @Override public void enter() { - mLastError = ConnectivityManager.TETHER_ERROR_NO_ERROR; + mLastError = TetheringManager.TETHER_ERROR_NO_ERROR; sendInterfaceState(STATE_UNAVAILABLE); } } diff --git a/packages/Tethering/src/android/net/ip/RouterAdvertisementDaemon.java b/packages/Tethering/src/android/net/ip/RouterAdvertisementDaemon.java index bba61d72d8d6..6f017dcb623f 100644 --- a/packages/Tethering/src/android/net/ip/RouterAdvertisementDaemon.java +++ b/packages/Tethering/src/android/net/ip/RouterAdvertisementDaemon.java @@ -668,7 +668,7 @@ public class RouterAdvertisementDaemon { } private final class UnicastResponder extends Thread { - private final InetSocketAddress mSolicitor = new InetSocketAddress(); + 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. diff --git a/packages/Tethering/src/com/android/server/connectivity/tethering/EntitlementManager.java b/packages/Tethering/src/com/android/server/connectivity/tethering/EntitlementManager.java index 7e685fbe97f1..1cabc8d0b5b7 100644 --- a/packages/Tethering/src/com/android/server/connectivity/tethering/EntitlementManager.java +++ b/packages/Tethering/src/com/android/server/connectivity/tethering/EntitlementManager.java @@ -16,18 +16,16 @@ package com.android.server.connectivity.tethering; -import static android.net.ConnectivityManager.EXTRA_ADD_TETHER_TYPE; -import static android.net.ConnectivityManager.EXTRA_PROVISION_CALLBACK; -import static android.net.ConnectivityManager.EXTRA_RUN_PROVISION; -import static android.net.ConnectivityManager.TETHERING_BLUETOOTH; -import static android.net.ConnectivityManager.TETHERING_INVALID; -import static android.net.ConnectivityManager.TETHERING_USB; -import static android.net.ConnectivityManager.TETHERING_WIFI; -import static android.net.ConnectivityManager.TETHER_ERROR_ENTITLEMENT_UNKONWN; -import static android.net.ConnectivityManager.TETHER_ERROR_NO_ERROR; -import static android.net.ConnectivityManager.TETHER_ERROR_PROVISION_FAILED; - -import static com.android.internal.R.string.config_wifi_tether_enable; +import static android.net.TetheringManager.EXTRA_ADD_TETHER_TYPE; +import static android.net.TetheringManager.EXTRA_PROVISION_CALLBACK; +import static android.net.TetheringManager.EXTRA_RUN_PROVISION; +import static android.net.TetheringManager.TETHERING_BLUETOOTH; +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_UNKONWN; +import static android.net.TetheringManager.TETHER_ERROR_NO_ERROR; +import static android.net.TetheringManager.TETHER_ERROR_PROVISION_FAILED; import android.app.AlarmManager; import android.app.PendingIntent; @@ -36,7 +34,6 @@ import android.content.ComponentName; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; -import android.content.res.Resources; import android.net.util.SharedLog; import android.os.Bundle; import android.os.Handler; @@ -54,12 +51,13 @@ import android.util.SparseIntArray; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.util.StateMachine; +import com.android.networkstack.tethering.R; import java.io.PrintWriter; /** * Re-check tethering provisioning for enabled downstream tether types. - * Reference ConnectivityManager.TETHERING_{@code *} for each tether type. + * Reference TetheringManager.TETHERING_{@code *} for each tether type. * * All methods of this class must be accessed from the thread of tethering * state machine. @@ -75,9 +73,7 @@ public class EntitlementManager { "com.android.server.connectivity.tethering.PROVISIONING_RECHECK_ALARM"; private static final String EXTRA_SUBID = "subId"; - // {@link ComponentName} of the Service used to run tether provisioning. - private static final ComponentName TETHER_SERVICE = ComponentName.unflattenFromString( - Resources.getSystem().getString(config_wifi_tether_enable)); + private final ComponentName mSilentProvisioningService; private static final int MS_PER_HOUR = 60 * 60 * 1000; private static final int EVENT_START_PROVISIONING = 0; private static final int EVENT_STOP_PROVISIONING = 1; @@ -86,9 +82,9 @@ public class EntitlementManager { private static final int EVENT_GET_ENTITLEMENT_VALUE = 4; // The ArraySet contains enabled downstream types, ex: - // {@link ConnectivityManager.TETHERING_WIFI} - // {@link ConnectivityManager.TETHERING_USB} - // {@link ConnectivityManager.TETHERING_BLUETOOTH} + // {@link TetheringManager.TETHERING_WIFI} + // {@link TetheringManager.TETHERING_USB} + // {@link TetheringManager.TETHERING_BLUETOOTH} private final ArraySet<Integer> mCurrentTethers; private final Context mContext; private final int mPermissionChangeMessageCode; @@ -96,8 +92,8 @@ public class EntitlementManager { private final SparseIntArray mEntitlementCacheValue; private final EntitlementHandler mHandler; private final StateMachine mTetherMasterSM; - // Key: ConnectivityManager.TETHERING_*(downstream). - // Value: ConnectivityManager.TETHER_ERROR_{NO_ERROR or PROVISION_FAILED}(provisioning result). + // Key: TetheringManager.TETHERING_*(downstream). + // Value: TetheringManager.TETHER_ERROR_{NO_ERROR or PROVISION_FAILED}(provisioning result). private final SparseIntArray mCellularPermitted; private PendingIntent mProvisioningRecheckAlarm; private boolean mCellularUpstreamPermitted = true; @@ -122,6 +118,8 @@ public class EntitlementManager { mHandler = new EntitlementHandler(masterHandler.getLooper()); 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) { @@ -133,7 +131,7 @@ public class EntitlementManager { /** * Ui entitlement check fails in |downstream|. * - * @param downstream tethering type from ConnectivityManager.TETHERING_{@code *}. + * @param downstream tethering type from TetheringManager.TETHERING_{@code *}. */ void onUiEntitlementFailed(int downstream); } @@ -169,7 +167,7 @@ public class EntitlementManager { * This is called when tethering starts. * Launch provisioning app if upstream is cellular. * - * @param downstreamType tethering type from ConnectivityManager.TETHERING_{@code *} + * @param downstreamType tethering type from TetheringManager.TETHERING_{@code *} * @param showProvisioningUi a boolean indicating whether to show the * provisioning app UI if there is one. */ @@ -210,7 +208,7 @@ public class EntitlementManager { /** * Tell EntitlementManager that a given type of tethering has been disabled * - * @param type tethering type from ConnectivityManager.TETHERING_{@code *} + * @param type tethering type from TetheringManager.TETHERING_{@code *} */ public void stopProvisioningIfNeeded(int type) { mHandler.sendMessage(mHandler.obtainMessage(EVENT_STOP_PROVISIONING, type, 0)); @@ -296,7 +294,7 @@ public class EntitlementManager { /** * Re-check tethering provisioning for all enabled tether types. - * Reference ConnectivityManager.TETHERING_{@code *} for each tether type. + * 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. @@ -363,7 +361,7 @@ public class EntitlementManager { /** * Run no UI tethering provisioning check. - * @param type tethering type from ConnectivityManager.TETHERING_{@code *} + * @param type tethering type from TetheringManager.TETHERING_{@code *} * @param subId default data subscription ID. */ @VisibleForTesting @@ -377,7 +375,7 @@ public class EntitlementManager { intent.putExtra(EXTRA_RUN_PROVISION, true); intent.putExtra(EXTRA_PROVISION_CALLBACK, receiver); intent.putExtra(EXTRA_SUBID, subId); - intent.setComponent(TETHER_SERVICE); + 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); @@ -390,7 +388,7 @@ public class EntitlementManager { /** * Run the UI-enabled tethering provisioning check. - * @param type tethering type from ConnectivityManager.TETHERING_{@code *} + * @param type tethering type from TetheringManager.TETHERING_{@code *} * @param subId default data subscription ID. * @param receiver to receive entitlement check result. */ @@ -398,7 +396,7 @@ public class EntitlementManager { protected void runUiTetherProvisioning(int type, int subId, ResultReceiver receiver) { if (DBG) mLog.i("runUiTetherProvisioning: " + type); - Intent intent = new Intent(Settings.ACTION_TETHER_PROVISIONING); + Intent intent = new Intent(Settings.ACTION_TETHER_PROVISIONING_UI); intent.putExtra(EXTRA_ADD_TETHER_TYPE, type); intent.putExtra(EXTRA_PROVISION_CALLBACK, receiver); intent.putExtra(EXTRA_SUBID, subId); @@ -461,7 +459,7 @@ public class EntitlementManager { * Add the mapping between provisioning result and tethering type. * Notify UpstreamNetworkMonitor if Cellular permission changes. * - * @param type tethering type from ConnectivityManager.TETHERING_{@code *} + * @param type tethering type from TetheringManager.TETHERING_{@code *} * @param resultCode Provisioning result */ protected void addDownstreamMapping(int type, int resultCode) { @@ -476,7 +474,7 @@ public class EntitlementManager { /** * Remove the mapping for input tethering type. - * @param type tethering type from ConnectivityManager.TETHERING_{@code *} + * @param type tethering type from TetheringManager.TETHERING_{@code *} */ protected void removeDownstreamMapping(int type) { mLog.i("removeDownstreamMapping: " + type); @@ -625,7 +623,7 @@ public class EntitlementManager { /** * Update the last entitlement value to internal cache * - * @param type tethering type from ConnectivityManager.TETHERING_{@code *} + * @param type tethering type from TetheringManager.TETHERING_{@code *} * @param resultCode last entitlement value * @return the last updated entitlement value */ diff --git a/packages/Tethering/src/com/android/server/connectivity/tethering/OffloadController.java b/packages/Tethering/src/com/android/server/connectivity/tethering/OffloadController.java index 38fa91e7387e..cc36f4a9c516 100644 --- a/packages/Tethering/src/com/android/server/connectivity/tethering/OffloadController.java +++ b/packages/Tethering/src/com/android/server/connectivity/tethering/OffloadController.java @@ -16,35 +16,40 @@ package com.android.server.connectivity.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.STATS_PER_UID; import static android.net.NetworkStats.TAG_NONE; import static android.net.NetworkStats.UID_ALL; -import static android.net.TrafficStats.UID_TETHERING; +import static android.net.NetworkStats.UID_TETHERING; import static android.provider.Settings.Global.TETHER_OFFLOAD_DISABLED; +import android.annotation.NonNull; +import android.annotation.Nullable; +import android.app.usage.NetworkStatsManager; import android.content.ContentResolver; -import android.net.ITetheringStatsProvider; 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.AbstractNetworkStatsProvider; +import android.net.netstats.provider.NetworkStatsProviderCallback; import android.net.util.SharedLog; import android.os.Handler; -import android.os.INetworkManagementService; -import android.os.Looper; -import android.os.RemoteException; -import android.os.SystemClock; 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.server.connectivity.tethering.OffloadHardwareInterface.ForwardedStats; @@ -73,13 +78,19 @@ public class OffloadController { 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; - private final INetworkManagementService mNms; - private final ITetheringStatsProvider mStatsProvider; + private final @NonNull OffloadTetheringStatsProvider mStatsProvider; + private final @Nullable NetworkStatsProviderCallback mStatsProviderCb; private final SharedLog mLog; private final HashMap<String, LinkProperties> mDownstreams; private boolean mConfigInitialized; @@ -109,22 +120,23 @@ public class OffloadController { private int mNatUpdateNetlinkErrors; public OffloadController(Handler h, OffloadHardwareInterface hwi, - ContentResolver contentResolver, INetworkManagementService nms, SharedLog log) { + ContentResolver contentResolver, NetworkStatsManager nsm, SharedLog log) { mHandler = h; mHwInterface = hwi; mContentResolver = contentResolver; - mNms = nms; mStatsProvider = new OffloadTetheringStatsProvider(); mLog = log.forSubComponent(TAG); mDownstreams = new HashMap<>(); mExemptPrefixes = new HashSet<>(); mLastLocalPrefixStrs = new HashSet<>(); - + NetworkStatsProviderCallback providerCallback = null; try { - mNms.registerTetheringStatsProvider(mStatsProvider, getClass().getSimpleName()); - } catch (RemoteException e) { - mLog.e("Cannot register offload stats provider: " + e); + providerCallback = nsm.registerNetworkStatsProvider( + getClass().getSimpleName(), mStatsProvider); + } catch (RuntimeException e) { + Log.wtf(TAG, "Cannot register offload stats provider: " + e); } + mStatsProviderCb = providerCallback; } /** Start hardware offload. */ @@ -173,7 +185,7 @@ public class OffloadController { // and we need to synchronize stats and limits between // software and hardware forwarding. updateStatsForAllUpstreams(); - forceTetherStatsPoll(); + mStatsProvider.pushTetherStats(); } @Override @@ -186,7 +198,7 @@ public class OffloadController { // limits set take into account any software tethering // traffic that has been happening in the meantime. updateStatsForAllUpstreams(); - forceTetherStatsPoll(); + mStatsProvider.pushTetherStats(); // [2] (Re)Push all state. computeAndPushLocalPrefixes(UpdateType.FORCE); pushAllDownstreamState(); @@ -204,14 +216,11 @@ public class OffloadController { // the HAL queued the callback. // TODO: rev the HAL so that it provides an interface name. - // Fetch current stats, so that when our notification reaches - // NetworkStatsService and triggers a poll, we will respond with - // current data (which will be above the limit that was reached). - // Note that if we just changed upstream, this is unnecessary but harmless. - // The stats for the previous upstream were already updated on this thread - // just after the upstream was changed, so they are also up-to-date. updateStatsForCurrentUpstream(); - forceTetherStatsPoll(); + mStatsProvider.pushTetherStats(); + // Push stats to service does not cause the service react to it immediately. + // Inform the service about limit reached. + if (mStatsProviderCb != null) mStatsProviderCb.onLimitReached(); } @Override @@ -253,42 +262,37 @@ public class OffloadController { return mConfigInitialized && mControlInitialized; } - private class OffloadTetheringStatsProvider extends ITetheringStatsProvider.Stub { - @Override - public NetworkStats getTetherStats(int how) { - // getTetherStats() is the only function in OffloadController that can be called from - // a different thread. Do not attempt to update stats by querying the offload HAL - // synchronously from a different thread than our Handler thread. http://b/64771555. - Runnable updateStats = () -> { - updateStatsForCurrentUpstream(); - }; - if (Looper.myLooper() == mHandler.getLooper()) { - updateStats.run(); - } else { - mHandler.post(updateStats); - } - - NetworkStats stats = new NetworkStats(SystemClock.elapsedRealtime(), 0); - NetworkStats.Entry entry = new NetworkStats.Entry(); - entry.set = SET_DEFAULT; - entry.tag = TAG_NONE; - entry.uid = (how == STATS_PER_UID) ? UID_TETHERING : UID_ALL; - - for (Map.Entry<String, ForwardedStats> kv : mForwardedStats.entrySet()) { - ForwardedStats value = kv.getValue(); - entry.iface = kv.getKey(); - entry.rxBytes = value.rxBytes; - entry.txBytes = value.txBytes; - stats.addValues(entry); + @VisibleForTesting + class OffloadTetheringStatsProvider extends AbstractNetworkStatsProvider { + // 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); + + @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.addValues(entry); } return stats; } @Override - public void setInterfaceQuota(String iface, long quotaBytes) { + public void setLimit(String iface, long quotaBytes) { + mLog.i("setLimit: " + iface + "," + quotaBytes); + // Listen for all iface is necessary since upstream might be changed after limit + // is set. mHandler.post(() -> { - if (quotaBytes == ITetheringStatsProvider.QUOTA_UNLIMITED) { + if (quotaBytes == QUOTA_UNLIMITED) { mInterfaceQuotas.remove(iface); } else { mInterfaceQuotas.put(iface, quotaBytes); @@ -296,6 +300,42 @@ public class OffloadController { 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. + if (null == mStatsProviderCb) return; + final NetworkStats ifaceDiff = + getTetherStats(StatsType.STATS_PER_IFACE).subtract(mIfaceStats); + final NetworkStats uidDiff = + getTetherStats(StatsType.STATS_PER_UID).subtract(mUidStats); + try { + mStatsProviderCb.onStatsUpdated(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 requestStatsUpdate(int token) { + mLog.i("requestStatsUpdate: " + 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 setAlert(long quotaBytes) { + // TODO: Ask offload HAL to notify alert without stopping traffic. + } } private String currentUpstreamInterface() { @@ -353,14 +393,6 @@ public class OffloadController { } } - private void forceTetherStatsPoll() { - try { - mNms.tetherLimitReached(mStatsProvider); - } catch (RemoteException e) { - mLog.e("Cannot report data limit reached: " + e); - } - } - /** Set current tethering upstream LinkProperties. */ public void setUpstreamLinkProperties(LinkProperties lp) { if (!started() || Objects.equals(mUpstreamLinkProperties, lp)) return; diff --git a/packages/Tethering/src/com/android/server/connectivity/tethering/OffloadHardwareInterface.java b/packages/Tethering/src/com/android/server/connectivity/tethering/OffloadHardwareInterface.java index 4a8ef1f92754..90b9d3f148dc 100644 --- a/packages/Tethering/src/com/android/server/connectivity/tethering/OffloadHardwareInterface.java +++ b/packages/Tethering/src/com/android/server/connectivity/tethering/OffloadHardwareInterface.java @@ -29,6 +29,8 @@ import android.os.Handler; import android.os.RemoteException; import android.system.OsConstants; +import com.android.internal.annotations.VisibleForTesting; + import java.util.ArrayList; @@ -91,6 +93,12 @@ public class OffloadHardwareInterface { 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; diff --git a/packages/Tethering/src/com/android/server/connectivity/tethering/Tethering.java b/packages/Tethering/src/com/android/server/connectivity/tethering/Tethering.java index 2c8858eeafd3..5bf41ce25b2b 100644 --- a/packages/Tethering/src/com/android/server/connectivity/tethering/Tethering.java +++ b/packages/Tethering/src/com/android/server/connectivity/tethering/Tethering.java @@ -20,23 +20,24 @@ 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_RNDIS; -import static android.net.ConnectivityManager.ACTION_TETHER_STATE_CHANGED; +import static android.net.ConnectivityManager.ACTION_RESTRICT_BACKGROUND_CHANGED; import static android.net.ConnectivityManager.CONNECTIVITY_ACTION; -import static android.net.ConnectivityManager.EXTRA_ACTIVE_LOCAL_ONLY; -import static android.net.ConnectivityManager.EXTRA_ACTIVE_TETHER; -import static android.net.ConnectivityManager.EXTRA_AVAILABLE_TETHER; -import static android.net.ConnectivityManager.EXTRA_ERRORED_TETHER; import static android.net.ConnectivityManager.EXTRA_NETWORK_INFO; -import static android.net.ConnectivityManager.TETHERING_BLUETOOTH; -import static android.net.ConnectivityManager.TETHERING_INVALID; -import static android.net.ConnectivityManager.TETHERING_USB; -import static android.net.ConnectivityManager.TETHERING_WIFI; -import static android.net.ConnectivityManager.TETHERING_WIFI_P2P; -import static android.net.ConnectivityManager.TETHER_ERROR_MASTER_ERROR; -import static android.net.ConnectivityManager.TETHER_ERROR_NO_ERROR; -import static android.net.ConnectivityManager.TETHER_ERROR_SERVICE_UNAVAIL; -import static android.net.ConnectivityManager.TETHER_ERROR_UNAVAIL_IFACE; -import static android.net.ConnectivityManager.TETHER_ERROR_UNKNOWN_IFACE; +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_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_MASTER_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.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; @@ -50,8 +51,10 @@ import static android.telephony.CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANG import static android.telephony.SubscriptionManager.INVALID_SUBSCRIPTION_ID; import android.app.Notification; +import android.app.NotificationChannel; import android.app.NotificationManager; import android.app.PendingIntent; +import android.app.usage.NetworkStatsManager; import android.bluetooth.BluetoothAdapter; import android.bluetooth.BluetoothPan; import android.bluetooth.BluetoothProfile; @@ -62,19 +65,18 @@ import android.content.Intent; import android.content.IntentFilter; import android.content.res.Resources; import android.hardware.usb.UsbManager; +import android.net.ConnectivityManager; import android.net.INetd; -import android.net.INetworkPolicyManager; -import android.net.INetworkStatsService; import android.net.ITetheringEventCallback; import android.net.IpPrefix; import android.net.LinkAddress; import android.net.LinkProperties; import android.net.Network; import android.net.NetworkInfo; -import android.net.NetworkUtils; import android.net.TetherStatesParcel; import android.net.TetheringConfigurationParcel; 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; @@ -87,12 +89,12 @@ import android.net.wifi.p2p.WifiP2pManager; import android.os.Binder; import android.os.Bundle; import android.os.Handler; -import android.os.INetworkManagementService; 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.telephony.PhoneStateListener; @@ -102,9 +104,10 @@ 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.VisibleForTesting; -import com.android.internal.messages.nano.SystemMessageProto.SystemMessage; -import com.android.internal.notification.SystemNotificationChannels; import com.android.internal.util.IndentingPrintWriter; import com.android.internal.util.MessageUtils; import com.android.internal.util.State; @@ -139,6 +142,8 @@ public class Tethering { }; 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; @@ -172,10 +177,6 @@ public class Tethering { private final Context mContext; private final ArrayMap<String, TetherState> mTetherStates; private final BroadcastReceiver mStateReceiver; - // Stopship: replace mNMService before production. - private final INetworkManagementService mNMService; - private final INetworkStatsService mStatsService; - private final INetworkPolicyManager mPolicyManager; private final Looper mLooper; private final StateMachine mTetherMasterSM; private final OffloadController mOffloadController; @@ -205,14 +206,13 @@ public class Tethering { private boolean mWifiTetherRequested; private Network mTetherUpstream; private TetherStatesParcel mTetherStatesParcel; + private boolean mDataSaverEnabled = false; + private String mWifiP2pTetherInterface = null; public Tethering(TetheringDependencies deps) { mLog.mark("Tethering.constructed"); mDeps = deps; mContext = mDeps.getContext(); - mNMService = mDeps.getINetworkManagementService(); - mStatsService = mDeps.getINetworkStatsService(); - mPolicyManager = mDeps.getINetworkPolicyManager(); mNetd = mDeps.getINetd(mContext); mLooper = mDeps.getTetheringLooper(); @@ -223,12 +223,13 @@ public class Tethering { mTetherMasterSM = new TetherMasterSM("TetherMaster", mLooper, deps); mTetherMasterSM.start(); + final NetworkStatsManager statsManager = + (NetworkStatsManager) mContext.getSystemService(Context.NETWORK_STATS_SERVICE); mHandler = mTetherMasterSM.getHandler(); mOffloadController = new OffloadController(mHandler, - mDeps.getOffloadHardwareInterface(mHandler, mLog), - mContext.getContentResolver(), mNMService, - mLog); - mUpstreamNetworkMonitor = deps.getUpstreamNetworkMonitor(mContext, mTetherMasterSM, mLog, + mDeps.getOffloadHardwareInterface(mHandler, mLog), mContext.getContentResolver(), + statsManager, mLog); + mUpstreamNetworkMonitor = mDeps.getUpstreamNetworkMonitor(mContext, mTetherMasterSM, mLog, TetherMasterSM.EVENT_UPSTREAM_CALLBACK); mForwardedDownstreams = new HashSet<>(); @@ -264,7 +265,7 @@ public class Tethering { } final UserManager userManager = (UserManager) mContext.getSystemService( - Context.USER_SERVICE); + Context.USER_SERVICE); mTetheringRestriction = new UserRestrictionActionListener(userManager, this); final TetheringThreadExecutor executor = new TetheringThreadExecutor(mHandler); mActiveDataSubIdListener = new ActiveDataSubIdListener(executor); @@ -288,14 +289,8 @@ public class Tethering { 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, handler); - - filter = new IntentFilter(); - filter.addAction(Intent.ACTION_MEDIA_SHARED); - filter.addAction(Intent.ACTION_MEDIA_UNSHARED); - filter.addDataScheme("file"); - mContext.registerReceiver(mStateReceiver, filter, null, handler); - } private class TetheringThreadExecutor implements Executor { @@ -421,7 +416,6 @@ public class Tethering { } } - void interfaceRemoved(String iface) { if (VDBG) Log.d(TAG, "interfaceRemoved " + iface); synchronized (mPublicSync) { @@ -492,7 +486,7 @@ public class Tethering { } private void setBluetoothTethering(final boolean enable, final ResultReceiver receiver) { - final BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter(); + 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)); @@ -670,19 +664,19 @@ public class Tethering { if (usbTethered) { if (wifiTethered || bluetoothTethered) { - showTetheredNotification(SystemMessage.NOTE_TETHER_GENERAL); + showTetheredNotification(R.drawable.stat_sys_tether_general); } else { - showTetheredNotification(SystemMessage.NOTE_TETHER_USB); + showTetheredNotification(R.drawable.stat_sys_tether_usb); } } else if (wifiTethered) { if (bluetoothTethered) { - showTetheredNotification(SystemMessage.NOTE_TETHER_GENERAL); + showTetheredNotification(R.drawable.stat_sys_tether_general); } else { /* We now have a status bar icon for WifiTethering, so drop the notification */ clearTetheredNotification(); } } else if (bluetoothTethered) { - showTetheredNotification(SystemMessage.NOTE_TETHER_BLUETOOTH); + showTetheredNotification(R.drawable.stat_sys_tether_bluetooth); } else { clearTetheredNotification(); } @@ -695,30 +689,22 @@ public class Tethering { @VisibleForTesting protected void showTetheredNotification(int id, boolean tetheringOn) { NotificationManager notificationManager = - (NotificationManager) mContext.getSystemService(Context.NOTIFICATION_SERVICE); + (NotificationManager) mContext.createContextAsUser(UserHandle.ALL, 0) + .getSystemService(Context.NOTIFICATION_SERVICE); if (notificationManager == null) { return; } - int icon = 0; - switch(id) { - case SystemMessage.NOTE_TETHER_USB: - icon = R.drawable.stat_sys_tether_usb; - break; - case SystemMessage.NOTE_TETHER_BLUETOOTH: - icon = R.drawable.stat_sys_tether_bluetooth; - break; - case SystemMessage.NOTE_TETHER_GENERAL: - default: - icon = R.drawable.stat_sys_tether_general; - break; - } + final NotificationChannel channel = new NotificationChannel( + "TETHERING_STATUS", + mContext.getResources().getString(R.string.notification_channel_tethering_status), + NotificationManager.IMPORTANCE_LOW); + notificationManager.createNotificationChannel(channel); if (mLastNotificationId != 0) { - if (mLastNotificationId == icon) { + if (mLastNotificationId == id) { return; } - notificationManager.cancelAsUser(null, mLastNotificationId, - UserHandle.ALL); + notificationManager.cancel(null, mLastNotificationId); mLastNotificationId = 0; } @@ -726,8 +712,8 @@ public class Tethering { intent.setClassName("com.android.settings", "com.android.settings.TetherSettings"); intent.setFlags(Intent.FLAG_ACTIVITY_NO_HISTORY); - PendingIntent pi = PendingIntent.getActivityAsUser(mContext, 0, intent, 0, - null, UserHandle.CURRENT); + PendingIntent pi = PendingIntent.getActivity( + mContext.createContextAsUser(UserHandle.CURRENT, 0), 0, intent, 0, null); Resources r = mContext.getResources(); final CharSequence title; @@ -742,32 +728,30 @@ public class Tethering { } if (mTetheredNotificationBuilder == null) { - mTetheredNotificationBuilder = new Notification.Builder(mContext, - SystemNotificationChannels.NETWORK_STATUS); + mTetheredNotificationBuilder = new Notification.Builder(mContext, channel.getId()); mTetheredNotificationBuilder.setWhen(0) .setOngoing(true) .setColor(mContext.getColor( - com.android.internal.R.color.system_notification_accent_color)) + android.R.color.system_notification_accent_color)) .setVisibility(Notification.VISIBILITY_PUBLIC) .setCategory(Notification.CATEGORY_STATUS); } - mTetheredNotificationBuilder.setSmallIcon(icon) + mTetheredNotificationBuilder.setSmallIcon(id) .setContentTitle(title) .setContentText(message) .setContentIntent(pi); mLastNotificationId = id; - notificationManager.notifyAsUser(null, mLastNotificationId, - mTetheredNotificationBuilder.buildInto(new Notification()), UserHandle.ALL); + notificationManager.notify(null, mLastNotificationId, mTetheredNotificationBuilder.build()); } @VisibleForTesting protected void clearTetheredNotification() { NotificationManager notificationManager = - (NotificationManager) mContext.getSystemService(Context.NOTIFICATION_SERVICE); + (NotificationManager) mContext.createContextAsUser(UserHandle.ALL, 0) + .getSystemService(Context.NOTIFICATION_SERVICE); if (notificationManager != null && mLastNotificationId != 0) { - notificationManager.cancelAsUser(null, mLastNotificationId, - UserHandle.ALL); + notificationManager.cancel(null, mLastNotificationId); mLastNotificationId = 0; } } @@ -792,6 +776,9 @@ public class Tethering { } 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(); } } @@ -866,6 +853,11 @@ public class Tethering { } } + private boolean isGroupOwner(WifiP2pGroup group) { + return group != null && group.isGroupOwner() + && !TextUtils.isEmpty(group.getInterface()); + } + private void handleWifiP2pAction(Intent intent) { if (mConfig.isWifiP2pLegacyTetheringMode()) return; @@ -878,30 +870,51 @@ public class Tethering { Log.d(TAG, "WifiP2pAction: P2pInfo: " + p2pInfo + " Group: " + group); } - if (p2pInfo == null) return; - // When a p2p group is disconnected, p2pInfo would be cleared. - // group is still valid for detecting whether this device is group owner. - if (group == null || !group.isGroupOwner() - || TextUtils.isEmpty(group.getInterface())) return; - synchronized (Tethering.this.mPublicSync) { - // Enter below only if this device is Group Owner with a valid interface. - if (p2pInfo.groupFormed) { - TetherState tetherState = mTetherStates.get(group.getInterface()); - if (tetherState == null - || (tetherState.lastState != IpServer.STATE_TETHERED - && tetherState.lastState != IpServer.STATE_LOCAL_ONLY)) { - enableWifiIpServingLocked(group.getInterface(), IFACE_IP_MODE_LOCAL_ONLY); - } - } else { - disableWifiP2pIpServingLocked(group.getInterface()); + // 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 @@ -979,7 +992,9 @@ public class Tethering { disableWifiIpServingLockedCommon(TETHERING_WIFI, ifname, apState); } - private void disableWifiP2pIpServingLocked(String ifname) { + private void disableWifiP2pIpServingLockedIfNeeded(String ifname) { + if (TextUtils.isEmpty(ifname)) return; + disableWifiIpServingLockedCommon(TETHERING_WIFI_P2P, ifname, /* dummy */ 0); } @@ -1022,8 +1037,8 @@ public class Tethering { String[] ifaces = null; try { - ifaces = mNMService.listInterfaces(); - } catch (Exception e) { + ifaces = mNetd.interfaceGetList(); + } catch (RemoteException | ServiceSpecificException e) { Log.e(TAG, "Error listing Interfaces", e); return; } @@ -1282,25 +1297,25 @@ public class Tethering { protected boolean turnOnMasterTetherSettings() { final TetheringConfiguration cfg = mConfig; try { - mNMService.setIpForwardingEnabled(true); - } catch (Exception e) { + 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]; + ? cfg.legacyDhcpRanges : new String[0]; try { - // TODO: Find a more accurate method name (startDHCPv4()?). - mNMService.startTethering(dhcpRanges); - } catch (Exception e) { + NetdUtils.tetherStart(mNetd, true /** usingLegacyDnsProxy */, dhcpRanges); + } catch (RemoteException | ServiceSpecificException e) { try { - mNMService.stopTethering(); - mNMService.startTethering(dhcpRanges); - } catch (Exception ee) { + // Stop and retry. + mNetd.tetherStop(); + NetdUtils.tetherStart(mNetd, true /** usingLegacyDnsProxy */, dhcpRanges); + } catch (RemoteException | ServiceSpecificException ee) { mLog.e(ee); transitionTo(mStartTetheringErrorState); return false; @@ -1312,15 +1327,15 @@ public class Tethering { protected boolean turnOffMasterTetherSettings() { try { - mNMService.stopTethering(); - } catch (Exception e) { + mNetd.tetherStop(); + } catch (RemoteException | ServiceSpecificException e) { mLog.e(e); transitionTo(mStopTetheringErrorState); return false; } try { - mNMService.setIpForwardingEnabled(false); - } catch (Exception e) { + mNetd.ipfwdDisableForwarding(TAG); + } catch (RemoteException | ServiceSpecificException e) { mLog.e(e); transitionTo(mSetIpForwardingDisabledErrorState); return false; @@ -1383,19 +1398,25 @@ public class Tethering { protected void setDnsForwarders(final Network network, final LinkProperties lp) { // TODO: Set v4 and/or v6 DNS per available connectivity. - String[] dnsServers = mConfig.defaultIPv4DNS; final Collection<InetAddress> dnses = lp.getDnsServers(); // TODO: Properly support the absence of DNS servers. + final String[] dnsServers; if (dnses != null && !dnses.isEmpty()) { - // TODO: remove this invocation of NetworkUtils.makeStrings(). - dnsServers = NetworkUtils.makeStrings(dnses); + 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.netId : NETID_UNSET; try { - mNMService.setDnsForwarders(network, dnsServers); + mNetd.tetherDnsSet(netId, dnsServers); mLog.log(String.format( "SET DNS forwarders: network=%s dnsServers=%s", network, Arrays.toString(dnsServers))); - } catch (Exception e) { + } 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); @@ -1698,8 +1719,8 @@ public class Tethering { Log.e(TAG, "Error in startTethering"); notify(IpServer.CMD_START_TETHERING_ERROR); try { - mNMService.setIpForwardingEnabled(false); - } catch (Exception e) { } + mNetd.ipfwdDisableForwarding(TAG); + } catch (RemoteException | ServiceSpecificException e) { } } } @@ -1709,8 +1730,8 @@ public class Tethering { Log.e(TAG, "Error in stopTethering"); notify(IpServer.CMD_STOP_TETHERING_ERROR); try { - mNMService.setIpForwardingEnabled(false); - } catch (Exception e) { } + mNetd.ipfwdDisableForwarding(TAG); + } catch (RemoteException | ServiceSpecificException e) { } } } @@ -1720,11 +1741,11 @@ public class Tethering { Log.e(TAG, "Error in setDnsForwarders"); notify(IpServer.CMD_SET_DNS_FORWARDERS_ERROR); try { - mNMService.stopTethering(); - } catch (Exception e) { } + mNetd.tetherStop(); + } catch (RemoteException | ServiceSpecificException e) { } try { - mNMService.setIpForwardingEnabled(false); - } catch (Exception e) { } + mNetd.ipfwdDisableForwarding(TAG); + } catch (RemoteException | ServiceSpecificException e) { } } } @@ -1884,7 +1905,7 @@ public class Tethering { } } - void dump(FileDescriptor fd, PrintWriter writer, String[] args) { + 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, " "); @@ -1993,15 +2014,6 @@ public class Tethering { mLog.log(String.format("OBSERVED iface=%s state=%s error=%s", iface, state, error)); - try { - // Notify that we're tethering (or not) this interface. - // This is how data saver for instance knows if the user explicitly - // turned on tethering (thus keeping us from being in data saver mode). - mPolicyManager.onTetheringChanged(iface, state == IpServer.STATE_TETHERED); - } catch (RemoteException e) { - // Not really very much we can do here. - } - // If TetherMasterSM is in ErrorState, TetherMasterSM stays there. // Thus we give a chance for TetherMasterSM to recover to InitialState // by sending CMD_CLEAR_ERROR @@ -2065,7 +2077,7 @@ public class Tethering { mLog.log("adding TetheringInterfaceStateMachine for: " + iface); final TetherState tetherState = new TetherState( - new IpServer(iface, mLooper, interfaceType, mLog, mNMService, mStatsService, + new IpServer(iface, mLooper, interfaceType, mLog, mNetd, makeControlCallback(), mConfig.enableLegacyDhcpServer, mDeps.getIpServerDependencies())); mTetherStates.put(iface, tetherState); diff --git a/packages/Tethering/src/com/android/server/connectivity/tethering/TetheringConfiguration.java b/packages/Tethering/src/com/android/server/connectivity/tethering/TetheringConfiguration.java index 490614b03149..068c346fbfc1 100644 --- a/packages/Tethering/src/com/android/server/connectivity/tethering/TetheringConfiguration.java +++ b/packages/Tethering/src/com/android/server/connectivity/tethering/TetheringConfiguration.java @@ -21,31 +21,19 @@ 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.Settings.Global.TETHER_ENABLE_LEGACY_DHCP_SERVER; - -import static com.android.internal.R.array.config_mobile_hotspot_provision_app; -import static com.android.internal.R.array.config_tether_bluetooth_regexs; -import static com.android.internal.R.array.config_tether_dhcp_range; -import static com.android.internal.R.array.config_tether_upstream_types; -import static com.android.internal.R.array.config_tether_usb_regexs; -import static com.android.internal.R.array.config_tether_wifi_p2p_regexs; -import static com.android.internal.R.array.config_tether_wifi_regexs; -import static com.android.internal.R.bool.config_tether_upstream_automatic; -import static com.android.internal.R.integer.config_mobile_hotspot_provision_check_period; -import static com.android.internal.R.string.config_mobile_hotspot_provision_app_no_ui; - -import android.content.ContentResolver; +import static android.provider.DeviceConfig.NAMESPACE_CONNECTIVITY; + import android.content.Context; import android.content.res.Resources; -import android.net.ConnectivityManager; import android.net.TetheringConfigurationParcel; import android.net.util.SharedLog; -import android.provider.Settings; +import android.provider.DeviceConfig; import android.telephony.SubscriptionManager; import android.telephony.TelephonyManager; import android.text.TextUtils; import com.android.internal.annotations.VisibleForTesting; +import com.android.networkstack.tethering.R; import java.io.PrintWriter; import java.util.ArrayList; @@ -85,6 +73,12 @@ public class TetheringConfiguration { private static final String[] DEFAULT_IPV4_DNS = {"8.8.4.4", "8.8.8.8"}; + /** + * 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"; + public final String[] tetherableUsbRegexs; public final String[] tetherableWifiRegexs; public final String[] tetherableWifiP2pRegexs; @@ -108,27 +102,30 @@ public class TetheringConfiguration { activeDataSubId = id; Resources res = getResources(ctx, activeDataSubId); - tetherableUsbRegexs = getResourceStringArray(res, config_tether_usb_regexs); + tetherableUsbRegexs = getResourceStringArray(res, R.array.config_tether_usb_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, config_tether_wifi_regexs); - tetherableWifiP2pRegexs = getResourceStringArray(res, config_tether_wifi_p2p_regexs); - tetherableBluetoothRegexs = getResourceStringArray(res, config_tether_bluetooth_regexs); + tetherableWifiRegexs = getResourceStringArray(res, R.array.config_tether_wifi_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, config_tether_upstream_automatic); + chooseUpstreamAutomatically = getResourceBoolean( + res, R.bool.config_tether_upstream_automatic); preferredUpstreamIfaceTypes = getUpstreamIfaceTypes(res, isDunRequired); legacyDhcpRanges = getLegacyDhcpRanges(res); defaultIPv4DNS = copy(DEFAULT_IPV4_DNS); - enableLegacyDhcpServer = getEnableLegacyDhcpServer(ctx); + enableLegacyDhcpServer = getEnableLegacyDhcpServer(res); - provisioningApp = getResourceStringArray(res, config_mobile_hotspot_provision_app); + provisioningApp = getResourceStringArray(res, R.array.config_mobile_hotspot_provision_app); provisioningAppNoUi = getProvisioningAppNoUi(res); provisioningCheckPeriod = getResourceInteger(res, - config_mobile_hotspot_provision_check_period, + R.integer.config_mobile_hotspot_provision_check_period, 0 /* No periodic re-check */); configLog.log(toString()); @@ -179,8 +176,8 @@ public class TetheringConfiguration { pw.print("chooseUpstreamAutomatically: "); pw.println(chooseUpstreamAutomatically); - dumpStringArray(pw, "preferredUpstreamIfaceTypes", - preferredUpstreamNames(preferredUpstreamIfaceTypes)); + pw.print("legacyPreredUpstreamIfaceTypes: "); + pw.println(Arrays.toString(toIntArray(preferredUpstreamIfaceTypes))); dumpStringArray(pw, "legacyDhcpRanges", legacyDhcpRanges); dumpStringArray(pw, "defaultIPv4DNS", defaultIPv4DNS); @@ -205,7 +202,7 @@ public class TetheringConfiguration { sj.add(String.format("isDunRequired:%s", isDunRequired)); sj.add(String.format("chooseUpstreamAutomatically:%s", chooseUpstreamAutomatically)); sj.add(String.format("preferredUpstreamIfaceTypes:%s", - makeString(preferredUpstreamNames(preferredUpstreamIfaceTypes)))); + toIntArray(preferredUpstreamIfaceTypes))); sj.add(String.format("provisioningApp:%s", makeString(provisioningApp))); sj.add(String.format("provisioningAppNoUi:%s", provisioningAppNoUi)); sj.add(String.format("enableLegacyDhcpServer:%s", enableLegacyDhcpServer)); @@ -234,21 +231,6 @@ public class TetheringConfiguration { return sj.toString(); } - private static String[] preferredUpstreamNames(Collection<Integer> upstreamTypes) { - String[] upstreamNames = null; - - if (upstreamTypes != null) { - upstreamNames = new String[upstreamTypes.size()]; - int i = 0; - for (Integer netType : upstreamTypes) { - upstreamNames[i] = ConnectivityManager.getNetworkTypeName(netType); - i++; - } - } - - return upstreamNames; - } - /** Check whether dun is required. */ public static boolean checkDunRequired(Context ctx) { final TelephonyManager tm = (TelephonyManager) ctx.getSystemService(TELEPHONY_SERVICE); @@ -258,7 +240,7 @@ public class TetheringConfiguration { } private static Collection<Integer> getUpstreamIfaceTypes(Resources res, boolean dunRequired) { - final int[] ifaceTypes = res.getIntArray(config_tether_upstream_types); + 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) { @@ -308,7 +290,7 @@ public class TetheringConfiguration { } private static String[] getLegacyDhcpRanges(Resources res) { - final String[] fromResource = getResourceStringArray(res, config_tether_dhcp_range); + final String[] fromResource = getResourceStringArray(res, R.array.config_tether_dhcp_range); if ((fromResource.length > 0) && (fromResource.length % 2 == 0)) { return fromResource; } @@ -317,7 +299,7 @@ public class TetheringConfiguration { private static String getProvisioningAppNoUi(Resources res) { try { - return res.getString(config_mobile_hotspot_provision_app_no_ui); + return res.getString(R.string.config_mobile_hotspot_provision_app_no_ui); } catch (Resources.NotFoundException e) { return ""; } @@ -348,10 +330,14 @@ public class TetheringConfiguration { } } - private static boolean getEnableLegacyDhcpServer(Context ctx) { - final ContentResolver cr = ctx.getContentResolver(); - final int intVal = Settings.Global.getInt(cr, TETHER_ENABLE_LEGACY_DHCP_SERVER, 0); - return intVal != 0; + private boolean getEnableLegacyDhcpServer(final Resources res) { + return getResourceBoolean(res, R.bool.config_tether_enable_legacy_dhcp_server) + || getDeviceConfigBoolean(TETHER_ENABLE_LEGACY_DHCP_SERVER); + } + + @VisibleForTesting + protected boolean getDeviceConfigBoolean(final String name) { + return DeviceConfig.getBoolean(NAMESPACE_CONNECTIVITY, name, false /** defaultValue */); } private Resources getResources(Context ctx, int subId) { @@ -388,6 +374,15 @@ public class TetheringConfiguration { 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. */ @@ -400,12 +395,7 @@ public class TetheringConfiguration { parcel.isDunRequired = isDunRequired; parcel.chooseUpstreamAutomatically = chooseUpstreamAutomatically; - int[] preferredTypes = new int[preferredUpstreamIfaceTypes.size()]; - int index = 0; - for (Integer type : preferredUpstreamIfaceTypes) { - preferredTypes[index++] = type; - } - parcel.preferredUpstreamIfaceTypes = preferredTypes; + parcel.preferredUpstreamIfaceTypes = toIntArray(preferredUpstreamIfaceTypes); parcel.legacyDhcpRanges = legacyDhcpRanges; parcel.defaultIPv4DNS = defaultIPv4DNS; diff --git a/packages/Tethering/src/com/android/server/connectivity/tethering/TetheringDependencies.java b/packages/Tethering/src/com/android/server/connectivity/tethering/TetheringDependencies.java index b16b3294a112..e019c3aca26a 100644 --- a/packages/Tethering/src/com/android/server/connectivity/tethering/TetheringDependencies.java +++ b/packages/Tethering/src/com/android/server/connectivity/tethering/TetheringDependencies.java @@ -16,18 +16,15 @@ package com.android.server.connectivity.tethering; +import android.bluetooth.BluetoothAdapter; import android.content.Context; import android.net.INetd; -import android.net.INetworkPolicyManager; -import android.net.INetworkStatsService; 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.INetworkManagementService; import android.os.Looper; -import android.os.ServiceManager; import com.android.internal.util.StateMachine; @@ -97,33 +94,6 @@ public abstract class TetheringDependencies { } /** - * Get a reference to INetworkManagementService to registerTetheringStatsProvider from - * OffloadController. Note: This should be removed soon by Usage refactor work in R - * development cycle. - */ - public INetworkManagementService getINetworkManagementService() { - return INetworkManagementService.Stub.asInterface( - ServiceManager.getService(Context.NETWORKMANAGEMENT_SERVICE)); - } - - /** - * Get a reference to INetworkStatsService to force update tethering usage. - * Note: This should be removed in R development cycle. - */ - public INetworkStatsService getINetworkStatsService() { - return INetworkStatsService.Stub.asInterface( - ServiceManager.getService(Context.NETWORK_STATS_SERVICE)); - } - - /** - * Get a reference to INetworkPolicyManager to be used by tethering. - */ - public INetworkPolicyManager getINetworkPolicyManager() { - return INetworkPolicyManager.Stub.asInterface( - ServiceManager.getService(Context.NETWORK_POLICY_SERVICE)); - } - - /** * Get a reference to INetd to be used by tethering. */ public INetd getINetd(Context context) { @@ -140,4 +110,9 @@ public abstract class TetheringDependencies { * Get Context of TetheringSerice. */ public abstract Context getContext(); + + /** + * Get a reference to BluetoothAdapter to be used by tethering. + */ + public abstract BluetoothAdapter getBluetoothAdapter(); } diff --git a/packages/Tethering/src/com/android/server/connectivity/tethering/TetheringInterfaceUtils.java b/packages/Tethering/src/com/android/server/connectivity/tethering/TetheringInterfaceUtils.java index 6334c20c2acc..d5cdd8a004dc 100644 --- a/packages/Tethering/src/com/android/server/connectivity/tethering/TetheringInterfaceUtils.java +++ b/packages/Tethering/src/com/android/server/connectivity/tethering/TetheringInterfaceUtils.java @@ -22,14 +22,17 @@ import android.net.NetworkCapabilities; import android.net.RouteInfo; import android.net.util.InterfaceSet; -import java.net.Inet4Address; -import java.net.Inet6Address; 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. @@ -40,7 +43,7 @@ public final class TetheringInterfaceUtils { } final LinkProperties lp = ns.linkProperties; - final String if4 = getInterfaceForDestination(lp, Inet4Address.ANY); + final String if4 = getInterfaceForDestination(lp, INADDR_ANY); final String if6 = getIPv6Interface(ns); return (if4 == null && if6 == null) ? null : new InterfaceSet(if4, if6); @@ -76,7 +79,7 @@ public final class TetheringInterfaceUtils { && ns.networkCapabilities.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR); return canTether - ? getInterfaceForDestination(ns.linkProperties, Inet6Address.ANY) + ? getInterfaceForDestination(ns.linkProperties, IN6ADDR_ANY) : null; } @@ -86,4 +89,12 @@ public final class TetheringInterfaceUtils { : 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/server/connectivity/tethering/TetheringService.java b/packages/Tethering/src/com/android/server/connectivity/tethering/TetheringService.java index 775484eabfa3..cb7d3920e693 100644 --- a/packages/Tethering/src/com/android/server/connectivity/tethering/TetheringService.java +++ b/packages/Tethering/src/com/android/server/connectivity/tethering/TetheringService.java @@ -24,13 +24,14 @@ 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.ConnectivityManager; 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.dhcp.DhcpServerCallbacks; import android.net.dhcp.DhcpServingParamsParcel; @@ -42,7 +43,6 @@ import android.os.IBinder; import android.os.Looper; import android.os.RemoteException; import android.os.ResultReceiver; -import android.os.ServiceManager; import android.os.SystemProperties; import android.os.UserManager; import android.provider.Settings; @@ -307,9 +307,15 @@ public class TetheringService extends Service { mDeps = new TetheringDependencies() { @Override public NetworkRequest getDefaultNetworkRequest() { - ConnectivityManager cm = (ConnectivityManager) mContext.getSystemService( - Context.CONNECTIVITY_SERVICE); - return cm.getDefaultRequest(); + // 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 @@ -357,7 +363,7 @@ public class TetheringService extends Service { IBinder connector; try { final long before = System.currentTimeMillis(); - while ((connector = ServiceManager.getService( + while ((connector = (IBinder) mContext.getSystemService( Context.NETWORK_STACK_SERVICE)) == null) { if (System.currentTimeMillis() - before > NETWORKSTACK_TIMEOUT_MS) { Log.wtf(TAG, "Timeout, fail to get INetworkStackConnector"); @@ -371,6 +377,11 @@ public class TetheringService extends Service { } return INetworkStackConnector.Stub.asInterface(connector); } + + @Override + public BluetoothAdapter getBluetoothAdapter() { + return BluetoothAdapter.getDefaultAdapter(); + } }; } return mDeps; diff --git a/packages/Tethering/src/com/android/server/connectivity/tethering/UpstreamNetworkMonitor.java b/packages/Tethering/src/com/android/server/connectivity/tethering/UpstreamNetworkMonitor.java index 22150f623a35..2875f71e5ed2 100644 --- a/packages/Tethering/src/com/android/server/connectivity/tethering/UpstreamNetworkMonitor.java +++ b/packages/Tethering/src/com/android/server/connectivity/tethering/UpstreamNetworkMonitor.java @@ -16,11 +16,15 @@ package com.android.server.connectivity.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_NONE; -import static android.net.ConnectivityManager.getNetworkTypeName; +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; @@ -35,10 +39,11 @@ import android.net.NetworkRequest; import android.net.util.PrefixUtils; import android.net.util.SharedLog; import android.os.Handler; -import android.os.Process; import android.util.Log; +import android.util.SparseIntArray; import com.android.internal.annotations.VisibleForTesting; +import com.android.internal.util.Preconditions; import com.android.internal.util.StateMachine; import java.util.HashMap; @@ -79,11 +84,25 @@ public class UpstreamNetworkMonitor { 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; @@ -130,15 +149,15 @@ public class UpstreamNetworkMonitor { */ public void startTrackDefaultNetwork(NetworkRequest defaultNetworkRequest, EntitlementManager entitle) { - // This 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 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. + + // 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) { - final NetworkRequest trackDefaultRequest = new NetworkRequest(defaultNetworkRequest); mDefaultNetworkCallback = new UpstreamNetworkCallback(CALLBACK_DEFAULT_INTERNET); - cm().requestNetwork(trackDefaultRequest, mDefaultNetworkCallback, mHandler); + cm().requestNetwork(defaultNetworkRequest, mDefaultNetworkCallback, mHandler); } if (mEntitlementMgr == null) { mEntitlementMgr = entitle; @@ -198,19 +217,28 @@ public class UpstreamNetworkMonitor { mLog.e("registerMobileNetworkRequest() already registered"); return; } - // The following use of the legacy type system cannot be removed until - // after upstream selection no longer finds networks by legacy type. - // See also http://b/34364553 . - final int legacyType = mDunRequired ? TYPE_MOBILE_DUN : TYPE_MOBILE_HIPRI; - final NetworkRequest mobileUpstreamRequest = new NetworkRequest.Builder() - .setCapabilities(ConnectivityManager.networkCapabilitiesForType(legacyType)) - .build(); + 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. @@ -239,7 +267,7 @@ public class UpstreamNetworkMonitor { final TypeStatePair typeStatePair = findFirstAvailableUpstreamByType( mNetworkMap.values(), preferredTypes, isCellularUpstreamPermitted()); - mLog.log("preferred upstream type: " + getNetworkTypeName(typeStatePair.type)); + mLog.log("preferred upstream type: " + typeStatePair.type); switch (typeStatePair.type) { case TYPE_MOBILE_DUN: @@ -356,16 +384,6 @@ public class UpstreamNetworkMonitor { notifyTarget(EVENT_ON_LINKPROPERTIES, network); } - private void handleSuspended(Network network) { - if (!network.equals(mTetheringUpstreamNetwork)) return; - mLog.log("SUSPENDED current upstream: " + network); - } - - private void handleResumed(Network network) { - if (!network.equals(mTetheringUpstreamNetwork)) return; - mLog.log("RESUMED current upstream: " + network); - } - private void handleLost(Network network) { // There are few TODOs within ConnectivityService's rematching code // pertaining to spurious onLost() notifications. @@ -455,20 +473,6 @@ public class UpstreamNetworkMonitor { } @Override - public void onNetworkSuspended(Network network) { - if (mCallbackType == CALLBACK_LISTEN_ALL) { - handleSuspended(network); - } - } - - @Override - public void onNetworkResumed(Network network) { - if (mCallbackType == CALLBACK_LISTEN_ALL) { - handleResumed(network); - } - } - - @Override public void onLost(Network network) { if (mCallbackType == CALLBACK_DEFAULT_INTERNET) { mDefaultInternetNetwork = null; @@ -512,18 +516,15 @@ public class UpstreamNetworkMonitor { for (int type : preferredTypes) { NetworkCapabilities nc; try { - nc = ConnectivityManager.networkCapabilitiesForType(type); + nc = networkCapabilitiesForType(type); } catch (IllegalArgumentException iae) { - Log.e(TAG, "No NetworkCapabilities mapping for legacy type: " - + ConnectivityManager.getNetworkTypeName(type)); + Log.e(TAG, "No NetworkCapabilities mapping for legacy type: " + type); continue; } if (!isCellularUpstreamPermitted && isCellular(nc)) { continue; } - nc.setSingleUid(Process.myUid()); - for (UpstreamNetworkState value : netStates) { if (!nc.satisfiedByNetworkCapabilities(value.networkCapabilities)) { continue; @@ -577,4 +578,28 @@ public class UpstreamNetworkMonitor { 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 nc = new NetworkCapabilities(); + + // Map from type to transports. + final int notFound = -1; + final int transport = sLegacyTypeToTransport.get(type, notFound); + Preconditions.checkArgument(transport != notFound, "unknown legacy type: " + type); + nc.addTransportType(transport); + + if (type == TYPE_MOBILE_DUN) { + nc.addCapability(NetworkCapabilities.NET_CAPABILITY_DUN); + // DUN is restricted network, see NetworkCapabilities#FORCE_RESTRICTED_CAPABILITIES. + nc.removeCapability(NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED); + } else { + nc.addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET); + } + return nc; + } } diff --git a/packages/Tethering/tests/unit/jarjar-rules.txt b/packages/Tethering/tests/unit/jarjar-rules.txt index 64fdebd92726..921fbed373b0 100644 --- a/packages/Tethering/tests/unit/jarjar-rules.txt +++ b/packages/Tethering/tests/unit/jarjar-rules.txt @@ -7,5 +7,6 @@ rule com.android.internal.util.MessageUtils* com.android.networkstack.tethering. rule com.android.internal.util.Preconditions* com.android.networkstack.tethering.util.Preconditions@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.net.LocalLog* com.android.networkstack.tethering.LocalLog@1 diff --git a/packages/Tethering/tests/unit/src/android/net/ip/IpServerTest.java b/packages/Tethering/tests/unit/src/android/net/ip/IpServerTest.java index fd2f708aea30..f29ad780b92c 100644 --- a/packages/Tethering/tests/unit/src/android/net/ip/IpServerTest.java +++ b/packages/Tethering/tests/unit/src/android/net/ip/IpServerTest.java @@ -16,13 +16,14 @@ package android.net.ip; -import static android.net.ConnectivityManager.TETHERING_BLUETOOTH; -import static android.net.ConnectivityManager.TETHERING_USB; -import static android.net.ConnectivityManager.TETHERING_WIFI; -import static android.net.ConnectivityManager.TETHERING_WIFI_P2P; -import static android.net.ConnectivityManager.TETHER_ERROR_ENABLE_NAT_ERROR; -import static android.net.ConnectivityManager.TETHER_ERROR_NO_ERROR; -import static android.net.ConnectivityManager.TETHER_ERROR_TETHER_IFACE_ERROR; +import static android.net.INetd.IF_STATE_UP; +import static android.net.TetheringManager.TETHERING_BLUETOOTH; +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_NAT_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; @@ -51,8 +52,7 @@ import static org.mockito.Mockito.verifyNoMoreInteractions; import static org.mockito.Mockito.when; import android.net.INetd; -import android.net.INetworkStatsService; -import android.net.InterfaceConfiguration; +import android.net.InterfaceConfigurationParcel; import android.net.IpPrefix; import android.net.LinkAddress; import android.net.LinkProperties; @@ -64,7 +64,6 @@ import android.net.dhcp.IDhcpServerCallbacks; import android.net.util.InterfaceParams; import android.net.util.InterfaceSet; import android.net.util.SharedLog; -import android.os.INetworkManagementService; import android.os.RemoteException; import android.os.test.TestLooper; import android.text.TextUtils; @@ -89,6 +88,8 @@ 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 String BLUETOOTH_IFACE_ADDR = "192.168.42.1"; + private static final int BLUETOOTH_DHCP_PREFIX_LENGTH = 24; private static final int DHCP_LEASE_TIME_SECS = 3600; private static final InterfaceParams TEST_IFACE_PARAMS = new InterfaceParams( @@ -96,11 +97,8 @@ public class IpServerTest { private static final int MAKE_DHCPSERVER_TIMEOUT_MS = 1000; - @Mock private INetworkManagementService mNMService; @Mock private INetd mNetd; - @Mock private INetworkStatsService mStatsService; @Mock private IpServer.Callback mCallback; - @Mock private InterfaceConfiguration mInterfaceConfiguration; @Mock private SharedLog mSharedLog; @Mock private IDhcpServer mDhcpServer; @Mock private RouterAdvertisementDaemon mRaDaemon; @@ -112,6 +110,7 @@ public class IpServerTest { private final ArgumentCaptor<LinkProperties> mLinkPropertiesCaptor = ArgumentCaptor.forClass(LinkProperties.class); private IpServer mIpServer; + private InterfaceConfigurationParcel mInterfaceConfiguration; private void initStateMachine(int interfaceType) throws Exception { initStateMachine(interfaceType, false /* usingLegacyDhcp */); @@ -131,17 +130,20 @@ public class IpServerTest { }).when(mDependencies).makeDhcpServer(any(), mDhcpParamsCaptor.capture(), any()); when(mDependencies.getRouterAdvertisementDaemon(any())).thenReturn(mRaDaemon); when(mDependencies.getInterfaceParams(IFACE_NAME)).thenReturn(TEST_IFACE_PARAMS); - when(mDependencies.getNetdService()).thenReturn(mNetd); - + mInterfaceConfiguration = new InterfaceConfigurationParcel(); + mInterfaceConfiguration.flags = new String[0]; + if (interfaceType == TETHERING_BLUETOOTH) { + mInterfaceConfiguration.ipv4Addr = BLUETOOTH_IFACE_ADDR; + mInterfaceConfiguration.prefixLength = BLUETOOTH_DHCP_PREFIX_LENGTH; + } mIpServer = new IpServer( - IFACE_NAME, mLooper.getLooper(), interfaceType, mSharedLog, - mNMService, mStatsService, mCallback, usingLegacyDhcp, mDependencies); + IFACE_NAME, mLooper.getLooper(), interfaceType, mSharedLog, mNetd, + mCallback, usingLegacyDhcp, mDependencies); mIpServer.start(); // 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(mNMService, mStatsService, mCallback); - when(mNMService.getInterfaceConfig(IFACE_NAME)).thenReturn(mInterfaceConfiguration); + reset(mNetd, mCallback); when(mRaDaemon.start()).thenReturn(true); } @@ -158,8 +160,7 @@ public class IpServerTest { if (upstreamIface != null) { dispatchTetherConnectionChanged(upstreamIface); } - reset(mNMService, mStatsService, mCallback); - when(mNMService.getInterfaceConfig(IFACE_NAME)).thenReturn(mInterfaceConfiguration); + reset(mNetd, mCallback); } @Before public void setUp() throws Exception { @@ -169,15 +170,14 @@ public class IpServerTest { @Test public void startsOutAvailable() { - mIpServer = new IpServer(IFACE_NAME, mLooper.getLooper(), - TETHERING_BLUETOOTH, mSharedLog, mNMService, mStatsService, mCallback, - false /* usingLegacyDhcp */, mDependencies); + mIpServer = new IpServer(IFACE_NAME, mLooper.getLooper(), TETHERING_BLUETOOTH, mSharedLog, + mNetd, mCallback, false /* usingLegacyDhcp */, 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, mNMService, mStatsService); + verifyNoMoreInteractions(mCallback, mNetd); } @Test @@ -196,7 +196,7 @@ public class IpServerTest { // None of these commands should trigger us to request action from // the rest of the system. dispatchCommand(command); - verifyNoMoreInteractions(mNMService, mStatsService, mCallback); + verifyNoMoreInteractions(mNetd, mCallback); } } @@ -208,7 +208,7 @@ public class IpServerTest { verify(mCallback).updateInterfaceState( mIpServer, STATE_UNAVAILABLE, TETHER_ERROR_NO_ERROR); verify(mCallback).updateLinkProperties(eq(mIpServer), any(LinkProperties.class)); - verifyNoMoreInteractions(mNMService, mStatsService, mCallback); + verifyNoMoreInteractions(mNetd, mCallback); } @Test @@ -216,13 +216,17 @@ public class IpServerTest { initStateMachine(TETHERING_BLUETOOTH); dispatchCommand(IpServer.CMD_TETHER_REQUESTED, STATE_TETHERED); - InOrder inOrder = inOrder(mCallback, mNMService); - inOrder.verify(mNMService).tetherInterface(IFACE_NAME); + 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(mNMService, mStatsService, mCallback); + verifyNoMoreInteractions(mNetd, mCallback); } @Test @@ -230,14 +234,16 @@ public class IpServerTest { initTetheredStateMachine(TETHERING_BLUETOOTH, null); dispatchCommand(IpServer.CMD_TETHER_UNREQUESTED); - InOrder inOrder = inOrder(mNMService, mNetd, mStatsService, mCallback); - inOrder.verify(mNMService).untetherInterface(IFACE_NAME); + InOrder inOrder = inOrder(mNetd, mCallback); + 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(mCallback).updateInterfaceState( mIpServer, STATE_AVAILABLE, TETHER_ERROR_NO_ERROR); inOrder.verify(mCallback).updateLinkProperties( eq(mIpServer), any(LinkProperties.class)); - verifyNoMoreInteractions(mNMService, mStatsService, mCallback); + verifyNoMoreInteractions(mNetd, mCallback); } @Test @@ -245,16 +251,19 @@ public class IpServerTest { initStateMachine(TETHERING_USB); dispatchCommand(IpServer.CMD_TETHER_REQUESTED, STATE_TETHERED); - InOrder inOrder = inOrder(mCallback, mNMService); - inOrder.verify(mNMService).getInterfaceConfig(IFACE_NAME); - inOrder.verify(mNMService).setInterfaceConfig(IFACE_NAME, mInterfaceConfiguration); - inOrder.verify(mNMService).tetherInterface(IFACE_NAME); + InOrder inOrder = inOrder(mCallback, mNetd); + 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(mNMService, mStatsService, mCallback); + verifyNoMoreInteractions(mNetd, mCallback); } @Test @@ -262,16 +271,19 @@ public class IpServerTest { initStateMachine(TETHERING_WIFI_P2P); dispatchCommand(IpServer.CMD_TETHER_REQUESTED, STATE_LOCAL_ONLY); - InOrder inOrder = inOrder(mCallback, mNMService); - inOrder.verify(mNMService).getInterfaceConfig(IFACE_NAME); - inOrder.verify(mNMService).setInterfaceConfig(IFACE_NAME, mInterfaceConfiguration); - inOrder.verify(mNMService).tetherInterface(IFACE_NAME); + InOrder inOrder = inOrder(mCallback, mNetd); + 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(mNMService, mStatsService, mCallback); + verifyNoMoreInteractions(mNetd, mCallback); } @Test @@ -281,10 +293,10 @@ public class IpServerTest { // Telling the state machine about its upstream interface triggers // a little more configuration. dispatchTetherConnectionChanged(UPSTREAM_IFACE); - InOrder inOrder = inOrder(mNMService); - inOrder.verify(mNMService).enableNat(IFACE_NAME, UPSTREAM_IFACE); - inOrder.verify(mNMService).startInterfaceForwarding(IFACE_NAME, UPSTREAM_IFACE); - verifyNoMoreInteractions(mNMService, mStatsService, mCallback); + InOrder inOrder = inOrder(mNetd); + inOrder.verify(mNetd).tetherAddForward(IFACE_NAME, UPSTREAM_IFACE); + inOrder.verify(mNetd).ipfwdAddInterfaceForward(IFACE_NAME, UPSTREAM_IFACE); + verifyNoMoreInteractions(mNetd, mCallback); } @Test @@ -292,49 +304,44 @@ public class IpServerTest { initTetheredStateMachine(TETHERING_BLUETOOTH, UPSTREAM_IFACE); dispatchTetherConnectionChanged(UPSTREAM_IFACE2); - InOrder inOrder = inOrder(mNMService, mStatsService); - inOrder.verify(mStatsService).forceUpdate(); - inOrder.verify(mNMService).stopInterfaceForwarding(IFACE_NAME, UPSTREAM_IFACE); - inOrder.verify(mNMService).disableNat(IFACE_NAME, UPSTREAM_IFACE); - inOrder.verify(mNMService).enableNat(IFACE_NAME, UPSTREAM_IFACE2); - inOrder.verify(mNMService).startInterfaceForwarding(IFACE_NAME, UPSTREAM_IFACE2); - verifyNoMoreInteractions(mNMService, mStatsService, mCallback); + 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(mNMService).enableNat(IFACE_NAME, UPSTREAM_IFACE2); + doThrow(RemoteException.class).when(mNetd).tetherAddForward(IFACE_NAME, UPSTREAM_IFACE2); dispatchTetherConnectionChanged(UPSTREAM_IFACE2); - InOrder inOrder = inOrder(mNMService, mStatsService); - inOrder.verify(mStatsService).forceUpdate(); - inOrder.verify(mNMService).stopInterfaceForwarding(IFACE_NAME, UPSTREAM_IFACE); - inOrder.verify(mNMService).disableNat(IFACE_NAME, UPSTREAM_IFACE); - inOrder.verify(mNMService).enableNat(IFACE_NAME, UPSTREAM_IFACE2); - inOrder.verify(mStatsService).forceUpdate(); - inOrder.verify(mNMService).stopInterfaceForwarding(IFACE_NAME, UPSTREAM_IFACE2); - inOrder.verify(mNMService).disableNat(IFACE_NAME, 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(mNMService).startInterfaceForwarding( + doThrow(RemoteException.class).when(mNetd).ipfwdAddInterfaceForward( IFACE_NAME, UPSTREAM_IFACE2); dispatchTetherConnectionChanged(UPSTREAM_IFACE2); - InOrder inOrder = inOrder(mNMService, mStatsService); - inOrder.verify(mStatsService).forceUpdate(); - inOrder.verify(mNMService).stopInterfaceForwarding(IFACE_NAME, UPSTREAM_IFACE); - inOrder.verify(mNMService).disableNat(IFACE_NAME, UPSTREAM_IFACE); - inOrder.verify(mNMService).enableNat(IFACE_NAME, UPSTREAM_IFACE2); - inOrder.verify(mNMService).startInterfaceForwarding(IFACE_NAME, UPSTREAM_IFACE2); - inOrder.verify(mStatsService).forceUpdate(); - inOrder.verify(mNMService).stopInterfaceForwarding(IFACE_NAME, UPSTREAM_IFACE2); - inOrder.verify(mNMService).disableNat(IFACE_NAME, 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 @@ -342,17 +349,18 @@ public class IpServerTest { initTetheredStateMachine(TETHERING_BLUETOOTH, UPSTREAM_IFACE); dispatchCommand(IpServer.CMD_TETHER_UNREQUESTED); - InOrder inOrder = inOrder(mNMService, mNetd, mStatsService, mCallback); - inOrder.verify(mStatsService).forceUpdate(); - inOrder.verify(mNMService).stopInterfaceForwarding(IFACE_NAME, UPSTREAM_IFACE); - inOrder.verify(mNMService).disableNat(IFACE_NAME, UPSTREAM_IFACE); - inOrder.verify(mNMService).untetherInterface(IFACE_NAME); + InOrder inOrder = inOrder(mNetd, mCallback); + 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(mCallback).updateInterfaceState( mIpServer, STATE_AVAILABLE, TETHER_ERROR_NO_ERROR); inOrder.verify(mCallback).updateLinkProperties( eq(mIpServer), any(LinkProperties.class)); - verifyNoMoreInteractions(mNMService, mStatsService, mCallback); + verifyNoMoreInteractions(mNetd, mCallback); } @Test @@ -361,13 +369,14 @@ public class IpServerTest { initTetheredStateMachine(TETHERING_USB, null); if (shouldThrow) { - doThrow(RemoteException.class).when(mNMService).untetherInterface(IFACE_NAME); + doThrow(RemoteException.class).when(mNetd).tetherInterfaceRemove(IFACE_NAME); } dispatchCommand(IpServer.CMD_INTERFACE_DOWN); - InOrder usbTeardownOrder = inOrder(mNMService, mInterfaceConfiguration, mCallback); - usbTeardownOrder.verify(mInterfaceConfiguration).setInterfaceDown(); - usbTeardownOrder.verify(mNMService).setInterfaceConfig( - IFACE_NAME, mInterfaceConfiguration); + 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( @@ -380,12 +389,15 @@ public class IpServerTest { public void usbShouldBeTornDownOnTetherError() throws Exception { initStateMachine(TETHERING_USB); - doThrow(RemoteException.class).when(mNMService).tetherInterface(IFACE_NAME); + doThrow(RemoteException.class).when(mNetd).tetherInterfaceAdd(IFACE_NAME); dispatchCommand(IpServer.CMD_TETHER_REQUESTED, STATE_TETHERED); - InOrder usbTeardownOrder = inOrder(mNMService, mInterfaceConfiguration, mCallback); - usbTeardownOrder.verify(mInterfaceConfiguration).setInterfaceDown(); - usbTeardownOrder.verify(mNMService).setInterfaceConfig( - IFACE_NAME, mInterfaceConfiguration); + 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( @@ -397,11 +409,13 @@ public class IpServerTest { public void shouldTearDownUsbOnUpstreamError() throws Exception { initTetheredStateMachine(TETHERING_USB, null); - doThrow(RemoteException.class).when(mNMService).enableNat(anyString(), anyString()); + doThrow(RemoteException.class).when(mNetd).tetherAddForward(anyString(), anyString()); dispatchTetherConnectionChanged(UPSTREAM_IFACE); - InOrder usbTeardownOrder = inOrder(mNMService, mInterfaceConfiguration, mCallback); - usbTeardownOrder.verify(mInterfaceConfiguration).setInterfaceDown(); - usbTeardownOrder.verify(mNMService).setInterfaceConfig(IFACE_NAME, mInterfaceConfiguration); + 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_NAT_ERROR); usbTeardownOrder.verify(mCallback).updateLinkProperties( @@ -413,11 +427,11 @@ public class IpServerTest { public void ignoresDuplicateUpstreamNotifications() throws Exception { initTetheredStateMachine(TETHERING_WIFI, UPSTREAM_IFACE); - verifyNoMoreInteractions(mNMService, mStatsService, mCallback); + verifyNoMoreInteractions(mNetd, mCallback); for (int i = 0; i < 5; i++) { dispatchTetherConnectionChanged(UPSTREAM_IFACE); - verifyNoMoreInteractions(mNMService, mStatsService, mCallback); + verifyNoMoreInteractions(mNetd, mCallback); } } @@ -525,4 +539,22 @@ public class IpServerTest { // 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/com/android/server/connectivity/tethering/EntitlementManagerTest.java b/packages/Tethering/tests/unit/src/com/android/server/connectivity/tethering/EntitlementManagerTest.java index 99cf9e90d912..4f0746199786 100644 --- a/packages/Tethering/tests/unit/src/com/android/server/connectivity/tethering/EntitlementManagerTest.java +++ b/packages/Tethering/tests/unit/src/com/android/server/connectivity/tethering/EntitlementManagerTest.java @@ -16,12 +16,13 @@ package com.android.server.connectivity.tethering; -import static android.net.ConnectivityManager.TETHERING_BLUETOOTH; -import static android.net.ConnectivityManager.TETHERING_USB; -import static android.net.ConnectivityManager.TETHERING_WIFI; -import static android.net.ConnectivityManager.TETHER_ERROR_ENTITLEMENT_UNKONWN; -import static android.net.ConnectivityManager.TETHER_ERROR_NO_ERROR; -import static android.net.ConnectivityManager.TETHER_ERROR_PROVISION_FAILED; +import static android.net.TetheringManager.TETHERING_BLUETOOTH; +import static android.net.TetheringManager.TETHERING_USB; +import static android.net.TetheringManager.TETHERING_WIFI; +import static android.net.TetheringManager.TETHER_ERROR_ENTITLEMENT_UNKONWN; +import static android.net.TetheringManager.TETHER_ERROR_NO_ERROR; +import static android.net.TetheringManager.TETHER_ERROR_PROVISION_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; @@ -39,7 +40,6 @@ import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; -import android.content.ContentResolver; import android.content.Context; import android.content.res.Resources; import android.net.util.SharedLog; @@ -49,18 +49,16 @@ import android.os.PersistableBundle; import android.os.ResultReceiver; import android.os.SystemProperties; import android.os.test.TestLooper; -import android.provider.Settings; +import android.provider.DeviceConfig; import android.telephony.CarrierConfigManager; -import android.test.mock.MockContentResolver; import androidx.test.filters.SmallTest; import androidx.test.runner.AndroidJUnit4; -import com.android.internal.R; import com.android.internal.util.State; import com.android.internal.util.StateMachine; import com.android.internal.util.test.BroadcastInterceptingContext; -import com.android.internal.util.test.FakeSettingsProvider; +import com.android.networkstack.tethering.R; import org.junit.After; import org.junit.Before; @@ -94,7 +92,6 @@ public final class EntitlementManagerTest { private final PersistableBundle mCarrierConfig = new PersistableBundle(); private final TestLooper mLooper = new TestLooper(); private Context mMockContext; - private MockContentResolver mContentResolver; private TestStateMachine mSM; private WrappedEntitlementManager mEnMgr; @@ -110,11 +107,6 @@ public final class EntitlementManagerTest { public Resources getResources() { return mResources; } - - @Override - public ContentResolver getContentResolver() { - return mContentResolver; - } } public class WrappedEntitlementManager extends EntitlementManager { @@ -151,28 +143,33 @@ public final class EntitlementManagerTest { MockitoAnnotations.initMocks(this); mMockingSession = mockitoSession() .initMocks(this) - .spyStatic(SystemProperties.class) + .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(false).when( + () -> DeviceConfig.getBoolean(eq(NAMESPACE_CONNECTIVITY), + eq(TetheringConfiguration.TETHER_ENABLE_LEGACY_DHCP_SERVER), anyBoolean())); when(mResources.getStringArray(R.array.config_tether_dhcp_range)) - .thenReturn(new String[0]); + .thenReturn(new String[0]); when(mResources.getStringArray(R.array.config_tether_usb_regexs)) - .thenReturn(new String[0]); + .thenReturn(new String[0]); when(mResources.getStringArray(R.array.config_tether_wifi_regexs)) - .thenReturn(new String[0]); + .thenReturn(new String[0]); when(mResources.getStringArray(R.array.config_tether_bluetooth_regexs)) - .thenReturn(new String[0]); + .thenReturn(new String[0]); when(mResources.getIntArray(R.array.config_tether_upstream_types)) - .thenReturn(new int[0]); + .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); - mContentResolver = new MockContentResolver(); - mContentResolver.addProvider(Settings.AUTHORITY, new FakeSettingsProvider()); mMockContext = new MockContext(mContext); mSM = new TestStateMachine(); mEnMgr = new WrappedEntitlementManager(mMockContext, mSM, mLog, EVENT_EM_UPDATE); diff --git a/packages/Tethering/tests/unit/src/com/android/server/connectivity/tethering/OffloadControllerTest.java b/packages/Tethering/tests/unit/src/com/android/server/connectivity/tethering/OffloadControllerTest.java index 7886ca6c132d..7e62e5aca993 100644 --- a/packages/Tethering/tests/unit/src/com/android/server/connectivity/tethering/OffloadControllerTest.java +++ b/packages/Tethering/tests/unit/src/com/android/server/connectivity/tethering/OffloadControllerTest.java @@ -16,21 +16,26 @@ package com.android.server.connectivity.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.STATS_PER_IFACE; -import static android.net.NetworkStats.STATS_PER_UID; 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.net.TrafficStats.UID_TETHERING; import static android.provider.Settings.Global.TETHER_OFFLOAD_DISABLED; +import static com.android.server.connectivity.tethering.OffloadController.StatsType.STATS_PER_IFACE; +import static com.android.server.connectivity.tethering.OffloadController.StatsType.STATS_PER_UID; import static com.android.server.connectivity.tethering.OffloadHardwareInterface.ForwardedStats; import static com.android.testutils.MiscAssertsKt.assertContainsAll; import static com.android.testutils.MiscAssertsKt.assertThrows; +import static com.android.testutils.NetworkStatsUtilsKt.orderInsensitiveEquals; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; +import static org.mockito.ArgumentMatchers.anyInt; import static org.mockito.Matchers.any; import static org.mockito.Matchers.anyLong; import static org.mockito.Matchers.anyObject; @@ -39,11 +44,14 @@ 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; @@ -51,10 +59,12 @@ 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.AbstractNetworkStatsProvider; +import android.net.netstats.provider.NetworkStatsProviderCallback; import android.net.util.SharedLog; import android.os.Handler; -import android.os.INetworkManagementService; import android.os.Looper; import android.provider.Settings; import android.provider.Settings.SettingNotFoundException; @@ -97,11 +107,13 @@ public class OffloadControllerTest { @Mock private OffloadHardwareInterface mHardware; @Mock private ApplicationInfo mApplicationInfo; @Mock private Context mContext; - @Mock private INetworkManagementService mNMService; + @Mock private NetworkStatsManager mStatsManager; + @Mock private NetworkStatsProviderCallback mTetherStatsProviderCb; private final ArgumentCaptor<ArrayList> mStringArrayCaptor = ArgumentCaptor.forClass(ArrayList.class); - private final ArgumentCaptor<ITetheringStatsProvider.Stub> mTetherStatsProviderCaptor = - ArgumentCaptor.forClass(ITetheringStatsProvider.Stub.class); + private final ArgumentCaptor<OffloadController.OffloadTetheringStatsProvider> + mTetherStatsProviderCaptor = + ArgumentCaptor.forClass(OffloadController.OffloadTetheringStatsProvider.class); private final ArgumentCaptor<OffloadHardwareInterface.ControlCallback> mControlCallbackCaptor = ArgumentCaptor.forClass(OffloadHardwareInterface.ControlCallback.class); private MockContentResolver mContentResolver; @@ -114,6 +126,8 @@ public class OffloadControllerTest { mContentResolver.addProvider(Settings.AUTHORITY, new FakeSettingsProvider()); when(mContext.getContentResolver()).thenReturn(mContentResolver); FakeSettingsProvider.clearSettingsProvider(); + when(mStatsManager.registerNetworkStatsProvider(anyString(), any())) + .thenReturn(mTetherStatsProviderCb); } @After public void tearDown() throws Exception { @@ -139,9 +153,9 @@ public class OffloadControllerTest { private OffloadController makeOffloadController() throws Exception { OffloadController offload = new OffloadController(new Handler(Looper.getMainLooper()), - mHardware, mContentResolver, mNMService, new SharedLog("test")); - verify(mNMService).registerTetheringStatsProvider( - mTetherStatsProviderCaptor.capture(), anyString()); + mHardware, mContentResolver, mStatsManager, new SharedLog("test")); + verify(mStatsManager).registerNetworkStatsProvider(anyString(), + mTetherStatsProviderCaptor.capture()); return offload; } @@ -384,12 +398,11 @@ public class OffloadControllerTest { inOrder.verifyNoMoreInteractions(); } - private void assertNetworkStats(String iface, ForwardedStats stats, NetworkStats.Entry entry) { - assertEquals(iface, entry.iface); - assertEquals(stats.rxBytes, entry.rxBytes); - assertEquals(stats.txBytes, entry.txBytes); - assertEquals(SET_DEFAULT, entry.set); - assertEquals(TAG_NONE, entry.tag); + 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 @@ -400,19 +413,16 @@ public class OffloadControllerTest { final OffloadController offload = makeOffloadController(); offload.start(); + final OffloadController.OffloadTetheringStatsProvider provider = + mTetherStatsProviderCaptor.getValue(); + final String ethernetIface = "eth1"; final String mobileIface = "rmnet_data0"; - ForwardedStats ethernetStats = new ForwardedStats(); - ethernetStats.rxBytes = 12345; - ethernetStats.txBytes = 54321; - - ForwardedStats mobileStats = new ForwardedStats(); - mobileStats.rxBytes = 999; - mobileStats.txBytes = 99999; - - when(mHardware.getForwardedStats(eq(ethernetIface))).thenReturn(ethernetStats); - when(mHardware.getForwardedStats(eq(mobileIface))).thenReturn(mobileStats); + when(mHardware.getForwardedStats(eq(ethernetIface))).thenReturn( + new ForwardedStats(12345, 54321)); + when(mHardware.getForwardedStats(eq(mobileIface))).thenReturn( + new ForwardedStats(999, 99999)); InOrder inOrder = inOrder(mHardware); @@ -432,10 +442,35 @@ public class OffloadControllerTest { // Expect that we fetch stats from the previous upstream. inOrder.verify(mHardware, times(1)).getForwardedStats(eq(mobileIface)); - ethernetStats = new ForwardedStats(); - ethernetStats.rxBytes = 100000; - ethernetStats.txBytes = 100000; - when(mHardware.getForwardedStats(eq(ethernetIface))).thenReturn(ethernetStats); + // Verify that the fetched stats are stored. + final NetworkStats ifaceStats = provider.getTetherStats(STATS_PER_IFACE); + final NetworkStats uidStats = provider.getTetherStats(STATS_PER_UID); + final NetworkStats expectedIfaceStats = new NetworkStats(0L, 2) + .addValues(buildTestEntry(STATS_PER_IFACE, mobileIface, 999, 99999)) + .addValues(buildTestEntry(STATS_PER_IFACE, ethernetIface, 12345, 54321)); + + final NetworkStats expectedUidStats = new NetworkStats(0L, 2) + .addValues(buildTestEntry(STATS_PER_UID, mobileIface, 999, 99999)) + .addValues(buildTestEntry(STATS_PER_UID, ethernetIface, 12345, 54321)); + + assertTrue(orderInsensitiveEquals(expectedIfaceStats, ifaceStats)); + assertTrue(orderInsensitiveEquals(expectedUidStats, uidStats)); + + final ArgumentCaptor<NetworkStats> ifaceStatsCaptor = ArgumentCaptor.forClass( + NetworkStats.class); + final ArgumentCaptor<NetworkStats> uidStatsCaptor = ArgumentCaptor.forClass( + NetworkStats.class); + + // Force pushing stats update to verify the stats reported. + provider.pushTetherStats(); + verify(mTetherStatsProviderCb, times(1)).onStatsUpdated(anyInt(), + ifaceStatsCaptor.capture(), uidStatsCaptor.capture()); + assertTrue(orderInsensitiveEquals(expectedIfaceStats, ifaceStatsCaptor.getValue())); + assertTrue(orderInsensitiveEquals(expectedUidStats, uidStatsCaptor.getValue())); + + + 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( @@ -443,37 +478,38 @@ public class OffloadControllerTest { // Expect that we fetch stats from the previous upstream. inOrder.verify(mHardware, times(1)).getForwardedStats(eq(ethernetIface)); - ITetheringStatsProvider provider = mTetherStatsProviderCaptor.getValue(); - NetworkStats stats = provider.getTetherStats(STATS_PER_IFACE); - NetworkStats perUidStats = provider.getTetherStats(STATS_PER_UID); - waitForIdle(); // There is no current upstream, so no stats are fetched. inOrder.verify(mHardware, never()).getForwardedStats(any()); inOrder.verifyNoMoreInteractions(); - assertEquals(2, stats.size()); - assertEquals(2, perUidStats.size()); - - NetworkStats.Entry entry = null; - for (int i = 0; i < stats.size(); i++) { - assertEquals(UID_ALL, stats.getValues(i, entry).uid); - assertEquals(UID_TETHERING, perUidStats.getValues(i, entry).uid); - } - - int ethernetPosition = ethernetIface.equals(stats.getValues(0, entry).iface) ? 0 : 1; - int mobilePosition = 1 - ethernetPosition; - - entry = stats.getValues(mobilePosition, entry); - assertNetworkStats(mobileIface, mobileStats, entry); - entry = perUidStats.getValues(mobilePosition, entry); - assertNetworkStats(mobileIface, mobileStats, entry); - - ethernetStats.rxBytes = 12345 + 100000; - ethernetStats.txBytes = 54321 + 100000; - entry = stats.getValues(ethernetPosition, entry); - assertNetworkStats(ethernetIface, ethernetStats, entry); - entry = perUidStats.getValues(ethernetPosition, entry); - assertNetworkStats(ethernetIface, ethernetStats, entry); + // Verify that the stored stats is accumulated. + final NetworkStats ifaceStatsAccu = provider.getTetherStats(STATS_PER_IFACE); + final NetworkStats uidStatsAccu = provider.getTetherStats(STATS_PER_UID); + final NetworkStats expectedIfaceStatsAccu = new NetworkStats(0L, 2) + .addValues(buildTestEntry(STATS_PER_IFACE, mobileIface, 999, 99999)) + .addValues(buildTestEntry(STATS_PER_IFACE, ethernetIface, 112345, 154321)); + + final NetworkStats expectedUidStatsAccu = new NetworkStats(0L, 2) + .addValues(buildTestEntry(STATS_PER_UID, mobileIface, 999, 99999)) + .addValues(buildTestEntry(STATS_PER_UID, ethernetIface, 112345, 154321)); + + assertTrue(orderInsensitiveEquals(expectedIfaceStatsAccu, ifaceStatsAccu)); + assertTrue(orderInsensitiveEquals(expectedUidStatsAccu, uidStatsAccu)); + + // Verify that only diff of stats is reported. + reset(mTetherStatsProviderCb); + provider.pushTetherStats(); + final NetworkStats expectedIfaceStatsDiff = new NetworkStats(0L, 2) + .addValues(buildTestEntry(STATS_PER_IFACE, mobileIface, 0, 0)) + .addValues(buildTestEntry(STATS_PER_IFACE, ethernetIface, 100000, 100000)); + + final NetworkStats expectedUidStatsDiff = new NetworkStats(0L, 2) + .addValues(buildTestEntry(STATS_PER_UID, mobileIface, 0, 0)) + .addValues(buildTestEntry(STATS_PER_UID, ethernetIface, 100000, 100000)); + verify(mTetherStatsProviderCb, times(1)).onStatsUpdated(anyInt(), + ifaceStatsCaptor.capture(), uidStatsCaptor.capture()); + assertTrue(orderInsensitiveEquals(expectedIfaceStatsDiff, ifaceStatsCaptor.getValue())); + assertTrue(orderInsensitiveEquals(expectedUidStatsDiff, uidStatsCaptor.getValue())); } @Test @@ -493,19 +529,19 @@ public class OffloadControllerTest { lp.setInterfaceName(ethernetIface); offload.setUpstreamLinkProperties(lp); - ITetheringStatsProvider provider = mTetherStatsProviderCaptor.getValue(); + AbstractNetworkStatsProvider provider = mTetherStatsProviderCaptor.getValue(); 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. - provider.setInterfaceQuota(ethernetIface, ethernetLimit); + provider.setLimit(ethernetIface, ethernetLimit); waitForIdle(); inOrder.verify(mHardware).setDataLimit(ethernetIface, ethernetLimit); inOrder.verifyNoMoreInteractions(); // Applying an interface quota to another upstream does not take any immediate action. - provider.setInterfaceQuota(mobileIface, mobileLimit); + provider.setLimit(mobileIface, mobileLimit); waitForIdle(); inOrder.verify(mHardware, never()).setDataLimit(anyString(), anyLong()); @@ -518,7 +554,7 @@ public class OffloadControllerTest { // Setting a limit of ITetheringStatsProvider.QUOTA_UNLIMITED causes the limit to be set // to Long.MAX_VALUE. - provider.setInterfaceQuota(mobileIface, ITetheringStatsProvider.QUOTA_UNLIMITED); + provider.setLimit(mobileIface, ITetheringStatsProvider.QUOTA_UNLIMITED); waitForIdle(); inOrder.verify(mHardware).setDataLimit(mobileIface, Long.MAX_VALUE); @@ -526,7 +562,7 @@ public class OffloadControllerTest { when(mHardware.setUpstreamParameters(any(), any(), any(), any())).thenReturn(false); lp.setInterfaceName(ethernetIface); offload.setUpstreamLinkProperties(lp); - provider.setInterfaceQuota(mobileIface, mobileLimit); + provider.setLimit(mobileIface, mobileLimit); waitForIdle(); inOrder.verify(mHardware, never()).setDataLimit(anyString(), anyLong()); @@ -535,7 +571,7 @@ public class OffloadControllerTest { when(mHardware.setDataLimit(anyString(), anyLong())).thenReturn(false); lp.setInterfaceName(mobileIface); offload.setUpstreamLinkProperties(lp); - provider.setInterfaceQuota(mobileIface, mobileLimit); + provider.setLimit(mobileIface, mobileLimit); waitForIdle(); inOrder.verify(mHardware).getForwardedStats(ethernetIface); inOrder.verify(mHardware).stopOffloadControl(); @@ -551,7 +587,7 @@ public class OffloadControllerTest { OffloadHardwareInterface.ControlCallback callback = mControlCallbackCaptor.getValue(); callback.onStoppedLimitReached(); - verify(mNMService, times(1)).tetherLimitReached(mTetherStatsProviderCaptor.getValue()); + verify(mTetherStatsProviderCb, times(1)).onStatsUpdated(anyInt(), any(), any()); } @Test @@ -654,9 +690,10 @@ public class OffloadControllerTest { // Verify forwarded stats behaviour. verify(mHardware, times(1)).getForwardedStats(eq(RMNET0)); verify(mHardware, times(1)).getForwardedStats(eq(WLAN0)); + // TODO: verify the exact stats reported. + verify(mTetherStatsProviderCb, times(1)).onStatsUpdated(anyInt(), any(), any()); + verifyNoMoreInteractions(mTetherStatsProviderCb); verifyNoMoreInteractions(mHardware); - verify(mNMService, times(1)).tetherLimitReached(mTetherStatsProviderCaptor.getValue()); - verifyNoMoreInteractions(mNMService); } @Test @@ -719,8 +756,8 @@ public class OffloadControllerTest { // Verify forwarded stats behaviour. verify(mHardware, times(1)).getForwardedStats(eq(RMNET0)); verify(mHardware, times(1)).getForwardedStats(eq(WLAN0)); - verify(mNMService, times(1)).tetherLimitReached(mTetherStatsProviderCaptor.getValue()); - verifyNoMoreInteractions(mNMService); + verify(mTetherStatsProviderCb, times(1)).onStatsUpdated(anyInt(), any(), any()); + verifyNoMoreInteractions(mTetherStatsProviderCb); // TODO: verify local prefixes and downstreams are also pushed to the HAL. verify(mHardware, times(1)).setLocalPrefixes(mStringArrayCaptor.capture()); diff --git a/packages/Tethering/tests/unit/src/com/android/server/connectivity/tethering/TetheringConfigurationTest.java b/packages/Tethering/tests/unit/src/com/android/server/connectivity/tethering/TetheringConfigurationTest.java index 7799da4b94a7..3635964dd6a6 100644 --- a/packages/Tethering/tests/unit/src/com/android/server/connectivity/tethering/TetheringConfigurationTest.java +++ b/packages/Tethering/tests/unit/src/com/android/server/connectivity/tethering/TetheringConfigurationTest.java @@ -21,40 +21,38 @@ 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.Settings.Global.TETHER_ENABLE_LEGACY_DHCP_SERVER; +import static android.provider.DeviceConfig.NAMESPACE_CONNECTIVITY; import static android.telephony.SubscriptionManager.INVALID_SUBSCRIPTION_ID; -import static com.android.internal.R.array.config_mobile_hotspot_provision_app; -import static com.android.internal.R.array.config_tether_bluetooth_regexs; -import static com.android.internal.R.array.config_tether_dhcp_range; -import static com.android.internal.R.array.config_tether_upstream_types; -import static com.android.internal.R.array.config_tether_usb_regexs; -import static com.android.internal.R.array.config_tether_wifi_regexs; +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.eq; import static org.mockito.Mockito.when; -import android.content.ContentResolver; import android.content.Context; import android.content.res.Resources; import android.net.util.SharedLog; -import android.provider.Settings; +import android.provider.DeviceConfig; import android.telephony.TelephonyManager; -import android.test.mock.MockContentResolver; import androidx.test.filters.SmallTest; import androidx.test.runner.AndroidJUnit4; import com.android.internal.util.test.BroadcastInterceptingContext; -import com.android.internal.util.test.FakeSettingsProvider; +import com.android.networkstack.tethering.R; +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 org.mockito.MockitoSession; +import org.mockito.quality.Strictness; import java.util.Arrays; import java.util.Iterator; @@ -69,9 +67,10 @@ public class TetheringConfigurationTest { @Mock private TelephonyManager mTelephonyManager; @Mock private Resources mResources; @Mock private Resources mResourcesForSubId; - private MockContentResolver mContentResolver; private Context mMockContext; private boolean mHasTelephonyManager; + private boolean mEnableLegacyDhcpServer; + private MockitoSession mMockingSession; private class MockTetheringConfiguration extends TetheringConfiguration { MockTetheringConfiguration(Context ctx, SharedLog log, int id) { @@ -101,32 +100,44 @@ public class TetheringConfigurationTest { } return super.getSystemService(name); } - - @Override - public ContentResolver getContentResolver() { - return mContentResolver; - } } @Before public void setUp() throws Exception { - MockitoAnnotations.initMocks(this); - when(mResources.getStringArray(config_tether_dhcp_range)).thenReturn(new String[0]); - when(mResources.getStringArray(config_tether_usb_regexs)).thenReturn(new String[0]); - when(mResources.getStringArray(config_tether_wifi_regexs)) + // TODO: use a dependencies class instead of mock statics. + mMockingSession = mockitoSession() + .initMocks(this) + .mockStatic(DeviceConfig.class) + .strictness(Strictness.WARN) + .startMocking(); + doReturn(false).when( + () -> DeviceConfig.getBoolean(eq(NAMESPACE_CONNECTIVITY), + eq(TetheringConfiguration.TETHER_ENABLE_LEGACY_DHCP_SERVER), anyBoolean())); + + 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[]{ "test_wlan\\d" }); - when(mResources.getStringArray(config_tether_bluetooth_regexs)).thenReturn(new String[0]); - when(mResources.getIntArray(config_tether_upstream_types)).thenReturn(new int[0]); - when(mResources.getStringArray(config_mobile_hotspot_provision_app)) + 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]); - mContentResolver = new MockContentResolver(); - mContentResolver.addProvider(Settings.AUTHORITY, new FakeSettingsProvider()); + when(mResources.getBoolean(R.bool.config_tether_enable_legacy_dhcp_server)).thenReturn( + false); mHasTelephonyManager = true; mMockContext = new MockContext(mContext); + mEnableLegacyDhcpServer = false; + } + + @After + public void tearDown() throws Exception { + mMockingSession.finishMocking(); } private TetheringConfiguration getTetheringConfiguration(int... legacyTetherUpstreamTypes) { - when(mResources.getIntArray(config_tether_upstream_types)).thenReturn( + when(mResources.getIntArray(R.array.config_tether_upstream_types)).thenReturn( legacyTetherUpstreamTypes); return new TetheringConfiguration(mMockContext, mLog, INVALID_SUBSCRIPTION_ID); } @@ -210,7 +221,7 @@ public class TetheringConfigurationTest { @Test public void testNoDefinedUpstreamTypesAddsEthernet() { - when(mResources.getIntArray(config_tether_upstream_types)).thenReturn(new int[]{}); + when(mResources.getIntArray(R.array.config_tether_upstream_types)).thenReturn(new int[]{}); when(mTelephonyManager.isTetheringApnRequired()).thenReturn(false); final TetheringConfiguration cfg = new TetheringConfiguration( @@ -232,7 +243,7 @@ public class TetheringConfigurationTest { @Test public void testDefinedUpstreamTypesSansEthernetAddsEthernet() { - when(mResources.getIntArray(config_tether_upstream_types)).thenReturn( + when(mResources.getIntArray(R.array.config_tether_upstream_types)).thenReturn( new int[]{TYPE_WIFI, TYPE_MOBILE_HIPRI}); when(mTelephonyManager.isTetheringApnRequired()).thenReturn(false); @@ -250,7 +261,7 @@ public class TetheringConfigurationTest { @Test public void testDefinedUpstreamTypesWithEthernetDoesNotAddEthernet() { - when(mResources.getIntArray(config_tether_upstream_types)) + when(mResources.getIntArray(R.array.config_tether_upstream_types)) .thenReturn(new int[]{TYPE_WIFI, TYPE_ETHERNET, TYPE_MOBILE_HIPRI}); when(mTelephonyManager.isTetheringApnRequired()).thenReturn(false); @@ -268,19 +279,38 @@ public class TetheringConfigurationTest { @Test public void testNewDhcpServerDisabled() { - Settings.Global.putInt(mContentResolver, TETHER_ENABLE_LEGACY_DHCP_SERVER, 1); - - final TetheringConfiguration cfg = new TetheringConfiguration( - mMockContext, mLog, INVALID_SUBSCRIPTION_ID); - assertTrue(cfg.enableLegacyDhcpServer); + when(mResources.getBoolean(R.bool.config_tether_enable_legacy_dhcp_server)).thenReturn( + true); + doReturn(false).when( + () -> DeviceConfig.getBoolean(eq(NAMESPACE_CONNECTIVITY), + eq(TetheringConfiguration.TETHER_ENABLE_LEGACY_DHCP_SERVER), anyBoolean())); + + 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.getBoolean(eq(NAMESPACE_CONNECTIVITY), + eq(TetheringConfiguration.TETHER_ENABLE_LEGACY_DHCP_SERVER), anyBoolean())); + + final TetheringConfiguration enableByDevConfig = + new TetheringConfiguration(mMockContext, mLog, INVALID_SUBSCRIPTION_ID); + assertTrue(enableByDevConfig.enableLegacyDhcpServer); } @Test public void testNewDhcpServerEnabled() { - Settings.Global.putInt(mContentResolver, TETHER_ENABLE_LEGACY_DHCP_SERVER, 0); + when(mResources.getBoolean(R.bool.config_tether_enable_legacy_dhcp_server)).thenReturn( + false); + doReturn(false).when( + () -> DeviceConfig.getBoolean(eq(NAMESPACE_CONNECTIVITY), + eq(TetheringConfiguration.TETHER_ENABLE_LEGACY_DHCP_SERVER), anyBoolean())); + + final TetheringConfiguration cfg = + new TetheringConfiguration(mMockContext, mLog, INVALID_SUBSCRIPTION_ID); - final TetheringConfiguration cfg = new TetheringConfiguration( - mMockContext, mLog, INVALID_SUBSCRIPTION_ID); assertFalse(cfg.enableLegacyDhcpServer); } @@ -299,16 +329,17 @@ public class TetheringConfigurationTest { private void setUpResourceForSubId() { when(mResourcesForSubId.getStringArray( - config_tether_dhcp_range)).thenReturn(new String[0]); + R.array.config_tether_dhcp_range)).thenReturn(new String[0]); when(mResourcesForSubId.getStringArray( - config_tether_usb_regexs)).thenReturn(new String[0]); + R.array.config_tether_usb_regexs)).thenReturn(new String[0]); when(mResourcesForSubId.getStringArray( - config_tether_wifi_regexs)).thenReturn(new String[]{ "test_wlan\\d" }); + R.array.config_tether_wifi_regexs)).thenReturn(new String[]{ "test_wlan\\d" }); when(mResourcesForSubId.getStringArray( - config_tether_bluetooth_regexs)).thenReturn(new String[0]); - when(mResourcesForSubId.getIntArray(config_tether_upstream_types)).thenReturn(new int[0]); + 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( - config_mobile_hotspot_provision_app)).thenReturn(PROVISIONING_APP_NAME); + R.array.config_mobile_hotspot_provision_app)).thenReturn(PROVISIONING_APP_NAME); } } diff --git a/packages/Tethering/tests/unit/src/com/android/server/connectivity/tethering/TetheringTest.java b/packages/Tethering/tests/unit/src/com/android/server/connectivity/tethering/TetheringTest.java index 809f0e994737..affd69154b70 100644 --- a/packages/Tethering/tests/unit/src/com/android/server/connectivity/tethering/TetheringTest.java +++ b/packages/Tethering/tests/unit/src/com/android/server/connectivity/tethering/TetheringTest.java @@ -19,16 +19,18 @@ package com.android.server.connectivity.tethering; import static android.hardware.usb.UsbManager.USB_CONFIGURED; import static android.hardware.usb.UsbManager.USB_CONNECTED; import static android.hardware.usb.UsbManager.USB_FUNCTION_RNDIS; -import static android.net.ConnectivityManager.ACTION_TETHER_STATE_CHANGED; -import static android.net.ConnectivityManager.EXTRA_ACTIVE_LOCAL_ONLY; -import static android.net.ConnectivityManager.EXTRA_ACTIVE_TETHER; -import static android.net.ConnectivityManager.EXTRA_AVAILABLE_TETHER; -import static android.net.ConnectivityManager.TETHERING_USB; -import static android.net.ConnectivityManager.TETHERING_WIFI; -import static android.net.ConnectivityManager.TETHER_ERROR_NO_ERROR; -import static android.net.ConnectivityManager.TETHER_ERROR_UNKNOWN_IFACE; -import static android.net.ConnectivityManager.TYPE_WIFI_P2P; +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_USB; +import static android.net.TetheringManager.TETHERING_WIFI; +import static android.net.TetheringManager.TETHER_ERROR_NO_ERROR; +import static android.net.TetheringManager.TETHER_ERROR_UNKNOWN_IFACE; 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; @@ -36,7 +38,6 @@ 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.provider.Settings.Global.TETHER_ENABLE_LEGACY_DHCP_SERVER; import static android.telephony.SubscriptionManager.INVALID_SUBSCRIPTION_ID; import static org.junit.Assert.assertArrayEquals; @@ -50,10 +51,10 @@ 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.atLeastOnce; 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; @@ -61,6 +62,8 @@ 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; @@ -69,19 +72,17 @@ import android.content.IntentFilter; import android.content.pm.ApplicationInfo; import android.content.res.Resources; import android.hardware.usb.UsbManager; +import android.net.ConnectivityManager; import android.net.INetd; -import android.net.INetworkPolicyManager; -import android.net.INetworkStatsService; import android.net.ITetheringEventCallback; import android.net.InetAddresses; -import android.net.InterfaceConfiguration; +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.NetworkInfo; import android.net.NetworkRequest; import android.net.RouteInfo; import android.net.TetherStatesParcel; @@ -101,7 +102,6 @@ import android.net.wifi.p2p.WifiP2pInfo; import android.net.wifi.p2p.WifiP2pManager; import android.os.Bundle; import android.os.Handler; -import android.os.INetworkManagementService; import android.os.Looper; import android.os.PersistableBundle; import android.os.RemoteException; @@ -122,6 +122,7 @@ 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.networkstack.tethering.R; import org.junit.After; import org.junit.Before; @@ -135,6 +136,7 @@ import java.net.Inet4Address; import java.net.Inet6Address; import java.util.ArrayList; import java.util.Arrays; +import java.util.Collection; import java.util.Vector; @RunWith(AndroidJUnit4.class) @@ -147,14 +149,13 @@ public class TetheringTest { private static final String TEST_USB_IFNAME = "test_rndis0"; private static final String TEST_WLAN_IFNAME = "test_wlan0"; private static final String TEST_P2P_IFNAME = "test_p2p-p2p0-0"; + private static final String TETHERING_NAME = "Tethering"; private static final int DHCPSERVER_START_TIMEOUT_MS = 1000; @Mock private ApplicationInfo mApplicationInfo; @Mock private Context mContext; - @Mock private INetworkManagementService mNMService; - @Mock private INetworkStatsService mStatsService; - @Mock private INetworkPolicyManager mPolicyManager; + @Mock private NetworkStatsManager mStatsManager; @Mock private OffloadHardwareInterface mOffloadHardwareInterface; @Mock private Resources mResources; @Mock private TelephonyManager mTelephonyManager; @@ -168,6 +169,7 @@ public class TetheringTest { @Mock private INetd mNetd; @Mock private UserManager mUserManager; @Mock private NetworkRequest mNetworkRequest; + @Mock private ConnectivityManager mCm; private final MockIpServerDependencies mIpServerDependencies = spy(new MockIpServerDependencies()); @@ -185,6 +187,7 @@ public class TetheringTest { private BroadcastReceiver mBroadcastReceiver; private Tethering mTethering; private PhoneStateListener mPhoneStateListener; + private InterfaceConfigurationParcel mInterfaceConfiguration; private class TestContext extends BroadcastInterceptingContext { TestContext(Context base) { @@ -217,6 +220,8 @@ public class TetheringTest { 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; return super.getSystemService(name); } @@ -225,6 +230,11 @@ public class TetheringTest { if (TelephonyManager.class.equals(serviceClass)) return Context.TELEPHONY_SERVICE; return super.getSystemServiceName(serviceClass); } + + @Override + public Context createContextAsUser(UserHandle user, int flags) { + return mContext; + } } public class MockIpServerDependencies extends IpServer.Dependencies { @@ -248,11 +258,6 @@ public class TetheringTest { } @Override - public INetd getNetdService() { - return mNetd; - } - - @Override public void makeDhcpServer(String ifName, DhcpServingParamsParcel params, DhcpServerCallbacks cb) { new Thread(() -> { @@ -271,6 +276,11 @@ public class TetheringTest { } @Override + protected boolean getDeviceConfigBoolean(final String name) { + return false; + } + + @Override protected Resources getResourcesForSubIdWrapper(Context ctx, int subId) { return mResources; } @@ -329,21 +339,6 @@ public class TetheringTest { } @Override - public INetworkManagementService getINetworkManagementService() { - return mNMService; - } - - @Override - public INetworkStatsService getINetworkStatsService() { - return mStatsService; - } - - @Override - public INetworkPolicyManager getINetworkPolicyManager() { - return mPolicyManager; - } - - @Override public INetd getINetd(Context context) { return mNetd; } @@ -357,6 +352,12 @@ public class TetheringTest { public Context getContext() { return mServiceContext; } + + @Override + public BluetoothAdapter getBluetoothAdapter() { + // TODO: add test for bluetooth tethering. + return null; + } } private static UpstreamNetworkState buildMobileUpstreamState(boolean withIPv4, @@ -415,32 +416,33 @@ public class TetheringTest { @Before public void setUp() throws Exception { MockitoAnnotations.initMocks(this); - when(mResources.getStringArray(com.android.internal.R.array.config_tether_dhcp_range)) + when(mResources.getStringArray(R.array.config_tether_dhcp_range)) .thenReturn(new String[0]); - when(mResources.getStringArray(com.android.internal.R.array.config_tether_usb_regexs)) + when(mResources.getStringArray(R.array.config_tether_usb_regexs)) .thenReturn(new String[] { "test_rndis\\d" }); - when(mResources.getStringArray(com.android.internal.R.array.config_tether_wifi_regexs)) + when(mResources.getStringArray(R.array.config_tether_wifi_regexs)) .thenReturn(new String[]{ "test_wlan\\d" }); - when(mResources.getStringArray(com.android.internal.R.array.config_tether_wifi_p2p_regexs)) + when(mResources.getStringArray(R.array.config_tether_wifi_p2p_regexs)) .thenReturn(new String[]{ "test_p2p-p2p\\d-.*" }); - when(mResources.getStringArray(com.android.internal.R.array.config_tether_bluetooth_regexs)) + when(mResources.getStringArray(R.array.config_tether_bluetooth_regexs)) .thenReturn(new String[0]); - when(mResources.getIntArray(com.android.internal.R.array.config_tether_upstream_types)) - .thenReturn(new int[0]); - when(mResources.getBoolean(com.android.internal.R.bool.config_tether_upstream_automatic)) - .thenReturn(false); - when(mNMService.listInterfaces()) + when(mResources.getIntArray(R.array.config_tether_upstream_types)).thenReturn(new int[0]); + when(mResources.getBoolean(R.bool.config_tether_upstream_automatic)).thenReturn(false); + 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}); - when(mNMService.getInterfaceConfig(anyString())) - .thenReturn(new InterfaceConfiguration()); + when(mResources.getString(R.string.config_wifi_tether_enable)).thenReturn(""); + mInterfaceConfiguration = new InterfaceConfigurationParcel(); + mInterfaceConfiguration.flags = new String[0]; when(mRouterAdvertisementDaemon.start()) .thenReturn(true); mServiceContext = new TestContext(mContext); + when(mContext.getSystemService(Context.NOTIFICATION_SERVICE)).thenReturn(null); mContentResolver = new MockContentResolver(mServiceContext); mContentResolver.addProvider(Settings.AUTHORITY, new FakeSettingsProvider()); - Settings.Global.putInt(mContentResolver, TETHER_ENABLE_LEGACY_DHCP_SERVER, 0); mIntents = new Vector<>(); mBroadcastReceiver = new BroadcastReceiver() { @Override @@ -451,7 +453,7 @@ public class TetheringTest { mServiceContext.registerReceiver(mBroadcastReceiver, new IntentFilter(ACTION_TETHER_STATE_CHANGED)); mTethering = makeTethering(); - verify(mNMService).registerTetheringStatsProvider(any(), anyString()); + verify(mStatsManager, times(1)).registerNetworkStatsProvider(anyString(), any()); verify(mNetd).registerUnsolicitedEventListener(any()); final ArgumentCaptor<PhoneStateListener> phoneListenerCaptor = ArgumentCaptor.forClass(PhoneStateListener.class); @@ -491,20 +493,21 @@ public class TetheringTest { private void sendWifiP2pConnectionChanged( boolean isGroupFormed, boolean isGroupOwner, String ifname) { + WifiP2pGroup group = null; WifiP2pInfo p2pInfo = new WifiP2pInfo(); p2pInfo.groupFormed = isGroupFormed; - p2pInfo.isGroupOwner = isGroupOwner; - - NetworkInfo networkInfo = new NetworkInfo(TYPE_WIFI_P2P, 0, null, null); + if (isGroupFormed) { + p2pInfo.isGroupOwner = isGroupOwner; + group = mock(WifiP2pGroup.class); + when(group.isGroupOwner()).thenReturn(isGroupOwner); + when(group.getInterface()).thenReturn(ifname); + } - WifiP2pGroup group = new WifiP2pGroup(); - group.setIsGroupOwner(isGroupOwner); - group.setInterface(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); - final Intent intent = new Intent(WifiP2pManager.WIFI_P2P_CONNECTION_CHANGED_ACTION); - intent.putExtra(WifiP2pManager.EXTRA_WIFI_P2P_INFO, p2pInfo); - intent.putExtra(WifiP2pManager.EXTRA_NETWORK_INFO, networkInfo); - intent.putExtra(WifiP2pManager.EXTRA_WIFI_P2P_GROUP, group); mServiceContext.sendBroadcastAsUserMultiplePermissions(intent, UserHandle.ALL, P2P_RECEIVER_PERMISSIONS_FOR_BROADCAST); } @@ -523,10 +526,11 @@ public class TetheringTest { } private void verifyInterfaceServingModeStarted(String ifname) throws Exception { - verify(mNMService, times(1)).getInterfaceConfig(ifname); - verify(mNMService, times(1)) - .setInterfaceConfig(eq(ifname), any(InterfaceConfiguration.class)); - verify(mNMService, times(1)).tetherInterface(ifname); + 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) { @@ -558,7 +562,7 @@ public class TetheringTest { verify(mWifiManager).updateInterfaceIpState( TEST_WLAN_IFNAME, WifiManager.IFACE_IP_MODE_UNSPECIFIED); } - verifyNoMoreInteractions(mNMService); + verifyNoMoreInteractions(mNetd); verifyNoMoreInteractions(mWifiManager); } @@ -581,14 +585,14 @@ public class TetheringTest { prepareUsbTethering(upstreamState); // This should produce no activity of any kind. - verifyNoMoreInteractions(mNMService); + verifyNoMoreInteractions(mNetd); // Pretend we then receive USB configured broadcast. sendUsbBroadcast(true, true, true); mLooper.dispatchAll(); // Now we should see the start of tethering mechanics (in this case: // tetherMatchingInterfaces() which starts by fetching all interfaces). - verify(mNMService, times(1)).listInterfaces(); + verify(mNetd, times(1)).interfaceGetList(); // UpstreamNetworkMonitor should receive selected upstream verify(mUpstreamNetworkMonitor, times(1)).selectPreferredUpstreamType(any()); @@ -618,9 +622,9 @@ public class TetheringTest { verifyInterfaceServingModeStarted(TEST_WLAN_IFNAME); verifyTetheringBroadcast(TEST_WLAN_IFNAME, EXTRA_AVAILABLE_TETHER); - verify(mNMService, times(1)).setIpForwardingEnabled(true); - verify(mNMService, times(1)).startTethering(any(String[].class)); - verifyNoMoreInteractions(mNMService); + 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( @@ -638,16 +642,16 @@ public class TetheringTest { mTethering.interfaceRemoved(TEST_WLAN_IFNAME); mLooper.dispatchAll(); - verify(mNMService, times(1)).untetherInterface(TEST_WLAN_IFNAME); - // {g,s}etInterfaceConfig() called twice for enabling and disabling IPv4. - verify(mNMService, times(2)).getInterfaceConfig(TEST_WLAN_IFNAME); - verify(mNMService, times(2)) - .setInterfaceConfig(eq(TEST_WLAN_IFNAME), any(InterfaceConfiguration.class)); - verify(mNMService, times(1)).stopTethering(); - verify(mNMService, times(1)).setIpForwardingEnabled(false); + 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(mNMService); + verifyNoMoreInteractions(mNetd); verifyNoMoreInteractions(mWifiManager); // Asking for the last error after the per-interface state machine // has been reaped yields an unknown interface error. @@ -684,8 +688,8 @@ public class TetheringTest { UpstreamNetworkState upstreamState = buildMobileIPv4UpstreamState(); runUsbTethering(upstreamState); - verify(mNMService, times(1)).enableNat(TEST_USB_IFNAME, TEST_MOBILE_IFNAME); - verify(mNMService, times(1)).startInterfaceForwarding(TEST_USB_IFNAME, TEST_MOBILE_IFNAME); + 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()); @@ -694,7 +698,8 @@ public class TetheringTest { @Test public void workingMobileUsbTethering_IPv4LegacyDhcp() { - Settings.Global.putInt(mContentResolver, TETHER_ENABLE_LEGACY_DHCP_SERVER, 1); + when(mResources.getBoolean(R.bool.config_tether_enable_legacy_dhcp_server)).thenReturn( + true); sendConfigurationChanged(); final UpstreamNetworkState upstreamState = buildMobileIPv4UpstreamState(); runUsbTethering(upstreamState); @@ -708,8 +713,8 @@ public class TetheringTest { UpstreamNetworkState upstreamState = buildMobileIPv6UpstreamState(); runUsbTethering(upstreamState); - verify(mNMService, times(1)).enableNat(TEST_USB_IFNAME, TEST_MOBILE_IFNAME); - verify(mNMService, times(1)).startInterfaceForwarding(TEST_USB_IFNAME, TEST_MOBILE_IFNAME); + 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()); @@ -721,8 +726,8 @@ public class TetheringTest { UpstreamNetworkState upstreamState = buildMobileDualStackUpstreamState(); runUsbTethering(upstreamState); - verify(mNMService, times(1)).enableNat(TEST_USB_IFNAME, TEST_MOBILE_IFNAME); - verify(mNMService, times(1)).startInterfaceForwarding(TEST_USB_IFNAME, TEST_MOBILE_IFNAME); + 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)).start(any()); @@ -736,12 +741,11 @@ public class TetheringTest { UpstreamNetworkState upstreamState = buildMobile464xlatUpstreamState(); runUsbTethering(upstreamState); - verify(mNMService, times(1)).enableNat(TEST_USB_IFNAME, TEST_XLAT_MOBILE_IFNAME); - verify(mNMService, times(1)).enableNat(TEST_USB_IFNAME, TEST_MOBILE_IFNAME); + 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)).start(any()); - verify(mNMService, times(1)).startInterfaceForwarding(TEST_USB_IFNAME, TEST_MOBILE_IFNAME); - verify(mNMService, times(1)).startInterfaceForwarding(TEST_USB_IFNAME, - TEST_XLAT_MOBILE_IFNAME); + 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()); @@ -754,9 +758,9 @@ public class TetheringTest { UpstreamNetworkState upstreamState = buildMobileIPv6UpstreamState(); runUsbTethering(upstreamState); - verify(mNMService, times(1)).enableNat(TEST_USB_IFNAME, TEST_MOBILE_IFNAME); + verify(mNetd, times(1)).tetherAddForward(TEST_USB_IFNAME, TEST_MOBILE_IFNAME); verify(mDhcpServer, timeout(DHCPSERVER_START_TIMEOUT_MS).times(1)).start(any()); - verify(mNMService, times(1)).startInterfaceForwarding(TEST_USB_IFNAME, TEST_MOBILE_IFNAME); + verify(mNetd, times(1)).ipfwdAddInterfaceForward(TEST_USB_IFNAME, TEST_MOBILE_IFNAME); // Then 464xlat comes up upstreamState = buildMobile464xlatUpstreamState(); @@ -772,20 +776,18 @@ public class TetheringTest { mLooper.dispatchAll(); // Forwarding is added for 464xlat - verify(mNMService, times(1)).enableNat(TEST_USB_IFNAME, TEST_XLAT_MOBILE_IFNAME); - verify(mNMService, times(1)).startInterfaceForwarding(TEST_USB_IFNAME, - TEST_XLAT_MOBILE_IFNAME); + 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(mNMService, times(1)).enableNat(TEST_USB_IFNAME, TEST_MOBILE_IFNAME); - verify(mNMService, times(1)).startInterfaceForwarding(TEST_USB_IFNAME, TEST_MOBILE_IFNAME); + 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)).start(any()); } @Test public void configTetherUpstreamAutomaticIgnoresConfigTetherUpstreamTypes() throws Exception { - when(mResources.getBoolean(com.android.internal.R.bool.config_tether_upstream_automatic)) - .thenReturn(true); + when(mResources.getBoolean(R.bool.config_tether_upstream_automatic)).thenReturn(true); sendConfigurationChanged(); // Setup IPv6 @@ -820,7 +822,7 @@ public class TetheringTest { mLooper.dispatchAll(); verify(mWifiManager, times(1)).startSoftAp(null); verifyNoMoreInteractions(mWifiManager); - verifyNoMoreInteractions(mNMService); + verifyNoMoreInteractions(mNetd); // Emulate externally-visible WifiManager effects, causing the // per-interface state machine to start up, and telling us that @@ -833,7 +835,7 @@ public class TetheringTest { verifyTetheringBroadcast(TEST_WLAN_IFNAME, EXTRA_AVAILABLE_TETHER); verify(mWifiManager).updateInterfaceIpState( TEST_WLAN_IFNAME, WifiManager.IFACE_IP_MODE_UNSPECIFIED); - verifyNoMoreInteractions(mNMService); + verifyNoMoreInteractions(mNetd); verifyNoMoreInteractions(mWifiManager); } @@ -847,7 +849,7 @@ public class TetheringTest { mLooper.dispatchAll(); verify(mWifiManager, times(1)).startSoftAp(null); verifyNoMoreInteractions(mWifiManager); - verifyNoMoreInteractions(mNMService); + verifyNoMoreInteractions(mNetd); // Emulate externally-visible WifiManager effects, causing the // per-interface state machine to start up, and telling us that @@ -858,9 +860,11 @@ public class TetheringTest { verifyInterfaceServingModeStarted(TEST_WLAN_IFNAME); verifyTetheringBroadcast(TEST_WLAN_IFNAME, EXTRA_AVAILABLE_TETHER); - verify(mNMService, times(1)).setIpForwardingEnabled(true); - verify(mNMService, times(1)).startTethering(any(String[].class)); - verifyNoMoreInteractions(mNMService); + 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( @@ -878,8 +882,8 @@ public class TetheringTest { ///// // We do not currently emulate any upstream being found. // - // This is why there are no calls to verify mNMService.enableNat() or - // mNMService.startInterfaceForwarding(). + // This is why there are no calls to verify mNetd.tetherAddForward() or + // mNetd.ipfwdAddInterfaceForward(). ///// // Emulate pressing the WiFi tethering button. @@ -887,7 +891,7 @@ public class TetheringTest { mLooper.dispatchAll(); verify(mWifiManager, times(1)).stopSoftAp(); verifyNoMoreInteractions(mWifiManager); - verifyNoMoreInteractions(mNMService); + verifyNoMoreInteractions(mNetd); // Emulate externally-visible WifiManager effects, when tethering mode // is being torn down. @@ -895,16 +899,16 @@ public class TetheringTest { mTethering.interfaceRemoved(TEST_WLAN_IFNAME); mLooper.dispatchAll(); - verify(mNMService, times(1)).untetherInterface(TEST_WLAN_IFNAME); - // {g,s}etInterfaceConfig() called twice for enabling and disabling IPv4. - verify(mNMService, atLeastOnce()).getInterfaceConfig(TEST_WLAN_IFNAME); - verify(mNMService, atLeastOnce()) - .setInterfaceConfig(eq(TEST_WLAN_IFNAME), any(InterfaceConfiguration.class)); - verify(mNMService, times(1)).stopTethering(); - verify(mNMService, times(1)).setIpForwardingEnabled(false); + 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(mNMService); + verifyNoMoreInteractions(mNetd); verifyNoMoreInteractions(mWifiManager); // Asking for the last error after the per-interface state machine // has been reaped yields an unknown interface error. @@ -915,14 +919,14 @@ public class TetheringTest { @Test public void failureEnablingIpForwarding() throws Exception { when(mWifiManager.startSoftAp(any(WifiConfiguration.class))).thenReturn(true); - doThrow(new RemoteException()).when(mNMService).setIpForwardingEnabled(true); + doThrow(new RemoteException()).when(mNetd).ipfwdEnableForwarding(TETHERING_NAME); // Emulate pressing the WiFi tethering button. mTethering.startTethering(TETHERING_WIFI, null, false); mLooper.dispatchAll(); verify(mWifiManager, times(1)).startSoftAp(null); verifyNoMoreInteractions(mWifiManager); - verifyNoMoreInteractions(mNMService); + verifyNoMoreInteractions(mNetd); // Emulate externally-visible WifiManager effects, causing the // per-interface state machine to start up, and telling us that @@ -931,15 +935,15 @@ public class TetheringTest { sendWifiApStateChanged(WIFI_AP_STATE_ENABLED, TEST_WLAN_IFNAME, IFACE_IP_MODE_TETHERED); mLooper.dispatchAll(); - // We verify get/set called thrice here: twice for setup (on NMService) and once during - // teardown (on Netd) because all events happen over the course of the single + // 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(mNMService, times(2)).getInterfaceConfig(TEST_WLAN_IFNAME); - verify(mNMService, times(2)) - .setInterfaceConfig(eq(TEST_WLAN_IFNAME), any(InterfaceConfiguration.class)); - verify(mNetd, times(1)).interfaceSetCfg(argThat(p -> TEST_WLAN_IFNAME.equals(p.ifName))); - verify(mNMService, times(1)).tetherInterface(TEST_WLAN_IFNAME); + 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( @@ -949,18 +953,20 @@ public class TetheringTest { assertEquals(3, mTetheringDependencies.mIsTetheringSupportedCalls); verifyTetheringBroadcast(TEST_WLAN_IFNAME, EXTRA_AVAILABLE_TETHER); // This is called, but will throw. - verify(mNMService, times(1)).setIpForwardingEnabled(true); + verify(mNetd, times(1)).ipfwdEnableForwarding(TETHERING_NAME); // This never gets called because of the exception thrown above. - verify(mNMService, times(0)).startTethering(any(String[].class)); + 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(mNMService, times(1)).untetherInterface(TEST_WLAN_IFNAME); + 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(mNMService); + verifyNoMoreInteractions(mNetd); } private void runUserRestrictionsChange( @@ -1232,9 +1238,9 @@ public class TetheringTest { verifyInterfaceServingModeStarted(TEST_P2P_IFNAME); verifyTetheringBroadcast(TEST_P2P_IFNAME, EXTRA_AVAILABLE_TETHER); - verify(mNMService, times(1)).setIpForwardingEnabled(true); - verify(mNMService, times(1)).startTethering(any(String[].class)); - verifyNoMoreInteractions(mNMService); + 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(); // This will be called twice, one is on entering IpServer.STATE_AVAILABLE, @@ -1249,16 +1255,16 @@ public class TetheringTest { mTethering.interfaceRemoved(TEST_P2P_IFNAME); mLooper.dispatchAll(); - verify(mNMService, times(1)).untetherInterface(TEST_P2P_IFNAME); - // {g,s}etInterfaceConfig() called twice for enabling and disabling IPv4. - verify(mNMService, times(2)).getInterfaceConfig(TEST_P2P_IFNAME); - verify(mNMService, times(2)) - .setInterfaceConfig(eq(TEST_P2P_IFNAME), any(InterfaceConfiguration.class)); - verify(mNMService, times(1)).stopTethering(); - verify(mNMService, times(1)).setIpForwardingEnabled(false); + 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(mNMService); + 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)); @@ -1272,12 +1278,11 @@ public class TetheringTest { sendWifiP2pConnectionChanged(true, false, TEST_P2P_IFNAME); mLooper.dispatchAll(); - verify(mNMService, never()).getInterfaceConfig(TEST_P2P_IFNAME); - verify(mNMService, never()) - .setInterfaceConfig(eq(TEST_P2P_IFNAME), any(InterfaceConfiguration.class)); - verify(mNMService, never()).tetherInterface(TEST_P2P_IFNAME); - verify(mNMService, never()).setIpForwardingEnabled(true); - verify(mNMService, never()).startTethering(any(String[].class)); + 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. @@ -1285,13 +1290,13 @@ public class TetheringTest { mTethering.interfaceRemoved(TEST_P2P_IFNAME); mLooper.dispatchAll(); - verify(mNMService, never()).untetherInterface(TEST_P2P_IFNAME); - verify(mNMService, never()).getInterfaceConfig(TEST_P2P_IFNAME); - verify(mNMService, never()) - .setInterfaceConfig(eq(TEST_P2P_IFNAME), any(InterfaceConfiguration.class)); - verify(mNMService, never()).stopTethering(); - verify(mNMService, never()).setIpForwardingEnabled(false); - verifyNoMoreInteractions(mNMService); + 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)); @@ -1310,7 +1315,7 @@ public class TetheringTest { private void workingWifiP2pGroupOwnerLegacyMode( boolean emulateInterfaceStatusChanged) throws Exception { // change to legacy mode and update tethering information by chaning SIM - when(mResources.getStringArray(com.android.internal.R.array.config_tether_wifi_p2p_regexs)) + when(mResources.getStringArray(R.array.config_tether_wifi_p2p_regexs)) .thenReturn(new String[]{}); final int fakeSubId = 1234; mPhoneStateListener.onActiveDataSubscriptionIdChanged(fakeSubId); @@ -1321,12 +1326,11 @@ public class TetheringTest { sendWifiP2pConnectionChanged(true, true, TEST_P2P_IFNAME); mLooper.dispatchAll(); - verify(mNMService, never()).getInterfaceConfig(TEST_P2P_IFNAME); - verify(mNMService, never()) - .setInterfaceConfig(eq(TEST_P2P_IFNAME), any(InterfaceConfiguration.class)); - verify(mNMService, never()).tetherInterface(TEST_P2P_IFNAME); - verify(mNMService, never()).setIpForwardingEnabled(true); - verify(mNMService, never()).startTethering(any(String[].class)); + 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 @@ -1349,6 +1353,50 @@ public class TetheringTest { 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)); + } + // 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/server/connectivity/tethering/UpstreamNetworkMonitorTest.java b/packages/Tethering/tests/unit/src/com/android/server/connectivity/tethering/UpstreamNetworkMonitorTest.java index c90abbbedb5f..5ed75bf26f8b 100644 --- a/packages/Tethering/tests/unit/src/com/android/server/connectivity/tethering/UpstreamNetworkMonitorTest.java +++ b/packages/Tethering/tests/unit/src/com/android/server/connectivity/tethering/UpstreamNetworkMonitorTest.java @@ -18,13 +18,14 @@ package com.android.server.connectivity.tethering; import static android.net.ConnectivityManager.TYPE_MOBILE_DUN; import static android.net.ConnectivityManager.TYPE_MOBILE_HIPRI; -import static android.net.ConnectivityManager.TYPE_NONE; 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.server.connectivity.tethering.UpstreamNetworkMonitor.TYPE_NONE; + import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; @@ -538,13 +539,15 @@ public class UpstreamNetworkMonitorTest { 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 = ConnectivityManager.networkCapabilitiesForType(legacyType); + final NetworkCapabilities nc = + UpstreamNetworkMonitor.networkCapabilitiesForType(legacyType); assertTrue(nc.satisfiedByNetworkCapabilities(ns.networkCapabilities)); } diff --git a/packages/WAPPushManager/Android.bp b/packages/WAPPushManager/Android.bp index c3913698022d..083dac944936 100644 --- a/packages/WAPPushManager/Android.bp +++ b/packages/WAPPushManager/Android.bp @@ -10,5 +10,5 @@ android_app { proguard_flags_files: ["proguard.flags"], }, - product_specific: true, + system_ext_specific: true, } diff --git a/packages/WAPPushManager/CleanSpec.mk b/packages/WAPPushManager/CleanSpec.mk index 2dcbb1034622..f4e316c56bbf 100644 --- a/packages/WAPPushManager/CleanSpec.mk +++ b/packages/WAPPushManager/CleanSpec.mk @@ -49,3 +49,5 @@ # ************************************************ $(call add-clean-step, rm -rf $(PRODUCT_OUT)/system/app/WAPPushManager) +$(call add-clean-step, rm -rf $(TARGET_OUT_PRODUCT)/app/WAPPushManager) + diff --git a/packages/WallpaperCropper/Android.bp b/packages/WallpaperCropper/Android.bp index 40c423520081..ac38b271395c 100644 --- a/packages/WallpaperCropper/Android.bp +++ b/packages/WallpaperCropper/Android.bp @@ -3,7 +3,7 @@ android_app { srcs: ["src/**/*.java"], platform_apis: true, certificate: "platform", - product_specific: true, + system_ext_specific: true, privileged: true, optimize: { proguard_flags_files: ["proguard.flags"], diff --git a/packages/WallpaperCropper/CleanSpec.mk b/packages/WallpaperCropper/CleanSpec.mk index e6d8d5a774f1..f08c3430756a 100644 --- a/packages/WallpaperCropper/CleanSpec.mk +++ b/packages/WallpaperCropper/CleanSpec.mk @@ -44,6 +44,7 @@ #$(call add-clean-step, find $(OUT_DIR) -type f -name "IGTalkSession*" -print0 | xargs -0 rm -f) #$(call add-clean-step, rm -rf $(PRODUCT_OUT)/data/*) $(call add-clean-step, rm -rf $(PRODUCT_OUT)/system/priv-app/WallpaperCropper) +$(call add-clean-step, rm -rf $(TARGET_OUT_PRODUCT)/priv-app/WallpaperCropper) # ************************************************ # NEWER CLEAN STEPS MUST BE AT THE END OF THE LIST diff --git a/rs/java/android/renderscript/BaseObj.java b/rs/java/android/renderscript/BaseObj.java index b7e05d9c984c..7b5514b8a0d1 100644 --- a/rs/java/android/renderscript/BaseObj.java +++ b/rs/java/android/renderscript/BaseObj.java @@ -16,8 +16,10 @@ package android.renderscript; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; + import dalvik.system.CloseGuard; + import java.util.concurrent.locks.ReentrantReadWriteLock; /** diff --git a/rs/java/android/renderscript/Element.java b/rs/java/android/renderscript/Element.java index b8eb3a1d7a40..0941907d35f8 100644 --- a/rs/java/android/renderscript/Element.java +++ b/rs/java/android/renderscript/Element.java @@ -16,7 +16,7 @@ package android.renderscript; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; /** * <p>An Element represents one item within an {@link diff --git a/rs/java/android/renderscript/FileA3D.java b/rs/java/android/renderscript/FileA3D.java index 9a6b0bcd4544..7cc2825ae565 100644 --- a/rs/java/android/renderscript/FileA3D.java +++ b/rs/java/android/renderscript/FileA3D.java @@ -16,13 +16,13 @@ package android.renderscript; -import java.io.File; -import java.io.InputStream; - -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.res.AssetManager; import android.content.res.Resources; +import java.io.File; +import java.io.InputStream; + /** * @hide * @deprecated in API 16 diff --git a/rs/java/android/renderscript/Font.java b/rs/java/android/renderscript/Font.java index 583350e91795..df9d8019f28d 100644 --- a/rs/java/android/renderscript/Font.java +++ b/rs/java/android/renderscript/Font.java @@ -16,17 +16,16 @@ package android.renderscript; +import android.compat.annotation.UnsupportedAppUsage; +import android.content.res.AssetManager; +import android.content.res.Resources; +import android.os.Environment; + import java.io.File; import java.io.InputStream; import java.util.HashMap; import java.util.Map; -import android.os.Environment; - -import android.annotation.UnsupportedAppUsage; -import android.content.res.AssetManager; -import android.content.res.Resources; - /** * @hide * @deprecated in API 16 diff --git a/rs/java/android/renderscript/Matrix4f.java b/rs/java/android/renderscript/Matrix4f.java index 026c9fbd7d5e..a9469c979494 100644 --- a/rs/java/android/renderscript/Matrix4f.java +++ b/rs/java/android/renderscript/Matrix4f.java @@ -16,8 +16,7 @@ package android.renderscript; -import android.annotation.UnsupportedAppUsage; -import java.lang.Math; +import android.compat.annotation.UnsupportedAppUsage; /** diff --git a/rs/java/android/renderscript/Mesh.java b/rs/java/android/renderscript/Mesh.java index 5321dcb957dc..826225a70d86 100644 --- a/rs/java/android/renderscript/Mesh.java +++ b/rs/java/android/renderscript/Mesh.java @@ -16,7 +16,8 @@ package android.renderscript; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; + import java.util.Vector; /** diff --git a/rs/java/android/renderscript/Program.java b/rs/java/android/renderscript/Program.java index e28d646f5f1c..ff072183e927 100644 --- a/rs/java/android/renderscript/Program.java +++ b/rs/java/android/renderscript/Program.java @@ -17,14 +17,14 @@ package android.renderscript; +import android.compat.annotation.UnsupportedAppUsage; +import android.content.res.Resources; +import android.util.Log; + import java.io.IOException; import java.io.InputStream; import java.io.UnsupportedEncodingException; -import android.annotation.UnsupportedAppUsage; -import android.content.res.Resources; -import android.util.Log; - /** * @hide diff --git a/rs/java/android/renderscript/ProgramFragment.java b/rs/java/android/renderscript/ProgramFragment.java index 3dde9b6d6400..880531207b4d 100644 --- a/rs/java/android/renderscript/ProgramFragment.java +++ b/rs/java/android/renderscript/ProgramFragment.java @@ -16,7 +16,7 @@ package android.renderscript; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; /** diff --git a/rs/java/android/renderscript/ProgramFragmentFixedFunction.java b/rs/java/android/renderscript/ProgramFragmentFixedFunction.java index d05d41da8b6f..c741ce6e77ed 100644 --- a/rs/java/android/renderscript/ProgramFragmentFixedFunction.java +++ b/rs/java/android/renderscript/ProgramFragmentFixedFunction.java @@ -16,7 +16,7 @@ package android.renderscript; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; /** diff --git a/rs/java/android/renderscript/ProgramRaster.java b/rs/java/android/renderscript/ProgramRaster.java index 33000acb4eb0..a21696c82161 100644 --- a/rs/java/android/renderscript/ProgramRaster.java +++ b/rs/java/android/renderscript/ProgramRaster.java @@ -16,7 +16,7 @@ package android.renderscript; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; /** diff --git a/rs/java/android/renderscript/ProgramStore.java b/rs/java/android/renderscript/ProgramStore.java index 622fe21be47a..7e61347ee218 100644 --- a/rs/java/android/renderscript/ProgramStore.java +++ b/rs/java/android/renderscript/ProgramStore.java @@ -16,7 +16,7 @@ package android.renderscript; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; /** diff --git a/rs/java/android/renderscript/ProgramVertex.java b/rs/java/android/renderscript/ProgramVertex.java index 83d9ea7be645..9257234de42c 100644 --- a/rs/java/android/renderscript/ProgramVertex.java +++ b/rs/java/android/renderscript/ProgramVertex.java @@ -38,7 +38,7 @@ **/ package android.renderscript; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; /** diff --git a/rs/java/android/renderscript/ProgramVertexFixedFunction.java b/rs/java/android/renderscript/ProgramVertexFixedFunction.java index 579d3bb507e8..03c2eaf91242 100644 --- a/rs/java/android/renderscript/ProgramVertexFixedFunction.java +++ b/rs/java/android/renderscript/ProgramVertexFixedFunction.java @@ -16,7 +16,7 @@ package android.renderscript; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; /** diff --git a/rs/java/android/renderscript/RSSurfaceView.java b/rs/java/android/renderscript/RSSurfaceView.java index 561373cef625..6bdde387b334 100644 --- a/rs/java/android/renderscript/RSSurfaceView.java +++ b/rs/java/android/renderscript/RSSurfaceView.java @@ -16,7 +16,7 @@ package android.renderscript; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; import android.util.AttributeSet; import android.view.SurfaceHolder; diff --git a/rs/java/android/renderscript/RenderScript.java b/rs/java/android/renderscript/RenderScript.java index f4c27771c846..46c49e5a5e11 100644 --- a/rs/java/android/renderscript/RenderScript.java +++ b/rs/java/android/renderscript/RenderScript.java @@ -16,7 +16,7 @@ package android.renderscript; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; import android.content.res.AssetManager; import android.graphics.Bitmap; diff --git a/rs/java/android/renderscript/RenderScriptCacheDir.java b/rs/java/android/renderscript/RenderScriptCacheDir.java index 1797bef4be8d..862d032d6987 100644 --- a/rs/java/android/renderscript/RenderScriptCacheDir.java +++ b/rs/java/android/renderscript/RenderScriptCacheDir.java @@ -16,7 +16,8 @@ package android.renderscript; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; + import java.io.File; /** diff --git a/rs/java/android/renderscript/RenderScriptGL.java b/rs/java/android/renderscript/RenderScriptGL.java index 6fac83e8c4a8..dafaf367364d 100644 --- a/rs/java/android/renderscript/RenderScriptGL.java +++ b/rs/java/android/renderscript/RenderScriptGL.java @@ -16,7 +16,7 @@ package android.renderscript; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; import android.graphics.SurfaceTexture; import android.view.Surface; diff --git a/rs/java/android/renderscript/Script.java b/rs/java/android/renderscript/Script.java index 9ad9aea9d7aa..d1d3a7642382 100644 --- a/rs/java/android/renderscript/Script.java +++ b/rs/java/android/renderscript/Script.java @@ -16,7 +16,7 @@ package android.renderscript; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.util.SparseArray; /** diff --git a/services/Android.bp b/services/Android.bp index 80452f19e6c1..943e491393dd 100644 --- a/services/Android.bp +++ b/services/Android.bp @@ -111,7 +111,7 @@ droidstubs { srcs: [":services-sources"], installable: false, // TODO: remove the --hide options below - args: " --show-single-annotation android.annotation.SystemApi\\(client=android.annotation.SystemApi.Client.MODULE_LIBRARIES,process=android.annotation.SystemApi.Process.SYSTEM_SERVER\\)" + + args: " --show-annotation android.annotation.SystemApi\\(client=android.annotation.SystemApi.Client.MODULE_LIBRARIES,process=android.annotation.SystemApi.Process.SYSTEM_SERVER\\)" + " --hide-annotation android.annotation.Hide" + " --hide-package com.google.android.startop.iorap" + " --hide ReferencesHidden" + diff --git a/services/core/java/com/android/server/AlarmManagerService.java b/services/core/java/com/android/server/AlarmManagerService.java index d16244167c62..bbb7c523bac9 100644 --- a/services/core/java/com/android/server/AlarmManagerService.java +++ b/services/core/java/com/android/server/AlarmManagerService.java @@ -2167,8 +2167,9 @@ class AlarmManagerService extends SystemService { @Override public long currentNetworkTimeMillis() { final NtpTrustedTime time = NtpTrustedTime.getInstance(getContext()); - if (time.hasCache()) { - return time.currentTimeMillis(); + NtpTrustedTime.TimeResult ntpResult = time.getCachedTimeResult(); + if (ntpResult != null) { + return ntpResult.currentTimeMillis(); } else { throw new ParcelableException(new DateTimeException("Missing NTP fix")); } diff --git a/services/core/java/com/android/server/ConnectivityService.java b/services/core/java/com/android/server/ConnectivityService.java index bb78aceb3b5f..657207237bf0 100644 --- a/services/core/java/com/android/server/ConnectivityService.java +++ b/services/core/java/com/android/server/ConnectivityService.java @@ -94,6 +94,7 @@ import android.net.NetworkInfo.DetailedState; import android.net.NetworkMisc; import android.net.NetworkMonitorManager; import android.net.NetworkPolicyManager; +import android.net.NetworkProvider; import android.net.NetworkQuotaInfo; import android.net.NetworkRequest; import android.net.NetworkScore; @@ -221,6 +222,7 @@ import java.util.Objects; import java.util.Set; import java.util.SortedSet; import java.util.TreeSet; +import java.util.concurrent.atomic.AtomicInteger; /** * @hide @@ -364,10 +366,10 @@ public class ConnectivityService extends IConnectivityManager.Stub private static final int EVENT_PROXY_HAS_CHANGED = 16; /** - * used internally when registering NetworkFactories - * obj = NetworkFactoryInfo + * used internally when registering NetworkProviders + * obj = NetworkProviderInfo */ - private static final int EVENT_REGISTER_NETWORK_FACTORY = 17; + private static final int EVENT_REGISTER_NETWORK_PROVIDER = 17; /** * used internally when registering NetworkAgents @@ -403,10 +405,10 @@ public class ConnectivityService extends IConnectivityManager.Stub private static final int EVENT_RELEASE_NETWORK_REQUEST = 22; /** - * used internally when registering NetworkFactories + * used internally when registering NetworkProviders * obj = Messenger */ - private static final int EVENT_UNREGISTER_NETWORK_FACTORY = 23; + private static final int EVENT_UNREGISTER_NETWORK_PROVIDER = 23; /** * used internally to expire a wakelock when transitioning @@ -597,6 +599,10 @@ public class ConnectivityService extends IConnectivityManager.Stub // sequence number of NetworkRequests private int mNextNetworkRequestId = 1; + // Sequence number for NetworkProvider IDs. + private final AtomicInteger mNextNetworkProviderId = new AtomicInteger( + NetworkProvider.FIRST_PROVIDER_ID); + // NetworkRequest activity String log entries. private static final int MAX_NETWORK_REQUEST_LOGS = 20; private final LocalLog mNetworkRequestInfoLogs = new LocalLog(MAX_NETWORK_REQUEST_LOGS); @@ -2381,9 +2387,9 @@ public class ConnectivityService extends IConnectivityManager.Stub return; } - pw.print("NetworkFactories for:"); - for (NetworkFactoryInfo nfi : mNetworkFactoryInfos.values()) { - pw.print(" " + nfi.name); + pw.print("NetworkProviders for:"); + for (NetworkProviderInfo npi : mNetworkProviderInfos.values()) { + pw.print(" " + npi.name); } pw.println(); pw.println(); @@ -2714,7 +2720,7 @@ public class ConnectivityService extends IConnectivityManager.Stub nai.lastValidated = valid; nai.everValidated |= valid; updateCapabilities(oldScore, nai, nai.networkCapabilities); - // If score has changed, rebroadcast to NetworkFactories. b/17726566 + // If score has changed, rebroadcast to NetworkProviders. b/17726566 if (oldScore != nai.getCurrentScore()) sendUpdatedScoreToFactories(nai); if (valid) { handleFreshlyValidatedNetwork(nai); @@ -2829,6 +2835,7 @@ public class ConnectivityService extends IConnectivityManager.Stub return true; } + // TODO: delete when direct use of registerNetworkFactory is no longer supported. private boolean maybeHandleNetworkFactoryMessage(Message msg) { switch (msg.what) { default: @@ -3018,32 +3025,16 @@ public class ConnectivityService extends IConnectivityManager.Stub private void handleAsyncChannelHalfConnect(Message msg) { ensureRunningOnConnectivityServiceThread(); final AsyncChannel ac = (AsyncChannel) msg.obj; - if (mNetworkFactoryInfos.containsKey(msg.replyTo)) { + if (mNetworkProviderInfos.containsKey(msg.replyTo)) { if (msg.arg1 == AsyncChannel.STATUS_SUCCESSFUL) { if (VDBG) log("NetworkFactory connected"); // Finish setting up the full connection - mNetworkFactoryInfos.get(msg.replyTo).asyncChannel.sendMessage( - AsyncChannel.CMD_CHANNEL_FULL_CONNECTION); - // A network factory has connected. Send it all current NetworkRequests. - for (NetworkRequestInfo nri : mNetworkRequests.values()) { - if (nri.request.isListen()) continue; - ensureRunningOnConnectivityServiceThread(); - NetworkAgentInfo nai = nri.mSatisfier; - final int score; - final int serial; - if (nai != null) { - score = nai.getCurrentScore(); - serial = nai.factorySerialNumber; - } else { - score = 0; - serial = NetworkFactory.SerialNumber.NONE; - } - ac.sendMessage(android.net.NetworkFactory.CMD_REQUEST_NETWORK, score, serial, - nri.request); - } + NetworkProviderInfo npi = mNetworkProviderInfos.get(msg.replyTo); + npi.completeConnection(); + sendAllRequestsToProvider(npi); } else { loge("Error connecting NetworkFactory"); - mNetworkFactoryInfos.remove(msg.obj); + mNetworkProviderInfos.remove(msg.obj); } } else if (mNetworkAgentInfos.containsKey(msg.replyTo)) { if (msg.arg1 == AsyncChannel.STATUS_SUCCESSFUL) { @@ -3075,8 +3066,8 @@ public class ConnectivityService extends IConnectivityManager.Stub if (nai != null) { disconnectAndDestroyNetwork(nai); } else { - NetworkFactoryInfo nfi = mNetworkFactoryInfos.remove(msg.replyTo); - if (DBG && nfi != null) log("unregisterNetworkFactory for " + nfi.name); + NetworkProviderInfo npi = mNetworkProviderInfos.remove(msg.replyTo); + if (DBG && npi != null) log("unregisterNetworkFactory for " + npi.name); } } @@ -3159,7 +3150,7 @@ public class ConnectivityService extends IConnectivityManager.Stub // ip[6]tables to flush routes and remove the incoming packet mark rule, so do it // after we've rematched networks with requests which should make a potential // fallback network the default or requested a new network from the - // NetworkFactories, so network traffic isn't interrupted for an unnecessarily + // NetworkProviders, so network traffic isn't interrupted for an unnecessarily // long time. destroyNativeNetwork(nai); mDnsManager.removeNetwork(nai.network); @@ -3422,9 +3413,8 @@ public class ConnectivityService extends IConnectivityManager.Stub } } - for (NetworkFactoryInfo nfi : mNetworkFactoryInfos.values()) { - nfi.asyncChannel.sendMessage(android.net.NetworkFactory.CMD_CANCEL_REQUEST, - nri.request); + for (NetworkProviderInfo npi : mNetworkProviderInfos.values()) { + npi.cancelRequest(nri.request); } } else { // listens don't have a singular affectedNetwork. Check all networks to see @@ -3619,14 +3609,29 @@ public class ConnectivityService extends IConnectivityManager.Stub enforceSettingsPermission(); } + final NetworkMonitorManager nm = getNetworkMonitorManager(mNetwork); + if (nm == null) return; + nm.notifyCaptivePortalAppFinished(response); + } + + @Override + public void appRequest(final int request) { + final NetworkMonitorManager nm = getNetworkMonitorManager(mNetwork); + if (nm == null) return; + + if (request == CaptivePortal.APP_REQUEST_REEVALUATION_REQUIRED) { + nm.forceReevaluation(Binder.getCallingUid()); + } + } + + @Nullable + private NetworkMonitorManager getNetworkMonitorManager(final Network network) { // getNetworkAgentInfoForNetwork is thread-safe - final NetworkAgentInfo nai = getNetworkAgentInfoForNetwork(mNetwork); - if (nai == null) return; + final NetworkAgentInfo nai = getNetworkAgentInfoForNetwork(network); + if (nai == null) return null; // nai.networkMonitor() is thread-safe - final NetworkMonitorManager nm = nai.networkMonitor(); - if (nm == null) return; - nm.notifyCaptivePortalAppFinished(response); + return nai.networkMonitor(); } @Override @@ -3859,12 +3864,12 @@ public class ConnectivityService extends IConnectivityManager.Stub handleApplyDefaultProxy((ProxyInfo)msg.obj); break; } - case EVENT_REGISTER_NETWORK_FACTORY: { - handleRegisterNetworkFactory((NetworkFactoryInfo)msg.obj); + case EVENT_REGISTER_NETWORK_PROVIDER: { + handleRegisterNetworkProvider((NetworkProviderInfo) msg.obj); break; } - case EVENT_UNREGISTER_NETWORK_FACTORY: { - handleUnregisterNetworkFactory((Messenger)msg.obj); + case EVENT_UNREGISTER_NETWORK_PROVIDER: { + handleUnregisterNetworkProvider((Messenger) msg.obj); break; } case EVENT_REGISTER_NETWORK_AGENT: { @@ -4909,7 +4914,7 @@ public class ConnectivityService extends IConnectivityManager.Stub } }; - private final HashMap<Messenger, NetworkFactoryInfo> mNetworkFactoryInfos = new HashMap<>(); + private final HashMap<Messenger, NetworkProviderInfo> mNetworkProviderInfos = new HashMap<>(); private final HashMap<NetworkRequest, NetworkRequestInfo> mNetworkRequests = new HashMap<>(); private static final int MAX_NETWORK_REQUESTS_PER_UID = 100; @@ -4917,18 +4922,73 @@ public class ConnectivityService extends IConnectivityManager.Stub @GuardedBy("mUidToNetworkRequestCount") private final SparseIntArray mUidToNetworkRequestCount = new SparseIntArray(); - private static class NetworkFactoryInfo { + private static class NetworkProviderInfo { public final String name; public final Messenger messenger; - public final AsyncChannel asyncChannel; - public final int factorySerialNumber; + private final AsyncChannel mAsyncChannel; + private final IBinder.DeathRecipient mDeathRecipient; + public final int providerId; - NetworkFactoryInfo(String name, Messenger messenger, AsyncChannel asyncChannel, - int factorySerialNumber) { + NetworkProviderInfo(String name, Messenger messenger, AsyncChannel asyncChannel, + int providerId, IBinder.DeathRecipient deathRecipient) { this.name = name; this.messenger = messenger; - this.asyncChannel = asyncChannel; - this.factorySerialNumber = factorySerialNumber; + this.providerId = providerId; + mAsyncChannel = asyncChannel; + mDeathRecipient = deathRecipient; + + if ((mAsyncChannel == null) == (mDeathRecipient == null)) { + throw new AssertionError("Must pass exactly one of asyncChannel or deathRecipient"); + } + } + + boolean isLegacyNetworkFactory() { + return mAsyncChannel != null; + } + + void sendMessageToNetworkProvider(int what, int arg1, int arg2, Object obj) { + try { + messenger.send(Message.obtain(null /* handler */, what, arg1, arg2, obj)); + } catch (RemoteException e) { + // Remote process died. Ignore; the death recipient will remove this + // NetworkProviderInfo from mNetworkProviderInfos. + } + } + + void requestNetwork(NetworkRequest request, int score, int servingProviderId) { + if (isLegacyNetworkFactory()) { + mAsyncChannel.sendMessage(android.net.NetworkFactory.CMD_REQUEST_NETWORK, score, + servingProviderId, request); + } else { + sendMessageToNetworkProvider(NetworkProvider.CMD_REQUEST_NETWORK, score, + servingProviderId, request); + } + } + + void cancelRequest(NetworkRequest request) { + if (isLegacyNetworkFactory()) { + mAsyncChannel.sendMessage(android.net.NetworkFactory.CMD_CANCEL_REQUEST, request); + } else { + sendMessageToNetworkProvider(NetworkProvider.CMD_CANCEL_REQUEST, 0, 0, request); + } + } + + void connect(Context context, Handler handler) { + if (isLegacyNetworkFactory()) { + mAsyncChannel.connect(context, handler, messenger); + } else { + try { + messenger.getBinder().linkToDeath(mDeathRecipient, 0); + } catch (RemoteException e) { + mDeathRecipient.binderDied(); + } + } + } + + void completeConnection() { + if (isLegacyNetworkFactory()) { + mAsyncChannel.sendMessage(AsyncChannel.CMD_CHANNEL_FULL_CONNECTION); + } } } @@ -5299,6 +5359,11 @@ public class ConnectivityService extends IConnectivityManager.Stub mHandler.sendMessage(mHandler.obtainMessage(EVENT_REGISTER_NETWORK_LISTENER, nri)); } + /** Returns the next Network provider ID. */ + public final int nextNetworkProviderId() { + return mNextNetworkProviderId.getAndIncrement(); + } + @Override public void releaseNetworkRequest(NetworkRequest networkRequest) { ensureNetworkRequestHasType(networkRequest); @@ -5309,31 +5374,65 @@ public class ConnectivityService extends IConnectivityManager.Stub @Override public int registerNetworkFactory(Messenger messenger, String name) { enforceNetworkFactoryPermission(); - NetworkFactoryInfo nfi = new NetworkFactoryInfo(name, messenger, new AsyncChannel(), - NetworkFactory.SerialNumber.nextSerialNumber()); - mHandler.sendMessage(mHandler.obtainMessage(EVENT_REGISTER_NETWORK_FACTORY, nfi)); - return nfi.factorySerialNumber; + NetworkProviderInfo npi = new NetworkProviderInfo(name, messenger, new AsyncChannel(), + nextNetworkProviderId(), null /* deathRecipient */); + mHandler.sendMessage(mHandler.obtainMessage(EVENT_REGISTER_NETWORK_PROVIDER, npi)); + return npi.providerId; + } + + private void handleRegisterNetworkProvider(NetworkProviderInfo npi) { + if (mNetworkProviderInfos.containsKey(npi.messenger)) { + // Avoid creating duplicates. even if an app makes a direct AIDL call. + // This will never happen if an app calls ConnectivityManager#registerNetworkProvider, + // as that will throw if a duplicate provider is registered. + Slog.e(TAG, "Attempt to register existing NetworkProviderInfo " + + mNetworkProviderInfos.get(npi.messenger).name); + return; + } + + if (DBG) log("Got NetworkProvider Messenger for " + npi.name); + mNetworkProviderInfos.put(npi.messenger, npi); + npi.connect(mContext, mTrackerHandler); + if (!npi.isLegacyNetworkFactory()) { + // Legacy NetworkFactories get their requests when their AsyncChannel connects. + sendAllRequestsToProvider(npi); + } + } + + @Override + public int registerNetworkProvider(Messenger messenger, String name) { + enforceNetworkFactoryPermission(); + NetworkProviderInfo npi = new NetworkProviderInfo(name, messenger, + null /* asyncChannel */, nextNetworkProviderId(), + () -> unregisterNetworkProvider(messenger)); + mHandler.sendMessage(mHandler.obtainMessage(EVENT_REGISTER_NETWORK_PROVIDER, npi)); + return npi.providerId; } - private void handleRegisterNetworkFactory(NetworkFactoryInfo nfi) { - if (DBG) log("Got NetworkFactory Messenger for " + nfi.name); - mNetworkFactoryInfos.put(nfi.messenger, nfi); - nfi.asyncChannel.connect(mContext, mTrackerHandler, nfi.messenger); + @Override + public void unregisterNetworkProvider(Messenger messenger) { + enforceNetworkFactoryPermission(); + mHandler.sendMessage(mHandler.obtainMessage(EVENT_UNREGISTER_NETWORK_PROVIDER, messenger)); } @Override public void unregisterNetworkFactory(Messenger messenger) { - enforceNetworkFactoryPermission(); - mHandler.sendMessage(mHandler.obtainMessage(EVENT_UNREGISTER_NETWORK_FACTORY, messenger)); + unregisterNetworkProvider(messenger); } - private void handleUnregisterNetworkFactory(Messenger messenger) { - NetworkFactoryInfo nfi = mNetworkFactoryInfos.remove(messenger); - if (nfi == null) { - loge("Failed to find Messenger in unregisterNetworkFactory"); + private void handleUnregisterNetworkProvider(Messenger messenger) { + NetworkProviderInfo npi = mNetworkProviderInfos.remove(messenger); + if (npi == null) { + loge("Failed to find Messenger in unregisterNetworkProvider"); return; } - if (DBG) log("unregisterNetworkFactory for " + nfi.name); + if (DBG) log("unregisterNetworkProvider for " + npi.name); + } + + @Override + public void declareNetworkRequestUnfulfillable(NetworkRequest request) { + enforceNetworkFactoryPermission(); + mHandler.post(() -> handleReleaseNetworkRequest(request, Binder.getCallingUid(), true)); } // NOTE: Accessed on multiple threads, must be synchronized on itself. @@ -5401,7 +5500,7 @@ public class ConnectivityService extends IConnectivityManager.Stub LinkProperties linkProperties, NetworkCapabilities networkCapabilities, int currentScore, NetworkMisc networkMisc) { return registerNetworkAgent(messenger, networkInfo, linkProperties, networkCapabilities, - currentScore, networkMisc, NetworkFactory.SerialNumber.NONE); + currentScore, networkMisc, NetworkProvider.ID_NONE); } /** @@ -5417,11 +5516,11 @@ public class ConnectivityService extends IConnectivityManager.Stub * @param currentScore the initial score of the network. See * {@link NetworkAgentInfo#getCurrentScore}. * @param networkMisc metadata about the network. This is never updated. - * @param factorySerialNumber the serial number of the factory owning this NetworkAgent. + * @param providerId the ID of the provider owning this NetworkAgent. */ public int registerNetworkAgent(Messenger messenger, NetworkInfo networkInfo, LinkProperties linkProperties, NetworkCapabilities networkCapabilities, - int currentScore, NetworkMisc networkMisc, int factorySerialNumber) { + int currentScore, NetworkMisc networkMisc, int providerId) { enforceNetworkFactoryPermission(); LinkProperties lp = new LinkProperties(linkProperties); @@ -5434,7 +5533,7 @@ public class ConnectivityService extends IConnectivityManager.Stub final NetworkAgentInfo nai = new NetworkAgentInfo(messenger, new AsyncChannel(), new Network(mNetIdManager.reserveNetId()), new NetworkInfo(networkInfo), lp, nc, ns, mContext, mTrackerHandler, new NetworkMisc(networkMisc), this, mNetd, - mDnsResolver, mNMS, factorySerialNumber); + mDnsResolver, mNMS, providerId); // Make sure the network capabilities reflect what the agent info says. nai.getAndSetNetworkCapabilities(mixInCapabilities(nai, nc)); final String extraInfo = networkInfo.getExtraInfo(); @@ -5713,7 +5812,7 @@ public class ConnectivityService extends IConnectivityManager.Stub // Once a NetworkAgent is connected, complain if some immutable capabilities are removed. // Don't complain for VPNs since they're not driven by requests and there is no risk of // causing a connect/teardown loop. - // TODO: remove this altogether and make it the responsibility of the NetworkFactories to + // TODO: remove this altogether and make it the responsibility of the NetworkProviders to // avoid connect/teardown loops. if (nai.everConnected && !nai.isVPN() && @@ -5953,9 +6052,27 @@ public class ConnectivityService extends IConnectivityManager.Stub if (VDBG || DDBG){ log("sending new Min Network Score(" + score + "): " + networkRequest.toString()); } - for (NetworkFactoryInfo nfi : mNetworkFactoryInfos.values()) { - nfi.asyncChannel.sendMessage(android.net.NetworkFactory.CMD_REQUEST_NETWORK, score, - serial, networkRequest); + for (NetworkProviderInfo npi : mNetworkProviderInfos.values()) { + npi.requestNetwork(networkRequest, score, serial); + } + } + + /** Sends all current NetworkRequests to the specified factory. */ + private void sendAllRequestsToProvider(NetworkProviderInfo npi) { + ensureRunningOnConnectivityServiceThread(); + for (NetworkRequestInfo nri : mNetworkRequests.values()) { + if (nri.request.isListen()) continue; + NetworkAgentInfo nai = nri.mSatisfier; + final int score; + final int serial; + if (nai != null) { + score = nai.getCurrentScore(); + serial = nai.factorySerialNumber; + } else { + score = 0; + serial = NetworkProvider.ID_NONE; + } + npi.requestNetwork(nri.request, score, serial); } } @@ -6236,11 +6353,11 @@ public class ConnectivityService extends IConnectivityManager.Stub Slog.wtf(TAG, "BUG: " + newSatisfier.name() + " already has " + nri.request); } addedRequests.add(nri); - // Tell NetworkFactories about the new score, so they can stop + // Tell NetworkProviders about the new score, so they can stop // trying to connect if they know they cannot match it. // TODO - this could get expensive if we have a lot of requests for this // network. Think about if there is a way to reduce this. Push - // netid->request mapping to each factory? + // netid->request mapping to each provider? sendUpdatedScoreToFactories(nri.request, newSatisfier); if (isDefaultRequest(nri)) { isNewDefault = true; @@ -6269,7 +6386,7 @@ public class ConnectivityService extends IConnectivityManager.Stub } else { Slog.wtf(TAG, "BUG: Removing request " + nri.request.requestId + " from " + newNetwork.name() + - " without updating mSatisfier or factories!"); + " without updating mSatisfier or providers!"); } // TODO: Technically, sending CALLBACK_LOST here is // incorrect if there is a replacement network currently diff --git a/services/core/java/com/android/server/DynamicSystemService.java b/services/core/java/com/android/server/DynamicSystemService.java index 7909e3096cbe..c60460fccb76 100644 --- a/services/core/java/com/android/server/DynamicSystemService.java +++ b/services/core/java/com/android/server/DynamicSystemService.java @@ -44,9 +44,9 @@ public class DynamicSystemService extends IDynamicSystemService.Stub implements private static final String TAG = "DynamicSystemService"; private static final String NO_SERVICE_ERROR = "no gsiservice"; private static final int GSID_ROUGH_TIMEOUT_MS = 8192; - private static final String PATH_DEFAULT = "/data/gsi"; + private static final String PATH_DEFAULT = "/data/gsi/"; private Context mContext; - private String mInstallPath; + private String mInstallPath, mDsuSlot; private volatile IGsiService mGsiService; DynamicSystemService(Context context) { @@ -115,7 +115,7 @@ public class DynamicSystemService extends IDynamicSystemService.Stub implements } @Override - public boolean startInstallation() throws RemoteException { + public boolean startInstallation(String dsuSlot) throws RemoteException { IGsiService service = getGsiService(); // priority from high to low: sysprop -> sdcard -> /data String path = SystemProperties.get("os.aot.path"); @@ -129,16 +129,17 @@ public class DynamicSystemService extends IDynamicSystemService.Stub implements if (!Environment.MEDIA_MOUNTED.equals(volume.getState())) continue; File sdCard = volume.getPathFile(); if (sdCard.isDirectory()) { - path = sdCard.getPath(); + path = new File(sdCard, dsuSlot).getPath(); break; } } if (path.isEmpty()) { - path = PATH_DEFAULT; + path = PATH_DEFAULT + dsuSlot; } Slog.i(TAG, "startInstallation -> " + path); } mInstallPath = path; + mDsuSlot = dsuSlot; if (service.openInstall(path) != 0) { Slog.i(TAG, "Failed to open " + path); return false; @@ -203,7 +204,7 @@ public class DynamicSystemService extends IDynamicSystemService.Stub implements public boolean setEnable(boolean enable, boolean oneShot) throws RemoteException { IGsiService gsiService = getGsiService(); if (enable) { - return gsiService.enableGsi(oneShot) == 0; + return gsiService.enableGsi(oneShot, mDsuSlot) == 0; } else { return gsiService.disableGsi(); } diff --git a/services/core/java/com/android/server/MmsServiceBroker.java b/services/core/java/com/android/server/MmsServiceBroker.java index fe154ed8d396..9b1326bc88d7 100644 --- a/services/core/java/com/android/server/MmsServiceBroker.java +++ b/services/core/java/com/android/server/MmsServiceBroker.java @@ -16,6 +16,8 @@ package com.android.server; +import static android.telephony.SubscriptionManager.INVALID_SIM_SLOT_INDEX; + import android.Manifest; import android.app.AppOpsManager; import android.app.PendingIntent; @@ -37,6 +39,7 @@ import android.os.SystemClock; import android.os.UserHandle; import android.service.carrier.CarrierMessagingService; import android.telephony.SmsManager; +import android.telephony.SubscriptionInfo; import android.telephony.SubscriptionManager; import android.telephony.TelephonyManager; import android.util.Slog; @@ -512,11 +515,11 @@ public class MmsServiceBroker extends SystemService { // Grant permission for the carrier app. Intent intent = new Intent(action); - TelephonyManager telephonyManager = - (TelephonyManager) mContext.getSystemService(Context.TELEPHONY_SERVICE); - List<String> carrierPackages = - telephonyManager.getCarrierPackageNamesForIntentAndPhone( - intent, SubscriptionManager.getPhoneId(subId)); + TelephonyManager telephonyManager = (TelephonyManager) + mContext.getSystemService(Context.TELEPHONY_SERVICE); + List<String> carrierPackages = telephonyManager + .getCarrierPackageNamesForIntentAndPhone( + intent, getPhoneIdFromSubId(subId)); if (carrierPackages != null && carrierPackages.size() == 1) { LocalServices.getService(UriGrantsManagerInternal.class) .grantUriPermissionFromIntent(callingUid, carrierPackages.get(0), @@ -528,4 +531,13 @@ public class MmsServiceBroker extends SystemService { return contentUri; } } + + private int getPhoneIdFromSubId(int subId) { + SubscriptionManager subManager = (SubscriptionManager) + mContext.getSystemService(Context.TELEPHONY_SUBSCRIPTION_SERVICE); + if (subManager == null) return INVALID_SIM_SLOT_INDEX; + SubscriptionInfo info = subManager.getActiveSubscriptionInfo(subId); + if (info == null) return INVALID_SIM_SLOT_INDEX; + return info.getSimSlotIndex(); + } } diff --git a/services/core/java/com/android/server/NetworkManagementService.java b/services/core/java/com/android/server/NetworkManagementService.java index 0d496b6b427d..1daed1b54683 100644 --- a/services/core/java/com/android/server/NetworkManagementService.java +++ b/services/core/java/com/android/server/NetworkManagementService.java @@ -58,10 +58,12 @@ import android.net.NetworkStack; import android.net.NetworkStats; import android.net.NetworkUtils; import android.net.RouteInfo; -import android.net.TetherConfigParcel; import android.net.TetherStatsParcel; import android.net.UidRange; import android.net.UidRangeParcel; +import android.net.shared.NetdUtils; +import android.net.shared.RouteUtils; +import android.net.shared.RouteUtils.ModifyOperation; import android.net.util.NetdService; import android.os.BatteryStats; import android.os.Binder; @@ -897,48 +899,14 @@ public class NetworkManagementService extends INetworkManagementService.Stub { @Override public void addRoute(int netId, RouteInfo route) { - modifyRoute(MODIFY_OPERATION_ADD, netId, route); + NetworkStack.checkNetworkStackPermission(mContext); + RouteUtils.modifyRoute(mNetdService, ModifyOperation.ADD, netId, route); } @Override public void removeRoute(int netId, RouteInfo route) { - modifyRoute(MODIFY_OPERATION_REMOVE, netId, route); - } - - private void modifyRoute(boolean add, int netId, RouteInfo route) { NetworkStack.checkNetworkStackPermission(mContext); - - final String ifName = route.getInterface(); - final String dst = route.getDestination().toString(); - final String nextHop; - - switch (route.getType()) { - case RouteInfo.RTN_UNICAST: - if (route.hasGateway()) { - nextHop = route.getGateway().getHostAddress(); - } else { - nextHop = INetd.NEXTHOP_NONE; - } - break; - case RouteInfo.RTN_UNREACHABLE: - nextHop = INetd.NEXTHOP_UNREACHABLE; - break; - case RouteInfo.RTN_THROW: - nextHop = INetd.NEXTHOP_THROW; - break; - default: - nextHop = INetd.NEXTHOP_NONE; - break; - } - try { - if (add) { - mNetdService.networkAddRoute(netId, ifName, dst, nextHop); - } else { - mNetdService.networkRemoveRoute(netId, ifName, dst, nextHop); - } - } catch (RemoteException | ServiceSpecificException e) { - throw new IllegalStateException(e); - } + RouteUtils.modifyRoute(mNetdService, ModifyOperation.REMOVE, netId, route); } private ArrayList<String> readRouteList(String filename) { @@ -1022,12 +990,8 @@ public class NetworkManagementService extends INetworkManagementService.Stub { @Override public void startTetheringWithConfiguration(boolean usingLegacyDnsProxy, String[] dhcpRange) { NetworkStack.checkNetworkStackPermission(mContext); - // an odd number of addrs will fail try { - final TetherConfigParcel config = new TetherConfigParcel(); - config.usingLegacyDnsProxy = usingLegacyDnsProxy; - config.dhcpRanges = dhcpRange; - mNetdService.tetherStartWithConfiguration(config); + NetdUtils.tetherStart(mNetdService, usingLegacyDnsProxy, dhcpRange); } catch (RemoteException | ServiceSpecificException e) { throw new IllegalStateException(e); } @@ -1059,26 +1023,21 @@ public class NetworkManagementService extends INetworkManagementService.Stub { public void tetherInterface(String iface) { NetworkStack.checkNetworkStackPermission(mContext); try { - mNetdService.tetherInterfaceAdd(iface); + final LinkAddress addr = getInterfaceConfig(iface).getLinkAddress(); + final IpPrefix dest = new IpPrefix(addr.getAddress(), addr.getPrefixLength()); + NetdUtils.tetherInterface(mNetdService, iface, dest); } catch (RemoteException | ServiceSpecificException e) { throw new IllegalStateException(e); } - List<RouteInfo> routes = new ArrayList<>(); - // The RouteInfo constructor truncates the LinkAddress to a network prefix, thus making it - // suitable to use as a route destination. - routes.add(new RouteInfo(getInterfaceConfig(iface).getLinkAddress(), null, iface)); - addInterfaceToLocalNetwork(iface, routes); } @Override public void untetherInterface(String iface) { NetworkStack.checkNetworkStackPermission(mContext); try { - mNetdService.tetherInterfaceRemove(iface); + NetdUtils.untetherInterface(mNetdService, iface); } catch (RemoteException | ServiceSpecificException e) { throw new IllegalStateException(e); - } finally { - removeInterfaceFromLocalNetwork(iface); } } @@ -2121,16 +2080,8 @@ public class NetworkManagementService extends INetworkManagementService.Stub { @Override public void addInterfaceToLocalNetwork(String iface, List<RouteInfo> routes) { modifyInterfaceInNetwork(MODIFY_OPERATION_ADD, INetd.LOCAL_NET_ID, iface); - - for (RouteInfo route : routes) { - if (!route.isDefaultRoute()) { - modifyRoute(MODIFY_OPERATION_ADD, INetd.LOCAL_NET_ID, route); - } - } - - // IPv6 link local should be activated always. - modifyRoute(MODIFY_OPERATION_ADD, INetd.LOCAL_NET_ID, - new RouteInfo(new IpPrefix("fe80::/64"), null, iface)); + // modifyInterfaceInNetwork already check calling permission. + RouteUtils.addRoutesToLocalNetwork(mNetdService, iface, routes); } @Override @@ -2140,17 +2091,8 @@ public class NetworkManagementService extends INetworkManagementService.Stub { @Override public int removeRoutesFromLocalNetwork(List<RouteInfo> routes) { - int failures = 0; - - for (RouteInfo route : routes) { - try { - modifyRoute(MODIFY_OPERATION_REMOVE, INetd.LOCAL_NET_ID, route); - } catch (IllegalStateException e) { - failures++; - } - } - - return failures; + NetworkStack.checkNetworkStackPermission(mContext); + return RouteUtils.removeRoutesFromLocalNetwork(mNetdService, routes); } @Override diff --git a/services/core/java/com/android/server/NetworkScoreService.java b/services/core/java/com/android/server/NetworkScoreService.java index 9a7a4e79ab33..2fb1f7783814 100644 --- a/services/core/java/com/android/server/NetworkScoreService.java +++ b/services/core/java/com/android/server/NetworkScoreService.java @@ -54,7 +54,6 @@ import android.provider.Settings.Global; import android.text.TextUtils; import android.util.ArrayMap; import android.util.ArraySet; -import android.util.IntArray; import android.util.Log; import com.android.internal.annotations.GuardedBy; @@ -527,7 +526,7 @@ public class NetworkScoreService extends INetworkScoreService.Stub { @Override public void accept(INetworkScoreCache networkScoreCache, Object cookie) { - int filterType = NetworkScoreManager.CACHE_FILTER_NONE; + int filterType = NetworkScoreManager.SCORE_FILTER_NONE; if (cookie instanceof Integer) { filterType = (Integer) cookie; } @@ -551,17 +550,17 @@ public class NetworkScoreService extends INetworkScoreService.Stub { private List<ScoredNetwork> filterScores(List<ScoredNetwork> scoredNetworkList, int filterType) { switch (filterType) { - case NetworkScoreManager.CACHE_FILTER_NONE: + case NetworkScoreManager.SCORE_FILTER_NONE: return scoredNetworkList; - case NetworkScoreManager.CACHE_FILTER_CURRENT_NETWORK: + case NetworkScoreManager.SCORE_FILTER_CURRENT_NETWORK: if (mCurrentNetworkFilter == null) { mCurrentNetworkFilter = new CurrentNetworkScoreCacheFilter(new WifiInfoSupplier(mContext)); } return mCurrentNetworkFilter.apply(scoredNetworkList); - case NetworkScoreManager.CACHE_FILTER_SCAN_RESULTS: + case NetworkScoreManager.SCORE_FILTER_SCAN_RESULTS: if (mScanResultsFilter == null) { mScanResultsFilter = new ScanResultsScoreCacheFilter( new ScanResultsSupplier(mContext)); diff --git a/services/core/java/com/android/server/NetworkTimeUpdateServiceImpl.java b/services/core/java/com/android/server/NetworkTimeUpdateServiceImpl.java index cfe56052118f..7894788cb0b6 100644 --- a/services/core/java/com/android/server/NetworkTimeUpdateServiceImpl.java +++ b/services/core/java/com/android/server/NetworkTimeUpdateServiceImpl.java @@ -36,11 +36,11 @@ import android.os.Looper; import android.os.Message; import android.os.PowerManager; import android.os.SystemClock; +import android.os.TimestampedValue; import android.provider.Settings; import android.util.Log; import android.util.NtpTrustedTime; import android.util.TimeUtils; -import android.util.TimestampedValue; import com.android.internal.util.DumpUtils; @@ -154,17 +154,20 @@ public class NetworkTimeUpdateServiceImpl extends Binder implements NetworkTimeU private void onPollNetworkTimeUnderWakeLock(int event) { // Force an NTP fix when outdated - if (mTime.getCacheAge() >= mPollingIntervalMs) { + NtpTrustedTime.TimeResult cachedNtpResult = mTime.getCachedTimeResult(); + if (cachedNtpResult == null || cachedNtpResult.getAgeMillis() >= mPollingIntervalMs) { if (DBG) Log.d(TAG, "Stale NTP fix; forcing refresh"); mTime.forceRefresh(); + cachedNtpResult = mTime.getCachedTimeResult(); } - if (mTime.getCacheAge() < mPollingIntervalMs) { + if (cachedNtpResult != null && cachedNtpResult.getAgeMillis() < mPollingIntervalMs) { // Obtained fresh fix; schedule next normal update resetAlarm(mPollingIntervalMs); // Suggest the time to the time detector. It may choose use it to set the system clock. - TimestampedValue<Long> timeSignal = mTime.getCachedNtpTimeSignal(); + TimestampedValue<Long> timeSignal = new TimestampedValue<>( + cachedNtpResult.getElapsedRealtimeMillis(), cachedNtpResult.getTimeMillis()); NetworkTimeSuggestion timeSuggestion = new NetworkTimeSuggestion(timeSignal); timeSuggestion.addDebugInfo("Origin: NetworkTimeUpdateServiceImpl. event=" + event); mTimeDetector.suggestNetworkTime(timeSuggestion); @@ -275,8 +278,11 @@ public class NetworkTimeUpdateServiceImpl extends Binder implements NetworkTimeU TimeUtils.formatDuration(mPollingIntervalShorterMs, pw); pw.println("\nTryAgainTimesMax: " + mTryAgainTimesMax); pw.println("\nTryAgainCounter: " + mTryAgainCounter); - pw.println("NTP cache age: " + mTime.getCacheAge()); - pw.println("NTP cache certainty: " + mTime.getCacheCertainty()); + NtpTrustedTime.TimeResult ntpResult = mTime.getCachedTimeResult(); + pw.println("NTP cache result: " + ntpResult); + if (ntpResult != null) { + pw.println("NTP result age: " + ntpResult.getAgeMillis()); + } pw.println(); } } diff --git a/services/core/java/com/android/server/StorageManagerService.java b/services/core/java/com/android/server/StorageManagerService.java index d1bc6af88347..90b0c11cc8dd 100644 --- a/services/core/java/com/android/server/StorageManagerService.java +++ b/services/core/java/com/android/server/StorageManagerService.java @@ -2648,9 +2648,11 @@ class StorageManagerService extends IStorageManager.Stub */ @Override public boolean supportsCheckpoint() throws RemoteException { - // Only the system process is permitted to start checkpoints - if (Binder.getCallingUid() != android.os.Process.SYSTEM_UID) { - throw new SecurityException("no permission to check filesystem checkpoint support"); + // Only the root, system_server and shell processes are permitted to start checkpoints + final int callingUid = Binder.getCallingUid(); + if (callingUid != Process.SYSTEM_UID && callingUid != Process.ROOT_UID + && callingUid != Process.SHELL_UID) { + throw new SecurityException("no permission to start filesystem checkpoint"); } return mVold.supportsCheckpoint(); @@ -2665,8 +2667,10 @@ class StorageManagerService extends IStorageManager.Stub */ @Override public void startCheckpoint(int numTries) throws RemoteException { - // Only the system process is permitted to start checkpoints - if (Binder.getCallingUid() != android.os.Process.SYSTEM_UID) { + // Only the root, system_server and shell processes are permitted to start checkpoints + final int callingUid = Binder.getCallingUid(); + if (callingUid != Process.SYSTEM_UID && callingUid != Process.ROOT_UID + && callingUid != Process.SHELL_UID) { throw new SecurityException("no permission to start filesystem checkpoint"); } diff --git a/services/core/java/com/android/server/TelephonyRegistry.java b/services/core/java/com/android/server/TelephonyRegistry.java index 078ef7888916..8b436c5f2435 100644 --- a/services/core/java/com/android/server/TelephonyRegistry.java +++ b/services/core/java/com/android/server/TelephonyRegistry.java @@ -16,12 +16,15 @@ package com.android.server; +import static android.telephony.SubscriptionManager.INVALID_SIM_SLOT_INDEX; import static android.telephony.TelephonyManager.ACTION_MULTI_SIM_CONFIG_CHANGED; import static android.telephony.TelephonyRegistryManager.SIM_ACTIVATION_TYPE_DATA; import static android.telephony.TelephonyRegistryManager.SIM_ACTIVATION_TYPE_VOICE; import static java.util.Arrays.copyOf; +import android.annotation.NonNull; +import android.annotation.Nullable; import android.app.ActivityManager; import android.app.AppOpsManager; import android.content.BroadcastReceiver; @@ -44,8 +47,16 @@ import android.telephony.Annotation.RadioPowerState; import android.telephony.Annotation.SrvccState; import android.telephony.CallAttributes; import android.telephony.CallQuality; +import android.telephony.CellIdentity; import android.telephony.CellInfo; import android.telephony.CellLocation; +import android.telephony.CellSignalStrength; +import android.telephony.CellSignalStrengthCdma; +import android.telephony.CellSignalStrengthGsm; +import android.telephony.CellSignalStrengthLte; +import android.telephony.CellSignalStrengthNr; +import android.telephony.CellSignalStrengthTdscdma; +import android.telephony.CellSignalStrengthWcdma; import android.telephony.DataFailCause; import android.telephony.DisconnectCause; import android.telephony.LocationAccessPolicy; @@ -57,6 +68,7 @@ import android.telephony.PreciseDisconnectCause; import android.telephony.Rlog; import android.telephony.ServiceState; import android.telephony.SignalStrength; +import android.telephony.SubscriptionInfo; import android.telephony.SubscriptionManager; import android.telephony.TelephonyManager; import android.telephony.data.ApnSetting; @@ -95,7 +107,7 @@ import java.util.NoSuchElementException; * and 15973975 by saving the phoneId of the registrant and then using the * phoneId when deciding to to make a callback. This is necessary because * a subId changes from to a dummy value when a SIM is removed and thus won't - * compare properly. Because SubscriptionManager.getPhoneId(int subId) handles + * compare properly. Because getPhoneIdFromSubId(int subId) handles * the dummy value conversion we properly do the callbacks. * * Eventually we may want to remove the notion of dummy value but for now this @@ -112,6 +124,7 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub { Context context; String callingPackage; + String callingFeatureId; IBinder binder; @@ -128,7 +141,7 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub { int subId = SubscriptionManager.INVALID_SUBSCRIPTION_ID; - int phoneId = SubscriptionManager.INVALID_PHONE_INDEX; + int phoneId = SubscriptionManager.INVALID_SIM_SLOT_INDEX; boolean matchPhoneStateListenerEvent(int events) { return (callback != null) && ((events & this.events) != 0); @@ -145,7 +158,7 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub { boolean canReadCallLog() { try { return TelephonyPermissions.checkReadCallLog( - context, subId, callerPid, callerUid, callingPackage); + context, subId, callerPid, callerUid, callingPackage, callingFeatureId); } catch (SecurityException e) { return false; } @@ -203,7 +216,7 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub { // Connection state of default APN type data (i.e. internet) of phones private int[] mDataConnectionState; - private Bundle[] mCellLocation; + private CellIdentity[] mCellIdentity; private int[] mDataConnectionNetworkType; @@ -226,7 +239,7 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub { private int mDefaultSubId = SubscriptionManager.INVALID_SUBSCRIPTION_ID; - private int mDefaultPhoneId = SubscriptionManager.INVALID_PHONE_INDEX; + private int mDefaultPhoneId = SubscriptionManager.INVALID_SIM_SLOT_INDEX; private int[] mRingingCallState; @@ -269,11 +282,12 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub { static final int ENFORCE_PHONE_STATE_PERMISSION_MASK = PhoneStateListener.LISTEN_CALL_FORWARDING_INDICATOR | PhoneStateListener.LISTEN_MESSAGE_WAITING_INDICATOR - | PhoneStateListener.LISTEN_EMERGENCY_NUMBER_LIST; + | PhoneStateListener.LISTEN_EMERGENCY_NUMBER_LIST + | PhoneStateListener.LISTEN_REGISTRATION_FAILURE; static final int PRECISE_PHONE_STATE_PERMISSION_MASK = - PhoneStateListener.LISTEN_PRECISE_CALL_STATE | - PhoneStateListener.LISTEN_PRECISE_DATA_CONNECTION_STATE; + PhoneStateListener.LISTEN_PRECISE_CALL_STATE + | PhoneStateListener.LISTEN_PRECISE_DATA_CONNECTION_STATE; static final int READ_ACTIVE_EMERGENCY_SESSION_PERMISSION_MASK = PhoneStateListener.LISTEN_OUTGOING_EMERGENCY_CALL @@ -291,7 +305,7 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub { int numPhones = getTelephonyManager().getPhoneCount(); for (int sub = 0; sub < numPhones; sub++) { TelephonyRegistry.this.notifyCellLocationForSubscriber(sub, - mCellLocation[sub]); + mCellIdentity[sub]); } break; } @@ -355,7 +369,7 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub { SubscriptionManager.getDefaultSubscriptionId()); int newDefaultPhoneId = intent.getIntExtra( SubscriptionManager.EXTRA_SLOT_INDEX, - SubscriptionManager.getPhoneId(newDefaultSubId)); + getPhoneIdFromSubId(newDefaultSubId)); if (DBG) { log("onReceive:current mDefaultSubId=" + mDefaultSubId + " current mDefaultPhoneId=" + mDefaultPhoneId @@ -397,10 +411,14 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub { mVoiceActivationState = copyOf(mVoiceActivationState, mNumPhones); mDataActivationState = copyOf(mDataActivationState, mNumPhones); mUserMobileDataState = copyOf(mUserMobileDataState, mNumPhones); - mSignalStrength = copyOf(mSignalStrength, mNumPhones); + if (mSignalStrength != null) { + mSignalStrength = copyOf(mSignalStrength, mNumPhones); + } else { + mSignalStrength = new SignalStrength[mNumPhones]; + } mMessageWaiting = copyOf(mMessageWaiting, mNumPhones); mCallForwarding = copyOf(mCallForwarding, mNumPhones); - mCellLocation = copyOf(mCellLocation, mNumPhones); + mCellIdentity = copyOf(mCellIdentity, mNumPhones); mSrvccState = copyOf(mSrvccState, mNumPhones); mPreciseCallState = copyOf(mPreciseCallState, mNumPhones); mForegroundCallState = copyOf(mForegroundCallState, mNumPhones); @@ -431,11 +449,11 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub { mDataActivationState[i] = TelephonyManager.SIM_ACTIVATION_STATE_UNKNOWN; mCallIncomingNumber[i] = ""; mServiceState[i] = new ServiceState(); - mSignalStrength[i] = new SignalStrength(); + mSignalStrength[i] = null; mUserMobileDataState[i] = false; mMessageWaiting[i] = false; mCallForwarding[i] = false; - mCellLocation[i] = new Bundle(); + mCellIdentity[i] = null; mCellInfo.add(i, null); mImsReasonInfo.add(i, null); mSrvccState[i] = TelephonyManager.SRVCC_STATE_HANDOVER_NONE; @@ -451,15 +469,6 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub { mBackgroundCallState[i] = PreciseCallState.PRECISE_CALL_STATE_IDLE; mPreciseDataConnectionStates.add(new HashMap<String, PreciseDataConnectionState>()); } - - // Note that location can be null for non-phone builds like - // like the generic one. - CellLocation location = CellLocation.getEmpty(); - if (location != null) { - for (int i = oldNumPhones; i < mNumPhones; i++) { - location.fillInNotifierBundle(mCellLocation[i]); - } - } } private void cutListToSize(List list, int size) { @@ -499,7 +508,7 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub { mSignalStrength = new SignalStrength[numPhones]; mMessageWaiting = new boolean[numPhones]; mCallForwarding = new boolean[numPhones]; - mCellLocation = new Bundle[numPhones]; + mCellIdentity = new CellIdentity[numPhones]; mSrvccState = new int[numPhones]; mPreciseCallState = new PreciseCallState[numPhones]; mForegroundCallState = new int[numPhones]; @@ -524,11 +533,11 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub { mDataActivationState[i] = TelephonyManager.SIM_ACTIVATION_STATE_UNKNOWN; mCallIncomingNumber[i] = ""; mServiceState[i] = new ServiceState(); - mSignalStrength[i] = new SignalStrength(); + mSignalStrength[i] = null; mUserMobileDataState[i] = false; mMessageWaiting[i] = false; mCallForwarding[i] = false; - mCellLocation[i] = new Bundle(); + mCellIdentity[i] = null; mCellInfo.add(i, null); mImsReasonInfo.add(i, null); mSrvccState[i] = TelephonyManager.SRVCC_STATE_HANDOVER_NONE; @@ -545,14 +554,6 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub { mPreciseDataConnectionStates.add(new HashMap<String, PreciseDataConnectionState>()); } - // Note that location can be null for non-phone builds like - // like the generic one. - if (location != null) { - for (int i = 0; i < numPhones; i++) { - location.fillInNotifierBundle(mCellLocation[i]); - } - } - mAppOps = mContext.getSystemService(AppOpsManager.class); } @@ -568,7 +569,7 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub { } @Override - public void addOnSubscriptionsChangedListener(String callingPackage, + public void addOnSubscriptionsChangedListener(String callingPackage, String callingFeatureId, IOnSubscriptionsChangedListener callback) { int callerUserId = UserHandle.getCallingUserId(); mAppOps.checkPackage(Binder.getCallingUid(), callingPackage); @@ -590,6 +591,7 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub { r.context = mContext; r.onSubscriptionsChangedListenerCallback = callback; r.callingPackage = callingPackage; + r.callingFeatureId = callingFeatureId; r.callerUid = Binder.getCallingUid(); r.callerPid = Binder.getCallingPid(); r.events = 0; @@ -622,7 +624,7 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub { @Override public void addOnOpportunisticSubscriptionsChangedListener(String callingPackage, - IOnSubscriptionsChangedListener callback) { + String callingFeatureId, IOnSubscriptionsChangedListener callback) { int callerUserId = UserHandle.getCallingUserId(); mAppOps.checkPackage(Binder.getCallingUid(), callingPackage); if (VDBG) { @@ -643,6 +645,7 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub { r.context = mContext; r.onOpportunisticSubscriptionsChangedListenerCallback = callback; r.callingPackage = callingPackage; + r.callingFeatureId = callingFeatureId; r.callerUid = Binder.getCallingUid(); r.callerPid = Binder.getCallingPid(); r.events = 0; @@ -718,21 +721,28 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub { } } + @Deprecated @Override - public void listen(String pkgForDebug, IPhoneStateListener callback, int events, + public void listen(String callingPackage, IPhoneStateListener callback, int events, boolean notifyNow) { - listenForSubscriber(SubscriptionManager.DEFAULT_SUBSCRIPTION_ID, pkgForDebug, callback, - events, notifyNow); + listenWithFeature(callingPackage, null, callback, events, notifyNow); } @Override - public void listenForSubscriber(int subId, String pkgForDebug, IPhoneStateListener callback, - int events, boolean notifyNow) { - listen(pkgForDebug, callback, events, notifyNow, subId); + public void listenWithFeature(String callingPackage, String callingFeatureId, + IPhoneStateListener callback, int events, boolean notifyNow) { + listenForSubscriber(SubscriptionManager.DEFAULT_SUBSCRIPTION_ID, callingPackage, + callingFeatureId, callback, events, notifyNow); } - private void listen(String callingPackage, IPhoneStateListener callback, int events, - boolean notifyNow, int subId) { + @Override + public void listenForSubscriber(int subId, String callingPackage, String callingFeatureId, + IPhoneStateListener callback, int events, boolean notifyNow) { + listen(callingPackage, callingFeatureId, callback, events, notifyNow, subId); + } + + private void listen(String callingPackage, @Nullable String callingFeatureId, + IPhoneStateListener callback, int events, boolean notifyNow, int subId) { int callerUserId = UserHandle.getCallingUserId(); mAppOps.checkPackage(Binder.getCallingUid(), callingPackage); String str = "listen: E pkg=" + callingPackage + " events=0x" + Integer.toHexString(events) @@ -747,11 +757,12 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub { // Checks permission and throws SecurityException for disallowed operations. For pre-M // apps whose runtime permission has been revoked, we return immediately to skip sending // events to the app without crashing it. - if (!checkListenerPermission(events, subId, callingPackage, "listen")) { + if (!checkListenerPermission(events, subId, callingPackage, callingFeatureId, + "listen")) { return; } - int phoneId = SubscriptionManager.getPhoneId(subId); + int phoneId = getPhoneIdFromSubId(subId); synchronized (mRecords) { // register IBinder b = callback.asBinder(); @@ -764,6 +775,7 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub { r.context = mContext; r.callback = callback; r.callingPackage = callingPackage; + r.callingFeatureId = callingFeatureId; r.callerUid = Binder.getCallingUid(); r.callerPid = Binder.getCallingPid(); // Legacy applications pass SubscriptionManager.DEFAULT_SUB_ID, @@ -786,9 +798,11 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub { if (checkFineLocationAccess(r, Build.VERSION_CODES.Q)) { r.callback.onServiceStateChanged(rawSs); } else if (checkCoarseLocationAccess(r, Build.VERSION_CODES.Q)) { - r.callback.onServiceStateChanged(rawSs.sanitizeLocationInfo(false)); + r.callback.onServiceStateChanged( + rawSs.createLocationInfoSanitizedCopy(false)); } else { - r.callback.onServiceStateChanged(rawSs.sanitizeLocationInfo(true)); + r.callback.onServiceStateChanged( + rawSs.createLocationInfoSanitizedCopy(true)); } } catch (RemoteException ex) { remove(r.binder); @@ -796,10 +810,12 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub { } if ((events & PhoneStateListener.LISTEN_SIGNAL_STRENGTH) != 0) { try { - int gsmSignalStrength = mSignalStrength[phoneId] - .getGsmSignalStrength(); - r.callback.onSignalStrengthChanged((gsmSignalStrength == 99 ? -1 - : gsmSignalStrength)); + if (mSignalStrength[phoneId] != null) { + int gsmSignalStrength = mSignalStrength[phoneId] + .getGsmSignalStrength(); + r.callback.onSignalStrengthChanged((gsmSignalStrength == 99 ? -1 + : gsmSignalStrength)); + } } catch (RemoteException ex) { remove(r.binder); } @@ -822,11 +838,10 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub { } if (validateEventsAndUserLocked(r, PhoneStateListener.LISTEN_CELL_LOCATION)) { try { - if (DBG_LOC) log("listen: mCellLocation = " - + mCellLocation[phoneId]); + if (DBG_LOC) log("listen: mCellIdentity = " + mCellIdentity[phoneId]); if (checkFineLocationAccess(r, Build.VERSION_CODES.Q)) { - r.callback.onCellLocationChanged( - new Bundle(mCellLocation[phoneId])); + // null will be translated to empty CellLocation object in client. + r.callback.onCellLocationChanged(mCellIdentity[phoneId]); } } catch (RemoteException ex) { remove(r.binder); @@ -857,7 +872,9 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub { } if ((events & PhoneStateListener.LISTEN_SIGNAL_STRENGTHS) != 0) { try { - r.callback.onSignalStrengthsChanged(mSignalStrength[phoneId]); + if (mSignalStrength[phoneId] != null) { + r.callback.onSignalStrengthsChanged(mSignalStrength[phoneId]); + } } catch (RemoteException ex) { remove(r.binder); } @@ -1077,7 +1094,7 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub { // Called only by Telecomm to communicate call state across different phone accounts. So // there is no need to add a valid subId or slotId. broadcastCallStateChanged(state, phoneNumber, - SubscriptionManager.INVALID_PHONE_INDEX, + SubscriptionManager.INVALID_SIM_SLOT_INDEX, SubscriptionManager.INVALID_SUBSCRIPTION_ID); } @@ -1144,9 +1161,9 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub { if (checkFineLocationAccess(r, Build.VERSION_CODES.Q)) { stateToSend = new ServiceState(state); } else if (checkCoarseLocationAccess(r, Build.VERSION_CODES.Q)) { - stateToSend = state.sanitizeLocationInfo(false); + stateToSend = state.createLocationInfoSanitizedCopy(false); } else { - stateToSend = state.sanitizeLocationInfo(true); + stateToSend = state.createLocationInfoSanitizedCopy(true); } if (DBG) { log("notifyServiceStateForSubscriber: callback.onSSC r=" + r @@ -1291,7 +1308,8 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub { // only CarrierService with carrier privilege rule should have the permission int[] subIds = Arrays.stream(SubscriptionManager.from(mContext) .getActiveSubscriptionIdList(false)) - .filter(i -> TelephonyPermissions.checkCarrierPrivilegeForSubId(i)).toArray(); + .filter(i -> TelephonyPermissions.checkCarrierPrivilegeForSubId(mContext, + i)).toArray(); if (ArrayUtils.isEmpty(subIds)) { loge("notifyCarrierNetworkChange without carrier privilege"); // the active subId does not have carrier privilege. @@ -1301,7 +1319,7 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub { synchronized (mRecords) { mCarrierNetworkChangeState = active; for (int subId : subIds) { - int phoneId = SubscriptionManager.getPhoneId(subId); + int phoneId = getPhoneIdFromSubId(subId); if (VDBG) { log("notifyCarrierNetworkChange: active=" + active + "subId: " + subId); @@ -1334,7 +1352,7 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub { log("notifyCellInfoForSubscriber: subId=" + subId + " cellInfo=" + cellInfo); } - int phoneId = SubscriptionManager.getPhoneId(subId); + int phoneId = getPhoneIdFromSubId(subId); synchronized (mRecords) { if (validatePhoneId(phoneId)) { mCellInfo.set(phoneId, cellInfo); @@ -1425,7 +1443,7 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub { log("notifyCallForwardingChangedForSubscriber: subId=" + subId + " cfi=" + cfi); } - int phoneId = SubscriptionManager.getPhoneId(subId); + int phoneId = getPhoneIdFromSubId(subId); synchronized (mRecords) { if (validatePhoneId(phoneId)) { mCallForwarding[phoneId] = cfi; @@ -1453,7 +1471,7 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub { if (!checkNotifyPermission("notifyDataActivity()" )) { return; } - int phoneId = SubscriptionManager.getPhoneId(subId); + int phoneId = getPhoneIdFromSubId(subId); synchronized (mRecords) { if (validatePhoneId(phoneId)) { mDataActivity[phoneId] = state; @@ -1593,7 +1611,7 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub { TelephonyManager.DATA_UNKNOWN, TelephonyManager.NETWORK_TYPE_UNKNOWN, ApnSetting.getApnTypesBitmaskFromString(apnType), null, null, - DataFailCause.NONE)); + DataFailCause.NONE, null)); for (Record r : mRecords) { if (r.matchPhoneStateListenerEvent( PhoneStateListener.LISTEN_PRECISE_DATA_CONNECTION_STATE) @@ -1612,11 +1630,13 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub { } } - public void notifyCellLocation(Bundle cellLocation) { - notifyCellLocationForSubscriber(SubscriptionManager.DEFAULT_SUBSCRIPTION_ID, cellLocation); + @Override + public void notifyCellLocation(CellIdentity cellLocation) { + notifyCellLocationForSubscriber(SubscriptionManager.DEFAULT_SUBSCRIPTION_ID, cellLocation); } - public void notifyCellLocationForSubscriber(int subId, Bundle cellLocation) { + @Override + public void notifyCellLocationForSubscriber(int subId, CellIdentity cellLocation) { log("notifyCellLocationForSubscriber: subId=" + subId + " cellLocation=" + cellLocation); if (!checkNotifyPermission("notifyCellLocation()")) { @@ -1626,10 +1646,10 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub { log("notifyCellLocationForSubscriber: subId=" + subId + " cellLocation=" + cellLocation); } - int phoneId = SubscriptionManager.getPhoneId(subId); + int phoneId = getPhoneIdFromSubId(subId); synchronized (mRecords) { if (validatePhoneId(phoneId)) { - mCellLocation[phoneId] = cellLocation; + mCellIdentity[phoneId] = cellLocation; for (Record r : mRecords) { if (validateEventsAndUserLocked(r, PhoneStateListener.LISTEN_CELL_LOCATION) && idMatch(r.subId, subId, phoneId) && @@ -1639,7 +1659,7 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub { log("notifyCellLocation: cellLocation=" + cellLocation + " r=" + r); } - r.callback.onCellLocationChanged(new Bundle(cellLocation)); + r.callback.onCellLocationChanged(cellLocation); } catch (RemoteException ex) { mRemoveList.add(r.binder); } @@ -1735,7 +1755,7 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub { if (!checkNotifyPermission("notifyImsCallDisconnectCause()")) { return; } - int phoneId = SubscriptionManager.getPhoneId(subId); + int phoneId = getPhoneIdFromSubId(subId); synchronized (mRecords) { if (validatePhoneId(phoneId)) { mImsReasonInfo.set(phoneId, imsReasonInfo); @@ -1776,7 +1796,7 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub { TelephonyManager.DATA_UNKNOWN, TelephonyManager.NETWORK_TYPE_UNKNOWN, ApnSetting.getApnTypesBitmaskFromString(apnType), null, null, - failCause)); + failCause, null)); for (Record r : mRecords) { if (r.matchPhoneStateListenerEvent( PhoneStateListener.LISTEN_PRECISE_DATA_CONNECTION_STATE) @@ -1802,7 +1822,7 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub { if (VDBG) { log("notifySrvccStateChanged: subId=" + subId + " srvccState=" + state); } - int phoneId = SubscriptionManager.getPhoneId(subId); + int phoneId = getPhoneIdFromSubId(subId); synchronized (mRecords) { if (validatePhoneId(phoneId)) { mSrvccState[phoneId] = state; @@ -2048,6 +2068,40 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub { } @Override + public void notifyRegistrationFailed(int phoneId, int subId, @NonNull CellIdentity cellIdentity, + @NonNull String chosenPlmn, int domain, int causeCode, int additionalCauseCode) { + if (!checkNotifyPermission("notifyRegistrationFailed()")) { + return; + } + + // In case callers don't have fine location access, pre-construct a location-free version + // of the CellIdentity. This will still have the PLMN ID, which should be sufficient for + // most purposes. + final CellIdentity noLocationCi = cellIdentity.sanitizeLocationInfo(); + + synchronized (mRecords) { + if (validatePhoneId(phoneId)) { + for (Record r : mRecords) { + if (r.matchPhoneStateListenerEvent( + PhoneStateListener.LISTEN_REGISTRATION_FAILURE) + && idMatch(r.subId, subId, phoneId)) { + try { + r.callback.onRegistrationFailed( + checkFineLocationAccess(r, Build.VERSION_CODES.R) + ? cellIdentity : noLocationCi, + chosenPlmn, domain, causeCode, + additionalCauseCode); + } catch (RemoteException ex) { + mRemoveList.add(r.binder); + } + } + } + } + handleRemoveListLocked(); + } + } + + @Override public void dump(FileDescriptor fd, PrintWriter writer, String[] args) { final IndentingPrintWriter pw = new IndentingPrintWriter(writer, " "); @@ -2076,7 +2130,7 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub { pw.println("mCallForwarding=" + mCallForwarding[i]); pw.println("mDataActivity=" + mDataActivity[i]); pw.println("mDataConnectionState=" + mDataConnectionState[i]); - pw.println("mCellLocation=" + mCellLocation[i]); + pw.println("mCellIdentity=" + mCellIdentity[i]); pw.println("mCellInfo=" + mCellInfo.get(i)); pw.println("mImsCallDisconnectCause=" + mImsReasonInfo.get(i)); pw.println("mSrvccState=" + mSrvccState[i]); @@ -2165,13 +2219,32 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub { Intent intent = new Intent(TelephonyIntents.ACTION_SIGNAL_STRENGTH_CHANGED); Bundle data = new Bundle(); - signalStrength.fillInNotifierBundle(data); + fillInSignalStrengthNotifierBundle(signalStrength, data); intent.putExtras(data); intent.putExtra(PHONE_CONSTANTS_SUBSCRIPTION_KEY, subId); intent.putExtra(PHONE_CONSTANTS_SLOT_KEY, phoneId); mContext.sendStickyBroadcastAsUser(intent, UserHandle.ALL); } + private void fillInSignalStrengthNotifierBundle(SignalStrength signalStrength, Bundle bundle) { + List<CellSignalStrength> cellSignalStrengths = signalStrength.getCellSignalStrengths(); + for (CellSignalStrength cellSignalStrength : cellSignalStrengths) { + if (cellSignalStrength instanceof CellSignalStrengthLte) { + bundle.putParcelable("Lte", (CellSignalStrengthLte) cellSignalStrength); + } else if (cellSignalStrength instanceof CellSignalStrengthCdma) { + bundle.putParcelable("Cdma", (CellSignalStrengthCdma) cellSignalStrength); + } else if (cellSignalStrength instanceof CellSignalStrengthGsm) { + bundle.putParcelable("Gsm", (CellSignalStrengthGsm) cellSignalStrength); + } else if (cellSignalStrength instanceof CellSignalStrengthWcdma) { + bundle.putParcelable("Wcdma", (CellSignalStrengthWcdma) cellSignalStrength); + } else if (cellSignalStrength instanceof CellSignalStrengthTdscdma) { + bundle.putParcelable("Tdscdma", (CellSignalStrengthTdscdma) cellSignalStrength); + } else if (cellSignalStrength instanceof CellSignalStrengthNr) { + bundle.putParcelable("Nr", (CellSignalStrengthNr) cellSignalStrength); + } + } + } + /** * Broadcasts an intent notifying apps of a phone state change. {@code subId} can be * a valid subId, in which case this function fires a subId-specific intent, or it @@ -2208,7 +2281,7 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub { intent.putExtra(SubscriptionManager.EXTRA_SUBSCRIPTION_INDEX, subId); } // If the phoneId is invalid, the broadcast is for overall call state. - if (phoneId != SubscriptionManager.INVALID_PHONE_INDEX) { + if (phoneId != SubscriptionManager.INVALID_SIM_SLOT_INDEX) { intent.putExtra(PHONE_CONSTANTS_SLOT_KEY, phoneId); intent.putExtra(SubscriptionManager.EXTRA_SLOT_INDEX, phoneId); } @@ -2263,7 +2336,7 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub { return; } - TelephonyPermissions.enforceCallingOrSelfCarrierPrivilege( + TelephonyPermissions.enforceCallingOrSelfCarrierPrivilege(mContext, SubscriptionManager.getDefaultSubscriptionId(), method); } @@ -2282,8 +2355,8 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub { == PackageManager.PERMISSION_GRANTED; } - private boolean checkListenerPermission( - int events, int subId, String callingPackage, String message) { + private boolean checkListenerPermission(int events, int subId, String callingPackage, + @Nullable String callingFeatureId, String message) { LocationAccessPolicy.LocationPermissionQuery.Builder locationQueryBuilder = new LocationAccessPolicy.LocationPermissionQuery.Builder() .setCallingPackage(callingPackage) @@ -2318,7 +2391,7 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub { if ((events & ENFORCE_PHONE_STATE_PERMISSION_MASK) != 0) { if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState( - mContext, subId, callingPackage, message)) { + mContext, subId, callingPackage, callingFeatureId, message)) { return false; } } @@ -2480,11 +2553,14 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub { if ((events & PhoneStateListener.LISTEN_SIGNAL_STRENGTHS) != 0) { try { - SignalStrength signalStrength = mSignalStrength[phoneId]; - if (DBG) { - log("checkPossibleMissNotify: onSignalStrengthsChanged SS=" + signalStrength); + if (mSignalStrength[phoneId] != null) { + SignalStrength signalStrength = mSignalStrength[phoneId]; + if (DBG) { + log("checkPossibleMissNotify: onSignalStrengthsChanged SS=" + + signalStrength); + } + r.callback.onSignalStrengthsChanged(new SignalStrength(signalStrength)); } - r.callback.onSignalStrengthsChanged(new SignalStrength(signalStrength)); } catch (RemoteException ex) { mRemoveList.add(r.binder); } @@ -2492,14 +2568,16 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub { if ((events & PhoneStateListener.LISTEN_SIGNAL_STRENGTH) != 0) { try { - int gsmSignalStrength = mSignalStrength[phoneId] - .getGsmSignalStrength(); - if (DBG) { - log("checkPossibleMissNotify: onSignalStrengthChanged SS=" + - gsmSignalStrength); + if (mSignalStrength[phoneId] != null) { + int gsmSignalStrength = mSignalStrength[phoneId] + .getGsmSignalStrength(); + if (DBG) { + log("checkPossibleMissNotify: onSignalStrengthChanged SS=" + + gsmSignalStrength); + } + r.callback.onSignalStrengthChanged((gsmSignalStrength == 99 ? -1 + : gsmSignalStrength)); } - r.callback.onSignalStrengthChanged((gsmSignalStrength == 99 ? -1 - : gsmSignalStrength)); } catch (RemoteException ex) { mRemoveList.add(r.binder); } @@ -2559,10 +2637,13 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub { if (validateEventsAndUserLocked(r, PhoneStateListener.LISTEN_CELL_LOCATION)) { try { - if (DBG_LOC) log("checkPossibleMissNotify: onCellLocationChanged mCellLocation = " - + mCellLocation[phoneId]); + if (DBG_LOC) { + log("checkPossibleMissNotify: onCellLocationChanged mCellIdentity = " + + mCellIdentity[phoneId]); + } if (checkFineLocationAccess(r, Build.VERSION_CODES.Q)) { - r.callback.onCellLocationChanged(new Bundle(mCellLocation[phoneId])); + // null will be translated to empty CellLocation object in client. + r.callback.onCellLocationChanged(mCellIdentity[phoneId]); } } catch (RemoteException ex) { mRemoveList.add(r.binder); @@ -2673,4 +2754,18 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub { private static CallQuality createCallQuality() { return new CallQuality(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0); } + + private int getPhoneIdFromSubId(int subId) { + SubscriptionManager subManager = (SubscriptionManager) + mContext.getSystemService(Context.TELEPHONY_SUBSCRIPTION_SERVICE); + if (subManager == null) return INVALID_SIM_SLOT_INDEX; + + if (subId == SubscriptionManager.DEFAULT_SUBSCRIPTION_ID) { + subId = SubscriptionManager.getDefaultSubscriptionId(); + } + + SubscriptionInfo info = subManager.getActiveSubscriptionInfo(subId); + if (info == null) return INVALID_SIM_SLOT_INDEX; + return info.getSimSlotIndex(); + } } diff --git a/services/core/java/com/android/server/VibratorService.java b/services/core/java/com/android/server/VibratorService.java index a1480e305d9e..e7179e09c4b3 100644 --- a/services/core/java/com/android/server/VibratorService.java +++ b/services/core/java/com/android/server/VibratorService.java @@ -60,7 +60,6 @@ import android.provider.DeviceConfig; import android.provider.Settings; import android.provider.Settings.SettingNotFoundException; import android.util.DebugUtils; -import android.util.Pair; import android.util.Slog; import android.util.SparseArray; import android.util.StatsLog; @@ -162,8 +161,7 @@ public class VibratorService extends IVibratorService.Stub private int mHapticFeedbackIntensity; private int mNotificationIntensity; private int mRingIntensity; - private SparseArray<Pair<VibrationEffect, AudioAttributes>> mAlwaysOnEffects = - new SparseArray<>(); + private SparseArray<Vibration> mAlwaysOnEffects = new SparseArray<>(); static native boolean vibratorExists(); static native void vibratorInit(); @@ -477,6 +475,10 @@ public class VibratorService extends IVibratorService.Stub Settings.System.getUriFor(Settings.System.RING_VIBRATION_INTENSITY), true, mSettingObserver, UserHandle.USER_ALL); + mContext.getContentResolver().registerContentObserver( + Settings.Global.getUriFor(Settings.Global.ZEN_MODE), + true, mSettingObserver, UserHandle.USER_ALL); + mContext.registerReceiver(new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { @@ -524,7 +526,8 @@ public class VibratorService extends IVibratorService.Stub } @Override // Binder call - public boolean setAlwaysOnEffect(int id, VibrationEffect effect, AudioAttributes attrs) { + public boolean setAlwaysOnEffect(int uid, String opPkg, int alwaysOnId, VibrationEffect effect, + AudioAttributes attrs) { if (!hasPermission(android.Manifest.permission.VIBRATE_ALWAYS_ON)) { throw new SecurityException("Requires VIBRATE_ALWAYS_ON permission"); } @@ -534,8 +537,8 @@ public class VibratorService extends IVibratorService.Stub } if (effect == null) { synchronized (mLock) { - mAlwaysOnEffects.delete(id); - vibratorAlwaysOnDisable(id); + mAlwaysOnEffects.delete(alwaysOnId); + vibratorAlwaysOnDisable(alwaysOnId); } } else { if (!verifyVibrationEffect(effect)) { @@ -545,14 +548,11 @@ public class VibratorService extends IVibratorService.Stub Slog.e(TAG, "Only prebaked effects supported for always-on."); return false; } - if (attrs == null) { - attrs = new AudioAttributes.Builder() - .setUsage(AudioAttributes.USAGE_UNKNOWN) - .build(); - } + attrs = fixupVibrationAttributes(attrs); synchronized (mLock) { - mAlwaysOnEffects.put(id, Pair.create(effect, attrs)); - updateAlwaysOnLocked(id, effect, attrs); + Vibration vib = new Vibration(null, effect, attrs, uid, opPkg, null); + mAlwaysOnEffects.put(alwaysOnId, vib); + updateAlwaysOnLocked(alwaysOnId, vib); } } return true; @@ -592,6 +592,25 @@ public class VibratorService extends IVibratorService.Stub return true; } + private AudioAttributes fixupVibrationAttributes(AudioAttributes attrs) { + if (attrs == null) { + attrs = new AudioAttributes.Builder() + .setUsage(AudioAttributes.USAGE_UNKNOWN) + .build(); + } + if (shouldBypassDnd(attrs)) { + if (!(hasPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) + || hasPermission(android.Manifest.permission.MODIFY_PHONE_STATE) + || hasPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING))) { + final int flags = attrs.getAllFlags() + & ~AudioAttributes.FLAG_BYPASS_INTERRUPTION_POLICY; + attrs = new AudioAttributes.Builder(attrs).replaceFlags(flags).build(); + } + } + + return attrs; + } + private static long[] getLongIntArray(Resources r, int resid) { int[] ar = r.getIntArray(resid); if (ar == null) { @@ -621,21 +640,7 @@ public class VibratorService extends IVibratorService.Stub return; } - if (attrs == null) { - attrs = new AudioAttributes.Builder() - .setUsage(AudioAttributes.USAGE_UNKNOWN) - .build(); - } - - if (shouldBypassDnd(attrs)) { - if (!(hasPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) - || hasPermission(android.Manifest.permission.MODIFY_PHONE_STATE) - || hasPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING))) { - final int flags = attrs.getAllFlags() - & ~AudioAttributes.FLAG_BYPASS_INTERRUPTION_POLICY; - attrs = new AudioAttributes.Builder(attrs).replaceFlags(flags).build(); - } - } + attrs = fixupVibrationAttributes(attrs); // If our current vibration is longer than the new vibration and is the same amplitude, // then just let the current one finish. @@ -796,29 +801,8 @@ public class VibratorService extends IVibratorService.Stub private void startVibrationLocked(final Vibration vib) { Trace.traceBegin(Trace.TRACE_TAG_VIBRATOR, "startVibrationLocked"); try { - if (!isAllowedToVibrateLocked(vib)) { - return; - } - final int intensity = getCurrentIntensityLocked(vib); - if (intensity == Vibrator.VIBRATION_INTENSITY_OFF) { - return; - } - - if (vib.isRingtone() && !shouldVibrateForRingtone()) { - if (DEBUG) { - Slog.e(TAG, "Vibrate ignored, not vibrating for ringtones"); - } - return; - } - - final int mode = getAppOpMode(vib); - if (mode != AppOpsManager.MODE_ALLOWED) { - if (mode == AppOpsManager.MODE_ERRORED) { - // We might be getting calls from within system_server, so we don't actually - // want to throw a SecurityException here. - Slog.w(TAG, "Would be an error: vibrate from uid " + vib.uid); - } + if (!shouldVibrate(vib, intensity)) { return; } applyVibrationIntensityScalingLocked(vib, intensity); @@ -985,6 +969,35 @@ public class VibratorService extends IVibratorService.Stub return mode; } + private boolean shouldVibrate(Vibration vib, int intensity) { + if (!isAllowedToVibrateLocked(vib)) { + return false; + } + + if (intensity == Vibrator.VIBRATION_INTENSITY_OFF) { + return false; + } + + if (vib.isRingtone() && !shouldVibrateForRingtone()) { + if (DEBUG) { + Slog.e(TAG, "Vibrate ignored, not vibrating for ringtones"); + } + return false; + } + + final int mode = getAppOpMode(vib); + if (mode != AppOpsManager.MODE_ALLOWED) { + if (mode == AppOpsManager.MODE_ERRORED) { + // We might be getting calls from within system_server, so we don't actually + // want to throw a SecurityException here. + Slog.w(TAG, "Would be an error: vibrate from uid " + vib.uid); + } + return false; + } + + return true; + } + @GuardedBy("mLock") private void reportFinishVibrationLocked() { Trace.traceBegin(Trace.TRACE_TAG_VIBRATOR, "reportFinishVibrationLocked"); @@ -1096,14 +1109,12 @@ public class VibratorService extends IVibratorService.Stub mVibrator.getDefaultRingVibrationIntensity(), UserHandle.USER_CURRENT); } - private void updateAlwaysOnLocked(int id, VibrationEffect effect, AudioAttributes attrs) { - // TODO: Check DND and LowPower settings - final Vibration vib = new Vibration(null, effect, attrs, 0, null, null); + private void updateAlwaysOnLocked(int id, Vibration vib) { final int intensity = getCurrentIntensityLocked(vib); - if (intensity == Vibrator.VIBRATION_INTENSITY_OFF) { + if (!shouldVibrate(vib, intensity)) { vibratorAlwaysOnDisable(id); } else { - final VibrationEffect.Prebaked prebaked = (VibrationEffect.Prebaked) effect; + final VibrationEffect.Prebaked prebaked = (VibrationEffect.Prebaked) vib.effect; final int strength = intensityToEffectStrength(intensity); vibratorAlwaysOnEnable(id, prebaked.getId(), strength); } @@ -1112,8 +1123,8 @@ public class VibratorService extends IVibratorService.Stub private void updateAlwaysOnLocked() { for (int i = 0; i < mAlwaysOnEffects.size(); i++) { int id = mAlwaysOnEffects.keyAt(i); - Pair<VibrationEffect, AudioAttributes> pair = mAlwaysOnEffects.valueAt(i); - updateAlwaysOnLocked(id, pair.first, pair.second); + Vibration vib = mAlwaysOnEffects.valueAt(i); + updateAlwaysOnLocked(id, vib); } } diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java index 1c4f1e3ed5bf..2af04ae3f800 100644 --- a/services/core/java/com/android/server/am/ActivityManagerService.java +++ b/services/core/java/com/android/server/am/ActivityManagerService.java @@ -5280,7 +5280,7 @@ public class ActivityManagerService extends IActivityManager.Stub storageManager.commitChanges(); } catch (Exception e) { PowerManager pm = (PowerManager) - mInjector.getContext().getSystemService(Context.POWER_SERVICE); + mContext.getSystemService(Context.POWER_SERVICE); pm.reboot("Checkpoint commit failed"); } diff --git a/services/core/java/com/android/server/am/ActivityManagerShellCommand.java b/services/core/java/com/android/server/am/ActivityManagerShellCommand.java index b406ce6c3ca8..972b10608056 100644 --- a/services/core/java/com/android/server/am/ActivityManagerShellCommand.java +++ b/services/core/java/com/android/server/am/ActivityManagerShellCommand.java @@ -2899,33 +2899,37 @@ final class ActivityManagerShellCommand extends ShellCommand { } ArraySet<Long> enabled = new ArraySet<>(); ArraySet<Long> disabled = new ArraySet<>(); - switch (toggleValue) { - case "enable": - enabled.add(changeId); - pw.println("Enabled change " + changeId + " for " + packageName + "."); - CompatibilityChangeConfig overrides = - new CompatibilityChangeConfig( - new Compatibility.ChangeConfig(enabled, disabled)); - platformCompat.setOverrides(overrides, packageName); - return 0; - case "disable": - disabled.add(changeId); - pw.println("Disabled change " + changeId + " for " + packageName + "."); - overrides = - new CompatibilityChangeConfig( - new Compatibility.ChangeConfig(enabled, disabled)); - platformCompat.setOverrides(overrides, packageName); - return 0; - case "reset": - if (platformCompat.clearOverride(changeId, packageName)) { - pw.println("Reset change " + changeId + " for " + packageName - + " to default value."); - } else { - pw.println("No override exists for changeId " + changeId + "."); - } - return 0; - default: - pw.println("Invalid toggle value: '" + toggleValue + "'."); + try { + switch (toggleValue) { + case "enable": + enabled.add(changeId); + CompatibilityChangeConfig overrides = + new CompatibilityChangeConfig( + new Compatibility.ChangeConfig(enabled, disabled)); + platformCompat.setOverrides(overrides, packageName); + pw.println("Enabled change " + changeId + " for " + packageName + "."); + return 0; + case "disable": + disabled.add(changeId); + overrides = + new CompatibilityChangeConfig( + new Compatibility.ChangeConfig(enabled, disabled)); + platformCompat.setOverrides(overrides, packageName); + pw.println("Disabled change " + changeId + " for " + packageName + "."); + return 0; + case "reset": + if (platformCompat.clearOverride(changeId, packageName)) { + pw.println("Reset change " + changeId + " for " + packageName + + " to default value."); + } else { + pw.println("No override exists for changeId " + changeId + "."); + } + return 0; + default: + pw.println("Invalid toggle value: '" + toggleValue + "'."); + } + } catch (SecurityException e) { + pw.println(e.getMessage()); } return -1; } diff --git a/services/core/java/com/android/server/am/ProcessList.java b/services/core/java/com/android/server/am/ProcessList.java index f5579761c151..766fa3ba55c1 100644 --- a/services/core/java/com/android/server/am/ProcessList.java +++ b/services/core/java/com/android/server/am/ProcessList.java @@ -1363,7 +1363,7 @@ public final class ProcessList { final int procCount = procs.size(); for (int i = 0; i < procCount; i++) { final int procUid = procs.keyAt(i); - if (UserHandle.isApp(procUid) || !UserHandle.isSameUser(procUid, uid)) { + if (!UserHandle.isCore(procUid) || !UserHandle.isSameUser(procUid, uid)) { // Don't use an app process or different user process for system component. continue; } diff --git a/services/core/java/com/android/server/appop/AppOpsService.java b/services/core/java/com/android/server/appop/AppOpsService.java index 314e04c8da32..d45bc72aee11 100644 --- a/services/core/java/com/android/server/appop/AppOpsService.java +++ b/services/core/java/com/android/server/appop/AppOpsService.java @@ -1110,8 +1110,8 @@ public class AppOpsService extends IAppOpsService.Stub { return Collections.emptyList(); } synchronized (this) { - Ops pkgOps = getOpsRawLocked(uid, resolvedPackageName, false /* edit */, - false /* uidMismatchExpected */); + Ops pkgOps = getOpsRawLocked(uid, resolvedPackageName, false /* isPrivileged */, + false /* edit */); if (pkgOps == null) { return null; } @@ -1208,8 +1208,7 @@ public class AppOpsService extends IAppOpsService.Stub { private void pruneOp(Op op, int uid, String packageName) { if (!op.hasAnyTime()) { - Ops ops = getOpsRawLocked(uid, packageName, false /* edit */, - false /* uidMismatchExpected */); + Ops ops = getOpsRawLocked(uid, packageName, false /* isPrivileged */, false /* edit */); if (ops != null) { ops.remove(op.op); if (ops.size() <= 0) { @@ -1409,11 +1408,6 @@ public class AppOpsService extends IAppOpsService.Stub { } } - @Override - public void setMode(int code, int uid, String packageName, int mode) { - setMode(code, uid, packageName, mode, true, false); - } - /** * Sets the mode for a certain op and uid. * @@ -1421,19 +1415,25 @@ public class AppOpsService extends IAppOpsService.Stub { * @param uid The UID for which to set * @param packageName The package for which to set * @param mode The new mode to set - * @param verifyUid Iff {@code true}, check that the package name belongs to the uid - * @param isPrivileged Whether the package is privileged. (Only used if {@code verifyUid == - * false}) */ - private void setMode(int code, int uid, @NonNull String packageName, int mode, - boolean verifyUid, boolean isPrivileged) { + @Override + public void setMode(int code, int uid, @NonNull String packageName, int mode) { enforceManageAppOpsModes(Binder.getCallingPid(), Binder.getCallingUid(), uid); verifyIncomingOp(code); ArraySet<ModeCallback> repCbs = null; code = AppOpsManager.opToSwitch(code); + + boolean isPrivileged; + try { + isPrivileged = verifyAndGetIsPrivileged(uid, packageName); + } catch (SecurityException e) { + Slog.e(TAG, "Cannot setMode", e); + return; + } + synchronized (this) { UidState uidState = getUidStateLocked(uid, false); - Op op = getOpLocked(code, uid, packageName, true, verifyUid, isPrivileged); + Op op = getOpLocked(code, uid, packageName, isPrivileged, true); if (op != null) { if (op.mode != mode) { op.mode = mode; @@ -1799,34 +1799,32 @@ public class AppOpsService extends IAppOpsService.Stub { } /** - * @see #checkOperationUnchecked(int, int, String, boolean, boolean) - */ - private @Mode int checkOperationUnchecked(int code, int uid, @NonNull String packageName, - boolean raw) { - return checkOperationUnchecked(code, uid, packageName, raw, true); - } - - /** * Get the mode of an app-op. * * @param code The code of the op * @param uid The uid of the package the op belongs to * @param packageName The package the op belongs to * @param raw If the raw state of eval-ed state should be checked. - * @param verify If the code should check the package belongs to the uid * * @return The mode of the op */ private @Mode int checkOperationUnchecked(int code, int uid, @NonNull String packageName, - boolean raw, boolean verify) { + boolean raw) { if (isOpRestrictedDueToSuspend(code, packageName, uid)) { return AppOpsManager.MODE_IGNORED; } + + boolean isPrivileged; + + try { + isPrivileged = verifyAndGetIsPrivileged(uid, packageName); + } catch (SecurityException e) { + Slog.e(TAG, "checkOperation", e); + return AppOpsManager.opToDefaultMode(code); + } + synchronized (this) { - if (verify) { - checkPackage(uid, packageName); - } - if (isOpRestrictedLocked(uid, code, packageName)) { + if (isOpRestrictedLocked(uid, code, packageName, isPrivileged)) { return AppOpsManager.MODE_IGNORED; } code = AppOpsManager.opToSwitch(code); @@ -1836,7 +1834,7 @@ public class AppOpsService extends IAppOpsService.Stub { final int rawMode = uidState.opModes.get(code); return raw ? rawMode : uidState.evalMode(code, rawMode); } - Op op = getOpLocked(code, uid, packageName, false, verify, false); + Op op = getOpLocked(code, uid, packageName, false, false); if (op == null) { return AppOpsManager.opToDefaultMode(code); } @@ -1941,14 +1939,12 @@ public class AppOpsService extends IAppOpsService.Stub { @Override public int checkPackage(int uid, String packageName) { Preconditions.checkNotNull(packageName); - synchronized (this) { - Ops ops = getOpsRawLocked(uid, packageName, true /* edit */, - true /* uidMismatchExpected */); - if (ops != null) { - return AppOpsManager.MODE_ALLOWED; - } else { - return AppOpsManager.MODE_ERRORED; - } + try { + verifyAndGetIsPrivileged(uid, packageName); + + return AppOpsManager.MODE_ALLOWED; + } catch (SecurityException ignored) { + return AppOpsManager.MODE_ERRORED; } } @@ -2011,9 +2007,16 @@ public class AppOpsService extends IAppOpsService.Stub { private int noteOperationUnchecked(int code, int uid, String packageName, int proxyUid, String proxyPackageName, @OpFlags int flags) { + boolean isPrivileged; + try { + isPrivileged = verifyAndGetIsPrivileged(uid, packageName); + } catch (SecurityException e) { + Slog.e(TAG, "noteOperation", e); + return AppOpsManager.MODE_ERRORED; + } + synchronized (this) { - final Ops ops = getOpsRawLocked(uid, packageName, true /* edit */, - false /* uidMismatchExpected */); + final Ops ops = getOpsRawLocked(uid, packageName, isPrivileged, true /* edit */); if (ops == null) { scheduleOpNotedIfNeededLocked(code, uid, packageName, AppOpsManager.MODE_IGNORED); @@ -2022,7 +2025,7 @@ public class AppOpsService extends IAppOpsService.Stub { return AppOpsManager.MODE_ERRORED; } final Op op = getOpLocked(ops, code, true); - if (isOpRestrictedLocked(uid, code, packageName)) { + if (isOpRestrictedLocked(uid, code, packageName, isPrivileged)) { scheduleOpNotedIfNeededLocked(code, uid, packageName, AppOpsManager.MODE_IGNORED); return AppOpsManager.MODE_IGNORED; @@ -2181,16 +2184,25 @@ public class AppOpsService extends IAppOpsService.Stub { return AppOpsManager.MODE_IGNORED; } ClientState client = (ClientState)token; + + boolean isPrivileged; + try { + isPrivileged = verifyAndGetIsPrivileged(uid, packageName); + } catch (SecurityException e) { + Slog.e(TAG, "startOperation", e); + return AppOpsManager.MODE_ERRORED; + } + synchronized (this) { - final Ops ops = getOpsRawLocked(uid, resolvedPackageName, true /* edit */, - false /* uidMismatchExpected */); + final Ops ops = getOpsRawLocked(uid, resolvedPackageName, isPrivileged, + true /* edit */); if (ops == null) { if (DEBUG) Slog.d(TAG, "startOperation: no op for code " + code + " uid " + uid + " package " + resolvedPackageName); return AppOpsManager.MODE_ERRORED; } final Op op = getOpLocked(ops, code, true); - if (isOpRestrictedLocked(uid, code, resolvedPackageName)) { + if (isOpRestrictedLocked(uid, code, resolvedPackageName, isPrivileged)) { return AppOpsManager.MODE_IGNORED; } final int switchCode = AppOpsManager.opToSwitch(code); @@ -2262,8 +2274,17 @@ public class AppOpsService extends IAppOpsService.Stub { return; } ClientState client = (ClientState) token; + + boolean isPrivileged; + try { + isPrivileged = verifyAndGetIsPrivileged(uid, packageName); + } catch (SecurityException e) { + Slog.e(TAG, "Cannot finishOperation", e); + return; + } + synchronized (this) { - Op op = getOpLocked(code, uid, resolvedPackageName, true, true, false); + Op op = getOpLocked(code, uid, resolvedPackageName, isPrivileged, true); if (op == null) { return; } @@ -2513,8 +2534,76 @@ public class AppOpsService extends IAppOpsService.Stub { uidState.pendingStateCommitTime = 0; } - private Ops getOpsRawLocked(int uid, String packageName, boolean edit, - boolean uidMismatchExpected) { + /** + * Verify that package belongs to uid and return whether the package is privileged. + * + * @param uid The uid the package belongs to + * @param packageName The package the might belong to the uid + * + * @return {@code true} iff the package is privileged + */ + private boolean verifyAndGetIsPrivileged(int uid, String packageName) { + if (uid == Process.ROOT_UID) { + // For backwards compatibility, don't check package name for root UID. + return false; + } + + // Do not check if uid/packageName is already known + synchronized (this) { + UidState uidState = mUidStates.get(uid); + if (uidState != null && uidState.pkgOps != null) { + Ops ops = uidState.pkgOps.get(packageName); + + if (ops != null) { + return ops.isPrivileged; + } + } + } + + boolean isPrivileged = false; + final long ident = Binder.clearCallingIdentity(); + try { + int pkgUid; + + ApplicationInfo appInfo = LocalServices.getService(PackageManagerInternal.class) + .getApplicationInfo(packageName, PackageManager.MATCH_DIRECT_BOOT_AWARE + | PackageManager.MATCH_DIRECT_BOOT_UNAWARE + | PackageManager.MATCH_HIDDEN_UNTIL_INSTALLED_COMPONENTS + | PackageManager.MATCH_UNINSTALLED_PACKAGES + | PackageManager.MATCH_INSTANT, + Process.SYSTEM_UID, UserHandle.getUserId(uid)); + if (appInfo != null) { + pkgUid = appInfo.uid; + isPrivileged = (appInfo.privateFlags + & ApplicationInfo.PRIVATE_FLAG_PRIVILEGED) != 0; + } else { + pkgUid = resolveUid(packageName); + if (pkgUid >= 0) { + isPrivileged = false; + } + } + if (pkgUid != uid) { + throw new SecurityException("Specified package " + packageName + " under uid " + uid + + " but it is really " + pkgUid); + } + } finally { + Binder.restoreCallingIdentity(ident); + } + + return isPrivileged; + } + + /** + * Get (and potentially create) ops. + * + * @param uid The uid the package belongs to + * @param packageName The name of the package + * @param isPrivileged If the package is privilidged (ignored if {@code edit} is false) + * @param edit If an ops does not exist, create the ops? + + * @return + */ + private Ops getOpsRawLocked(int uid, String packageName, boolean isPrivileged, boolean edit) { UidState uidState = getUidStateLocked(uid, edit); if (uidState == null) { return null; @@ -2532,47 +2621,6 @@ public class AppOpsService extends IAppOpsService.Stub { if (!edit) { return null; } - boolean isPrivileged = false; - // This is the first time we have seen this package name under this uid, - // so let's make sure it is valid. - if (uid != 0) { - final long ident = Binder.clearCallingIdentity(); - try { - int pkgUid = -1; - try { - ApplicationInfo appInfo = ActivityThread.getPackageManager() - .getApplicationInfo(packageName, - PackageManager.MATCH_DIRECT_BOOT_AWARE - | PackageManager.MATCH_DIRECT_BOOT_UNAWARE, - UserHandle.getUserId(uid)); - if (appInfo != null) { - pkgUid = appInfo.uid; - isPrivileged = (appInfo.privateFlags - & ApplicationInfo.PRIVATE_FLAG_PRIVILEGED) != 0; - } else { - pkgUid = resolveUid(packageName); - if (pkgUid >= 0) { - isPrivileged = false; - } - } - } catch (RemoteException e) { - Slog.w(TAG, "Could not contact PackageManager", e); - } - if (pkgUid != uid) { - // Oops! The package name is not valid for the uid they are calling - // under. Abort. - if (!uidMismatchExpected) { - RuntimeException ex = new RuntimeException("here"); - ex.fillInStackTrace(); - Slog.w(TAG, "Bad call: specified package " + packageName - + " under uid " + uid + " but it is really " + pkgUid, ex); - } - return null; - } - } finally { - Binder.restoreCallingIdentity(ident); - } - } ops = new Ops(packageName, uidState, isPrivileged); uidState.pkgOps.put(packageName, ops); } @@ -2580,7 +2628,7 @@ public class AppOpsService extends IAppOpsService.Stub { } /** - * Get the state of all ops for a package, <b>don't verify that package belongs to uid</b>. + * Get the state of all ops for a package. * * <p>Usually callers should use {@link #getOpLocked} and not call this directly. * @@ -2638,23 +2686,15 @@ public class AppOpsService extends IAppOpsService.Stub { * @param code The code of the op * @param uid The uid the of the package * @param packageName The package name for which to get the state for + * @param isPrivileged Whether the package is privileged or not (only used if {@code edit + * == true}) * @param edit Iff {@code true} create the {@link Op} object if not yet created - * @param verifyUid Iff {@code true} check that the package belongs to the uid - * @param isPrivileged Whether the package is privileged or not (only used if {@code verifyUid - * == false}) * * @return The {@link Op state} of the op */ - private @Nullable Op getOpLocked(int code, int uid, @NonNull String packageName, boolean edit, - boolean verifyUid, boolean isPrivileged) { - Ops ops; - - if (verifyUid) { - ops = getOpsRawLocked(uid, packageName, edit, false /* uidMismatchExpected */); - } else { - ops = getOpsRawNoVerifyLocked(uid, packageName, edit, isPrivileged); - } - + private @Nullable Op getOpLocked(int code, int uid, @NonNull String packageName, + boolean isPrivileged, boolean edit) { + Ops ops = getOpsRawNoVerifyLocked(uid, packageName, edit, isPrivileged); if (ops == null) { return null; } @@ -2684,7 +2724,8 @@ public class AppOpsService extends IAppOpsService.Stub { return pmi.isPackageSuspended(packageName, UserHandle.getUserId(uid)); } - private boolean isOpRestrictedLocked(int uid, int code, String packageName) { + private boolean isOpRestrictedLocked(int uid, int code, String packageName, + boolean isPrivileged) { int userHandle = UserHandle.getUserId(uid); final int restrictionSetCount = mOpUserRestrictions.size(); @@ -2696,8 +2737,8 @@ public class AppOpsService extends IAppOpsService.Stub { if (AppOpsManager.opAllowSystemBypassRestriction(code)) { // If we are the system, bypass user restrictions for certain codes synchronized (this) { - Ops ops = getOpsRawLocked(uid, packageName, true /* edit */, - false /* uidMismatchExpected */); + Ops ops = getOpsRawLocked(uid, packageName, isPrivileged, + true /* edit */); if ((ops != null) && ops.isPrivileged) { return false; } @@ -3068,7 +3109,7 @@ public class AppOpsService extends IAppOpsService.Stub { out.attribute(null, "n", Integer.toString(pkg.getUid())); synchronized (this) { Ops ops = getOpsRawLocked(pkg.getUid(), pkg.getPackageName(), - false /* edit */, false /* uidMismatchExpected */); + false /* isPrivileged */, false /* edit */); // Should always be present as the list of PackageOps is generated // from Ops. if (ops != null) { @@ -4647,18 +4688,8 @@ public class AppOpsService extends IAppOpsService.Stub { } @Override - public void setUidMode(int code, int uid, int mode) { - AppOpsService.this.setUidMode(code, uid, mode); - } - - @Override public void setAllPkgModesToDefault(int code, int uid) { AppOpsService.this.setAllPkgModesToDefault(code, uid); } - - @Override - public @Mode int checkOperationUnchecked(int code, int uid, @NonNull String packageName) { - return AppOpsService.this.checkOperationUnchecked(code, uid, packageName, true, false); - } } } diff --git a/services/core/java/com/android/server/appop/TEST_MAPPING b/services/core/java/com/android/server/appop/TEST_MAPPING index a53797dfa9e0..1a5dac503463 100644 --- a/services/core/java/com/android/server/appop/TEST_MAPPING +++ b/services/core/java/com/android/server/appop/TEST_MAPPING @@ -10,6 +10,14 @@ "include-filter": "com.android.server.appop" } ] + }, + { + "name": "FrameworksMockingServicesTests", + "options": [ + { + "include-filter": "com.android.server.appop" + } + ] } ] } diff --git a/services/core/java/com/android/server/audio/AudioService.java b/services/core/java/com/android/server/audio/AudioService.java index 25fdf6447061..88a63f1aa06d 100644 --- a/services/core/java/com/android/server/audio/AudioService.java +++ b/services/core/java/com/android/server/audio/AudioService.java @@ -6292,7 +6292,7 @@ public class AudioService extends IAudioService.Stub return false; } boolean suppress = false; - if (resolvedStream == DEFAULT_VOL_STREAM_NO_PLAYBACK && mController != null) { + if (resolvedStream != AudioSystem.STREAM_MUSIC && mController != null) { final long now = SystemClock.uptimeMillis(); if ((flags & AudioManager.FLAG_SHOW_UI) != 0 && !mVisible) { // ui will become visible diff --git a/services/core/java/com/android/server/compat/CompatConfig.java b/services/core/java/com/android/server/compat/CompatConfig.java index cf83dd630a29..f15d999e1006 100644 --- a/services/core/java/com/android/server/compat/CompatConfig.java +++ b/services/core/java/com/android/server/compat/CompatConfig.java @@ -17,8 +17,10 @@ package com.android.server.compat; import android.compat.Compatibility.ChangeConfig; +import android.content.Context; import android.content.pm.ApplicationInfo; import android.os.Environment; +import android.os.RemoteException; import android.text.TextUtils; import android.util.LongArray; import android.util.LongSparseArray; @@ -26,8 +28,11 @@ import android.util.Slog; import com.android.internal.annotations.GuardedBy; import com.android.internal.annotations.VisibleForTesting; +import com.android.internal.compat.AndroidBuildClassifier; import com.android.internal.compat.CompatibilityChangeConfig; import com.android.internal.compat.CompatibilityChangeInfo; +import com.android.internal.compat.IOverrideValidator; +import com.android.internal.compat.OverrideAllowedState; import com.android.server.compat.config.Change; import com.android.server.compat.config.XmlParser; @@ -54,22 +59,14 @@ final class CompatConfig { private static final String TAG = "CompatConfig"; - private static final CompatConfig sInstance = new CompatConfig().initConfigFromLib( - Environment.buildPath( - Environment.getRootDirectory(), "etc", "compatconfig")); - @GuardedBy("mChanges") private final LongSparseArray<CompatChange> mChanges = new LongSparseArray<>(); - @VisibleForTesting - CompatConfig() { - } + private IOverrideValidator mOverrideValidator; - /** - * @return The static instance of this class to be used within the system server. - */ - static CompatConfig get() { - return sInstance; + @VisibleForTesting + CompatConfig(AndroidBuildClassifier androidBuildClassifier, Context context) { + mOverrideValidator = new OverrideValidatorImpl(androidBuildClassifier, context, this); } /** @@ -159,8 +156,12 @@ final class CompatConfig { * @param enabled If the change should be enabled or disabled. * @return {@code true} if the change existed before adding the override. */ - boolean addOverride(long changeId, String packageName, boolean enabled) { + boolean addOverride(long changeId, String packageName, boolean enabled) + throws RemoteException, SecurityException { boolean alreadyKnown = true; + OverrideAllowedState allowedState = + mOverrideValidator.getOverrideAllowedState(changeId, packageName); + allowedState.enforce(changeId, packageName); synchronized (mChanges) { CompatChange c = mChanges.get(changeId); if (c == null) { @@ -186,6 +187,20 @@ final class CompatConfig { } /** + * Returns the minimum sdk version for which this change should be enabled (or 0 if it is not + * target sdk gated). + */ + int minTargetSdkForChangeId(long changeId) { + synchronized (mChanges) { + CompatChange c = mChanges.get(changeId); + if (c == null) { + return 0; + } + return c.getEnableAfterTargetSdk(); + } + } + + /** * Removes an override previously added via {@link #addOverride(long, String, boolean)}. This * restores the default behaviour for the given change and app, once any app processes have been * restarted. @@ -194,34 +209,44 @@ final class CompatConfig { * @param packageName The app package name that was overridden. * @return {@code true} if an override existed; */ - boolean removeOverride(long changeId, String packageName) { + boolean removeOverride(long changeId, String packageName) + throws RemoteException, SecurityException { boolean overrideExists = false; synchronized (mChanges) { CompatChange c = mChanges.get(changeId); - if (c != null) { - overrideExists = true; - c.removePackageOverride(packageName); + try { + if (c != null) { + OverrideAllowedState allowedState = + mOverrideValidator.getOverrideAllowedState(changeId, packageName); + allowedState.enforce(changeId, packageName); + overrideExists = true; + c.removePackageOverride(packageName); + } + } catch (RemoteException e) { + // Should never occur, since validator is in the same process. + throw new RuntimeException("Unable to call override validator!", e); } } return overrideExists; } /** - * Overrides the enabled state for a given change and app. This method is intended to be used - * *only* for debugging purposes. + * Overrides the enabled state for a given change and app. * * <p>Note, package overrides are not persistent and will be lost on system or runtime restart. * * @param overrides list of overrides to default changes config. * @param packageName app for which the overrides will be applied. */ - void addOverrides(CompatibilityChangeConfig overrides, String packageName) { + void addOverrides(CompatibilityChangeConfig overrides, String packageName) + throws RemoteException, SecurityException { synchronized (mChanges) { for (Long changeId : overrides.enabledChanges()) { addOverride(changeId, packageName, true); } for (Long changeId : overrides.disabledChanges()) { addOverride(changeId, packageName, false); + } } } @@ -235,10 +260,22 @@ final class CompatConfig { * * @param packageName The package for which the overrides should be purged. */ - void removePackageOverrides(String packageName) { + void removePackageOverrides(String packageName) throws RemoteException, SecurityException { synchronized (mChanges) { for (int i = 0; i < mChanges.size(); ++i) { - mChanges.valueAt(i).removePackageOverride(packageName); + try { + CompatChange change = mChanges.valueAt(i); + OverrideAllowedState allowedState = + mOverrideValidator.getOverrideAllowedState(change.getId(), + packageName); + allowedState.enforce(change.getId(), packageName); + if (change != null) { + mChanges.valueAt(i).removePackageOverride(packageName); + } + } catch (RemoteException e) { + // Should never occur, since validator is in the same process. + throw new RuntimeException("Unable to call override validator!", e); + } } } } @@ -326,17 +363,23 @@ final class CompatConfig { } } - CompatConfig initConfigFromLib(File libraryDir) { + static CompatConfig create(AndroidBuildClassifier androidBuildClassifier, Context context) { + CompatConfig config = new CompatConfig(androidBuildClassifier, context); + config.initConfigFromLib(Environment.buildPath( + Environment.getRootDirectory(), "etc", "compatconfig")); + return config; + } + + void initConfigFromLib(File libraryDir) { if (!libraryDir.exists() || !libraryDir.isDirectory()) { Slog.e(TAG, "No directory " + libraryDir + ", skipping"); - return this; + return; } for (File f : libraryDir.listFiles()) { Slog.d(TAG, "Found a config file: " + f.getPath()); //TODO(b/138222363): Handle duplicate ids across config files. readConfig(f); } - return this; } private void readConfig(File configFile) { @@ -350,4 +393,7 @@ final class CompatConfig { } } + IOverrideValidator getOverrideValidator() { + return mOverrideValidator; + } } diff --git a/services/core/java/com/android/server/compat/OverrideValidatorImpl.java b/services/core/java/com/android/server/compat/OverrideValidatorImpl.java new file mode 100644 index 000000000000..dfc00806992b --- /dev/null +++ b/services/core/java/com/android/server/compat/OverrideValidatorImpl.java @@ -0,0 +1,94 @@ +/* + * 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.compat; + +import static com.android.internal.compat.OverrideAllowedState.ALLOWED; +import static com.android.internal.compat.OverrideAllowedState.DISABLED_NON_TARGET_SDK; +import static com.android.internal.compat.OverrideAllowedState.DISABLED_NOT_DEBUGGABLE; +import static com.android.internal.compat.OverrideAllowedState.DISABLED_TARGET_SDK_TOO_HIGH; +import static com.android.internal.compat.OverrideAllowedState.PACKAGE_DOES_NOT_EXIST; + +import android.content.Context; +import android.content.pm.ApplicationInfo; +import android.content.pm.PackageManager; +import android.content.pm.PackageManager.NameNotFoundException; + +import com.android.internal.annotations.VisibleForTesting; +import com.android.internal.compat.AndroidBuildClassifier; +import com.android.internal.compat.IOverrideValidator; +import com.android.internal.compat.OverrideAllowedState; + +/** + * Implementation of the policy for allowing compat change overrides. + */ +public class OverrideValidatorImpl extends IOverrideValidator.Stub { + + private AndroidBuildClassifier mAndroidBuildClassifier; + private Context mContext; + private CompatConfig mCompatConfig; + + @VisibleForTesting + OverrideValidatorImpl(AndroidBuildClassifier androidBuildClassifier, + Context context, CompatConfig config) { + mAndroidBuildClassifier = androidBuildClassifier; + mContext = context; + mCompatConfig = config; + } + + @Override + public OverrideAllowedState getOverrideAllowedState(long changeId, String packageName) { + boolean debuggableBuild = false; + boolean finalBuild = false; + + debuggableBuild = mAndroidBuildClassifier.isDebuggableBuild(); + finalBuild = mAndroidBuildClassifier.isFinalBuild(); + + // Allow any override for userdebug or eng builds. + if (debuggableBuild) { + return new OverrideAllowedState(ALLOWED, -1, -1); + } + PackageManager packageManager = mContext.getPackageManager(); + if (packageManager == null) { + throw new IllegalStateException("No PackageManager!"); + } + ApplicationInfo applicationInfo; + try { + applicationInfo = packageManager.getApplicationInfo(packageName, 0); + } catch (NameNotFoundException e) { + return new OverrideAllowedState(PACKAGE_DOES_NOT_EXIST, -1, -1); + } + int appTargetSdk = applicationInfo.targetSdkVersion; + // Only allow overriding debuggable apps. + if ((applicationInfo.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) { + return new OverrideAllowedState(DISABLED_NOT_DEBUGGABLE, -1, -1); + } + int minTargetSdk = mCompatConfig.minTargetSdkForChangeId(changeId); + // Do not allow overriding non-target sdk gated changes on user builds + if (minTargetSdk == -1) { + return new OverrideAllowedState(DISABLED_NON_TARGET_SDK, appTargetSdk, minTargetSdk); + } + // Allow overriding any change for debuggable apps on non-final builds. + if (!finalBuild) { + return new OverrideAllowedState(ALLOWED, appTargetSdk, minTargetSdk); + } + // Only allow to opt-in for a targetSdk gated change. + if (applicationInfo.targetSdkVersion < minTargetSdk) { + return new OverrideAllowedState(ALLOWED, appTargetSdk, minTargetSdk); + } + return new OverrideAllowedState(DISABLED_TARGET_SDK_TOO_HIGH, appTargetSdk, minTargetSdk); + } +} diff --git a/services/core/java/com/android/server/compat/PlatformCompat.java b/services/core/java/com/android/server/compat/PlatformCompat.java index 4a3d7d69d874..029b7bc32ef3 100644 --- a/services/core/java/com/android/server/compat/PlatformCompat.java +++ b/services/core/java/com/android/server/compat/PlatformCompat.java @@ -27,9 +27,12 @@ import android.os.UserHandle; import android.util.Slog; import android.util.StatsLog; +import com.android.internal.annotations.VisibleForTesting; +import com.android.internal.compat.AndroidBuildClassifier; import com.android.internal.compat.ChangeReporter; import com.android.internal.compat.CompatibilityChangeConfig; import com.android.internal.compat.CompatibilityChangeInfo; +import com.android.internal.compat.IOverrideValidator; import com.android.internal.compat.IPlatformCompat; import com.android.internal.util.DumpUtils; @@ -45,11 +48,21 @@ public class PlatformCompat extends IPlatformCompat.Stub { private final Context mContext; private final ChangeReporter mChangeReporter; + private final CompatConfig mCompatConfig; public PlatformCompat(Context context) { mContext = context; mChangeReporter = new ChangeReporter( StatsLog.APP_COMPATIBILITY_CHANGE_REPORTED__SOURCE__SYSTEM_SERVER); + mCompatConfig = CompatConfig.create(new AndroidBuildClassifier(), mContext); + } + + @VisibleForTesting + PlatformCompat(Context context, CompatConfig compatConfig) { + mContext = context; + mChangeReporter = new ChangeReporter( + StatsLog.APP_COMPATIBILITY_CHANGE_REPORTED__SOURCE__SYSTEM_SERVER); + mCompatConfig = compatConfig; } @Override @@ -74,7 +87,7 @@ public class PlatformCompat extends IPlatformCompat.Stub { @Override public boolean isChangeEnabled(long changeId, ApplicationInfo appInfo) { - if (CompatConfig.get().isChangeEnabled(changeId, appInfo)) { + if (mCompatConfig.isChangeEnabled(changeId, appInfo)) { reportChange(changeId, appInfo.uid, StatsLog.APP_COMPATIBILITY_CHANGE_REPORTED__STATE__ENABLED); return true; @@ -121,57 +134,59 @@ public class PlatformCompat extends IPlatformCompat.Stub { * otherwise. */ public boolean registerListener(long changeId, CompatChange.ChangeListener listener) { - return CompatConfig.get().registerListener(changeId, listener); + return mCompatConfig.registerListener(changeId, listener); } @Override - public void setOverrides(CompatibilityChangeConfig overrides, String packageName) { - CompatConfig.get().addOverrides(overrides, packageName); + public void setOverrides(CompatibilityChangeConfig overrides, String packageName) + throws RemoteException, SecurityException { + mCompatConfig.addOverrides(overrides, packageName); killPackage(packageName); } @Override - public void setOverridesForTest(CompatibilityChangeConfig overrides, String packageName) { - CompatConfig.get().addOverrides(overrides, packageName); + public void setOverridesForTest(CompatibilityChangeConfig overrides, String packageName) + throws RemoteException, SecurityException { + mCompatConfig.addOverrides(overrides, packageName); } @Override - public void clearOverrides(String packageName) { - CompatConfig config = CompatConfig.get(); - config.removePackageOverrides(packageName); + public void clearOverrides(String packageName) throws RemoteException, SecurityException { + mCompatConfig.removePackageOverrides(packageName); killPackage(packageName); } @Override - public void clearOverridesForTest(String packageName) { - CompatConfig config = CompatConfig.get(); - config.removePackageOverrides(packageName); + public void clearOverridesForTest(String packageName) + throws RemoteException, SecurityException { + mCompatConfig.removePackageOverrides(packageName); } @Override - public boolean clearOverride(long changeId, String packageName) { - boolean existed = CompatConfig.get().removeOverride(changeId, packageName); + public boolean clearOverride(long changeId, String packageName) + throws RemoteException, SecurityException { + boolean existed = mCompatConfig.removeOverride(changeId, packageName); killPackage(packageName); return existed; } @Override public CompatibilityChangeConfig getAppConfig(ApplicationInfo appInfo) { - return CompatConfig.get().getAppConfig(appInfo); + return mCompatConfig.getAppConfig(appInfo); } @Override public CompatibilityChangeInfo[] listAllChanges() { - return CompatConfig.get().dumpChanges(); + return mCompatConfig.dumpChanges(); } /** * Check whether the change is known to the compat config. - * @param changeId + * * @return {@code true} if the change is known. */ public boolean isKnownChangeId(long changeId) { - return CompatConfig.get().isKnownChangeId(changeId); + return mCompatConfig.isKnownChangeId(changeId); } @@ -181,11 +196,11 @@ public class PlatformCompat extends IPlatformCompat.Stub { * * @param appInfo The app in question * @return A sorted long array of change IDs. We use a primitive array to minimize memory - * footprint: Every app process will store this array statically so we aim to reduce - * overhead as much as possible. + * footprint: Every app process will store this array statically so we aim to reduce + * overhead as much as possible. */ public long[] getDisabledChanges(ApplicationInfo appInfo) { - return CompatConfig.get().getDisabledChanges(appInfo); + return mCompatConfig.getDisabledChanges(appInfo); } /** @@ -195,18 +210,24 @@ public class PlatformCompat extends IPlatformCompat.Stub { * @return The change ID, or {@code -1} if no change with that name exists. */ public long lookupChangeId(String name) { - return CompatConfig.get().lookupChangeId(name); + return mCompatConfig.lookupChangeId(name); } @Override protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { if (!DumpUtils.checkDumpAndUsageStatsPermission(mContext, "platform_compat", pw)) return; - CompatConfig.get().dumpConfig(pw); + mCompatConfig.dumpConfig(pw); + } + + @Override + public IOverrideValidator getOverrideValidator() { + return mCompatConfig.getOverrideValidator(); } /** * Clears information stored about events reported on behalf of an app. * To be called once upon app start or end. A second call would be a no-op. + * * @param appInfo the app to reset */ public void resetReporting(ApplicationInfo appInfo) { diff --git a/services/core/java/com/android/server/connectivity/DataConnectionStats.java b/services/core/java/com/android/server/connectivity/DataConnectionStats.java index 1b1c54682255..5010e46a74eb 100644 --- a/services/core/java/com/android/server/connectivity/DataConnectionStats.java +++ b/services/core/java/com/android/server/connectivity/DataConnectionStats.java @@ -16,6 +16,9 @@ package com.android.server.connectivity; +import static android.telephony.AccessNetworkConstants.TRANSPORT_TYPE_WWAN; +import static android.telephony.NetworkRegistrationInfo.DOMAIN_PS; + import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; @@ -24,6 +27,7 @@ import android.net.ConnectivityManager; import android.os.Handler; import android.os.Looper; import android.os.RemoteException; +import android.telephony.NetworkRegistrationInfo; import android.telephony.PhoneStateListener; import android.telephony.ServiceState; import android.telephony.SignalStrength; @@ -91,7 +95,10 @@ public class DataConnectionStats extends BroadcastReceiver { boolean visible = (simReadyOrUnknown || isCdma()) // we only check the sim state for GSM && hasService() && mDataState == TelephonyManager.DATA_CONNECTED; - int networkType = mServiceState.getDataNetworkType(); + NetworkRegistrationInfo regInfo = + mServiceState.getNetworkRegistrationInfo(DOMAIN_PS, TRANSPORT_TYPE_WWAN); + int networkType = regInfo == null ? TelephonyManager.NETWORK_TYPE_UNKNOWN + : regInfo.getAccessNetworkTechnology(); if (DEBUG) Log.d(TAG, String.format("Noting data connection for network type %s: %svisible", networkType, visible ? "" : "not ")); try { diff --git a/services/core/java/com/android/server/connectivity/KeepaliveTracker.java b/services/core/java/com/android/server/connectivity/KeepaliveTracker.java index 9bae902eb7b1..af8a3666e9b7 100644 --- a/services/core/java/com/android/server/connectivity/KeepaliveTracker.java +++ b/services/core/java/com/android/server/connectivity/KeepaliveTracker.java @@ -39,11 +39,11 @@ import android.annotation.NonNull; import android.annotation.Nullable; import android.content.Context; import android.net.ISocketKeepaliveCallback; +import android.net.InvalidPacketException; import android.net.KeepalivePacketData; import android.net.NattKeepalivePacketData; import android.net.NetworkAgent; import android.net.NetworkUtils; -import android.net.SocketKeepalive.InvalidPacketException; import android.net.SocketKeepalive.InvalidSocketException; import android.net.TcpKeepalivePacketData; import android.net.util.IpUtils; @@ -657,7 +657,10 @@ public class KeepaliveTracker { final TcpKeepalivePacketData packet; try { packet = TcpKeepaliveController.getTcpKeepalivePacket(fd); - } catch (InvalidPacketException | InvalidSocketException e) { + } catch (InvalidSocketException e) { + notifyErrorCallback(cb, e.error); + return; + } catch (InvalidPacketException e) { notifyErrorCallback(cb, e.error); return; } diff --git a/services/core/java/com/android/server/connectivity/MultipathPolicyTracker.java b/services/core/java/com/android/server/connectivity/MultipathPolicyTracker.java index 6fa999cb039a..04c792ae482b 100644 --- a/services/core/java/com/android/server/connectivity/MultipathPolicyTracker.java +++ b/services/core/java/com/android/server/connectivity/MultipathPolicyTracker.java @@ -26,6 +26,7 @@ import static android.net.NetworkCapabilities.TRANSPORT_CELLULAR; import static android.net.NetworkPolicy.LIMIT_DISABLED; import static android.net.NetworkPolicy.WARNING_DISABLED; import static android.provider.Settings.Global.NETWORK_DEFAULT_DAILY_MULTIPATH_QUOTA_BYTES; +import static android.telephony.SubscriptionManager.INVALID_SUBSCRIPTION_ID; import static com.android.server.net.NetworkPolicyManagerInternal.QUOTA_TYPE_MULTIPATH; import static com.android.server.net.NetworkPolicyManagerService.OPPORTUNISTIC_QUOTA_UNKNOWN; @@ -46,19 +47,18 @@ import android.net.NetworkIdentity; import android.net.NetworkPolicy; import android.net.NetworkPolicyManager; import android.net.NetworkRequest; +import android.net.NetworkSpecifier; import android.net.NetworkStats; import android.net.NetworkTemplate; -import android.net.StringNetworkSpecifier; +import android.net.TelephonyNetworkSpecifier; +import android.net.Uri; import android.os.BestClock; import android.os.Handler; import android.os.SystemClock; -import android.net.Uri; import android.os.UserHandle; import android.provider.Settings; import android.telephony.TelephonyManager; -import android.util.DataUnit; import android.util.DebugUtils; -import android.util.Pair; import android.util.Range; import android.util.Slog; @@ -74,7 +74,6 @@ import java.time.ZoneId; import java.time.ZoneOffset; import java.time.ZonedDateTime; import java.time.temporal.ChronoUnit; -import java.util.Iterator; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.TimeUnit; @@ -185,7 +184,6 @@ public class MultipathPolicyTracker { // Track information on mobile networks as they come and go. class MultipathTracker { final Network network; - final int subId; final String subscriberId; private long mQuota; @@ -198,13 +196,14 @@ public class MultipathPolicyTracker { public MultipathTracker(Network network, NetworkCapabilities nc) { this.network = network; this.mNetworkCapabilities = new NetworkCapabilities(nc); - try { - subId = Integer.parseInt( - ((StringNetworkSpecifier) nc.getNetworkSpecifier()).toString()); - } catch (ClassCastException | NullPointerException | NumberFormatException e) { + NetworkSpecifier specifier = nc.getNetworkSpecifier(); + int subId = INVALID_SUBSCRIPTION_ID; + if (specifier instanceof TelephonyNetworkSpecifier) { + subId = ((TelephonyNetworkSpecifier) specifier).getSubscriptionId(); + } else { throw new IllegalStateException(String.format( - "Can't get subId from mobile network %s (%s): %s", - network, nc, e.getMessage())); + "Can't get subId from mobile network %s (%s)", + network, nc)); } TelephonyManager tele = mContext.getSystemService(TelephonyManager.class); diff --git a/services/core/java/com/android/server/connectivity/NetworkNotificationManager.java b/services/core/java/com/android/server/connectivity/NetworkNotificationManager.java index 21795184b1bd..2c415570d5fa 100644 --- a/services/core/java/com/android/server/connectivity/NetworkNotificationManager.java +++ b/services/core/java/com/android/server/connectivity/NetworkNotificationManager.java @@ -28,7 +28,7 @@ import android.content.Context; import android.content.Intent; import android.content.res.Resources; import android.net.NetworkSpecifier; -import android.net.StringNetworkSpecifier; +import android.net.TelephonyNetworkSpecifier; import android.net.wifi.WifiInfo; import android.os.UserHandle; import android.telephony.SubscriptionManager; @@ -223,14 +223,8 @@ public class NetworkNotificationManager { // name has been added to it NetworkSpecifier specifier = nai.networkCapabilities.getNetworkSpecifier(); int subId = SubscriptionManager.DEFAULT_SUBSCRIPTION_ID; - if (specifier instanceof StringNetworkSpecifier) { - try { - subId = Integer.parseInt( - ((StringNetworkSpecifier) specifier).specifier); - } catch (NumberFormatException e) { - Slog.e(TAG, "NumberFormatException on " - + ((StringNetworkSpecifier) specifier).specifier); - } + if (specifier instanceof TelephonyNetworkSpecifier) { + subId = ((TelephonyNetworkSpecifier) specifier).getSubscriptionId(); } details = mTelephonyManager.createForSubscriptionId(subId) diff --git a/services/core/java/com/android/server/connectivity/TcpKeepaliveController.java b/services/core/java/com/android/server/connectivity/TcpKeepaliveController.java index e570ef1e9bf2..1129899ee3ff 100644 --- a/services/core/java/com/android/server/connectivity/TcpKeepaliveController.java +++ b/services/core/java/com/android/server/connectivity/TcpKeepaliveController.java @@ -30,8 +30,8 @@ import static android.system.OsConstants.IP_TTL; import static android.system.OsConstants.TIOCOUTQ; import android.annotation.NonNull; +import android.net.InvalidPacketException; import android.net.NetworkUtils; -import android.net.SocketKeepalive.InvalidPacketException; import android.net.SocketKeepalive.InvalidSocketException; import android.net.TcpKeepalivePacketData; import android.net.TcpKeepalivePacketDataParcelable; diff --git a/services/core/java/com/android/server/connectivity/Vpn.java b/services/core/java/com/android/server/connectivity/Vpn.java index 09790c46972e..a46ada873408 100644 --- a/services/core/java/com/android/server/connectivity/Vpn.java +++ b/services/core/java/com/android/server/connectivity/Vpn.java @@ -54,10 +54,10 @@ import android.net.LocalSocketAddress; import android.net.Network; import android.net.NetworkAgent; import android.net.NetworkCapabilities; -import android.net.NetworkFactory; import android.net.NetworkInfo; import android.net.NetworkInfo.DetailedState; import android.net.NetworkMisc; +import android.net.NetworkProvider; import android.net.RouteInfo; import android.net.UidRange; import android.net.VpnService; @@ -958,7 +958,7 @@ public class Vpn { mNetworkAgent = new NetworkAgent(mLooper, mContext, NETWORKTYPE /* logtag */, mNetworkInfo, mNetworkCapabilities, lp, ConnectivityConstants.VPN_DEFAULT_SCORE, networkMisc, - NetworkFactory.SerialNumber.VPN) { + NetworkProvider.ID_VPN) { @Override public void unwanted() { // We are user controlled, not driven by NetworkRequest. diff --git a/services/core/java/com/android/server/display/DisplayModeDirector.java b/services/core/java/com/android/server/display/DisplayModeDirector.java index 1fc0db3ff7cb..6dcfadef5f8c 100644 --- a/services/core/java/com/android/server/display/DisplayModeDirector.java +++ b/services/core/java/com/android/server/display/DisplayModeDirector.java @@ -76,7 +76,7 @@ public class DisplayModeDirector { private static final int GLOBAL_ID = -1; // The tolerance within which we consider something approximately equals. - private static final float EPSILON = 0.001f; + private static final float EPSILON = 0.01f; private final Object mLock = new Object(); private final Context mContext; diff --git a/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java b/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java index 63302705b36f..69cbc22f41bf 100644 --- a/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java +++ b/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java @@ -3454,7 +3454,7 @@ public class InputMethodManagerService extends IInputMethodManager.Stub } /** - * This is kept due to {@link android.annotation.UnsupportedAppUsage} in + * This is kept due to {@link android.compat.annotation.UnsupportedAppUsage} in * {@link InputMethodManager#getInputMethodWindowVisibleHeight()} and a dependency in * {@link InputMethodService#onCreate()}. * diff --git a/services/core/java/com/android/server/job/controllers/TimeController.java b/services/core/java/com/android/server/job/controllers/TimeController.java index ababad961c2d..97df55706bf8 100644 --- a/services/core/java/com/android/server/job/controllers/TimeController.java +++ b/services/core/java/com/android/server/job/controllers/TimeController.java @@ -325,8 +325,7 @@ public final class TimeController extends StateController { && !wouldBeReadyWithConstraintLocked( job, JobStatus.CONSTRAINT_TIMING_DELAY)) { if (DEBUG) { - Slog.i(TAG, - "Skipping " + job + " because delay won't make it ready."); + Slog.i(TAG, "Skipping " + job + " because delay won't make it ready."); } continue; } @@ -385,7 +384,8 @@ public final class TimeController extends StateController { /** * Set an alarm with the {@link android.app.AlarmManager} for the next time at which a job's * delay will expire. - * This alarm <b>will</b> wake up the phone. + * This alarm <b>will not</b> wake up the phone if + * {@link TcConstants#USE_NON_WAKEUP_ALARM_FOR_DELAY} is true. */ private void setDelayExpiredAlarmLocked(long alarmTimeElapsedMillis, WorkSource ws) { alarmTimeElapsedMillis = maybeAdjustAlarmTime(alarmTimeElapsedMillis); @@ -393,8 +393,11 @@ public final class TimeController extends StateController { return; } mNextDelayExpiredElapsedMillis = alarmTimeElapsedMillis; - updateAlarmWithListenerLocked(DELAY_TAG, mNextDelayExpiredListener, - mNextDelayExpiredElapsedMillis, ws); + final int alarmType = + mTcConstants.USE_NON_WAKEUP_ALARM_FOR_DELAY + ? AlarmManager.ELAPSED_REALTIME : AlarmManager.ELAPSED_REALTIME_WAKEUP; + updateAlarmWithListenerLocked(DELAY_TAG, alarmType, + mNextDelayExpiredListener, mNextDelayExpiredElapsedMillis, ws); } /** @@ -408,16 +411,16 @@ public final class TimeController extends StateController { return; } mNextJobExpiredElapsedMillis = alarmTimeElapsedMillis; - updateAlarmWithListenerLocked(DEADLINE_TAG, mDeadlineExpiredListener, - mNextJobExpiredElapsedMillis, ws); + updateAlarmWithListenerLocked(DEADLINE_TAG, AlarmManager.ELAPSED_REALTIME_WAKEUP, + mDeadlineExpiredListener, mNextJobExpiredElapsedMillis, ws); } private long maybeAdjustAlarmTime(long proposedAlarmTimeElapsedMillis) { return Math.max(proposedAlarmTimeElapsedMillis, sElapsedRealtimeClock.millis()); } - private void updateAlarmWithListenerLocked(String tag, OnAlarmListener listener, - long alarmTimeElapsed, WorkSource ws) { + private void updateAlarmWithListenerLocked(String tag, @AlarmManager.AlarmType int alarmType, + OnAlarmListener listener, long alarmTimeElapsed, WorkSource ws) { ensureAlarmServiceLocked(); if (alarmTimeElapsed == Long.MAX_VALUE) { mAlarmService.cancel(listener); @@ -425,7 +428,7 @@ public final class TimeController extends StateController { if (DEBUG) { Slog.d(TAG, "Setting " + tag + " for: " + alarmTimeElapsed); } - mAlarmService.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, alarmTimeElapsed, + mAlarmService.set(alarmType, alarmTimeElapsed, AlarmManager.WINDOW_HEURISTIC, 0, tag, listener, null, ws); } } @@ -464,8 +467,11 @@ public final class TimeController extends StateController { private final KeyValueListParser mParser = new KeyValueListParser(','); private static final String KEY_SKIP_NOT_READY_JOBS = "skip_not_ready_jobs"; + private static final String KEY_USE_NON_WAKEUP_ALARM_FOR_DELAY = + "use_non_wakeup_delay_alarm"; private static final boolean DEFAULT_SKIP_NOT_READY_JOBS = true; + private static final boolean DEFAULT_USE_NON_WAKEUP_ALARM_FOR_DELAY = true; /** * Whether or not TimeController should skip setting wakeup alarms for jobs that aren't @@ -474,6 +480,12 @@ public final class TimeController extends StateController { public boolean SKIP_NOT_READY_JOBS = DEFAULT_SKIP_NOT_READY_JOBS; /** + * Whether or not TimeController should skip setting wakeup alarms for jobs that aren't + * ready now. + */ + public boolean USE_NON_WAKEUP_ALARM_FOR_DELAY = DEFAULT_USE_NON_WAKEUP_ALARM_FOR_DELAY; + + /** * Creates a content observer. * * @param handler The handler to run {@link #onChange} on, or null if none. @@ -510,6 +522,12 @@ public final class TimeController extends StateController { recheckAlarmsLocked(); } } + + USE_NON_WAKEUP_ALARM_FOR_DELAY = mParser.getBoolean( + KEY_USE_NON_WAKEUP_ALARM_FOR_DELAY, DEFAULT_USE_NON_WAKEUP_ALARM_FOR_DELAY); + // Intentionally not calling checkExpiredDelaysAndResetAlarm() here. There's no need to + // iterate through the entire list again for this constant change. The next delay alarm + // that is set will make use of the new constant value. } private void dump(IndentingPrintWriter pw) { @@ -517,12 +535,16 @@ public final class TimeController extends StateController { pw.println("TimeController:"); pw.increaseIndent(); pw.printPair(KEY_SKIP_NOT_READY_JOBS, SKIP_NOT_READY_JOBS).println(); + pw.printPair(KEY_USE_NON_WAKEUP_ALARM_FOR_DELAY, + USE_NON_WAKEUP_ALARM_FOR_DELAY).println(); pw.decreaseIndent(); } private void dump(ProtoOutputStream proto) { final long tcToken = proto.start(ConstantsProto.TIME_CONTROLLER); proto.write(ConstantsProto.TimeController.SKIP_NOT_READY_JOBS, SKIP_NOT_READY_JOBS); + proto.write(ConstantsProto.TimeController.USE_NON_WAKEUP_ALARM_FOR_DELAY, + USE_NON_WAKEUP_ALARM_FOR_DELAY); proto.end(tcToken); } } diff --git a/services/core/java/com/android/server/location/NtpTimeHelper.java b/services/core/java/com/android/server/location/NtpTimeHelper.java index 296b500eacee..88e9b50bb298 100644 --- a/services/core/java/com/android/server/location/NtpTimeHelper.java +++ b/services/core/java/com/android/server/location/NtpTimeHelper.java @@ -130,7 +130,8 @@ class NtpTimeHelper { // force refresh NTP cache when outdated boolean refreshSuccess = true; - if (mNtpTime.getCacheAge() >= NTP_INTERVAL) { + NtpTrustedTime.TimeResult ntpResult = mNtpTime.getCachedTimeResult(); + if (ntpResult == null || ntpResult.getAgeMillis() >= NTP_INTERVAL) { // Blocking network operation. refreshSuccess = mNtpTime.forceRefresh(); } @@ -140,17 +141,17 @@ class NtpTimeHelper { // only update when NTP time is fresh // If refreshSuccess is false, cacheAge does not drop down. - if (mNtpTime.getCacheAge() < NTP_INTERVAL) { - long time = mNtpTime.getCachedNtpTime(); - long timeReference = mNtpTime.getCachedNtpTimeReference(); - long certainty = mNtpTime.getCacheCertainty(); + ntpResult = mNtpTime.getCachedTimeResult(); + if (ntpResult != null && ntpResult.getAgeMillis() < NTP_INTERVAL) { + long time = ntpResult.getTimeMillis(); + long timeReference = ntpResult.getElapsedRealtimeMillis(); + long certainty = ntpResult.getCertaintyMillis(); if (DEBUG) { long now = System.currentTimeMillis(); Log.d(TAG, "NTP server returned: " - + time + " (" + new Date(time) - + ") reference: " + timeReference - + " certainty: " + certainty + + time + " (" + new Date(time) + ")" + + " ntpResult: " + ntpResult + " system time offset: " + (time - now)); } diff --git a/services/core/java/com/android/server/net/NetworkPolicyManagerInternal.java b/services/core/java/com/android/server/net/NetworkPolicyManagerInternal.java index 7f650ee7e138..b24a938ef7ea 100644 --- a/services/core/java/com/android/server/net/NetworkPolicyManagerInternal.java +++ b/services/core/java/com/android/server/net/NetworkPolicyManagerInternal.java @@ -18,8 +18,10 @@ package com.android.server.net; import static com.android.server.net.NetworkPolicyManagerService.isUidNetworkingBlockedInternal; +import android.annotation.NonNull; import android.net.Network; import android.net.NetworkTemplate; +import android.net.netstats.provider.AbstractNetworkStatsProvider; import android.telephony.SubscriptionPlan; import java.util.Set; @@ -126,4 +128,12 @@ public abstract class NetworkPolicyManagerInternal { */ public abstract void setMeteredRestrictedPackagesAsync( Set<String> packageNames, int userId); + + /** + * Notifies that any of the {@link AbstractNetworkStatsProvider} has reached its quota + * which was set through {@link AbstractNetworkStatsProvider#setLimit(String, long)}. + * + * @param tag the human readable identifier of the custom network stats provider. + */ + public abstract void onStatsProviderLimitReached(@NonNull String tag); } diff --git a/services/core/java/com/android/server/net/NetworkPolicyManagerService.java b/services/core/java/com/android/server/net/NetworkPolicyManagerService.java index e3e6d9d80827..c60fed073a15 100644 --- a/services/core/java/com/android/server/net/NetworkPolicyManagerService.java +++ b/services/core/java/com/android/server/net/NetworkPolicyManagerService.java @@ -75,6 +75,7 @@ import static android.net.NetworkTemplate.MATCH_MOBILE; import static android.net.NetworkTemplate.MATCH_WIFI; import static android.net.NetworkTemplate.buildTemplateMobileAll; import static android.net.TrafficStats.MB_IN_BYTES; +import static android.net.netstats.provider.AbstractNetworkStatsProvider.QUOTA_UNLIMITED; import static android.os.Trace.TRACE_TAG_NETWORK; import static android.provider.Settings.Global.NETPOLICY_OVERRIDE_ENABLED; import static android.provider.Settings.Global.NETPOLICY_QUOTA_ENABLED; @@ -160,7 +161,7 @@ import android.net.NetworkStack; import android.net.NetworkState; import android.net.NetworkStats; import android.net.NetworkTemplate; -import android.net.StringNetworkSpecifier; +import android.net.TelephonyNetworkSpecifier; import android.net.TrafficStats; import android.net.wifi.WifiConfiguration; import android.net.wifi.WifiManager; @@ -227,7 +228,6 @@ import com.android.internal.util.ConcurrentUtils; import com.android.internal.util.DumpUtils; import com.android.internal.util.FastXmlSerializer; import com.android.internal.util.IndentingPrintWriter; -import com.android.internal.util.Preconditions; import com.android.internal.util.StatLogger; import com.android.server.EventLogTags; import com.android.server.LocalServices; @@ -388,6 +388,8 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { private static final int MSG_SUBSCRIPTION_OVERRIDE = 16; private static final int MSG_METERED_RESTRICTED_PACKAGES_CHANGED = 17; private static final int MSG_SET_NETWORK_TEMPLATE_ENABLED = 18; + private static final int MSG_SUBSCRIPTION_PLANS_CHANGED = 19; + private static final int MSG_STATS_PROVIDER_LIMIT_REACHED = 20; private static final int UID_MSG_STATE_CHANGED = 100; private static final int UID_MSG_GONE = 101; @@ -2867,17 +2869,6 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { } @Override - public void onTetheringChanged(String iface, boolean tethering) { - // No need to enforce permission because setRestrictBackground() will do it. - synchronized (mUidRulesFirstLock) { - if (mRestrictBackground && tethering) { - Log.d(TAG, "Tethering on (" + iface +"); disable Data Saver"); - setRestrictBackground(false); - } - } - } - - @Override public void setRestrictBackground(boolean restrictBackground) { Trace.traceBegin(Trace.TRACE_TAG_NETWORK, "setRestrictBackground"); try { @@ -3038,12 +3029,13 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { // Verify they're not lying about package name mAppOps.checkPackage(callingUid, callingPackage); + final SubscriptionManager sm; final SubscriptionInfo si; final PersistableBundle config; final long token = Binder.clearCallingIdentity(); try { - si = mContext.getSystemService(SubscriptionManager.class) - .getActiveSubscriptionInfo(subId); + sm = mContext.getSystemService(SubscriptionManager.class); + si = sm.getActiveSubscriptionInfo(subId); config = mCarrierConfigManager.getConfigForSubId(subId); } finally { Binder.restoreCallingIdentity(token); @@ -3051,7 +3043,7 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { // First check: is caller the CarrierService? if (si != null) { - if (si.isEmbedded() && si.canManageSubscription(mContext, callingPackage)) { + if (si.isEmbedded() && sm.canManageSubscription(si, callingPackage)) { return; } } @@ -3091,6 +3083,34 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { mContext.enforceCallingOrSelfPermission(MANAGE_SUBSCRIPTION_PLANS, TAG); } + private void enforceSubscriptionPlanValidity(SubscriptionPlan[] plans) { + // nothing to check if no plans + if (plans.length == 0) { + return; + } + + long applicableNetworkTypes = 0; + boolean allNetworks = false; + for (SubscriptionPlan plan : plans) { + if (plan.getNetworkTypes() == null) { + allNetworks = true; + } else { + if ((applicableNetworkTypes & plan.getNetworkTypesBitMask()) != 0) { + throw new IllegalArgumentException( + "Multiple subscription plans defined for a single network type."); + } else { + applicableNetworkTypes |= plan.getNetworkTypesBitMask(); + } + } + } + + // ensure at least one plan applies for every network type + if (!allNetworks) { + throw new IllegalArgumentException( + "No generic subscription plan that applies to all network types."); + } + } + @Override public SubscriptionPlan[] getSubscriptionPlans(int subId, String callingPackage) { enforceSubscriptionPlanAccess(subId, Binder.getCallingUid(), callingPackage); @@ -3255,6 +3275,7 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { @Override public void setSubscriptionPlans(int subId, SubscriptionPlan[] plans, String callingPackage) { enforceSubscriptionPlanAccess(subId, Binder.getCallingUid(), callingPackage); + enforceSubscriptionPlanValidity(plans); for (SubscriptionPlan plan : plans) { Objects.requireNonNull(plan); @@ -3283,6 +3304,8 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); intent.putExtra(SubscriptionManager.EXTRA_SUBSCRIPTION_INDEX, subId); mContext.sendBroadcast(intent, android.Manifest.permission.MANAGE_SUBSCRIPTION_PLANS); + mHandler.sendMessage( + mHandler.obtainMessage(MSG_SUBSCRIPTION_PLANS_CHANGED, subId, 0, plans)); } finally { Binder.restoreCallingIdentity(token); } @@ -4476,6 +4499,16 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { } } + private void dispatchSubscriptionPlansChanged(INetworkPolicyListener listener, int subId, + SubscriptionPlan[] plans) { + if (listener != null) { + try { + listener.onSubscriptionPlansChanged(subId, plans); + } catch (RemoteException ignored) { + } + } + } + private final Handler.Callback mHandlerCallback = new Handler.Callback() { @Override public boolean handleMessage(Message msg) { @@ -4501,19 +4534,36 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { mListeners.finishBroadcast(); return true; } + case MSG_STATS_PROVIDER_LIMIT_REACHED: { + mNetworkStats.forceUpdate(); + + synchronized (mNetworkPoliciesSecondLock) { + // Some providers might hit the limit reached event prior to others. Thus, + // re-calculate and update interface quota for every provider is needed. + updateNetworkRulesNL(); + updateNetworkEnabledNL(); + updateNotificationsNL(); + } + return true; + } case MSG_LIMIT_REACHED: { final String iface = (String) msg.obj; - synchronized (mNetworkPoliciesSecondLock) { - if (mMeteredIfaces.contains(iface)) { - // force stats update to make sure we have - // numbers that caused alert to trigger. - mNetworkStats.forceUpdate(); - - updateNetworkEnabledNL(); - updateNotificationsNL(); + // fast return if not needed. + if (!mMeteredIfaces.contains(iface)) { + return true; } } + + // force stats update to make sure the service have the numbers that caused + // alert to trigger. + mNetworkStats.forceUpdate(); + + synchronized (mNetworkPoliciesSecondLock) { + updateNetworkRulesNL(); + updateNetworkEnabledNL(); + updateNotificationsNL(); + } return true; } case MSG_RESTRICT_BACKGROUND_CHANGED: { @@ -4556,14 +4606,18 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { return true; } case MSG_UPDATE_INTERFACE_QUOTA: { - removeInterfaceQuota((String) msg.obj); + final String iface = (String) msg.obj; // int params need to be stitched back into a long - setInterfaceQuota((String) msg.obj, - ((long) msg.arg1 << 32) | (msg.arg2 & 0xFFFFFFFFL)); + final long quota = ((long) msg.arg1 << 32) | (msg.arg2 & 0xFFFFFFFFL); + removeInterfaceQuota(iface); + setInterfaceQuota(iface, quota); + mNetworkStats.setStatsProviderLimit(iface, quota); return true; } case MSG_REMOVE_INTERFACE_QUOTA: { - removeInterfaceQuota((String) msg.obj); + final String iface = (String) msg.obj; + removeInterfaceQuota(iface); + mNetworkStats.setStatsProviderLimit(iface, QUOTA_UNLIMITED); return true; } case MSG_RESET_FIREWALL_RULES_BY_UID: { @@ -4594,6 +4648,17 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { setNetworkTemplateEnabledInner(template, enabled); return true; } + case MSG_SUBSCRIPTION_PLANS_CHANGED: { + final SubscriptionPlan[] plans = (SubscriptionPlan[]) msg.obj; + final int subId = msg.arg1; + final int length = mListeners.beginBroadcast(); + for (int i = 0; i < length; i++) { + final INetworkPolicyListener listener = mListeners.getBroadcastItem(i); + dispatchSubscriptionPlansChanged(listener, subId, plans); + } + mListeners.finishBroadcast(); + return true; + } default: { return false; } @@ -5203,6 +5268,12 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { mHandler.obtainMessage(MSG_METERED_RESTRICTED_PACKAGES_CHANGED, userId, 0, packageNames).sendToTarget(); } + + @Override + public void onStatsProviderLimitReached(@NonNull String tag) { + Log.v(TAG, "onStatsProviderLimitReached: " + tag); + mHandler.obtainMessage(MSG_STATS_PROVIDER_LIMIT_REACHED).sendToTarget(); + } } private void setMeteredRestrictedPackagesInternal(Set<String> packageNames, int userId) { @@ -5231,16 +5302,12 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { } private int parseSubId(NetworkState state) { - // TODO: moved to using a legitimate NetworkSpecifier instead of string parsing int subId = INVALID_SUBSCRIPTION_ID; if (state != null && state.networkCapabilities != null && state.networkCapabilities.hasTransport(TRANSPORT_CELLULAR)) { NetworkSpecifier spec = state.networkCapabilities.getNetworkSpecifier(); - if (spec instanceof StringNetworkSpecifier) { - try { - subId = Integer.parseInt(((StringNetworkSpecifier) spec).specifier); - } catch (NumberFormatException e) { - } + if (spec instanceof TelephonyNetworkSpecifier) { + subId = ((TelephonyNetworkSpecifier) spec).getSubscriptionId(); } } return subId; diff --git a/services/core/java/com/android/server/net/NetworkStatsFactory.java b/services/core/java/com/android/server/net/NetworkStatsFactory.java index 3ca1803262e7..22b01bee6c6a 100644 --- a/services/core/java/com/android/server/net/NetworkStatsFactory.java +++ b/services/core/java/com/android/server/net/NetworkStatsFactory.java @@ -229,7 +229,7 @@ public class NetworkStatsFactory { entry.txPackets += reader.nextLong(); } - stats.addValues(entry); + stats.addEntry(entry); reader.finishLine(); } } catch (NullPointerException|NumberFormatException e) { @@ -279,7 +279,7 @@ public class NetworkStatsFactory { entry.txBytes = reader.nextLong(); entry.txPackets = reader.nextLong(); - stats.addValues(entry); + stats.addEntry(entry); reader.finishLine(); } } catch (NullPointerException|NumberFormatException e) { @@ -439,7 +439,7 @@ public class NetworkStatsFactory { if ((limitIfaces == null || ArrayUtils.contains(limitIfaces, entry.iface)) && (limitUid == UID_ALL || limitUid == entry.uid) && (limitTag == TAG_ALL || limitTag == entry.tag)) { - stats.addValues(entry); + stats.addEntry(entry); } reader.finishLine(); diff --git a/services/core/java/com/android/server/net/NetworkStatsManagerInternal.java b/services/core/java/com/android/server/net/NetworkStatsManagerInternal.java index 4843ede7219d..6d72cb5ee345 100644 --- a/services/core/java/com/android/server/net/NetworkStatsManagerInternal.java +++ b/services/core/java/com/android/server/net/NetworkStatsManagerInternal.java @@ -16,6 +16,7 @@ package com.android.server.net; +import android.annotation.NonNull; import android.net.NetworkStats; import android.net.NetworkTemplate; @@ -34,4 +35,10 @@ public abstract class NetworkStatsManagerInternal { /** Force update of statistics. */ public abstract void forceUpdate(); + + /** + * Set the quota limit to all registered custom network stats providers. + * Note that invocation of any interface will be sent to all providers. + */ + public abstract void setStatsProviderLimit(@NonNull String iface, long quota); } diff --git a/services/core/java/com/android/server/net/NetworkStatsService.java b/services/core/java/com/android/server/net/NetworkStatsService.java index a41fb7d32762..fc39a253bc24 100644 --- a/services/core/java/com/android/server/net/NetworkStatsService.java +++ b/services/core/java/com/android/server/net/NetworkStatsService.java @@ -18,6 +18,7 @@ package com.android.server.net; import static android.Manifest.permission.ACCESS_NETWORK_STATE; import static android.Manifest.permission.READ_NETWORK_USAGE_HISTORY; +import static android.Manifest.permission.UPDATE_DEVICE_STATS; import static android.content.Intent.ACTION_SHUTDOWN; import static android.content.Intent.ACTION_UID_REMOVED; import static android.content.Intent.ACTION_USER_REMOVED; @@ -27,6 +28,7 @@ import static android.net.ConnectivityManager.isNetworkTypeMobile; import static android.net.NetworkStack.checkNetworkStackPermission; import static android.net.NetworkStats.DEFAULT_NETWORK_ALL; import static android.net.NetworkStats.IFACE_ALL; +import static android.net.NetworkStats.IFACE_VT; import static android.net.NetworkStats.INTERFACES_ALL; import static android.net.NetworkStats.METERED_ALL; import static android.net.NetworkStats.ROAMING_ALL; @@ -70,6 +72,7 @@ import static com.android.server.NetworkManagementSocketTagger.resetKernelUidSta import static com.android.server.NetworkManagementSocketTagger.setKernelCounterSet; import android.annotation.NonNull; +import android.annotation.Nullable; import android.app.AlarmManager; import android.app.PendingIntent; import android.app.usage.NetworkStatsManager; @@ -96,6 +99,9 @@ import android.net.NetworkStats.NonMonotonicObserver; import android.net.NetworkStatsHistory; import android.net.NetworkTemplate; import android.net.TrafficStats; +import android.net.netstats.provider.INetworkStatsProvider; +import android.net.netstats.provider.INetworkStatsProviderCallback; +import android.net.netstats.provider.NetworkStatsProviderCallback; import android.os.BestClock; import android.os.Binder; import android.os.DropBoxManager; @@ -108,6 +114,7 @@ import android.os.Looper; import android.os.Message; import android.os.Messenger; import android.os.PowerManager; +import android.os.RemoteCallbackList; import android.os.RemoteException; import android.os.SystemClock; import android.os.Trace; @@ -175,7 +182,7 @@ public class NetworkStatsService extends INetworkStatsService.Stub { * This avoids firing the global alert too often on devices with high transfer speeds and * high quota. */ - private static final int PERFORM_POLL_DELAY_MS = 1000; + private static final int DEFAULT_PERFORM_POLL_DELAY_MS = 1000; private static final String TAG_NETSTATS_ERROR = "netstats_error"; @@ -211,13 +218,15 @@ public class NetworkStatsService extends INetworkStatsService.Stub { /** * Virtual network interface for video telephony. This is for VT data usage counting purpose. */ - public static final String VT_INTERFACE = "vt_data0"; + // TODO: Remove this after no one is using it. + public static final String VT_INTERFACE = NetworkStats.IFACE_VT; /** * Settings that can be changed externally. */ public interface NetworkStatsSettings { public long getPollInterval(); + public long getPollDelay(); public boolean getSampleEnabled(); public boolean getAugmentEnabled(); @@ -246,6 +255,7 @@ public class NetworkStatsService extends INetworkStatsService.Stub { } private final Object mStatsLock = new Object(); + private final Object mStatsProviderLock = new Object(); /** Set of currently active ifaces. */ @GuardedBy("mStatsLock") @@ -270,6 +280,9 @@ public class NetworkStatsService extends INetworkStatsService.Stub { private final DropBoxNonMonotonicObserver mNonMonotonicObserver = new DropBoxNonMonotonicObserver(); + private final RemoteCallbackList<NetworkStatsProviderCallbackImpl> mStatsProviderCbList = + new RemoteCallbackList<>(); + @GuardedBy("mStatsLock") private NetworkStatsRecorder mDevRecorder; @GuardedBy("mStatsLock") @@ -500,9 +513,9 @@ public class NetworkStatsService extends INetworkStatsService.Stub { } /** - * Register for a global alert that is delivered through - * {@link INetworkManagementEventObserver} once a threshold amount of data - * has been transferred. + * Register for a global alert that is delivered through {@link INetworkManagementEventObserver} + * or {@link NetworkStatsProviderCallback#onAlertReached()} once a threshold amount of data has + * been transferred. */ private void registerGlobalAlert() { try { @@ -512,6 +525,7 @@ public class NetworkStatsService extends INetworkStatsService.Stub { } catch (RemoteException e) { // ignored; service lives in system_server } + invokeForAllStatsProviderCallbacks((cb) -> cb.mProvider.setAlert(mGlobalAlertBytes)); } @Override @@ -712,7 +726,7 @@ public class NetworkStatsService extends INetworkStatsService.Stub { final NetworkStatsHistory.Entry entry = history.getValues(start, end, now, null); final NetworkStats stats = new NetworkStats(end - start, 1); - stats.addValues(new NetworkStats.Entry(IFACE_ALL, UID_ALL, SET_ALL, TAG_NONE, + stats.addEntry(new NetworkStats.Entry(IFACE_ALL, UID_ALL, SET_ALL, TAG_NONE, METERED_ALL, ROAMING_ALL, DEFAULT_NETWORK_ALL, entry.rxBytes, entry.rxPackets, entry.txBytes, entry.txPackets, entry.operations)); return stats; @@ -801,8 +815,7 @@ public class NetworkStatsService extends INetworkStatsService.Stub { @Override public void incrementOperationCount(int uid, int tag, int operationCount) { if (Binder.getCallingUid() != uid) { - mContext.enforceCallingOrSelfPermission( - android.Manifest.permission.UPDATE_DEVICE_STATS, TAG); + mContext.enforceCallingOrSelfPermission(UPDATE_DEVICE_STATS, TAG); } if (operationCount < 0) { @@ -1093,7 +1106,7 @@ public class NetworkStatsService extends INetworkStatsService.Stub { /** * Observer that watches for {@link INetworkManagementService} alerts. */ - private INetworkManagementEventObserver mAlertObserver = new BaseNetworkObserver() { + private final INetworkManagementEventObserver mAlertObserver = new BaseNetworkObserver() { @Override public void limitReached(String limitName, String iface) { // only someone like NMS should be calling us @@ -1104,7 +1117,7 @@ public class NetworkStatsService extends INetworkStatsService.Stub { // such a call pending; UID stats are handled during normal polling interval. if (!mHandler.hasMessages(MSG_PERFORM_POLL_REGISTER_ALERT)) { mHandler.sendEmptyMessageDelayed(MSG_PERFORM_POLL_REGISTER_ALERT, - PERFORM_POLL_DELAY_MS); + mSettings.getPollDelay()); } } } @@ -1179,8 +1192,8 @@ public class NetworkStatsService extends INetworkStatsService.Stub { ident.getSubType(), ident.getSubscriberId(), ident.getNetworkId(), ident.getRoaming(), true /* metered */, true /* onDefaultNetwork */); - findOrCreateNetworkIdentitySet(mActiveIfaces, VT_INTERFACE).add(vtIdent); - findOrCreateNetworkIdentitySet(mActiveUidIfaces, VT_INTERFACE).add(vtIdent); + findOrCreateNetworkIdentitySet(mActiveIfaces, IFACE_VT).add(vtIdent); + findOrCreateNetworkIdentitySet(mActiveUidIfaces, IFACE_VT).add(vtIdent); } if (isMobile) { @@ -1250,6 +1263,14 @@ public class NetworkStatsService extends INetworkStatsService.Stub { xtSnapshot.combineAllValues(tetherSnapshot); devSnapshot.combineAllValues(tetherSnapshot); + // Snapshot for dev/xt stats from all custom stats providers. Counts per-interface data + // from stats providers that isn't already counted by dev and XT stats. + Trace.traceBegin(TRACE_TAG_NETWORK, "snapshotStatsProvider"); + final NetworkStats providersnapshot = getNetworkStatsFromProviders(STATS_PER_IFACE); + Trace.traceEnd(TRACE_TAG_NETWORK); + xtSnapshot.combineAllValues(providersnapshot); + devSnapshot.combineAllValues(providersnapshot); + // For xt/dev, we pass a null VPN array because usage is aggregated by UID, so VPN traffic // can't be reattributed to responsible apps. Trace.traceBegin(TRACE_TAG_NETWORK, "recordDev"); @@ -1353,6 +1374,10 @@ public class NetworkStatsService extends INetworkStatsService.Stub { performSampleLocked(); } + // request asynchronous stats update from all providers for next poll. + // TODO: request with a valid token. + invokeForAllStatsProviderCallbacks((cb) -> cb.mProvider.requestStatsUpdate(0 /* unused */)); + // finally, dispatch updated event to any listeners final Intent updatedIntent = new Intent(ACTION_NETWORK_STATS_UPDATED); updatedIntent.setFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); @@ -1474,6 +1499,12 @@ public class NetworkStatsService extends INetworkStatsService.Stub { public void forceUpdate() { NetworkStatsService.this.forceUpdate(); } + + @Override + public void setStatsProviderLimit(@NonNull String iface, long quota) { + Slog.v(TAG, "setStatsProviderLimit(" + iface + "," + quota + ")"); + invokeForAllStatsProviderCallbacks((cb) -> cb.mProvider.setLimit(iface, quota)); + } } @Override @@ -1688,6 +1719,12 @@ public class NetworkStatsService extends INetworkStatsService.Stub { uidSnapshot.combineAllValues(vtStats); } + // get a stale copy of uid stats snapshot provided by providers. + final NetworkStats providerStats = getNetworkStatsFromProviders(STATS_PER_UID); + providerStats.filter(UID_ALL, ifaces, TAG_ALL); + mStatsFactory.apply464xlatAdjustments(uidSnapshot, providerStats, mUseBpfTrafficStats); + uidSnapshot.combineAllValues(providerStats); + uidSnapshot.combineAllValues(mUidOperations); return uidSnapshot; @@ -1724,6 +1761,152 @@ public class NetworkStatsService extends INetworkStatsService.Stub { } } + /** + * Registers a custom provider of {@link android.net.NetworkStats} to combine the network + * statistics that cannot be seen by the kernel to system. To unregister, invoke the + * {@code unregister()} of the returned callback. + * + * @param tag a human readable identifier of the custom network stats provider. + * @param provider the binder interface of + * {@link android.net.netstats.provider.AbstractNetworkStatsProvider} that + * needs to be registered to the system. + * + * @return a binder interface of + * {@link android.net.netstats.provider.NetworkStatsProviderCallback}, which can be + * used to report events to the system. + */ + public @NonNull INetworkStatsProviderCallback registerNetworkStatsProvider( + @NonNull String tag, @NonNull INetworkStatsProvider provider) { + mContext.enforceCallingOrSelfPermission(UPDATE_DEVICE_STATS, TAG); + Objects.requireNonNull(provider, "provider is null"); + Objects.requireNonNull(tag, "tag is null"); + try { + NetworkStatsProviderCallbackImpl callback = new NetworkStatsProviderCallbackImpl( + tag, provider, mAlertObserver, mStatsProviderCbList); + mStatsProviderCbList.register(callback); + Log.d(TAG, "registerNetworkStatsProvider from " + callback.mTag + " uid/pid=" + + getCallingUid() + "/" + getCallingPid()); + return callback; + } catch (RemoteException e) { + Log.e(TAG, "registerNetworkStatsProvider failed", e); + } + return null; + } + + // Collect stats from local cache of providers. + private @NonNull NetworkStats getNetworkStatsFromProviders(int how) { + final NetworkStats ret = new NetworkStats(0L, 0); + invokeForAllStatsProviderCallbacks((cb) -> ret.combineAllValues(cb.getCachedStats(how))); + return ret; + } + + @FunctionalInterface + private interface ThrowingConsumer<S, T extends Throwable> { + void accept(S s) throws T; + } + + private void invokeForAllStatsProviderCallbacks( + @NonNull ThrowingConsumer<NetworkStatsProviderCallbackImpl, RemoteException> task) { + synchronized (mStatsProviderCbList) { + final int length = mStatsProviderCbList.beginBroadcast(); + try { + for (int i = 0; i < length; i++) { + final NetworkStatsProviderCallbackImpl cb = + mStatsProviderCbList.getBroadcastItem(i); + try { + task.accept(cb); + } catch (RemoteException e) { + Log.e(TAG, "Fail to broadcast to provider: " + cb.mTag, e); + } + } + } finally { + mStatsProviderCbList.finishBroadcast(); + } + } + } + + private static class NetworkStatsProviderCallbackImpl extends INetworkStatsProviderCallback.Stub + implements IBinder.DeathRecipient { + @NonNull final String mTag; + @NonNull private final Object mProviderStatsLock = new Object(); + @NonNull final INetworkStatsProvider mProvider; + @NonNull final INetworkManagementEventObserver mAlertObserver; + @NonNull final RemoteCallbackList<NetworkStatsProviderCallbackImpl> mStatsProviderCbList; + + @GuardedBy("mProviderStatsLock") + // STATS_PER_IFACE and STATS_PER_UID + private final NetworkStats mIfaceStats = new NetworkStats(0L, 0); + @GuardedBy("mProviderStatsLock") + private final NetworkStats mUidStats = new NetworkStats(0L, 0); + + NetworkStatsProviderCallbackImpl( + @NonNull String tag, @NonNull INetworkStatsProvider provider, + @NonNull INetworkManagementEventObserver alertObserver, + @NonNull RemoteCallbackList<NetworkStatsProviderCallbackImpl> cbList) + throws RemoteException { + mTag = tag; + mProvider = provider; + mProvider.asBinder().linkToDeath(this, 0); + mAlertObserver = alertObserver; + mStatsProviderCbList = cbList; + } + + @NonNull + public NetworkStats getCachedStats(int how) { + synchronized (mProviderStatsLock) { + NetworkStats stats; + switch (how) { + case STATS_PER_IFACE: + stats = mIfaceStats; + break; + case STATS_PER_UID: + stats = mUidStats; + break; + default: + throw new IllegalArgumentException("Invalid type: " + how); + } + // Return a defensive copy instead of local reference. + return stats.clone(); + } + } + + @Override + public void onStatsUpdated(int token, @Nullable NetworkStats ifaceStats, + @Nullable NetworkStats uidStats) { + // TODO: 1. Use token to map ifaces to correct NetworkIdentity. + // 2. Store the difference and store it directly to the recorder. + synchronized (mProviderStatsLock) { + if (ifaceStats != null) mIfaceStats.combineAllValues(ifaceStats); + if (uidStats != null) mUidStats.combineAllValues(uidStats); + } + } + + @Override + public void onAlertReached() throws RemoteException { + mAlertObserver.limitReached(LIMIT_GLOBAL_ALERT, null /* unused */); + } + + @Override + public void onLimitReached() { + Log.d(TAG, mTag + ": onLimitReached"); + LocalServices.getService(NetworkPolicyManagerInternal.class) + .onStatsProviderLimitReached(mTag); + } + + @Override + public void binderDied() { + Log.d(TAG, mTag + ": binderDied"); + mStatsProviderCbList.unregister(this); + } + + @Override + public void unregister() { + Log.d(TAG, mTag + ": unregister"); + mStatsProviderCbList.unregister(this); + } + + } + @VisibleForTesting static class HandlerCallback implements Handler.Callback { private final NetworkStatsService mService; @@ -1813,6 +1996,10 @@ public class NetworkStatsService extends INetworkStatsService.Stub { return getGlobalLong(NETSTATS_POLL_INTERVAL, 30 * MINUTE_IN_MILLIS); } @Override + public long getPollDelay() { + return DEFAULT_PERFORM_POLL_DELAY_MS; + } + @Override public long getGlobalAlertBytes(long def) { return getGlobalLong(NETSTATS_GLOBAL_ALERT_BYTES, def); } diff --git a/services/core/java/com/android/server/os/DeviceIdentifiersPolicyService.java b/services/core/java/com/android/server/os/DeviceIdentifiersPolicyService.java index 9c1ac346ce32..947405ed2a78 100644 --- a/services/core/java/com/android/server/os/DeviceIdentifiersPolicyService.java +++ b/services/core/java/com/android/server/os/DeviceIdentifiersPolicyService.java @@ -56,16 +56,17 @@ public final class DeviceIdentifiersPolicyService extends SystemService { // for any device / profile owner checks. The majority of requests for the serial number // should use the getSerialForPackage method with the calling package specified. if (!TelephonyPermissions.checkCallingOrSelfReadDeviceIdentifiers(mContext, - /* callingPackage */ null, "getSerial")) { + /* callingPackage */ null, null, "getSerial")) { return Build.UNKNOWN; } return SystemProperties.get("ro.serialno", Build.UNKNOWN); } @Override - public @Nullable String getSerialForPackage(String callingPackage) throws RemoteException { + public @Nullable String getSerialForPackage(String callingPackage, + String callingFeatureId) throws RemoteException { if (!TelephonyPermissions.checkCallingOrSelfReadDeviceIdentifiers(mContext, - callingPackage, "getSerial")) { + callingPackage, callingFeatureId, "getSerial")) { return Build.UNKNOWN; } return SystemProperties.get("ro.serialno", Build.UNKNOWN); diff --git a/services/core/java/com/android/server/pm/StagingManager.java b/services/core/java/com/android/server/pm/StagingManager.java index 2705455078ff..349a0031613b 100644 --- a/services/core/java/com/android/server/pm/StagingManager.java +++ b/services/core/java/com/android/server/pm/StagingManager.java @@ -41,6 +41,7 @@ import android.os.Bundle; import android.os.Handler; import android.os.IBinder; import android.os.ParcelFileDescriptor; +import android.os.ParcelableException; import android.os.PowerManager; import android.os.RemoteException; import android.os.ServiceManager; @@ -414,29 +415,28 @@ public class StagingManager { } else { params.installFlags |= PackageManager.INSTALL_DISABLE_VERIFICATION; } - int apkSessionId = mPi.createSession( - params, originalSession.getInstallerPackageName(), - 0 /* UserHandle.SYSTEM */); - PackageInstallerSession apkSession = mPi.getSession(apkSessionId); - try { + int apkSessionId = mPi.createSession( + params, originalSession.getInstallerPackageName(), + 0 /* UserHandle.SYSTEM */); + PackageInstallerSession apkSession = mPi.getSession(apkSessionId); apkSession.open(); for (String apkFilePath : apkFilePaths) { File apkFile = new File(apkFilePath); ParcelFileDescriptor pfd = ParcelFileDescriptor.open(apkFile, ParcelFileDescriptor.MODE_READ_ONLY); - long sizeBytes = pfd.getStatSize(); + long sizeBytes = (pfd == null) ? -1 : pfd.getStatSize(); if (sizeBytes < 0) { Slog.e(TAG, "Unable to get size of: " + apkFilePath); return null; } apkSession.write(apkFile.getName(), 0, sizeBytes, pfd); } - } catch (IOException e) { + return apkSession; + } catch (IOException | ParcelableException e) { Slog.e(TAG, "Failure to install APK staged session " + originalSession.sessionId, e); return null; } - return apkSession; } private boolean commitApkSession(@NonNull PackageInstallerSession apkSession, diff --git a/services/core/java/com/android/server/pm/dex/DexManager.java b/services/core/java/com/android/server/pm/dex/DexManager.java index f56231fc02af..9e86a4bd2880 100644 --- a/services/core/java/com/android/server/pm/dex/DexManager.java +++ b/services/core/java/com/android/server/pm/dex/DexManager.java @@ -229,6 +229,7 @@ public class DexManager { // If the dex file is the primary apk (or a split) and not isUsedByOtherApps // do not record it. This case does not bring any new usable information // and can be safely skipped. + dexPathIndex++; continue; } diff --git a/services/core/java/com/android/server/stats/OWNERS b/services/core/java/com/android/server/stats/OWNERS index 8d7f8822f78e..fc7fd220b26a 100644 --- a/services/core/java/com/android/server/stats/OWNERS +++ b/services/core/java/com/android/server/stats/OWNERS @@ -1,9 +1,8 @@ -bookatz@google.com -cjyu@google.com -dwchen@google.com +jeffreyhuang@google.com joeo@google.com +muhammadq@google.com +ruchirr@google.com singhtejinder@google.com -stlafon@google.com +tsaichristine@google.com yaochen@google.com -yanglu@google.com -yro@google.com
\ No newline at end of file +yro@google.com diff --git a/services/core/java/com/android/server/timedetector/TimeDetectorStrategy.java b/services/core/java/com/android/server/timedetector/TimeDetectorStrategy.java index b4f4eca5f188..468b806d6dce 100644 --- a/services/core/java/com/android/server/timedetector/TimeDetectorStrategy.java +++ b/services/core/java/com/android/server/timedetector/TimeDetectorStrategy.java @@ -21,8 +21,7 @@ import android.annotation.Nullable; import android.app.timedetector.ManualTimeSuggestion; import android.app.timedetector.NetworkTimeSuggestion; import android.app.timedetector.PhoneTimeSuggestion; -import android.content.Intent; -import android.util.TimestampedValue; +import android.os.TimestampedValue; import java.io.PrintWriter; @@ -62,10 +61,10 @@ public interface TimeDetectorStrategy { /** Acquire a suitable wake lock. Must be followed by {@link #releaseWakeLock()} */ void acquireWakeLock(); - /** Returns the elapsedRealtimeMillis clock value. The WakeLock must be held. */ + /** Returns the elapsedRealtimeMillis clock value. */ long elapsedRealtimeMillis(); - /** Returns the system clock value. The WakeLock must be held. */ + /** Returns the system clock value. */ long systemClockMillis(); /** Sets the device system clock. The WakeLock must be held. */ @@ -73,9 +72,6 @@ public interface TimeDetectorStrategy { /** Release the wake lock acquired by a call to {@link #acquireWakeLock()}. */ void releaseWakeLock(); - - /** Send the supplied intent as a stick broadcast. */ - void sendStickyBroadcast(@NonNull Intent intent); } /** Initialize the strategy. */ diff --git a/services/core/java/com/android/server/timedetector/TimeDetectorStrategyCallbackImpl.java b/services/core/java/com/android/server/timedetector/TimeDetectorStrategyCallbackImpl.java index 42d59d51c6af..19484db149b1 100644 --- a/services/core/java/com/android/server/timedetector/TimeDetectorStrategyCallbackImpl.java +++ b/services/core/java/com/android/server/timedetector/TimeDetectorStrategyCallbackImpl.java @@ -20,11 +20,9 @@ import android.annotation.NonNull; import android.app.AlarmManager; import android.content.ContentResolver; import android.content.Context; -import android.content.Intent; import android.os.PowerManager; import android.os.SystemClock; import android.os.SystemProperties; -import android.os.UserHandle; import android.provider.Settings; import android.util.Slog; @@ -90,13 +88,11 @@ public final class TimeDetectorStrategyCallbackImpl implements TimeDetectorStrat @Override public long elapsedRealtimeMillis() { - checkWakeLockHeld(); return SystemClock.elapsedRealtime(); } @Override public long systemClockMillis() { - checkWakeLockHeld(); return System.currentTimeMillis(); } @@ -112,11 +108,6 @@ public final class TimeDetectorStrategyCallbackImpl implements TimeDetectorStrat mWakeLock.release(); } - @Override - public void sendStickyBroadcast(@NonNull Intent intent) { - mContext.sendStickyBroadcastAsUser(intent, UserHandle.ALL); - } - private void checkWakeLockHeld() { if (!mWakeLock.isHeld()) { Slog.wtf(TAG, "WakeLock " + mWakeLock + " not held"); diff --git a/services/core/java/com/android/server/timedetector/TimeDetectorStrategyImpl.java b/services/core/java/com/android/server/timedetector/TimeDetectorStrategyImpl.java index 02656eaf5c6c..e95fc4a4a938 100644 --- a/services/core/java/com/android/server/timedetector/TimeDetectorStrategyImpl.java +++ b/services/core/java/com/android/server/timedetector/TimeDetectorStrategyImpl.java @@ -23,11 +23,9 @@ import android.app.AlarmManager; import android.app.timedetector.ManualTimeSuggestion; import android.app.timedetector.NetworkTimeSuggestion; import android.app.timedetector.PhoneTimeSuggestion; -import android.content.Intent; -import android.telephony.TelephonyManager; +import android.os.TimestampedValue; import android.util.LocalLog; import android.util.Slog; -import android.util.TimestampedValue; import com.android.internal.annotations.GuardedBy; import com.android.internal.annotations.VisibleForTesting; @@ -535,17 +533,6 @@ public final class TimeDetectorStrategyImpl implements TimeDetectorStrategy { } else { mLastAutoSystemClockTimeSet = null; } - - // Historically, Android has sent a TelephonyManager.ACTION_NETWORK_SET_TIME broadcast only - // when setting the time using NITZ. - if (origin == ORIGIN_PHONE) { - // Send a broadcast that telephony code used to send after setting the clock. - // TODO Remove this broadcast as soon as there are no remaining listeners. - Intent intent = new Intent(TelephonyManager.ACTION_NETWORK_SET_TIME); - intent.addFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING); - intent.putExtra("time", newSystemClockMillis); - mCallback.sendStickyBroadcast(intent); - } } /** diff --git a/services/core/java/com/android/server/wallpaper/GLHelper.java b/services/core/java/com/android/server/wallpaper/GLHelper.java new file mode 100644 index 000000000000..1d733f53f055 --- /dev/null +++ b/services/core/java/com/android/server/wallpaper/GLHelper.java @@ -0,0 +1,148 @@ +/* + * 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.wallpaper; + +import static android.opengl.EGL14.EGL_ALPHA_SIZE; +import static android.opengl.EGL14.EGL_BLUE_SIZE; +import static android.opengl.EGL14.EGL_CONFIG_CAVEAT; +import static android.opengl.EGL14.EGL_CONTEXT_CLIENT_VERSION; +import static android.opengl.EGL14.EGL_DEFAULT_DISPLAY; +import static android.opengl.EGL14.EGL_DEPTH_SIZE; +import static android.opengl.EGL14.EGL_GREEN_SIZE; +import static android.opengl.EGL14.EGL_HEIGHT; +import static android.opengl.EGL14.EGL_NONE; +import static android.opengl.EGL14.EGL_NO_CONTEXT; +import static android.opengl.EGL14.EGL_NO_DISPLAY; +import static android.opengl.EGL14.EGL_NO_SURFACE; +import static android.opengl.EGL14.EGL_OPENGL_ES2_BIT; +import static android.opengl.EGL14.EGL_RED_SIZE; +import static android.opengl.EGL14.EGL_RENDERABLE_TYPE; +import static android.opengl.EGL14.EGL_STENCIL_SIZE; +import static android.opengl.EGL14.EGL_WIDTH; +import static android.opengl.EGL14.eglChooseConfig; +import static android.opengl.EGL14.eglCreateContext; +import static android.opengl.EGL14.eglCreatePbufferSurface; +import static android.opengl.EGL14.eglDestroyContext; +import static android.opengl.EGL14.eglDestroySurface; +import static android.opengl.EGL14.eglGetDisplay; +import static android.opengl.EGL14.eglGetError; +import static android.opengl.EGL14.eglInitialize; +import static android.opengl.EGL14.eglMakeCurrent; +import static android.opengl.EGL14.eglTerminate; +import static android.opengl.GLES20.GL_MAX_TEXTURE_SIZE; +import static android.opengl.GLES20.glGetIntegerv; + +import android.opengl.EGLConfig; +import android.opengl.EGLContext; +import android.opengl.EGLDisplay; +import android.opengl.EGLSurface; +import android.opengl.GLUtils; +import android.os.SystemProperties; +import android.util.Log; + +class GLHelper { + private static final String TAG = GLHelper.class.getSimpleName(); + private static final int sMaxTextureSize; + + static { + int maxTextureSize = SystemProperties.getInt("sys.max_texture_size", 0); + sMaxTextureSize = maxTextureSize > 0 ? maxTextureSize : retrieveTextureSizeFromGL(); + } + + private static int retrieveTextureSizeFromGL() { + try { + String err; + + // Before we can retrieve info from GL, + // we have to create EGLContext, EGLConfig and EGLDisplay first. + // We will fail at querying info from GL once one of above failed. + // When this happens, we will use defValue instead. + EGLDisplay eglDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY); + if (eglDisplay == null || eglDisplay == EGL_NO_DISPLAY) { + err = "eglGetDisplay failed: " + GLUtils.getEGLErrorString(eglGetError()); + throw new RuntimeException(err); + } + + if (!eglInitialize(eglDisplay, null, 0 /* majorOffset */, null, 1 /* minorOffset */)) { + err = "eglInitialize failed: " + GLUtils.getEGLErrorString(eglGetError()); + throw new RuntimeException(err); + } + + EGLConfig eglConfig = null; + int[] configsCount = new int[1]; + EGLConfig[] configs = new EGLConfig[1]; + int[] configSpec = new int[] { + EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT, + EGL_RED_SIZE, 8, + EGL_GREEN_SIZE, 8, + EGL_BLUE_SIZE, 8, + EGL_ALPHA_SIZE, 0, + EGL_DEPTH_SIZE, 0, + EGL_STENCIL_SIZE, 0, + EGL_CONFIG_CAVEAT, EGL_NONE, + EGL_NONE + }; + + if (!eglChooseConfig(eglDisplay, configSpec, 0 /* attrib_listOffset */, + configs, 0 /* configOffset */, 1 /* config_size */, + configsCount, 0 /* num_configOffset */)) { + err = "eglChooseConfig failed: " + GLUtils.getEGLErrorString(eglGetError()); + throw new RuntimeException(err); + } else if (configsCount[0] > 0) { + eglConfig = configs[0]; + } + + if (eglConfig == null) { + throw new RuntimeException("eglConfig not initialized!"); + } + + int[] attr_list = new int[] {EGL_CONTEXT_CLIENT_VERSION, 2, EGL_NONE}; + EGLContext eglContext = eglCreateContext( + eglDisplay, eglConfig, EGL_NO_CONTEXT, attr_list, 0 /* offset */); + + if (eglContext == null || eglContext == EGL_NO_CONTEXT) { + err = "eglCreateContext failed: " + GLUtils.getEGLErrorString(eglGetError()); + throw new RuntimeException(err); + } + + // We create a push buffer temporarily for querying info from GL. + int[] attrs = {EGL_WIDTH, 1, EGL_HEIGHT, 1, EGL_NONE}; + EGLSurface eglSurface = + eglCreatePbufferSurface(eglDisplay, eglConfig, attrs, 0 /* offset */); + eglMakeCurrent(eglDisplay, eglSurface, eglSurface, eglContext); + + // Now, we are ready to query the info from GL. + int[] maxSize = new int[1]; + glGetIntegerv(GL_MAX_TEXTURE_SIZE, maxSize, 0 /* offset */); + + // We have got the info we want, release all egl resources. + eglMakeCurrent(eglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT); + eglDestroySurface(eglDisplay, eglSurface); + eglDestroyContext(eglDisplay, eglContext); + eglTerminate(eglDisplay); + return maxSize[0]; + } catch (RuntimeException e) { + Log.w(TAG, "Retrieve from GL failed", e); + return Integer.MAX_VALUE; + } + } + + static int getMaxTextureSize() { + return sMaxTextureSize; + } +} + diff --git a/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java b/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java index b0f1e5d69be4..991c09a97bf5 100644 --- a/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java +++ b/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java @@ -134,6 +134,9 @@ public class WallpaperManagerService extends IWallpaperManager.Stub private static final boolean DEBUG = false; private static final boolean DEBUG_LIVE = true; + // This 100MB limitation is defined in RecordingCanvas. + private static final int MAX_BITMAP_SIZE = 100 * 1024 * 1024; + public static class Lifecycle extends SystemService { private IWallpaperManagerService mService; @@ -572,7 +575,9 @@ public class WallpaperManagerService extends IWallpaperManager.Stub // Only generate crop for default display. final DisplayData wpData = getDisplayDataOrCreate(DEFAULT_DISPLAY); - Rect cropHint = new Rect(wallpaper.cropHint); + final Rect cropHint = new Rect(wallpaper.cropHint); + final DisplayInfo displayInfo = new DisplayInfo(); + mDisplayManager.getDisplay(DEFAULT_DISPLAY).getDisplayInfo(displayInfo); if (DEBUG) { Slog.v(TAG, "Generating crop for new wallpaper(s): 0x" @@ -618,12 +623,12 @@ public class WallpaperManagerService extends IWallpaperManager.Stub } // scale if the crop height winds up not matching the recommended metrics - needScale = (wpData.mHeight != cropHint.height()); + needScale = wpData.mHeight != cropHint.height() + || cropHint.height() > GLHelper.getMaxTextureSize() + || cropHint.width() > GLHelper.getMaxTextureSize(); //make sure screen aspect ratio is preserved if width is scaled under screen size if (needScale) { - final DisplayInfo displayInfo = new DisplayInfo(); - mDisplayManager.getDisplay(DEFAULT_DISPLAY).getDisplayInfo(displayInfo); final float scaleByHeight = (float) wpData.mHeight / (float) cropHint.height(); final int newWidth = (int) (cropHint.width() * scaleByHeight); if (newWidth < displayInfo.logicalWidth) { @@ -644,14 +649,29 @@ public class WallpaperManagerService extends IWallpaperManager.Stub if (!needCrop && !needScale) { // Simple case: the nominal crop fits what we want, so we take // the whole thing and just copy the image file directly. - if (DEBUG) { - Slog.v(TAG, "Null crop of new wallpaper; copying"); + + // TODO: It is not accurate to estimate bitmap size without decoding it, + // may be we can try to remove this optimized way in the future, + // that means, we will always go into the 'else' block. + + // This is just a quick estimation, may be smaller than it is. + long estimateSize = options.outWidth * options.outHeight * 4; + + // A bitmap over than MAX_BITMAP_SIZE will make drawBitmap() fail. + // Please see: RecordingCanvas#throwIfCannotDraw. + if (estimateSize < MAX_BITMAP_SIZE) { + success = FileUtils.copyFile(wallpaper.wallpaperFile, wallpaper.cropFile); } - success = FileUtils.copyFile(wallpaper.wallpaperFile, wallpaper.cropFile); + if (!success) { wallpaper.cropFile.delete(); // TODO: fall back to default wallpaper in this case } + + if (DEBUG) { + Slog.v(TAG, "Null crop of new wallpaper, estimate size=" + + estimateSize + ", success=" + success); + } } else { // Fancy case: crop and scale. First, we decode and scale down if appropriate. FileOutputStream f = null; @@ -665,49 +685,78 @@ public class WallpaperManagerService extends IWallpaperManager.Stub // We calculate the largest power-of-two under the actual ratio rather than // just let the decode take care of it because we also want to remap where the // cropHint rectangle lies in the decoded [super]rect. - final BitmapFactory.Options scaler; final int actualScale = cropHint.height() / wpData.mHeight; int scale = 1; - while (2*scale < actualScale) { + while (2 * scale <= actualScale) { scale *= 2; } - if (scale > 1) { - scaler = new BitmapFactory.Options(); - scaler.inSampleSize = scale; + options.inSampleSize = scale; + options.inJustDecodeBounds = false; + + final Rect estimateCrop = new Rect(cropHint); + estimateCrop.scale(1f / options.inSampleSize); + final float hRatio = (float) wpData.mHeight / estimateCrop.height(); + final int destHeight = (int) (estimateCrop.height() * hRatio); + final int destWidth = (int) (estimateCrop.width() * hRatio); + + // We estimated an invalid crop, try to adjust the cropHint to get a valid one. + if (destWidth > GLHelper.getMaxTextureSize()) { + int newHeight = (int) (wpData.mHeight / hRatio); + int newWidth = (int) (wpData.mWidth / hRatio); + if (DEBUG) { - Slog.v(TAG, "Downsampling cropped rect with scale " + scale); + Slog.v(TAG, "Invalid crop dimensions, trying to adjust."); } - } else { - scaler = null; + + estimateCrop.set(cropHint); + estimateCrop.left += (cropHint.width() - newWidth) / 2; + estimateCrop.top += (cropHint.height() - newHeight) / 2; + estimateCrop.right = estimateCrop.left + newWidth; + estimateCrop.bottom = estimateCrop.top + newHeight; + cropHint.set(estimateCrop); + estimateCrop.scale(1f / options.inSampleSize); + } + + // We've got the safe cropHint; now we want to scale it properly to + // the desired rectangle. + // That's a height-biased operation: make it fit the hinted height. + final int safeHeight = (int) (estimateCrop.height() * hRatio); + final int safeWidth = (int) (estimateCrop.width() * hRatio); + + if (DEBUG) { + Slog.v(TAG, "Decode parameters:"); + Slog.v(TAG, " cropHint=" + cropHint + ", estimateCrop=" + estimateCrop); + Slog.v(TAG, " down sampling=" + options.inSampleSize + + ", hRatio=" + hRatio); + Slog.v(TAG, " dest=" + destWidth + "x" + destHeight); + Slog.v(TAG, " safe=" + safeWidth + "x" + safeHeight); + Slog.v(TAG, " maxTextureSize=" + GLHelper.getMaxTextureSize()); } - Bitmap cropped = decoder.decodeRegion(cropHint, scaler); + + Bitmap cropped = decoder.decodeRegion(cropHint, options); decoder.recycle(); if (cropped == null) { Slog.e(TAG, "Could not decode new wallpaper"); } else { - // We've got the extracted crop; now we want to scale it properly to - // the desired rectangle. That's a height-biased operation: make it - // fit the hinted height, and accept whatever width we end up with. - cropHint.offsetTo(0, 0); - cropHint.right /= scale; // adjust by downsampling factor - cropHint.bottom /= scale; - final float heightR = - ((float) wpData.mHeight) / ((float) cropHint.height()); - if (DEBUG) { - Slog.v(TAG, "scale " + heightR + ", extracting " + cropHint); - } - final int destWidth = (int)(cropHint.width() * heightR); + // We are safe to create final crop with safe dimensions now. final Bitmap finalCrop = Bitmap.createScaledBitmap(cropped, - destWidth, wpData.mHeight, true); + safeWidth, safeHeight, true); if (DEBUG) { Slog.v(TAG, "Final extract:"); Slog.v(TAG, " dims: w=" + wpData.mWidth + " h=" + wpData.mHeight); - Slog.v(TAG, " out: w=" + finalCrop.getWidth() + Slog.v(TAG, " out: w=" + finalCrop.getWidth() + " h=" + finalCrop.getHeight()); } + // A bitmap over than MAX_BITMAP_SIZE will make drawBitmap() fail. + // Please see: RecordingCanvas#throwIfCannotDraw. + if (finalCrop.getByteCount() > MAX_BITMAP_SIZE) { + throw new RuntimeException( + "Too large bitmap, limit=" + MAX_BITMAP_SIZE); + } + f = new FileOutputStream(wallpaper.cropFile); bos = new BufferedOutputStream(f, 32*1024); finalCrop.compress(Bitmap.CompressFormat.JPEG, 100, bos); @@ -1981,6 +2030,11 @@ public class WallpaperManagerService extends IWallpaperManager.Stub if (!isWallpaperSupported(callingPackage)) { return; } + + // Make sure both width and height are not larger than max texture size. + width = Math.min(width, GLHelper.getMaxTextureSize()); + height = Math.min(height, GLHelper.getMaxTextureSize()); + synchronized (mLock) { int userId = UserHandle.getCallingUserId(); WallpaperData wallpaper = getWallpaperSafeLocked(userId, FLAG_SYSTEM); diff --git a/services/core/jni/com_android_server_net_NetworkStatsFactory.cpp b/services/core/jni/com_android_server_net_NetworkStatsFactory.cpp index 9cd743b3466a..8b6526ff49f0 100644 --- a/services/core/jni/com_android_server_net_NetworkStatsFactory.cpp +++ b/services/core/jni/com_android_server_net_NetworkStatsFactory.cpp @@ -20,6 +20,7 @@ #include <inttypes.h> #include <sys/stat.h> #include <sys/types.h> +#include <vector> #include <jni.h> diff --git a/services/core/jni/com_android_server_net_NetworkStatsService.cpp b/services/core/jni/com_android_server_net_NetworkStatsService.cpp index 4696dd0bb88b..0275f3ea32f7 100644 --- a/services/core/jni/com_android_server_net_NetworkStatsService.cpp +++ b/services/core/jni/com_android_server_net_NetworkStatsService.cpp @@ -33,7 +33,6 @@ #include "bpf/BpfUtils.h" #include "netdbpf/BpfNetworkStats.h" -using android::bpf::Stats; using android::bpf::bpfGetUidStats; using android::bpf::bpfGetIfaceStats; diff --git a/services/net/Android.bp b/services/net/Android.bp index 9c7cfc197bba..cf84bdfb5b6f 100644 --- a/services/net/Android.bp +++ b/services/net/Android.bp @@ -23,7 +23,6 @@ filegroup { name: "services-tethering-shared-srcs", srcs: [ ":framework-annotations", - "java/android/net/util/NetdService.java", "java/android/net/util/NetworkConstants.java", ], visibility: ["//frameworks/base/packages/Tethering"], diff --git a/services/net/java/android/net/TcpKeepalivePacketData.java b/services/net/java/android/net/TcpKeepalivePacketData.java index 7f2f499ab21f..aad75ae16aa9 100644 --- a/services/net/java/android/net/TcpKeepalivePacketData.java +++ b/services/net/java/android/net/TcpKeepalivePacketData.java @@ -19,7 +19,6 @@ import static android.net.SocketKeepalive.ERROR_INVALID_IP_ADDRESS; import android.annotation.NonNull; import android.annotation.Nullable; -import android.net.SocketKeepalive.InvalidPacketException; import android.net.util.IpUtils; import android.os.Parcel; import android.os.Parcelable; diff --git a/services/net/java/android/net/ip/IpClientCallbacks.java b/services/net/java/android/net/ip/IpClientCallbacks.java index 61cd88aac921..c93e5c5e4759 100644 --- a/services/net/java/android/net/ip/IpClientCallbacks.java +++ b/services/net/java/android/net/ip/IpClientCallbacks.java @@ -17,6 +17,7 @@ package android.net.ip; import android.net.DhcpResults; +import android.net.DhcpResultsParcelable; import android.net.Layer2PacketParcelable; import android.net.LinkProperties; @@ -69,6 +70,18 @@ public class IpClientCallbacks { public void onNewDhcpResults(DhcpResults dhcpResults) {} /** + * Callback called when new DHCP results are available. + * + * <p>This is purely advisory and not an indication of provisioning success or failure. This is + * only here for callers that want to expose DHCPv4 results to other APIs + * (e.g., WifiInfo#setInetAddress). + * + * <p>DHCPv4 or static IPv4 configuration failure or success can be determined by whether or not + * the passed-in DhcpResults object is null. + */ + public void onNewDhcpResults(DhcpResultsParcelable dhcpResults) {} + + /** * Indicates that provisioning was successful. */ public void onProvisioningSuccess(LinkProperties newLp) {} diff --git a/services/net/java/android/net/ip/IpClientUtil.java b/services/net/java/android/net/ip/IpClientUtil.java index 4d60e6239376..7f723b1c232b 100644 --- a/services/net/java/android/net/ip/IpClientUtil.java +++ b/services/net/java/android/net/ip/IpClientUtil.java @@ -119,6 +119,7 @@ public class IpClientUtil { @Override public void onNewDhcpResults(DhcpResultsParcelable dhcpResults) { mCb.onNewDhcpResults(fromStableParcelable(dhcpResults)); + mCb.onNewDhcpResults(dhcpResults); } @Override diff --git a/services/robotests/src/com/android/server/location/NtpTimeHelperTest.java b/services/robotests/src/com/android/server/location/NtpTimeHelperTest.java index a8a258fc5ff7..9c5d4ad6ceeb 100644 --- a/services/robotests/src/com/android/server/location/NtpTimeHelperTest.java +++ b/services/robotests/src/com/android/server/location/NtpTimeHelperTest.java @@ -3,6 +3,7 @@ package com.android.server.location; import static com.google.common.truth.Truth.assertThat; import static org.mockito.Mockito.doReturn; +import static org.mockito.Mockito.mock; import android.os.Looper; import android.os.SystemClock; @@ -52,8 +53,10 @@ public class NtpTimeHelperTest { @Test public void handleInjectNtpTime_cachedAgeLow_injectTime() throws InterruptedException { - doReturn(NtpTimeHelper.NTP_INTERVAL - 1).when(mMockNtpTrustedTime).getCacheAge(); - doReturn(MOCK_NTP_TIME).when(mMockNtpTrustedTime).getCachedNtpTime(); + NtpTrustedTime.TimeResult result = mock(NtpTrustedTime.TimeResult.class); + doReturn(NtpTimeHelper.NTP_INTERVAL - 1).when(result).getAgeMillis(); + doReturn(MOCK_NTP_TIME).when(result).getTimeMillis(); + doReturn(result).when(mMockNtpTrustedTime).getCachedTimeResult(); mNtpTimeHelper.retrieveAndInjectNtpTime(); @@ -64,7 +67,9 @@ public class NtpTimeHelperTest { @Test public void handleInjectNtpTime_injectTimeFailed_injectTimeDelayed() throws InterruptedException { - doReturn(NtpTimeHelper.NTP_INTERVAL + 1).when(mMockNtpTrustedTime).getCacheAge(); + NtpTrustedTime.TimeResult result1 = mock(NtpTrustedTime.TimeResult.class); + doReturn(NtpTimeHelper.NTP_INTERVAL + 1).when(result1).getAgeMillis(); + doReturn(result1).when(mMockNtpTrustedTime).getCachedTimeResult(); doReturn(false).when(mMockNtpTrustedTime).forceRefresh(); mNtpTimeHelper.retrieveAndInjectNtpTime(); @@ -72,8 +77,10 @@ public class NtpTimeHelperTest { assertThat(mCountDownLatch.await(2, TimeUnit.SECONDS)).isFalse(); doReturn(true).when(mMockNtpTrustedTime).forceRefresh(); - doReturn(1L).when(mMockNtpTrustedTime).getCacheAge(); - doReturn(MOCK_NTP_TIME).when(mMockNtpTrustedTime).getCachedNtpTime(); + NtpTrustedTime.TimeResult result2 = mock(NtpTrustedTime.TimeResult.class); + doReturn(1L).when(result2).getAgeMillis(); + doReturn(MOCK_NTP_TIME).when(result2).getTimeMillis(); + doReturn(result2).when(mMockNtpTrustedTime).getCachedTimeResult(); SystemClock.sleep(NtpTimeHelper.RETRY_INTERVAL); waitForTasksToBePostedOnHandlerAndRunThem(); diff --git a/services/tests/mockingservicestests/AndroidManifest.xml b/services/tests/mockingservicestests/AndroidManifest.xml index 32d7d026ff10..1200c0c8c7bd 100644 --- a/services/tests/mockingservicestests/AndroidManifest.xml +++ b/services/tests/mockingservicestests/AndroidManifest.xml @@ -20,6 +20,7 @@ <uses-permission android:name="android.permission.CHANGE_CONFIGURATION" /> <uses-permission android:name="android.permission.HARDWARE_TEST"/> <uses-permission android:name="android.permission.INTERACT_ACROSS_USERS_FULL" /> + <uses-permission android:name="android.permission.WRITE_SECURE_SETTINGS" /> <application android:testOnly="true" android:debuggable="true"> diff --git a/services/tests/servicestests/src/com/android/server/appop/AppOpsServiceTest.java b/services/tests/mockingservicestests/src/com/android/server/appop/AppOpsServiceTest.java index 71661452d800..698e491a8926 100644 --- a/services/tests/servicestests/src/com/android/server/appop/AppOpsServiceTest.java +++ b/services/tests/mockingservicestests/src/com/android/server/appop/AppOpsServiceTest.java @@ -25,14 +25,27 @@ import static android.app.AppOpsManager.OP_READ_SMS; import static android.app.AppOpsManager.OP_WIFI_SCAN; import static android.app.AppOpsManager.OP_WRITE_SMS; +import static com.android.dx.mockito.inline.extended.ExtendedMockito.doNothing; +import static com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn; +import static com.android.dx.mockito.inline.extended.ExtendedMockito.mock; +import static com.android.dx.mockito.inline.extended.ExtendedMockito.mockitoSession; +import static com.android.dx.mockito.inline.extended.ExtendedMockito.spy; +import static com.android.dx.mockito.inline.extended.ExtendedMockito.when; + import static com.google.common.truth.Truth.assertThat; import static com.google.common.truth.Truth.assertWithMessage; +import static org.mockito.ArgumentMatchers.anyInt; +import static org.mockito.ArgumentMatchers.anyString; +import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.ArgumentMatchers.nullable; + import android.app.ActivityManager; import android.app.AppOpsManager; import android.app.AppOpsManager.OpEntry; import android.app.AppOpsManager.PackageOps; import android.content.Context; +import android.content.pm.PackageManagerInternal; import android.os.Handler; import android.os.HandlerThread; import android.os.Process; @@ -43,12 +56,17 @@ import androidx.test.InstrumentationRegistry; import androidx.test.filters.SmallTest; import androidx.test.runner.AndroidJUnit4; +import com.android.dx.mockito.inline.extended.StaticMockitoSession; +import com.android.server.LocalServices; + +import org.junit.After; import org.junit.AfterClass; import org.junit.Before; import org.junit.BeforeClass; import org.junit.Ignore; import org.junit.Test; import org.junit.runner.RunWith; +import org.mockito.quality.Strictness; import java.io.File; import java.util.List; @@ -69,21 +87,46 @@ public class AppOpsServiceTest { // State will be persisted into this XML file. private static final String APP_OPS_FILENAME = "appops-service-test.xml"; + private static final Context sContext = InstrumentationRegistry.getTargetContext(); + private static final String sMyPackageName = sContext.getOpPackageName(); + private File mAppOpsFile; - private Context mContext; private Handler mHandler; - private AppOpsManager mAppOpsManager; private AppOpsService mAppOpsService; - private String mMyPackageName; private int mMyUid; private long mTestStartMillis; + private StaticMockitoSession mMockingSession; + + @Before + public void mockPackageManagerInternalGetApplicationInfo() { + mMockingSession = mockitoSession() + .strictness(Strictness.LENIENT) + .spyStatic(LocalServices.class) + .startMocking(); + + // Mock LocalServices.getService(PackageManagerInternal.class).getApplicationInfo dependency + // needed by AppOpsService + PackageManagerInternal mockPackageManagerInternal = mock(PackageManagerInternal.class); + when(mockPackageManagerInternal.getApplicationInfo(eq(sMyPackageName), anyInt(), anyInt(), + anyInt())).thenReturn(sContext.getApplicationInfo()); + doReturn(mockPackageManagerInternal).when( + () -> LocalServices.getService(PackageManagerInternal.class)); + } + + private void setupAppOpsService() { + mAppOpsService = new AppOpsService(mAppOpsFile, mHandler); + mAppOpsService.mContext = spy(sContext); + + // Always approve all permission checks + doNothing().when(mAppOpsService.mContext).enforcePermission(anyString(), anyInt(), + anyInt(), nullable(String.class)); + } private static String sDefaultAppopHistoryParameters; @Before public void setUp() { - mContext = InstrumentationRegistry.getTargetContext(); - mAppOpsFile = new File(mContext.getFilesDir(), APP_OPS_FILENAME); + mAppOpsFile = new File(sContext.getFilesDir(), APP_OPS_FILENAME); if (mAppOpsFile.exists()) { // Start with a clean state (persisted into XML). mAppOpsFile.delete(); @@ -92,13 +135,10 @@ public class AppOpsServiceTest { HandlerThread handlerThread = new HandlerThread(TAG); handlerThread.start(); mHandler = new Handler(handlerThread.getLooper()); - mMyPackageName = mContext.getOpPackageName(); mMyUid = Process.myUid(); - mAppOpsManager = mContext.getSystemService(AppOpsManager.class); - mAppOpsService = new AppOpsService(mAppOpsFile, mHandler); - mAppOpsService.mHistoricalRegistry.systemReady(mContext.getContentResolver()); - mAppOpsService.mContext = mContext; + setupAppOpsService(); + mAppOpsService.mHistoricalRegistry.systemReady(sContext.getContentResolver()); mTestStartMillis = System.currentTimeMillis(); } @@ -118,6 +158,11 @@ public class AppOpsServiceTest { sDefaultAppopHistoryParameters); } + @After + public void resetStaticMocks() { + mMockingSession.finishMocking(); + } + @Test public void testGetOpsForPackage_noOpsLogged() { assertThat(getLoggedOps()).isNull(); @@ -125,16 +170,16 @@ public class AppOpsServiceTest { @Test public void testNoteOperationAndGetOpsForPackage() { - mAppOpsService.setMode(OP_READ_SMS, mMyUid, mMyPackageName, MODE_ALLOWED); - mAppOpsService.setMode(OP_WRITE_SMS, mMyUid, mMyPackageName, MODE_ERRORED); + mAppOpsService.setMode(OP_READ_SMS, mMyUid, sMyPackageName, MODE_ALLOWED); + mAppOpsService.setMode(OP_WRITE_SMS, mMyUid, sMyPackageName, MODE_ERRORED); // Note an op that's allowed. - mAppOpsService.noteOperation(OP_READ_SMS, mMyUid, mMyPackageName); + mAppOpsService.noteOperation(OP_READ_SMS, mMyUid, sMyPackageName); List<PackageOps> loggedOps = getLoggedOps(); assertContainsOp(loggedOps, OP_READ_SMS, mTestStartMillis, -1, MODE_ALLOWED); // Note another op that's not allowed. - mAppOpsService.noteOperation(OP_WRITE_SMS, mMyUid, mMyPackageName); + mAppOpsService.noteOperation(OP_WRITE_SMS, mMyUid, sMyPackageName); loggedOps = getLoggedOps(); assertContainsOp(loggedOps, OP_READ_SMS, mTestStartMillis, -1, MODE_ALLOWED); assertContainsOp(loggedOps, OP_WRITE_SMS, -1, mTestStartMillis, MODE_ERRORED); @@ -148,17 +193,17 @@ public class AppOpsServiceTest { @Test public void testNoteOperationAndGetOpsForPackage_controlledByDifferentOp() { // This op controls WIFI_SCAN - mAppOpsService.setMode(OP_COARSE_LOCATION, mMyUid, mMyPackageName, MODE_ALLOWED); + mAppOpsService.setMode(OP_COARSE_LOCATION, mMyUid, sMyPackageName, MODE_ALLOWED); - assertThat(mAppOpsService.noteOperation(OP_WIFI_SCAN, mMyUid, mMyPackageName)) + assertThat(mAppOpsService.noteOperation(OP_WIFI_SCAN, mMyUid, sMyPackageName)) .isEqualTo(MODE_ALLOWED); assertContainsOp(getLoggedOps(), OP_WIFI_SCAN, mTestStartMillis, -1, MODE_ALLOWED /* default for WIFI_SCAN; this is not changed or used in this test */); // Now set COARSE_LOCATION to ERRORED -> this will make WIFI_SCAN disabled as well. - mAppOpsService.setMode(OP_COARSE_LOCATION, mMyUid, mMyPackageName, MODE_ERRORED); - assertThat(mAppOpsService.noteOperation(OP_WIFI_SCAN, mMyUid, mMyPackageName)) + mAppOpsService.setMode(OP_COARSE_LOCATION, mMyUid, sMyPackageName, MODE_ERRORED); + assertThat(mAppOpsService.noteOperation(OP_WIFI_SCAN, mMyUid, sMyPackageName)) .isEqualTo(MODE_ERRORED); assertContainsOp(getLoggedOps(), OP_WIFI_SCAN, mTestStartMillis, mTestStartMillis, @@ -168,15 +213,14 @@ public class AppOpsServiceTest { // Tests the dumping and restoring of the in-memory state to/from XML. @Test public void testStatePersistence() { - mAppOpsService.setMode(OP_READ_SMS, mMyUid, mMyPackageName, MODE_ALLOWED); - mAppOpsService.setMode(OP_WRITE_SMS, mMyUid, mMyPackageName, MODE_ERRORED); - mAppOpsService.noteOperation(OP_READ_SMS, mMyUid, mMyPackageName); - mAppOpsService.noteOperation(OP_WRITE_SMS, mMyUid, mMyPackageName); + mAppOpsService.setMode(OP_READ_SMS, mMyUid, sMyPackageName, MODE_ALLOWED); + mAppOpsService.setMode(OP_WRITE_SMS, mMyUid, sMyPackageName, MODE_ERRORED); + mAppOpsService.noteOperation(OP_READ_SMS, mMyUid, sMyPackageName); + mAppOpsService.noteOperation(OP_WRITE_SMS, mMyUid, sMyPackageName); mAppOpsService.writeState(); // Create a new app ops service, and initialize its state from XML. - mAppOpsService = new AppOpsService(mAppOpsFile, mHandler); - mAppOpsService.mContext = mContext; + setupAppOpsService(); mAppOpsService.readState(); // Query the state of the 2nd service. @@ -188,13 +232,12 @@ public class AppOpsServiceTest { // Tests that ops are persisted during shutdown. @Test public void testShutdown() { - mAppOpsService.setMode(OP_READ_SMS, mMyUid, mMyPackageName, MODE_ALLOWED); - mAppOpsService.noteOperation(OP_READ_SMS, mMyUid, mMyPackageName); + mAppOpsService.setMode(OP_READ_SMS, mMyUid, sMyPackageName, MODE_ALLOWED); + mAppOpsService.noteOperation(OP_READ_SMS, mMyUid, sMyPackageName); mAppOpsService.shutdown(); // Create a new app ops service, and initialize its state from XML. - mAppOpsService = new AppOpsService(mAppOpsFile, mHandler); - mAppOpsService.mContext = mContext; + setupAppOpsService(); mAppOpsService.readState(); // Query the state of the 2nd service. @@ -204,21 +247,21 @@ public class AppOpsServiceTest { @Test public void testGetOpsForPackage() { - mAppOpsService.setMode(OP_READ_SMS, mMyUid, mMyPackageName, MODE_ALLOWED); - mAppOpsService.noteOperation(OP_READ_SMS, mMyUid, mMyPackageName); + mAppOpsService.setMode(OP_READ_SMS, mMyUid, sMyPackageName, MODE_ALLOWED); + mAppOpsService.noteOperation(OP_READ_SMS, mMyUid, sMyPackageName); // Query all ops List<PackageOps> loggedOps = mAppOpsService.getOpsForPackage( - mMyUid, mMyPackageName, null /* all ops */); + mMyUid, sMyPackageName, null /* all ops */); assertContainsOp(loggedOps, OP_READ_SMS, mTestStartMillis, -1, MODE_ALLOWED); // Query specific ops loggedOps = mAppOpsService.getOpsForPackage( - mMyUid, mMyPackageName, new int[]{OP_READ_SMS, OP_WRITE_SMS}); + mMyUid, sMyPackageName, new int[]{OP_READ_SMS, OP_WRITE_SMS}); assertContainsOp(loggedOps, OP_READ_SMS, mTestStartMillis, -1, MODE_ALLOWED); // Query unknown UID - loggedOps = mAppOpsService.getOpsForPackage(mMyUid + 1, mMyPackageName, null /* all ops */); + loggedOps = mAppOpsService.getOpsForPackage(mMyUid + 1, sMyPackageName, null /* all ops */); assertThat(loggedOps).isNull(); // Query unknown package name @@ -226,31 +269,31 @@ public class AppOpsServiceTest { assertThat(loggedOps).isNull(); // Query op code that's not been logged - loggedOps = mAppOpsService.getOpsForPackage(mMyUid, mMyPackageName, + loggedOps = mAppOpsService.getOpsForPackage(mMyUid, sMyPackageName, new int[]{OP_WRITE_SMS}); assertThat(loggedOps).isNull(); } @Test public void testPackageRemoved() { - mAppOpsService.setMode(OP_READ_SMS, mMyUid, mMyPackageName, MODE_ALLOWED); - mAppOpsService.noteOperation(OP_READ_SMS, mMyUid, mMyPackageName); + mAppOpsService.setMode(OP_READ_SMS, mMyUid, sMyPackageName, MODE_ALLOWED); + mAppOpsService.noteOperation(OP_READ_SMS, mMyUid, sMyPackageName); List<PackageOps> loggedOps = getLoggedOps(); assertContainsOp(loggedOps, OP_READ_SMS, mTestStartMillis, -1, MODE_ALLOWED); - mAppOpsService.packageRemoved(mMyUid, mMyPackageName); + mAppOpsService.packageRemoved(mMyUid, sMyPackageName); assertThat(getLoggedOps()).isNull(); } @Ignore("Historical appops are disabled in Android Q") @Test public void testPackageRemovedHistoricalOps() throws InterruptedException { - mAppOpsService.setMode(OP_READ_SMS, mMyUid, mMyPackageName, MODE_ALLOWED); - mAppOpsService.noteOperation(OP_READ_SMS, mMyUid, mMyPackageName); + mAppOpsService.setMode(OP_READ_SMS, mMyUid, sMyPackageName, MODE_ALLOWED); + mAppOpsService.noteOperation(OP_READ_SMS, mMyUid, sMyPackageName); AppOpsManager.HistoricalOps historicalOps = new AppOpsManager.HistoricalOps(0, 15000); - historicalOps.increaseAccessCount(OP_READ_SMS, mMyUid, mMyPackageName, + historicalOps.increaseAccessCount(OP_READ_SMS, mMyUid, sMyPackageName, AppOpsManager.UID_STATE_PERSISTENT, 0, 1); mAppOpsService.addHistoricalOps(historicalOps); @@ -263,7 +306,7 @@ public class AppOpsServiceTest { }); // First, do a fetch to ensure it's written - mAppOpsService.getHistoricalOps(mMyUid, mMyPackageName, null, 0, Long.MAX_VALUE, 0, + mAppOpsService.getHistoricalOps(mMyUid, sMyPackageName, null, 0, Long.MAX_VALUE, 0, callback); latchRef.get().await(5, TimeUnit.SECONDS); @@ -271,11 +314,11 @@ public class AppOpsServiceTest { assertThat(resultOpsRef.get().isEmpty()).isFalse(); // Then, check it's deleted on removal - mAppOpsService.packageRemoved(mMyUid, mMyPackageName); + mAppOpsService.packageRemoved(mMyUid, sMyPackageName); latchRef.set(new CountDownLatch(1)); - mAppOpsService.getHistoricalOps(mMyUid, mMyPackageName, null, 0, Long.MAX_VALUE, 0, + mAppOpsService.getHistoricalOps(mMyUid, sMyPackageName, null, 0, Long.MAX_VALUE, 0, callback); latchRef.get().await(5, TimeUnit.SECONDS); @@ -285,8 +328,8 @@ public class AppOpsServiceTest { @Test public void testUidRemoved() { - mAppOpsService.setMode(OP_READ_SMS, mMyUid, mMyPackageName, MODE_ALLOWED); - mAppOpsService.noteOperation(OP_READ_SMS, mMyUid, mMyPackageName); + mAppOpsService.setMode(OP_READ_SMS, mMyUid, sMyPackageName, MODE_ALLOWED); + mAppOpsService.noteOperation(OP_READ_SMS, mMyUid, sMyPackageName); List<PackageOps> loggedOps = getLoggedOps(); assertContainsOp(loggedOps, OP_READ_SMS, mTestStartMillis, -1, MODE_ALLOWED); @@ -297,7 +340,7 @@ public class AppOpsServiceTest { private void setupProcStateTests() { // For the location proc state tests - mAppOpsService.setMode(OP_COARSE_LOCATION, mMyUid, mMyPackageName, MODE_FOREGROUND); + mAppOpsService.setMode(OP_COARSE_LOCATION, mMyUid, sMyPackageName, MODE_FOREGROUND); mAppOpsService.mConstants.FG_SERVICE_STATE_SETTLE_TIME = 0; mAppOpsService.mConstants.TOP_STATE_SETTLE_TIME = 0; mAppOpsService.mConstants.BG_STATE_SETTLE_TIME = 0; @@ -308,18 +351,18 @@ public class AppOpsServiceTest { setupProcStateTests(); mAppOpsService.updateUidProcState(mMyUid, ActivityManager.PROCESS_STATE_CACHED_EMPTY); - assertThat(mAppOpsService.noteOperation(OP_COARSE_LOCATION, mMyUid, mMyPackageName)) + assertThat(mAppOpsService.noteOperation(OP_COARSE_LOCATION, mMyUid, sMyPackageName)) .isNotEqualTo(MODE_ALLOWED); mAppOpsService.updateUidProcState(mMyUid, ActivityManager.PROCESS_STATE_TOP); - assertThat(mAppOpsService.noteOperation(OP_COARSE_LOCATION, mMyUid, mMyPackageName)) + assertThat(mAppOpsService.noteOperation(OP_COARSE_LOCATION, mMyUid, sMyPackageName)) .isEqualTo(MODE_ALLOWED); mAppOpsService.updateUidProcState(mMyUid, ActivityManager.PROCESS_STATE_CACHED_EMPTY); // Second time to make sure that settle time is overcome Thread.sleep(50); mAppOpsService.updateUidProcState(mMyUid, ActivityManager.PROCESS_STATE_CACHED_EMPTY); - assertThat(mAppOpsService.noteOperation(OP_COARSE_LOCATION, mMyUid, mMyPackageName)) + assertThat(mAppOpsService.noteOperation(OP_COARSE_LOCATION, mMyUid, sMyPackageName)) .isNotEqualTo(MODE_ALLOWED); } @@ -328,11 +371,11 @@ public class AppOpsServiceTest { setupProcStateTests(); mAppOpsService.updateUidProcState(mMyUid, ActivityManager.PROCESS_STATE_CACHED_EMPTY); - assertThat(mAppOpsService.noteOperation(OP_COARSE_LOCATION, mMyUid, mMyPackageName)) + assertThat(mAppOpsService.noteOperation(OP_COARSE_LOCATION, mMyUid, sMyPackageName)) .isNotEqualTo(MODE_ALLOWED); mAppOpsService.updateUidProcState(mMyUid, PROCESS_STATE_FOREGROUND_SERVICE); - assertThat(mAppOpsService.noteOperation(OP_COARSE_LOCATION, mMyUid, mMyPackageName)) + assertThat(mAppOpsService.noteOperation(OP_COARSE_LOCATION, mMyUid, sMyPackageName)) .isNotEqualTo(MODE_ALLOWED); } @@ -341,12 +384,12 @@ public class AppOpsServiceTest { setupProcStateTests(); mAppOpsService.updateUidProcState(mMyUid, ActivityManager.PROCESS_STATE_CACHED_EMPTY); - assertThat(mAppOpsService.noteOperation(OP_COARSE_LOCATION, mMyUid, mMyPackageName)) + assertThat(mAppOpsService.noteOperation(OP_COARSE_LOCATION, mMyUid, sMyPackageName)) .isNotEqualTo(MODE_ALLOWED); mAppOpsService.updateUidProcState(mMyUid, PROCESS_STATE_FOREGROUND_SERVICE_LOCATION); - assertThat(mAppOpsService.noteOperation(OP_COARSE_LOCATION, mMyUid, mMyPackageName)) + assertThat(mAppOpsService.noteOperation(OP_COARSE_LOCATION, mMyUid, sMyPackageName)) .isEqualTo(MODE_ALLOWED); } @@ -355,18 +398,18 @@ public class AppOpsServiceTest { setupProcStateTests(); mAppOpsService.updateUidProcState(mMyUid, ActivityManager.PROCESS_STATE_CACHED_EMPTY); - assertThat(mAppOpsService.noteOperation(OP_COARSE_LOCATION, mMyUid, mMyPackageName)) + assertThat(mAppOpsService.noteOperation(OP_COARSE_LOCATION, mMyUid, sMyPackageName)) .isNotEqualTo(MODE_ALLOWED); mAppOpsService.updateUidProcState(mMyUid, ActivityManager.PROCESS_STATE_TOP); - assertThat(mAppOpsService.noteOperation(OP_COARSE_LOCATION, mMyUid, mMyPackageName)) + assertThat(mAppOpsService.noteOperation(OP_COARSE_LOCATION, mMyUid, sMyPackageName)) .isEqualTo(MODE_ALLOWED); mAppOpsService.updateUidProcState(mMyUid, PROCESS_STATE_FOREGROUND_SERVICE); // Second time to make sure that settle time is overcome Thread.sleep(50); mAppOpsService.updateUidProcState(mMyUid, PROCESS_STATE_FOREGROUND_SERVICE); - assertThat(mAppOpsService.noteOperation(OP_COARSE_LOCATION, mMyUid, mMyPackageName)) + assertThat(mAppOpsService.noteOperation(OP_COARSE_LOCATION, mMyUid, sMyPackageName)) .isNotEqualTo(MODE_ALLOWED); } @@ -375,30 +418,30 @@ public class AppOpsServiceTest { setupProcStateTests(); mAppOpsService.updateUidProcState(mMyUid, ActivityManager.PROCESS_STATE_CACHED_EMPTY); - assertThat(mAppOpsService.noteOperation(OP_COARSE_LOCATION, mMyUid, mMyPackageName)) + assertThat(mAppOpsService.noteOperation(OP_COARSE_LOCATION, mMyUid, sMyPackageName)) .isNotEqualTo(MODE_ALLOWED); mAppOpsService.updateUidProcState(mMyUid, ActivityManager.PROCESS_STATE_TOP); - assertThat(mAppOpsService.noteOperation(OP_COARSE_LOCATION, mMyUid, mMyPackageName)) + assertThat(mAppOpsService.noteOperation(OP_COARSE_LOCATION, mMyUid, sMyPackageName)) .isEqualTo(MODE_ALLOWED); mAppOpsService.updateUidProcState(mMyUid, PROCESS_STATE_FOREGROUND_SERVICE_LOCATION); // Second time to make sure that settle time is overcome Thread.sleep(50); mAppOpsService.updateUidProcState(mMyUid, PROCESS_STATE_FOREGROUND_SERVICE_LOCATION); - assertThat(mAppOpsService.noteOperation(OP_COARSE_LOCATION, mMyUid, mMyPackageName)) + assertThat(mAppOpsService.noteOperation(OP_COARSE_LOCATION, mMyUid, sMyPackageName)) .isEqualTo(MODE_ALLOWED); mAppOpsService.updateUidProcState(mMyUid, PROCESS_STATE_FOREGROUND_SERVICE); // Second time to make sure that settle time is overcome Thread.sleep(50); mAppOpsService.updateUidProcState(mMyUid, PROCESS_STATE_FOREGROUND_SERVICE); - assertThat(mAppOpsService.noteOperation(OP_COARSE_LOCATION, mMyUid, mMyPackageName)) + assertThat(mAppOpsService.noteOperation(OP_COARSE_LOCATION, mMyUid, sMyPackageName)) .isNotEqualTo(MODE_ALLOWED); } private List<PackageOps> getLoggedOps() { - return mAppOpsService.getOpsForPackage(mMyUid, mMyPackageName, null /* all ops */); + return mAppOpsService.getOpsForPackage(mMyUid, sMyPackageName, null /* all ops */); } private void assertContainsOp(List<PackageOps> loggedOps, int opCode, long minMillis, @@ -407,7 +450,7 @@ public class AppOpsServiceTest { boolean opLogged = false; for (PackageOps pkgOps : loggedOps) { assertWithMessage("Unexpected UID").that(mMyUid).isEqualTo(pkgOps.getUid()); - assertWithMessage("Unexpected package name").that(mMyPackageName).isEqualTo( + assertWithMessage("Unexpected package name").that(sMyPackageName).isEqualTo( pkgOps.getPackageName()); for (OpEntry opEntry : pkgOps.getOps()) { diff --git a/services/tests/mockingservicestests/src/com/android/server/job/controllers/TimeControllerTest.java b/services/tests/mockingservicestests/src/com/android/server/job/controllers/TimeControllerTest.java index 19369dbe5f44..6c29f6050276 100644 --- a/services/tests/mockingservicestests/src/com/android/server/job/controllers/TimeControllerTest.java +++ b/services/tests/mockingservicestests/src/com/android/server/job/controllers/TimeControllerTest.java @@ -530,6 +530,46 @@ public class TimeControllerTest { } @Test + public void testJobDelayWakeupAlarmToggling() { + final long now = JobSchedulerService.sElapsedRealtimeClock.millis(); + + JobStatus job = createJobStatus( + "testMaybeStartTrackingJobLocked_DeadlineReverseOrder", + createJob().setMinimumLatency(HOUR_IN_MILLIS)); + + doReturn(true).when(mTimeController) + .wouldBeReadyWithConstraintLocked(eq(job), anyInt()); + + // Starting off with using a wakeup alarm. + mConstants.USE_NON_WAKEUP_ALARM_FOR_DELAY = false; + InOrder inOrder = inOrder(mAlarmManager); + + mTimeController.maybeStartTrackingJobLocked(job, null); + inOrder.verify(mAlarmManager, times(1)) + .set(eq(AlarmManager.ELAPSED_REALTIME_WAKEUP), eq(now + HOUR_IN_MILLIS), anyLong(), + anyLong(), + eq(TAG_DELAY), any(), any(), any()); + + // Use a non wakeup alarm. + mConstants.USE_NON_WAKEUP_ALARM_FOR_DELAY = true; + + mTimeController.maybeStartTrackingJobLocked(job, null); + inOrder.verify(mAlarmManager, times(1)) + .set(eq(AlarmManager.ELAPSED_REALTIME), eq(now + HOUR_IN_MILLIS), anyLong(), + anyLong(), eq(TAG_DELAY), + any(), any(), any()); + + // Back off, use a wakeup alarm. + mConstants.USE_NON_WAKEUP_ALARM_FOR_DELAY = false; + + mTimeController.maybeStartTrackingJobLocked(job, null); + inOrder.verify(mAlarmManager, times(1)) + .set(eq(AlarmManager.ELAPSED_REALTIME_WAKEUP), eq(now + HOUR_IN_MILLIS), anyLong(), + anyLong(), + eq(TAG_DELAY), any(), any(), any()); + } + + @Test public void testCheckExpiredDelaysAndResetAlarm_WithSkipping_AllReady() { mConstants.SKIP_NOT_READY_JOBS = true; mTimeController.recheckAlarmsLocked(); diff --git a/services/tests/servicestests/src/com/android/server/DynamicSystemServiceTest.java b/services/tests/servicestests/src/com/android/server/DynamicSystemServiceTest.java index 50437b4d5f3e..d367f71de921 100644 --- a/services/tests/servicestests/src/com/android/server/DynamicSystemServiceTest.java +++ b/services/tests/servicestests/src/com/android/server/DynamicSystemServiceTest.java @@ -36,7 +36,7 @@ public class DynamicSystemServiceTest extends AndroidTestCase { public void test1() { assertTrue("dynamic_system service available", mService != null); try { - mService.startInstallation(); + mService.startInstallation("dsu"); fail("DynamicSystemService did not throw SecurityException as expected"); } catch (SecurityException e) { // expected diff --git a/services/tests/servicestests/src/com/android/server/NetworkScoreServiceTest.java b/services/tests/servicestests/src/com/android/server/NetworkScoreServiceTest.java index 8fd8d0461e75..ca5dfb133345 100644 --- a/services/tests/servicestests/src/com/android/server/NetworkScoreServiceTest.java +++ b/services/tests/servicestests/src/com/android/server/NetworkScoreServiceTest.java @@ -16,7 +16,7 @@ package com.android.server; -import static android.net.NetworkScoreManager.CACHE_FILTER_NONE; +import static android.net.NetworkScoreManager.SCORE_FILTER_NONE; import static junit.framework.Assert.assertEquals; import static junit.framework.Assert.assertFalse; @@ -29,6 +29,7 @@ import static org.mockito.Matchers.anyString; import static org.mockito.Matchers.eq; import static org.mockito.Mockito.atLeastOnce; import static org.mockito.Mockito.doThrow; +import static org.mockito.Mockito.mock; import static org.mockito.Mockito.never; import static org.mockito.Mockito.timeout; import static org.mockito.Mockito.times; @@ -57,7 +58,6 @@ import android.net.wifi.ScanResult; import android.net.wifi.WifiConfiguration; import android.net.wifi.WifiInfo; import android.net.wifi.WifiManager; -import android.net.wifi.WifiSsid; import android.os.Binder; import android.os.Handler; import android.os.HandlerThread; @@ -180,8 +180,8 @@ public class NetworkScoreServiceTest { } private ScanResult createScanResult(String ssid, String bssid) { - ScanResult result = new ScanResult(); - result.wifiSsid = WifiSsid.createFromAsciiEncoded(ssid); + ScanResult result = mock(ScanResult.class); + result.SSID = ssid; result.BSSID = bssid; return result; } @@ -304,7 +304,7 @@ public class NetworkScoreServiceTest { bindToScorer(true /*callerIsScorer*/); mNetworkScoreService.registerNetworkScoreCache(NetworkKey.TYPE_WIFI, - mNetworkScoreCache, CACHE_FILTER_NONE); + mNetworkScoreCache, SCORE_FILTER_NONE); mNetworkScoreService.updateScores(new ScoredNetwork[]{SCORED_NETWORK}); @@ -319,9 +319,9 @@ public class NetworkScoreServiceTest { bindToScorer(true /*callerIsScorer*/); mNetworkScoreService.registerNetworkScoreCache(NetworkKey.TYPE_WIFI, - mNetworkScoreCache, CACHE_FILTER_NONE); + mNetworkScoreCache, SCORE_FILTER_NONE); mNetworkScoreService.registerNetworkScoreCache( - NetworkKey.TYPE_WIFI, mNetworkScoreCache2, CACHE_FILTER_NONE); + NetworkKey.TYPE_WIFI, mNetworkScoreCache2, SCORE_FILTER_NONE); // updateScores should update both caches mNetworkScoreService.updateScores(new ScoredNetwork[]{SCORED_NETWORK}); @@ -376,7 +376,7 @@ public class NetworkScoreServiceTest { bindToScorer(true /*callerIsScorer*/); mNetworkScoreService.registerNetworkScoreCache(NetworkKey.TYPE_WIFI, mNetworkScoreCache, - CACHE_FILTER_NONE); + SCORE_FILTER_NONE); mNetworkScoreService.clearScores(); verify(mNetworkScoreCache).clearScores(); @@ -390,7 +390,7 @@ public class NetworkScoreServiceTest { .thenReturn(PackageManager.PERMISSION_GRANTED); mNetworkScoreService.registerNetworkScoreCache(NetworkKey.TYPE_WIFI, mNetworkScoreCache, - CACHE_FILTER_NONE); + SCORE_FILTER_NONE); mNetworkScoreService.clearScores(); verify(mNetworkScoreCache).clearScores(); @@ -470,7 +470,7 @@ public class NetworkScoreServiceTest { try { mNetworkScoreService.registerNetworkScoreCache( - NetworkKey.TYPE_WIFI, mNetworkScoreCache, CACHE_FILTER_NONE); + NetworkKey.TYPE_WIFI, mNetworkScoreCache, SCORE_FILTER_NONE); fail("SecurityException expected"); } catch (SecurityException e) { // expected @@ -613,7 +613,7 @@ public class NetworkScoreServiceTest { new ArrayList<>(scoredNetworkList), NetworkKey.TYPE_WIFI, mCurrentNetworkFilter, mScanResultsFilter); - consumer.accept(mNetworkScoreCache, NetworkScoreManager.CACHE_FILTER_NONE); + consumer.accept(mNetworkScoreCache, NetworkScoreManager.SCORE_FILTER_NONE); verify(mNetworkScoreCache).updateScores(scoredNetworkList); verifyZeroInteractions(mCurrentNetworkFilter, mScanResultsFilter); @@ -654,7 +654,7 @@ public class NetworkScoreServiceTest { Collections.emptyList(), NetworkKey.TYPE_WIFI, mCurrentNetworkFilter, mScanResultsFilter); - consumer.accept(mNetworkScoreCache, NetworkScoreManager.CACHE_FILTER_NONE); + consumer.accept(mNetworkScoreCache, NetworkScoreManager.SCORE_FILTER_NONE); verifyZeroInteractions(mNetworkScoreCache, mCurrentNetworkFilter, mScanResultsFilter); } @@ -671,7 +671,7 @@ public class NetworkScoreServiceTest { List<ScoredNetwork> filteredList = new ArrayList<>(scoredNetworkList); filteredList.remove(SCORED_NETWORK); when(mCurrentNetworkFilter.apply(scoredNetworkList)).thenReturn(filteredList); - consumer.accept(mNetworkScoreCache, NetworkScoreManager.CACHE_FILTER_CURRENT_NETWORK); + consumer.accept(mNetworkScoreCache, NetworkScoreManager.SCORE_FILTER_CURRENT_NETWORK); verify(mNetworkScoreCache).updateScores(filteredList); verifyZeroInteractions(mScanResultsFilter); @@ -689,7 +689,7 @@ public class NetworkScoreServiceTest { List<ScoredNetwork> filteredList = new ArrayList<>(scoredNetworkList); filteredList.remove(SCORED_NETWORK); when(mScanResultsFilter.apply(scoredNetworkList)).thenReturn(filteredList); - consumer.accept(mNetworkScoreCache, NetworkScoreManager.CACHE_FILTER_SCAN_RESULTS); + consumer.accept(mNetworkScoreCache, NetworkScoreManager.SCORE_FILTER_SCAN_RESULTS); verify(mNetworkScoreCache).updateScores(filteredList); verifyZeroInteractions(mCurrentNetworkFilter); @@ -792,7 +792,7 @@ public class NetworkScoreServiceTest { @Test public void testScanResultsScoreCacheFilter_invalidScanResults() throws Exception { List<ScanResult> invalidScanResults = Lists.newArrayList( - new ScanResult(), + mock(ScanResult.class), createScanResult("", SCORED_NETWORK.networkKey.wifiKey.bssid), createScanResult(WifiManager.UNKNOWN_SSID, SCORED_NETWORK.networkKey.wifiKey.bssid), createScanResult(SSID, null), diff --git a/services/tests/servicestests/src/com/android/server/appwidget/AppWidgetServiceImplTest.java b/services/tests/servicestests/src/com/android/server/appwidget/AppWidgetServiceImplTest.java index f3c76b609c25..8871348d0027 100644 --- a/services/tests/servicestests/src/com/android/server/appwidget/AppWidgetServiceImplTest.java +++ b/services/tests/servicestests/src/com/android/server/appwidget/AppWidgetServiceImplTest.java @@ -28,6 +28,7 @@ import static org.mockito.Mockito.when; import android.app.admin.DevicePolicyManagerInternal; import android.appwidget.AppWidgetManager; +import android.appwidget.AppWidgetManagerInternal; import android.appwidget.AppWidgetProviderInfo; import android.appwidget.PendingHostUpdate; import android.content.BroadcastReceiver; @@ -80,6 +81,7 @@ public class AppWidgetServiceImplTest extends InstrumentationTestCase { super.setUp(); LocalServices.removeServiceForTest(DevicePolicyManagerInternal.class); LocalServices.removeServiceForTest(ShortcutServiceInternal.class); + LocalServices.removeServiceForTest(AppWidgetManagerInternal.class); mTestContext = new TestContext(); mPkgName = mTestContext.getOpPackageName(); diff --git a/services/tests/servicestests/src/com/android/server/compat/ApplicationInfoBuilder.java b/services/tests/servicestests/src/com/android/server/compat/ApplicationInfoBuilder.java new file mode 100644 index 000000000000..d0767ccb6f87 --- /dev/null +++ b/services/tests/servicestests/src/com/android/server/compat/ApplicationInfoBuilder.java @@ -0,0 +1,58 @@ +/* + * 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.compat; + +import android.content.pm.ApplicationInfo; + +class ApplicationInfoBuilder { + private boolean mIsDebuggable; + private int mTargetSdk; + private String mPackageName; + + private ApplicationInfoBuilder() { + mTargetSdk = -1; + } + + static ApplicationInfoBuilder create() { + return new ApplicationInfoBuilder(); + } + + ApplicationInfoBuilder withTargetSdk(int targetSdk) { + mTargetSdk = targetSdk; + return this; + } + + ApplicationInfoBuilder debuggable() { + mIsDebuggable = true; + return this; + } + + ApplicationInfoBuilder withPackageName(String packageName) { + mPackageName = packageName; + return this; + } + + ApplicationInfo build() { + final ApplicationInfo applicationInfo = new ApplicationInfo(); + if (mIsDebuggable) { + applicationInfo.flags |= ApplicationInfo.FLAG_DEBUGGABLE; + } + applicationInfo.packageName = mPackageName; + applicationInfo.targetSdkVersion = mTargetSdk; + return applicationInfo; + } +} diff --git a/services/tests/servicestests/src/com/android/server/compat/CompatConfigBuilder.java b/services/tests/servicestests/src/com/android/server/compat/CompatConfigBuilder.java new file mode 100644 index 000000000000..328c71dbc7db --- /dev/null +++ b/services/tests/servicestests/src/com/android/server/compat/CompatConfigBuilder.java @@ -0,0 +1,99 @@ +/* + * 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.compat; + +import android.content.Context; + +import com.android.internal.compat.AndroidBuildClassifier; + +import java.util.ArrayList; + +/** + * Helper class for creating a CompatConfig. + */ +class CompatConfigBuilder { + private ArrayList<CompatChange> mChanges; + private AndroidBuildClassifier mBuildClassifier; + private Context mContext; + + private CompatConfigBuilder(AndroidBuildClassifier buildClassifier, Context context) { + mChanges = new ArrayList<>(); + mBuildClassifier = buildClassifier; + mContext = context; + } + + static CompatConfigBuilder create(AndroidBuildClassifier buildClassifier, Context context) { + return new CompatConfigBuilder(buildClassifier, context); + } + + CompatConfigBuilder addTargetSdkChangeWithId(int sdk, long id) { + mChanges.add(new CompatChange(id, "", sdk, false, "")); + return this; + } + + CompatConfigBuilder addTargetSdkDisabledChangeWithId(int sdk, long id) { + mChanges.add(new CompatChange(id, "", sdk, true, "")); + return this; + } + + CompatConfigBuilder addTargetSdkChangeWithIdAndName(int sdk, long id, String name) { + mChanges.add(new CompatChange(id, name, sdk, false, "")); + return this; + } + + CompatConfigBuilder addTargetSdkChangeWithIdAndDescription(int sdk, long id, + String description) { + mChanges.add(new CompatChange(id, "", sdk, false, description)); + return this; + } + + CompatConfigBuilder addEnabledChangeWithId(long id) { + mChanges.add(new CompatChange(id, "", -1, false, "")); + return this; + } + + CompatConfigBuilder addEnabledChangeWithIdAndName(long id, String name) { + mChanges.add(new CompatChange(id, name, -1, false, "")); + return this; + } + CompatConfigBuilder addEnabledChangeWithIdAndDescription(long id, String description) { + mChanges.add(new CompatChange(id, "", -1, false, description)); + return this; + } + + CompatConfigBuilder addDisabledChangeWithId(long id) { + mChanges.add(new CompatChange(id, "", -1, true, "")); + return this; + } + + CompatConfigBuilder addDisabledChangeWithIdAndName(long id, String name) { + mChanges.add(new CompatChange(id, name, -1, true, "")); + return this; + } + + CompatConfigBuilder addDisabledChangeWithIdAndDescription(long id, String description) { + mChanges.add(new CompatChange(id, "", -1, true, description)); + return this; + } + + CompatConfig build() { + CompatConfig config = new CompatConfig(mBuildClassifier, mContext); + for (CompatChange change : mChanges) { + config.addChange(change); + } + return config; + } +} diff --git a/services/tests/servicestests/src/com/android/server/compat/CompatConfigTest.java b/services/tests/servicestests/src/com/android/server/compat/CompatConfigTest.java index cb99c118a407..407f67e2fd8e 100644 --- a/services/tests/servicestests/src/com/android/server/compat/CompatConfigTest.java +++ b/services/tests/servicestests/src/com/android/server/compat/CompatConfigTest.java @@ -18,12 +18,25 @@ package com.android.server.compat; import static com.google.common.truth.Truth.assertThat; +import static org.mockito.Mockito.anyInt; +import static org.mockito.Mockito.eq; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; +import static org.testng.Assert.assertThrows; + +import android.content.Context; import android.content.pm.ApplicationInfo; +import android.content.pm.PackageManager; import androidx.test.runner.AndroidJUnit4; +import com.android.internal.compat.AndroidBuildClassifier; + +import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; import java.io.File; import java.io.FileOutputStream; @@ -34,12 +47,12 @@ import java.util.UUID; @RunWith(AndroidJUnit4.class) public class CompatConfigTest { - private ApplicationInfo makeAppInfo(String pName, int targetSdkVersion) { - ApplicationInfo ai = new ApplicationInfo(); - ai.packageName = pName; - ai.targetSdkVersion = targetSdkVersion; - return ai; - } + @Mock + private Context mContext; + @Mock + PackageManager mPackageManager; + @Mock + private AndroidBuildClassifier mBuildClassifier; private File createTempDir() { String base = System.getProperty("java.io.tmpdir"); @@ -54,112 +67,206 @@ public class CompatConfigTest { os.close(); } + @Before + public void setUp() throws Exception { + MockitoAnnotations.initMocks(this); + when(mContext.getPackageManager()).thenReturn(mPackageManager); + // Assume userdebug/eng non-final build + when(mBuildClassifier.isDebuggableBuild()).thenReturn(true); + when(mBuildClassifier.isFinalBuild()).thenReturn(false); + } + + @Test + public void testUnknownChangeEnabled() throws Exception { + CompatConfig compatConfig = new CompatConfig(mBuildClassifier, mContext); + assertThat(compatConfig.isChangeEnabled(1234L, ApplicationInfoBuilder.create().build())) + .isTrue(); + } + @Test - public void testUnknownChangeEnabled() { - CompatConfig pc = new CompatConfig(); - assertThat(pc.isChangeEnabled(1234L, makeAppInfo("com.some.package", 1))).isTrue(); + public void testDisabledChangeDisabled() throws Exception { + CompatConfig compatConfig = CompatConfigBuilder.create(mBuildClassifier, mContext) + .addDisabledChangeWithId(1234L) + .build(); + + assertThat(compatConfig.isChangeEnabled(1234L, ApplicationInfoBuilder.create().build())) + .isFalse(); } @Test - public void testDisabledChangeDisabled() { - CompatConfig pc = new CompatConfig(); - pc.addChange(new CompatChange(1234L, "MY_CHANGE", -1, true, "")); - assertThat(pc.isChangeEnabled(1234L, makeAppInfo("com.some.package", 1))).isFalse(); + public void testTargetSdkChangeDisabled() throws Exception { + CompatConfig compatConfig = CompatConfigBuilder.create(mBuildClassifier, mContext) + .addTargetSdkChangeWithId(2, 1234L) + .build(); + + assertThat(compatConfig.isChangeEnabled(1234L, + ApplicationInfoBuilder.create().withTargetSdk(2).build())) + .isFalse(); } @Test - public void testTargetSdkChangeDisabled() { - CompatConfig pc = new CompatConfig(); - pc.addChange(new CompatChange(1234L, "MY_CHANGE", 2, false, null)); - assertThat(pc.isChangeEnabled(1234L, makeAppInfo("com.some.package", 2))).isFalse(); + public void testTargetSdkChangeEnabled() throws Exception { + CompatConfig compatConfig = CompatConfigBuilder.create(mBuildClassifier, mContext) + .addTargetSdkChangeWithId(2, 1234L) + .build(); + + assertThat(compatConfig.isChangeEnabled(1234L, + ApplicationInfoBuilder.create().withTargetSdk(3).build())).isTrue(); } @Test - public void testTargetSdkChangeEnabled() { - CompatConfig pc = new CompatConfig(); - pc.addChange(new CompatChange(1234L, "MY_CHANGE", 2, false, "")); - assertThat(pc.isChangeEnabled(1234L, makeAppInfo("com.some.package", 3))).isTrue(); + public void testDisabledOverrideTargetSdkChange() throws Exception { + CompatConfig compatConfig = CompatConfigBuilder.create(mBuildClassifier, mContext) + .addTargetSdkDisabledChangeWithId(2, 1234L) + .build(); + + assertThat(compatConfig.isChangeEnabled(1234L, + ApplicationInfoBuilder.create().withTargetSdk(3).build())).isFalse(); } @Test - public void testDisabledOverrideTargetSdkChange() { - CompatConfig pc = new CompatConfig(); - pc.addChange(new CompatChange(1234L, "MY_CHANGE", 2, true, null)); - assertThat(pc.isChangeEnabled(1234L, makeAppInfo("com.some.package", 3))).isFalse(); + public void testGetDisabledChanges() throws Exception { + CompatConfig compatConfig = CompatConfigBuilder.create(mBuildClassifier, mContext) + .addDisabledChangeWithId(1234L) + .addEnabledChangeWithId(2345L) + .build(); + + assertThat(compatConfig.getDisabledChanges( + ApplicationInfoBuilder.create().build())).asList().containsExactly(1234L); } @Test - public void testGetDisabledChanges() { - CompatConfig pc = new CompatConfig(); - pc.addChange(new CompatChange(1234L, "MY_CHANGE", -1, true, null)); - pc.addChange(new CompatChange(2345L, "OTHER_CHANGE", -1, false, null)); - assertThat(pc.getDisabledChanges( - makeAppInfo("com.some.package", 2))).asList().containsExactly(1234L); + public void testGetDisabledChangesSorted() throws Exception { + CompatConfig compatConfig = CompatConfigBuilder.create(mBuildClassifier, mContext) + .addDisabledChangeWithId(1234L) + .addDisabledChangeWithId(123L) + .addDisabledChangeWithId(12L) + .build(); + + assertThat(compatConfig.getDisabledChanges(ApplicationInfoBuilder.create().build())) + .asList().containsExactly(12L, 123L, 1234L); } @Test - public void testGetDisabledChangesSorted() { - CompatConfig pc = new CompatConfig(); - pc.addChange(new CompatChange(1234L, "MY_CHANGE", 2, true, null)); - pc.addChange(new CompatChange(123L, "OTHER_CHANGE", 2, true, null)); - pc.addChange(new CompatChange(12L, "THIRD_CHANGE", 2, true, null)); - assertThat(pc.getDisabledChanges( - makeAppInfo("com.some.package", 2))).asList().containsExactly(12L, 123L, 1234L); + public void testPackageOverrideEnabled() throws Exception { + CompatConfig compatConfig = CompatConfigBuilder.create(mBuildClassifier, mContext) + .addDisabledChangeWithId(1234L) + .build(); + + compatConfig.addOverride(1234L, "com.some.package", true); + + assertThat(compatConfig.isChangeEnabled(1234L, ApplicationInfoBuilder.create() + .withPackageName("com.some.package").build())).isTrue(); + assertThat(compatConfig.isChangeEnabled(1234L, ApplicationInfoBuilder.create() + .withPackageName("com.other.package").build())).isFalse(); } @Test - public void testPackageOverrideEnabled() { - CompatConfig pc = new CompatConfig(); - pc.addChange(new CompatChange(1234L, "MY_CHANGE", -1, true, null)); // disabled - pc.addOverride(1234L, "com.some.package", true); - assertThat(pc.isChangeEnabled(1234L, makeAppInfo("com.some.package", 2))).isTrue(); - assertThat(pc.isChangeEnabled(1234L, makeAppInfo("com.other.package", 2))).isFalse(); + public void testPackageOverrideDisabled() throws Exception { + CompatConfig compatConfig = CompatConfigBuilder.create(mBuildClassifier, mContext) + .addEnabledChangeWithId(1234L) + .build(); + + compatConfig.addOverride(1234L, "com.some.package", false); + + assertThat(compatConfig.isChangeEnabled(1234L, ApplicationInfoBuilder.create() + .withPackageName("com.some.package").build())).isFalse(); + assertThat(compatConfig.isChangeEnabled(1234L, ApplicationInfoBuilder.create() + .withPackageName("com.other.package").build())).isTrue(); } @Test - public void testPackageOverrideDisabled() { - CompatConfig pc = new CompatConfig(); - pc.addChange(new CompatChange(1234L, "MY_CHANGE", -1, false, null)); - pc.addOverride(1234L, "com.some.package", false); - assertThat(pc.isChangeEnabled(1234L, makeAppInfo("com.some.package", 2))).isFalse(); - assertThat(pc.isChangeEnabled(1234L, makeAppInfo("com.other.package", 2))).isTrue(); + public void testPackageOverrideUnknownPackage() throws Exception { + CompatConfig compatConfig = new CompatConfig(mBuildClassifier, mContext); + + compatConfig.addOverride(1234L, "com.some.package", false); + + assertThat(compatConfig.isChangeEnabled(1234L, ApplicationInfoBuilder.create() + .withPackageName("com.some.package").build())).isFalse(); + assertThat(compatConfig.isChangeEnabled(1234L, ApplicationInfoBuilder.create() + .withPackageName("com.other.package").build())).isTrue(); } @Test - public void testPackageOverrideUnknownPackage() { - CompatConfig pc = new CompatConfig(); - pc.addOverride(1234L, "com.some.package", false); - assertThat(pc.isChangeEnabled(1234L, makeAppInfo("com.some.package", 2))).isFalse(); - assertThat(pc.isChangeEnabled(1234L, makeAppInfo("com.other.package", 2))).isTrue(); + public void testPreventAddOverride() throws Exception { + final long changeId = 1234L; + CompatConfig compatConfig = CompatConfigBuilder.create(mBuildClassifier, mContext) + .addDisabledChangeWithId(1234L) + .build(); + ApplicationInfo applicationInfo = ApplicationInfoBuilder.create() + .withPackageName("com.some.package") + .build(); + PackageManager packageManager = mock(PackageManager.class); + when(mContext.getPackageManager()).thenReturn(packageManager); + when(packageManager.getApplicationInfo(eq("com.some.package"), anyInt())) + .thenReturn(applicationInfo); + + // Force the validator to prevent overriding the change by using a user build. + when(mBuildClassifier.isDebuggableBuild()).thenReturn(false); + when(mBuildClassifier.isFinalBuild()).thenReturn(true); + + assertThrows(SecurityException.class, + () -> compatConfig.addOverride(1234L, "com.some.package", true) + ); + assertThat(compatConfig.isChangeEnabled(1234L, applicationInfo)).isFalse(); } @Test - public void testPackageOverrideUnknownChange() { - CompatConfig pc = new CompatConfig(); - assertThat(pc.isChangeEnabled(1234L, makeAppInfo("com.some.package", 1))).isTrue(); + public void testPreventRemoveOverride() throws Exception { + CompatConfig compatConfig = CompatConfigBuilder.create(mBuildClassifier, mContext) + .addDisabledChangeWithId(1234L) + .build(); + ApplicationInfo applicationInfo = ApplicationInfoBuilder.create() + .withPackageName("com.some.package") + .build(); + when(mPackageManager.getApplicationInfo(eq("com.some.package"), anyInt())) + .thenReturn(applicationInfo); + // Assume the override was allowed to be added. + compatConfig.addOverride(1234L, "com.some.package", true); + + // Validator allows turning on the change. + assertThat(compatConfig.isChangeEnabled(1234L, applicationInfo)).isTrue(); + + // Reject all override attempts. + // Force the validator to prevent overriding the change by using a user build. + when(mBuildClassifier.isDebuggableBuild()).thenReturn(false); + when(mBuildClassifier.isFinalBuild()).thenReturn(true); + // Try to turn off change, but validator prevents it. + assertThrows(SecurityException.class, + () -> compatConfig.removeOverride(1234L, "com.some.package")); + assertThat(compatConfig.isChangeEnabled(1234L, applicationInfo)).isTrue(); } @Test - public void testRemovePackageOverride() { - CompatConfig pc = new CompatConfig(); - pc.addChange(new CompatChange(1234L, "MY_CHANGE", -1, false, null)); - pc.addOverride(1234L, "com.some.package", false); - pc.removeOverride(1234L, "com.some.package"); - assertThat(pc.isChangeEnabled(1234L, makeAppInfo("com.some.package", 2))).isTrue(); + public void testRemovePackageOverride() throws Exception { + CompatConfig compatConfig = CompatConfigBuilder.create(mBuildClassifier, mContext) + .addEnabledChangeWithId(1234L) + .build(); + ApplicationInfo applicationInfo = ApplicationInfoBuilder.create() + .withPackageName("com.some.package") + .build(); + + assertThat(compatConfig.addOverride(1234L, "com.some.package", false)).isTrue(); + assertThat(compatConfig.isChangeEnabled(1234L, applicationInfo)).isFalse(); + + compatConfig.removeOverride(1234L, "com.some.package"); + assertThat(compatConfig.isChangeEnabled(1234L, applicationInfo)).isTrue(); } @Test - public void testLookupChangeId() { - CompatConfig pc = new CompatConfig(); - pc.addChange(new CompatChange(1234L, "MY_CHANGE", -1, false, null)); - pc.addChange(new CompatChange(2345L, "ANOTHER_CHANGE", -1, false, null)); - assertThat(pc.lookupChangeId("MY_CHANGE")).isEqualTo(1234L); + public void testLookupChangeId() throws Exception { + CompatConfig compatConfig = CompatConfigBuilder.create(mBuildClassifier, mContext) + .addEnabledChangeWithIdAndName(1234L, "MY_CHANGE") + .addEnabledChangeWithIdAndName(2345L, "MY_OTHER_CHANGE") + .build(); + + assertThat(compatConfig.lookupChangeId("MY_CHANGE")).isEqualTo(1234L); } @Test - public void testLookupChangeIdNotPresent() { - CompatConfig pc = new CompatConfig(); - assertThat(pc.lookupChangeId("MY_CHANGE")).isEqualTo(-1L); + public void testLookupChangeIdNotPresent() throws Exception { + CompatConfig compatConfig = new CompatConfig(mBuildClassifier, mContext); + assertThat(compatConfig.lookupChangeId("MY_CHANGE")).isEqualTo(-1L); } @Test @@ -172,14 +279,17 @@ public class CompatConfigTest { File dir = createTempDir(); writeToFile(dir, "platform_compat_config.xml", configXml); - - CompatConfig pc = new CompatConfig(); - pc.initConfigFromLib(dir); - - assertThat(pc.isChangeEnabled(1234L, makeAppInfo("com.some.package", 1))).isFalse(); - assertThat(pc.isChangeEnabled(1234L, makeAppInfo("com.some.package", 3))).isTrue(); - assertThat(pc.isChangeEnabled(1235L, makeAppInfo("com.some.package", 5))).isFalse(); - assertThat(pc.isChangeEnabled(1236L, makeAppInfo("com.some.package", 1))).isTrue(); + CompatConfig compatConfig = new CompatConfig(mBuildClassifier, mContext); + compatConfig.initConfigFromLib(dir); + + assertThat(compatConfig.isChangeEnabled(1234L, + ApplicationInfoBuilder.create().withTargetSdk(1).build())).isFalse(); + assertThat(compatConfig.isChangeEnabled(1234L, + ApplicationInfoBuilder.create().withTargetSdk(3).build())).isTrue(); + assertThat(compatConfig.isChangeEnabled(1235L, + ApplicationInfoBuilder.create().withTargetSdk(5).build())).isFalse(); + assertThat(compatConfig.isChangeEnabled(1236L, + ApplicationInfoBuilder.create().withTargetSdk(1).build())).isTrue(); } @Test @@ -195,15 +305,16 @@ public class CompatConfigTest { File dir = createTempDir(); writeToFile(dir, "libcore_platform_compat_config.xml", configXml1); writeToFile(dir, "frameworks_platform_compat_config.xml", configXml2); - - CompatConfig pc = new CompatConfig(); - pc.initConfigFromLib(dir); - - assertThat(pc.isChangeEnabled(1234L, makeAppInfo("com.some.package", 1))).isFalse(); - assertThat(pc.isChangeEnabled(1234L, makeAppInfo("com.some.package", 3))).isTrue(); - assertThat(pc.isChangeEnabled(1235L, makeAppInfo("com.some.package", 5))).isFalse(); - assertThat(pc.isChangeEnabled(1236L, makeAppInfo("com.some.package", 1))).isTrue(); + CompatConfig compatConfig = new CompatConfig(mBuildClassifier, mContext); + compatConfig.initConfigFromLib(dir); + + assertThat(compatConfig.isChangeEnabled(1234L, + ApplicationInfoBuilder.create().withTargetSdk(1).build())).isFalse(); + assertThat(compatConfig.isChangeEnabled(1234L, + ApplicationInfoBuilder.create().withTargetSdk(3).build())).isTrue(); + assertThat(compatConfig.isChangeEnabled(1235L, + ApplicationInfoBuilder.create().withTargetSdk(5).build())).isFalse(); + assertThat(compatConfig.isChangeEnabled(1236L, + ApplicationInfoBuilder.create().withTargetSdk(1).build())).isTrue(); } } - - diff --git a/services/tests/servicestests/src/com/android/server/compat/CompatibilityChangeConfigBuilder.java b/services/tests/servicestests/src/com/android/server/compat/CompatibilityChangeConfigBuilder.java new file mode 100644 index 000000000000..793296e88169 --- /dev/null +++ b/services/tests/servicestests/src/com/android/server/compat/CompatibilityChangeConfigBuilder.java @@ -0,0 +1,52 @@ +/* + * 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.compat; + +import android.compat.Compatibility; + +import com.android.internal.compat.CompatibilityChangeConfig; + +import java.util.HashSet; +import java.util.Set; + +class CompatibilityChangeConfigBuilder { + private Set<Long> mEnabled; + private Set<Long> mDisabled; + + private CompatibilityChangeConfigBuilder() { + mEnabled = new HashSet<>(); + mDisabled = new HashSet<>(); + } + + static CompatibilityChangeConfigBuilder create() { + return new CompatibilityChangeConfigBuilder(); + } + + CompatibilityChangeConfigBuilder enable(Long id) { + mEnabled.add(id); + return this; + } + + CompatibilityChangeConfigBuilder disable(Long id) { + mDisabled.add(id); + return this; + } + + CompatibilityChangeConfig build() { + return new CompatibilityChangeConfig(new Compatibility.ChangeConfig(mEnabled, mDisabled)); + } +} diff --git a/services/tests/servicestests/src/com/android/server/compat/OverrideValidatorImplTest.java b/services/tests/servicestests/src/com/android/server/compat/OverrideValidatorImplTest.java new file mode 100644 index 000000000000..ecd07bdc4544 --- /dev/null +++ b/services/tests/servicestests/src/com/android/server/compat/OverrideValidatorImplTest.java @@ -0,0 +1,383 @@ +/* + * 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.compat; + +import static com.android.internal.compat.OverrideAllowedState.ALLOWED; +import static com.android.internal.compat.OverrideAllowedState.DISABLED_NON_TARGET_SDK; +import static com.android.internal.compat.OverrideAllowedState.DISABLED_NOT_DEBUGGABLE; +import static com.android.internal.compat.OverrideAllowedState.DISABLED_TARGET_SDK_TOO_HIGH; + +import static com.google.common.truth.Truth.assertThat; + +import static org.mockito.ArgumentMatchers.anyInt; +import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +import android.content.Context; +import android.content.pm.PackageManager; + +import androidx.test.runner.AndroidJUnit4; + +import com.android.internal.compat.AndroidBuildClassifier; +import com.android.internal.compat.IOverrideValidator; +import com.android.internal.compat.OverrideAllowedState; + +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; + +@RunWith(AndroidJUnit4.class) +public class OverrideValidatorImplTest { + private static final String PACKAGE_NAME = "my.package"; + private static final int TARGET_SDK = 10; + private static final int TARGET_SDK_BEFORE = 9; + private static final int TARGET_SDK_AFTER = 11; + + @Mock + private PackageManager mPackageManager; + @Mock + Context mContext; + + private AndroidBuildClassifier debuggableBuild() { + AndroidBuildClassifier buildClassifier = mock(AndroidBuildClassifier.class); + when(buildClassifier.isDebuggableBuild()).thenReturn(true); + return buildClassifier; + } + + private AndroidBuildClassifier betaBuild() { + AndroidBuildClassifier buildClassifier = mock(AndroidBuildClassifier.class); + when(buildClassifier.isDebuggableBuild()).thenReturn(false); + when(buildClassifier.isFinalBuild()).thenReturn(false); + return buildClassifier; + } + + private AndroidBuildClassifier finalBuild() { + AndroidBuildClassifier buildClassifier = mock(AndroidBuildClassifier.class); + when(buildClassifier.isDebuggableBuild()).thenReturn(false); + when(buildClassifier.isFinalBuild()).thenReturn(true); + return buildClassifier; + } + + @Before + public void setUp() throws Exception { + MockitoAnnotations.initMocks(this); + when(mContext.getPackageManager()).thenReturn(mPackageManager); + } + + @Test + public void getOverrideAllowedState_debugBuildAnyChangeDebugApp_allowOverride() + throws Exception { + CompatConfig config = CompatConfigBuilder.create(debuggableBuild(), mContext) + .addTargetSdkChangeWithId(TARGET_SDK_BEFORE, 1) + .addTargetSdkChangeWithId(TARGET_SDK, 2) + .addTargetSdkChangeWithId(TARGET_SDK_AFTER, 3) + .addEnabledChangeWithId(4) + .addDisabledChangeWithId(5).build(); + IOverrideValidator overrideValidator = config.getOverrideValidator(); + when(mPackageManager.getApplicationInfo(eq(PACKAGE_NAME), anyInt())) + .thenReturn(ApplicationInfoBuilder.create() + .debuggable() + .withTargetSdk(TARGET_SDK) + .withPackageName(PACKAGE_NAME).build()); + + OverrideAllowedState stateTargetSdkLessChange = + overrideValidator.getOverrideAllowedState(1, PACKAGE_NAME); + OverrideAllowedState stateTargetSdkEqualChange = + overrideValidator.getOverrideAllowedState(2, PACKAGE_NAME); + OverrideAllowedState stateTargetSdkAfterChange = + overrideValidator.getOverrideAllowedState(3, PACKAGE_NAME); + OverrideAllowedState stateEnabledChange = + overrideValidator.getOverrideAllowedState(4, PACKAGE_NAME); + OverrideAllowedState stateDisabledChange = + overrideValidator.getOverrideAllowedState(5, PACKAGE_NAME); + + assertThat(stateTargetSdkLessChange) + .isEqualTo(new OverrideAllowedState(ALLOWED, -1, -1)); + assertThat(stateTargetSdkEqualChange) + .isEqualTo(new OverrideAllowedState(ALLOWED, -1, -1)); + assertThat(stateTargetSdkAfterChange) + .isEqualTo(new OverrideAllowedState(ALLOWED, -1, -1)); + assertThat(stateEnabledChange) + .isEqualTo(new OverrideAllowedState(ALLOWED, -1, -1)); + assertThat(stateDisabledChange) + .isEqualTo(new OverrideAllowedState(ALLOWED, -1, -1)); + } + + @Test + public void getOverrideAllowedState_debugBuildAnyChangeReleaseApp_allowOverride() + throws Exception { + CompatConfig config = CompatConfigBuilder.create(debuggableBuild(), mContext) + .addTargetSdkChangeWithId(TARGET_SDK_BEFORE, 1) + .addTargetSdkChangeWithId(TARGET_SDK, 2) + .addTargetSdkChangeWithId(TARGET_SDK_AFTER, 3) + .addEnabledChangeWithId(4) + .addDisabledChangeWithId(5).build(); + IOverrideValidator overrideValidator = config.getOverrideValidator(); + when(mPackageManager.getApplicationInfo(eq(PACKAGE_NAME), anyInt())) + .thenReturn(ApplicationInfoBuilder.create() + .withPackageName(PACKAGE_NAME) + .withTargetSdk(TARGET_SDK).build()); + + OverrideAllowedState stateTargetSdkLessChange = + overrideValidator.getOverrideAllowedState(1, PACKAGE_NAME); + OverrideAllowedState stateTargetSdkEqualChange = + overrideValidator.getOverrideAllowedState(2, PACKAGE_NAME); + OverrideAllowedState stateTargetSdkAfterChange = + overrideValidator.getOverrideAllowedState(3, PACKAGE_NAME); + OverrideAllowedState stateEnabledChange = + overrideValidator.getOverrideAllowedState(4, PACKAGE_NAME); + OverrideAllowedState stateDisabledChange = + overrideValidator.getOverrideAllowedState(5, PACKAGE_NAME); + + assertThat(stateTargetSdkLessChange) + .isEqualTo(new OverrideAllowedState(ALLOWED, -1, -1)); + assertThat(stateTargetSdkEqualChange) + .isEqualTo(new OverrideAllowedState(ALLOWED, -1, -1)); + assertThat(stateTargetSdkAfterChange) + .isEqualTo(new OverrideAllowedState(ALLOWED, -1, -1)); + assertThat(stateEnabledChange) + .isEqualTo(new OverrideAllowedState(ALLOWED, -1, -1)); + assertThat(stateDisabledChange) + .isEqualTo(new OverrideAllowedState(ALLOWED, -1, -1)); + } + + @Test + public void getOverrideAllowedState_betaBuildTargetSdkChangeDebugApp_allowOverride() + throws Exception { + CompatConfig config = CompatConfigBuilder.create(betaBuild(), mContext) + .addTargetSdkChangeWithId(TARGET_SDK_BEFORE, 1) + .addTargetSdkChangeWithId(TARGET_SDK, 2) + .addTargetSdkChangeWithId(TARGET_SDK_AFTER, 3).build(); + IOverrideValidator overrideValidator = config.getOverrideValidator(); + when(mPackageManager.getApplicationInfo(eq(PACKAGE_NAME), anyInt())) + .thenReturn(ApplicationInfoBuilder.create() + .debuggable() + .withTargetSdk(TARGET_SDK) + .withPackageName(PACKAGE_NAME).build()); + + OverrideAllowedState stateTargetSdkLessChange = + overrideValidator.getOverrideAllowedState(1, PACKAGE_NAME); + OverrideAllowedState stateTargetSdkEqualChange = + overrideValidator.getOverrideAllowedState(2, PACKAGE_NAME); + OverrideAllowedState stateTargetSdkAfterChange = + overrideValidator.getOverrideAllowedState(3, PACKAGE_NAME); + + assertThat(stateTargetSdkLessChange) + .isEqualTo(new OverrideAllowedState(ALLOWED, TARGET_SDK, TARGET_SDK_BEFORE)); + assertThat(stateTargetSdkEqualChange) + .isEqualTo(new OverrideAllowedState(ALLOWED, TARGET_SDK, TARGET_SDK)); + assertThat(stateTargetSdkAfterChange) + .isEqualTo(new OverrideAllowedState(ALLOWED, TARGET_SDK, TARGET_SDK_AFTER)); + } + + @Test + public void getOverrideAllowedState_betaBuildEnabledChangeDebugApp_rejectOverride() + throws Exception { + CompatConfig config = CompatConfigBuilder.create(betaBuild(), mContext) + .addEnabledChangeWithId(1).build(); + IOverrideValidator overrideValidator = config.getOverrideValidator(); + when(mPackageManager.getApplicationInfo(eq(PACKAGE_NAME), anyInt())) + .thenReturn(ApplicationInfoBuilder.create() + .withPackageName(PACKAGE_NAME) + .debuggable() + .build()); + + OverrideAllowedState allowedState = + overrideValidator.getOverrideAllowedState(1, PACKAGE_NAME); + + assertThat(allowedState) + .isEqualTo(new OverrideAllowedState(DISABLED_NON_TARGET_SDK, -1, -1)); + } + + @Test + public void getOverrideAllowedState_betaBuildDisabledChangeDebugApp_rejectOverride() + throws Exception { + CompatConfig config = CompatConfigBuilder.create(betaBuild(), mContext) + .addDisabledChangeWithId(1).build(); + IOverrideValidator overrideValidator = config.getOverrideValidator(); + when(mPackageManager.getApplicationInfo(eq(PACKAGE_NAME), anyInt())) + .thenReturn(ApplicationInfoBuilder.create() + .debuggable() + .withPackageName(PACKAGE_NAME).build()); + + OverrideAllowedState allowedState = + overrideValidator.getOverrideAllowedState(1, PACKAGE_NAME); + + assertThat(allowedState) + .isEqualTo(new OverrideAllowedState(DISABLED_NON_TARGET_SDK, -1, -1)); + } + + @Test + public void getOverrideAllowedState_betaBuildAnyChangeReleaseApp_rejectOverride() + throws Exception { + CompatConfig config = CompatConfigBuilder.create(betaBuild(), mContext) + .addTargetSdkChangeWithId(TARGET_SDK_BEFORE, 1) + .addTargetSdkChangeWithId(TARGET_SDK, 2) + .addTargetSdkChangeWithId(TARGET_SDK_AFTER, 3) + .addEnabledChangeWithId(4) + .addDisabledChangeWithId(5).build(); + IOverrideValidator overrideValidator = config.getOverrideValidator(); + when(mPackageManager.getApplicationInfo(eq(PACKAGE_NAME), anyInt())) + .thenReturn(ApplicationInfoBuilder.create() + .withPackageName(PACKAGE_NAME) + .withTargetSdk(TARGET_SDK).build()); + + OverrideAllowedState stateTargetSdkLessChange = + overrideValidator.getOverrideAllowedState(1, PACKAGE_NAME); + OverrideAllowedState stateTargetSdkEqualChange = + overrideValidator.getOverrideAllowedState(2, PACKAGE_NAME); + OverrideAllowedState stateTargetSdkAfterChange = + overrideValidator.getOverrideAllowedState(3, PACKAGE_NAME); + OverrideAllowedState stateEnabledChange = + overrideValidator.getOverrideAllowedState(4, PACKAGE_NAME); + OverrideAllowedState stateDisabledChange = + overrideValidator.getOverrideAllowedState(5, PACKAGE_NAME); + + assertThat(stateTargetSdkLessChange) + .isEqualTo(new OverrideAllowedState(DISABLED_NOT_DEBUGGABLE, -1, -1)); + assertThat(stateTargetSdkEqualChange) + .isEqualTo(new OverrideAllowedState(DISABLED_NOT_DEBUGGABLE, -1, -1)); + assertThat(stateTargetSdkAfterChange) + .isEqualTo(new OverrideAllowedState(DISABLED_NOT_DEBUGGABLE, -1, -1)); + assertThat(stateEnabledChange) + .isEqualTo(new OverrideAllowedState(DISABLED_NOT_DEBUGGABLE, -1, -1)); + assertThat(stateDisabledChange) + .isEqualTo(new OverrideAllowedState(DISABLED_NOT_DEBUGGABLE, -1, -1)); + } + + @Test + public void getOverrideAllowedState_finalBuildTargetSdkChangeDebugAppOptin_allowOverride() + throws Exception { + CompatConfig config = CompatConfigBuilder.create(finalBuild(), mContext) + .addTargetSdkChangeWithId(TARGET_SDK_AFTER, 1).build(); + IOverrideValidator overrideValidator = config.getOverrideValidator(); + when(mPackageManager.getApplicationInfo(eq(PACKAGE_NAME), anyInt())) + .thenReturn(ApplicationInfoBuilder.create() + .debuggable() + .withTargetSdk(TARGET_SDK) + .withPackageName(PACKAGE_NAME).build()); + + OverrideAllowedState allowedState = + overrideValidator.getOverrideAllowedState(1, PACKAGE_NAME); + + assertThat(allowedState) + .isEqualTo(new OverrideAllowedState(ALLOWED, TARGET_SDK, TARGET_SDK_AFTER)); + } + + @Test + public void getOverrideAllowedState_finalBuildTargetSdkChangeDebugAppOptout_rejectOverride() + throws Exception { + CompatConfig config = CompatConfigBuilder.create(finalBuild(), mContext) + .addTargetSdkChangeWithId(TARGET_SDK_BEFORE, 1) + .addTargetSdkChangeWithId(TARGET_SDK, 2).build(); + IOverrideValidator overrideValidator = config.getOverrideValidator(); + when(mPackageManager.getApplicationInfo(eq(PACKAGE_NAME), anyInt())) + .thenReturn(ApplicationInfoBuilder.create() + .withPackageName(PACKAGE_NAME) + .withTargetSdk(TARGET_SDK) + .debuggable() + .build()); + + OverrideAllowedState stateTargetSdkLessChange = + overrideValidator.getOverrideAllowedState(1, PACKAGE_NAME); + OverrideAllowedState stateTargetSdkEqualChange = + overrideValidator.getOverrideAllowedState(2, PACKAGE_NAME); + + assertThat(stateTargetSdkLessChange).isEqualTo( + new OverrideAllowedState(DISABLED_TARGET_SDK_TOO_HIGH, TARGET_SDK, + TARGET_SDK_BEFORE)); + assertThat(stateTargetSdkEqualChange).isEqualTo( + new OverrideAllowedState(DISABLED_TARGET_SDK_TOO_HIGH, TARGET_SDK, TARGET_SDK)); + } + + @Test + public void getOverrideAllowedState_finalBuildEnabledChangeDebugApp_rejectOverride() + throws Exception { + CompatConfig config = CompatConfigBuilder.create(finalBuild(), mContext) + .addEnabledChangeWithId(1).build(); + IOverrideValidator overrideValidator = config.getOverrideValidator(); + when(mPackageManager.getApplicationInfo(eq(PACKAGE_NAME), anyInt())) + .thenReturn(ApplicationInfoBuilder.create() + .withPackageName(PACKAGE_NAME) + .debuggable().build()); + + OverrideAllowedState allowedState = + overrideValidator.getOverrideAllowedState(1, PACKAGE_NAME); + + assertThat(allowedState) + .isEqualTo(new OverrideAllowedState(DISABLED_NON_TARGET_SDK, -1, -1)); + } + + @Test + public void getOverrideAllowedState_finalBuildDisabledChangeDebugApp_rejectOverride() + throws Exception { + CompatConfig config = CompatConfigBuilder.create(finalBuild(), mContext) + .addDisabledChangeWithId(1).build(); + IOverrideValidator overrideValidator = config.getOverrideValidator(); + when(mPackageManager.getApplicationInfo(eq(PACKAGE_NAME), anyInt())) + .thenReturn(ApplicationInfoBuilder.create() + .withPackageName(PACKAGE_NAME) + .debuggable().build()); + + OverrideAllowedState allowedState = + overrideValidator.getOverrideAllowedState(1, PACKAGE_NAME); + + assertThat(allowedState) + .isEqualTo(new OverrideAllowedState(DISABLED_NON_TARGET_SDK, -1, -1)); + } + + @Test + public void getOverrideAllowedState_finalBuildAnyChangeReleaseApp_rejectOverride() + throws Exception { + CompatConfig config = CompatConfigBuilder.create(finalBuild(), mContext) + .addTargetSdkChangeWithId(TARGET_SDK_BEFORE, 1) + .addTargetSdkChangeWithId(TARGET_SDK, 2) + .addTargetSdkChangeWithId(TARGET_SDK_AFTER, 3) + .addEnabledChangeWithId(4) + .addDisabledChangeWithId(5).build(); + IOverrideValidator overrideValidator = config.getOverrideValidator(); + when(mPackageManager.getApplicationInfo(eq(PACKAGE_NAME), anyInt())) + .thenReturn(ApplicationInfoBuilder.create() + .withPackageName(PACKAGE_NAME) + .withTargetSdk(TARGET_SDK).build()); + + OverrideAllowedState stateTargetSdkLessChange = + overrideValidator.getOverrideAllowedState(1, PACKAGE_NAME); + OverrideAllowedState stateTargetSdkEqualChange = + overrideValidator.getOverrideAllowedState(2, PACKAGE_NAME); + OverrideAllowedState stateTargetSdkAfterChange = + overrideValidator.getOverrideAllowedState(3, PACKAGE_NAME); + OverrideAllowedState stateEnabledChange = + overrideValidator.getOverrideAllowedState(4, PACKAGE_NAME); + OverrideAllowedState stateDisabledChange = + overrideValidator.getOverrideAllowedState(5, PACKAGE_NAME); + + assertThat(stateTargetSdkLessChange) + .isEqualTo(new OverrideAllowedState(DISABLED_NOT_DEBUGGABLE, -1, -1)); + assertThat(stateTargetSdkEqualChange) + .isEqualTo(new OverrideAllowedState(DISABLED_NOT_DEBUGGABLE, -1, -1)); + assertThat(stateTargetSdkAfterChange) + .isEqualTo(new OverrideAllowedState(DISABLED_NOT_DEBUGGABLE, -1, -1)); + assertThat(stateEnabledChange) + .isEqualTo(new OverrideAllowedState(DISABLED_NOT_DEBUGGABLE, -1, -1)); + assertThat(stateDisabledChange) + .isEqualTo(new OverrideAllowedState(DISABLED_NOT_DEBUGGABLE, -1, -1)); + } +} diff --git a/services/tests/servicestests/src/com/android/server/compat/PlatformCompatTest.java b/services/tests/servicestests/src/com/android/server/compat/PlatformCompatTest.java index c406876c5cee..ce5d6d9be770 100644 --- a/services/tests/servicestests/src/com/android/server/compat/PlatformCompatTest.java +++ b/services/tests/servicestests/src/com/android/server/compat/PlatformCompatTest.java @@ -26,21 +26,20 @@ import static org.mockito.Mockito.when; import static org.mockito.internal.verification.VerificationModeFactory.times; import static org.testng.Assert.assertThrows; -import android.compat.Compatibility; import android.content.Context; import android.content.pm.PackageManager; -import com.android.internal.compat.CompatibilityChangeConfig; +import androidx.test.runner.AndroidJUnit4; -import com.google.common.collect.ImmutableSet; +import com.android.internal.compat.AndroidBuildClassifier; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; -import org.mockito.junit.MockitoJUnitRunner; +import org.mockito.MockitoAnnotations; -@RunWith(MockitoJUnitRunner.class) +@RunWith(AndroidJUnit4.class) public class PlatformCompatTest { private static final String PACKAGE_NAME = "my.package"; @@ -50,84 +49,77 @@ public class PlatformCompatTest { private PackageManager mPackageManager; @Mock CompatChange.ChangeListener mListener1, mListener2; - + PlatformCompat mPlatformCompat; + CompatConfig mCompatConfig; + @Mock + private AndroidBuildClassifier mBuildClassifier; @Before public void setUp() throws Exception { + MockitoAnnotations.initMocks(this); when(mContext.getPackageManager()).thenReturn(mPackageManager); when(mPackageManager.getPackageUid(eq(PACKAGE_NAME), eq(0))).thenThrow( new PackageManager.NameNotFoundException()); - CompatConfig.get().clearChanges(); + mCompatConfig = new CompatConfig(mBuildClassifier, mContext); + mPlatformCompat = new PlatformCompat(mContext, mCompatConfig); + // Assume userdebug/eng non-final build + when(mBuildClassifier.isDebuggableBuild()).thenReturn(true); + when(mBuildClassifier.isFinalBuild()).thenReturn(false); } @Test - public void testRegisterListenerToSameIdThrows() { - PlatformCompat pc = new PlatformCompat(mContext); - + public void testRegisterListenerToSameIdThrows() throws Exception { // Registering a listener to change 1 is successful. - pc.registerListener(1, mListener1); + mPlatformCompat.registerListener(1, mListener1); // Registering a listener to change 2 is successful. - pc.registerListener(2, mListener1); + mPlatformCompat.registerListener(2, mListener1); // Trying to register another listener to change id 1 fails. - assertThrows(IllegalStateException.class, () -> pc.registerListener(1, mListener1)); + assertThrows(IllegalStateException.class, + () -> mPlatformCompat.registerListener(1, mListener1)); } @Test - public void testRegisterListenerReturn() { - PlatformCompat pc = new PlatformCompat(mContext); - - pc.setOverrides( - new CompatibilityChangeConfig( - new Compatibility.ChangeConfig(ImmutableSet.of(1L), ImmutableSet.of())), + public void testRegisterListenerReturn() throws Exception { + mPlatformCompat.setOverrides( + CompatibilityChangeConfigBuilder.create().enable(1L).build(), PACKAGE_NAME); // Change id 1 is known (added in setOverrides). - assertThat(pc.registerListener(1, mListener1)).isTrue(); + assertThat(mPlatformCompat.registerListener(1, mListener1)).isTrue(); // Change 2 is unknown. - assertThat(pc.registerListener(2, mListener1)).isFalse(); + assertThat(mPlatformCompat.registerListener(2, mListener1)).isFalse(); } @Test - public void testListenerCalledOnSetOverrides() { - PlatformCompat pc = new PlatformCompat(mContext); + public void testListenerCalledOnSetOverrides() throws Exception { + mPlatformCompat.registerListener(1, mListener1); + mPlatformCompat.registerListener(2, mListener1); - pc.registerListener(1, mListener1); - pc.registerListener(2, mListener1); - - pc.setOverrides( - new CompatibilityChangeConfig( - new Compatibility.ChangeConfig(ImmutableSet.of(1L), ImmutableSet.of(2L))), + mPlatformCompat.setOverrides( + CompatibilityChangeConfigBuilder.create().enable(1L).disable(2L).build(), PACKAGE_NAME); verify(mListener1, times(2)).onCompatChange(PACKAGE_NAME); } @Test - public void testListenerNotCalledOnWrongPackage() { - PlatformCompat pc = new PlatformCompat(mContext); - - pc.registerListener(1, mListener1); - pc.registerListener(2, mListener1); + public void testListenerNotCalledOnWrongPackage() throws Exception { + mPlatformCompat.registerListener(1, mListener1); + mPlatformCompat.registerListener(2, mListener1); - pc.setOverridesForTest( - new CompatibilityChangeConfig( - new Compatibility.ChangeConfig(ImmutableSet.of(1L), ImmutableSet.of(2L))), + mPlatformCompat.setOverrides( + CompatibilityChangeConfigBuilder.create().enable(1L).disable(2L).build(), PACKAGE_NAME); verify(mListener1, never()).onCompatChange("other.package"); } @Test - public void testListenerCalledOnSetOverridesTwoListeners() { - PlatformCompat pc = new PlatformCompat(mContext); - pc.registerListener(1, mListener1); + public void testListenerCalledOnSetOverridesTwoListeners() throws Exception { + mPlatformCompat.registerListener(1, mListener1); - final ImmutableSet<Long> enabled = ImmutableSet.of(1L); - final ImmutableSet<Long> disabled = ImmutableSet.of(2L); - - pc.setOverrides( - new CompatibilityChangeConfig( - new Compatibility.ChangeConfig(enabled, disabled)), + mPlatformCompat.setOverrides( + CompatibilityChangeConfigBuilder.create().enable(1L).disable(2L).build(), PACKAGE_NAME); verify(mListener1, times(1)).onCompatChange(PACKAGE_NAME); @@ -136,11 +128,10 @@ public class PlatformCompatTest { reset(mListener1); reset(mListener2); - pc.registerListener(2, mListener2); + mPlatformCompat.registerListener(2, mListener2); - pc.setOverrides( - new CompatibilityChangeConfig( - new Compatibility.ChangeConfig(enabled, disabled)), + mPlatformCompat.setOverrides( + CompatibilityChangeConfigBuilder.create().enable(1L).disable(2L).build(), PACKAGE_NAME); verify(mListener1, times(1)).onCompatChange(PACKAGE_NAME); @@ -148,31 +139,23 @@ public class PlatformCompatTest { } @Test - public void testListenerCalledOnSetOverridesForTest() { - PlatformCompat pc = new PlatformCompat(mContext); - - pc.registerListener(1, mListener1); - pc.registerListener(2, mListener1); + public void testListenerCalledOnSetOverridesForTest() throws Exception { + mPlatformCompat.registerListener(1, mListener1); + mPlatformCompat.registerListener(2, mListener1); - pc.setOverridesForTest( - new CompatibilityChangeConfig( - new Compatibility.ChangeConfig(ImmutableSet.of(1L), ImmutableSet.of(2L))), + mPlatformCompat.setOverrides( + CompatibilityChangeConfigBuilder.create().enable(1L).disable(2L).build(), PACKAGE_NAME); verify(mListener1, times(2)).onCompatChange(PACKAGE_NAME); } @Test - public void testListenerCalledOnSetOverridesTwoListenersForTest() { - PlatformCompat pc = new PlatformCompat(mContext); - pc.registerListener(1, mListener1); + public void testListenerCalledOnSetOverridesTwoListenersForTest() throws Exception { + mPlatformCompat.registerListener(1, mListener1); - final ImmutableSet<Long> enabled = ImmutableSet.of(1L); - final ImmutableSet<Long> disabled = ImmutableSet.of(2L); - - pc.setOverridesForTest( - new CompatibilityChangeConfig( - new Compatibility.ChangeConfig(enabled, disabled)), + mPlatformCompat.setOverrides( + CompatibilityChangeConfigBuilder.create().enable(1L).disable(2L).build(), PACKAGE_NAME); verify(mListener1, times(1)).onCompatChange(PACKAGE_NAME); @@ -181,10 +164,10 @@ public class PlatformCompatTest { reset(mListener1); reset(mListener2); - pc.registerListener(2, mListener2); - pc.setOverridesForTest( - new CompatibilityChangeConfig( - new Compatibility.ChangeConfig(enabled, disabled)), + mPlatformCompat.registerListener(2, mListener2); + + mPlatformCompat.setOverrides( + CompatibilityChangeConfigBuilder.create().enable(1L).disable(2L).build(), PACKAGE_NAME); verify(mListener1, times(1)).onCompatChange(PACKAGE_NAME); @@ -192,15 +175,12 @@ public class PlatformCompatTest { } @Test - public void testListenerCalledOnClearOverrides() { - PlatformCompat pc = new PlatformCompat(mContext); + public void testListenerCalledOnClearOverrides() throws Exception { + mPlatformCompat.registerListener(1, mListener1); + mPlatformCompat.registerListener(2, mListener2); - pc.registerListener(1, mListener1); - pc.registerListener(2, mListener2); - - pc.setOverrides( - new CompatibilityChangeConfig( - new Compatibility.ChangeConfig(ImmutableSet.of(1L), ImmutableSet.of())), + mPlatformCompat.setOverrides( + CompatibilityChangeConfigBuilder.create().enable(1L).build(), PACKAGE_NAME); verify(mListener1, times(1)).onCompatChange(PACKAGE_NAME); verify(mListener2, never()).onCompatChange(PACKAGE_NAME); @@ -208,21 +188,18 @@ public class PlatformCompatTest { reset(mListener1); reset(mListener2); - pc.clearOverrides(PACKAGE_NAME); + mPlatformCompat.clearOverrides(PACKAGE_NAME); verify(mListener1, times(1)).onCompatChange(PACKAGE_NAME); verify(mListener2, never()).onCompatChange(PACKAGE_NAME); } @Test - public void testListenerCalledOnClearOverridesMultipleOverrides() { - PlatformCompat pc = new PlatformCompat(mContext); - - pc.registerListener(1, mListener1); - pc.registerListener(2, mListener2); + public void testListenerCalledOnClearOverridesMultipleOverrides() throws Exception { + mPlatformCompat.registerListener(1, mListener1); + mPlatformCompat.registerListener(2, mListener2); - pc.setOverrides( - new CompatibilityChangeConfig( - new Compatibility.ChangeConfig(ImmutableSet.of(1L), ImmutableSet.of(2L))), + mPlatformCompat.setOverrides( + CompatibilityChangeConfigBuilder.create().enable(1L).disable(2L).build(), PACKAGE_NAME); verify(mListener1, times(1)).onCompatChange(PACKAGE_NAME); verify(mListener2, times(1)).onCompatChange(PACKAGE_NAME); @@ -230,21 +207,18 @@ public class PlatformCompatTest { reset(mListener1); reset(mListener2); - pc.clearOverrides(PACKAGE_NAME); + mPlatformCompat.clearOverrides(PACKAGE_NAME); verify(mListener1, times(1)).onCompatChange(PACKAGE_NAME); verify(mListener2, times(1)).onCompatChange(PACKAGE_NAME); } @Test - public void testListenerCalledOnClearOverrideExists() { - PlatformCompat pc = new PlatformCompat(mContext); + public void testListenerCalledOnClearOverrideExists() throws Exception { + mPlatformCompat.registerListener(1, mListener1); + mPlatformCompat.registerListener(2, mListener2); - pc.registerListener(1, mListener1); - pc.registerListener(2, mListener2); - - pc.setOverrides( - new CompatibilityChangeConfig( - new Compatibility.ChangeConfig(ImmutableSet.of(1L), ImmutableSet.of())), + mPlatformCompat.setOverrides( + CompatibilityChangeConfigBuilder.create().enable(1L).build(), PACKAGE_NAME); verify(mListener1, times(1)).onCompatChange(PACKAGE_NAME); verify(mListener2, never()).onCompatChange(PACKAGE_NAME); @@ -252,21 +226,17 @@ public class PlatformCompatTest { reset(mListener1); reset(mListener2); - pc.clearOverride(1, PACKAGE_NAME); + mPlatformCompat.clearOverride(1, PACKAGE_NAME); verify(mListener1, times(1)).onCompatChange(PACKAGE_NAME); verify(mListener2, never()).onCompatChange(PACKAGE_NAME); } @Test - public void testListenerCalledOnClearOverrideDoesntExist() { - PlatformCompat pc = new PlatformCompat(mContext); - - pc.registerListener(1, mListener1); + public void testListenerCalledOnClearOverrideDoesntExist() throws Exception { + mPlatformCompat.registerListener(1, mListener1); - pc.clearOverride(1, PACKAGE_NAME); + mPlatformCompat.clearOverride(1, PACKAGE_NAME); // Listener not called when a non existing override is removed. verify(mListener1, never()).onCompatChange(PACKAGE_NAME); } - - } diff --git a/services/tests/servicestests/src/com/android/server/net/NetworkPolicyManagerServiceTest.java b/services/tests/servicestests/src/com/android/server/net/NetworkPolicyManagerServiceTest.java index 7e08d955c5d1..2e58ad68fc7c 100644 --- a/services/tests/servicestests/src/com/android/server/net/NetworkPolicyManagerServiceTest.java +++ b/services/tests/servicestests/src/com/android/server/net/NetworkPolicyManagerServiceTest.java @@ -37,6 +37,7 @@ import static android.net.NetworkPolicyManager.uidRulesToString; import static android.net.NetworkStats.IFACE_ALL; import static android.net.NetworkStats.SET_ALL; import static android.net.NetworkStats.TAG_ALL; +import static android.net.NetworkStats.TAG_NONE; import static android.net.NetworkTemplate.buildTemplateMobileAll; import static android.net.NetworkTemplate.buildTemplateWifi; import static android.net.TrafficStats.MB_IN_BYTES; @@ -111,7 +112,7 @@ import android.net.NetworkState; import android.net.NetworkStats; import android.net.NetworkStatsHistory; import android.net.NetworkTemplate; -import android.net.StringNetworkSpecifier; +import android.net.TelephonyNetworkSpecifier; import android.os.Binder; import android.os.Handler; import android.os.INetworkManagementService; @@ -1197,11 +1198,11 @@ public class NetworkPolicyManagerServiceTest { history.recordData(start, end, new NetworkStats.Entry(DataUnit.MEGABYTES.toBytes(1440), 0L, 0L, 0L, 0)); stats.clear(); - stats.addValues(IFACE_ALL, UID_A, SET_ALL, TAG_ALL, + stats.addEntry(IFACE_ALL, UID_A, SET_ALL, TAG_ALL, DataUnit.MEGABYTES.toBytes(480), 0, 0, 0, 0); - stats.addValues(IFACE_ALL, UID_B, SET_ALL, TAG_ALL, + stats.addEntry(IFACE_ALL, UID_B, SET_ALL, TAG_ALL, DataUnit.MEGABYTES.toBytes(480), 0, 0, 0, 0); - stats.addValues(IFACE_ALL, UID_C, SET_ALL, TAG_ALL, + stats.addEntry(IFACE_ALL, UID_C, SET_ALL, TAG_ALL, DataUnit.MEGABYTES.toBytes(480), 0, 0, 0, 0); reset(mNotifManager); @@ -1225,9 +1226,9 @@ public class NetworkPolicyManagerServiceTest { history.recordData(start, end, new NetworkStats.Entry(DataUnit.MEGABYTES.toBytes(1440), 0L, 0L, 0L, 0)); stats.clear(); - stats.addValues(IFACE_ALL, UID_A, SET_ALL, TAG_ALL, + stats.addEntry(IFACE_ALL, UID_A, SET_ALL, TAG_ALL, DataUnit.MEGABYTES.toBytes(960), 0, 0, 0, 0); - stats.addValues(IFACE_ALL, UID_B, SET_ALL, TAG_ALL, + stats.addEntry(IFACE_ALL, UID_B, SET_ALL, TAG_ALL, DataUnit.MEGABYTES.toBytes(480), 0, 0, 0, 0); reset(mNotifManager); @@ -1683,6 +1684,59 @@ public class NetworkPolicyManagerServiceTest { } /** + * Test that when StatsProvider triggers limit reached, new limit will be calculated and + * re-armed. + */ + @Test + public void testStatsProviderLimitReached() throws Exception { + final int CYCLE_DAY = 15; + + final NetworkStats stats = new NetworkStats(0L, 1); + stats.addEntry(TEST_IFACE, UID_A, SET_ALL, TAG_NONE, + 2999, 1, 2000, 1, 0); + when(mStatsService.getNetworkTotalBytes(any(), anyLong(), anyLong())) + .thenReturn(stats.getTotalBytes()); + when(mStatsService.getNetworkUidBytes(any(), anyLong(), anyLong())) + .thenReturn(stats); + + // Get active mobile network in place + expectMobileDefaults(); + mService.updateNetworks(); + verify(mStatsService).setStatsProviderLimit(TEST_IFACE, Long.MAX_VALUE); + + // Set limit to 10KB. + setNetworkPolicies(new NetworkPolicy( + sTemplateMobileAll, CYCLE_DAY, TIMEZONE_UTC, WARNING_DISABLED, 10000L, + true)); + postMsgAndWaitForCompletion(); + + // Verifies that remaining quota is set to providers. + verify(mStatsService).setStatsProviderLimit(TEST_IFACE, 10000L - 4999L); + + reset(mStatsService); + + // Increase the usage. + stats.addEntry(TEST_IFACE, UID_A, SET_ALL, TAG_NONE, + 1000, 1, 999, 1, 0); + when(mStatsService.getNetworkTotalBytes(any(), anyLong(), anyLong())) + .thenReturn(stats.getTotalBytes()); + when(mStatsService.getNetworkUidBytes(any(), anyLong(), anyLong())) + .thenReturn(stats); + + // Simulates that limit reached fires earlier by provider, but actually the quota is not + // yet reached. + final NetworkPolicyManagerInternal npmi = LocalServices + .getService(NetworkPolicyManagerInternal.class); + npmi.onStatsProviderLimitReached("TEST"); + + // Verifies that the limit reached leads to a force update and new limit should be set. + postMsgAndWaitForCompletion(); + verify(mStatsService).forceUpdate(); + postMsgAndWaitForCompletion(); + verify(mStatsService).setStatsProviderLimit(TEST_IFACE, 10000L - 4999L - 1999L); + } + + /** * Exhaustively test isUidNetworkingBlocked to output the expected results based on external * conditions. */ @@ -1784,7 +1838,8 @@ public class NetworkPolicyManagerServiceTest { if (!roaming) { nc.addCapability(NET_CAPABILITY_NOT_ROAMING); } - nc.setNetworkSpecifier(new StringNetworkSpecifier(String.valueOf(subId))); + nc.setNetworkSpecifier(new TelephonyNetworkSpecifier.Builder() + .setSubscriptionId(subId).build()); return nc; } diff --git a/services/tests/servicestests/src/com/android/server/pm/ModuleInfoProviderTest.java b/services/tests/servicestests/src/com/android/server/pm/ModuleInfoProviderTest.java index bd3d9ab2220d..3852b9fec001 100644 --- a/services/tests/servicestests/src/com/android/server/pm/ModuleInfoProviderTest.java +++ b/services/tests/servicestests/src/com/android/server/pm/ModuleInfoProviderTest.java @@ -17,6 +17,7 @@ package com.android.server.pm; import android.content.Context; import android.content.pm.ModuleInfo; +import android.content.pm.PackageManager; import android.test.InstrumentationTestCase; import com.android.frameworks.servicestests.R; @@ -28,7 +29,7 @@ public class ModuleInfoProviderTest extends InstrumentationTestCase { public void testSuccessfulParse() { ModuleInfoProvider provider = getProvider(R.xml.well_formed_metadata); - List<ModuleInfo> mi = provider.getInstalledModules(0); + List<ModuleInfo> mi = provider.getInstalledModules(PackageManager.MATCH_ALL); assertEquals(2, mi.size()); Collections.sort(mi, (ModuleInfo m1, ModuleInfo m2) -> @@ -49,18 +50,18 @@ public class ModuleInfoProviderTest extends InstrumentationTestCase { public void testParseFailure_incorrectTopLevelElement() { ModuleInfoProvider provider = getProvider(R.xml.unparseable_metadata1); - assertEquals(0, provider.getInstalledModules(0).size()); + assertEquals(0, provider.getInstalledModules(PackageManager.MATCH_ALL).size()); } public void testParseFailure_incorrectModuleElement() { ModuleInfoProvider provider = getProvider(R.xml.unparseable_metadata2); - assertEquals(0, provider.getInstalledModules(0).size()); + assertEquals(0, provider.getInstalledModules(PackageManager.MATCH_ALL).size()); } public void testParse_unknownAttributesIgnored() { ModuleInfoProvider provider = getProvider(R.xml.well_formed_metadata); - List<ModuleInfo> mi = provider.getInstalledModules(0); + List<ModuleInfo> mi = provider.getInstalledModules(PackageManager.MATCH_ALL); assertEquals(2, mi.size()); ModuleInfo mi1 = provider.getModuleInfo("com.android.module1", 0); diff --git a/services/tests/servicestests/src/com/android/server/pm/dex/DexManagerTests.java b/services/tests/servicestests/src/com/android/server/pm/dex/DexManagerTests.java index 0196279cbf56..a4ba056b96a8 100644 --- a/services/tests/servicestests/src/com/android/server/pm/dex/DexManagerTests.java +++ b/services/tests/servicestests/src/com/android/server/pm/dex/DexManagerTests.java @@ -160,6 +160,31 @@ public class DexManagerTests { } @Test + public void testNotifyPrimaryAndSecondary() { + List<String> dexFiles = mFooUser0.getBaseAndSplitDexPaths(); + List<String> secondaries = mFooUser0.getSecondaryDexPaths(); + int baseAndSplitCount = dexFiles.size(); + dexFiles.addAll(secondaries); + + notifyDexLoad(mFooUser0, dexFiles, mUser0); + + PackageUseInfo pui = getPackageUseInfo(mFooUser0); + assertIsUsedByOtherApps(mFooUser0, pui, false); + assertEquals(secondaries.size(), pui.getDexUseInfoMap().size()); + + String[] allExpectedContexts = DexoptUtils.processContextForDexLoad( + Arrays.asList(mFooUser0.mClassLoader), + Arrays.asList(String.join(File.pathSeparator, dexFiles))); + String[] secondaryExpectedContexts = Arrays.copyOfRange(allExpectedContexts, + baseAndSplitCount, dexFiles.size()); + + assertSecondaryUse(mFooUser0, pui, secondaries, /*isUsedByOtherApps*/false, mUser0, + secondaryExpectedContexts); + + assertHasDclInfo(mFooUser0, mFooUser0, secondaries); + } + + @Test public void testNotifySecondaryForeign() { // Foo loads bar secondary files. List<String> barSecondaries = mBarUser0.getSecondaryDexPaths(); diff --git a/services/tests/servicestests/src/com/android/server/timedetector/TimeDetectorServiceTest.java b/services/tests/servicestests/src/com/android/server/timedetector/TimeDetectorServiceTest.java index 71b568cc06c5..ae5369204428 100644 --- a/services/tests/servicestests/src/com/android/server/timedetector/TimeDetectorServiceTest.java +++ b/services/tests/servicestests/src/com/android/server/timedetector/TimeDetectorServiceTest.java @@ -37,7 +37,7 @@ import android.os.Handler; import android.os.HandlerThread; import android.os.Looper; import android.os.Message; -import android.util.TimestampedValue; +import android.os.TimestampedValue; import androidx.test.runner.AndroidJUnit4; diff --git a/services/tests/servicestests/src/com/android/server/timedetector/TimeDetectorStrategyImplTest.java b/services/tests/servicestests/src/com/android/server/timedetector/TimeDetectorStrategyImplTest.java index ca6fd08092df..d940a6a320f2 100644 --- a/services/tests/servicestests/src/com/android/server/timedetector/TimeDetectorStrategyImplTest.java +++ b/services/tests/servicestests/src/com/android/server/timedetector/TimeDetectorStrategyImplTest.java @@ -18,7 +18,6 @@ package com.android.server.timedetector; 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; @@ -26,11 +25,10 @@ import static org.junit.Assert.fail; import android.app.timedetector.ManualTimeSuggestion; import android.app.timedetector.NetworkTimeSuggestion; import android.app.timedetector.PhoneTimeSuggestion; -import android.content.Intent; import android.icu.util.Calendar; import android.icu.util.GregorianCalendar; import android.icu.util.TimeZone; -import android.util.TimestampedValue; +import android.os.TimestampedValue; import androidx.test.runner.AndroidJUnit4; @@ -78,8 +76,7 @@ public class TimeDetectorStrategyImplTest { long expectedSystemClockMillis = mScript.calculateTimeInMillisForNow(timeSuggestion.getUtcTime()); - mScript.verifySystemClockWasSetAndResetCallTracking( - expectedSystemClockMillis, true /* expectNetworkBroadcast */) + mScript.verifySystemClockWasSetAndResetCallTracking(expectedSystemClockMillis) .assertLatestPhoneSuggestion(phoneId, timeSuggestion); } @@ -118,8 +115,7 @@ public class TimeDetectorStrategyImplTest { mScript.calculateTimeInMillisForNow(timeSuggestion1.getUtcTime()); mScript.simulatePhoneTimeSuggestion(timeSuggestion1) - .verifySystemClockWasSetAndResetCallTracking( - expectedSystemClockMillis1, true /* expectNetworkBroadcast */) + .verifySystemClockWasSetAndResetCallTracking(expectedSystemClockMillis1) .assertLatestPhoneSuggestion(phoneId, timeSuggestion1); } @@ -146,8 +142,7 @@ public class TimeDetectorStrategyImplTest { mScript.calculateTimeInMillisForNow(timeSuggestion3.getUtcTime()); mScript.simulatePhoneTimeSuggestion(timeSuggestion3) - .verifySystemClockWasSetAndResetCallTracking( - expectedSystemClockMillis3, true /* expectNetworkBroadcast */) + .verifySystemClockWasSetAndResetCallTracking(expectedSystemClockMillis3) .assertLatestPhoneSuggestion(phoneId, timeSuggestion3); } } @@ -175,8 +170,7 @@ public class TimeDetectorStrategyImplTest { mScript.calculateTimeInMillisForNow(phone2TimeSuggestion.getUtcTime()); mScript.simulatePhoneTimeSuggestion(phone2TimeSuggestion) - .verifySystemClockWasSetAndResetCallTracking( - expectedSystemClockMillis, true /* expectNetworkBroadcast */) + .verifySystemClockWasSetAndResetCallTracking(expectedSystemClockMillis) .assertLatestPhoneSuggestion(phone1Id, null) .assertLatestPhoneSuggestion(phone2Id, phone2TimeSuggestion); } @@ -193,8 +187,7 @@ public class TimeDetectorStrategyImplTest { mScript.calculateTimeInMillisForNow(phone1TimeSuggestion.getUtcTime()); mScript.simulatePhoneTimeSuggestion(phone1TimeSuggestion) - .verifySystemClockWasSetAndResetCallTracking( - expectedSystemClockMillis, true /* expectNetworkBroadcast */) + .verifySystemClockWasSetAndResetCallTracking(expectedSystemClockMillis) .assertLatestPhoneSuggestion(phone1Id, phone1TimeSuggestion); } @@ -227,8 +220,7 @@ public class TimeDetectorStrategyImplTest { mScript.calculateTimeInMillisForNow(phone2TimeSuggestion.getUtcTime()); mScript.simulatePhoneTimeSuggestion(phone2TimeSuggestion) - .verifySystemClockWasSetAndResetCallTracking( - expectedSystemClockMillis, true /* expectNetworkBroadcast */) + .verifySystemClockWasSetAndResetCallTracking(expectedSystemClockMillis) .assertLatestPhoneSuggestion(phone2Id, phone2TimeSuggestion); } } @@ -265,8 +257,7 @@ public class TimeDetectorStrategyImplTest { mScript.simulateTimePassing(); long expectedSystemClockMillis1 = mScript.calculateTimeInMillisForNow(utcTime1); mScript.simulatePhoneTimeSuggestion(timeSuggestion1) - .verifySystemClockWasSetAndResetCallTracking( - expectedSystemClockMillis1, true /* expectNetworkBroadcast */) + .verifySystemClockWasSetAndResetCallTracking(expectedSystemClockMillis1) .assertLatestPhoneSuggestion(phoneId, timeSuggestion1); // The UTC time increment should be larger than the system clock update threshold so we @@ -304,8 +295,7 @@ public class TimeDetectorStrategyImplTest { PhoneTimeSuggestion timeSuggestion4 = createPhoneTimeSuggestion(phoneId, utcTime4); mScript.simulatePhoneTimeSuggestion(timeSuggestion4) - .verifySystemClockWasSetAndResetCallTracking( - expectedSystemClockMillis4, true /* expectNetworkBroadcast */) + .verifySystemClockWasSetAndResetCallTracking(expectedSystemClockMillis4) .assertLatestPhoneSuggestion(phoneId, timeSuggestion4); } @@ -339,8 +329,7 @@ public class TimeDetectorStrategyImplTest { // Turn on auto time detection. mScript.simulateAutoTimeDetectionToggle() - .verifySystemClockWasSetAndResetCallTracking( - expectedSystemClockMillis1, true /* expectNetworkBroadcast */) + .verifySystemClockWasSetAndResetCallTracking(expectedSystemClockMillis1) .assertLatestPhoneSuggestion(phoneId, timeSuggestion1); // Turn off auto time detection. @@ -367,8 +356,7 @@ public class TimeDetectorStrategyImplTest { // Turn on auto time detection. mScript.simulateAutoTimeDetectionToggle() - .verifySystemClockWasSetAndResetCallTracking( - expectedSystemClockMillis2, true /* expectNetworkBroadcast */) + .verifySystemClockWasSetAndResetCallTracking(expectedSystemClockMillis2) .assertLatestPhoneSuggestion(phoneId, timeSuggestion2); } @@ -388,7 +376,7 @@ public class TimeDetectorStrategyImplTest { mScript.calculateTimeInMillisForNow(phoneSuggestion.getUtcTime()); mScript.simulatePhoneTimeSuggestion(phoneSuggestion) .verifySystemClockWasSetAndResetCallTracking( - expectedSystemClockMillis, true /* expectedNetworkBroadcast */) + expectedSystemClockMillis /* expectedNetworkBroadcast */) .assertLatestPhoneSuggestion(phoneId, phoneSuggestion); // Look inside and check what the strategy considers the current best phone suggestion. @@ -416,8 +404,7 @@ public class TimeDetectorStrategyImplTest { long expectedSystemClockMillis = mScript.calculateTimeInMillisForNow(timeSuggestion.getUtcTime()); mScript.simulateManualTimeSuggestion(timeSuggestion) - .verifySystemClockWasSetAndResetCallTracking( - expectedSystemClockMillis, false /* expectNetworkBroadcast */); + .verifySystemClockWasSetAndResetCallTracking(expectedSystemClockMillis); } @Test @@ -439,8 +426,7 @@ public class TimeDetectorStrategyImplTest { long expectedAutoClockMillis = mScript.calculateTimeInMillisForNow(phoneTimeSuggestion.getUtcTime()); mScript.simulatePhoneTimeSuggestion(phoneTimeSuggestion) - .verifySystemClockWasSetAndResetCallTracking( - expectedAutoClockMillis, true /* expectNetworkBroadcast */) + .verifySystemClockWasSetAndResetCallTracking(expectedAutoClockMillis) .assertLatestPhoneSuggestion(phoneId, phoneTimeSuggestion); // Simulate the passage of time. @@ -463,8 +449,7 @@ public class TimeDetectorStrategyImplTest { long expectedManualClockMillis = mScript.calculateTimeInMillisForNow(manualTimeSuggestion.getUtcTime()); mScript.simulateManualTimeSuggestion(manualTimeSuggestion) - .verifySystemClockWasSetAndResetCallTracking( - expectedManualClockMillis, false /* expectNetworkBroadcast */) + .verifySystemClockWasSetAndResetCallTracking(expectedManualClockMillis) .assertLatestPhoneSuggestion(phoneId, phoneTimeSuggestion); // Simulate the passage of time. @@ -475,8 +460,7 @@ public class TimeDetectorStrategyImplTest { expectedAutoClockMillis = mScript.calculateTimeInMillisForNow(phoneTimeSuggestion.getUtcTime()); - mScript.verifySystemClockWasSetAndResetCallTracking( - expectedAutoClockMillis, true /* expectNetworkBroadcast */) + mScript.verifySystemClockWasSetAndResetCallTracking(expectedAutoClockMillis) .assertLatestPhoneSuggestion(phoneId, phoneTimeSuggestion); // Switch back to manual - nothing should happen to the clock. @@ -514,8 +498,7 @@ public class TimeDetectorStrategyImplTest { long expectedSystemClockMillis = mScript.calculateTimeInMillisForNow(timeSuggestion.getUtcTime()); mScript.simulateNetworkTimeSuggestion(timeSuggestion) - .verifySystemClockWasSetAndResetCallTracking( - expectedSystemClockMillis, false /* expectNetworkBroadcast */); + .verifySystemClockWasSetAndResetCallTracking(expectedSystemClockMillis); } @Test @@ -550,8 +533,7 @@ public class TimeDetectorStrategyImplTest { mScript.simulateTimePassing(smallTimeIncrementMillis) .simulateNetworkTimeSuggestion(networkTimeSuggestion1) .verifySystemClockWasSetAndResetCallTracking( - mScript.calculateTimeInMillisForNow(networkTimeSuggestion1.getUtcTime()), - false /* expectNetworkBroadcast */); + mScript.calculateTimeInMillisForNow(networkTimeSuggestion1.getUtcTime())); // Check internal state. mScript.assertLatestPhoneSuggestion(ARBITRARY_PHONE_ID, null) @@ -570,8 +552,7 @@ public class TimeDetectorStrategyImplTest { mScript.simulateTimePassing(smallTimeIncrementMillis) .simulatePhoneTimeSuggestion(phoneTimeSuggestion) .verifySystemClockWasSetAndResetCallTracking( - mScript.calculateTimeInMillisForNow(phoneTimeSuggestion.getUtcTime()), - true /* expectNetworkBroadcast */); + mScript.calculateTimeInMillisForNow(phoneTimeSuggestion.getUtcTime())); // Check internal state. mScript.assertLatestPhoneSuggestion(ARBITRARY_PHONE_ID, phoneTimeSuggestion) @@ -622,8 +603,7 @@ public class TimeDetectorStrategyImplTest { // Verify the latest network time now wins. mScript.verifySystemClockWasSetAndResetCallTracking( - mScript.calculateTimeInMillisForNow(networkTimeSuggestion2.getUtcTime()), - false /* expectNetworkTimeBroadcast */); + mScript.calculateTimeInMillisForNow(networkTimeSuggestion2.getUtcTime())); // Check internal state. mScript.assertLatestPhoneSuggestion(ARBITRARY_PHONE_ID, phoneTimeSuggestion) @@ -645,7 +625,6 @@ public class TimeDetectorStrategyImplTest { // Tracking operations. private boolean mSystemClockWasSet; - private Intent mBroadcastSent; @Override public int systemClockUpdateThresholdMillis() { @@ -672,7 +651,6 @@ public class TimeDetectorStrategyImplTest { @Override public long systemClockMillis() { - assertWakeLockAcquired(); return mSystemClockMillis; } @@ -689,12 +667,6 @@ public class TimeDetectorStrategyImplTest { mWakeLockAcquired = false; } - @Override - public void sendStickyBroadcast(Intent intent) { - assertNotNull(intent); - mBroadcastSent = intent; - } - // Methods below are for managing the fake's behavior. void pokeSystemClockUpdateThreshold(int thresholdMillis) { @@ -739,17 +711,8 @@ public class TimeDetectorStrategyImplTest { assertEquals(expectedSystemClockMillis, mSystemClockMillis); } - void verifyIntentWasBroadcast() { - assertTrue(mBroadcastSent != null); - } - - void verifyIntentWasNotBroadcast() { - assertNull(mBroadcastSent); - } - void resetCallTracking() { mSystemClockWasSet = false; - mBroadcastSent = null; } private void assertWakeLockAcquired() { @@ -832,17 +795,12 @@ public class TimeDetectorStrategyImplTest { Script verifySystemClockWasNotSetAndResetCallTracking() { mFakeCallback.verifySystemClockNotSet(); - mFakeCallback.verifyIntentWasNotBroadcast(); mFakeCallback.resetCallTracking(); return this; } - Script verifySystemClockWasSetAndResetCallTracking( - long expectedSystemClockMillis, boolean expectNetworkBroadcast) { + Script verifySystemClockWasSetAndResetCallTracking(long expectedSystemClockMillis) { mFakeCallback.verifySystemClockWasSet(expectedSystemClockMillis); - if (expectNetworkBroadcast) { - mFakeCallback.verifyIntentWasBroadcast(); - } mFakeCallback.resetCallTracking(); return this; } diff --git a/services/tests/servicestests/src/com/android/server/timedetector/TimeDetectorStrategyTest.java b/services/tests/servicestests/src/com/android/server/timedetector/TimeDetectorStrategyTest.java index 239d413c12d2..f1e9191ddb4f 100644 --- a/services/tests/servicestests/src/com/android/server/timedetector/TimeDetectorStrategyTest.java +++ b/services/tests/servicestests/src/com/android/server/timedetector/TimeDetectorStrategyTest.java @@ -18,7 +18,7 @@ package com.android.server.timedetector; import static org.junit.Assert.assertEquals; -import android.util.TimestampedValue; +import android.os.TimestampedValue; import androidx.test.runner.AndroidJUnit4; diff --git a/telecomm/TEST_MAPPING b/telecomm/TEST_MAPPING new file mode 100644 index 000000000000..d58566673eec --- /dev/null +++ b/telecomm/TEST_MAPPING @@ -0,0 +1,29 @@ +{ + "presubmit": [ + { + "name": "TeleServiceTests", + "options": [ + { + "exclude-annotation": "androidx.test.filters.FlakyTest" + } + ] + }, + { + "name": "TelecomUnitTests", + "options": [ + { + "exclude-annotation": "androidx.test.filters.FlakyTest" + } + ] + }, + { + "name": "TelephonyProviderTests", + "options": [ + { + "exclude-annotation": "androidx.test.filters.FlakyTest" + } + ] + } + ] +} + diff --git a/telecomm/java/android/telecom/AudioState.java b/telecomm/java/android/telecom/AudioState.java index 8b8c86be7b0a..ea641f866b98 100644 --- a/telecomm/java/android/telecom/AudioState.java +++ b/telecomm/java/android/telecom/AudioState.java @@ -19,7 +19,7 @@ package android.telecom; import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.SystemApi; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.os.Build; import android.os.Parcel; import android.os.Parcelable; diff --git a/telecomm/java/android/telecom/Call.java b/telecomm/java/android/telecom/Call.java index 86ad795b9ea2..826a89eb38bb 100644 --- a/telecomm/java/android/telecom/Call.java +++ b/telecomm/java/android/telecom/Call.java @@ -20,12 +20,11 @@ import android.annotation.IntDef; import android.annotation.Nullable; import android.annotation.SystemApi; import android.annotation.TestApi; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.net.Uri; import android.os.Build; import android.os.Bundle; import android.os.Handler; -import android.os.IBinder; import android.os.ParcelFileDescriptor; import com.android.internal.telecom.IVideoProvider; @@ -569,6 +568,7 @@ public final class Call { private final Bundle mExtras; private final Bundle mIntentExtras; private final long mCreationTimeMillis; + private final String mContactDisplayName; private final @CallDirection int mCallDirection; private final @Connection.VerificationStatus int mCallerNumberVerificationStatus; @@ -873,6 +873,17 @@ public final class Call { } /** + * Returns the name of the caller on the remote end, as derived from a + * {@link android.provider.ContactsContract} lookup of the call's handle. + * @return The name of the caller, or {@code null} if the lookup is not yet complete, if + * there's no contacts entry for the caller, or if the {@link InCallService} does + * not hold the {@link android.Manifest.permission#READ_CONTACTS} permission. + */ + public @Nullable String getContactDisplayName() { + return mContactDisplayName; + } + + /** * Indicates whether the call is an incoming or outgoing call. * @return The call's direction. */ @@ -910,6 +921,7 @@ public final class Call { areBundlesEqual(mExtras, d.mExtras) && areBundlesEqual(mIntentExtras, d.mIntentExtras) && Objects.equals(mCreationTimeMillis, d.mCreationTimeMillis) && + Objects.equals(mContactDisplayName, d.mContactDisplayName) && Objects.equals(mCallDirection, d.mCallDirection) && Objects.equals(mCallerNumberVerificationStatus, d.mCallerNumberVerificationStatus); @@ -934,6 +946,7 @@ public final class Call { mExtras, mIntentExtras, mCreationTimeMillis, + mContactDisplayName, mCallDirection, mCallerNumberVerificationStatus); } @@ -956,6 +969,7 @@ public final class Call { Bundle extras, Bundle intentExtras, long creationTimeMillis, + String contactDisplayName, int callDirection, int callerNumberVerificationStatus) { mTelecomCallId = telecomCallId; @@ -974,6 +988,7 @@ public final class Call { mExtras = extras; mIntentExtras = intentExtras; mCreationTimeMillis = creationTimeMillis; + mContactDisplayName = contactDisplayName; mCallDirection = callDirection; mCallerNumberVerificationStatus = callerNumberVerificationStatus; } @@ -997,6 +1012,7 @@ public final class Call { parcelableCall.getExtras(), parcelableCall.getIntentExtras(), parcelableCall.getCreationTimeMillis(), + parcelableCall.getContactDisplayName(), parcelableCall.getCallDirection(), parcelableCall.getCallerNumberVerificationStatus()); } @@ -1446,6 +1462,7 @@ public final class Call { private boolean mChildrenCached; private String mParentId = null; + private String mActiveGenericConferenceChild = null; private int mState; private List<String> mCannedTextResponses = null; private String mCallingPackage; @@ -1944,6 +1961,20 @@ public final class Call { } /** + * Returns the child {@link Call} in a generic conference that is currently active. + * For calls that are not generic conferences, or when the generic conference has more than + * 2 children, returns {@code null}. + * @see Details#PROPERTY_GENERIC_CONFERENCE + * @return The active child call. + */ + public @Nullable Call getGenericConferenceActiveChildCall() { + if (mActiveGenericConferenceChild != null) { + return mPhone.internalGetCallByTelecomId(mActiveGenericConferenceChild); + } + return null; + } + + /** * Obtains a list of canned, pre-configured message responses to present to the user as * ways of rejecting this {@code Call} using via a text message. * @@ -2191,6 +2222,13 @@ public final class Call { mChildrenCached = false; } + String activeChildCallId = parcelableCall.getActiveChildCallId(); + boolean activeChildChanged = !Objects.equals(activeChildCallId, + mActiveGenericConferenceChild); + if (activeChildChanged) { + mActiveGenericConferenceChild = activeChildCallId; + } + List<String> conferenceableCallIds = parcelableCall.getConferenceableCallIds(); List<Call> conferenceableCalls = new ArrayList<Call>(conferenceableCallIds.size()); for (String otherId : conferenceableCallIds) { @@ -2250,7 +2288,7 @@ public final class Call { if (parentChanged) { fireParentChanged(getParent()); } - if (childrenChanged) { + if (childrenChanged || activeChildChanged) { fireChildrenChanged(getChildren()); } if (isRttChanged) { diff --git a/telecomm/java/android/telecom/CallerInfo.java b/telecomm/java/android/telecom/CallerInfo.java index a5d25e2ce4bb..fb6f99405759 100644 --- a/telecomm/java/android/telecom/CallerInfo.java +++ b/telecomm/java/android/telecom/CallerInfo.java @@ -17,7 +17,7 @@ package android.telecom; import android.annotation.Nullable; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.ComponentName; import android.content.ContentResolver; import android.content.Context; @@ -41,8 +41,8 @@ import com.android.i18n.phonenumbers.NumberParseException; import com.android.i18n.phonenumbers.PhoneNumberUtil; import com.android.i18n.phonenumbers.Phonenumber.PhoneNumber; import com.android.i18n.phonenumbers.geocoding.PhoneNumberOfflineGeocoder; - import com.android.internal.annotations.VisibleForTesting; + import java.util.Locale; diff --git a/telecomm/java/android/telecom/Connection.java b/telecomm/java/android/telecom/Connection.java index 8808339b1664..f205ec64f49b 100644 --- a/telecomm/java/android/telecom/Connection.java +++ b/telecomm/java/android/telecom/Connection.java @@ -21,9 +21,9 @@ import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.SystemApi; import android.annotation.TestApi; -import android.annotation.UnsupportedAppUsage; import android.app.Notification; import android.bluetooth.BluetoothDevice; +import android.compat.annotation.UnsupportedAppUsage; import android.content.Intent; import android.hardware.camera2.CameraManager; import android.net.Uri; diff --git a/telecomm/java/android/telecom/Log.java b/telecomm/java/android/telecom/Log.java index 7d4ee7686512..4f6a9d6450f8 100644 --- a/telecomm/java/android/telecom/Log.java +++ b/telecomm/java/android/telecom/Log.java @@ -16,7 +16,7 @@ package android.telecom; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; import android.net.Uri; import android.os.Build; diff --git a/telecomm/java/android/telecom/ParcelableCall.java b/telecomm/java/android/telecom/ParcelableCall.java index a234bb0af8fa..415a817b58d5 100644 --- a/telecomm/java/android/telecom/ParcelableCall.java +++ b/telecomm/java/android/telecom/ParcelableCall.java @@ -16,27 +16,286 @@ package android.telecom; -import android.annotation.UnsupportedAppUsage; +import android.annotation.Nullable; +import android.compat.annotation.UnsupportedAppUsage; import android.net.Uri; import android.os.Build; import android.os.Bundle; -import android.os.IBinder; import android.os.Parcel; import android.os.Parcelable; import android.os.RemoteException; import android.telecom.Call.Details.CallDirection; +import com.android.internal.telecom.IVideoProvider; + import java.util.ArrayList; import java.util.Collections; import java.util.List; -import com.android.internal.telecom.IVideoProvider; - /** * Information about a call that is used between InCallService and Telecom. * @hide */ public final class ParcelableCall implements Parcelable { + + public static class ParcelableCallBuilder { + private String mId; + private int mState; + private DisconnectCause mDisconnectCause; + private List<String> mCannedSmsResponses; + private int mCapabilities; + private int mProperties; + private int mSupportedAudioRoutes; + private long mConnectTimeMillis; + private Uri mHandle; + private int mHandlePresentation; + private String mCallerDisplayName; + private int mCallerDisplayNamePresentation; + private GatewayInfo mGatewayInfo; + private PhoneAccountHandle mAccountHandle; + private boolean mIsVideoCallProviderChanged; + private IVideoProvider mVideoCallProvider; + private boolean mIsRttCallChanged; + private ParcelableRttCall mRttCall; + private String mParentCallId; + private List<String> mChildCallIds; + private StatusHints mStatusHints; + private int mVideoState; + private List<String> mConferenceableCallIds; + private Bundle mIntentExtras; + private Bundle mExtras; + private long mCreationTimeMillis; + private int mCallDirection; + private int mCallerNumberVerificationStatus; + private String mContactDisplayName; + private String mActiveChildCallId; + + public ParcelableCallBuilder setId(String id) { + mId = id; + return this; + } + + public ParcelableCallBuilder setState(int state) { + mState = state; + return this; + } + + public ParcelableCallBuilder setDisconnectCause(DisconnectCause disconnectCause) { + mDisconnectCause = disconnectCause; + return this; + } + + public ParcelableCallBuilder setCannedSmsResponses(List<String> cannedSmsResponses) { + mCannedSmsResponses = cannedSmsResponses; + return this; + } + + public ParcelableCallBuilder setCapabilities(int capabilities) { + mCapabilities = capabilities; + return this; + } + + public ParcelableCallBuilder setProperties(int properties) { + mProperties = properties; + return this; + } + + public ParcelableCallBuilder setSupportedAudioRoutes(int supportedAudioRoutes) { + mSupportedAudioRoutes = supportedAudioRoutes; + return this; + } + + public ParcelableCallBuilder setConnectTimeMillis(long connectTimeMillis) { + mConnectTimeMillis = connectTimeMillis; + return this; + } + + public ParcelableCallBuilder setHandle(Uri handle) { + mHandle = handle; + return this; + } + + public ParcelableCallBuilder setHandlePresentation(int handlePresentation) { + mHandlePresentation = handlePresentation; + return this; + } + + public ParcelableCallBuilder setCallerDisplayName(String callerDisplayName) { + mCallerDisplayName = callerDisplayName; + return this; + } + + public ParcelableCallBuilder setCallerDisplayNamePresentation( + int callerDisplayNamePresentation) { + mCallerDisplayNamePresentation = callerDisplayNamePresentation; + return this; + } + + public ParcelableCallBuilder setGatewayInfo(GatewayInfo gatewayInfo) { + mGatewayInfo = gatewayInfo; + return this; + } + + public ParcelableCallBuilder setAccountHandle(PhoneAccountHandle accountHandle) { + mAccountHandle = accountHandle; + return this; + } + + public ParcelableCallBuilder setIsVideoCallProviderChanged( + boolean isVideoCallProviderChanged) { + mIsVideoCallProviderChanged = isVideoCallProviderChanged; + return this; + } + + public ParcelableCallBuilder setVideoCallProvider(IVideoProvider videoCallProvider) { + mVideoCallProvider = videoCallProvider; + return this; + } + + public ParcelableCallBuilder setIsRttCallChanged(boolean isRttCallChanged) { + mIsRttCallChanged = isRttCallChanged; + return this; + } + + public ParcelableCallBuilder setRttCall(ParcelableRttCall rttCall) { + mRttCall = rttCall; + return this; + } + + public ParcelableCallBuilder setParentCallId(String parentCallId) { + mParentCallId = parentCallId; + return this; + } + + public ParcelableCallBuilder setChildCallIds(List<String> childCallIds) { + mChildCallIds = childCallIds; + return this; + } + + public ParcelableCallBuilder setStatusHints(StatusHints statusHints) { + mStatusHints = statusHints; + return this; + } + + public ParcelableCallBuilder setVideoState(int videoState) { + mVideoState = videoState; + return this; + } + + public ParcelableCallBuilder setConferenceableCallIds( + List<String> conferenceableCallIds) { + mConferenceableCallIds = conferenceableCallIds; + return this; + } + + public ParcelableCallBuilder setIntentExtras(Bundle intentExtras) { + mIntentExtras = intentExtras; + return this; + } + + public ParcelableCallBuilder setExtras(Bundle extras) { + mExtras = extras; + return this; + } + + public ParcelableCallBuilder setCreationTimeMillis(long creationTimeMillis) { + mCreationTimeMillis = creationTimeMillis; + return this; + } + + public ParcelableCallBuilder setCallDirection(int callDirection) { + mCallDirection = callDirection; + return this; + } + + public ParcelableCallBuilder setCallerNumberVerificationStatus( + int callerNumberVerificationStatus) { + mCallerNumberVerificationStatus = callerNumberVerificationStatus; + return this; + } + + public ParcelableCallBuilder setContactDisplayName(String contactDisplayName) { + mContactDisplayName = contactDisplayName; + return this; + } + + public ParcelableCallBuilder setActiveChildCallId(String activeChildCallId) { + mActiveChildCallId = activeChildCallId; + return this; + } + + public ParcelableCall createParcelableCall() { + return new ParcelableCall( + mId, + mState, + mDisconnectCause, + mCannedSmsResponses, + mCapabilities, + mProperties, + mSupportedAudioRoutes, + mConnectTimeMillis, + mHandle, + mHandlePresentation, + mCallerDisplayName, + mCallerDisplayNamePresentation, + mGatewayInfo, + mAccountHandle, + mIsVideoCallProviderChanged, + mVideoCallProvider, + mIsRttCallChanged, + mRttCall, + mParentCallId, + mChildCallIds, + mStatusHints, + mVideoState, + mConferenceableCallIds, + mIntentExtras, + mExtras, + mCreationTimeMillis, + mCallDirection, + mCallerNumberVerificationStatus, + mContactDisplayName, + mActiveChildCallId); + } + + public static ParcelableCallBuilder fromParcelableCall(ParcelableCall parcelableCall) { + ParcelableCallBuilder newBuilder = new ParcelableCallBuilder(); + newBuilder.mId = parcelableCall.mId; + newBuilder.mState = parcelableCall.mState; + newBuilder.mDisconnectCause = parcelableCall.mDisconnectCause; + newBuilder.mCannedSmsResponses = parcelableCall.mCannedSmsResponses; + newBuilder.mCapabilities = parcelableCall.mCapabilities; + newBuilder.mProperties = parcelableCall.mProperties; + newBuilder.mSupportedAudioRoutes = parcelableCall.mSupportedAudioRoutes; + newBuilder.mConnectTimeMillis = parcelableCall.mConnectTimeMillis; + newBuilder.mHandle = parcelableCall.mHandle; + newBuilder.mHandlePresentation = parcelableCall.mHandlePresentation; + newBuilder.mCallerDisplayName = parcelableCall.mCallerDisplayName; + newBuilder.mCallerDisplayNamePresentation = + parcelableCall.mCallerDisplayNamePresentation; + newBuilder.mGatewayInfo = parcelableCall.mGatewayInfo; + newBuilder.mAccountHandle = parcelableCall.mAccountHandle; + newBuilder.mIsVideoCallProviderChanged = parcelableCall.mIsVideoCallProviderChanged; + newBuilder.mVideoCallProvider = parcelableCall.mVideoCallProvider; + newBuilder.mIsRttCallChanged = parcelableCall.mIsRttCallChanged; + newBuilder.mRttCall = parcelableCall.mRttCall; + newBuilder.mParentCallId = parcelableCall.mParentCallId; + newBuilder.mChildCallIds = parcelableCall.mChildCallIds; + newBuilder.mStatusHints = parcelableCall.mStatusHints; + newBuilder.mVideoState = parcelableCall.mVideoState; + newBuilder.mConferenceableCallIds = parcelableCall.mConferenceableCallIds; + newBuilder.mIntentExtras = parcelableCall.mIntentExtras; + newBuilder.mExtras = parcelableCall.mExtras; + newBuilder.mCreationTimeMillis = parcelableCall.mCreationTimeMillis; + newBuilder.mCallDirection = parcelableCall.mCallDirection; + newBuilder.mCallerNumberVerificationStatus = + parcelableCall.mCallerNumberVerificationStatus; + newBuilder.mContactDisplayName = parcelableCall.mContactDisplayName; + newBuilder.mActiveChildCallId = parcelableCall.mActiveChildCallId; + return newBuilder; + } + } + private final String mId; private final int mState; private final DisconnectCause mDisconnectCause; @@ -66,6 +325,8 @@ public final class ParcelableCall implements Parcelable { private final long mCreationTimeMillis; private final int mCallDirection; private final int mCallerNumberVerificationStatus; + private final String mContactDisplayName; + private final String mActiveChildCallId; // Only valid for CDMA conferences public ParcelableCall( String id, @@ -95,7 +356,10 @@ public final class ParcelableCall implements Parcelable { Bundle extras, long creationTimeMillis, int callDirection, - int callerNumberVerificationStatus) { + int callerNumberVerificationStatus, + String contactDisplayName, + String activeChildCallId + ) { mId = id; mState = state; mDisconnectCause = disconnectCause; @@ -124,6 +388,8 @@ public final class ParcelableCall implements Parcelable { mCreationTimeMillis = creationTimeMillis; mCallDirection = callDirection; mCallerNumberVerificationStatus = callerNumberVerificationStatus; + mContactDisplayName = contactDisplayName; + mActiveChildCallId = activeChildCallId; } /** The unique ID of the call. */ @@ -333,6 +599,21 @@ public final class ParcelableCall implements Parcelable { return mCallerNumberVerificationStatus; } + /** + * @return the name of the remote party as derived from a contacts DB lookup. + */ + public @Nullable String getContactDisplayName() { + return mContactDisplayName; + } + + /** + * @return On a CDMA conference with two participants, returns the ID of the child call that's + * currently active. + */ + public @Nullable String getActiveChildCallId() { + return mActiveChildCallId; + } + /** Responsible for creating ParcelableCall objects for deserialized Parcels. */ @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) public static final @android.annotation.NonNull Parcelable.Creator<ParcelableCall> CREATOR = @@ -372,35 +653,40 @@ public final class ParcelableCall implements Parcelable { long creationTimeMillis = source.readLong(); int callDirection = source.readInt(); int callerNumberVerificationStatus = source.readInt(); - return new ParcelableCall( - id, - state, - disconnectCause, - cannedSmsResponses, - capabilities, - properties, - supportedAudioRoutes, - connectTimeMillis, - handle, - handlePresentation, - callerDisplayName, - callerDisplayNamePresentation, - gatewayInfo, - accountHandle, - isVideoCallProviderChanged, - videoCallProvider, - isRttCallChanged, - rttCall, - parentCallId, - childCallIds, - statusHints, - videoState, - conferenceableCallIds, - intentExtras, - extras, - creationTimeMillis, - callDirection, - callerNumberVerificationStatus); + String contactDisplayName = source.readString(); + String activeChildCallId = source.readString(); + return new ParcelableCallBuilder() + .setId(id) + .setState(state) + .setDisconnectCause(disconnectCause) + .setCannedSmsResponses(cannedSmsResponses) + .setCapabilities(capabilities) + .setProperties(properties) + .setSupportedAudioRoutes(supportedAudioRoutes) + .setConnectTimeMillis(connectTimeMillis) + .setHandle(handle) + .setHandlePresentation(handlePresentation) + .setCallerDisplayName(callerDisplayName) + .setCallerDisplayNamePresentation(callerDisplayNamePresentation) + .setGatewayInfo(gatewayInfo) + .setAccountHandle(accountHandle) + .setIsVideoCallProviderChanged(isVideoCallProviderChanged) + .setVideoCallProvider(videoCallProvider) + .setIsRttCallChanged(isRttCallChanged) + .setRttCall(rttCall) + .setParentCallId(parentCallId) + .setChildCallIds(childCallIds) + .setStatusHints(statusHints) + .setVideoState(videoState) + .setConferenceableCallIds(conferenceableCallIds) + .setIntentExtras(intentExtras) + .setExtras(extras) + .setCreationTimeMillis(creationTimeMillis) + .setCallDirection(callDirection) + .setCallerNumberVerificationStatus(callerNumberVerificationStatus) + .setContactDisplayName(contactDisplayName) + .setActiveChildCallId(activeChildCallId) + .createParcelableCall(); } @Override @@ -447,6 +733,8 @@ public final class ParcelableCall implements Parcelable { destination.writeLong(mCreationTimeMillis); destination.writeInt(mCallDirection); destination.writeInt(mCallerNumberVerificationStatus); + destination.writeString(mContactDisplayName); + destination.writeString(mActiveChildCallId); } @Override diff --git a/telecomm/java/android/telecom/Phone.java b/telecomm/java/android/telecom/Phone.java index 61a639a1a235..a427ed612b31 100644 --- a/telecomm/java/android/telecom/Phone.java +++ b/telecomm/java/android/telecom/Phone.java @@ -17,8 +17,8 @@ package android.telecom; import android.annotation.SystemApi; -import android.annotation.UnsupportedAppUsage; import android.bluetooth.BluetoothDevice; +import android.compat.annotation.UnsupportedAppUsage; import android.os.Build; import android.os.Bundle; import android.util.ArrayMap; diff --git a/telecomm/java/android/telecom/PhoneAccountHandle.java b/telecomm/java/android/telecom/PhoneAccountHandle.java index eb568e04ebf3..e1bcb5fbdf00 100644 --- a/telecomm/java/android/telecom/PhoneAccountHandle.java +++ b/telecomm/java/android/telecom/PhoneAccountHandle.java @@ -18,7 +18,7 @@ package android.telecom; import android.annotation.NonNull; import android.annotation.Nullable; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.ComponentName; import android.os.Build; import android.os.Parcel; diff --git a/telecomm/java/android/telecom/TelecomManager.java b/telecomm/java/android/telecom/TelecomManager.java index af3c55abf00c..9cf4803966c6 100644 --- a/telecomm/java/android/telecom/TelecomManager.java +++ b/telecomm/java/android/telecom/TelecomManager.java @@ -26,7 +26,7 @@ import android.annotation.SuppressLint; import android.annotation.SystemApi; import android.annotation.SystemService; import android.annotation.TestApi; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.ComponentName; import android.content.Context; import android.content.Intent; diff --git a/telecomm/java/android/telecom/VideoCallImpl.java b/telecomm/java/android/telecom/VideoCallImpl.java index 4a1aa0a8ffa4..109e7f829f2e 100644 --- a/telecomm/java/android/telecom/VideoCallImpl.java +++ b/telecomm/java/android/telecom/VideoCallImpl.java @@ -16,7 +16,7 @@ package android.telecom; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.net.Uri; import android.os.Build; import android.os.Handler; diff --git a/telecomm/java/android/telecom/VideoProfile.java b/telecomm/java/android/telecom/VideoProfile.java index 64e6ca3416e3..4197f3cfc6c3 100644 --- a/telecomm/java/android/telecom/VideoProfile.java +++ b/telecomm/java/android/telecom/VideoProfile.java @@ -19,7 +19,6 @@ package android.telecom; import android.annotation.FloatRange; import android.annotation.IntDef; import android.annotation.IntRange; -import android.annotation.UnsupportedAppUsage; import android.os.Parcel; import android.os.Parcelable; diff --git a/telephony/TEST_MAPPING b/telephony/TEST_MAPPING new file mode 100644 index 000000000000..d58566673eec --- /dev/null +++ b/telephony/TEST_MAPPING @@ -0,0 +1,29 @@ +{ + "presubmit": [ + { + "name": "TeleServiceTests", + "options": [ + { + "exclude-annotation": "androidx.test.filters.FlakyTest" + } + ] + }, + { + "name": "TelecomUnitTests", + "options": [ + { + "exclude-annotation": "androidx.test.filters.FlakyTest" + } + ] + }, + { + "name": "TelephonyProviderTests", + "options": [ + { + "exclude-annotation": "androidx.test.filters.FlakyTest" + } + ] + } + ] +} + diff --git a/telephony/common/android/telephony/LocationAccessPolicy.java b/telephony/common/android/telephony/LocationAccessPolicy.java index 825ce2fc1a00..8ac675502527 100644 --- a/telephony/common/android/telephony/LocationAccessPolicy.java +++ b/telephony/common/android/telephony/LocationAccessPolicy.java @@ -18,6 +18,7 @@ package android.telephony; import android.Manifest; import android.annotation.NonNull; +import android.annotation.Nullable; import android.annotation.UserIdInt; import android.app.ActivityManager; import android.app.AppOpsManager; @@ -62,6 +63,7 @@ public final class LocationAccessPolicy { /** Data structure for location permission query */ public static class LocationPermissionQuery { public final String callingPackage; + public final String callingFeatureId; public final int callingUid; public final int callingPid; public final int minSdkVersionForCoarse; @@ -69,10 +71,11 @@ public final class LocationAccessPolicy { public final boolean logAsInfo; public final String method; - private LocationPermissionQuery(String callingPackage, int callingUid, int callingPid, - int minSdkVersionForCoarse, int minSdkVersionForFine, boolean logAsInfo, - String method) { + private LocationPermissionQuery(String callingPackage, @Nullable String callingFeatureId, + int callingUid, int callingPid, int minSdkVersionForCoarse, + int minSdkVersionForFine, boolean logAsInfo, String method) { this.callingPackage = callingPackage; + this.callingFeatureId = callingFeatureId; this.callingUid = callingUid; this.callingPid = callingPid; this.minSdkVersionForCoarse = minSdkVersionForCoarse; @@ -84,6 +87,7 @@ public final class LocationAccessPolicy { /** Builder for LocationPermissionQuery */ public static class Builder { private String mCallingPackage; + private String mCallingFeatureId; private int mCallingUid; private int mCallingPid; private int mMinSdkVersionForCoarse = Integer.MAX_VALUE; @@ -102,6 +106,11 @@ public final class LocationAccessPolicy { /** * Mandatory parameter, used for performing permission checks. */ + public Builder setCallingFeatureId(@Nullable String callingFeatureId) { + mCallingFeatureId = callingFeatureId; + return this; + } + public Builder setCallingUid(int callingUid) { mCallingUid = callingUid; return this; @@ -153,8 +162,8 @@ public final class LocationAccessPolicy { /** build LocationPermissionQuery */ public LocationPermissionQuery build() { - return new LocationPermissionQuery(mCallingPackage, mCallingUid, - mCallingPid, mMinSdkVersionForCoarse, mMinSdkVersionForFine, + return new LocationPermissionQuery(mCallingPackage, mCallingFeatureId, + mCallingUid, mCallingPid, mMinSdkVersionForCoarse, mMinSdkVersionForFine, mLogAsInfo, mMethod); } } diff --git a/telephony/common/com/android/internal/telephony/CarrierAppUtils.java b/telephony/common/com/android/internal/telephony/CarrierAppUtils.java index b5d33699a7f6..3f5aa0f86b75 100644 --- a/telephony/common/com/android/internal/telephony/CarrierAppUtils.java +++ b/telephony/common/com/android/internal/telephony/CarrierAppUtils.java @@ -24,10 +24,10 @@ import android.content.pm.PackageManager; import android.content.res.Resources; import android.os.RemoteException; import android.provider.Settings; +import android.util.Log; import android.telephony.TelephonyManager; import android.util.ArrayMap; import android.util.ArraySet; -import android.util.Slog; import com.android.internal.R; import com.android.internal.annotations.VisibleForTesting; @@ -77,7 +77,7 @@ public final class CarrierAppUtils { IPackageManager packageManager, TelephonyManager telephonyManager, ContentResolver contentResolver, int userId) { if (DEBUG) { - Slog.d(TAG, "disableCarrierAppsUntilPrivileged"); + Log.d(TAG, "disableCarrierAppsUntilPrivileged"); } SystemConfig config = SystemConfig.getInstance(); ArraySet<String> systemCarrierAppsDisabledUntilUsed = @@ -103,7 +103,7 @@ public final class CarrierAppUtils { public static synchronized void disableCarrierAppsUntilPrivileged(String callingPackage, IPackageManager packageManager, ContentResolver contentResolver, int userId) { if (DEBUG) { - Slog.d(TAG, "disableCarrierAppsUntilPrivileged"); + Log.d(TAG, "disableCarrierAppsUntilPrivileged"); } SystemConfig config = SystemConfig.getInstance(); ArraySet<String> systemCarrierAppsDisabledUntilUsed = @@ -174,7 +174,7 @@ public final class CarrierAppUtils { || ai.enabledSetting == PackageManager.COMPONENT_ENABLED_STATE_DISABLED_UNTIL_USED || (ai.flags & ApplicationInfo.FLAG_INSTALLED) == 0)) { - Slog.i(TAG, "Update state(" + packageName + "): ENABLED for user " + Log.i(TAG, "Update state(" + packageName + "): ENABLED for user " + userId); packageManager.setSystemAppInstallState( packageName, @@ -197,7 +197,7 @@ public final class CarrierAppUtils { == PackageManager.COMPONENT_ENABLED_STATE_DISABLED_UNTIL_USED || (associatedApp.flags & ApplicationInfo.FLAG_INSTALLED) == 0) { - Slog.i(TAG, "Update associated state(" + associatedApp.packageName + Log.i(TAG, "Update associated state(" + associatedApp.packageName + "): ENABLED for user " + userId); packageManager.setSystemAppInstallState( associatedApp.packageName, @@ -222,7 +222,7 @@ public final class CarrierAppUtils { && ai.enabledSetting == PackageManager.COMPONENT_ENABLED_STATE_DEFAULT && (ai.flags & ApplicationInfo.FLAG_INSTALLED) != 0) { - Slog.i(TAG, "Update state(" + packageName + Log.i(TAG, "Update state(" + packageName + "): DISABLED_UNTIL_USED for user " + userId); packageManager.setSystemAppInstallState( packageName, @@ -240,7 +240,7 @@ public final class CarrierAppUtils { == PackageManager.COMPONENT_ENABLED_STATE_DEFAULT && (associatedApp.flags & ApplicationInfo.FLAG_INSTALLED) != 0) { - Slog.i(TAG, + Log.i(TAG, "Update associated state(" + associatedApp.packageName + "): DISABLED_UNTIL_USED for user " + userId); packageManager.setSystemAppInstallState( @@ -268,7 +268,7 @@ public final class CarrierAppUtils { packageManager.grantDefaultPermissionsToEnabledCarrierApps(packageNames, userId); } } catch (RemoteException e) { - Slog.w(TAG, "Could not reach PackageManager", e); + Log.w(TAG, "Could not reach PackageManager", e); } } @@ -390,7 +390,7 @@ public final class CarrierAppUtils { return ai; } } catch (RemoteException e) { - Slog.w(TAG, "Could not reach PackageManager", e); + Log.w(TAG, "Could not reach PackageManager", e); } return null; } diff --git a/telephony/common/com/android/internal/telephony/EncodeException.java b/telephony/common/com/android/internal/telephony/EncodeException.java index cdc853e09895..bb723a0f47b3 100644 --- a/telephony/common/com/android/internal/telephony/EncodeException.java +++ b/telephony/common/com/android/internal/telephony/EncodeException.java @@ -16,7 +16,7 @@ package com.android.internal.telephony; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; /** * {@hide} diff --git a/telephony/common/com/android/internal/telephony/GsmAlphabet.java b/telephony/common/com/android/internal/telephony/GsmAlphabet.java index 79d366037f08..60cd40094950 100644 --- a/telephony/common/com/android/internal/telephony/GsmAlphabet.java +++ b/telephony/common/com/android/internal/telephony/GsmAlphabet.java @@ -16,10 +16,10 @@ package com.android.internal.telephony; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.res.Resources; import android.os.Build; -import android.telephony.Rlog; +import android.util.Log; import android.text.TextUtils; import android.util.SparseIntArray; @@ -496,11 +496,11 @@ public class GsmAlphabet { StringBuilder ret = new StringBuilder(lengthSeptets); if (languageTable < 0 || languageTable > sLanguageTables.length) { - Rlog.w(TAG, "unknown language table " + languageTable + ", using default"); + Log.w(TAG, "unknown language table " + languageTable + ", using default"); languageTable = 0; } if (shiftTable < 0 || shiftTable > sLanguageShiftTables.length) { - Rlog.w(TAG, "unknown single shift table " + shiftTable + ", using default"); + Log.w(TAG, "unknown single shift table " + shiftTable + ", using default"); shiftTable = 0; } @@ -510,11 +510,11 @@ public class GsmAlphabet { String shiftTableToChar = sLanguageShiftTables[shiftTable]; if (languageTableToChar.isEmpty()) { - Rlog.w(TAG, "no language table for code " + languageTable + ", using default"); + Log.w(TAG, "no language table for code " + languageTable + ", using default"); languageTableToChar = sLanguageTables[0]; } if (shiftTableToChar.isEmpty()) { - Rlog.w(TAG, "no single shift table for code " + shiftTable + ", using default"); + Log.w(TAG, "no single shift table for code " + shiftTable + ", using default"); shiftTableToChar = sLanguageShiftTables[0]; } @@ -554,7 +554,7 @@ public class GsmAlphabet { } } } catch (RuntimeException ex) { - Rlog.e(TAG, "Error GSM 7 bit packed: ", ex); + Log.e(TAG, "Error GSM 7 bit packed: ", ex); return null; } @@ -811,7 +811,7 @@ public class GsmAlphabet { for (int i = 0; i < sz; i++) { char c = s.charAt(i); if (c == GSM_EXTENDED_ESCAPE) { - Rlog.w(TAG, "countGsmSeptets() string contains Escape character, skipping."); + Log.w(TAG, "countGsmSeptets() string contains Escape character, skipping."); continue; } if (charToLanguageTable.get(c, -1) != -1) { @@ -890,7 +890,7 @@ public class GsmAlphabet { for (int i = 0; i < sz && !lpcList.isEmpty(); i++) { char c = s.charAt(i); if (c == GSM_EXTENDED_ESCAPE) { - Rlog.w(TAG, "countGsmSeptets() string contains Escape character, ignoring!"); + Log.w(TAG, "countGsmSeptets() string contains Escape character, ignoring!"); continue; } // iterate through enabled locking shift tables @@ -1494,7 +1494,7 @@ public class GsmAlphabet { int numTables = sLanguageTables.length; int numShiftTables = sLanguageShiftTables.length; if (numTables != numShiftTables) { - Rlog.e(TAG, "Error: language tables array length " + numTables + + Log.e(TAG, "Error: language tables array length " + numTables + " != shift tables array length " + numShiftTables); } @@ -1504,7 +1504,7 @@ public class GsmAlphabet { int tableLen = table.length(); if (tableLen != 0 && tableLen != 128) { - Rlog.e(TAG, "Error: language tables index " + i + + Log.e(TAG, "Error: language tables index " + i + " length " + tableLen + " (expected 128 or 0)"); } @@ -1522,7 +1522,7 @@ public class GsmAlphabet { int shiftTableLen = shiftTable.length(); if (shiftTableLen != 0 && shiftTableLen != 128) { - Rlog.e(TAG, "Error: language shift tables index " + i + + Log.e(TAG, "Error: language shift tables index " + i + " length " + shiftTableLen + " (expected 128 or 0)"); } diff --git a/telephony/common/com/android/internal/telephony/HbpcdUtils.java b/telephony/common/com/android/internal/telephony/HbpcdUtils.java index 2f3194214be6..714f5a673633 100644 --- a/telephony/common/com/android/internal/telephony/HbpcdUtils.java +++ b/telephony/common/com/android/internal/telephony/HbpcdUtils.java @@ -19,7 +19,7 @@ package com.android.internal.telephony; import android.content.ContentResolver; import android.content.Context; import android.database.Cursor; -import android.telephony.Rlog; +import android.util.Log; import com.android.internal.telephony.HbpcdLookup.ArbitraryMccSidMatch; import com.android.internal.telephony.HbpcdLookup.MccIdd; @@ -54,16 +54,16 @@ public final class HbpcdUtils { if (c2 != null) { int c2Counter = c2.getCount(); if (DBG) { - Rlog.d(LOG_TAG, "Query unresolved arbitrary table, entries are " + c2Counter); + Log.d(LOG_TAG, "Query unresolved arbitrary table, entries are " + c2Counter); } if (c2Counter == 1) { if (DBG) { - Rlog.d(LOG_TAG, "Query Unresolved arbitrary returned the cursor " + c2); + Log.d(LOG_TAG, "Query Unresolved arbitrary returned the cursor " + c2); } c2.moveToFirst(); tmpMcc = c2.getInt(0); if (DBG) { - Rlog.d(LOG_TAG, "MCC found in arbitrary_mcc_sid_match: " + tmpMcc); + Log.d(LOG_TAG, "MCC found in arbitrary_mcc_sid_match: " + tmpMcc); } c2.close(); return tmpMcc; @@ -85,18 +85,18 @@ public final class HbpcdUtils { int c3Counter = c3.getCount(); if (c3Counter > 0) { if (c3Counter > 1) { - Rlog.w(LOG_TAG, "something wrong, get more results for 1 conflict SID: " + c3); + Log.w(LOG_TAG, "something wrong, get more results for 1 conflict SID: " + c3); } - if (DBG) Rlog.d(LOG_TAG, "Query conflict sid returned the cursor " + c3); + if (DBG) Log.d(LOG_TAG, "Query conflict sid returned the cursor " + c3); c3.moveToFirst(); tmpMcc = c3.getInt(0); if (DBG) { - Rlog.d(LOG_TAG, "MCC found in mcc_lookup_table. Return tmpMcc = " + tmpMcc); + Log.d(LOG_TAG, "MCC found in mcc_lookup_table. Return tmpMcc = " + tmpMcc); } if (!isNitzTimeZone) { // time zone is not accurate, it may get wrong mcc, ignore it. if (DBG) { - Rlog.d(LOG_TAG, "time zone is not accurate, mcc may be " + tmpMcc); + Log.d(LOG_TAG, "time zone is not accurate, mcc may be " + tmpMcc); } tmpMcc = 0; } @@ -115,18 +115,18 @@ public final class HbpcdUtils { null, null); if (c5 != null) { if (c5.getCount() > 0) { - if (DBG) Rlog.d(LOG_TAG, "Query Range returned the cursor " + c5); + if (DBG) Log.d(LOG_TAG, "Query Range returned the cursor " + c5); c5.moveToFirst(); tmpMcc = c5.getInt(0); - if (DBG) Rlog.d(LOG_TAG, "SID found in mcc_sid_range. Return tmpMcc = " + tmpMcc); + if (DBG) Log.d(LOG_TAG, "SID found in mcc_sid_range. Return tmpMcc = " + tmpMcc); c5.close(); return tmpMcc; } c5.close(); } - if (DBG) Rlog.d(LOG_TAG, "SID NOT found in mcc_sid_range."); + if (DBG) Log.d(LOG_TAG, "SID NOT found in mcc_sid_range."); - if (DBG) Rlog.d(LOG_TAG, "Exit getMccByOtherFactors. Return tmpMcc = " + tmpMcc); + if (DBG) Log.d(LOG_TAG, "Exit getMccByOtherFactors. Return tmpMcc = " + tmpMcc); // If unknown MCC still could not be resolved, return tmpMcc; } @@ -135,7 +135,7 @@ public final class HbpcdUtils { * Gets country information with given MCC. */ public String getIddByMcc(int mcc) { - if (DBG) Rlog.d(LOG_TAG, "Enter getHbpcdInfoByMCC."); + if (DBG) Log.d(LOG_TAG, "Enter getHbpcdInfoByMCC."); String idd = ""; Cursor c = null; @@ -145,19 +145,19 @@ public final class HbpcdUtils { MccIdd.MCC + "=" + mcc, null, null); if (cur != null) { if (cur.getCount() > 0) { - if (DBG) Rlog.d(LOG_TAG, "Query Idd returned the cursor " + cur); + if (DBG) Log.d(LOG_TAG, "Query Idd returned the cursor " + cur); // TODO: for those country having more than 1 IDDs, need more information // to decide which IDD would be used. currently just use the first 1. cur.moveToFirst(); idd = cur.getString(0); - if (DBG) Rlog.d(LOG_TAG, "IDD = " + idd); + if (DBG) Log.d(LOG_TAG, "IDD = " + idd); } cur.close(); } if (c != null) c.close(); - if (DBG) Rlog.d(LOG_TAG, "Exit getHbpcdInfoByMCC."); + if (DBG) Log.d(LOG_TAG, "Exit getHbpcdInfoByMCC."); return idd; } } diff --git a/telephony/common/com/android/internal/telephony/SmsApplication.java b/telephony/common/com/android/internal/telephony/SmsApplication.java index 53842cdeea5a..3a900d9c224f 100644 --- a/telephony/common/com/android/internal/telephony/SmsApplication.java +++ b/telephony/common/com/android/internal/telephony/SmsApplication.java @@ -20,6 +20,7 @@ import android.Manifest.permission; import android.annotation.Nullable; import android.app.AppOpsManager; import android.app.role.RoleManager; +import android.compat.annotation.UnsupportedAppUsage; import android.content.ComponentName; import android.content.Context; import android.content.Intent; @@ -40,7 +41,7 @@ import android.os.UserHandle; import android.provider.Telephony; import android.provider.Telephony.Sms.Intents; import android.telephony.PackageChangeReceiver; -import android.telephony.Rlog; +import android.util.Log; import android.telephony.TelephonyManager; import android.util.Log; @@ -48,8 +49,6 @@ import com.android.internal.annotations.VisibleForTesting; import com.android.internal.logging.MetricsLogger; import com.android.internal.logging.nano.MetricsProto.MetricsEvent; -import dalvik.annotation.compat.UnsupportedAppUsage; - import java.util.Collection; import java.util.HashMap; import java.util.List; @@ -569,7 +568,7 @@ public final class SmsApplication { int mode = appOps.unsafeCheckOp(opStr, applicationData.mUid, applicationData.mPackageName); if (mode != AppOpsManager.MODE_ALLOWED) { - Rlog.e(LOG_TAG, applicationData.mPackageName + " lost " + Log.e(LOG_TAG, applicationData.mPackageName + " lost " + opStr + ": " + (updateIfNeeded ? " (fixing)" : " (no permission to fix)")); if (updateIfNeeded) { @@ -647,7 +646,7 @@ public final class SmsApplication { int uid = packageManager.getPackageInfo(oldPackageName, 0).applicationInfo.uid; setExclusiveAppops(oldPackageName, appOps, uid, AppOpsManager.MODE_DEFAULT); } catch (NameNotFoundException e) { - Rlog.w(LOG_TAG, "Old SMS package not found: " + oldPackageName); + Log.w(LOG_TAG, "Old SMS package not found: " + oldPackageName); } } @@ -754,7 +753,7 @@ public final class SmsApplication { // the package signature matches system signature. final int result = packageManager.checkSignatures(context.getPackageName(), packageName); if (result != PackageManager.SIGNATURE_MATCH) { - Rlog.e(LOG_TAG, packageName + " does not have system signature"); + Log.e(LOG_TAG, packageName + " does not have system signature"); return; } try { @@ -762,13 +761,13 @@ public final class SmsApplication { int mode = appOps.unsafeCheckOp(AppOpsManager.OPSTR_WRITE_SMS, info.applicationInfo.uid, packageName); if (mode != AppOpsManager.MODE_ALLOWED) { - Rlog.w(LOG_TAG, packageName + " does not have OP_WRITE_SMS: (fixing)"); + Log.w(LOG_TAG, packageName + " does not have OP_WRITE_SMS: (fixing)"); setExclusiveAppops(packageName, appOps, info.applicationInfo.uid, AppOpsManager.MODE_ALLOWED); } } catch (NameNotFoundException e) { // No whitelisted system app on this device - Rlog.e(LOG_TAG, "Package not found: " + packageName); + Log.e(LOG_TAG, "Package not found: " + packageName); } } diff --git a/telephony/common/com/android/internal/telephony/SmsConstants.java b/telephony/common/com/android/internal/telephony/SmsConstants.java index 19f52b0ef429..3aa8bbf607d1 100644 --- a/telephony/common/com/android/internal/telephony/SmsConstants.java +++ b/telephony/common/com/android/internal/telephony/SmsConstants.java @@ -15,7 +15,7 @@ */ package com.android.internal.telephony; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; /** * SMS Constants and must be the same as the corresponding diff --git a/telephony/common/com/android/internal/telephony/SmsNumberUtils.java b/telephony/common/com/android/internal/telephony/SmsNumberUtils.java index 06c08f56aa1f..cd365a113189 100644 --- a/telephony/common/com/android/internal/telephony/SmsNumberUtils.java +++ b/telephony/common/com/android/internal/telephony/SmsNumberUtils.java @@ -24,13 +24,16 @@ import android.os.PersistableBundle; import android.os.SystemProperties; import android.telephony.CarrierConfigManager; import android.telephony.PhoneNumberUtils; -import android.telephony.Rlog; import android.telephony.TelephonyManager; import android.text.TextUtils; +import android.util.Base64; +import android.util.Log; import com.android.internal.telephony.HbpcdLookup.MccIdd; import com.android.internal.telephony.HbpcdLookup.MccLookup; +import java.security.MessageDigest; +import java.security.NoSuchAlgorithmException; import java.util.ArrayList; import java.util.HashMap; @@ -143,7 +146,7 @@ public class SmsNumberUtils { // First check whether the number is a NANP number. int nanpState = checkNANP(numberEntry, allIDDs); - if (DBG) Rlog.d(TAG, "NANP type: " + getNumberPlanType(nanpState)); + if (DBG) Log.d(TAG, "NANP type: " + getNumberPlanType(nanpState)); if ((nanpState == NP_NANP_LOCAL) || (nanpState == NP_NANP_AREA_LOCAL) @@ -173,7 +176,7 @@ public class SmsNumberUtils { int internationalState = checkInternationalNumberPlan(context, numberEntry, allIDDs, NANP_IDD); - if (DBG) Rlog.d(TAG, "International type: " + getNumberPlanType(internationalState)); + if (DBG) Log.d(TAG, "International type: " + getNumberPlanType(internationalState)); String returnNumber = null; switch (internationalState) { @@ -272,7 +275,7 @@ public class SmsNumberUtils { } } } catch (SQLException e) { - Rlog.e(TAG, "Can't access HbpcdLookup database", e); + Log.e(TAG, "Can't access HbpcdLookup database", e); } finally { if (cursor != null) { cursor.close(); @@ -281,7 +284,7 @@ public class SmsNumberUtils { IDDS_MAPS.put(mcc, allIDDs); - if (DBG) Rlog.d(TAG, "MCC = " + mcc + ", all IDDs = " + allIDDs); + if (DBG) Log.d(TAG, "MCC = " + mcc + ", all IDDs = " + allIDDs); return allIDDs; } @@ -472,7 +475,7 @@ public class SmsNumberUtils { int tempCC = allCCs[i]; for (int j = 0; j < MAX_COUNTRY_CODES_LENGTH; j ++) { if (tempCC == ccArray[j]) { - if (DBG) Rlog.d(TAG, "Country code = " + tempCC); + if (DBG) Log.d(TAG, "Country code = " + tempCC); return tempCC; } } @@ -509,7 +512,7 @@ public class SmsNumberUtils { } } } catch (SQLException e) { - Rlog.e(TAG, "Can't access HbpcdLookup database", e); + Log.e(TAG, "Can't access HbpcdLookup database", e); } finally { if (cursor != null) { cursor.close(); @@ -561,10 +564,10 @@ public class SmsNumberUtils { * Filter the destination number if using VZW sim card. */ public static String filterDestAddr(Context context, int subId, String destAddr) { - if (DBG) Rlog.d(TAG, "enter filterDestAddr. destAddr=\"" + Rlog.pii(TAG, destAddr) + "\"" ); + if (DBG) Log.d(TAG, "enter filterDestAddr. destAddr=\"" + pii(TAG, destAddr) + "\"" ); if (destAddr == null || !PhoneNumberUtils.isGlobalPhoneNumber(destAddr)) { - Rlog.w(TAG, "destAddr" + Rlog.pii(TAG, destAddr) + + Log.w(TAG, "destAddr" + pii(TAG, destAddr) + " is not a global phone number! Nothing changed."); return destAddr; } @@ -585,9 +588,9 @@ public class SmsNumberUtils { } if (DBG) { - Rlog.d(TAG, "destAddr is " + ((result != null)?"formatted.":"not formatted.")); - Rlog.d(TAG, "leave filterDestAddr, new destAddr=\"" + (result != null ? Rlog.pii(TAG, - result) : Rlog.pii(TAG, destAddr)) + "\""); + Log.d(TAG, "destAddr is " + ((result != null)?"formatted.":"not formatted.")); + Log.d(TAG, "leave filterDestAddr, new destAddr=\"" + (result != null ? pii(TAG, + result) : pii(TAG, destAddr)) + "\""); } return result != null ? result : destAddr; } @@ -608,7 +611,7 @@ public class SmsNumberUtils { networkType = CDMA_HOME_NETWORK; } } else { - if (DBG) Rlog.w(TAG, "warning! unknown mPhoneType value=" + phoneType); + if (DBG) Log.w(TAG, "warning! unknown mPhoneType value=" + phoneType); } return networkType; @@ -650,4 +653,44 @@ public class SmsNumberUtils { // by default this value is false return false; } + + /** + * Redact personally identifiable information for production users. + * @param tag used to identify the source of a log message + * @param pii the personally identifiable information we want to apply secure hash on. + * @return If tag is loggable in verbose mode or pii is null, return the original input. + * otherwise return a secure Hash of input pii + */ + private static String pii(String tag, Object pii) { + String val = String.valueOf(pii); + if (pii == null || TextUtils.isEmpty(val) || Log.isLoggable(tag, Log.VERBOSE)) { + return val; + } + return "[" + secureHash(val.getBytes()) + "]"; + } + + /** + * Returns a secure hash (using the SHA1 algorithm) of the provided input. + * + * @return "****" if the build type is user, otherwise the hash + * @param input the bytes for which the secure hash should be computed. + */ + private static String secureHash(byte[] input) { + // Refrain from logging user personal information in user build. + if (android.os.Build.IS_USER) { + return "****"; + } + + MessageDigest messageDigest; + + try { + messageDigest = MessageDigest.getInstance("SHA-1"); + } catch (NoSuchAlgorithmException e) { + return "####"; + } + + byte[] result = messageDigest.digest(input); + return Base64.encodeToString( + result, Base64.URL_SAFE | Base64.NO_PADDING | Base64.NO_WRAP); + } } diff --git a/telephony/common/com/android/internal/telephony/TelephonyPermissions.java b/telephony/common/com/android/internal/telephony/TelephonyPermissions.java index 606fd5b89791..c8e2b8962072 100644 --- a/telephony/common/com/android/internal/telephony/TelephonyPermissions.java +++ b/telephony/common/com/android/internal/telephony/TelephonyPermissions.java @@ -18,6 +18,7 @@ package com.android.internal.telephony; import static android.content.pm.PackageManager.PERMISSION_GRANTED; import android.Manifest; +import android.annotation.Nullable; import android.app.AppOpsManager; import android.app.admin.DevicePolicyManager; import android.content.Context; @@ -26,10 +27,7 @@ import android.content.pm.PackageManager; import android.os.Binder; import android.os.Build; import android.os.Process; -import android.os.RemoteException; -import android.os.ServiceManager; import android.os.UserHandle; -import android.telephony.Rlog; import android.telephony.SubscriptionManager; import android.telephony.TelephonyManager; import android.util.Log; @@ -41,7 +39,6 @@ import java.util.HashMap; import java.util.HashSet; import java.util.Map; import java.util.Set; -import java.util.function.Supplier; /** Utility class for Telephony permission enforcement. */ public final class TelephonyPermissions { @@ -49,9 +46,6 @@ public final class TelephonyPermissions { private static final boolean DBG = false; - private static final Supplier<ITelephony> TELEPHONY_SUPPLIER = () -> - ITelephony.Stub.asInterface(ServiceManager.getService(Context.TELEPHONY_SERVICE)); - /** * Whether to disable the new device identifier access restrictions. */ @@ -95,16 +89,19 @@ public final class TelephonyPermissions { * inaccesible to carrier-privileged apps). */ public static boolean checkCallingOrSelfReadPhoneState( - Context context, int subId, String callingPackage, String message) { + Context context, int subId, String callingPackage, @Nullable String callingFeatureId, + String message) { return checkReadPhoneState(context, subId, Binder.getCallingPid(), Binder.getCallingUid(), - callingPackage, message); + callingPackage, callingFeatureId, message); } /** Identical to checkCallingOrSelfReadPhoneState but never throws SecurityException */ public static boolean checkCallingOrSelfReadPhoneStateNoThrow( - Context context, int subId, String callingPackage, String message) { + Context context, int subId, String callingPackage, @Nullable String callingFeatureId, + String message) { try { - return checkCallingOrSelfReadPhoneState(context, subId, callingPackage, message); + return checkCallingOrSelfReadPhoneState(context, subId, callingPackage, + callingFeatureId, message); } catch (SecurityException se) { return false; } @@ -132,49 +129,8 @@ public final class TelephonyPermissions { * devices. */ public static boolean checkReadPhoneState( - Context context, int subId, int pid, int uid, String callingPackage, String message) { - return checkReadPhoneState( - context, TELEPHONY_SUPPLIER, subId, pid, uid, callingPackage, message); - } - - /** - * Check whether the calling packages has carrier privileges for the passing subscription. - * @return {@code true} if the caller has carrier privileges, {@false} otherwise. - */ - public static boolean checkCarrierPrivilegeForSubId(int subId) { - if (SubscriptionManager.isValidSubscriptionId(subId) - && getCarrierPrivilegeStatus(TELEPHONY_SUPPLIER, subId, Binder.getCallingUid()) - == TelephonyManager.CARRIER_PRIVILEGE_STATUS_HAS_ACCESS) { - return true; - } - return false; - } - - /** - * Check whether the app with the given pid/uid can read phone state. - * - * <p>This method behaves in one of the following ways: - * <ul> - * <li>return true: if the caller has the READ_PRIVILEGED_PHONE_STATE permission, the - * READ_PHONE_STATE runtime permission, or carrier privileges on the given subId. - * <li>throw SecurityException: if the caller didn't declare any of these permissions, or, for - * apps which support runtime permissions, if the caller does not currently have any of - * these permissions. - * <li>return false: if the caller lacks all of these permissions and doesn't support runtime - * permissions. This implies that the user revoked the ability to read phone state - * manually (via AppOps). In this case we can't throw as it would break app compatibility, - * so we return false to indicate that the calling function should return dummy data. - * </ul> - * - * <p>Note: for simplicity, this method always returns false for callers using legacy - * permissions and who have had READ_PHONE_STATE revoked, even if they are carrier-privileged. - * Such apps should migrate to runtime permissions or stop requiring READ_PHONE_STATE on P+ - * devices. - */ - @VisibleForTesting - public static boolean checkReadPhoneState( - Context context, Supplier<ITelephony> telephonySupplier, int subId, int pid, int uid, - String callingPackage, String message) { + Context context, int subId, int pid, int uid, String callingPackage, + @Nullable String callingFeatureId, String message) { try { context.enforcePermission( android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE, pid, uid, message); @@ -189,7 +145,7 @@ public final class TelephonyPermissions { // If we don't have the runtime permission, but do have carrier privileges, that // suffices for reading phone state. if (SubscriptionManager.isValidSubscriptionId(subId)) { - enforceCarrierPrivilege(telephonySupplier, subId, uid, message); + enforceCarrierPrivilege(context, subId, uid, message); return true; } throw phoneStateException; @@ -204,23 +160,16 @@ public final class TelephonyPermissions { } /** - * Check whether the app with the given pid/uid can read phone state, or has carrier - * privileges on any active subscription. - * - * <p>If the app does not have carrier privilege, this method will return {@code false} instead - * of throwing a SecurityException. Therefore, the callers cannot tell the difference - * between M+ apps which declare the runtime permission but do not have it, and pre-M apps - * which declare the static permission but had access revoked via AppOps. Apps in the former - * category expect SecurityExceptions; apps in the latter don't. So this method is suitable for - * use only if the behavior in both scenarios is meant to be identical. - * - * @return {@code true} if the app can read phone state or has carrier privilege; - * {@code false} otherwise. + * Check whether the calling packages has carrier privileges for the passing subscription. + * @return {@code true} if the caller has carrier privileges, {@false} otherwise. */ - public static boolean checkReadPhoneStateOnAnyActiveSub( - Context context, int pid, int uid, String callingPackage, String message) { - return checkReadPhoneStateOnAnyActiveSub(context, TELEPHONY_SUPPLIER, pid, uid, - callingPackage, message); + public static boolean checkCarrierPrivilegeForSubId(Context context, int subId) { + if (SubscriptionManager.isValidSubscriptionId(subId) + && getCarrierPrivilegeStatus(context, subId, Binder.getCallingUid()) + == TelephonyManager.CARRIER_PRIVILEGE_STATUS_HAS_ACCESS) { + return true; + } + return false; } /** @@ -237,10 +186,8 @@ public final class TelephonyPermissions { * @return {@code true} if the app can read phone state or has carrier privilege; * {@code false} otherwise. */ - @VisibleForTesting - public static boolean checkReadPhoneStateOnAnyActiveSub( - Context context, Supplier<ITelephony> telephonySupplier, int pid, int uid, - String callingPackage, String message) { + public static boolean checkReadPhoneStateOnAnyActiveSub(Context context, int pid, int uid, + String callingPackage, @Nullable String callingFeatureId, String message) { try { context.enforcePermission( android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE, pid, uid, message); @@ -254,7 +201,7 @@ public final class TelephonyPermissions { } catch (SecurityException phoneStateException) { // If we don't have the runtime permission, but do have carrier privileges, that // suffices for reading phone state. - return checkCarrierPrivilegeForAnySubId(context, telephonySupplier, uid); + return checkCarrierPrivilegeForAnySubId(context, uid); } } @@ -283,9 +230,10 @@ public final class TelephonyPermissions { * </ul> */ public static boolean checkCallingOrSelfReadDeviceIdentifiers(Context context, - String callingPackage, String message) { + String callingPackage, @Nullable String callingFeatureId, String message) { return checkCallingOrSelfReadDeviceIdentifiers(context, - SubscriptionManager.INVALID_SUBSCRIPTION_ID, callingPackage, message); + SubscriptionManager.INVALID_SUBSCRIPTION_ID, callingPackage, callingFeatureId, + message); } /** @@ -306,9 +254,9 @@ public final class TelephonyPermissions { * </ul> */ public static boolean checkCallingOrSelfReadDeviceIdentifiers(Context context, int subId, - String callingPackage, String message) { + String callingPackage, @Nullable String callingFeatureId, String message) { return checkPrivilegedReadPermissionOrCarrierPrivilegePermission( - context, subId, callingPackage, message, true); + context, subId, callingPackage, callingFeatureId, message, true); } /** @@ -328,9 +276,9 @@ public final class TelephonyPermissions { * </ul> */ public static boolean checkCallingOrSelfReadSubscriberIdentifiers(Context context, int subId, - String callingPackage, String message) { + String callingPackage, @Nullable String callingFeatureId, String message) { return checkPrivilegedReadPermissionOrCarrierPrivilegePermission( - context, subId, callingPackage, message, false); + context, subId, callingPackage, callingFeatureId, message, false); } /** @@ -352,8 +300,8 @@ public final class TelephonyPermissions { * </ul> */ private static boolean checkPrivilegedReadPermissionOrCarrierPrivilegePermission( - Context context, int subId, String callingPackage, String message, - boolean allowCarrierPrivilegeOnAnySub) { + Context context, int subId, String callingPackage, @Nullable String callingFeatureId, + String message, boolean allowCarrierPrivilegeOnAnySub) { int uid = Binder.getCallingUid(); int pid = Binder.getCallingPid(); // Allow system and root access to the device identifiers. @@ -368,12 +316,11 @@ public final class TelephonyPermissions { } // If the calling package has carrier privileges for specified sub, then allow access. - if (checkCarrierPrivilegeForSubId(subId)) return true; + if (checkCarrierPrivilegeForSubId(context, subId)) return true; // If the calling package has carrier privileges for any subscription // and allowCarrierPrivilegeOnAnySub is set true, then allow access. - if (allowCarrierPrivilegeOnAnySub && checkCarrierPrivilegeForAnySubId( - context, TELEPHONY_SUPPLIER, uid)) { + if (allowCarrierPrivilegeOnAnySub && checkCarrierPrivilegeForAnySubId(context, uid)) { return true; } @@ -465,7 +412,7 @@ public final class TelephonyPermissions { uid) == PackageManager.PERMISSION_GRANTED) { return false; } - if (checkCarrierPrivilegeForSubId(subId)) { + if (checkCarrierPrivilegeForSubId(context, subId)) { return false; } } @@ -479,27 +426,14 @@ public final class TelephonyPermissions { * to it, {@code false} otherwise. */ public static boolean checkReadCallLog( - Context context, int subId, int pid, int uid, String callingPackage) { - return checkReadCallLog( - context, TELEPHONY_SUPPLIER, subId, pid, uid, callingPackage); - } - - /** - * Check whether the app with the given pid/uid can read the call log. - * @return {@code true} if the specified app has the read call log permission and AppOpp granted - * to it, {@code false} otherwise. - */ - @VisibleForTesting - public static boolean checkReadCallLog( - Context context, Supplier<ITelephony> telephonySupplier, int subId, int pid, int uid, - String callingPackage) { - + Context context, int subId, int pid, int uid, String callingPackage, + @Nullable String callingPackageName) { if (context.checkPermission(Manifest.permission.READ_CALL_LOG, pid, uid) != PERMISSION_GRANTED) { // If we don't have the runtime permission, but do have carrier privileges, that // suffices for being able to see the call phone numbers. if (SubscriptionManager.isValidSubscriptionId(subId)) { - enforceCarrierPrivilege(telephonySupplier, subId, uid, "readCallLog"); + enforceCarrierPrivilege(context, subId, uid, "readCallLog"); return true; } return false; @@ -519,10 +453,11 @@ public final class TelephonyPermissions { * default SMS app and apps with READ_SMS or READ_PHONE_NUMBERS can also read phone numbers. */ public static boolean checkCallingOrSelfReadPhoneNumber( - Context context, int subId, String callingPackage, String message) { + Context context, int subId, String callingPackage, @Nullable String callingFeatureId, + String message) { return checkReadPhoneNumber( - context, TELEPHONY_SUPPLIER, subId, Binder.getCallingPid(), Binder.getCallingUid(), - callingPackage, message); + context, subId, Binder.getCallingPid(), Binder.getCallingUid(), + callingPackage, callingFeatureId, message); } /** @@ -533,8 +468,8 @@ public final class TelephonyPermissions { */ @VisibleForTesting public static boolean checkReadPhoneNumber( - Context context, Supplier<ITelephony> telephonySupplier, int subId, int pid, int uid, - String callingPackage, String message) { + Context context, int subId, int pid, int uid, + String callingPackage, @Nullable String callingFeatureId, String message) { // Default SMS app can always read it. AppOpsManager appOps = (AppOpsManager) context.getSystemService(Context.APP_OPS_SERVICE); if (appOps.noteOp(AppOpsManager.OPSTR_WRITE_SMS, uid, callingPackage) == @@ -548,7 +483,8 @@ public final class TelephonyPermissions { // First, check if we can read the phone state. try { return checkReadPhoneState( - context, telephonySupplier, subId, pid, uid, callingPackage, message); + context, subId, pid, uid, callingPackage, callingFeatureId, + message); } catch (SecurityException readPhoneStateSecurityException) { } // Can be read with READ_SMS too. @@ -588,8 +524,8 @@ public final class TelephonyPermissions { return; } - if (DBG) Rlog.d(LOG_TAG, "No modify permission, check carrier privilege next."); - enforceCallingOrSelfCarrierPrivilege(subId, message); + if (DBG) Log.d(LOG_TAG, "No modify permission, check carrier privilege next."); + enforceCallingOrSelfCarrierPrivilege(context, subId, message); } /** @@ -606,10 +542,10 @@ public final class TelephonyPermissions { } if (DBG) { - Rlog.d(LOG_TAG, "No READ_PHONE_STATE permission, check carrier privilege next."); + Log.d(LOG_TAG, "No READ_PHONE_STATE permission, check carrier privilege next."); } - enforceCallingOrSelfCarrierPrivilege(subId, message); + enforceCallingOrSelfCarrierPrivilege(context, subId, message); } /** @@ -626,11 +562,11 @@ public final class TelephonyPermissions { } if (DBG) { - Rlog.d(LOG_TAG, "No READ_PRIVILEDED_PHONE_STATE permission, " + Log.d(LOG_TAG, "No READ_PRIVILEDED_PHONE_STATE permission, " + "check carrier privilege next."); } - enforceCallingOrSelfCarrierPrivilege(subId, message); + enforceCallingOrSelfCarrierPrivilege(context, subId, message); } /** @@ -638,35 +574,31 @@ public final class TelephonyPermissions { * * @throws SecurityException if the caller does not have the required privileges */ - public static void enforceCallingOrSelfCarrierPrivilege(int subId, String message) { + public static void enforceCallingOrSelfCarrierPrivilege( + Context context, int subId, String message) { // NOTE: It's critical that we explicitly pass the calling UID here rather than call // TelephonyManager#hasCarrierPrivileges directly, as the latter only works when called from // the phone process. When called from another process, it will check whether that process // has carrier privileges instead. - enforceCarrierPrivilege(subId, Binder.getCallingUid(), message); - } - - private static void enforceCarrierPrivilege(int subId, int uid, String message) { - enforceCarrierPrivilege(TELEPHONY_SUPPLIER, subId, uid, message); + enforceCarrierPrivilege(context, subId, Binder.getCallingUid(), message); } private static void enforceCarrierPrivilege( - Supplier<ITelephony> telephonySupplier, int subId, int uid, String message) { - if (getCarrierPrivilegeStatus(telephonySupplier, subId, uid) + Context context, int subId, int uid, String message) { + if (getCarrierPrivilegeStatus(context, subId, uid) != TelephonyManager.CARRIER_PRIVILEGE_STATUS_HAS_ACCESS) { - if (DBG) Rlog.e(LOG_TAG, "No Carrier Privilege."); + if (DBG) Log.e(LOG_TAG, "No Carrier Privilege."); throw new SecurityException(message); } } /** Returns whether the provided uid has carrier privileges for any active subscription ID. */ - private static boolean checkCarrierPrivilegeForAnySubId( - Context context, Supplier<ITelephony> telephonySupplier, int uid) { + private static boolean checkCarrierPrivilegeForAnySubId(Context context, int uid) { SubscriptionManager sm = (SubscriptionManager) context.getSystemService( Context.TELEPHONY_SUBSCRIPTION_SERVICE); int[] activeSubIds = sm.getActiveSubscriptionIdList(/* visibleOnly */ false); for (int activeSubId : activeSubIds) { - if (getCarrierPrivilegeStatus(telephonySupplier, activeSubId, uid) + if (getCarrierPrivilegeStatus(context, activeSubId, uid) == TelephonyManager.CARRIER_PRIVILEGE_STATUS_HAS_ACCESS) { return true; } @@ -674,18 +606,15 @@ public final class TelephonyPermissions { return false; } - private static int getCarrierPrivilegeStatus( - Supplier<ITelephony> telephonySupplier, int subId, int uid) { - ITelephony telephony = telephonySupplier.get(); + private static int getCarrierPrivilegeStatus(Context context, int subId, int uid) { + final long identity = Binder.clearCallingIdentity(); try { - if (telephony != null) { - return telephony.getCarrierPrivilegeStatusForUid(subId, uid); - } - } catch (RemoteException e) { - // Fallback below. + TelephonyManager telephonyManager = (TelephonyManager) context.getSystemService( + Context.TELEPHONY_SERVICE); + return telephonyManager.createForSubscriptionId(subId).getCarrierPrivilegeStatus(uid); + } finally { + Binder.restoreCallingIdentity(identity); } - Rlog.e(LOG_TAG, "Phone process is down, cannot check carrier privileges"); - return TelephonyManager.CARRIER_PRIVILEGE_STATUS_NO_ACCESS; } /** diff --git a/telephony/java/com/android/internal/telephony/util/TelephonyUtils.java b/telephony/common/com/android/internal/telephony/util/TelephonyUtils.java index 0498d7c31406..0498d7c31406 100644 --- a/telephony/java/com/android/internal/telephony/util/TelephonyUtils.java +++ b/telephony/common/com/android/internal/telephony/util/TelephonyUtils.java diff --git a/telephony/common/com/google/android/mms/ContentType.java b/telephony/common/com/google/android/mms/ContentType.java index 12e4b7e26e1e..4a971dd34c8f 100644 --- a/telephony/common/com/google/android/mms/ContentType.java +++ b/telephony/common/com/google/android/mms/ContentType.java @@ -17,7 +17,7 @@ package com.google.android.mms; -import dalvik.annotation.compat.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import java.util.ArrayList; diff --git a/telephony/common/com/google/android/mms/InvalidHeaderValueException.java b/telephony/common/com/google/android/mms/InvalidHeaderValueException.java index 2836c3075b3b..55087ff0fb1d 100644 --- a/telephony/common/com/google/android/mms/InvalidHeaderValueException.java +++ b/telephony/common/com/google/android/mms/InvalidHeaderValueException.java @@ -17,7 +17,7 @@ package com.google.android.mms; -import dalvik.annotation.compat.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; /** * Thrown when an invalid header value was set. diff --git a/telephony/common/com/google/android/mms/MmsException.java b/telephony/common/com/google/android/mms/MmsException.java index 5be33ed1fac9..24bceb37f590 100644 --- a/telephony/common/com/google/android/mms/MmsException.java +++ b/telephony/common/com/google/android/mms/MmsException.java @@ -17,7 +17,7 @@ package com.google.android.mms; -import dalvik.annotation.compat.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; /** * A generic exception that is thrown by the Mms client. diff --git a/telephony/common/com/google/android/mms/pdu/AcknowledgeInd.java b/telephony/common/com/google/android/mms/pdu/AcknowledgeInd.java index ae447d7a7417..8693385bb032 100644 --- a/telephony/common/com/google/android/mms/pdu/AcknowledgeInd.java +++ b/telephony/common/com/google/android/mms/pdu/AcknowledgeInd.java @@ -17,7 +17,7 @@ package com.google.android.mms.pdu; -import dalvik.annotation.compat.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import com.google.android.mms.InvalidHeaderValueException; diff --git a/telephony/common/com/google/android/mms/pdu/Base64.java b/telephony/common/com/google/android/mms/pdu/Base64.java index 483fa7f9842e..0d6a46a59fcc 100644 --- a/telephony/common/com/google/android/mms/pdu/Base64.java +++ b/telephony/common/com/google/android/mms/pdu/Base64.java @@ -17,7 +17,7 @@ package com.google.android.mms.pdu; -import dalvik.annotation.compat.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; public class Base64 { /** diff --git a/telephony/common/com/google/android/mms/pdu/CharacterSets.java b/telephony/common/com/google/android/mms/pdu/CharacterSets.java index 27da35e2d928..5172b7b67f88 100644 --- a/telephony/common/com/google/android/mms/pdu/CharacterSets.java +++ b/telephony/common/com/google/android/mms/pdu/CharacterSets.java @@ -17,7 +17,7 @@ package com.google.android.mms.pdu; -import dalvik.annotation.compat.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import java.io.UnsupportedEncodingException; import java.util.HashMap; diff --git a/telephony/common/com/google/android/mms/pdu/DeliveryInd.java b/telephony/common/com/google/android/mms/pdu/DeliveryInd.java index 7093ac63338c..8fb6a7545abf 100644 --- a/telephony/common/com/google/android/mms/pdu/DeliveryInd.java +++ b/telephony/common/com/google/android/mms/pdu/DeliveryInd.java @@ -17,7 +17,7 @@ package com.google.android.mms.pdu; -import dalvik.annotation.compat.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import com.google.android.mms.InvalidHeaderValueException; diff --git a/telephony/common/com/google/android/mms/pdu/EncodedStringValue.java b/telephony/common/com/google/android/mms/pdu/EncodedStringValue.java index 41662750842f..8c0380f77cdd 100644 --- a/telephony/common/com/google/android/mms/pdu/EncodedStringValue.java +++ b/telephony/common/com/google/android/mms/pdu/EncodedStringValue.java @@ -17,10 +17,9 @@ package com.google.android.mms.pdu; +import android.compat.annotation.UnsupportedAppUsage; import android.util.Log; -import dalvik.annotation.compat.UnsupportedAppUsage; - import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.UnsupportedEncodingException; diff --git a/telephony/common/com/google/android/mms/pdu/GenericPdu.java b/telephony/common/com/google/android/mms/pdu/GenericPdu.java index ebf16ac7e632..320b13ffed2b 100644 --- a/telephony/common/com/google/android/mms/pdu/GenericPdu.java +++ b/telephony/common/com/google/android/mms/pdu/GenericPdu.java @@ -17,7 +17,7 @@ package com.google.android.mms.pdu; -import dalvik.annotation.compat.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import com.google.android.mms.InvalidHeaderValueException; diff --git a/telephony/common/com/google/android/mms/pdu/MultimediaMessagePdu.java b/telephony/common/com/google/android/mms/pdu/MultimediaMessagePdu.java index e108f7600baf..42a89c69e873 100644 --- a/telephony/common/com/google/android/mms/pdu/MultimediaMessagePdu.java +++ b/telephony/common/com/google/android/mms/pdu/MultimediaMessagePdu.java @@ -17,7 +17,7 @@ package com.google.android.mms.pdu; -import dalvik.annotation.compat.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import com.google.android.mms.InvalidHeaderValueException; diff --git a/telephony/common/com/google/android/mms/pdu/NotificationInd.java b/telephony/common/com/google/android/mms/pdu/NotificationInd.java index b561bd4ab3a7..ca4615c2e9fe 100644 --- a/telephony/common/com/google/android/mms/pdu/NotificationInd.java +++ b/telephony/common/com/google/android/mms/pdu/NotificationInd.java @@ -17,7 +17,7 @@ package com.google.android.mms.pdu; -import dalvik.annotation.compat.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import com.google.android.mms.InvalidHeaderValueException; diff --git a/telephony/common/com/google/android/mms/pdu/NotifyRespInd.java b/telephony/common/com/google/android/mms/pdu/NotifyRespInd.java index 3c70f86a0890..ebd81afc0173 100644 --- a/telephony/common/com/google/android/mms/pdu/NotifyRespInd.java +++ b/telephony/common/com/google/android/mms/pdu/NotifyRespInd.java @@ -17,7 +17,7 @@ package com.google.android.mms.pdu; -import dalvik.annotation.compat.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import com.google.android.mms.InvalidHeaderValueException; diff --git a/telephony/common/com/google/android/mms/pdu/PduBody.java b/telephony/common/com/google/android/mms/pdu/PduBody.java index 51914e4110b0..f7f285f653b9 100644 --- a/telephony/common/com/google/android/mms/pdu/PduBody.java +++ b/telephony/common/com/google/android/mms/pdu/PduBody.java @@ -17,7 +17,7 @@ package com.google.android.mms.pdu; -import dalvik.annotation.compat.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import java.util.HashMap; import java.util.Map; diff --git a/telephony/common/com/google/android/mms/pdu/PduComposer.java b/telephony/common/com/google/android/mms/pdu/PduComposer.java index e24bf21a11b5..b8b212c493aa 100644 --- a/telephony/common/com/google/android/mms/pdu/PduComposer.java +++ b/telephony/common/com/google/android/mms/pdu/PduComposer.java @@ -17,12 +17,11 @@ package com.google.android.mms.pdu; +import android.compat.annotation.UnsupportedAppUsage; import android.content.ContentResolver; import android.content.Context; import android.text.TextUtils; -import dalvik.annotation.compat.UnsupportedAppUsage; - import java.io.ByteArrayOutputStream; import java.io.FileNotFoundException; import java.io.IOException; diff --git a/telephony/common/com/google/android/mms/pdu/PduContentTypes.java b/telephony/common/com/google/android/mms/pdu/PduContentTypes.java index 8551b2f9b693..57141fedf1e0 100644 --- a/telephony/common/com/google/android/mms/pdu/PduContentTypes.java +++ b/telephony/common/com/google/android/mms/pdu/PduContentTypes.java @@ -17,7 +17,7 @@ package com.google.android.mms.pdu; -import dalvik.annotation.compat.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; public class PduContentTypes { /** diff --git a/telephony/common/com/google/android/mms/pdu/PduHeaders.java b/telephony/common/com/google/android/mms/pdu/PduHeaders.java index b5244645fda1..3e6218480dc5 100644 --- a/telephony/common/com/google/android/mms/pdu/PduHeaders.java +++ b/telephony/common/com/google/android/mms/pdu/PduHeaders.java @@ -17,7 +17,7 @@ package com.google.android.mms.pdu; -import dalvik.annotation.compat.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import com.google.android.mms.InvalidHeaderValueException; diff --git a/telephony/common/com/google/android/mms/pdu/PduParser.java b/telephony/common/com/google/android/mms/pdu/PduParser.java index f48399410723..5340245ae869 100755 --- a/telephony/common/com/google/android/mms/pdu/PduParser.java +++ b/telephony/common/com/google/android/mms/pdu/PduParser.java @@ -17,10 +17,9 @@ package com.google.android.mms.pdu; +import android.compat.annotation.UnsupportedAppUsage; import android.util.Log; -import dalvik.annotation.compat.UnsupportedAppUsage; - import com.google.android.mms.ContentType; import com.google.android.mms.InvalidHeaderValueException; diff --git a/telephony/common/com/google/android/mms/pdu/PduPart.java b/telephony/common/com/google/android/mms/pdu/PduPart.java index 09b775118dc3..8dd976b2569f 100644 --- a/telephony/common/com/google/android/mms/pdu/PduPart.java +++ b/telephony/common/com/google/android/mms/pdu/PduPart.java @@ -17,10 +17,9 @@ package com.google.android.mms.pdu; +import android.compat.annotation.UnsupportedAppUsage; import android.net.Uri; -import dalvik.annotation.compat.UnsupportedAppUsage; - import java.util.HashMap; import java.util.Map; diff --git a/telephony/common/com/google/android/mms/pdu/PduPersister.java b/telephony/common/com/google/android/mms/pdu/PduPersister.java index 8efca0ea3909..fcd5b8ff57a8 100755 --- a/telephony/common/com/google/android/mms/pdu/PduPersister.java +++ b/telephony/common/com/google/android/mms/pdu/PduPersister.java @@ -17,6 +17,7 @@ package com.google.android.mms.pdu; +import android.compat.annotation.UnsupportedAppUsage; import android.content.ContentResolver; import android.content.ContentUris; import android.content.ContentValues; @@ -40,8 +41,6 @@ import android.telephony.TelephonyManager; import android.text.TextUtils; import android.util.Log; -import dalvik.annotation.compat.UnsupportedAppUsage; - import com.google.android.mms.ContentType; import com.google.android.mms.InvalidHeaderValueException; import com.google.android.mms.MmsException; diff --git a/telephony/common/com/google/android/mms/pdu/QuotedPrintable.java b/telephony/common/com/google/android/mms/pdu/QuotedPrintable.java index 9d6535c72e90..4e1d7f5775ec 100644 --- a/telephony/common/com/google/android/mms/pdu/QuotedPrintable.java +++ b/telephony/common/com/google/android/mms/pdu/QuotedPrintable.java @@ -17,7 +17,7 @@ package com.google.android.mms.pdu; -import dalvik.annotation.compat.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import java.io.ByteArrayOutputStream; diff --git a/telephony/common/com/google/android/mms/pdu/ReadOrigInd.java b/telephony/common/com/google/android/mms/pdu/ReadOrigInd.java index e38c62dde622..4ba3c71580e0 100644 --- a/telephony/common/com/google/android/mms/pdu/ReadOrigInd.java +++ b/telephony/common/com/google/android/mms/pdu/ReadOrigInd.java @@ -17,7 +17,7 @@ package com.google.android.mms.pdu; -import dalvik.annotation.compat.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import com.google.android.mms.InvalidHeaderValueException; diff --git a/telephony/common/com/google/android/mms/pdu/ReadRecInd.java b/telephony/common/com/google/android/mms/pdu/ReadRecInd.java index 9696bc259d00..37ccfb9c9b9b 100644 --- a/telephony/common/com/google/android/mms/pdu/ReadRecInd.java +++ b/telephony/common/com/google/android/mms/pdu/ReadRecInd.java @@ -17,7 +17,7 @@ package com.google.android.mms.pdu; -import dalvik.annotation.compat.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import com.google.android.mms.InvalidHeaderValueException; diff --git a/telephony/common/com/google/android/mms/pdu/RetrieveConf.java b/telephony/common/com/google/android/mms/pdu/RetrieveConf.java index 03755af4189c..260adfc093f2 100644 --- a/telephony/common/com/google/android/mms/pdu/RetrieveConf.java +++ b/telephony/common/com/google/android/mms/pdu/RetrieveConf.java @@ -17,7 +17,7 @@ package com.google.android.mms.pdu; -import dalvik.annotation.compat.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import com.google.android.mms.InvalidHeaderValueException; diff --git a/telephony/common/com/google/android/mms/pdu/SendConf.java b/telephony/common/com/google/android/mms/pdu/SendConf.java index b85982791ada..779923801bfa 100644 --- a/telephony/common/com/google/android/mms/pdu/SendConf.java +++ b/telephony/common/com/google/android/mms/pdu/SendConf.java @@ -17,7 +17,7 @@ package com.google.android.mms.pdu; -import dalvik.annotation.compat.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import com.google.android.mms.InvalidHeaderValueException; diff --git a/telephony/common/com/google/android/mms/pdu/SendReq.java b/telephony/common/com/google/android/mms/pdu/SendReq.java index c1b7f934c0f7..6e2f2da01791 100644 --- a/telephony/common/com/google/android/mms/pdu/SendReq.java +++ b/telephony/common/com/google/android/mms/pdu/SendReq.java @@ -17,10 +17,9 @@ package com.google.android.mms.pdu; +import android.compat.annotation.UnsupportedAppUsage; import android.util.Log; -import dalvik.annotation.compat.UnsupportedAppUsage; - import com.google.android.mms.InvalidHeaderValueException; public class SendReq extends MultimediaMessagePdu { diff --git a/telephony/common/com/google/android/mms/util/AbstractCache.java b/telephony/common/com/google/android/mms/util/AbstractCache.java index ab5d48a4ce3d..25862e73581e 100644 --- a/telephony/common/com/google/android/mms/util/AbstractCache.java +++ b/telephony/common/com/google/android/mms/util/AbstractCache.java @@ -17,10 +17,9 @@ package com.google.android.mms.util; +import android.compat.annotation.UnsupportedAppUsage; import android.util.Log; -import dalvik.annotation.compat.UnsupportedAppUsage; - import java.util.HashMap; public abstract class AbstractCache<K, V> { diff --git a/telephony/common/com/google/android/mms/util/DownloadDrmHelper.java b/telephony/common/com/google/android/mms/util/DownloadDrmHelper.java index 118de465a518..0f9390daa725 100644 --- a/telephony/common/com/google/android/mms/util/DownloadDrmHelper.java +++ b/telephony/common/com/google/android/mms/util/DownloadDrmHelper.java @@ -17,12 +17,11 @@ package com.google.android.mms.util; +import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; import android.drm.DrmManagerClient; import android.util.Log; -import dalvik.annotation.compat.UnsupportedAppUsage; - public class DownloadDrmHelper { private static final String TAG = "DownloadDrmHelper"; diff --git a/telephony/common/com/google/android/mms/util/DrmConvertSession.java b/telephony/common/com/google/android/mms/util/DrmConvertSession.java index 0e8ec91f4ef6..156c7ad8baac 100644 --- a/telephony/common/com/google/android/mms/util/DrmConvertSession.java +++ b/telephony/common/com/google/android/mms/util/DrmConvertSession.java @@ -16,14 +16,13 @@ */ package com.google.android.mms.util; +import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; import android.drm.DrmConvertedStatus; import android.drm.DrmManagerClient; import android.provider.Downloads; import android.util.Log; -import dalvik.annotation.compat.UnsupportedAppUsage; - import java.io.FileNotFoundException; import java.io.IOException; import java.io.RandomAccessFile; diff --git a/telephony/common/com/google/android/mms/util/PduCache.java b/telephony/common/com/google/android/mms/util/PduCache.java index 94e38946f632..c380d6b3e30f 100644 --- a/telephony/common/com/google/android/mms/util/PduCache.java +++ b/telephony/common/com/google/android/mms/util/PduCache.java @@ -17,14 +17,13 @@ package com.google.android.mms.util; +import android.compat.annotation.UnsupportedAppUsage; import android.content.ContentUris; import android.content.UriMatcher; import android.net.Uri; import android.provider.Telephony.Mms; import android.util.Log; -import dalvik.annotation.compat.UnsupportedAppUsage; - import java.util.HashMap; import java.util.HashSet; diff --git a/telephony/common/com/google/android/mms/util/PduCacheEntry.java b/telephony/common/com/google/android/mms/util/PduCacheEntry.java index 1ecd1bf93e7f..a4a25d2471ff 100644 --- a/telephony/common/com/google/android/mms/util/PduCacheEntry.java +++ b/telephony/common/com/google/android/mms/util/PduCacheEntry.java @@ -17,7 +17,7 @@ package com.google.android.mms.util; -import dalvik.annotation.compat.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import com.google.android.mms.pdu.GenericPdu; diff --git a/telephony/common/com/google/android/mms/util/SqliteWrapper.java b/telephony/common/com/google/android/mms/util/SqliteWrapper.java index 2dd1dc11c2a9..31fe4d7683d6 100644 --- a/telephony/common/com/google/android/mms/util/SqliteWrapper.java +++ b/telephony/common/com/google/android/mms/util/SqliteWrapper.java @@ -18,6 +18,7 @@ package com.google.android.mms.util; import android.app.ActivityManager; +import android.compat.annotation.UnsupportedAppUsage; import android.content.ContentResolver; import android.content.ContentValues; import android.content.Context; @@ -27,8 +28,6 @@ import android.net.Uri; import android.util.Log; import android.widget.Toast; -import dalvik.annotation.compat.UnsupportedAppUsage; - public final class SqliteWrapper { private static final String TAG = "SqliteWrapper"; private static final String SQLITE_EXCEPTION_DETAIL_MESSAGE diff --git a/telephony/java/android/service/carrier/CarrierIdentifier.java b/telephony/java/android/service/carrier/CarrierIdentifier.java index af5bf7475f95..7957c258b54f 100644 --- a/telephony/java/android/service/carrier/CarrierIdentifier.java +++ b/telephony/java/android/service/carrier/CarrierIdentifier.java @@ -20,7 +20,7 @@ import android.annotation.NonNull; import android.annotation.Nullable; import android.os.Parcel; import android.os.Parcelable; -import android.telephony.Rlog; +import com.android.telephony.Rlog; import android.telephony.TelephonyManager; import com.android.internal.telephony.uicc.IccUtils; diff --git a/telephony/java/android/service/euicc/EuiccProfileInfo.java b/telephony/java/android/service/euicc/EuiccProfileInfo.java index 6c357ccdd03d..8450a9018634 100644 --- a/telephony/java/android/service/euicc/EuiccProfileInfo.java +++ b/telephony/java/android/service/euicc/EuiccProfileInfo.java @@ -19,7 +19,7 @@ import android.annotation.IntDef; import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.SystemApi; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.os.Parcel; import android.os.Parcelable; import android.service.carrier.CarrierIdentifier; diff --git a/telephony/java/android/service/euicc/GetDefaultDownloadableSubscriptionListResult.java b/telephony/java/android/service/euicc/GetDefaultDownloadableSubscriptionListResult.java index c7a985160730..2382f657c9ee 100644 --- a/telephony/java/android/service/euicc/GetDefaultDownloadableSubscriptionListResult.java +++ b/telephony/java/android/service/euicc/GetDefaultDownloadableSubscriptionListResult.java @@ -17,7 +17,7 @@ package android.service.euicc; import android.annotation.Nullable; import android.annotation.SystemApi; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.os.Parcel; import android.os.Parcelable; import android.telephony.euicc.DownloadableSubscription; diff --git a/telephony/java/android/service/euicc/GetDownloadableSubscriptionMetadataResult.java b/telephony/java/android/service/euicc/GetDownloadableSubscriptionMetadataResult.java index abd4065c754a..d0fb51180c1d 100644 --- a/telephony/java/android/service/euicc/GetDownloadableSubscriptionMetadataResult.java +++ b/telephony/java/android/service/euicc/GetDownloadableSubscriptionMetadataResult.java @@ -17,7 +17,7 @@ package android.service.euicc; import android.annotation.Nullable; import android.annotation.SystemApi; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.os.Parcel; import android.os.Parcelable; import android.telephony.euicc.DownloadableSubscription; diff --git a/telephony/java/android/telephony/AccessNetworkConstants.java b/telephony/java/android/telephony/AccessNetworkConstants.java index bb28df2b64eb..d325cd84855c 100644 --- a/telephony/java/android/telephony/AccessNetworkConstants.java +++ b/telephony/java/android/telephony/AccessNetworkConstants.java @@ -50,18 +50,12 @@ public final class AccessNetworkConstants { /** * Transport type for Wireless Wide Area Networks (i.e. Cellular) - * @hide */ - @SystemApi - @TestApi public static final int TRANSPORT_TYPE_WWAN = 1; /** * Transport type for Wireless Local Area Networks (i.e. Wifi) - * @hide */ - @SystemApi - @TestApi public static final int TRANSPORT_TYPE_WLAN = 2; /** @hide */ diff --git a/telephony/java/android/telephony/Annotation.java b/telephony/java/android/telephony/Annotation.java index 7482ecc85324..9e6dfef0608b 100644 --- a/telephony/java/android/telephony/Annotation.java +++ b/telephony/java/android/telephony/Annotation.java @@ -596,4 +596,17 @@ public class Annotation { @Retention(RetentionPolicy.SOURCE) public @interface ImsAudioCodec { } + + /** + * UICC SIM Application Types + */ + @IntDef(prefix = { "APPTYPE_" }, value = { + TelephonyManager.APPTYPE_SIM, + TelephonyManager.APPTYPE_USIM, + TelephonyManager.APPTYPE_RUIM, + TelephonyManager.APPTYPE_CSIM, + TelephonyManager.APPTYPE_ISIM + }) + @Retention(RetentionPolicy.SOURCE) + public @interface UiccAppType{} } diff --git a/telephony/java/android/telephony/AnomalyReporter.java b/telephony/java/android/telephony/AnomalyReporter.java index 9753d8be4065..097041f672ac 100644 --- a/telephony/java/android/telephony/AnomalyReporter.java +++ b/telephony/java/android/telephony/AnomalyReporter.java @@ -16,6 +16,8 @@ package android.telephony; +import com.android.telephony.Rlog; + import android.annotation.NonNull; import android.annotation.RequiresPermission; import android.content.Context; diff --git a/telephony/java/android/telephony/CarrierConfigManager.java b/telephony/java/android/telephony/CarrierConfigManager.java index 57a80183c4c2..61e67be2333f 100644 --- a/telephony/java/android/telephony/CarrierConfigManager.java +++ b/telephony/java/android/telephony/CarrierConfigManager.java @@ -24,7 +24,7 @@ import android.annotation.SuppressLint; import android.annotation.SystemApi; import android.annotation.SystemService; import android.annotation.TestApi; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.ComponentName; import android.content.Context; import android.os.PersistableBundle; @@ -35,6 +35,7 @@ import android.telecom.TelecomManager; import android.telephony.ims.ImsReasonInfo; import com.android.internal.telephony.ICarrierConfigLoader; +import com.android.telephony.Rlog; /** * Provides access to telephony configuration values that are carrier-specific. @@ -299,7 +300,6 @@ public class CarrierConfigManager { /** * A string array containing numbers that shouldn't be included in the call log. - * @hide */ public static final String KEY_UNLOGGABLE_NUMBERS_STRING_ARRAY = "unloggable_numbers_string_array"; @@ -312,12 +312,11 @@ public class CarrierConfigManager { KEY_HIDE_CARRIER_NETWORK_SETTINGS_BOOL = "hide_carrier_network_settings_bool"; /** - * Do only allow auto selection in Advanced Network Settings when in home network. + * Only allow auto selection in Advanced Network Settings when in home network. * Manual selection is allowed when in roaming network. - * @hide */ - public static final String - KEY_ONLY_AUTO_SELECT_IN_HOME_NETWORK_BOOL = "only_auto_select_in_home_network"; + public static final String KEY_ONLY_AUTO_SELECT_IN_HOME_NETWORK_BOOL = + "only_auto_select_in_home_network"; /** * Control whether users receive a simplified network settings UI and improved network @@ -581,9 +580,6 @@ public class CarrierConfigManager { * registration state to change. That is, turning on or off mobile data will not cause VT to be * enabled or disabled. * When {@code false}, disabling mobile data will cause VT to be de-registered. - * <p> - * See also {@link #KEY_VILTE_DATA_IS_METERED_BOOL}. - * @hide */ public static final String KEY_IGNORE_DATA_ENABLED_CHANGED_FOR_VIDEO_CALLS = "ignore_data_enabled_changed_for_video_calls"; @@ -647,7 +643,6 @@ public class CarrierConfigManager { /** * Default WFC_IMS_enabled: true VoWiFi by default is on * false VoWiFi by default is off - * @hide */ public static final String KEY_CARRIER_DEFAULT_WFC_IMS_ENABLED_BOOL = "carrier_default_wfc_ims_enabled_bool"; @@ -671,6 +666,12 @@ public class CarrierConfigManager { "carrier_promote_wfc_on_call_fail_bool"; /** + * Flag specifying whether provisioning is required for RCS. + */ + public static final String KEY_CARRIER_RCS_PROVISIONING_REQUIRED_BOOL = + "carrier_rcs_provisioning_required_bool"; + + /** * Flag specifying whether provisioning is required for VoLTE, Video Telephony, and WiFi * Calling. */ @@ -713,9 +714,7 @@ public class CarrierConfigManager { * * As of now, Verizon is the only carrier enforcing this dependency in their * WFC awareness and activation requirements. - * - * @hide - * */ + */ public static final String KEY_CARRIER_VOLTE_OVERRIDE_WFC_PROVISIONING_BOOL = "carrier_volte_override_wfc_provisioning_bool"; @@ -847,9 +846,12 @@ public class CarrierConfigManager { "carrier_force_disable_etws_cmas_test_bool"; /** - * The default flag specifying whether "Turn on Notifications" option will be always shown in - * Settings->More->Emergency broadcasts menu regardless developer options is turned on or not. + * The default flag specifying whether "Allow alerts" option will be always shown in + * emergency alerts settings regardless developer options is turned on or not. + * + * @deprecated The allow alerts option is always shown now. No longer need a config for that. */ + @Deprecated public static final String KEY_ALWAYS_SHOW_EMERGENCY_ALERT_ONOFF_BOOL = "always_show_emergency_alert_onoff_bool"; @@ -1073,10 +1075,6 @@ public class CarrierConfigManager { * * When {@code false}, the old behavior is used, where the toggle in accessibility settings is * used to set the IMS stack's RTT enabled state. - * - * @deprecated -- this flag no longer does anything. Remove once the new behavior is verified. - * - * @hide */ public static final String KEY_IGNORE_RTT_MODE_SETTING_BOOL = "ignore_rtt_mode_setting_bool"; @@ -1117,7 +1115,6 @@ public class CarrierConfigManager { * Determines whether the IMS conference merge process supports and returns its participants * data. When {@code true}, on merge complete, conference call would have a list of its * participants returned in XML format, {@code false otherwise}. - * @hide */ public static final String KEY_SUPPORT_IMS_CONFERENCE_EVENT_PACKAGE_BOOL = "support_ims_conference_event_package_bool"; @@ -1190,20 +1187,18 @@ public class CarrierConfigManager { public static final String KEY_ENABLE_APPS_STRING_ARRAY = "enable_apps_string_array"; /** - * Determine whether user can switch Wi-Fi preferred or Cellular preferred in calling preference. + * Determine whether user can switch Wi-Fi preferred or Cellular preferred + * in calling preference. * Some operators support Wi-Fi Calling only, not VoLTE. * They don't need "Cellular preferred" option. - * In this case, set uneditalbe attribute for preferred preference. - * @hide + * In this case, set uneditable attribute for preferred preference. */ public static final String KEY_EDITABLE_WFC_MODE_BOOL = "editable_wfc_mode_bool"; - /** - * Flag to indicate if Wi-Fi needs to be disabled in ECBM - * @hide - **/ - public static final String - KEY_CONFIG_WIFI_DISABLE_IN_ECBM = "config_wifi_disable_in_ecbm"; + /** + * Flag to indicate if Wi-Fi needs to be disabled in ECBM. + */ + public static final String KEY_CONFIG_WIFI_DISABLE_IN_ECBM = "config_wifi_disable_in_ecbm"; /** * List operator-specific error codes and indices of corresponding error strings in @@ -1267,9 +1262,8 @@ public class CarrierConfigManager { public static final String KEY_WFC_SPN_USE_ROOT_LOCALE = "wfc_spn_use_root_locale"; /** - * The Component Name of the activity that can setup the emergency addrees for WiFi Calling + * The Component Name of the activity that can setup the emergency address for WiFi Calling * as per carrier requirement. - * @hide */ public static final String KEY_WFC_EMERGENCY_ADDRESS_CARRIER_APP_STRING = "wfc_emergency_address_carrier_app_string"; @@ -1433,22 +1427,19 @@ public class CarrierConfigManager { public static final String KEY_ALLOW_ADDING_APNS_BOOL = "allow_adding_apns_bool"; /** - * APN types that user is not allowed to modify - * @hide + * APN types that user is not allowed to modify. */ public static final String KEY_READ_ONLY_APN_TYPES_STRING_ARRAY = "read_only_apn_types_string_array"; /** - * APN fields that user is not allowed to modify - * @hide + * APN fields that user is not allowed to modify. */ public static final String KEY_READ_ONLY_APN_FIELDS_STRING_ARRAY = "read_only_apn_fields_string_array"; /** * Default value of APN types field if not specified by user when adding/modifying an APN. - * @hide */ public static final String KEY_APN_SETTINGS_DEFAULT_APN_TYPES_STRING_ARRAY = "apn_settings_default_apn_types_string_array"; @@ -1479,29 +1470,25 @@ public class CarrierConfigManager { "hide_digits_helper_text_on_stk_input_screen_bool"; /** - * Boolean indicating if show data RAT icon on status bar even when data is disabled - * @hide + * Boolean indicating if show data RAT icon on status bar even when data is disabled. */ public static final String KEY_ALWAYS_SHOW_DATA_RAT_ICON_BOOL = "always_show_data_rat_icon_bool"; /** - * Boolean indicating if default data account should show LTE or 4G icon - * @hide + * Boolean indicating if default data account should show LTE or 4G icon. */ public static final String KEY_SHOW_4G_FOR_LTE_DATA_ICON_BOOL = "show_4g_for_lte_data_icon_bool"; /** * Boolean indicating if default data account should show 4G icon when in 3G. - * @hide */ public static final String KEY_SHOW_4G_FOR_3G_DATA_ICON_BOOL = "show_4g_for_3g_data_icon_bool"; /** - * Boolean indicating if lte+ icon should be shown if available - * @hide + * Boolean indicating if LTE+ icon should be shown if available. */ public static final String KEY_HIDE_LTE_PLUS_DATA_ICON_BOOL = "hide_lte_plus_data_icon_bool"; @@ -1516,10 +1503,8 @@ public class CarrierConfigManager { "operator_name_filter_pattern_string"; /** - * The string is used to compare with operator name. If it matches the pattern then show - * specific data icon. - * - * @hide + * The string is used to compare with operator name. + * If it matches the pattern then show specific data icon. */ public static final String KEY_SHOW_CARRIER_DATA_ICON_PATTERN_STRING = "show_carrier_data_icon_pattern_string"; @@ -1532,33 +1517,28 @@ public class CarrierConfigManager { "show_precise_failed_cause_bool"; /** - * Boolean to decide whether lte is enabled. - * @hide + * Boolean to decide whether LTE is enabled. */ public static final String KEY_LTE_ENABLED_BOOL = "lte_enabled_bool"; /** * Boolean to decide whether TD-SCDMA is supported. - * @hide */ public static final String KEY_SUPPORT_TDSCDMA_BOOL = "support_tdscdma_bool"; /** * A list of mcc/mnc that support TD-SCDMA for device when connect to the roaming network. - * @hide */ public static final String KEY_SUPPORT_TDSCDMA_ROAMING_NETWORKS_STRING_ARRAY = "support_tdscdma_roaming_networks_string_array"; /** * Boolean to decide whether world mode is enabled. - * @hide */ public static final String KEY_WORLD_MODE_ENABLED_BOOL = "world_mode_enabled_bool"; /** * Flatten {@link android.content.ComponentName} of the carrier's settings activity. - * @hide */ public static final String KEY_CARRIER_SETTINGS_ACTIVITY_COMPONENT_NAME_STRING = "carrier_settings_activity_component_name_string"; @@ -1596,7 +1576,10 @@ public class CarrierConfigManager { public static final String KEY_MMS_UA_PROF_TAG_NAME_STRING = "uaProfTagName"; public static final String KEY_MMS_UA_PROF_URL_STRING = "uaProfUrl"; public static final String KEY_MMS_USER_AGENT_STRING = "userAgent"; - /** @hide */ + /** + * If true, add "Connection: close" header to MMS HTTP requests so the connection + * is immediately closed (disabling keep-alive). + */ public static final String KEY_MMS_CLOSE_CONNECTION_BOOL = "mmsCloseConnection"; /** @@ -1612,25 +1595,23 @@ public class CarrierConfigManager { /** * Defines carrier-specific actions which act upon * com.android.internal.telephony.CARRIER_SIGNAL_REDIRECTED, used for customization of the - * default carrier app + * default carrier app. * Format: "CARRIER_ACTION_IDX, ..." * Where {@code CARRIER_ACTION_IDX} is an integer defined in - * {@link com.android.carrierdefaultapp.CarrierActionUtils CarrierActionUtils} + * com.android.carrierdefaultapp.CarrierActionUtils * Example: - * {@link com.android.carrierdefaultapp.CarrierActionUtils#CARRIER_ACTION_DISABLE_METERED_APNS - * disable_metered_apns} - * @hide + * com.android.carrierdefaultapp.CarrierActionUtils#CARRIER_ACTION_DISABLE_METERED_APNS + * disables metered APNs */ - @UnsupportedAppUsage + @SuppressLint("IntentName") public static final String KEY_CARRIER_DEFAULT_ACTIONS_ON_REDIRECTION_STRING_ARRAY = "carrier_default_actions_on_redirection_string_array"; /** - * Defines carrier-specific actions which act upon - * com.android.internal.telephony.CARRIER_SIGNAL_REQUEST_NETWORK_FAILED + * Defines carrier-specific actions which act upon CARRIER_SIGNAL_REQUEST_NETWORK_FAILED * and configured signal args: - * {@link com.android.internal.telephony.TelephonyIntents#EXTRA_APN_TYPE_KEY apnType}, - * {@link com.android.internal.telephony.TelephonyIntents#EXTRA_ERROR_CODE_KEY errorCode} + * android.telephony.TelephonyManager#EXTRA_APN_TYPE, + * android.telephony.TelephonyManager#EXTRA_ERROR_CODE * used for customization of the default carrier app * Format: * { @@ -1638,42 +1619,41 @@ public class CarrierConfigManager { * "APN_1, ERROR_CODE_2 : CARRIER_ACTION_IDX_1 " * } * Where {@code APN_1} is a string defined in - * {@link com.android.internal.telephony.PhoneConstants PhoneConstants} + * com.android.internal.telephony.PhoneConstants * Example: "default" * - * {@code ERROR_CODE_1} is an integer defined in - * {@link DataFailCause DcFailure} + * {@code ERROR_CODE_1} is an integer defined in android.telephony.DataFailCause * Example: - * {@link DataFailCause#MISSING_UNKNOWN_APN} + * android.telephony.DataFailCause#MISSING_UNKNOWN_APN * * {@code CARRIER_ACTION_IDX_1} is an integer defined in - * {@link com.android.carrierdefaultapp.CarrierActionUtils CarrierActionUtils} + * com.android.carrierdefaultapp.CarrierActionUtils * Example: - * {@link com.android.carrierdefaultapp.CarrierActionUtils#CARRIER_ACTION_DISABLE_METERED_APNS} - * @hide + * com.android.carrierdefaultapp.CarrierActionUtils#CARRIER_ACTION_DISABLE_METERED_APNS + * disables metered APNs */ + @SuppressLint("IntentName") public static final String KEY_CARRIER_DEFAULT_ACTIONS_ON_DCFAILURE_STRING_ARRAY = "carrier_default_actions_on_dcfailure_string_array"; /** - * Defines carrier-specific actions which act upon - * com.android.internal.telephony.CARRIER_SIGNAL_RESET, used for customization of the - * default carrier app + * Defines carrier-specific actions which act upon CARRIER_SIGNAL_RESET, + * used for customization of the default carrier app. * Format: "CARRIER_ACTION_IDX, ..." * Where {@code CARRIER_ACTION_IDX} is an integer defined in - * {@link com.android.carrierdefaultapp.CarrierActionUtils CarrierActionUtils} + * com.android.carrierdefaultapp.CarrierActionUtils * Example: - * {@link com.android.carrierdefaultapp.CarrierActionUtils - * #CARRIER_ACTION_CANCEL_ALL_NOTIFICATIONS clear all notifications on reset} - * @hide + * com.android.carrierdefaultapp.CarrierActionUtils#CARRIER_ACTION_CANCEL_ALL_NOTIFICATIONS + * clears all notifications on reset */ + @SuppressLint("IntentName") public static final String KEY_CARRIER_DEFAULT_ACTIONS_ON_RESET = "carrier_default_actions_on_reset_string_array"; /** * Defines carrier-specific actions which act upon * com.android.internal.telephony.CARRIER_SIGNAL_DEFAULT_NETWORK_AVAILABLE, - * used for customization of the default carrier app + * used for customization of the default carrier app. * Format: * { * "true : CARRIER_ACTION_IDX_1", @@ -1681,17 +1661,17 @@ public class CarrierConfigManager { * } * Where {@code true} is a boolean indicates default network available/unavailable * Where {@code CARRIER_ACTION_IDX} is an integer defined in - * {@link com.android.carrierdefaultapp.CarrierActionUtils CarrierActionUtils} + * com.android.carrierdefaultapp.CarrierActionUtils CarrierActionUtils * Example: - * {@link com.android.carrierdefaultapp.CarrierActionUtils - * #CARRIER_ACTION_ENABLE_DEFAULT_URL_HANDLER enable the app as the default URL handler} - * @hide + * com.android.carrierdefaultapp.CarrierActionUtils#CARRIER_ACTION_ENABLE_DEFAULT_URL_HANDLER + * enables the app as the default URL handler */ + @SuppressLint("IntentName") public static final String KEY_CARRIER_DEFAULT_ACTIONS_ON_DEFAULT_NETWORK_AVAILABLE = "carrier_default_actions_on_default_network_available_string_array"; + /** - * Defines a list of acceptable redirection url for default carrier app - * @hides + * Defines a list of acceptable redirection url for default carrier app. */ public static final String KEY_CARRIER_DEFAULT_REDIRECTION_URL_STRING_ARRAY = "carrier_default_redirection_url_string_array"; @@ -1819,10 +1799,10 @@ public class CarrierConfigManager { /** * Determines whether to enable enhanced call blocking feature on the device. - * @see SystemContract#ENHANCED_SETTING_KEY_BLOCK_UNREGISTERED - * @see SystemContract#ENHANCED_SETTING_KEY_BLOCK_PRIVATE - * @see SystemContract#ENHANCED_SETTING_KEY_BLOCK_PAYPHONE - * @see SystemContract#ENHANCED_SETTING_KEY_BLOCK_UNKNOWN + * android.provider.BlockedNumberContract.SystemContract#ENHANCED_SETTING_KEY_BLOCK_UNREGISTERED + * android.provider.BlockedNumberContract.SystemContract#ENHANCED_SETTING_KEY_BLOCK_PRIVATE + * android.provider.BlockedNumberContract.SystemContract#ENHANCED_SETTING_KEY_BLOCK_PAYPHONE + * android.provider.BlockedNumberContract.SystemContract#ENHANCED_SETTING_KEY_BLOCK_UNKNOWN * * <p> * 1. For Single SIM(SS) device, it can be customized in both carrier_config_mccmnc.xml @@ -1832,7 +1812,6 @@ public class CarrierConfigManager { * function is used regardless of SIM. * <p> * If {@code true} enable enhanced call blocking feature on the device, {@code false} otherwise. - * @hide */ public static final String KEY_SUPPORT_ENHANCED_CALL_BLOCKING_BOOL = "support_enhanced_call_blocking_bool"; @@ -1935,7 +1914,6 @@ public class CarrierConfigManager { /** * Flag indicating whether the carrier supports call deflection for an incoming IMS call. - * @hide */ public static final String KEY_CARRIER_ALLOW_DEFLECT_IMS_CALL_BOOL = "carrier_allow_deflect_ims_call_bool"; @@ -2000,8 +1978,6 @@ public class CarrierConfigManager { /** * Whether system apps are allowed to use fallback if carrier video call is not available. * Defaults to {@code true}. - * - * @hide */ public static final String KEY_ALLOW_VIDEO_CALLING_FALLBACK_BOOL = "allow_video_calling_fallback_bool"; @@ -2039,9 +2015,8 @@ public class CarrierConfigManager { "enhanced_4g_lte_title_variant_bool"; /** - * The index indicates the carrier specified title string of Enahnce 4G LTE Mode settings. + * The index indicates the carrier specified title string of Enhanced 4G LTE Mode settings. * Default value is 0, which indicates the default title string. - * @hide */ public static final String KEY_ENHANCED_4G_LTE_TITLE_VARIANT_INT = "enhanced_4g_lte_title_variant_int"; @@ -2085,15 +2060,13 @@ public class CarrierConfigManager { * {@link #KEY_USE_WFC_HOME_NETWORK_MODE_IN_ROAMING_NETWORK_BOOL} is false. If * {@link #KEY_USE_WFC_HOME_NETWORK_MODE_IN_ROAMING_NETWORK_BOOL} is true, this * configuration is ignored and roaming preference cannot be changed. - * @hide */ public static final String KEY_EDITABLE_WFC_ROAMING_MODE_BOOL = "editable_wfc_roaming_mode_bool"; /** - * Flag specifying wether to show blocking pay phone option in blocked numbers screen. Only show - * the option if payphone call presentation represents in the carrier's region. - * @hide + * Flag specifying whether to show blocking pay phone option in blocked numbers screen. + * Only show the option if payphone call presentation is present in the carrier's region. */ public static final java.lang.String KEY_SHOW_BLOCKING_PAY_PHONE_OPTION_BOOL = "show_blocking_pay_phone_option_bool"; @@ -2103,7 +2076,6 @@ public class CarrierConfigManager { * {@code false} - roaming preference can be selected separately from the home preference. * {@code true} - roaming preference is the same as home preference and * {@link #KEY_CARRIER_DEFAULT_WFC_IMS_MODE_INT} is used as the default value. - * @hide */ public static final String KEY_USE_WFC_HOME_NETWORK_MODE_IN_ROAMING_NETWORK_BOOL = "use_wfc_home_network_mode_in_roaming_network_bool"; @@ -2137,7 +2109,6 @@ public class CarrierConfigManager { * while the device is registered over WFC. Default value is -1, which indicates * that this notification is not pertinent for a particular carrier. We've added a delay * to prevent false positives. - * @hide */ public static final String KEY_EMERGENCY_NOTIFICATION_DELAY_INT = "emergency_notification_delay_int"; @@ -2188,7 +2159,6 @@ public class CarrierConfigManager { /** * Flag specifying whether to show an alert dialog for video call charges. * By default this value is {@code false}. - * @hide */ public static final String KEY_SHOW_VIDEO_CALL_CHARGES_ALERT_DIALOG_BOOL = "show_video_call_charges_alert_dialog_bool"; @@ -2475,10 +2445,9 @@ public class CarrierConfigManager { /** * Identifies if the key is available for WLAN or EPDG or both. The value is a bitmask. * 0 indicates that neither EPDG or WLAN is enabled. - * 1 indicates that key type {@link TelephonyManager#KEY_TYPE_EPDG} is enabled. - * 2 indicates that key type {@link TelephonyManager#KEY_TYPE_WLAN} is enabled. + * 1 indicates that key type TelephonyManager#KEY_TYPE_EPDG is enabled. + * 2 indicates that key type TelephonyManager#KEY_TYPE_WLAN is enabled. * 3 indicates that both are enabled. - * @hide */ public static final String IMSI_KEY_AVAILABILITY_INT = "imsi_key_availability_int"; @@ -2497,7 +2466,6 @@ public class CarrierConfigManager { /** * Flag specifying whether IMS registration state menu is shown in Status Info setting, * default to false. - * @hide */ public static final String KEY_SHOW_IMS_REGISTRATION_STATUS_BOOL = "show_ims_registration_status_bool"; @@ -2553,7 +2521,6 @@ public class CarrierConfigManager { /** * The flag to disable the popup dialog which warns the user of data charges. - * @hide */ public static final String KEY_DISABLE_CHARGE_INDICATION_BOOL = "disable_charge_indication_bool"; @@ -2618,15 +2585,13 @@ public class CarrierConfigManager { /** * Determines whether any carrier has been identified and its specific config has been applied, * default to false. - * @hide */ public static final String KEY_CARRIER_CONFIG_APPLIED_BOOL = "carrier_config_applied_bool"; /** * Determines whether we should show a warning asking the user to check with their carrier - * on pricing when the user enabled data roaming. + * on pricing when the user enabled data roaming, * default to false. - * @hide */ public static final String KEY_CHECK_PRICING_WITH_CARRIER_FOR_DATA_ROAMING_BOOL = "check_pricing_with_carrier_data_roaming_bool"; @@ -2778,10 +2743,10 @@ public class CarrierConfigManager { * Specifies a carrier-defined {@link android.telecom.CallRedirectionService} which Telecom * will bind to for outgoing calls. An empty string indicates that no carrier-defined * {@link android.telecom.CallRedirectionService} is specified. - * @hide */ public static final String KEY_CALL_REDIRECTION_SERVICE_COMPONENT_NAME_STRING = "call_redirection_service_component_name_string"; + /** * Support for the original string display of CDMA MO call. * By default, it is disabled. @@ -2894,8 +2859,8 @@ public class CarrierConfigManager { "call_waiting_service_class_int"; /** - * This configuration allow the system UI to display different 5G icon for different 5G - * scenario. + * This configuration allows the system UI to display different 5G icons for different 5G + * scenarios. * * There are five 5G scenarios: * 1. connected_mmwave: device currently connected to 5G cell as the secondary cell and using @@ -2912,24 +2877,22 @@ public class CarrierConfigManager { * 5G cell as a secondary cell) but the use of 5G is restricted. * * The configured string contains multiple key-value pairs separated by comma. For each pair, - * the key and value is separated by a colon. The key is corresponded to a 5G status above and + * the key and value are separated by a colon. The key corresponds to a 5G status above and * the value is the icon name. Use "None" as the icon name if no icon should be shown in a * specific 5G scenario. If the scenario is "None", config can skip this key and value. * * Icon name options: "5G_Plus", "5G". * * Here is an example: - * UE want to display 5G_Plus icon for scenario#1, and 5G icon for scenario#2; otherwise no + * UE wants to display 5G_Plus icon for scenario#1, and 5G icon for scenario#2; otherwise not * define. * The configuration is: "connected_mmwave:5G_Plus,connected:5G" - * - * @hide */ public static final String KEY_5G_ICON_CONFIGURATION_STRING = "5g_icon_configuration_string"; /** - * Timeout in second for displaying 5G icon, default value is 0 which means the timer is + * Timeout in seconds for displaying 5G icon, default value is 0 which means the timer is * disabled. * * System UI will show the 5G icon and start a timer with the timeout from this config when the @@ -2938,8 +2901,6 @@ public class CarrierConfigManager { * * If 5G is reacquired during this timer, the timer is canceled and restarted when 5G is next * lost. Allows us to momentarily lose 5G without blinking the icon. - * - * @hide */ public static final String KEY_5G_ICON_DISPLAY_GRACE_PERIOD_SEC_INT = "5g_icon_display_grace_period_sec_int"; @@ -3018,6 +2979,13 @@ public class CarrierConfigManager { "ping_test_before_data_switch_bool"; /** + * Controls time in milliseconds until DcTracker reevaluates 5G connection state. + * @hide + */ + public static final String KEY_5G_WATCHDOG_TIME_MS_LONG = + "5g_watchdog_time_long"; + + /** * Indicates zero or more emergency number prefix(es), because some carrier requires * if users dial an emergency number address with a specific prefix, the combination of the * prefix and the address is also a valid emergency number to dial. For example, an emergency @@ -3050,8 +3018,6 @@ public class CarrierConfigManager { * signal bar of primary network. By default it will be false, meaning whenever data * is going over opportunistic network, signal bar will reflect signal strength and rat * icon of that network. - * - * @hide */ public static final String KEY_ALWAYS_SHOW_PRIMARY_SIGNAL_BAR_IN_OPPORTUNISTIC_NETWORK_BOOLEAN = "always_show_primary_signal_bar_in_opportunistic_network_boolean"; @@ -3265,8 +3231,6 @@ public class CarrierConfigManager { /** * Determines whether wifi calling location privacy policy is shown. - * - * @hide */ public static final String KEY_SHOW_WFC_LOCATION_PRIVACY_POLICY_BOOL = "show_wfc_location_privacy_policy_bool"; @@ -3372,8 +3336,8 @@ public class CarrierConfigManager { "support_wps_over_ims_bool"; /** - * Holds the list of carrier certificate hashes. Note that each carrier has its own certificates - * @hide + * Holds the list of carrier certificate hashes. + * Note that each carrier has its own certificates. */ public static final String KEY_CARRIER_CERTIFICATE_STRING_ARRAY = "carrier_certificate_string_array"; @@ -3431,6 +3395,7 @@ public class CarrierConfigManager { sDefaults.putInt(KEY_CARRIER_DEFAULT_WFC_IMS_MODE_INT, 2); sDefaults.putInt(KEY_CARRIER_DEFAULT_WFC_IMS_ROAMING_MODE_INT, 2); sDefaults.putBoolean(KEY_CARRIER_FORCE_DISABLE_ETWS_CMAS_TEST_BOOL, false); + sDefaults.putBoolean(KEY_CARRIER_RCS_PROVISIONING_REQUIRED_BOOL, true); sDefaults.putBoolean(KEY_CARRIER_VOLTE_PROVISIONING_REQUIRED_BOOL, false); sDefaults.putBoolean(KEY_CARRIER_UT_PROVISIONING_REQUIRED_BOOL, false); sDefaults.putBoolean(KEY_CARRIER_SUPPORTS_SS_OVER_UT_BOOL, false); @@ -3556,7 +3521,7 @@ public class CarrierConfigManager { sDefaults.putInt(KEY_IMS_DTMF_TONE_DELAY_INT, 0); sDefaults.putInt(KEY_CDMA_DTMF_TONE_DELAY_INT, 100); sDefaults.putBoolean(KEY_CALL_FORWARDING_MAP_NON_NUMBER_TO_VOICEMAIL_BOOL, false); - sDefaults.putBoolean(KEY_IGNORE_RTT_MODE_SETTING_BOOL, true); + sDefaults.putBoolean(KEY_IGNORE_RTT_MODE_SETTING_BOOL, false); sDefaults.putInt(KEY_CDMA_3WAYCALL_FLASH_DELAY_INT , 0); sDefaults.putBoolean(KEY_SUPPORT_CONFERENCE_CALL_BOOL, true); sDefaults.putBoolean(KEY_SUPPORT_IMS_CONFERENCE_CALL_BOOL, true); @@ -3841,6 +3806,8 @@ public class CarrierConfigManager { /* Default value is 3 seconds. */ sDefaults.putLong(KEY_OPPORTUNISTIC_NETWORK_DATA_SWITCH_EXIT_HYSTERESIS_TIME_LONG, 3000); sDefaults.putBoolean(KEY_PING_TEST_BEFORE_DATA_SWITCH_BOOL, true); + /* Default value is 1 hour. */ + sDefaults.putLong(KEY_5G_WATCHDOG_TIME_MS_LONG, 3600000); sDefaults.putAll(Gps.getDefaults()); sDefaults.putIntArray(KEY_CDMA_ENHANCED_ROAMING_INDICATOR_FOR_HOME_NETWORK_INT_ARRAY, new int[] { @@ -3896,7 +3863,8 @@ public class CarrierConfigManager { + " ICarrierConfigLoader is null"); return null; } - return loader.getConfigForSubId(subId, mContext.getOpPackageName()); + return loader.getConfigForSubIdWithFeature(subId, mContext.getOpPackageName(), + null); } catch (RemoteException ex) { Rlog.e(TAG, "Error getting config for subId " + subId + ": " + ex.toString()); diff --git a/telephony/java/android/telephony/CbGeoUtils.java b/telephony/java/android/telephony/CbGeoUtils.java index 84be4e8b9ba4..719ba8d98773 100644 --- a/telephony/java/android/telephony/CbGeoUtils.java +++ b/telephony/java/android/telephony/CbGeoUtils.java @@ -16,6 +16,8 @@ package android.telephony; +import com.android.telephony.Rlog; + import android.annotation.NonNull; import android.annotation.SystemApi; import android.text.TextUtils; diff --git a/telephony/java/android/telephony/CellIdentity.java b/telephony/java/android/telephony/CellIdentity.java index b7dab161c331..399b1a4f25de 100644 --- a/telephony/java/android/telephony/CellIdentity.java +++ b/telephony/java/android/telephony/CellIdentity.java @@ -16,13 +16,19 @@ package android.telephony; +import com.android.telephony.Rlog; + import android.annotation.CallSuper; import android.annotation.NonNull; import android.annotation.Nullable; +import android.annotation.SystemApi; +import android.hardware.radio.V1_0.CellInfoType; import android.os.Parcel; import android.os.Parcelable; import android.text.TextUtils; +import com.android.telephony.Rlog; + import java.util.Objects; import java.util.UUID; @@ -181,7 +187,17 @@ public abstract class CellIdentity implements Parcelable { * @return a CellLocation object for this CellIdentity * @hide */ - public abstract CellLocation asCellLocation(); + @SystemApi + public abstract @NonNull CellLocation asCellLocation(); + + /** + * Create and a return a new instance of CellIdentity with location-identifying information + * removed. + * + * @hide + */ + @SystemApi + public abstract @NonNull CellIdentity sanitizeLocationInfo(); @Override public boolean equals(Object other) { @@ -310,4 +326,103 @@ public abstract class CellIdentity implements Parcelable { return true; } + /** @hide */ + public static CellIdentity create(android.hardware.radio.V1_0.CellIdentity cellIdentity) { + if (cellIdentity == null) return null; + switch(cellIdentity.cellInfoType) { + case CellInfoType.GSM: { + if (cellIdentity.cellIdentityGsm.size() == 1) { + return new CellIdentityGsm(cellIdentity.cellIdentityGsm.get(0)); + } + break; + } + case CellInfoType.WCDMA: { + if (cellIdentity.cellIdentityWcdma.size() == 1) { + return new CellIdentityWcdma(cellIdentity.cellIdentityWcdma.get(0)); + } + break; + } + case CellInfoType.TD_SCDMA: { + if (cellIdentity.cellIdentityTdscdma.size() == 1) { + return new CellIdentityTdscdma(cellIdentity.cellIdentityTdscdma.get(0)); + } + break; + } + case CellInfoType.LTE: { + if (cellIdentity.cellIdentityLte.size() == 1) { + return new CellIdentityLte(cellIdentity.cellIdentityLte.get(0)); + } + break; + } + case CellInfoType.CDMA: { + if (cellIdentity.cellIdentityCdma.size() == 1) { + return new CellIdentityCdma(cellIdentity.cellIdentityCdma.get(0)); + } + break; + } + case CellInfoType.NONE: break; + default: break; + } + return null; + } + + /** @hide */ + public static CellIdentity create(android.hardware.radio.V1_2.CellIdentity cellIdentity) { + if (cellIdentity == null) return null; + switch(cellIdentity.cellInfoType) { + case CellInfoType.GSM: { + if (cellIdentity.cellIdentityGsm.size() == 1) { + return new CellIdentityGsm(cellIdentity.cellIdentityGsm.get(0)); + } + break; + } + case CellInfoType.WCDMA: { + if (cellIdentity.cellIdentityWcdma.size() == 1) { + return new CellIdentityWcdma(cellIdentity.cellIdentityWcdma.get(0)); + } + break; + } + case CellInfoType.TD_SCDMA: { + if (cellIdentity.cellIdentityTdscdma.size() == 1) { + return new CellIdentityTdscdma(cellIdentity.cellIdentityTdscdma.get(0)); + } + break; + } + case CellInfoType.LTE: { + if (cellIdentity.cellIdentityLte.size() == 1) { + return new CellIdentityLte(cellIdentity.cellIdentityLte.get(0)); + } + break; + } + case CellInfoType.CDMA: { + if (cellIdentity.cellIdentityCdma.size() == 1) { + return new CellIdentityCdma(cellIdentity.cellIdentityCdma.get(0)); + } + break; + } + case CellInfoType.NONE: break; + default: break; + } + return null; + } + + /** @hide */ + public static CellIdentity create(android.hardware.radio.V1_5.CellIdentity ci) { + if (ci == null) return null; + switch (ci.getDiscriminator()) { + case android.hardware.radio.V1_5.CellIdentity.hidl_discriminator.gsm: + return new CellIdentityGsm(ci.gsm()); + case android.hardware.radio.V1_5.CellIdentity.hidl_discriminator.cdma: + return new CellIdentityCdma(ci.cdma()); + case android.hardware.radio.V1_5.CellIdentity.hidl_discriminator.lte: + return new CellIdentityLte(ci.lte()); + case android.hardware.radio.V1_5.CellIdentity.hidl_discriminator.wcdma: + return new CellIdentityWcdma(ci.wcdma()); + case android.hardware.radio.V1_5.CellIdentity.hidl_discriminator.tdscdma: + return new CellIdentityTdscdma(ci.tdscdma()); + case android.hardware.radio.V1_5.CellIdentity.hidl_discriminator.nr: + return new CellIdentityNr(ci.nr()); + default: return null; + } + } } diff --git a/telephony/java/android/telephony/CellIdentityCdma.java b/telephony/java/android/telephony/CellIdentityCdma.java index 880d3db681b5..1a6bf33cec71 100644 --- a/telephony/java/android/telephony/CellIdentityCdma.java +++ b/telephony/java/android/telephony/CellIdentityCdma.java @@ -16,6 +16,7 @@ package android.telephony; +import android.annotation.NonNull; import android.os.Parcel; import android.telephony.cdma.CdmaCellLocation; @@ -127,7 +128,8 @@ public final class CellIdentityCdma extends CellIdentity { } /** @hide */ - public CellIdentityCdma sanitizeLocationInfo() { + @Override + public @NonNull CellIdentityCdma sanitizeLocationInfo() { return new CellIdentityCdma(CellInfo.UNAVAILABLE, CellInfo.UNAVAILABLE, CellInfo.UNAVAILABLE, CellInfo.UNAVAILABLE, CellInfo.UNAVAILABLE, mAlphaLong, mAlphaShort); @@ -198,6 +200,7 @@ public final class CellIdentityCdma extends CellIdentity { } /** @hide */ + @NonNull @Override public CdmaCellLocation asCellLocation() { CdmaCellLocation cl = new CdmaCellLocation(); diff --git a/telephony/java/android/telephony/CellIdentityGsm.java b/telephony/java/android/telephony/CellIdentityGsm.java index 25c6577bdcf5..49f425acead6 100644 --- a/telephony/java/android/telephony/CellIdentityGsm.java +++ b/telephony/java/android/telephony/CellIdentityGsm.java @@ -16,8 +16,9 @@ package android.telephony; +import android.annotation.NonNull; import android.annotation.Nullable; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.os.Parcel; import android.telephony.gsm.GsmCellLocation; import android.text.TextUtils; @@ -103,7 +104,8 @@ public final class CellIdentityGsm extends CellIdentity { } /** @hide */ - public CellIdentityGsm sanitizeLocationInfo() { + @Override + public @NonNull CellIdentityGsm sanitizeLocationInfo() { return new CellIdentityGsm(CellInfo.UNAVAILABLE, CellInfo.UNAVAILABLE, CellInfo.UNAVAILABLE, CellInfo.UNAVAILABLE, mMccStr, mMncStr, mAlphaLong, mAlphaShort); } @@ -200,6 +202,7 @@ public final class CellIdentityGsm extends CellIdentity { } /** @hide */ + @NonNull @Override public GsmCellLocation asCellLocation() { GsmCellLocation cl = new GsmCellLocation(); diff --git a/telephony/java/android/telephony/CellIdentityLte.java b/telephony/java/android/telephony/CellIdentityLte.java index 997b19f3d4eb..bc4655069dba 100644 --- a/telephony/java/android/telephony/CellIdentityLte.java +++ b/telephony/java/android/telephony/CellIdentityLte.java @@ -16,8 +16,9 @@ package android.telephony; +import android.annotation.NonNull; import android.annotation.Nullable; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.os.Build; import android.os.Parcel; import android.telephony.gsm.GsmCellLocation; @@ -120,7 +121,8 @@ public final class CellIdentityLte extends CellIdentity { } /** @hide */ - public CellIdentityLte sanitizeLocationInfo() { + @Override + public @NonNull CellIdentityLte sanitizeLocationInfo() { return new CellIdentityLte(CellInfo.UNAVAILABLE, CellInfo.UNAVAILABLE, CellInfo.UNAVAILABLE, CellInfo.UNAVAILABLE, CellInfo.UNAVAILABLE, mMccStr, mMncStr, mAlphaLong, mAlphaShort); @@ -232,6 +234,7 @@ public final class CellIdentityLte extends CellIdentity { * * @hide */ + @NonNull @Override public GsmCellLocation asCellLocation() { GsmCellLocation cl = new GsmCellLocation(); diff --git a/telephony/java/android/telephony/CellIdentityNr.java b/telephony/java/android/telephony/CellIdentityNr.java index edc838c163db..f08a5807c2b6 100644 --- a/telephony/java/android/telephony/CellIdentityNr.java +++ b/telephony/java/android/telephony/CellIdentityNr.java @@ -17,6 +17,7 @@ package android.telephony; import android.annotation.IntRange; +import android.annotation.NonNull; import android.annotation.Nullable; import android.os.Parcel; import android.telephony.gsm.GsmCellLocation; @@ -68,7 +69,8 @@ public final class CellIdentityNr extends CellIdentity { } /** @hide */ - public CellIdentityNr sanitizeLocationInfo() { + @Override + public @NonNull CellIdentityNr sanitizeLocationInfo() { return new CellIdentityNr(CellInfo.UNAVAILABLE, CellInfo.UNAVAILABLE, CellInfo.UNAVAILABLE, mMccStr, mMncStr, CellInfo.UNAVAILABLE, mAlphaLong, mAlphaShort); } @@ -77,6 +79,7 @@ public final class CellIdentityNr extends CellIdentity { * @return a CellLocation object for this CellIdentity. * @hide */ + @NonNull @Override public CellLocation asCellLocation() { return new GsmCellLocation(); diff --git a/telephony/java/android/telephony/CellIdentityTdscdma.java b/telephony/java/android/telephony/CellIdentityTdscdma.java index 558e346284ea..4bb3a95a9f1d 100644 --- a/telephony/java/android/telephony/CellIdentityTdscdma.java +++ b/telephony/java/android/telephony/CellIdentityTdscdma.java @@ -97,7 +97,8 @@ public final class CellIdentityTdscdma extends CellIdentity { } /** @hide */ - public CellIdentityTdscdma sanitizeLocationInfo() { + @Override + public @NonNull CellIdentityTdscdma sanitizeLocationInfo() { return new CellIdentityTdscdma(mMccStr, mMncStr, CellInfo.UNAVAILABLE, CellInfo.UNAVAILABLE, CellInfo.UNAVAILABLE, CellInfo.UNAVAILABLE, mAlphaLong, mAlphaShort); } @@ -171,6 +172,7 @@ public final class CellIdentityTdscdma extends CellIdentity { } /** @hide */ + @NonNull @Override public GsmCellLocation asCellLocation() { GsmCellLocation cl = new GsmCellLocation(); diff --git a/telephony/java/android/telephony/CellIdentityWcdma.java b/telephony/java/android/telephony/CellIdentityWcdma.java index 031fed13d9f1..4ecd134c4ba9 100644 --- a/telephony/java/android/telephony/CellIdentityWcdma.java +++ b/telephony/java/android/telephony/CellIdentityWcdma.java @@ -16,8 +16,9 @@ package android.telephony; +import android.annotation.NonNull; import android.annotation.Nullable; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.os.Parcel; import android.telephony.gsm.GsmCellLocation; import android.text.TextUtils; @@ -97,7 +98,8 @@ public final class CellIdentityWcdma extends CellIdentity { } /** @hide */ - public CellIdentityWcdma sanitizeLocationInfo() { + @Override + public @NonNull CellIdentityWcdma sanitizeLocationInfo() { return new CellIdentityWcdma(CellInfo.UNAVAILABLE, CellInfo.UNAVAILABLE, CellInfo.UNAVAILABLE, CellInfo.UNAVAILABLE, mMccStr, mMncStr, mAlphaLong, mAlphaShort); @@ -196,6 +198,7 @@ public final class CellIdentityWcdma extends CellIdentity { } /** @hide */ + @NonNull @Override public GsmCellLocation asCellLocation() { GsmCellLocation cl = new GsmCellLocation(); diff --git a/telephony/java/android/telephony/CellInfo.java b/telephony/java/android/telephony/CellInfo.java index ae45307f19f0..ec86c144c08e 100644 --- a/telephony/java/android/telephony/CellInfo.java +++ b/telephony/java/android/telephony/CellInfo.java @@ -18,7 +18,8 @@ package android.telephony; import android.annotation.IntDef; import android.annotation.NonNull; -import android.annotation.UnsupportedAppUsage; +import android.annotation.SuppressLint; +import android.compat.annotation.UnsupportedAppUsage; import android.hardware.radio.V1_4.CellInfo.Info; import android.os.Parcel; import android.os.Parcelable; @@ -179,6 +180,18 @@ public abstract class CellInfo implements Parcelable { * * @return a time stamp in nanos since boot. */ + @SuppressLint("MethodNameUnits") + public long getTimestampNanos() { + return mTimeStamp; + } + + /** + * Approximate time this cell information was received from the modem. + * + * @return a time stamp in nanos since boot. + * @deprecated Use {@link #getTimestampNanos} instead. + */ + @Deprecated public long getTimeStamp() { return mTimeStamp; } diff --git a/telephony/java/android/telephony/CellInfoCdma.java b/telephony/java/android/telephony/CellInfoCdma.java index 30b131faf51d..acb21f450243 100644 --- a/telephony/java/android/telephony/CellInfoCdma.java +++ b/telephony/java/android/telephony/CellInfoCdma.java @@ -16,12 +16,13 @@ package android.telephony; +import com.android.telephony.Rlog; + import android.annotation.NonNull; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.os.Build; import android.os.Parcel; import android.os.Parcelable; -import android.telephony.Rlog; /** * A {@link CellInfo} representing a CDMA cell that provides identity and measurement info. diff --git a/telephony/java/android/telephony/CellInfoGsm.java b/telephony/java/android/telephony/CellInfoGsm.java index 137f97eeee62..79a9d44f36a2 100644 --- a/telephony/java/android/telephony/CellInfoGsm.java +++ b/telephony/java/android/telephony/CellInfoGsm.java @@ -16,11 +16,12 @@ package android.telephony; +import com.android.telephony.Rlog; + import android.annotation.NonNull; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.os.Parcel; import android.os.Parcelable; -import android.telephony.Rlog; /** * A {@link CellInfo} representing a GSM cell that provides identity and measurement info. diff --git a/telephony/java/android/telephony/CellInfoLte.java b/telephony/java/android/telephony/CellInfoLte.java index da7b7ab1488d..fed3ebf4af03 100644 --- a/telephony/java/android/telephony/CellInfoLte.java +++ b/telephony/java/android/telephony/CellInfoLte.java @@ -16,8 +16,10 @@ package android.telephony; +import com.android.telephony.Rlog; + import android.annotation.NonNull; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.os.Build; import android.os.Parcel; import android.os.Parcelable; diff --git a/telephony/java/android/telephony/CellInfoTdscdma.java b/telephony/java/android/telephony/CellInfoTdscdma.java index f1305f5ca768..58ff8c9558d9 100644 --- a/telephony/java/android/telephony/CellInfoTdscdma.java +++ b/telephony/java/android/telephony/CellInfoTdscdma.java @@ -16,6 +16,8 @@ package android.telephony; +import com.android.telephony.Rlog; + import android.annotation.NonNull; import android.os.Parcel; import android.os.Parcelable; diff --git a/telephony/java/android/telephony/CellInfoWcdma.java b/telephony/java/android/telephony/CellInfoWcdma.java index ee5fec838d2d..33f6a555414c 100644 --- a/telephony/java/android/telephony/CellInfoWcdma.java +++ b/telephony/java/android/telephony/CellInfoWcdma.java @@ -18,7 +18,7 @@ package android.telephony; import android.os.Parcel; import android.os.Parcelable; -import android.telephony.Rlog; +import com.android.telephony.Rlog; import java.util.Objects; diff --git a/telephony/java/android/telephony/CellLocation.java b/telephony/java/android/telephony/CellLocation.java index 01331535205c..64776e377fa4 100644 --- a/telephony/java/android/telephony/CellLocation.java +++ b/telephony/java/android/telephony/CellLocation.java @@ -16,13 +16,13 @@ package android.telephony; +import android.compat.annotation.UnsupportedAppUsage; import android.os.Bundle; import android.os.RemoteException; import android.os.ServiceManager; - -import android.annotation.UnsupportedAppUsage; import android.telephony.cdma.CdmaCellLocation; import android.telephony.gsm.GsmCellLocation; + import com.android.internal.telephony.ITelephony; import com.android.internal.telephony.PhoneConstants; diff --git a/telephony/java/android/telephony/CellSignalStrengthCdma.java b/telephony/java/android/telephony/CellSignalStrengthCdma.java index 199843905854..cab3b0cd3c47 100644 --- a/telephony/java/android/telephony/CellSignalStrengthCdma.java +++ b/telephony/java/android/telephony/CellSignalStrengthCdma.java @@ -20,7 +20,7 @@ import android.annotation.IntRange; import android.os.Parcel; import android.os.Parcelable; import android.os.PersistableBundle; -import android.telephony.Rlog; +import com.android.telephony.Rlog; import java.util.Objects; diff --git a/telephony/java/android/telephony/CellSignalStrengthGsm.java b/telephony/java/android/telephony/CellSignalStrengthGsm.java index fb16d540fbb4..28052aa93486 100644 --- a/telephony/java/android/telephony/CellSignalStrengthGsm.java +++ b/telephony/java/android/telephony/CellSignalStrengthGsm.java @@ -16,13 +16,14 @@ package android.telephony; +import com.android.telephony.Rlog; + import android.annotation.IntRange; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.os.Build; import android.os.Parcel; import android.os.Parcelable; import android.os.PersistableBundle; -import android.telephony.Rlog; import java.util.Objects; diff --git a/telephony/java/android/telephony/CellSignalStrengthLte.java b/telephony/java/android/telephony/CellSignalStrengthLte.java index 8df9d23598eb..2ef2a52977ff 100644 --- a/telephony/java/android/telephony/CellSignalStrengthLte.java +++ b/telephony/java/android/telephony/CellSignalStrengthLte.java @@ -16,8 +16,10 @@ package android.telephony; +import com.android.telephony.Rlog; + import android.annotation.IntRange; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.os.Parcel; import android.os.Parcelable; import android.os.PersistableBundle; diff --git a/telephony/java/android/telephony/CellSignalStrengthNr.java b/telephony/java/android/telephony/CellSignalStrengthNr.java index f31fafe36508..4d67bcf536cf 100644 --- a/telephony/java/android/telephony/CellSignalStrengthNr.java +++ b/telephony/java/android/telephony/CellSignalStrengthNr.java @@ -16,6 +16,8 @@ package android.telephony; +import com.android.telephony.Rlog; + import android.annotation.IntDef; import android.annotation.IntRange; import android.os.Parcel; @@ -155,7 +157,17 @@ public final class CellSignalStrengthNr extends CellSignalStrength implements Pa * @param ss signal strength from modem. */ public CellSignalStrengthNr(android.hardware.radio.V1_4.NrSignalStrength ss) { - this(ss.csiRsrp, ss.csiRsrq, ss.csiSinr, ss.ssRsrp, ss.ssRsrq, ss.ssSinr); + this(flip(ss.csiRsrp), flip(ss.csiRsrq), ss.csiSinr, flip(ss.ssRsrp), flip(ss.ssRsrq), + ss.ssSinr); + } + + /** + * Flip sign cell strength value when taking in the value from hal + * @param val cell strength value + * @return flipped value + */ + private static int flip(int val) { + return val != CellInfo.UNAVAILABLE ? -val : val; } /** diff --git a/telephony/java/android/telephony/CellSignalStrengthTdscdma.java b/telephony/java/android/telephony/CellSignalStrengthTdscdma.java index f4a3dbb37988..3bd9d5810136 100644 --- a/telephony/java/android/telephony/CellSignalStrengthTdscdma.java +++ b/telephony/java/android/telephony/CellSignalStrengthTdscdma.java @@ -16,6 +16,8 @@ package android.telephony; +import com.android.telephony.Rlog; + import android.annotation.IntRange; import android.annotation.NonNull; import android.os.Parcel; diff --git a/telephony/java/android/telephony/CellSignalStrengthWcdma.java b/telephony/java/android/telephony/CellSignalStrengthWcdma.java index 4dc54f0fef58..535e9520074d 100644 --- a/telephony/java/android/telephony/CellSignalStrengthWcdma.java +++ b/telephony/java/android/telephony/CellSignalStrengthWcdma.java @@ -16,13 +16,14 @@ package android.telephony; +import com.android.telephony.Rlog; + import android.annotation.IntRange; import android.annotation.StringDef; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.os.Parcel; import android.os.Parcelable; import android.os.PersistableBundle; -import android.telephony.Rlog; import android.text.TextUtils; import java.lang.annotation.Retention; diff --git a/telephony/java/android/telephony/DisconnectCause.java b/telephony/java/android/telephony/DisconnectCause.java index 04ec4b6949af..aff1391fc080 100644 --- a/telephony/java/android/telephony/DisconnectCause.java +++ b/telephony/java/android/telephony/DisconnectCause.java @@ -18,7 +18,7 @@ package android.telephony; import android.annotation.NonNull; import android.annotation.SystemApi; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; /** * Describes the cause of a disconnected call. Those disconnect causes can be converted into a more diff --git a/telephony/java/android/telephony/ImsManager.java b/telephony/java/android/telephony/ImsManager.java index 39af34c0e0f0..c706d288b7f2 100644 --- a/telephony/java/android/telephony/ImsManager.java +++ b/telephony/java/android/telephony/ImsManager.java @@ -17,6 +17,8 @@ package android.telephony.ims; import android.annotation.NonNull; +import android.annotation.SdkConstant; +import android.annotation.SuppressLint; import android.annotation.SystemApi; import android.annotation.SystemService; import android.annotation.TestApi; @@ -35,7 +37,26 @@ public class ImsManager { private Context mContext; - /** @hide */ + /** + * <p>Broadcast Action: Indicates that an IMS operation was rejected by the network due to it + * not being authorized on the network. + * May include the {@link SubscriptionManager#EXTRA_SUBSCRIPTION_INDEX} extra to also specify + * which subscription the operation was rejected for. + * <p class="note"> + * Carrier applications may listen to this broadcast to be notified of possible IMS provisioning + * issues. + */ + // Moved from TelephonyIntents, need to keep backwards compatibility with OEM apps that have + // this value hard-coded in BroadcastReceiver. + @SuppressLint("ActionValue") + @SdkConstant(SdkConstant.SdkConstantType.BROADCAST_INTENT_ACTION) + public static final String ACTION_FORBIDDEN_NO_SERVICE_AUTHORIZATION = + "com.android.internal.intent.action.ACTION_FORBIDDEN_NO_SERVICE_AUTHORIZATION"; + + /** + * Use {@link Context#getSystemService(String)} to get an instance of this class. + * @hide + */ public ImsManager(@NonNull Context context) { mContext = context; } diff --git a/telephony/java/android/telephony/JapanesePhoneNumberFormatter.java b/telephony/java/android/telephony/JapanesePhoneNumberFormatter.java index 92a674c57688..1c31368d8443 100644 --- a/telephony/java/android/telephony/JapanesePhoneNumberFormatter.java +++ b/telephony/java/android/telephony/JapanesePhoneNumberFormatter.java @@ -16,7 +16,7 @@ package android.telephony; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.text.Editable; /* diff --git a/telephony/java/android/telephony/NeighboringCellInfo.java b/telephony/java/android/telephony/NeighboringCellInfo.java index 023ed305ef50..5f4679918998 100644 --- a/telephony/java/android/telephony/NeighboringCellInfo.java +++ b/telephony/java/android/telephony/NeighboringCellInfo.java @@ -24,7 +24,7 @@ import static android.telephony.TelephonyManager.NETWORK_TYPE_HSUPA; import static android.telephony.TelephonyManager.NETWORK_TYPE_UMTS; import static android.telephony.TelephonyManager.NETWORK_TYPE_UNKNOWN; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.os.Build; import android.os.Parcel; import android.os.Parcelable; diff --git a/telephony/java/android/telephony/NetworkRegistrationInfo.java b/telephony/java/android/telephony/NetworkRegistrationInfo.java index fc717e7465b1..32ffb75f373c 100644 --- a/telephony/java/android/telephony/NetworkRegistrationInfo.java +++ b/telephony/java/android/telephony/NetworkRegistrationInfo.java @@ -36,23 +36,24 @@ import java.util.stream.Collectors; /** * Description of a mobile network registration info - * @hide */ -@SystemApi -@TestApi public final class NetworkRegistrationInfo implements Parcelable { /** * Network domain * @hide */ @Retention(RetentionPolicy.SOURCE) - @IntDef(prefix = "DOMAIN_", value = {DOMAIN_CS, DOMAIN_PS}) + @IntDef(prefix = "DOMAIN_", value = {DOMAIN_UNKNOWN, DOMAIN_CS, DOMAIN_PS, DOMAIN_CS_PS}) public @interface Domain {} - /** Circuit switching domain */ - public static final int DOMAIN_CS = 1; - /** Packet switching domain */ - public static final int DOMAIN_PS = 2; + /** Unknown / Unspecified domain */ + public static final int DOMAIN_UNKNOWN = 0; + /** Circuit switched domain */ + public static final int DOMAIN_CS = android.hardware.radio.V1_5.Domain.CS; + /** Packet switched domain */ + public static final int DOMAIN_PS = android.hardware.radio.V1_5.Domain.PS; + /** Applicable to both CS and PS Domain */ + public static final int DOMAIN_CS_PS = DOMAIN_CS | DOMAIN_PS; /** * Network registration state @@ -65,17 +66,41 @@ public final class NetworkRegistrationInfo implements Parcelable { REGISTRATION_STATE_UNKNOWN, REGISTRATION_STATE_ROAMING}) public @interface RegistrationState {} - /** Not registered. The device is not currently searching a new operator to register. */ + /** + * Not registered. The device is not currently searching a new operator to register. + * @hide + */ + @SystemApi @TestApi public static final int REGISTRATION_STATE_NOT_REGISTERED_OR_SEARCHING = 0; - /** Registered on home network. */ + /** + * Registered on home network. + * @hide + */ + @SystemApi @TestApi public static final int REGISTRATION_STATE_HOME = 1; - /** Not registered. The device is currently searching a new operator to register. */ + /** + * Not registered. The device is currently searching a new operator to register. + * @hide + */ + @SystemApi @TestApi public static final int REGISTRATION_STATE_NOT_REGISTERED_SEARCHING = 2; - /** Registration denied. */ + /** + * Registration denied. + * @hide + */ + @SystemApi @TestApi public static final int REGISTRATION_STATE_DENIED = 3; - /** Registration state is unknown. */ + /** + * Registration state is unknown. + * @hide + */ + @SystemApi @TestApi public static final int REGISTRATION_STATE_UNKNOWN = 4; - /** Registered on roaming network. */ + /** + * Registered on roaming network. + * @hide + */ + @SystemApi @TestApi public static final int REGISTRATION_STATE_ROAMING = 5; /** @hide */ @@ -88,7 +113,6 @@ public final class NetworkRegistrationInfo implements Parcelable { /** * The device isn't camped on an LTE cell or the LTE cell doesn't support E-UTRA-NR * Dual Connectivity(EN-DC). - * @hide */ public static final int NR_STATE_NONE = 0; @@ -96,7 +120,6 @@ public final class NetworkRegistrationInfo implements Parcelable { * The device is camped on an LTE cell that supports E-UTRA-NR Dual Connectivity(EN-DC) but * either the use of dual connectivity with NR(DCNR) is restricted or NR is not supported by * the selected PLMN. - * @hide */ public static final int NR_STATE_RESTRICTED = 1; @@ -104,14 +127,12 @@ public final class NetworkRegistrationInfo implements Parcelable { * The device is camped on an LTE cell that supports E-UTRA-NR Dual Connectivity(EN-DC) and both * the use of dual connectivity with NR(DCNR) is not restricted and NR is supported by the * selected PLMN. - * @hide */ public static final int NR_STATE_NOT_RESTRICTED = 2; /** * The device is camped on an LTE cell that supports E-UTRA-NR Dual Connectivity(EN-DC) and * also connected to at least one 5G cell as a secondary serving cell. - * @hide */ public static final int NR_STATE_CONNECTED = 3; @@ -125,22 +146,34 @@ public final class NetworkRegistrationInfo implements Parcelable { SERVICE_TYPE_VIDEO, SERVICE_TYPE_EMERGENCY}) public @interface ServiceType {} - /** Unkown service */ + /** + * Unknown service + */ public static final int SERVICE_TYPE_UNKNOWN = 0; - /** Voice service */ + /** + * Voice service + */ public static final int SERVICE_TYPE_VOICE = 1; - /** Data service */ + /** + * Data service + */ public static final int SERVICE_TYPE_DATA = 2; - /** SMS service */ + /** + * SMS service + */ public static final int SERVICE_TYPE_SMS = 3; - /** Video service */ + /** + * Video service + */ public static final int SERVICE_TYPE_VIDEO = 4; - /** Emergency service */ + /** + * Emergency service + */ public static final int SERVICE_TYPE_EMERGENCY = 5; @Domain @@ -326,9 +359,7 @@ public final class NetworkRegistrationInfo implements Parcelable { * Get the 5G NR connection state. * * @return the 5G NR connection state. - * @hide */ - @SystemApi public @NRState int getNrState() { return mNrState; } @@ -340,7 +371,10 @@ public final class NetworkRegistrationInfo implements Parcelable { /** * @return The registration state. + * + * @hide */ + @SystemApi @TestApi public @RegistrationState int getRegistrationState() { return mRegistrationState; } @@ -348,6 +382,21 @@ public final class NetworkRegistrationInfo implements Parcelable { /** * @return {@code true} if registered on roaming network, {@code false} otherwise. */ + public boolean isRegistered() { + return mRegistrationState == REGISTRATION_STATE_HOME + || mRegistrationState == REGISTRATION_STATE_ROAMING; + } + + /** + * @return {@code true} if registered on roaming network, {@code false} otherwise. + */ + public boolean isSearching() { + return mRegistrationState == REGISTRATION_STATE_NOT_REGISTERED_SEARCHING; + } + + /** + * @return {@code true} if registered on roaming network, {@code false} otherwise. + */ public boolean isRoaming() { return mRoamingType != ServiceState.ROAMING_TYPE_NOT_ROAMING; } @@ -372,15 +421,18 @@ public final class NetworkRegistrationInfo implements Parcelable { /** * @return the current network roaming type. + * @hide */ - + @SystemApi @TestApi public @ServiceState.RoamingType int getRoamingType() { return mRoamingType; } /** * @return Whether emergency is enabled. + * @hide */ + @SystemApi @TestApi public boolean isEmergencyEnabled() { return mEmergencyOnly; } /** @@ -418,7 +470,9 @@ public final class NetworkRegistrationInfo implements Parcelable { * @return Reason for denial if the registration state is {@link #REGISTRATION_STATE_DENIED}. * Depending on {@code accessNetworkTechnology}, the values are defined in 3GPP TS 24.008 * 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 public int getRejectCause() { return mRejectCause; } @@ -441,8 +495,10 @@ public final class NetworkRegistrationInfo implements Parcelable { /** * @return Data registration related info + * @hide */ @Nullable + @SystemApi @TestApi public DataSpecificRegistrationInfo getDataSpecificInfo() { return mDataSpecificInfo; } @@ -504,11 +560,21 @@ public final class NetworkRegistrationInfo implements Parcelable { } } + /** @hide */ + static @NonNull String domainToString(@Domain int domain) { + switch (domain) { + case DOMAIN_CS: return "CS"; + case DOMAIN_PS: return "PS"; + case DOMAIN_CS_PS: return "CS_PS"; + default: return "UNKNOWN"; + } + } + @NonNull @Override public String toString() { return new StringBuilder("NetworkRegistrationInfo{") - .append(" domain=").append((mDomain == DOMAIN_CS) ? "CS" : "PS") + .append(" domain=").append(domainToString(mDomain)) .append(" transportType=").append( AccessNetworkConstants.transportTypeToString(mTransportType)) .append(" registrationState=").append(registrationStateToString(mRegistrationState)) @@ -557,7 +623,11 @@ public final class NetworkRegistrationInfo implements Parcelable { && mNrState == other.mNrState; } + /** + * @hide + */ @Override + @SystemApi @TestApi public void writeToParcel(Parcel dest, int flags) { dest.writeInt(mDomain); dest.writeInt(mTransportType); @@ -645,8 +715,10 @@ public final class NetworkRegistrationInfo implements Parcelable { * .setRegistrationState(REGISTRATION_STATE_HOME) * .build(); * </code></pre> + * @hide */ - public static final class Builder{ + @SystemApi @TestApi + public static final class Builder { @Domain private int mDomain; @@ -745,7 +817,9 @@ public final class NetworkRegistrationInfo implements Parcelable { * @param emergencyOnly True if this network registration is for emergency use only. * * @return The same instance of the builder. + * @hide */ + @SystemApi @TestApi public @NonNull Builder setEmergencyOnly(boolean emergencyOnly) { mEmergencyOnly = emergencyOnly; return this; @@ -757,7 +831,9 @@ public final class NetworkRegistrationInfo implements Parcelable { * @param availableServices Available services. * * @return The same instance of the builder. + * @hide */ + @SystemApi @TestApi public @NonNull Builder setAvailableServices( @NonNull @ServiceType List<Integer> availableServices) { mAvailableServices = availableServices; @@ -770,7 +846,9 @@ public final class NetworkRegistrationInfo implements Parcelable { * @param cellIdentity The cell identity. * * @return The same instance of the builder. + * @hide */ + @SystemApi @TestApi public @NonNull Builder setCellIdentity(@Nullable CellIdentity cellIdentity) { mCellIdentity = cellIdentity; return this; @@ -778,9 +856,10 @@ public final class NetworkRegistrationInfo implements Parcelable { /** * Build the NetworkRegistrationInfo. - * * @return the NetworkRegistrationInfo object. + * @hide */ + @SystemApi @TestApi public @NonNull NetworkRegistrationInfo build() { return new NetworkRegistrationInfo(mDomain, mTransportType, mRegistrationState, mAccessNetworkTechnology, mRejectCause, mEmergencyOnly, mAvailableServices, diff --git a/telephony/java/android/telephony/NetworkScan.java b/telephony/java/android/telephony/NetworkScan.java index 202da6817cb5..c249ece92e73 100644 --- a/telephony/java/android/telephony/NetworkScan.java +++ b/telephony/java/android/telephony/NetworkScan.java @@ -16,6 +16,8 @@ package android.telephony; +import com.android.telephony.Rlog; + import android.annotation.IntDef; import android.content.Context; import android.os.RemoteException; diff --git a/telephony/java/android/telephony/NetworkService.java b/telephony/java/android/telephony/NetworkService.java index 8c5e10788b89..844289ce75d4 100644 --- a/telephony/java/android/telephony/NetworkService.java +++ b/telephony/java/android/telephony/NetworkService.java @@ -16,6 +16,8 @@ package android.telephony; +import com.android.telephony.Rlog; + import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.SdkConstant; diff --git a/telephony/java/android/telephony/NetworkServiceCallback.java b/telephony/java/android/telephony/NetworkServiceCallback.java index 89b96654451e..214ab41ae4f2 100644 --- a/telephony/java/android/telephony/NetworkServiceCallback.java +++ b/telephony/java/android/telephony/NetworkServiceCallback.java @@ -16,6 +16,8 @@ package android.telephony; +import com.android.telephony.Rlog; + import android.annotation.IntDef; import android.annotation.Nullable; import android.annotation.SystemApi; diff --git a/telephony/java/android/telephony/PhoneNumberFormattingTextWatcher.java b/telephony/java/android/telephony/PhoneNumberFormattingTextWatcher.java index ac6bcaa61997..d4ed860cdafd 100644 --- a/telephony/java/android/telephony/PhoneNumberFormattingTextWatcher.java +++ b/telephony/java/android/telephony/PhoneNumberFormattingTextWatcher.java @@ -16,15 +16,14 @@ package android.telephony; -import com.android.i18n.phonenumbers.AsYouTypeFormatter; -import com.android.i18n.phonenumbers.PhoneNumberUtil; - -import android.annotation.UnsupportedAppUsage; -import android.telephony.PhoneNumberUtils; +import android.compat.annotation.UnsupportedAppUsage; import android.text.Editable; import android.text.Selection; import android.text.TextWatcher; +import com.android.i18n.phonenumbers.AsYouTypeFormatter; +import com.android.i18n.phonenumbers.PhoneNumberUtil; + import java.util.Locale; /** diff --git a/telephony/java/android/telephony/PhoneNumberUtils.java b/telephony/java/android/telephony/PhoneNumberUtils.java index 67afa7d3a3c9..2f9e6ac0f9ff 100644 --- a/telephony/java/android/telephony/PhoneNumberUtils.java +++ b/telephony/java/android/telephony/PhoneNumberUtils.java @@ -16,12 +16,14 @@ package android.telephony; +import com.android.telephony.Rlog; + import android.annotation.IntDef; import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.SystemApi; import android.annotation.TestApi; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; import android.content.Intent; import android.content.res.Resources; diff --git a/telephony/java/android/telephony/PreciseCallState.java b/telephony/java/android/telephony/PreciseCallState.java index bfa6326c3c18..98eeacf1a416 100644 --- a/telephony/java/android/telephony/PreciseCallState.java +++ b/telephony/java/android/telephony/PreciseCallState.java @@ -19,14 +19,12 @@ package android.telephony; import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.SystemApi; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.os.Parcel; import android.os.Parcelable; import android.telephony.Annotation.DisconnectCauses; import android.telephony.Annotation.PreciseCallStates; import android.telephony.Annotation.PreciseDisconnectCauses; -import android.telephony.DisconnectCause; -import android.telephony.PreciseDisconnectCause; import java.util.Objects; diff --git a/telephony/java/android/telephony/PreciseDataConnectionState.java b/telephony/java/android/telephony/PreciseDataConnectionState.java index 78ad5c58423c..31434c1d2adf 100644 --- a/telephony/java/android/telephony/PreciseDataConnectionState.java +++ b/telephony/java/android/telephony/PreciseDataConnectionState.java @@ -20,7 +20,7 @@ import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.SystemApi; import android.annotation.TestApi; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.net.LinkProperties; import android.os.Build; import android.os.Parcel; @@ -81,18 +81,20 @@ public final class PreciseDataConnectionState implements Parcelable { /** - * Constructor + * Constructor of PreciseDataConnectionState * * @param state the state of the data connection * @param networkType the access network that is/would carry this data connection * @param apnTypes the APN types that this data connection carries - * @param apnSetting if there is a valid APN for this Data Connection, then the APN Settings; - * if there is no valid APN setting for the specific type, then this will be null + * @param apn the APN of this data connection * @param linkProperties if the data connection is connected, the properties of the connection * @param failCause in case a procedure related to this data connection fails, a non-zero error * code indicating the cause of the failure. + * @param apnSetting if there is a valid APN for this Data Connection, then the APN Settings; + * if there is no valid APN setting for the specific type, then this will be null * @hide */ + @SystemApi public PreciseDataConnectionState(@DataState int state, @NetworkType int networkType, @ApnType int apnTypes, @NonNull String apn, diff --git a/telephony/java/android/telephony/RadioAccessFamily.java b/telephony/java/android/telephony/RadioAccessFamily.java index 28f6515d09e5..bc8473865466 100644 --- a/telephony/java/android/telephony/RadioAccessFamily.java +++ b/telephony/java/android/telephony/RadioAccessFamily.java @@ -16,9 +16,7 @@ package android.telephony; -import android.annotation.UnsupportedAppUsage; -import android.hardware.radio.V1_0.RadioTechnology; -import android.hardware.radio.V1_4.CellInfo.Info; +import android.compat.annotation.UnsupportedAppUsage; import android.os.Build; import android.os.Parcel; import android.os.Parcelable; diff --git a/telephony/java/android/telephony/ServiceState.java b/telephony/java/android/telephony/ServiceState.java index a55f758f8ee2..ed003ed81ddc 100644 --- a/telephony/java/android/telephony/ServiceState.java +++ b/telephony/java/android/telephony/ServiceState.java @@ -21,7 +21,7 @@ import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.SystemApi; import android.annotation.TestApi; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.Intent; import android.os.Build; import android.os.Bundle; @@ -34,6 +34,8 @@ import android.telephony.NetworkRegistrationInfo.Domain; import android.telephony.NetworkRegistrationInfo.NRState; import android.text.TextUtils; +import com.android.telephony.Rlog; + import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.util.ArrayList; @@ -379,15 +381,15 @@ public class ServiceState implements Parcelable { /** * Create a new ServiceState from a intent notifier Bundle * - * This method is used by PhoneStateIntentReceiver, CellBroadcastReceiver, and maybe by - * external applications. + * This method is used to get ServiceState object from extras upon receiving + * {@link Intent#ACTION_SERVICE_STATE}. * * @param m Bundle from intent notifier * @return newly created ServiceState * @hide */ + @SystemApi @NonNull - @UnsupportedAppUsage public static ServiceState newFromBundle(@NonNull Bundle m) { ServiceState ret; ret = new ServiceState(); @@ -582,8 +584,8 @@ public class ServiceState implements Parcelable { */ @DuplexMode public int getDuplexMode() { - // only support LTE duplex mode - if (!isLte(getRilDataRadioTechnology())) { + // support LTE/NR duplex mode + if (!isPsOnlyTech(getRilDataRadioTechnology())) { return DUPLEX_MODE_UNKNOWN; } @@ -1281,11 +1283,15 @@ public class ServiceState implements Parcelable { /** * Set intent notifier Bundle based on service state. * + * Put ServiceState object and its fields into bundle which is used by TelephonyRegistry + * to broadcast {@link Intent#ACTION_SERVICE_STATE}. + * * @param m intent notifier Bundle * @hide + * */ - @UnsupportedAppUsage - public void fillInNotifierBundle(Bundle m) { + @SystemApi + public void fillInNotifierBundle(@NonNull Bundle m) { m.putParcelable(Intent.EXTRA_SERVICE_STATE, this); // serviceState already consists of below entries. // for backward compatibility, we continue fill in below entries. @@ -1618,7 +1624,8 @@ public class ServiceState implements Parcelable { * @return Current data network type * @hide */ - @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P) + @SystemApi + @TestApi public @NetworkType int getDataNetworkType() { final NetworkRegistrationInfo iwlanRegInfo = getNetworkRegistrationInfo( NetworkRegistrationInfo.DOMAIN_PS, AccessNetworkConstants.TRANSPORT_TYPE_WLAN); @@ -1711,9 +1718,10 @@ public class ServiceState implements Parcelable { } /** @hide */ - public static boolean isLte(int radioTechnology) { - return radioTechnology == RIL_RADIO_TECHNOLOGY_LTE || - radioTechnology == RIL_RADIO_TECHNOLOGY_LTE_CA; + public static boolean isPsOnlyTech(int radioTechnology) { + return radioTechnology == RIL_RADIO_TECHNOLOGY_LTE + || radioTechnology == RIL_RADIO_TECHNOLOGY_LTE_CA + || radioTechnology == RIL_RADIO_TECHNOLOGY_NR; } /** @hide */ @@ -1829,10 +1837,8 @@ public class ServiceState implements Parcelable { * Get all of the available network registration info. * * @return List of {@link NetworkRegistrationInfo} - * @hide */ @NonNull - @SystemApi public List<NetworkRegistrationInfo> getNetworkRegistrationInfoList() { synchronized (mNetworkRegistrationInfos) { List<NetworkRegistrationInfo> newList = new ArrayList<>(); @@ -1882,7 +1888,7 @@ public class ServiceState implements Parcelable { synchronized (mNetworkRegistrationInfos) { for (NetworkRegistrationInfo networkRegistrationInfo : mNetworkRegistrationInfos) { - if (networkRegistrationInfo.getDomain() == domain) { + if ((networkRegistrationInfo.getDomain() & domain) != 0) { list.add(new NetworkRegistrationInfo(networkRegistrationInfo)); } } @@ -1898,7 +1904,6 @@ public class ServiceState implements Parcelable { * @param transportType The transport type * @return The matching {@link NetworkRegistrationInfo} * @hide - * */ @Nullable @SystemApi @@ -1907,7 +1912,7 @@ public class ServiceState implements Parcelable { synchronized (mNetworkRegistrationInfos) { for (NetworkRegistrationInfo networkRegistrationInfo : mNetworkRegistrationInfos) { if (networkRegistrationInfo.getTransportType() == transportType - && networkRegistrationInfo.getDomain() == domain) { + && (networkRegistrationInfo.getDomain() & domain) != 0) { return new NetworkRegistrationInfo(networkRegistrationInfo); } } @@ -1950,9 +1955,18 @@ public class ServiceState implements Parcelable { * Returns a copy of self with location-identifying information removed. * Always clears the NetworkRegistrationInfo's CellIdentity fields, but if removeCoarseLocation * is true, clears other info as well. + * + * @param removeCoarseLocation Whether to also remove coarse location information. + * if false, it only clears fine location information such as + * NetworkRegistrationInfo's CellIdentity fields; If true, it will + * also remove other location information such as operator's MCC + * and MNC. + * @return the copied ServiceState with location info sanitized. * @hide */ - public ServiceState sanitizeLocationInfo(boolean removeCoarseLocation) { + @SystemApi + @NonNull + public ServiceState createLocationInfoSanitizedCopy(boolean removeCoarseLocation) { ServiceState state = new ServiceState(this); synchronized (state.mNetworkRegistrationInfos) { List<NetworkRegistrationInfo> networkRegistrationInfos = @@ -2032,4 +2046,27 @@ public class ServiceState implements Parcelable { public boolean isIwlanPreferred() { return mIsIwlanPreferred; } + /** + * @return {@code true}Returns True whenever the modem is searching for service. + * To check both CS and PS domain + */ + + public boolean isSearching() { + NetworkRegistrationInfo psRegState = getNetworkRegistrationInfo( + NetworkRegistrationInfo.DOMAIN_PS, AccessNetworkConstants.TRANSPORT_TYPE_WWAN); + + if (psRegState != null && psRegState.getRegistrationState() + == NetworkRegistrationInfo.REGISTRATION_STATE_NOT_REGISTERED_SEARCHING) { + return true; + } + + NetworkRegistrationInfo csRegState = getNetworkRegistrationInfo( + NetworkRegistrationInfo.DOMAIN_CS, AccessNetworkConstants.TRANSPORT_TYPE_WWAN); + + if (csRegState != null && csRegState.getRegistrationState() + == NetworkRegistrationInfo.REGISTRATION_STATE_NOT_REGISTERED_SEARCHING) { + return true; + } + return false; + } } diff --git a/telephony/java/android/telephony/SignalStrength.java b/telephony/java/android/telephony/SignalStrength.java index aac56c08bdc4..483ccc437f89 100644 --- a/telephony/java/android/telephony/SignalStrength.java +++ b/telephony/java/android/telephony/SignalStrength.java @@ -17,12 +17,17 @@ package android.telephony; import android.annotation.NonNull; -import android.annotation.UnsupportedAppUsage; +import android.annotation.SuppressLint; +import android.annotation.SystemApi; +import android.compat.annotation.UnsupportedAppUsage; import android.os.Build; import android.os.Bundle; import android.os.Parcel; import android.os.Parcelable; import android.os.PersistableBundle; +import android.os.SystemClock; + +import com.android.telephony.Rlog; import java.util.ArrayList; import java.util.List; @@ -74,6 +79,9 @@ public class SignalStrength implements Parcelable { /* The type of signal measurement */ private static final String MEASUREMENT_TYPE_RSCP = "rscp"; + // timeStamp of signalStrength in nanoseconds since boot + private long mTimestamp = Long.MAX_VALUE; + CellSignalStrengthCdma mCdma; CellSignalStrengthGsm mGsm; CellSignalStrengthWcdma mWcdma; @@ -132,6 +140,7 @@ public class SignalStrength implements Parcelable { mTdscdma = tdscdma; mLte = lte; mNr = nr; + mTimestamp = SystemClock.elapsedRealtimeNanos(); } /** @@ -266,6 +275,7 @@ public class SignalStrength implements Parcelable { mTdscdma.updateLevel(cc, ss); mLte.updateLevel(cc, ss); mNr.updateLevel(cc, ss); + mTimestamp = SystemClock.elapsedRealtimeNanos(); } /** @@ -275,8 +285,8 @@ public class SignalStrength implements Parcelable { * * @hide */ - @UnsupportedAppUsage - public SignalStrength(SignalStrength s) { + @SystemApi + public SignalStrength(@NonNull SignalStrength s) { copyFrom(s); } @@ -291,6 +301,7 @@ public class SignalStrength implements Parcelable { mTdscdma = new CellSignalStrengthTdscdma(s.mTdscdma); mLte = new CellSignalStrengthLte(s.mLte); mNr = new CellSignalStrengthNr(s.mNr); + mTimestamp = s.getTimestampNanos(); } /** @@ -308,6 +319,7 @@ public class SignalStrength implements Parcelable { mTdscdma = in.readParcelable(CellSignalStrengthTdscdma.class.getClassLoader()); mLte = in.readParcelable(CellSignalStrengthLte.class.getClassLoader()); mNr = in.readParcelable(CellSignalStrengthLte.class.getClassLoader()); + mTimestamp = in.readLong(); } /** @@ -320,9 +332,18 @@ public class SignalStrength implements Parcelable { out.writeParcelable(mTdscdma, flags); out.writeParcelable(mLte, flags); out.writeParcelable(mNr, flags); + out.writeLong(mTimestamp); } /** + * @return mTimestamp in nanoseconds + */ + @SuppressLint("MethodNameUnits") + public long getTimestampNanos() { + return mTimestamp; + } + + /** * {@link Parcelable#describeContents} */ public int describeContents() { diff --git a/telephony/java/android/telephony/SmsManager.java b/telephony/java/android/telephony/SmsManager.java index 34966865089b..b5dea7c02148 100644 --- a/telephony/java/android/telephony/SmsManager.java +++ b/telephony/java/android/telephony/SmsManager.java @@ -16,6 +16,7 @@ package android.telephony; +import android.Manifest; import android.annotation.CallbackExecutor; import android.annotation.IntDef; import android.annotation.NonNull; @@ -24,9 +25,9 @@ import android.annotation.RequiresPermission; import android.annotation.SuppressAutoDoc; import android.annotation.SystemApi; import android.annotation.TestApi; -import android.annotation.UnsupportedAppUsage; import android.app.ActivityThread; import android.app.PendingIntent; +import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; import android.content.pm.PackageManager; import android.database.CursorWindow; @@ -1635,14 +1636,16 @@ public final class SmsManager { * operation is performed on the correct subscription. * </p> * - * @param messageIndex is the record index of the message on ICC - * @return true for success + * @param messageIndex This is the same index used to access a message + * from {@link #getMessagesFromIcc()}. + * @return true for success, false if the operation fails. Failure can be due to IPC failure, + * RIL/modem error which results in SMS failed to be deleted on SIM * * {@hide} */ - @UnsupportedAppUsage - public boolean - deleteMessageFromIcc(int messageIndex) { + @SystemApi + @RequiresPermission(Manifest.permission.ACCESS_MESSAGES_ON_ICC) + public boolean deleteMessageFromIcc(int messageIndex) { boolean success = false; try { @@ -1684,6 +1687,7 @@ public final class SmsManager { * {@hide} */ @UnsupportedAppUsage + @RequiresPermission(Manifest.permission.ACCESS_MESSAGES_ON_ICC) public boolean updateMessageOnIcc(int messageIndex, int newStatus, byte[] pdu) { boolean success = false; @@ -1716,8 +1720,22 @@ public final class SmsManager { * operation is performed on the correct subscription. * </p> * + * @return <code>List</code> of <code>SmsMessage</code> objects + * + * {@hide} + */ + @SystemApi + @RequiresPermission(Manifest.permission.ACCESS_MESSAGES_ON_ICC) + public @NonNull List<SmsMessage> getMessagesFromIcc() { + return getAllMessagesFromIcc(); + } + + /** * @return <code>ArrayList</code> of <code>SmsMessage</code> objects * + * This is similar to {@link #getMessagesFromIcc} except that it will return ArrayList. + * Suggested to use {@link #getMessagesFromIcc} instead. + * * {@hide} */ @UnsupportedAppUsage @@ -2407,16 +2425,6 @@ public final class SmsManager { /** Intent extra name for HTTP status code for MMS HTTP failure in integer type */ public static final String EXTRA_MMS_HTTP_STATUS = "android.telephony.extra.MMS_HTTP_STATUS"; - /** Represents the received SMS message for importing {@hide} */ - public static final int SMS_TYPE_INCOMING = 0; - /** Represents the sent SMS message for importing {@hide} */ - public static final int SMS_TYPE_OUTGOING = 1; - - /** Message status property: whether the message has been seen. 1 means seen, 0 not {@hide} */ - public static final String MESSAGE_STATUS_SEEN = "seen"; - /** Message status property: whether the message has been read. 1 means read, 0 not {@hide} */ - public static final String MESSAGE_STATUS_READ = "read"; - /** * Get carrier-dependent MMS configuration values. * @@ -2684,7 +2692,7 @@ public final class SmsManager { ISms iccISms = getISmsServiceOrThrow(); if (iccISms != null) { return iccISms.checkSmsShortCodeDestination(getSubscriptionId(), - ActivityThread.currentPackageName(), destAddress, countryIso); + ActivityThread.currentPackageName(), null, destAddress, countryIso); } } catch (RemoteException e) { Log.e(TAG, "checkSmsShortCodeDestination() RemoteException", e); diff --git a/telephony/java/android/telephony/SmsMessage.java b/telephony/java/android/telephony/SmsMessage.java index 392d3eb37686..30a61c31ab81 100644 --- a/telephony/java/android/telephony/SmsMessage.java +++ b/telephony/java/android/telephony/SmsMessage.java @@ -16,11 +16,18 @@ package android.telephony; +import com.android.telephony.Rlog; + import static android.telephony.TelephonyManager.PHONE_TYPE_CDMA; +import android.Manifest; +import android.annotation.IntDef; +import android.annotation.NonNull; import android.annotation.Nullable; +import android.annotation.RequiresPermission; import android.annotation.StringDef; -import android.annotation.UnsupportedAppUsage; +import android.annotation.SystemApi; +import android.compat.annotation.UnsupportedAppUsage; import android.content.res.Resources; import android.os.Binder; import android.text.TextUtils; @@ -29,8 +36,10 @@ import com.android.internal.telephony.GsmAlphabet; import com.android.internal.telephony.GsmAlphabet.TextEncodingDetails; import com.android.internal.telephony.Sms7BitEncodingTranslator; import com.android.internal.telephony.SmsConstants; +import com.android.internal.telephony.SmsHeader; import com.android.internal.telephony.SmsMessageBase; import com.android.internal.telephony.SmsMessageBase.SubmitPduBase; +import com.android.internal.telephony.cdma.sms.UserData; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; @@ -54,6 +63,16 @@ public class SmsMessage { UNKNOWN, CLASS_0, CLASS_1, CLASS_2, CLASS_3; } + /** @hide */ + @IntDef(prefix = { "ENCODING_" }, value = { + ENCODING_UNKNOWN, + ENCODING_7BIT, + ENCODING_8BIT, + ENCODING_16BIT + }) + @Retention(RetentionPolicy.SOURCE) + public @interface EncodingSize {} + /** User data text encoding code unit size */ public static final int ENCODING_UNKNOWN = 0; public static final int ENCODING_7BIT = 1; @@ -313,6 +332,34 @@ public class SmsMessage { } /** + * Create an SmsMessage from a native SMS-Submit PDU, specified by Bluetooth Message Access + * Profile Specification v1.4.2 5.8. + * This is used by Bluetooth MAP profile to decode message when sending non UTF-8 SMS messages. + * + * @param data Message data. + * @param isCdma Indicates weather the type of the SMS is CDMA. + * @return An SmsMessage representing the message. + * + * @hide + */ + @SystemApi + @Nullable + public static SmsMessage createFromNativeSmsSubmitPdu(@NonNull byte[] data, boolean isCdma) { + SmsMessageBase wrappedMessage; + + if (isCdma) { + wrappedMessage = com.android.internal.telephony.cdma.SmsMessage.createFromEfRecord( + 0, data); + } else { + // Bluetooth uses its own method to decode GSM PDU so this part is not called. + wrappedMessage = com.android.internal.telephony.gsm.SmsMessage.createFromEfRecord( + 0, data); + } + + return wrappedMessage != null ? new SmsMessage(wrappedMessage) : null; + } + + /** * Get the TP-Layer-Length for the given SMS-SUBMIT PDU Basically, the * length in bytes (not hex chars) less the SMSC header * @@ -631,6 +678,83 @@ public class SmsMessage { } /** + * Get an SMS-SUBMIT PDU's encoded message. + * This is used by Bluetooth MAP profile to handle long non UTF-8 SMS messages. + * + * @param isTypeGsm true when message's type is GSM, false when type is CDMA + * @param destinationAddress the address of the destination for the message + * @param message message content + * @param encoding User data text encoding code unit size + * @param languageTable GSM national language table to use, specified by 3GPP + * 23.040 9.2.3.24.16 + * @param languageShiftTable GSM national language shift table to use, specified by 3GPP + * 23.040 9.2.3.24.15 + * @param refNumber parameter to create SmsHeader + * @param seqNumber parameter to create SmsHeader + * @param msgCount parameter to create SmsHeader + * @return a byte[] containing the encoded message + * + * @hide + */ + @RequiresPermission(Manifest.permission.BLUETOOTH_PRIVILEGED) + @SystemApi + @NonNull + public static byte[] getSubmitPduEncodedMessage(boolean isTypeGsm, + @NonNull String destinationAddress, + @NonNull String message, + @EncodingSize int encoding, int languageTable, + int languageShiftTable, int refNumber, + int seqNumber, int msgCount) { + byte[] data; + SmsHeader.ConcatRef concatRef = new SmsHeader.ConcatRef(); + concatRef.refNumber = refNumber; + concatRef.seqNumber = seqNumber; // 1-based sequence + concatRef.msgCount = msgCount; + // We currently set this to true since our messaging app will never + // send more than 255 parts (it converts the message to MMS well before that). + // However, we should support 3rd party messaging apps that might need 16-bit + // references + // Note: It's not sufficient to just flip this bit to true; it will have + // ripple effects (several calculations assume 8-bit ref). + concatRef.isEightBits = true; + SmsHeader smsHeader = new SmsHeader(); + smsHeader.concatRef = concatRef; + + /* Depending on the type, call either GSM or CDMA getSubmitPdu(). The encoding + * will be determined(again) by getSubmitPdu(). + * All packets need to be encoded using the same encoding, as the bMessage + * only have one filed to describe the encoding for all messages in a concatenated + * SMS... */ + if (encoding == ENCODING_7BIT) { + smsHeader.languageTable = languageTable; + smsHeader.languageShiftTable = languageShiftTable; + } + + if (isTypeGsm) { + data = com.android.internal.telephony.gsm.SmsMessage.getSubmitPdu(null, + destinationAddress, message, false, + SmsHeader.toByteArray(smsHeader), encoding, languageTable, + languageShiftTable).encodedMessage; + } else { // SMS_TYPE_CDMA + UserData uData = new UserData(); + uData.payloadStr = message; + uData.userDataHeader = smsHeader; + if (encoding == ENCODING_7BIT) { + uData.msgEncoding = UserData.ENCODING_GSM_7BIT_ALPHABET; + } else { // assume UTF-16 + uData.msgEncoding = UserData.ENCODING_UNICODE_16; + } + uData.msgEncodingSet = true; + data = com.android.internal.telephony.cdma.SmsMessage.getSubmitPdu( + destinationAddress, uData, false).encodedMessage; + } + if (data == null) { + return new byte[0]; + } + return data; + } + + /** * Returns the address of the SMS service center that relayed this message * or null if there is none. */ @@ -1038,10 +1162,10 @@ public class SmsMessage { } /** - * {@hide} * Returns the recipient address(receiver) of this SMS message in String form or null if * unavailable. */ + @Nullable public String getRecipientAddress() { return mWrappedSmsMessage.getRecipientAddress(); } diff --git a/telephony/java/android/telephony/SubscriptionInfo.java b/telephony/java/android/telephony/SubscriptionInfo.java index bbde1f48aed7..2d8e2376b9d8 100644 --- a/telephony/java/android/telephony/SubscriptionInfo.java +++ b/telephony/java/android/telephony/SubscriptionInfo.java @@ -16,9 +16,11 @@ package android.telephony; +import com.android.telephony.Rlog; + import android.annotation.Nullable; import android.annotation.SystemApi; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; import android.content.pm.PackageInfo; import android.content.pm.PackageManager; diff --git a/telephony/java/android/telephony/SubscriptionManager.java b/telephony/java/android/telephony/SubscriptionManager.java index c6142d9d1d93..d4ab04cc2170 100644 --- a/telephony/java/android/telephony/SubscriptionManager.java +++ b/telephony/java/android/telephony/SubscriptionManager.java @@ -16,6 +16,8 @@ package android.telephony; +import com.android.telephony.Rlog; + import static android.net.NetworkPolicyManager.OVERRIDE_CONGESTED; import static android.net.NetworkPolicyManager.OVERRIDE_UNMETERED; @@ -32,9 +34,9 @@ import android.annotation.SuppressAutoDoc; import android.annotation.SystemApi; import android.annotation.SystemService; import android.annotation.TestApi; -import android.annotation.UnsupportedAppUsage; import android.app.BroadcastOptions; import android.app.PendingIntent; +import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; import android.content.Intent; import android.content.pm.PackageInfo; @@ -1040,6 +1042,23 @@ public class SubscriptionManager { */ public void addOnSubscriptionsChangedListener(OnSubscriptionsChangedListener listener) { if (listener == null) return; + addOnSubscriptionsChangedListener(listener.mExecutor, listener); + } + + /** + * Register for changes to the list of active {@link SubscriptionInfo} records or to the + * individual records themselves. When a change occurs the onSubscriptionsChanged method of + * the listener will be invoked immediately if there has been a notification. The + * onSubscriptionChanged method will also be triggered once initially when calling this + * function. + * + * @param listener an instance of {@link OnSubscriptionsChangedListener} with + * onSubscriptionsChanged overridden. + * @param executor the executor that will execute callbacks. + */ + public void addOnSubscriptionsChangedListener( + @NonNull @CallbackExecutor Executor executor, + @NonNull OnSubscriptionsChangedListener listener) { String pkgName = mContext != null ? mContext.getOpPackageName() : "<unknown>"; if (DBG) { logd("register OnSubscriptionsChangedListener pkgName=" + pkgName @@ -1051,7 +1070,7 @@ public class SubscriptionManager { mContext.getSystemService(Context.TELEPHONY_REGISTRY_SERVICE); if (telephonyRegistryManager != null) { telephonyRegistryManager.addOnSubscriptionsChangedListener(listener, - listener.mExecutor); + executor); } } @@ -1186,7 +1205,8 @@ public class SubscriptionManager { try { ISub iSub = ISub.Stub.asInterface(ServiceManager.getService("isub")); if (iSub != null) { - subInfo = iSub.getActiveSubscriptionInfo(subId, mContext.getOpPackageName()); + subInfo = iSub.getActiveSubscriptionInfo(subId, mContext.getOpPackageName(), + null); } } catch (RemoteException ex) { // ignore it @@ -1219,7 +1239,8 @@ public class SubscriptionManager { try { ISub iSub = ISub.Stub.asInterface(ServiceManager.getService("isub")); if (iSub != null) { - result = iSub.getActiveSubscriptionInfoForIccId(iccId, mContext.getOpPackageName()); + result = iSub.getActiveSubscriptionInfoForIccId(iccId, mContext.getOpPackageName(), + null); } } catch (RemoteException ex) { // ignore it @@ -1253,7 +1274,7 @@ public class SubscriptionManager { ISub iSub = ISub.Stub.asInterface(ServiceManager.getService("isub")); if (iSub != null) { result = iSub.getActiveSubscriptionInfoForSimSlotIndex(slotIndex, - mContext.getOpPackageName()); + mContext.getOpPackageName(), null); } } catch (RemoteException ex) { // ignore it @@ -1276,7 +1297,8 @@ public class SubscriptionManager { try { ISub iSub = ISub.Stub.asInterface(ServiceManager.getService("isub")); if (iSub != null) { - result = iSub.getAllSubInfoList(mContext.getOpPackageName()); + result = iSub.getAllSubInfoList(mContext.getOpPackageName(), + null); } } catch (RemoteException ex) { // ignore it @@ -1351,7 +1373,8 @@ public class SubscriptionManager { try { ISub iSub = ISub.Stub.asInterface(ServiceManager.getService("isub")); if (iSub != null) { - activeList = iSub.getActiveSubscriptionInfoList(mContext.getOpPackageName()); + activeList = iSub.getActiveSubscriptionInfoList(mContext.getOpPackageName(), + null); } } catch (RemoteException ex) { // ignore it @@ -1401,7 +1424,8 @@ public class SubscriptionManager { try { ISub iSub = ISub.Stub.asInterface(ServiceManager.getService("isub")); if (iSub != null) { - result = iSub.getAvailableSubscriptionInfoList(mContext.getOpPackageName()); + result = iSub.getAvailableSubscriptionInfoList(mContext.getOpPackageName(), + null); } } catch (RemoteException ex) { // ignore it @@ -1518,7 +1542,8 @@ public class SubscriptionManager { try { ISub iSub = ISub.Stub.asInterface(ServiceManager.getService("isub")); if (iSub != null) { - result = iSub.getAllSubInfoCount(mContext.getOpPackageName()); + result = iSub.getAllSubInfoCount(mContext.getOpPackageName(), + null); } } catch (RemoteException ex) { // ignore it @@ -1546,7 +1571,8 @@ public class SubscriptionManager { try { ISub iSub = ISub.Stub.asInterface(ServiceManager.getService("isub")); if (iSub != null) { - result = iSub.getActiveSubInfoCount(mContext.getOpPackageName()); + result = iSub.getActiveSubInfoCount(mContext.getOpPackageName(), + null); } } catch (RemoteException ex) { // ignore it @@ -2283,7 +2309,7 @@ public class SubscriptionManager { ISub iSub = ISub.Stub.asInterface(ServiceManager.getService("isub")); if (iSub != null) { resultValue = iSub.getSubscriptionProperty(subId, propKey, - context.getOpPackageName()); + context.getOpPackageName(), null); } } catch (RemoteException ex) { // ignore it @@ -2424,7 +2450,8 @@ public class SubscriptionManager { try { ISub iSub = ISub.Stub.asInterface(ServiceManager.getService("isub")); if (iSub != null) { - return iSub.isActiveSubId(subId, mContext.getOpPackageName()); + return iSub.isActiveSubId(subId, mContext.getOpPackageName(), + null); } } catch (RemoteException ex) { } @@ -2477,6 +2504,8 @@ public class SubscriptionManager { * may not be displayed or used by decision making logic. * @throws SecurityException if the caller doesn't meet the requirements * outlined above. + * @throws IllegalArgumentException if plans don't meet the requirements + * defined in {@link SubscriptionPlan}. */ public void setSubscriptionPlans(int subId, @NonNull List<SubscriptionPlan> plans) { try { @@ -2650,8 +2679,7 @@ public class SubscriptionManager { /** * Checks whether the app with the given context is authorized to manage the given subscription - * according to its metadata. Only supported for embedded subscriptions (if - * {@code SubscriptionInfo#isEmbedded} returns true). + * according to its metadata. * * @param info The subscription to check. * @return whether the app is authorized to manage this subscription per its metadata. @@ -2664,16 +2692,16 @@ public class SubscriptionManager { * Checks whether the given app is authorized to manage the given subscription. An app can only * be authorized if it is included in the {@link android.telephony.UiccAccessRule} of the * {@link android.telephony.SubscriptionInfo} with the access status. - * Only supported for embedded subscriptions (if {@link SubscriptionInfo#isEmbedded} - * returns true). * * @param info The subscription to check. * @param packageName Package name of the app to check. * @return whether the app is authorized to manage this subscription per its access rules. * @hide */ - public boolean canManageSubscription(SubscriptionInfo info, String packageName) { - if (info == null || info.getAllAccessRules() == null) { + @SystemApi + public boolean canManageSubscription(@Nullable SubscriptionInfo info, + @Nullable String packageName) { + if (info == null || info.getAllAccessRules() == null || packageName == null) { return false; } PackageManager packageManager = mContext.getPackageManager(); @@ -2792,13 +2820,14 @@ public class SubscriptionManager { @SuppressAutoDoc // Blocked by b/72967236 - no support for carrier privileges @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE) public @NonNull List<SubscriptionInfo> getOpportunisticSubscriptions() { - String pkgForDebug = mContext != null ? mContext.getOpPackageName() : "<unknown>"; + String contextPkg = mContext != null ? mContext.getOpPackageName() : "<unknown>"; + String contextFeature = null; List<SubscriptionInfo> subInfoList = null; try { ISub iSub = ISub.Stub.asInterface(ServiceManager.getService("isub")); if (iSub != null) { - subInfoList = iSub.getOpportunisticSubscriptions(pkgForDebug); + subInfoList = iSub.getOpportunisticSubscriptions(contextPkg, contextFeature); } } catch (RemoteException ex) { // ignore it @@ -3036,7 +3065,8 @@ public class SubscriptionManager { @RequiresPermission(Manifest.permission.READ_PHONE_STATE) public @NonNull List<SubscriptionInfo> getSubscriptionsInGroup(@NonNull ParcelUuid groupUuid) { Preconditions.checkNotNull(groupUuid, "groupUuid can't be null"); - String pkgForDebug = mContext != null ? mContext.getOpPackageName() : "<unknown>"; + String contextPkg = mContext != null ? mContext.getOpPackageName() : "<unknown>"; + String contextFeature = null; if (VDBG) { logd("[getSubscriptionsInGroup]+ groupUuid:" + groupUuid); } @@ -3045,7 +3075,7 @@ public class SubscriptionManager { try { ISub iSub = ISub.Stub.asInterface(ServiceManager.getService("isub")); if (iSub != null) { - result = iSub.getSubscriptionsInGroup(groupUuid, pkgForDebug); + result = iSub.getSubscriptionsInGroup(groupUuid, contextPkg, contextFeature); } else { if (!isSystemProcess()) { throw new IllegalStateException("telephony service is null."); @@ -3168,6 +3198,34 @@ public class SubscriptionManager { } /** + * Set uicc applications being enabled or disabled. + * The value will be remembered on the subscription and will be applied whenever it's present. + * If the subscription in currently present, it will also apply the setting to modem + * immediately. + * + * Permissions android.Manifest.permission.MODIFY_PHONE_STATE is required + * + * @param enabled whether uicc applications are enabled or disabled. + * @param subscriptionId which subscription to operate on. + * @hide + */ + @SystemApi + @RequiresPermission(Manifest.permission.MODIFY_PHONE_STATE) + public void setUiccApplicationsEnabled(boolean enabled, int subscriptionId) { + if (VDBG) { + logd("setUiccApplicationsEnabled subId= " + subscriptionId + " enable " + enabled); + } + try { + ISub iSub = ISub.Stub.asInterface(ServiceManager.getService("isub")); + if (iSub != null) { + iSub.setUiccApplicationsEnabled(enabled, subscriptionId); + } + } catch (RemoteException ex) { + // ignore it + } + } + + /** * Whether it's supported to disable / re-enable a subscription on a physical (non-euicc) SIM. * * Physical SIM refers non-euicc, or aka non-programmable SIM. diff --git a/telephony/java/android/telephony/TelephonyManager.java b/telephony/java/android/telephony/TelephonyManager.java index 87bdaa9a9fe4..690393b52104 100644 --- a/telephony/java/android/telephony/TelephonyManager.java +++ b/telephony/java/android/telephony/TelephonyManager.java @@ -36,13 +36,13 @@ import android.annotation.SuppressLint; import android.annotation.SystemApi; import android.annotation.SystemService; import android.annotation.TestApi; -import android.annotation.UnsupportedAppUsage; import android.annotation.WorkerThread; import android.app.ActivityThread; import android.app.PendingIntent; import android.compat.Compatibility; import android.compat.annotation.ChangeId; import android.compat.annotation.EnabledAfter; +import android.compat.annotation.UnsupportedAppUsage; import android.content.ComponentName; import android.content.Context; import android.content.Intent; @@ -73,12 +73,13 @@ import android.telecom.PhoneAccountHandle; import android.telecom.TelecomManager; import android.telephony.Annotation.ApnType; import android.telephony.Annotation.CallState; -import android.telephony.Annotation.DataState; import android.telephony.Annotation.NetworkType; import android.telephony.Annotation.RadioPowerState; import android.telephony.Annotation.SimActivationState; +import android.telephony.Annotation.UiccAppType; import android.telephony.VisualVoicemailService.VisualVoicemailTask; import android.telephony.data.ApnSetting; +import android.telephony.data.ApnSetting.MvnoType; import android.telephony.emergency.EmergencyNumber; import android.telephony.emergency.EmergencyNumber.EmergencyServiceCategories; import android.telephony.ims.ImsMmTelManager; @@ -106,6 +107,7 @@ import com.android.internal.telephony.OperatorInfo; import com.android.internal.telephony.PhoneConstants; import com.android.internal.telephony.RILConstants; import com.android.internal.telephony.SmsApplication; +import com.android.telephony.Rlog; import dalvik.system.VMRuntime; @@ -379,6 +381,10 @@ public class TelephonyManager { return ActivityThread.currentOpPackageName(); } + private String getFeatureId() { + return null; + } + private boolean isSystemProcess() { return Process.myUid() == Process.SYSTEM_UID; } @@ -769,30 +775,6 @@ public class TelephonyManager { public static final String EXTRA_PRECISE_DISCONNECT_CAUSE = "precise_disconnect_cause"; /** - * The lookup key used with the {@link #ACTION_PRECISE_DATA_CONNECTION_STATE_CHANGED} broadcast - * for an String containing the data APN type. - * - * <p class="note"> - * Retrieve with - * {@link android.content.Intent#getStringExtra(String name)}. - * - * @hide - */ - public static final String EXTRA_DATA_APN_TYPE = PhoneConstants.DATA_APN_TYPE_KEY; - - /** - * The lookup key used with the {@link #ACTION_PRECISE_DATA_CONNECTION_STATE_CHANGED} broadcast - * for an String containing the data APN. - * - * <p class="note"> - * Retrieve with - * {@link android.content.Intent#getStringExtra(String name)}. - * - * @hide - */ - public static final String EXTRA_DATA_APN = PhoneConstants.DATA_APN_KEY; - - /** * Broadcast intent action for letting the default dialer to know to show voicemail * notification. * @@ -1454,25 +1436,6 @@ public class TelephonyManager { public static final String EXTRA_SIM_COMBINATION_NAMES = "android.telephony.extra.SIM_COMBINATION_NAMES"; - /** - * Broadcast Action: The time was set by the carrier (typically by the NITZ string). - * This is a sticky broadcast. - * The intent will have the following extra values:</p> - * <ul> - * <li><em>time</em> - The time as a long in UTC milliseconds.</li> - * </ul> - * - * <p class="note"> - * Requires the READ_PHONE_STATE permission. - * - * <p class="note">This is a protected intent that can only be sent - * by the system. - * - * @hide - */ - @SystemApi - public static final String ACTION_NETWORK_SET_TIME = "android.telephony.action.NETWORK_SET_TIME"; - // // // Device Info @@ -1511,7 +1474,8 @@ public class TelephonyManager { if (telephony == null) return null; try { - return telephony.getDeviceSoftwareVersionForSlot(slotIndex, getOpPackageName()); + return telephony.getDeviceSoftwareVersionForSlot(slotIndex, getOpPackageName(), + getFeatureId()); } catch (RemoteException ex) { return null; } catch (NullPointerException ex) { @@ -1552,7 +1516,8 @@ public class TelephonyManager { ITelephony telephony = getITelephony(); if (telephony == null) return null; - return telephony.getDeviceId(mContext.getOpPackageName()); + return telephony.getDeviceIdWithFeature(mContext.getOpPackageName(), + null); } catch (RemoteException ex) { return null; } catch (NullPointerException ex) { @@ -1596,7 +1561,8 @@ public class TelephonyManager { IPhoneSubInfo info = getSubscriberInfo(); if (info == null) return null; - return info.getDeviceIdForPhone(slotIndex, mContext.getOpPackageName()); + return info.getDeviceIdForPhone(slotIndex, mContext.getOpPackageName(), + null); } catch (RemoteException ex) { return null; } catch (NullPointerException ex) { @@ -1654,7 +1620,7 @@ public class TelephonyManager { if (telephony == null) return null; try { - return telephony.getImeiForSlot(slotIndex, getOpPackageName()); + return telephony.getImeiForSlot(slotIndex, getOpPackageName(), getFeatureId()); } catch (RemoteException ex) { return null; } catch (NullPointerException ex) { @@ -1748,7 +1714,7 @@ public class TelephonyManager { if (telephony == null) return null; try { - String meid = telephony.getMeidForSlot(slotIndex, getOpPackageName()); + String meid = telephony.getMeidForSlot(slotIndex, getOpPackageName(), getFeatureId()); if (TextUtils.isEmpty(meid)) { Log.d(TAG, "getMeid: return null because MEID is not available"); return null; @@ -1849,7 +1815,8 @@ public class TelephonyManager { IPhoneSubInfo info = getSubscriberInfo(); if (info == null) return null; - String nai = info.getNaiForSubscriber(subId, mContext.getOpPackageName()); + String nai = info.getNaiForSubscriber(subId, mContext.getOpPackageName(), + null); if (Log.isLoggable(TAG, Log.VERBOSE)) { Rlog.v(TAG, "Nai = " + nai); } @@ -1882,13 +1849,9 @@ public class TelephonyManager { return null; } - Bundle bundle = telephony.getCellLocation(mContext.getOpPackageName()); - if (bundle == null || bundle.isEmpty()) { - Rlog.d(TAG, "getCellLocation returning null because CellLocation is unavailable"); - return null; - } - - CellLocation cl = CellLocation.newFromBundle(bundle); + CellIdentity cellIdentity = telephony.getCellLocation(mContext.getOpPackageName(), + null); + CellLocation cl = cellIdentity.asCellLocation(); if (cl == null || cl.isEmpty()) { Rlog.d(TAG, "getCellLocation returning null because CellLocation is empty or" + " phone type doesn't match CellLocation type"); @@ -1970,7 +1933,8 @@ public class TelephonyManager { ITelephony telephony = getITelephony(); if (telephony == null) return null; - return telephony.getNeighboringCellInfo(mContext.getOpPackageName()); + return telephony.getNeighboringCellInfo(mContext.getOpPackageName(), + null); } catch (RemoteException ex) { return null; } catch (NullPointerException ex) { @@ -2398,7 +2362,7 @@ public class TelephonyManager { ITelephony telephony = getITelephony(); if (telephony == null) return ""; return telephony.getNetworkCountryIsoForPhone(getPhoneId(), - null /* no permission check */); + null /* no permission check */, null); } catch (RemoteException ex) { return ""; } @@ -2438,7 +2402,8 @@ public class TelephonyManager { ITelephony telephony = getITelephony(); if (telephony == null) return ""; - return telephony.getNetworkCountryIsoForPhone(slotIndex, getOpPackageName()); + return telephony.getNetworkCountryIsoForPhone(slotIndex, getOpPackageName(), + getFeatureId()); } catch (RemoteException ex) { return ""; } @@ -2570,7 +2535,8 @@ public class TelephonyManager { try { ITelephony telephony = getITelephony(); if (telephony != null) { - return telephony.getNetworkTypeForSubscriber(subId, getOpPackageName()); + return telephony.getNetworkTypeForSubscriber(subId, getOpPackageName(), + getFeatureId()); } else { // This can happen when the ITelephony interface is not up yet. return NETWORK_TYPE_UNKNOWN; @@ -2634,7 +2600,8 @@ public class TelephonyManager { try{ ITelephony telephony = getITelephony(); if (telephony != null) { - return telephony.getDataNetworkTypeForSubscriber(subId, getOpPackageName()); + return telephony.getDataNetworkTypeForSubscriber(subId, getOpPackageName(), + getFeatureId()); } else { // This can happen when the ITelephony interface is not up yet. return NETWORK_TYPE_UNKNOWN; @@ -2670,7 +2637,8 @@ public class TelephonyManager { try{ ITelephony telephony = getITelephony(); if (telephony != null) { - return telephony.getVoiceNetworkTypeForSubscriber(subId, getOpPackageName()); + return telephony.getVoiceNetworkTypeForSubscriber(subId, getOpPackageName(), + getFeatureId()); } else { // This can happen when the ITelephony interface is not up yet. return NETWORK_TYPE_UNKNOWN; @@ -2810,6 +2778,55 @@ public class TelephonyManager { } } + /** + * Returns the bitmask for a given technology (network type) + * @param networkType for which bitmask is returned + * @return the network type bitmask + * {@hide} + */ + public static @NetworkTypeBitMask long getBitMaskForNetworkType(@NetworkType int networkType) { + switch(networkType) { + case NETWORK_TYPE_GSM: + return NETWORK_TYPE_BITMASK_GSM; + case NETWORK_TYPE_GPRS: + return NETWORK_TYPE_BITMASK_GPRS; + case NETWORK_TYPE_EDGE: + return NETWORK_TYPE_BITMASK_EDGE; + case NETWORK_TYPE_CDMA: + return NETWORK_TYPE_BITMASK_CDMA; + case NETWORK_TYPE_1xRTT: + return NETWORK_TYPE_BITMASK_1xRTT; + case NETWORK_TYPE_EVDO_0: + return NETWORK_TYPE_BITMASK_EVDO_0; + case NETWORK_TYPE_EVDO_A: + return NETWORK_TYPE_BITMASK_EVDO_A; + case NETWORK_TYPE_EVDO_B: + return NETWORK_TYPE_BITMASK_EVDO_B; + case NETWORK_TYPE_EHRPD: + return NETWORK_TYPE_BITMASK_EHRPD; + case NETWORK_TYPE_HSUPA: + return NETWORK_TYPE_BITMASK_HSUPA; + case NETWORK_TYPE_HSDPA: + return NETWORK_TYPE_BITMASK_HSDPA; + case NETWORK_TYPE_HSPA: + return NETWORK_TYPE_BITMASK_HSPA; + case NETWORK_TYPE_HSPAP: + return NETWORK_TYPE_BITMASK_HSPAP; + case NETWORK_TYPE_UMTS: + return NETWORK_TYPE_BITMASK_UMTS; + case NETWORK_TYPE_TD_SCDMA: + return NETWORK_TYPE_BITMASK_TD_SCDMA; + case NETWORK_TYPE_LTE: + return NETWORK_TYPE_BITMASK_LTE; + case NETWORK_TYPE_LTE_CA: + return NETWORK_TYPE_BITMASK_LTE_CA; + case NETWORK_TYPE_NR: + return NETWORK_TYPE_BITMASK_NR; + default: + return NETWORK_TYPE_BITMASK_UNKNOWN; + } + } + // // // SIM Card @@ -3464,7 +3481,8 @@ public class TelephonyManager { IPhoneSubInfo info = getSubscriberInfo(); if (info == null) return null; - return info.getIccSerialNumberForSubscriber(subId, mContext.getOpPackageName()); + return info.getIccSerialNumberForSubscriber(subId, mContext.getOpPackageName(), + null); } catch (RemoteException ex) { return null; } catch (NullPointerException ex) { @@ -3508,7 +3526,8 @@ public class TelephonyManager { ITelephony telephony = getITelephony(); if (telephony == null) return PhoneConstants.LTE_ON_CDMA_UNKNOWN; - return telephony.getLteOnCdmaModeForSubscriber(subId, getOpPackageName()); + return telephony.getLteOnCdmaModeForSubscriber(subId, getOpPackageName(), + getFeatureId()); } catch (RemoteException ex) { // Assume no ICC card if remote exception which shouldn't happen return PhoneConstants.LTE_ON_CDMA_UNKNOWN; @@ -3736,7 +3755,8 @@ public class TelephonyManager { IPhoneSubInfo info = getSubscriberInfo(); if (info == null) return null; - return info.getSubscriberIdForSubscriber(subId, mContext.getOpPackageName()); + return info.getSubscriberIdForSubscriber(subId, mContext.getOpPackageName(), + null); } catch (RemoteException ex) { return null; } catch (NullPointerException ex) { @@ -3903,7 +3923,8 @@ public class TelephonyManager { IPhoneSubInfo info = getSubscriberInfo(); if (info == null) return null; - return info.getGroupIdLevel1ForSubscriber(getSubId(), mContext.getOpPackageName()); + return info.getGroupIdLevel1ForSubscriber(getSubId(), mContext.getOpPackageName(), + null); } catch (RemoteException ex) { return null; } catch (NullPointerException ex) { @@ -3926,7 +3947,8 @@ public class TelephonyManager { IPhoneSubInfo info = getSubscriberInfo(); if (info == null) return null; - return info.getGroupIdLevel1ForSubscriber(subId, mContext.getOpPackageName()); + return info.getGroupIdLevel1ForSubscriber(subId, mContext.getOpPackageName(), + null); } catch (RemoteException ex) { return null; } catch (NullPointerException ex) { @@ -3976,7 +3998,8 @@ public class TelephonyManager { try { ITelephony telephony = getITelephony(); if (telephony != null) - number = telephony.getLine1NumberForDisplay(subId, mContext.getOpPackageName()); + number = telephony.getLine1NumberForDisplay(subId, mContext.getOpPackageName(), + null); } catch (RemoteException ex) { } catch (NullPointerException ex) { } @@ -3987,7 +4010,8 @@ public class TelephonyManager { IPhoneSubInfo info = getSubscriberInfo(); if (info == null) return null; - return info.getLine1NumberForSubscriber(subId, mContext.getOpPackageName()); + return info.getLine1NumberForSubscriber(subId, mContext.getOpPackageName(), + null); } catch (RemoteException ex) { return null; } catch (NullPointerException ex) { @@ -4066,7 +4090,7 @@ public class TelephonyManager { ITelephony telephony = getITelephony(); if (telephony != null) alphaTag = telephony.getLine1AlphaTagForDisplay(subId, - getOpPackageName()); + getOpPackageName(), getFeatureId()); } catch (RemoteException ex) { } catch (NullPointerException ex) { } @@ -4077,7 +4101,8 @@ public class TelephonyManager { IPhoneSubInfo info = getSubscriberInfo(); if (info == null) return null; - return info.getLine1AlphaTagForSubscriber(subId, getOpPackageName()); + return info.getLine1AlphaTagForSubscriber(subId, getOpPackageName(), + getFeatureId()); } catch (RemoteException ex) { return null; } catch (NullPointerException ex) { @@ -4106,7 +4131,8 @@ public class TelephonyManager { try { ITelephony telephony = getITelephony(); if (telephony != null) - return telephony.getMergedSubscriberIds(getSubId(), getOpPackageName()); + return telephony.getMergedSubscriberIds(getSubId(), getOpPackageName(), + getFeatureId()); } catch (RemoteException ex) { } catch (NullPointerException ex) { } @@ -4161,7 +4187,7 @@ public class TelephonyManager { IPhoneSubInfo info = getSubscriberInfo(); if (info == null) return null; - return info.getMsisdnForSubscriber(subId, getOpPackageName()); + return info.getMsisdnForSubscriber(subId, getOpPackageName(), getFeatureId()); } catch (RemoteException ex) { return null; } catch (NullPointerException ex) { @@ -4195,7 +4221,8 @@ public class TelephonyManager { IPhoneSubInfo info = getSubscriberInfo(); if (info == null) return null; - return info.getVoiceMailNumberForSubscriber(subId, getOpPackageName()); + return info.getVoiceMailNumberForSubscriber(subId, getOpPackageName(), + getFeatureId()); } catch (RemoteException ex) { return null; } catch (NullPointerException ex) { @@ -4319,8 +4346,8 @@ public class TelephonyManager { try { ITelephony telephony = getITelephony(); if (telephony != null) { - return telephony - .getVisualVoicemailPackageName(mContext.getOpPackageName(), getSubId()); + return telephony.getVisualVoicemailPackageName(mContext.getOpPackageName(), + getFeatureId(), getSubId()); } } catch (RemoteException ex) { } catch (NullPointerException ex) { @@ -4756,7 +4783,8 @@ public class TelephonyManager { ITelephony telephony = getITelephony(); if (telephony == null) return 0; - return telephony.getVoiceMessageCountForSubscriber(subId, getOpPackageName()); + return telephony.getVoiceMessageCountForSubscriber(subId, getOpPackageName(), + getFeatureId()); } catch (RemoteException ex) { return 0; } catch (NullPointerException ex) { @@ -4792,7 +4820,8 @@ public class TelephonyManager { IPhoneSubInfo info = getSubscriberInfo(); if (info == null) return null; - return info.getVoiceMailAlphaTagForSubscriber(subId, getOpPackageName()); + return info.getVoiceMailAlphaTagForSubscriber(subId, getOpPackageName(), + getFeatureId()); } catch (RemoteException ex) { return null; } catch (NullPointerException ex) { @@ -4882,7 +4911,9 @@ public class TelephonyManager { * not present or not loaded * @hide */ - @UnsupportedAppUsage + @Nullable + @SystemApi + @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public String[] getIsimImpu() { try { IPhoneSubInfo info = getSubscriberInfo(); @@ -5188,7 +5219,7 @@ public class TelephonyManager { } else if (listener.mSubId != null) { subId = listener.mSubId; } - registry.listenForSubscriber(subId, getOpPackageName(), + registry.listenForSubscriber(subId, getOpPackageName(), getFeatureId(), listener.callback, events, notifyNow); } else { Rlog.w(TAG, "telephony registry not ready."); @@ -5218,7 +5249,8 @@ public class TelephonyManager { ITelephony telephony = getITelephony(); if (telephony == null) return -1; - return telephony.getCdmaEriIconIndexForSubscriber(subId, getOpPackageName()); + return telephony.getCdmaEriIconIndexForSubscriber(subId, getOpPackageName(), + getFeatureId()); } catch (RemoteException ex) { // the phone process is restarting. return -1; @@ -5253,7 +5285,8 @@ public class TelephonyManager { ITelephony telephony = getITelephony(); if (telephony == null) return -1; - return telephony.getCdmaEriIconModeForSubscriber(subId, getOpPackageName()); + return telephony.getCdmaEriIconModeForSubscriber(subId, getOpPackageName(), + getFeatureId()); } catch (RemoteException ex) { // the phone process is restarting. return -1; @@ -5284,7 +5317,8 @@ public class TelephonyManager { ITelephony telephony = getITelephony(); if (telephony == null) return null; - return telephony.getCdmaEriTextForSubscriber(subId, getOpPackageName()); + return telephony.getCdmaEriTextForSubscriber(subId, getOpPackageName(), + getFeatureId()); } catch (RemoteException ex) { // the phone process is restarting. return null; @@ -5376,8 +5410,7 @@ public class TelephonyManager { ITelephony telephony = getITelephony(); if (telephony == null) return null; - return telephony.getAllCellInfo( - getOpPackageName()); + return telephony.getAllCellInfo(getOpPackageName(), getFeatureId()); } catch (RemoteException ex) { } catch (NullPointerException ex) { } @@ -5477,7 +5510,7 @@ public class TelephonyManager { Binder.restoreCallingIdentity(identity); } } - }, getOpPackageName()); + }, getOpPackageName(), getFeatureId()); } catch (RemoteException ex) { } } @@ -5528,7 +5561,7 @@ public class TelephonyManager { Binder.restoreCallingIdentity(identity); } } - }, getOpPackageName(), workSource); + }, getOpPackageName(), getFeatureId(), workSource); } catch (RemoteException ex) { } } @@ -5685,7 +5718,10 @@ public class TelephonyManager { * @param AID Application id. See ETSI 102.221 and 101.220. * @param p2 P2 parameter (described in ISO 7816-4). * @return an IccOpenLogicalChannelResponse object. + * @deprecated Use {@link android.se.omapi.SEService} APIs instead. */ + // TODO(b/147153909): Update Javadoc to link to specific SEService API once integrated. + @Deprecated public IccOpenLogicalChannelResponse iccOpenLogicalChannel(String AID, int p2) { return iccOpenLogicalChannel(getSubId(), AID, p2); } @@ -5716,7 +5752,10 @@ public class TelephonyManager { * @param p2 P2 parameter (described in ISO 7816-4). * @return an IccOpenLogicalChannelResponse object. * @hide + * @deprecated Use {@link android.se.omapi.SEService} APIs instead. */ + // TODO(b/147153909): Update Javadoc to link to specific SEService API once integrated. + @Deprecated public IccOpenLogicalChannelResponse iccOpenLogicalChannel(int subId, String AID, int p2) { try { ITelephony telephony = getITelephony(); @@ -5744,7 +5783,10 @@ public class TelephonyManager { * iccOpenLogicalChannel. * @return true if the channel was closed successfully. * @hide + * @deprecated Use {@link android.se.omapi.SEService} APIs instead. */ + // TODO(b/147153909): Update Javadoc to link to specific SEService API once integrated. + @Deprecated @RequiresPermission(Manifest.permission.MODIFY_PHONE_STATE) @SystemApi public boolean iccCloseLogicalChannelBySlot(int slotIndex, int channel) { @@ -5771,7 +5813,10 @@ public class TelephonyManager { * @param channel is the channel id to be closed as returned by a successful * iccOpenLogicalChannel. * @return true if the channel was closed successfully. + * @deprecated Use {@link android.se.omapi.SEService} APIs instead. */ + // TODO(b/147153909): Update Javadoc to link to specific SEService API once integrated. + @Deprecated public boolean iccCloseLogicalChannel(int channel) { return iccCloseLogicalChannel(getSubId(), channel); } @@ -5790,7 +5835,10 @@ public class TelephonyManager { * iccOpenLogicalChannel. * @return true if the channel was closed successfully. * @hide + * @deprecated Use {@link android.se.omapi.SEService} APIs instead. */ + // TODO(b/147153909): Update Javadoc to link to specific SEService API once integrated. + @Deprecated public boolean iccCloseLogicalChannel(int subId, int channel) { try { ITelephony telephony = getITelephony(); @@ -5826,7 +5874,10 @@ public class TelephonyManager { * @return The APDU response from the ICC card with the status appended at the end, or null if * there is an issue connecting to the Telephony service. * @hide + * @deprecated Use {@link android.se.omapi.SEService} APIs instead. */ + // TODO(b/147153909): Update Javadoc to link to specific SEService API once integrated. + @Deprecated @RequiresPermission(Manifest.permission.MODIFY_PHONE_STATE) @SystemApi @Nullable @@ -5864,7 +5915,10 @@ public class TelephonyManager { * @param data Data to be sent with the APDU. * @return The APDU response from the ICC card with the status appended at * the end. + * @deprecated Use {@link android.se.omapi.SEService} APIs instead. */ + // TODO(b/147153909): Update Javadoc to link to specific SEService API once integrated. + @Deprecated public String iccTransmitApduLogicalChannel(int channel, int cla, int instruction, int p1, int p2, int p3, String data) { return iccTransmitApduLogicalChannel(getSubId(), channel, cla, @@ -5893,7 +5947,10 @@ public class TelephonyManager { * @return The APDU response from the ICC card with the status appended at * the end. * @hide + * @deprecated Use {@link android.se.omapi.SEService} APIs instead. */ + // TODO(b/147153909): Update Javadoc to link to specific SEService API once integrated. + @Deprecated public String iccTransmitApduLogicalChannel(int subId, int channel, int cla, int instruction, int p1, int p2, int p3, String data) { try { @@ -5929,7 +5986,10 @@ public class TelephonyManager { * @return The APDU response from the ICC card with the status appended at * the end. * @hide + * @deprecated Use {@link android.se.omapi.SEService} APIs instead. */ + // TODO(b/147153909): Update Javadoc to link to specific SEService API once integrated. + @Deprecated @RequiresPermission(Manifest.permission.MODIFY_PHONE_STATE) @SystemApi @NonNull @@ -5965,7 +6025,10 @@ public class TelephonyManager { * @param data Data to be sent with the APDU. * @return The APDU response from the ICC card with the status appended at * the end. + * @deprecated Use {@link android.se.omapi.SEService} APIs instead. */ + // TODO(b/147153909): Update Javadoc to link to specific SEService API once integrated. + @Deprecated public String iccTransmitApduBasicChannel(int cla, int instruction, int p1, int p2, int p3, String data) { return iccTransmitApduBasicChannel(getSubId(), cla, @@ -5992,7 +6055,10 @@ public class TelephonyManager { * @return The APDU response from the ICC card with the status appended at * the end. * @hide + * @deprecated Use {@link android.se.omapi.SEService} APIs instead. */ + // TODO(b/147153909): Update Javadoc to link to specific SEService API once integrated. + @Deprecated public String iccTransmitApduBasicChannel(int subId, int cla, int instruction, int p1, int p2, int p3, String data) { try { @@ -6020,7 +6086,10 @@ public class TelephonyManager { * @param p3 P3 value of the APDU command. * @param filePath * @return The APDU response. + * @deprecated Use {@link android.se.omapi.SEService} APIs instead. */ + // TODO(b/147153909): Update Javadoc to link to specific SEService API once integrated. + @Deprecated public byte[] iccExchangeSimIO(int fileID, int command, int p1, int p2, int p3, String filePath) { return iccExchangeSimIO(getSubId(), fileID, command, p1, p2, p3, filePath); @@ -6042,7 +6111,10 @@ public class TelephonyManager { * @param filePath * @return The APDU response. * @hide + * @deprecated Use {@link android.se.omapi.SEService} APIs instead. */ + // TODO(b/147153909): Update Javadoc to link to specific SEService API once integrated. + @Deprecated public byte[] iccExchangeSimIO(int subId, int fileID, int command, int p1, int p2, int p3, String filePath) { try { @@ -6068,7 +6140,10 @@ public class TelephonyManager { * @return The APDU response from the ICC card in hexadecimal format * with the last 4 bytes being the status word. If the command fails, * returns an empty string. + * @deprecated Use {@link android.se.omapi.SEService} APIs instead. */ + // TODO(b/147153909): Update Javadoc to link to specific SEService API once integrated. + @Deprecated public String sendEnvelopeWithStatus(String content) { return sendEnvelopeWithStatus(getSubId(), content); } @@ -6088,7 +6163,10 @@ public class TelephonyManager { * with the last 4 bytes being the status word. If the command fails, * returns an empty string. * @hide + * @deprecated Use {@link android.se.omapi.SEService} APIs instead. */ + // TODO(b/147153909): Update Javadoc to link to specific SEService API once integrated. + @Deprecated public String sendEnvelopeWithStatus(int subId, String content) { try { ITelephony telephony = getITelephony(); @@ -6621,19 +6699,6 @@ public class TelephonyManager { } } - /** - * UICC SIM Application Types - * @hide - */ - @IntDef(prefix = { "APPTYPE_" }, value = { - APPTYPE_SIM, - APPTYPE_USIM, - APPTYPE_RUIM, - APPTYPE_CSIM, - APPTYPE_ISIM - }) - @Retention(RetentionPolicy.SOURCE) - public @interface UiccAppType{} /** UICC application type is SIM */ public static final int APPTYPE_SIM = PhoneConstants.APPTYPE_SIM; /** UICC application type is USIM */ @@ -6744,7 +6809,8 @@ public class TelephonyManager { ITelephony telephony = getITelephony(); if (telephony == null) return null; - return telephony.getForbiddenPlmns(subId, appType, mContext.getOpPackageName()); + return telephony.getForbiddenPlmns(subId, appType, mContext.getOpPackageName(), + getFeatureId()); } catch (RemoteException ex) { return null; } catch (NullPointerException ex) { @@ -6778,7 +6844,7 @@ public class TelephonyManager { ITelephony telephony = getITelephony(); if (telephony == null) return -1; return telephony.setForbiddenPlmns( - getSubId(), APPTYPE_USIM, fplmns, getOpPackageName()); + getSubId(), APPTYPE_USIM, fplmns, getOpPackageName(), getFeatureId()); } catch (RemoteException ex) { Rlog.e(TAG, "setForbiddenPlmns RemoteException: " + ex.getMessage()); } catch (NullPointerException ex) { @@ -6799,7 +6865,7 @@ public class TelephonyManager { ITelephony telephony = getITelephony(); if (telephony == null) return new String[0]; - return telephony.getPcscfAddress(apnType, getOpPackageName()); + return telephony.getPcscfAddress(apnType, getOpPackageName(), getFeatureId()); } catch (RemoteException e) { return new String[0]; } @@ -7310,7 +7376,8 @@ public class TelephonyManager { try { ITelephony telephony = getITelephony(); if (telephony != null) { - return telephony.getCellNetworkScanResults(getSubId(), getOpPackageName()); + return telephony.getCellNetworkScanResults(getSubId(), getOpPackageName(), + getFeatureId()); } } catch (RemoteException ex) { Rlog.e(TAG, "getAvailableNetworks RemoteException", ex); @@ -7365,7 +7432,7 @@ public class TelephonyManager { } } return mTelephonyScanManager.requestNetworkScan(getSubId(), request, executor, callback, - getOpPackageName()); + getOpPackageName(), getFeatureId()); } /** @@ -8037,7 +8104,7 @@ public class TelephonyManager { try { ITelephony telephony = getITelephony(); if (telephony != null) - return telephony.isRadioOn(getOpPackageName()); + return telephony.isRadioOnWithFeature(getOpPackageName(), getFeatureId()); } catch (RemoteException e) { Log.e(TAG, "Error calling ITelephony#isRadioOn", e); } @@ -8051,9 +8118,9 @@ public class TelephonyManager { try { ITelephony telephony = getITelephony(); if (telephony != null) - return telephony.supplyPin(pin); + return telephony.supplyPinForSubscriber(getSubId(), pin); } catch (RemoteException e) { - Log.e(TAG, "Error calling ITelephony#supplyPin", e); + Log.e(TAG, "Error calling ITelephony#supplyPinForSubscriber", e); } return false; } @@ -8065,9 +8132,9 @@ public class TelephonyManager { try { ITelephony telephony = getITelephony(); if (telephony != null) - return telephony.supplyPuk(puk, pin); + return telephony.supplyPukForSubscriber(getSubId(), puk, pin); } catch (RemoteException e) { - Log.e(TAG, "Error calling ITelephony#supplyPuk", e); + Log.e(TAG, "Error calling ITelephony#supplyPukForSubscriber", e); } return false; } @@ -8079,9 +8146,9 @@ public class TelephonyManager { try { ITelephony telephony = getITelephony(); if (telephony != null) - return telephony.supplyPinReportResult(pin); + return telephony.supplyPinReportResultForSubscriber(getSubId(), pin); } catch (RemoteException e) { - Log.e(TAG, "Error calling ITelephony#supplyPinReportResult", e); + Log.e(TAG, "Error calling ITelephony#supplyPinReportResultForSubscriber", e); } return new int[0]; } @@ -8093,7 +8160,7 @@ public class TelephonyManager { try { ITelephony telephony = getITelephony(); if (telephony != null) - return telephony.supplyPukReportResult(puk, pin); + return telephony.supplyPukReportResultForSubscriber(getSubId(), puk, pin); } catch (RemoteException e) { Log.e(TAG, "Error calling ITelephony#]", e); } @@ -8350,7 +8417,8 @@ public class TelephonyManager { try { ITelephony telephony = getITelephony(); if (telephony != null) { - return telephony.getRadioPowerState(getSlotIndex(), mContext.getOpPackageName()); + return telephony.getRadioPowerState(getSlotIndex(), mContext.getOpPackageName(), + null); } } catch (RemoteException ex) { // This could happen if binder process crashes. @@ -8708,7 +8776,7 @@ public class TelephonyManager { try { ITelephony telephony = getITelephony(); if (telephony != null) - return telephony.isVideoCallingEnabled(getOpPackageName()); + return telephony.isVideoCallingEnabled(getOpPackageName(), getFeatureId()); } catch (RemoteException e) { Log.e(TAG, "Error calling ITelephony#isVideoCallingEnabled", e); } @@ -8724,7 +8792,8 @@ public class TelephonyManager { try { ITelephony telephony = getITelephony(); if (telephony != null) { - return telephony.canChangeDtmfToneLength(mSubId, getOpPackageName()); + return telephony.canChangeDtmfToneLength(mSubId, getOpPackageName(), + getFeatureId()); } } catch (RemoteException e) { Log.e(TAG, "Error calling ITelephony#canChangeDtmfToneLength", e); @@ -8743,7 +8812,7 @@ public class TelephonyManager { try { ITelephony telephony = getITelephony(); if (telephony != null) { - return telephony.isWorldPhone(mSubId, getOpPackageName()); + return telephony.isWorldPhone(mSubId, getOpPackageName(), getFeatureId()); } } catch (RemoteException e) { Log.e(TAG, "Error calling ITelephony#isWorldPhone", e); @@ -9024,15 +9093,20 @@ public class TelephonyManager { } /** - * Requested state of SIM - * - * CARD_POWER_DOWN * Powers down the SIM. SIM must be up prior. - * - * CARD_POWER_UP + * @hide + */ + @SystemApi + public static final int CARD_POWER_DOWN = 0; + + /** * Powers up the SIM normally. SIM must be down prior. - * - * CARD_POWER_UP_PASS_THROUGH + * @hide + */ + @SystemApi + public static final int CARD_POWER_UP = 1; + + /** * Powers up the SIM in PASS_THROUGH mode. SIM must be down prior. * When SIM is powered up in PASS_THOUGH mode, the modem does not send * any command to it (for example SELECT of MF, or TERMINAL CAPABILITY), @@ -9045,12 +9119,9 @@ public class TelephonyManager { * is activated, and normal behavior occurs at the next SIM initialization, * unless PASS_THROUGH mode is requested again. Hence, the last power-up mode * is NOT persistent across boots. On reboot, SIM will power up normally. + * @hide */ - /** @hide */ - public static final int CARD_POWER_DOWN = 0; - /** @hide */ - public static final int CARD_POWER_UP = 1; - /** @hide */ + @SystemApi public static final int CARD_POWER_UP_PASS_THROUGH = 2; /** @@ -9469,7 +9540,7 @@ public class TelephonyManager { ITelephony service = getITelephony(); if (service != null) { retval = service.getSubIdForPhoneAccountHandle( - phoneAccountHandle, mContext.getOpPackageName()); + phoneAccountHandle, mContext.getOpPackageName(), null); } } catch (RemoteException ex) { Log.e(TAG, "getSubscriptionId RemoteException", ex); @@ -9607,7 +9678,8 @@ public class TelephonyManager { try { ITelephony service = getITelephony(); if (service != null) { - return service.getServiceStateForSubscriber(subId, getOpPackageName()); + return service.getServiceStateForSubscriber(subId, getOpPackageName(), + getFeatureId()); } } catch (RemoteException e) { Log.e(TAG, "Error calling ITelephony#getServiceStateForSubscriber", e); @@ -10202,6 +10274,7 @@ public class TelephonyManager { * {@link android.Manifest.permission#MODIFY_PHONE_STATE MODIFY_PHONE_STATE}. * * @param enabled control enable or disable carrier data. + * @see #resetAllCarrierActions() * @hide */ @SystemApi @@ -10228,6 +10301,7 @@ public class TelephonyManager { * {@link android.Manifest.permission#MODIFY_PHONE_STATE MODIFY_PHONE_STATE}. * * @param enabled control enable or disable radio. + * @see #resetAllCarrierActions() * @hide */ @SystemApi @@ -10254,6 +10328,7 @@ public class TelephonyManager { * {@link android.Manifest.permission#MODIFY_PHONE_STATE MODIFY_PHONE_STATE}. * * @param report control start/stop reporting network status. + * @see #resetAllCarrierActions() * @hide */ @SystemApi @@ -10347,7 +10422,7 @@ public class TelephonyManager { try { ITelephony service = getITelephony(); if (service != null) { - return service.getClientRequestStats(getOpPackageName(), subId); + return service.getClientRequestStats(getOpPackageName(), getFeatureId(), subId); } } catch (RemoteException e) { Log.e(TAG, "Error calling ITelephony#getClientRequestStats", e); @@ -10636,7 +10711,7 @@ public class TelephonyManager { ITelephony telephony = getITelephony(); if (telephony != null) { return telephony.getNumberOfModemsWithSimultaneousDataConnections( - getSubId(), getOpPackageName()); + getSubId(), getOpPackageName(), getFeatureId()); } } catch (RemoteException ex) { // This could happen if binder process crashes. @@ -10992,7 +11067,8 @@ public class TelephonyManager { try { ITelephony telephony = getITelephony(); if (telephony != null) { - return telephony.getEmergencyNumberList(mContext.getOpPackageName()); + return telephony.getEmergencyNumberList(mContext.getOpPackageName(), + null); } else { throw new IllegalStateException("telephony service is null."); } @@ -11047,7 +11123,7 @@ public class TelephonyManager { ITelephony telephony = getITelephony(); if (telephony != null) { emergencyNumberList = telephony.getEmergencyNumberList( - mContext.getOpPackageName()); + mContext.getOpPackageName(), null); if (emergencyNumberList != null) { for (Integer subscriptionId : emergencyNumberList.keySet()) { List<EmergencyNumber> numberList = emergencyNumberList.get(subscriptionId); @@ -11353,12 +11429,14 @@ public class TelephonyManager { android.Manifest.permission.READ_PHONE_STATE }) public int getPreferredOpportunisticDataSubscription() { - String pkgForDebug = mContext != null ? mContext.getOpPackageName() : "<unknown>"; + String packageName = mContext != null ? mContext.getOpPackageName() : "<unknown>"; + String featureId = null; int subId = SubscriptionManager.INVALID_SUBSCRIPTION_ID; try { IOns iOpportunisticNetworkService = getIOns(); if (iOpportunisticNetworkService != null) { - subId = iOpportunisticNetworkService.getPreferredDataSubscriptionId(pkgForDebug); + subId = iOpportunisticNetworkService.getPreferredDataSubscriptionId( + packageName, featureId); } } catch (RemoteException ex) { Rlog.e(TAG, "getPreferredDataSubscriptionId RemoteException", ex); @@ -11485,7 +11563,8 @@ public class TelephonyManager { try { ITelephony telephony = getITelephony(); if (telephony != null) { - return telephony.isModemEnabledForSlot(slotIndex, mContext.getOpPackageName()); + return telephony.isModemEnabledForSlot(slotIndex, mContext.getOpPackageName(), + null); } } catch (RemoteException ex) { Log.e(TAG, "enableModem RemoteException", ex); @@ -11590,7 +11669,7 @@ public class TelephonyManager { try { ITelephony service = getITelephony(); if (service != null) { - return service.isMultiSimSupported(getOpPackageName()); + return service.isMultiSimSupported(getOpPackageName(), getFeatureId()); } } catch (RemoteException e) { Log.e(TAG, "isMultiSimSupported RemoteException", e); @@ -11642,7 +11721,7 @@ public class TelephonyManager { ITelephony service = getITelephony(); if (service != null) { return service.doesSwitchMultiSimConfigTriggerReboot(getSubId(), - getOpPackageName()); + getOpPackageName(), getFeatureId()); } } catch (RemoteException e) { Log.e(TAG, "doesSwitchMultiSimConfigTriggerReboot RemoteException", e); @@ -11676,6 +11755,32 @@ public class TelephonyManager { } /** + * Get the calling application status about carrier privileges for the subscription created + * in TelephonyManager. Used by Telephony Module for permission checking. + * + * @param uid Uid to check. + * @return any value of {@link #CARRIER_PRIVILEGE_STATUS_HAS_ACCESS}, + * {@link #CARRIER_PRIVILEGE_STATUS_NO_ACCESS}, + * {@link #CARRIER_PRIVILEGE_STATUS_RULES_NOT_LOADED}, or + * {@link #CARRIER_PRIVILEGE_STATUS_ERROR_LOADING_RULES} + * + * @hide + */ + @SystemApi + @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) + public int getCarrierPrivilegeStatus(int uid) { + try { + ITelephony telephony = getITelephony(); + if (telephony != null) { + return telephony.getCarrierPrivilegeStatusForUid(getSubId(), uid); + } + } catch (RemoteException ex) { + Log.e(TAG, "getCarrierPrivilegeStatus RemoteException", ex); + } + return TelephonyManager.CARRIER_PRIVILEGE_STATUS_NO_ACCESS; + } + + /** * Returns a list of APNs set as overrides by the device policy manager via * {@link #addDevicePolicyOverrideApn}. * This method must only be called from the system or phone processes. @@ -11815,6 +11920,37 @@ public class TelephonyManager { } /** + * Verifies whether the input MCC/MNC and MVNO correspond to the current carrier. + * + * @param mccmnc the carrier's mccmnc that you want to match + * @param mvnoType the mvnoType that defined in {@link ApnSetting} + * @param mvnoMatchData the MVNO match data + * @return {@code true} if input mccmnc and mvno matches with data from sim operator. + * {@code false} otherwise. + * + * {@hide} + */ + @SystemApi + public boolean isCurrentSimOperator(@NonNull String mccmnc, @MvnoType int mvnoType, + @Nullable String mvnoMatchData) { + try { + if (!mccmnc.equals(getSimOperator())) { + Log.d(TAG, "The mccmnc does not match"); + return false; + } + ITelephony service = getITelephony(); + if (service != null) { + return service.isMvnoMatched(getSubId(), mvnoType, mvnoMatchData); + } + } catch (RemoteException ex) { + if (!isSystemProcess()) { + ex.rethrowAsRuntimeException(); + } + } + return false; + } + + /** * Set allowing mobile data during voice call. * * @param allow {@code true} if allowing using data during voice call, {@code false} if diff --git a/telephony/java/android/telephony/TelephonyScanManager.java b/telephony/java/android/telephony/TelephonyScanManager.java index 9ff851598648..1651c8111ce8 100644 --- a/telephony/java/android/telephony/TelephonyScanManager.java +++ b/telephony/java/android/telephony/TelephonyScanManager.java @@ -16,6 +16,8 @@ package android.telephony; +import com.android.telephony.Rlog; + import static com.android.internal.util.Preconditions.checkNotNull; import android.content.Context; @@ -200,13 +202,14 @@ public final class TelephonyScanManager { */ public NetworkScan requestNetworkScan(int subId, NetworkScanRequest request, Executor executor, NetworkScanCallback callback, - String callingPackage) { + String callingPackage, String callingFeatureId) { try { ITelephony telephony = getITelephony(); if (telephony != null) { synchronized (mScanInfo) { int scanId = telephony.requestNetworkScan( - subId, request, mMessenger, new Binder(), callingPackage); + subId, request, mMessenger, new Binder(), callingPackage, + callingFeatureId); if (scanId == INVALID_SCAN_ID) { Rlog.e(TAG, "Failed to initiate network scan"); return null; diff --git a/telephony/java/android/telephony/UiccAccessRule.java b/telephony/java/android/telephony/UiccAccessRule.java index 93ccba1dd996..81a09c645070 100644 --- a/telephony/java/android/telephony/UiccAccessRule.java +++ b/telephony/java/android/telephony/UiccAccessRule.java @@ -15,6 +15,8 @@ */ package android.telephony; +import com.android.telephony.Rlog; + import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.SystemApi; diff --git a/telephony/java/android/telephony/VoLteServiceState.java b/telephony/java/android/telephony/VoLteServiceState.java index f65c7b0c0c9b..6b1544376a6c 100644 --- a/telephony/java/android/telephony/VoLteServiceState.java +++ b/telephony/java/android/telephony/VoLteServiceState.java @@ -16,12 +16,12 @@ package android.telephony; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; +import com.android.telephony.Rlog; import android.os.Build; import android.os.Bundle; import android.os.Parcel; import android.os.Parcelable; -import android.telephony.Rlog; /** * Contains LTE network state related information. diff --git a/telephony/java/android/telephony/cdma/CdmaCellLocation.java b/telephony/java/android/telephony/cdma/CdmaCellLocation.java index 45b1e474b93d..9bc39a0c6ced 100644 --- a/telephony/java/android/telephony/cdma/CdmaCellLocation.java +++ b/telephony/java/android/telephony/cdma/CdmaCellLocation.java @@ -16,7 +16,7 @@ package android.telephony.cdma; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.os.Build; import android.os.Bundle; import android.telephony.CellLocation; diff --git a/telephony/java/android/telephony/data/ApnSetting.java b/telephony/java/android/telephony/data/ApnSetting.java index dbfb6a2a0f2e..fab1bf2215af 100644 --- a/telephony/java/android/telephony/data/ApnSetting.java +++ b/telephony/java/android/telephony/data/ApnSetting.java @@ -28,7 +28,7 @@ import android.provider.Telephony; import android.provider.Telephony.Carriers; import android.telephony.Annotation.ApnType; import android.telephony.Annotation.NetworkType; -import android.telephony.Rlog; +import com.android.telephony.Rlog; import android.telephony.ServiceState; import android.telephony.TelephonyManager; import android.text.TextUtils; diff --git a/telephony/java/android/telephony/data/DataService.java b/telephony/java/android/telephony/data/DataService.java index 372bdf1c0f81..bff12b624ae8 100644 --- a/telephony/java/android/telephony/data/DataService.java +++ b/telephony/java/android/telephony/data/DataService.java @@ -31,7 +31,7 @@ import android.os.Looper; import android.os.Message; import android.os.RemoteException; import android.telephony.AccessNetworkConstants; -import android.telephony.Rlog; +import com.android.telephony.Rlog; import android.util.SparseArray; import com.android.internal.annotations.VisibleForTesting; diff --git a/telephony/java/android/telephony/data/DataServiceCallback.java b/telephony/java/android/telephony/data/DataServiceCallback.java index 11dc78a611ff..d33d3f9a5eee 100644 --- a/telephony/java/android/telephony/data/DataServiceCallback.java +++ b/telephony/java/android/telephony/data/DataServiceCallback.java @@ -22,7 +22,7 @@ import android.annotation.Nullable; import android.annotation.SystemApi; import android.net.LinkProperties; import android.os.RemoteException; -import android.telephony.Rlog; +import com.android.telephony.Rlog; import android.telephony.data.DataService.DataServiceProvider; import java.lang.annotation.Retention; diff --git a/telephony/java/android/telephony/data/QualifiedNetworksService.java b/telephony/java/android/telephony/data/QualifiedNetworksService.java index e793979a61c9..8220b16500de 100644 --- a/telephony/java/android/telephony/data/QualifiedNetworksService.java +++ b/telephony/java/android/telephony/data/QualifiedNetworksService.java @@ -28,7 +28,7 @@ import android.os.Message; import android.os.RemoteException; import android.telephony.AccessNetworkConstants.AccessNetworkType; import android.telephony.Annotation.ApnType; -import android.telephony.Rlog; +import com.android.telephony.Rlog; import android.util.SparseArray; import com.android.internal.annotations.VisibleForTesting; diff --git a/telephony/java/android/telephony/emergency/EmergencyNumber.java b/telephony/java/android/telephony/emergency/EmergencyNumber.java index 16662652847d..cd3fc953f9d2 100644 --- a/telephony/java/android/telephony/emergency/EmergencyNumber.java +++ b/telephony/java/android/telephony/emergency/EmergencyNumber.java @@ -25,7 +25,7 @@ import android.os.Parcel; import android.os.Parcelable; import android.telephony.CarrierConfigManager; import android.telephony.PhoneNumberUtils; -import android.telephony.Rlog; +import com.android.telephony.Rlog; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; diff --git a/telephony/java/android/telephony/euicc/DownloadableSubscription.java b/telephony/java/android/telephony/euicc/DownloadableSubscription.java index cb27f64da7fa..23d46ba09599 100644 --- a/telephony/java/android/telephony/euicc/DownloadableSubscription.java +++ b/telephony/java/android/telephony/euicc/DownloadableSubscription.java @@ -17,17 +17,18 @@ package android.telephony.euicc; import android.annotation.Nullable; import android.annotation.SystemApi; -import android.annotation.UnsupportedAppUsage; import android.app.PendingIntent; +import android.compat.annotation.UnsupportedAppUsage; import android.os.Parcel; import android.os.Parcelable; import android.telephony.UiccAccessRule; + +import com.android.internal.util.Preconditions; + import java.util.ArrayList; import java.util.Arrays; import java.util.List; -import com.android.internal.util.Preconditions; - /** * Information about a subscription which is downloadable to an eUICC using * {@link EuiccManager#downloadSubscription(DownloadableSubscription, boolean, PendingIntent). diff --git a/telephony/java/android/telephony/euicc/EuiccInfo.java b/telephony/java/android/telephony/euicc/EuiccInfo.java index 91ebb6ca2d45..467d2689cd3c 100644 --- a/telephony/java/android/telephony/euicc/EuiccInfo.java +++ b/telephony/java/android/telephony/euicc/EuiccInfo.java @@ -16,7 +16,7 @@ package android.telephony.euicc; import android.annotation.Nullable; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.os.Parcel; import android.os.Parcelable; diff --git a/telephony/java/android/telephony/gsm/GsmCellLocation.java b/telephony/java/android/telephony/gsm/GsmCellLocation.java index d6780ce107c9..30cea0e6dd59 100644 --- a/telephony/java/android/telephony/gsm/GsmCellLocation.java +++ b/telephony/java/android/telephony/gsm/GsmCellLocation.java @@ -16,7 +16,7 @@ package android.telephony.gsm; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.os.Build; import android.os.Bundle; import android.telephony.CellLocation; diff --git a/telephony/java/android/telephony/ims/ImsCallForwardInfo.java b/telephony/java/android/telephony/ims/ImsCallForwardInfo.java index 9f09d7a93a82..d53a2e6591a2 100644 --- a/telephony/java/android/telephony/ims/ImsCallForwardInfo.java +++ b/telephony/java/android/telephony/ims/ImsCallForwardInfo.java @@ -20,7 +20,7 @@ import android.annotation.IntDef; import android.annotation.NonNull; import android.annotation.SystemApi; import android.annotation.TestApi; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.os.Parcel; import android.os.Parcelable; diff --git a/telephony/java/android/telephony/ims/ImsCallProfile.java b/telephony/java/android/telephony/ims/ImsCallProfile.java index 87e53919c2a1..998b39dfb436 100644 --- a/telephony/java/android/telephony/ims/ImsCallProfile.java +++ b/telephony/java/android/telephony/ims/ImsCallProfile.java @@ -20,7 +20,7 @@ import android.annotation.IntDef; import android.annotation.NonNull; import android.annotation.SystemApi; import android.annotation.TestApi; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.os.Bundle; import android.os.Parcel; import android.os.Parcelable; diff --git a/telephony/java/android/telephony/ims/ImsConferenceState.java b/telephony/java/android/telephony/ims/ImsConferenceState.java index 8d2049b97138..abfee61930ed 100644 --- a/telephony/java/android/telephony/ims/ImsConferenceState.java +++ b/telephony/java/android/telephony/ims/ImsConferenceState.java @@ -24,7 +24,7 @@ import android.os.Parcel; import android.os.Parcelable; import android.telecom.Call; import android.telecom.Connection; -import android.telephony.Rlog; +import com.android.telephony.Rlog; import android.util.Log; import java.util.HashMap; diff --git a/telephony/java/android/telephony/ims/ImsExternalCallState.java b/telephony/java/android/telephony/ims/ImsExternalCallState.java index dcb9c9d5ec27..136a83e2eec9 100644 --- a/telephony/java/android/telephony/ims/ImsExternalCallState.java +++ b/telephony/java/android/telephony/ims/ImsExternalCallState.java @@ -24,7 +24,7 @@ import android.annotation.TestApi; import android.net.Uri; import android.os.Parcel; import android.os.Parcelable; -import android.telephony.Rlog; +import com.android.telephony.Rlog; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; diff --git a/telephony/java/android/telephony/ims/ImsRcsManager.java b/telephony/java/android/telephony/ims/ImsRcsManager.java index 0c8dba664b0a..5aa37bba7efe 100644 --- a/telephony/java/android/telephony/ims/ImsRcsManager.java +++ b/telephony/java/android/telephony/ims/ImsRcsManager.java @@ -28,6 +28,7 @@ import android.os.IBinder; import android.os.RemoteException; import android.os.ServiceManager; import android.telephony.AccessNetworkConstants; +import android.telephony.SubscriptionManager; import android.telephony.ims.aidl.IImsCapabilityCallback; import android.telephony.ims.aidl.IImsRcsController; import android.telephony.ims.feature.ImsFeature; @@ -35,6 +36,8 @@ import android.telephony.ims.feature.RcsFeature; import android.telephony.ims.stub.ImsRegistrationImplBase; import android.util.Log; +import com.android.internal.telephony.IIntegerConsumer; + import java.util.concurrent.Executor; import java.util.function.Consumer; @@ -154,9 +157,20 @@ public class ImsRcsManager implements RegistrationManager { if (executor == null) { throw new IllegalArgumentException("Must include a non-null Executor."); } + + IImsRcsController imsRcsController = getIImsRcsController(); + if (imsRcsController == null) { + Log.e(TAG, "Register registration callback: IImsRcsController is null"); + throw new ImsException("Cannot find remote IMS service", + ImsException.CODE_ERROR_SERVICE_UNAVAILABLE); + } + c.setExecutor(executor); - throw new UnsupportedOperationException("registerImsRegistrationCallback is not" - + "supported."); + try { + imsRcsController.registerImsRegistrationCallback(mSubId, c.getBinder()); + } catch (RemoteException | IllegalStateException e) { + throw new ImsException(e.getMessage(), ImsException.CODE_ERROR_SERVICE_UNAVAILABLE); + } } /**{@inheritDoc}*/ @@ -167,8 +181,18 @@ public class ImsRcsManager implements RegistrationManager { if (c == null) { throw new IllegalArgumentException("Must include a non-null RegistrationCallback."); } - throw new UnsupportedOperationException("unregisterImsRegistrationCallback is not" - + "supported."); + + IImsRcsController imsRcsController = getIImsRcsController(); + if (imsRcsController == null) { + Log.e(TAG, "Unregister registration callback: IImsRcsController is null"); + throw new IllegalStateException("Cannot find remote IMS service"); + } + + try { + imsRcsController.unregisterImsRegistrationCallback(mSubId, c.getBinder()); + } catch (RemoteException e) { + throw e.rethrowAsRuntimeException(); + } } /**{@inheritDoc}*/ @@ -182,8 +206,23 @@ public class ImsRcsManager implements RegistrationManager { if (executor == null) { throw new IllegalArgumentException("Must include a non-null Executor."); } - throw new UnsupportedOperationException("getRegistrationState is not" - + "supported."); + + IImsRcsController imsRcsController = getIImsRcsController(); + if (imsRcsController == null) { + Log.e(TAG, "Get registration state error: IImsRcsController is null"); + throw new IllegalStateException("Cannot find remote IMS service"); + } + + try { + imsRcsController.getImsRcsRegistrationState(mSubId, new IIntegerConsumer.Stub() { + @Override + public void accept(int result) { + executor.execute(() -> stateCallback.accept(result)); + } + }); + } catch (RemoteException e) { + throw e.rethrowAsRuntimeException(); + } } /**{@inheritDoc}*/ @@ -198,10 +237,25 @@ public class ImsRcsManager implements RegistrationManager { if (executor == null) { throw new IllegalArgumentException("Must include a non-null Executor."); } - throw new UnsupportedOperationException("getRegistrationTransportType is not" - + "supported."); - } + IImsRcsController imsRcsController = getIImsRcsController(); + if (imsRcsController == null) { + Log.e(TAG, "Get registration transport type error: IImsRcsController is null"); + throw new IllegalStateException("Cannot find remote IMS service"); + } + + try { + imsRcsController.getImsRcsRegistrationTransportType(mSubId, + new IIntegerConsumer.Stub() { + @Override + public void accept(int result) { + executor.execute(() -> transportTypeCallback.accept(result)); + } + }); + } catch (RemoteException e) { + throw e.rethrowAsRuntimeException(); + } + } /** * Registers an {@link AvailabilityCallback} with the system, which will provide RCS diff --git a/telephony/java/android/telephony/ims/ImsReasonInfo.java b/telephony/java/android/telephony/ims/ImsReasonInfo.java index f4b2cef73a44..0d6b31d349e1 100644 --- a/telephony/java/android/telephony/ims/ImsReasonInfo.java +++ b/telephony/java/android/telephony/ims/ImsReasonInfo.java @@ -20,7 +20,7 @@ import android.annotation.IntDef; import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.SystemApi; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.os.Build; import android.os.Parcel; import android.os.Parcelable; diff --git a/telephony/java/android/telephony/ims/ImsSsData.java b/telephony/java/android/telephony/ims/ImsSsData.java index 6b728599c7d3..2d2e63812fad 100644 --- a/telephony/java/android/telephony/ims/ImsSsData.java +++ b/telephony/java/android/telephony/ims/ImsSsData.java @@ -22,7 +22,7 @@ import android.annotation.SystemApi; import android.annotation.TestApi; import android.os.Parcel; import android.os.Parcelable; -import android.telephony.Rlog; +import com.android.telephony.Rlog; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; diff --git a/telephony/java/android/telephony/ims/ImsSsInfo.java b/telephony/java/android/telephony/ims/ImsSsInfo.java index 77bd98411037..9cce95fc67f8 100644 --- a/telephony/java/android/telephony/ims/ImsSsInfo.java +++ b/telephony/java/android/telephony/ims/ImsSsInfo.java @@ -21,7 +21,7 @@ import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.SystemApi; import android.annotation.TestApi; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.os.Parcel; import android.os.Parcelable; diff --git a/telephony/java/android/telephony/ims/ImsStreamMediaProfile.java b/telephony/java/android/telephony/ims/ImsStreamMediaProfile.java index b7ab0a09a1cb..b70fd649ab79 100644 --- a/telephony/java/android/telephony/ims/ImsStreamMediaProfile.java +++ b/telephony/java/android/telephony/ims/ImsStreamMediaProfile.java @@ -19,7 +19,7 @@ package android.telephony.ims; import android.annotation.NonNull; import android.annotation.SystemApi; import android.annotation.TestApi; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.os.Parcel; import android.os.Parcelable; diff --git a/telephony/java/android/telephony/ims/ImsVideoCallProvider.java b/telephony/java/android/telephony/ims/ImsVideoCallProvider.java index 270e693c8825..569c6d5a4e4d 100644 --- a/telephony/java/android/telephony/ims/ImsVideoCallProvider.java +++ b/telephony/java/android/telephony/ims/ImsVideoCallProvider.java @@ -18,7 +18,7 @@ package android.telephony.ims; import android.annotation.SystemApi; import android.annotation.TestApi; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.net.Uri; import android.os.Handler; import android.os.Looper; diff --git a/telephony/java/android/telephony/ims/ProvisioningManager.java b/telephony/java/android/telephony/ims/ProvisioningManager.java index e16085e30465..36624f27b0d5 100644 --- a/telephony/java/android/telephony/ims/ProvisioningManager.java +++ b/telephony/java/android/telephony/ims/ProvisioningManager.java @@ -26,8 +26,6 @@ import android.annotation.SystemApi; import android.annotation.TestApi; import android.annotation.WorkerThread; import android.content.Context; -import android.content.pm.IPackageManager; -import android.content.pm.PackageManager; import android.os.Binder; import android.os.RemoteException; import android.os.ServiceManager; @@ -35,6 +33,7 @@ import android.telephony.CarrierConfigManager; import android.telephony.SubscriptionManager; import android.telephony.ims.aidl.IImsConfigCallback; import android.telephony.ims.feature.MmTelFeature; +import android.telephony.ims.feature.RcsFeature; import android.telephony.ims.stub.ImsConfigImplBase; import android.telephony.ims.stub.ImsRegistrationImplBase; @@ -85,6 +84,11 @@ public class ProvisioningManager { "STRING_QUERY_RESULT_ERROR_NOT_READY"; /** + * There is no existing configuration for the queried provisioning key. + */ + public static final int PROVISIONING_RESULT_UNKNOWN = -1; + + /** * The integer result of provisioning for the queried key is disabled. */ public static final int PROVISIONING_VALUE_DISABLED = 0; @@ -95,6 +99,151 @@ public class ProvisioningManager { public static final int PROVISIONING_VALUE_ENABLED = 1; + // Inheriting values from ImsConfig for backwards compatibility. + /** + * An integer key representing the SIP T1 timer value in milliseconds for the associated + * subscription. + * <p> + * The SIP T1 timer is an estimate of the round-trip time and will retransmit + * INVITE transactions that are longer than T1 milliseconds over unreliable transports, doubling + * the time before retransmission every time there is no response. See RFC3261, section 17.1.1.1 + * for more details. + * <p> + * The value is an integer. + * @see #setProvisioningIntValue(int, int) + * @see #getProvisioningIntValue(int) + */ + public static final int KEY_T1_TIMER_VALUE_MS = 7; + + /** + * An integer key representing the voice over LTE (VoLTE) provisioning status for the + * associated subscription. Determines whether the user can register for voice services over + * LTE. + * <p> + * Use {@link #PROVISIONING_VALUE_ENABLED} to enable VoLTE provisioning and + * {@link #PROVISIONING_VALUE_DISABLED} to disable VoLTE provisioning. + * @see #setProvisioningIntValue(int, int) + * @see #getProvisioningIntValue(int) + */ + public static final int KEY_VOLTE_PROVISIONING_STATUS = 10; + + /** + * An integer key representing the video telephony (VT) provisioning status for the + * associated subscription. Determines whether the user can register for video services over + * LTE. + * <p> + * Use {@link #PROVISIONING_VALUE_ENABLED} to enable VT provisioning and + * {@link #PROVISIONING_VALUE_DISABLED} to disable VT provisioning. + * @see #setProvisioningIntValue(int, int) + * @see #getProvisioningIntValue(int) + */ + public static final int KEY_VT_PROVISIONING_STATUS = 11; + + /** + * An integer key associated with the carrier configured SIP PUBLISH timer, which dictates the + * expiration time in seconds for published online availability in RCS presence. + * <p> + * Value is in Integer format. + * @see #setProvisioningIntValue(int, int) + * @see #getProvisioningIntValue(int) + */ + public static final int KEY_RCS_PUBLISH_TIMER_SEC = 15; + + /** + * An integer key associated with the carrier configured expiration time in seconds for + * RCS presence published offline availability in RCS presence. + * <p> + * Value is in Integer format. + * @see #setProvisioningIntValue(int, int) + * @see #getProvisioningIntValue(int) + */ + public static final int KEY_RCS_PUBLISH_TIMER_EXTENDED_SEC = 16; + + /** + * An integer key associated with whether or not capability discovery is provisioned for this + * subscription. Any capability requests will be ignored by the RCS service. + * <p> + * The value is an integer, either {@link #PROVISIONING_VALUE_DISABLED} if capability + * discovery is disabled or {@link #PROVISIONING_VALUE_ENABLED} if capability discovery is + * enabled. + * @see #setProvisioningIntValue(int, int) + * @see #getProvisioningIntValue(int) + */ + public static final int KEY_RCS_CAPABILITY_DISCOVERY_ENABLED = 17; + + /** + * An integer key associated with the period of time the capability information of each contact + * is cached on the device. + * <p> + * Value is in Integer format. + * @see #setProvisioningIntValue(int, int) + * @see #getProvisioningIntValue(int) + */ + public static final int KEY_RCS_CAPABILITIES_CACHE_EXPIRATION_SEC = 18; + + /** + * An integer key associated with the period of time in seconds that the availability + * information of a contact is cached on the device. + * <p> + * Value is in Integer format. + * @see #setProvisioningIntValue(int, int) + * @see #getProvisioningIntValue(int) + */ + public static final int KEY_RCS_AVAILABILITY_CACHE_EXPIRATION_SEC = 19; + + /** + * An integer key associated with the carrier configured interval in seconds expected between + * successive capability polling attempts. + * <p> + * Value is in Integer format. + * @see #setProvisioningIntValue(int, int) + * @see #getProvisioningIntValue(int) + */ + public static final int KEY_RCS_CAPABILITIES_POLL_INTERVAL_SEC = 20; + + /** + * An integer key representing the minimum time allowed between two consecutive presence publish + * messages from the device. + * <p> + * Value is in Integer format. + * @see #setProvisioningIntValue(int, int) + * @see #getProvisioningIntValue(int) + */ + public static final int KEY_RCS_PUBLISH_SOURCE_THROTTLE_MS = 21; + + /** + * An integer key associated with the maximum number of MDNs contained in one SIP Request + * Contained List (RCS) used to retrieve the RCS capabilities of the contacts book. + * <p> + * Value is in Integer format. + * @see #setProvisioningIntValue(int, int) + * @see #getProvisioningIntValue(int) + */ + public static final int KEY_RCS_MAX_NUM_ENTRIES_IN_RCL = 22; + + /** + * An integer associated with the expiration timer used duriing the SIP subscription of a + * Request Contained List (RCL), which is used to retrieve the RCS capabilities of the contact + * book. + * <p> + * Value is in Integer format. + * @see #setProvisioningIntValue(int, int) + * @see #getProvisioningIntValue(int) + */ + public static final int KEY_RCS_CAPABILITY_POLL_LIST_SUB_EXP_SEC = 23; + + /** + * An integer key representing the RCS enhanced address book (EAB) provisioning status for the + * associated subscription. Determines whether or not SIP OPTIONS or presence will be used to + * retrieve RCS capabilities for the user's contacts. + * <p> + * Use {@link #PROVISIONING_VALUE_ENABLED} to enable EAB provisioning and + * {@link #PROVISIONING_VALUE_DISABLED} to disable EAB provisioning. + * @see #setProvisioningIntValue(int, int) + * @see #getProvisioningIntValue(int) + */ + public static final int KEY_EAB_PROVISIONING_STATUS = 25; + /** * Override the user-defined WiFi Roaming enabled setting for this subscription, defined in * {@link SubscriptionManager#WFC_ROAMING_ENABLED_CONTENT_URI}, for the purposes of provisioning @@ -225,10 +374,6 @@ public class ProvisioningManager { @RequiresPermission(Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public void registerProvisioningChangedCallback(@NonNull @CallbackExecutor Executor executor, @NonNull Callback callback) throws ImsException { - if (!isImsAvailableOnDevice()) { - throw new ImsException("IMS not available on device.", - ImsException.CODE_ERROR_UNSUPPORTED_OPERATION); - } callback.setExecutor(executor); try { getITelephony().registerImsProvisioningChangedCallback(mSubId, callback.getBinder()); @@ -263,7 +408,7 @@ public class ProvisioningManager { * * @param key An integer that represents the provisioning key, which is defined by the OEM. * @return an integer value for the provided key, or - * {@link ImsConfigImplBase#CONFIG_RESULT_UNKNOWN} if the key doesn't exist. + * {@link #PROVISIONING_RESULT_UNKNOWN} if the key doesn't exist. * @throws IllegalArgumentException if the key provided was invalid. */ @WorkerThread @@ -390,37 +535,75 @@ public class ProvisioningManager { } /** + * Get the provisioning status for the IMS RCS capability specified. + * + * If provisioning is not required for the queried + * {@link RcsFeature.RcsImsCapabilities.RcsImsCapabilityFlag} this method will always return + * {@code true}. + * + * @see CarrierConfigManager#KEY_CARRIER_RCS_PROVISIONING_REQUIRED_BOOL + * @return true if the device is provisioned for the capability or does not require + * provisioning, false if the capability does require provisioning and has not been + * provisioned yet. + */ + @WorkerThread + @RequiresPermission(Manifest.permission.READ_PRIVILEGED_PHONE_STATE) + public boolean getRcsProvisioningStatusForCapability( + @RcsFeature.RcsImsCapabilities.RcsImsCapabilityFlag int capability) { + try { + return getITelephony().getRcsProvisioningStatusForCapability(mSubId, capability); + } catch (RemoteException e) { + throw e.rethrowAsRuntimeException(); + } + } + + /** + * Set the provisioning status for the IMS RCS capability using the specified subscription. + * + * Provisioning may or may not be required, depending on the carrier configuration. If + * provisioning is not required for the carrier associated with this subscription or the device + * does not support the capability/technology combination specified, this operation will be a + * no-op. + * + * @see CarrierConfigManager#KEY_CARRIER_RCS_PROVISIONING_REQUIRED_BOOL + * @param isProvisioned true if the device is provisioned for the RCS capability specified, + * false otherwise. + */ + @WorkerThread + @RequiresPermission(Manifest.permission.MODIFY_PHONE_STATE) + public void setRcsProvisioningStatusForCapability( + @RcsFeature.RcsImsCapabilities.RcsImsCapabilityFlag int capability, + boolean isProvisioned) { + try { + getITelephony().setRcsProvisioningStatusForCapability(mSubId, capability, + isProvisioned); + } catch (RemoteException e) { + throw e.rethrowAsRuntimeException(); + } + } + + /** * Notify the framework that an RCS autoconfiguration XML file has been received for * provisioning. + * <p> + * Requires Permission: Manifest.permission.MODIFY_PHONE_STATE or that the calling app has + * carrier privileges (see {@link #hasCarrierPrivileges}). * @param config The XML file to be read. ASCII/UTF8 encoded text if not compressed. * @param isCompressed The XML file is compressed in gzip format and must be decompressed * before being read. - * @hide + * */ @RequiresPermission(Manifest.permission.MODIFY_PHONE_STATE) public void notifyRcsAutoConfigurationReceived(@NonNull byte[] config, boolean isCompressed) { if (config == null) { throw new IllegalArgumentException("Must include a non-null config XML file."); } - // TODO: Connect to ImsConfigImplBase. - throw new UnsupportedOperationException("notifyRcsAutoConfigurationReceived is not" - + "supported"); - } - - private static boolean isImsAvailableOnDevice() { - IPackageManager pm = IPackageManager.Stub.asInterface(ServiceManager.getService("package")); - if (pm == null) { - // For some reason package manger is not available.. This will fail internally anyways, - // so do not throw error and allow. - return true; - } try { - return pm.hasSystemFeature(PackageManager.FEATURE_TELEPHONY_IMS, 0); + getITelephony().notifyRcsAutoConfigurationReceived(mSubId, config, isCompressed); } catch (RemoteException e) { - // For some reason package manger is not available.. This will fail internally anyways, - // so do not throw error and allow. + throw e.rethrowAsRuntimeException(); } - return true; + } private static ITelephony getITelephony() { diff --git a/telephony/java/android/telephony/ims/RcsContactUceCapability.java b/telephony/java/android/telephony/ims/RcsContactUceCapability.java index 492170b1069a..893a311e646b 100644 --- a/telephony/java/android/telephony/ims/RcsContactUceCapability.java +++ b/telephony/java/android/telephony/ims/RcsContactUceCapability.java @@ -19,6 +19,7 @@ package android.telephony.ims; import android.annotation.IntDef; import android.annotation.NonNull; import android.annotation.Nullable; +import android.annotation.SystemApi; import android.net.Uri; import android.os.Parcel; import android.os.Parcelable; @@ -35,6 +36,7 @@ import java.util.Map; * Contains the User Capability Exchange capabilities corresponding to a contact's URI. * @hide */ +@SystemApi public final class RcsContactUceCapability implements Parcelable { /** Supports 1-to-1 chat */ @@ -135,7 +137,7 @@ public final class RcsContactUceCapability implements Parcelable { * @param type The capability to map to a service URI that is different from the contact's * URI. */ - public Builder add(@CapabilityFlag int type, @NonNull Uri serviceUri) { + public @NonNull Builder add(@CapabilityFlag int type, @NonNull Uri serviceUri) { mCapabilities.mCapabilities |= type; // Put each of these capabilities into the map separately. for (int shift = 0; shift < Integer.SIZE; shift++) { @@ -157,7 +159,7 @@ public final class RcsContactUceCapability implements Parcelable { * Add a UCE capability flag that this contact supports. * @param type the capability that the contact supports. */ - public Builder add(@CapabilityFlag int type) { + public @NonNull Builder add(@CapabilityFlag int type) { mCapabilities.mCapabilities |= type; return this; } @@ -167,7 +169,7 @@ public final class RcsContactUceCapability implements Parcelable { * @param extension A string containing a carrier specific service tag that is an extension * of the {@link CapabilityFlag}s that are defined here. */ - public Builder add(@NonNull String extension) { + public @NonNull Builder add(@NonNull String extension) { mCapabilities.mExtensionTags.add(extension); return this; } @@ -175,7 +177,7 @@ public final class RcsContactUceCapability implements Parcelable { /** * @return the constructed instance. */ - public RcsContactUceCapability build() { + public @NonNull RcsContactUceCapability build() { return mCapabilities; } } @@ -205,7 +207,7 @@ public final class RcsContactUceCapability implements Parcelable { } } - public static final Creator<RcsContactUceCapability> CREATOR = + public static final @NonNull Creator<RcsContactUceCapability> CREATOR = new Creator<RcsContactUceCapability>() { @Override public RcsContactUceCapability createFromParcel(Parcel in) { @@ -219,7 +221,7 @@ public final class RcsContactUceCapability implements Parcelable { }; @Override - public void writeToParcel(Parcel out, int flags) { + public void writeToParcel(@NonNull Parcel out, int flags) { out.writeParcelable(mContactUri, 0); out.writeInt(mCapabilities); out.writeStringList(mExtensionTags); diff --git a/telephony/java/android/telephony/ims/aidl/IImsConfig.aidl b/telephony/java/android/telephony/ims/aidl/IImsConfig.aidl index 53e459697958..57206c9f059a 100644 --- a/telephony/java/android/telephony/ims/aidl/IImsConfig.aidl +++ b/telephony/java/android/telephony/ims/aidl/IImsConfig.aidl @@ -40,4 +40,5 @@ interface IImsConfig { // Return result code defined in ImsConfig#OperationStatusConstants int setConfigString(int item, String value); void updateImsCarrierConfigs(in PersistableBundle bundle); + void notifyRcsAutoConfigurationReceived(in byte[] config, boolean isCompressed); } diff --git a/telephony/java/android/telephony/ims/aidl/IImsRcsController.aidl b/telephony/java/android/telephony/ims/aidl/IImsRcsController.aidl index e81bac0f6764..6f6aa44371fa 100644 --- a/telephony/java/android/telephony/ims/aidl/IImsRcsController.aidl +++ b/telephony/java/android/telephony/ims/aidl/IImsRcsController.aidl @@ -19,6 +19,9 @@ package android.telephony.ims.aidl; import android.net.Uri; import android.telephony.ims.aidl.IImsCapabilityCallback; import android.telephony.ims.aidl.IRcsUceControllerCallback; +import android.telephony.ims.aidl.IImsRegistrationCallback; + +import com.android.internal.telephony.IIntegerConsumer; /** * Interface used to interact with the Telephony IMS. @@ -26,6 +29,13 @@ import android.telephony.ims.aidl.IRcsUceControllerCallback; * {@hide} */ interface IImsRcsController { + // IMS RCS registration commands + void registerImsRegistrationCallback(int subId, IImsRegistrationCallback c); + void unregisterImsRegistrationCallback(int subId, IImsRegistrationCallback c); + void getImsRcsRegistrationState(int subId, IIntegerConsumer consumer); + void getImsRcsRegistrationTransportType(int subId, IIntegerConsumer consumer); + + // IMS RCS capability commands void registerRcsAvailabilityCallback(int subId, IImsCapabilityCallback c); void unregisterRcsAvailabilityCallback(int subId, IImsCapabilityCallback c); boolean isCapable(int subId, int capability, int radioTech); diff --git a/telephony/java/android/telephony/ims/aidl/IRcsFeatureListener.aidl b/telephony/java/android/telephony/ims/aidl/IRcsFeatureListener.aidl index 881b4776b25b..70cf651d3924 100644 --- a/telephony/java/android/telephony/ims/aidl/IRcsFeatureListener.aidl +++ b/telephony/java/android/telephony/ims/aidl/IRcsFeatureListener.aidl @@ -32,11 +32,11 @@ interface IRcsFeatureListener { oneway void onNetworkResponse(int code, in String reason, int operationToken); oneway void onCapabilityRequestResponsePresence(in List<RcsContactUceCapability> infos, int operationToken); - oneway void onNotifyUpdateCapabilities(); + oneway void onNotifyUpdateCapabilities(int publishTriggerType); oneway void onUnpublish(); // RcsSipOptionsImplBase specific oneway void onCapabilityRequestResponseOptions(int code, in String reason, in RcsContactUceCapability info, int operationToken); oneway void onRemoteCapabilityRequest(in Uri contactUri, in RcsContactUceCapability remoteInfo, int operationToken); -}
\ No newline at end of file +} diff --git a/telephony/java/android/telephony/ims/compat/ImsService.java b/telephony/java/android/telephony/ims/compat/ImsService.java index 97a8517afea9..eafbb14539f5 100644 --- a/telephony/java/android/telephony/ims/compat/ImsService.java +++ b/telephony/java/android/telephony/ims/compat/ImsService.java @@ -17,8 +17,8 @@ package android.telephony.ims.compat; import android.annotation.Nullable; -import android.annotation.UnsupportedAppUsage; import android.app.Service; +import android.compat.annotation.UnsupportedAppUsage; import android.content.Intent; import android.os.IBinder; import android.os.RemoteException; diff --git a/telephony/java/android/telephony/ims/compat/feature/ImsFeature.java b/telephony/java/android/telephony/ims/compat/feature/ImsFeature.java index de4f17466a47..5a9e8e2dafc4 100644 --- a/telephony/java/android/telephony/ims/compat/feature/ImsFeature.java +++ b/telephony/java/android/telephony/ims/compat/feature/ImsFeature.java @@ -17,7 +17,7 @@ package android.telephony.ims.compat.feature; import android.annotation.IntDef; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; import android.os.IInterface; import android.os.RemoteException; diff --git a/telephony/java/android/telephony/ims/compat/feature/MMTelFeature.java b/telephony/java/android/telephony/ims/compat/feature/MMTelFeature.java index 3fd356a510e6..b52c37106049 100644 --- a/telephony/java/android/telephony/ims/compat/feature/MMTelFeature.java +++ b/telephony/java/android/telephony/ims/compat/feature/MMTelFeature.java @@ -16,8 +16,8 @@ package android.telephony.ims.compat.feature; -import android.annotation.UnsupportedAppUsage; import android.app.PendingIntent; +import android.compat.annotation.UnsupportedAppUsage; import android.os.Message; import android.os.RemoteException; import android.telephony.ims.ImsCallProfile; diff --git a/telephony/java/android/telephony/ims/compat/stub/ImsCallSessionImplBase.java b/telephony/java/android/telephony/ims/compat/stub/ImsCallSessionImplBase.java index d77f78ea9e88..acab738737f4 100644 --- a/telephony/java/android/telephony/ims/compat/stub/ImsCallSessionImplBase.java +++ b/telephony/java/android/telephony/ims/compat/stub/ImsCallSessionImplBase.java @@ -16,7 +16,7 @@ package android.telephony.ims.compat.stub; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.os.Message; import android.os.RemoteException; import android.telephony.CallQuality; diff --git a/telephony/java/android/telephony/ims/compat/stub/ImsConfigImplBase.java b/telephony/java/android/telephony/ims/compat/stub/ImsConfigImplBase.java index e55c3d0823c2..aae6f9214c70 100644 --- a/telephony/java/android/telephony/ims/compat/stub/ImsConfigImplBase.java +++ b/telephony/java/android/telephony/ims/compat/stub/ImsConfigImplBase.java @@ -16,7 +16,7 @@ package android.telephony.ims.compat.stub; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; import android.content.Intent; import android.os.RemoteException; diff --git a/telephony/java/android/telephony/ims/compat/stub/ImsUtListenerImplBase.java b/telephony/java/android/telephony/ims/compat/stub/ImsUtListenerImplBase.java index e2024742c058..ce291d4d14c6 100644 --- a/telephony/java/android/telephony/ims/compat/stub/ImsUtListenerImplBase.java +++ b/telephony/java/android/telephony/ims/compat/stub/ImsUtListenerImplBase.java @@ -16,7 +16,7 @@ package android.telephony.ims.compat.stub; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.os.Bundle; import android.os.RemoteException; import android.telephony.ims.ImsCallForwardInfo; diff --git a/telephony/java/android/telephony/ims/feature/ImsFeature.java b/telephony/java/android/telephony/ims/feature/ImsFeature.java index 72390d070337..f14270f99c83 100644 --- a/telephony/java/android/telephony/ims/feature/ImsFeature.java +++ b/telephony/java/android/telephony/ims/feature/ImsFeature.java @@ -337,11 +337,10 @@ public abstract class ImsFeature { } /** - * @return The current state of the feature, defined as {@link #STATE_UNAVAILABLE}, - * {@link #STATE_INITIALIZING}, or {@link #STATE_READY}. - * @hide + * @return The current state of the ImsFeature, set previously by {@link #setFeatureState(int)} + * or {@link #STATE_UNAVAILABLE} if it has not been updated yet. */ - public int getFeatureState() { + public @ImsState int getFeatureState() { synchronized (mLock) { return mState; } diff --git a/telephony/java/android/telephony/ims/stub/ImsConfigImplBase.java b/telephony/java/android/telephony/ims/stub/ImsConfigImplBase.java index 4c0de7f9c1b7..e0d576db4f14 100644 --- a/telephony/java/android/telephony/ims/stub/ImsConfigImplBase.java +++ b/telephony/java/android/telephony/ims/stub/ImsConfigImplBase.java @@ -17,12 +17,14 @@ package android.telephony.ims.stub; 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.RemoteCallbackList; import android.os.RemoteException; +import android.telephony.ims.ProvisioningManager; import android.telephony.ims.aidl.IImsConfig; import android.telephony.ims.aidl.IImsConfigCallback; import android.util.Log; @@ -199,6 +201,12 @@ public class ImsConfigImplBase { } } + @Override + public void notifyRcsAutoConfigurationReceived(byte[] config, boolean isCompressed) + throws RemoteException { + getImsConfigImpl().notifyRcsAutoConfigurationReceived(config, isCompressed); + } + private void notifyImsConfigChanged(int item, int value) throws RemoteException { getImsConfigImpl().notifyConfigChanged(item, value); } @@ -228,7 +236,8 @@ public class ImsConfigImplBase { * The configuration requested resulted in an unknown result. This may happen if the * IMS configurations are unavailable. */ - public static final int CONFIG_RESULT_UNKNOWN = -1; + public static final int CONFIG_RESULT_UNKNOWN = ProvisioningManager.PROVISIONING_RESULT_UNKNOWN; + /** * Setting the configuration value completed. */ @@ -355,9 +364,9 @@ public class ImsConfigImplBase { * @param config The XML file to be read, if not compressed, it should be in ASCII/UTF8 format. * @param isCompressed The XML file is compressed in gzip format and must be decompressed * before being read. - * @hide + * */ - public void notifyRcsAutoConfigurationReceived(byte[] config, boolean isCompressed) { + public void notifyRcsAutoConfigurationReceived(@NonNull byte[] config, boolean isCompressed) { } /** diff --git a/telephony/java/android/telephony/ims/stub/ImsUtImplBase.java b/telephony/java/android/telephony/ims/stub/ImsUtImplBase.java index feac3c2ebfde..3ec4f3468497 100644 --- a/telephony/java/android/telephony/ims/stub/ImsUtImplBase.java +++ b/telephony/java/android/telephony/ims/stub/ImsUtImplBase.java @@ -16,6 +16,7 @@ package android.telephony.ims.stub; +import android.annotation.IntDef; import android.annotation.SystemApi; import android.annotation.TestApi; import android.os.Bundle; @@ -25,6 +26,9 @@ import android.telephony.ims.ImsUtListener; import com.android.ims.internal.IImsUt; import com.android.ims.internal.IImsUtListener; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; + /** * Base implementation of IMS UT interface, which implements stubs. Override these methods to * implement functionality. @@ -36,6 +40,70 @@ import com.android.ims.internal.IImsUtListener; @SystemApi @TestApi public class ImsUtImplBase { + /** + * Bar all incoming calls. (See 3GPP TS 24.611) + */ + public static final int CALL_BARRING_ALL_INCOMING = 1; + + /** + * Bar all outgoing calls. (See 3GPP TS 24.611) + */ + public static final int CALL_BARRING_ALL_OUTGOING = 2; + + /** + * Bar all outgoing international calls. (See 3GPP TS 24.611) + */ + public static final int CALL_BARRING_OUTGOING_INTL = 3; + + /** + * Bar all outgoing international calls, excluding those to the home PLMN country + * (See 3GPP TS 24.611) + */ + public static final int CALL_BARRING_OUTGOING_INTL_EXCL_HOME = 4; + + /** + * Bar all incoming calls when roaming (See 3GPP TS 24.611) + */ + public static final int CALL_BLOCKING_INCOMING_WHEN_ROAMING = 5; + + /** + * Enable Anonymous Communication Rejection (See 3GPP TS 24.611) + */ + public static final int CALL_BARRING_ANONYMOUS_INCOMING = 6; + + /** + * Bar all incoming and outgoing calls. (See 3GPP TS 24.611) + */ + public static final int CALL_BARRING_ALL = 7; + + /** + * Bar all outgoing service requests, including calls. (See 3GPP TS 24.611) + */ + public static final int CALL_BARRING_OUTGOING_ALL_SERVICES = 8; + + /** + * Bar all incoming service requests, including calls. (See 3GPP TS 24.611) + */ + public static final int CALL_BARRING_INCOMING_ALL_SERVICES = 9; + + /** + * Bar specific incoming calls. (See 3GPP TS 24.611) + */ + public static final int CALL_BARRING_SPECIFIC_INCOMING_CALLS = 10; + + /** @hide */ + @Retention(RetentionPolicy.SOURCE) + @IntDef(prefix = "CALL_BARRING_", value = {CALL_BARRING_ALL_INCOMING, CALL_BARRING_ALL_OUTGOING, + CALL_BARRING_OUTGOING_INTL, CALL_BARRING_OUTGOING_INTL_EXCL_HOME, + CALL_BLOCKING_INCOMING_WHEN_ROAMING, CALL_BARRING_ANONYMOUS_INCOMING, + CALL_BARRING_ALL, CALL_BARRING_OUTGOING_ALL_SERVICES, + CALL_BARRING_INCOMING_ALL_SERVICES, CALL_BARRING_SPECIFIC_INCOMING_CALLS}) + public @interface CallBarringMode {} + + /** + * Constant used to denote an invalid return value. + */ + public static final int INVALID_RESULT = -1; private IImsUt.Stub mServiceImpl = new IImsUt.Stub() { @Override @@ -247,15 +315,15 @@ public class ImsUtImplBase { /** * Updates the configuration of the call barring. */ - public int updateCallBarring(int cbType, int action, String[] barrList) { + public int updateCallBarring(@CallBarringMode int cbType, int action, String[] barrList) { return -1; } /** * Updates the configuration of the call barring for specified service class. */ - public int updateCallBarringForServiceClass(int cbType, int action, String[] barrList, - int serviceClass) { + public int updateCallBarringForServiceClass(@CallBarringMode int cbType, int action, + String[] barrList, int serviceClass) { return -1; } diff --git a/telephony/java/android/telephony/ims/stub/RcsPresenceExchangeImplBase.java b/telephony/java/android/telephony/ims/stub/RcsPresenceExchangeImplBase.java index 055fca57a628..bb034489a296 100644 --- a/telephony/java/android/telephony/ims/stub/RcsPresenceExchangeImplBase.java +++ b/telephony/java/android/telephony/ims/stub/RcsPresenceExchangeImplBase.java @@ -113,6 +113,51 @@ public class RcsPresenceExchangeImplBase extends RcsCapabilityExchange { }) public @interface PresenceResponseCode {} + + /** A capability update has been requested due to the Entity Tag (ETag) expiring. */ + public static final int CAPABILITY_UPDATE_TRIGGER_ETAG_EXPIRED = 0; + /** A capability update has been requested due to moving to LTE with VoPS disabled. */ + public static final int CAPABILITY_UPDATE_TRIGGER_MOVE_TO_LTE_VOPS_DISABLED = 1; + /** A capability update has been requested due to moving to LTE with VoPS enabled. */ + public static final int CAPABILITY_UPDATE_TRIGGER_MOVE_TO_LTE_VOPS_ENABLED = 2; + /** A capability update has been requested due to moving to eHRPD. */ + public static final int CAPABILITY_UPDATE_TRIGGER_MOVE_TO_EHRPD = 3; + /** A capability update has been requested due to moving to HSPA+. */ + public static final int CAPABILITY_UPDATE_TRIGGER_MOVE_TO_HSPAPLUS = 4; + /** A capability update has been requested due to moving to 3G. */ + public static final int CAPABILITY_UPDATE_TRIGGER_MOVE_TO_3G = 5; + /** A capability update has been requested due to moving to 2G. */ + public static final int CAPABILITY_UPDATE_TRIGGER_MOVE_TO_2G = 6; + /** A capability update has been requested due to moving to WLAN */ + public static final int CAPABILITY_UPDATE_TRIGGER_MOVE_TO_WLAN = 7; + /** A capability update has been requested due to moving to IWLAN */ + public static final int CAPABILITY_UPDATE_TRIGGER_MOVE_TO_IWLAN = 8; + /** A capability update has been requested but the reason is unknown. */ + public static final int CAPABILITY_UPDATE_TRIGGER_UNKNOWN = 9; + /** A capability update has been requested due to moving to 5G NR with VoPS disabled. */ + public static final int CAPABILITY_UPDATE_TRIGGER_MOVE_TO_NR5G_VOPS_DISABLED = 10; + /** A capability update has been requested due to moving to 5G NR with VoPS enabled. */ + public static final int CAPABILITY_UPDATE_TRIGGER_MOVE_TO_NR5G_VOPS_ENABLED = 11; + + /** @hide*/ + @IntDef(value = { + CAPABILITY_UPDATE_TRIGGER_ETAG_EXPIRED, + CAPABILITY_UPDATE_TRIGGER_MOVE_TO_LTE_VOPS_DISABLED, + CAPABILITY_UPDATE_TRIGGER_MOVE_TO_LTE_VOPS_ENABLED, + CAPABILITY_UPDATE_TRIGGER_MOVE_TO_EHRPD, + CAPABILITY_UPDATE_TRIGGER_MOVE_TO_HSPAPLUS, + CAPABILITY_UPDATE_TRIGGER_MOVE_TO_3G, + CAPABILITY_UPDATE_TRIGGER_MOVE_TO_2G, + CAPABILITY_UPDATE_TRIGGER_MOVE_TO_WLAN, + CAPABILITY_UPDATE_TRIGGER_MOVE_TO_IWLAN, + CAPABILITY_UPDATE_TRIGGER_UNKNOWN, + CAPABILITY_UPDATE_TRIGGER_MOVE_TO_NR5G_VOPS_DISABLED, + CAPABILITY_UPDATE_TRIGGER_MOVE_TO_NR5G_VOPS_ENABLED + }, prefix = "CAPABILITY_UPDATE_TRIGGER_") + @Retention(RetentionPolicy.SOURCE) + public @interface StackPublishTriggerType { + } + /** * Provide the framework with a subsequent network response update to * {@link #updateCapabilities(RcsContactUceCapability, int)} and @@ -164,15 +209,18 @@ public class RcsPresenceExchangeImplBase extends RcsCapabilityExchange { * This is typically used when trying to generate an initial PUBLISH for a new subscription to * the network. The device will cache all presence publications after boot until this method is * called once. + * @param publishTriggerType {@link StackPublishTriggerType} The reason for the capability + * update request. * @throws ImsException If this {@link RcsPresenceExchangeImplBase} instance is not currently * connected to the framework. This can happen if the {@link RcsFeature} is not * {@link ImsFeature#STATE_READY} and the {@link RcsFeature} has not received the * {@link ImsFeature#onFeatureReady()} callback. This may also happen in rare cases when the * Telephony stack has crashed. */ - public final void onNotifyUpdateCapabilites() throws ImsException { + public final void onNotifyUpdateCapabilites(@StackPublishTriggerType int publishTriggerType) + throws ImsException { try { - getListener().onNotifyUpdateCapabilities(); + getListener().onNotifyUpdateCapabilities(publishTriggerType); } catch (RemoteException e) { throw new ImsException(e.getMessage(), ImsException.CODE_ERROR_SERVICE_UNAVAILABLE); } diff --git a/telephony/java/com/android/ims/ImsConfig.java b/telephony/java/com/android/ims/ImsConfig.java index cfc803ca3639..0d86e2b7c2b1 100644 --- a/telephony/java/com/android/ims/ImsConfig.java +++ b/telephony/java/com/android/ims/ImsConfig.java @@ -19,7 +19,7 @@ package com.android.ims; import android.os.Handler; import android.os.Looper; import android.os.RemoteException; -import android.telephony.Rlog; +import com.android.telephony.Rlog; import android.telephony.ims.ImsReasonInfo; import android.telephony.ims.ProvisioningManager; import android.telephony.ims.aidl.IImsConfig; @@ -178,7 +178,7 @@ public class ImsConfig { * SIP T1 timer value in milliseconds. See RFC 3261 for define. * Value is in Integer format. */ - public static final int SIP_T1_TIMER = 7; + public static final int SIP_T1_TIMER = ProvisioningManager.KEY_T1_TIMER_VALUE_MS; /** * SIP T2 timer value in milliseconds. See RFC 3261 for define. @@ -196,13 +196,15 @@ public class ImsConfig { * VoLTE status for VLT/s status of Enabled (1), or Disabled (0). * Value is in Integer format. */ - public static final int VLT_SETTING_ENABLED = 10; + public static final int VLT_SETTING_ENABLED = + ProvisioningManager.KEY_VOLTE_PROVISIONING_STATUS; /** * VoLTE status for LVC/s status of Enabled (1), or Disabled (0). * Value is in Integer format. */ - public static final int LVC_SETTING_ENABLED = 11; + public static final int LVC_SETTING_ENABLED = + ProvisioningManager.KEY_VT_PROVISIONING_STATUS; /** * Domain Name for the device to populate the request URI for REGISTRATION. * Value is in String format. @@ -222,48 +224,56 @@ public class ImsConfig { * Requested expiration for Published Online availability. * Value is in Integer format. */ - public static final int PUBLISH_TIMER = 15; + public static final int PUBLISH_TIMER = ProvisioningManager.KEY_RCS_PUBLISH_TIMER_SEC; /** * Requested expiration for Published Offline availability. * Value is in Integer format. */ - public static final int PUBLISH_TIMER_EXTENDED = 16; + public static final int PUBLISH_TIMER_EXTENDED = + ProvisioningManager.KEY_RCS_PUBLISH_TIMER_EXTENDED_SEC; /** * * Value is in Integer format. */ - public static final int CAPABILITY_DISCOVERY_ENABLED = 17; + public static final int CAPABILITY_DISCOVERY_ENABLED = + ProvisioningManager.KEY_RCS_CAPABILITY_DISCOVERY_ENABLED; /** * Period of time the capability information of the contact is cached on handset. * Value is in Integer format. */ - public static final int CAPABILITIES_CACHE_EXPIRATION = 18; + public static final int CAPABILITIES_CACHE_EXPIRATION = + ProvisioningManager.KEY_RCS_CAPABILITIES_CACHE_EXPIRATION_SEC; /** * Peiod of time the availability information of a contact is cached on device. * Value is in Integer format. */ - public static final int AVAILABILITY_CACHE_EXPIRATION = 19; + public static final int AVAILABILITY_CACHE_EXPIRATION = + ProvisioningManager.KEY_RCS_AVAILABILITY_CACHE_EXPIRATION_SEC; /** * Interval between successive capabilities polling. * Value is in Integer format. */ - public static final int CAPABILITIES_POLL_INTERVAL = 20; + public static final int CAPABILITIES_POLL_INTERVAL = + ProvisioningManager.KEY_RCS_CAPABILITIES_POLL_INTERVAL_SEC; /** * Minimum time between two published messages from the device. * Value is in Integer format. */ - public static final int SOURCE_THROTTLE_PUBLISH = 21; + public static final int SOURCE_THROTTLE_PUBLISH = + ProvisioningManager.KEY_RCS_PUBLISH_SOURCE_THROTTLE_MS; /** * The Maximum number of MDNs contained in one Request Contained List. * Value is in Integer format. */ - public static final int MAX_NUMENTRIES_IN_RCL = 22; + public static final int MAX_NUMENTRIES_IN_RCL = + ProvisioningManager.KEY_RCS_MAX_NUM_ENTRIES_IN_RCL; /** * Expiration timer for subscription of a Request Contained List, used in capability * polling. * Value is in Integer format. */ - public static final int CAPAB_POLL_LIST_SUB_EXP = 23; + public static final int CAPAB_POLL_LIST_SUB_EXP = + ProvisioningManager.KEY_RCS_CAPABILITY_POLL_LIST_SUB_EXP_SEC; /** * Applies compression to LIST Subscription. * Value is in Integer format. Enable (1), Disable(0). @@ -273,7 +283,8 @@ public class ImsConfig { * VOLTE Status for EAB/s status of Enabled (1), or Disabled (0). * Value is in Integer format. */ - public static final int EAB_SETTING_ENABLED = 25; + public static final int EAB_SETTING_ENABLED = + ProvisioningManager.KEY_EAB_PROVISIONING_STATUS; /** * Wi-Fi calling roaming status. * Value is in Integer format. ON (1), OFF(0). diff --git a/telephony/java/com/android/ims/ImsUtInterface.java b/telephony/java/com/android/ims/ImsUtInterface.java index e80087d8924e..15f837189843 100644 --- a/telephony/java/com/android/ims/ImsUtInterface.java +++ b/telephony/java/com/android/ims/ImsUtInterface.java @@ -16,12 +16,12 @@ package com.android.ims; +import android.compat.annotation.UnsupportedAppUsage; import android.os.Handler; import android.os.Message; import android.telephony.ims.ImsCallForwardInfo; import android.telephony.ims.ImsSsInfo; - -import dalvik.annotation.compat.UnsupportedAppUsage; +import android.telephony.ims.stub.ImsUtImplBase; /** * Provides APIs for the supplementary service settings using IMS (Ut interface). @@ -59,47 +59,48 @@ public interface ImsUtInterface { * CDIV (Communication Diversion, 3GPP TS 24.604) * actions: target, no reply timer */ - public static final int CDIV_CF_UNCONDITIONAL = 0; - public static final int CDIV_CF_BUSY = 1; - public static final int CDIV_CF_NO_REPLY = 2; - public static final int CDIV_CF_NOT_REACHABLE = 3; + public static final int CDIV_CF_UNCONDITIONAL = ImsCallForwardInfo.CDIV_CF_REASON_UNCONDITIONAL; + public static final int CDIV_CF_BUSY = ImsCallForwardInfo.CDIV_CF_REASON_BUSY; + public static final int CDIV_CF_NO_REPLY = ImsCallForwardInfo.CDIV_CF_REASON_NO_REPLY; + public static final int CDIV_CF_NOT_REACHABLE = ImsCallForwardInfo.CDIV_CF_REASON_NOT_REACHABLE; // For CS service code: 002 - public static final int CDIV_CF_ALL = 4; + public static final int CDIV_CF_ALL = ImsCallForwardInfo.CDIV_CF_REASON_ALL; // For CS service code: 004 - public static final int CDIV_CF_ALL_CONDITIONAL = 5; + public static final int CDIV_CF_ALL_CONDITIONAL = + ImsCallForwardInfo.CDIV_CF_REASON_ALL_CONDITIONAL; // It's only supported in the IMS service (CS does not define it). // IR.92 recommends that an UE activates both the CFNRc and the CFNL // (CDIV using condition not-registered) to the same target. - public static final int CDIV_CF_NOT_LOGGED_IN = 6; + public static final int CDIV_CF_NOT_LOGGED_IN = ImsCallForwardInfo.CDIV_CF_REASON_NOT_LOGGED_IN; /** * CB (Communication Barring, 3GPP TS 24.611) */ // Barring of All Incoming Calls - public static final int CB_BAIC = 1; + public static final int CB_BAIC = ImsUtImplBase.CALL_BARRING_ALL_INCOMING; // Barring of All Outgoing Calls - public static final int CB_BAOC = 2; + public static final int CB_BAOC = ImsUtImplBase.CALL_BARRING_ALL_OUTGOING; // Barring of Outgoing International Calls - public static final int CB_BOIC = 3; + public static final int CB_BOIC = ImsUtImplBase.CALL_BARRING_OUTGOING_INTL; // Barring of Outgoing International Calls - excluding Home Country - public static final int CB_BOIC_EXHC = 4; + public static final int CB_BOIC_EXHC = ImsUtImplBase.CALL_BARRING_OUTGOING_INTL_EXCL_HOME; // Barring of Incoming Calls - when roaming - public static final int CB_BIC_WR = 5; + public static final int CB_BIC_WR = ImsUtImplBase.CALL_BLOCKING_INCOMING_WHEN_ROAMING; // Barring of Anonymous Communication Rejection (ACR) - a particular case of ICB service - public static final int CB_BIC_ACR = 6; + public static final int CB_BIC_ACR = ImsUtImplBase.CALL_BARRING_ANONYMOUS_INCOMING; // Barring of All Calls - public static final int CB_BA_ALL = 7; + public static final int CB_BA_ALL = ImsUtImplBase.CALL_BARRING_ALL; // Barring of Outgoing Services (Service Code 333 - 3GPP TS 22.030 Table B-1) - public static final int CB_BA_MO = 8; + public static final int CB_BA_MO = ImsUtImplBase.CALL_BARRING_OUTGOING_ALL_SERVICES; // Barring of Incoming Services (Service Code 353 - 3GPP TS 22.030 Table B-1) - public static final int CB_BA_MT = 9; + public static final int CB_BA_MT = ImsUtImplBase.CALL_BARRING_INCOMING_ALL_SERVICES; // Barring of Specific Incoming calls - public static final int CB_BS_MT = 10; + public static final int CB_BS_MT = ImsUtImplBase.CALL_BARRING_SPECIFIC_INCOMING_CALLS; /** * Invalid result value. */ - public static final int INVALID = (-1); + public static final int INVALID = ImsUtImplBase.INVALID_RESULT; diff --git a/telephony/java/com/android/internal/telephony/DctConstants.java b/telephony/java/com/android/internal/telephony/DctConstants.java index e1113eba006f..1449a62fbf35 100644 --- a/telephony/java/com/android/internal/telephony/DctConstants.java +++ b/telephony/java/com/android/internal/telephony/DctConstants.java @@ -15,9 +15,9 @@ */ package com.android.internal.telephony; -import com.android.internal.util.Protocol; +import android.compat.annotation.UnsupportedAppUsage; -import dalvik.annotation.compat.UnsupportedAppUsage; +import com.android.internal.util.Protocol; /** * @hide @@ -111,6 +111,9 @@ public class DctConstants { public static final int EVENT_DATA_SERVICE_BINDING_CHANGED = BASE + 49; public static final int EVENT_DEVICE_PROVISIONED_CHANGE = BASE + 50; public static final int EVENT_DATA_ENABLED_OVERRIDE_RULES_CHANGED = BASE + 51; + public static final int EVENT_SERVICE_STATE_CHANGED = BASE + 52; + public static final int EVENT_5G_TIMER_HYSTERESIS = BASE + 53; + public static final int EVENT_5G_TIMER_WATCHDOG = BASE + 54; /***** Constants *****/ diff --git a/telephony/java/com/android/internal/telephony/ICarrierConfigLoader.aidl b/telephony/java/com/android/internal/telephony/ICarrierConfigLoader.aidl index 4e79660df479..76ebc0f3ac2f 100644 --- a/telephony/java/com/android/internal/telephony/ICarrierConfigLoader.aidl +++ b/telephony/java/com/android/internal/telephony/ICarrierConfigLoader.aidl @@ -23,9 +23,13 @@ import android.os.PersistableBundle; */ interface ICarrierConfigLoader { + /** @deprecated Use {@link #getConfigForSubIdWithFeature(int, String, String) instead */ @UnsupportedAppUsage PersistableBundle getConfigForSubId(int subId, String callingPackage); + PersistableBundle getConfigForSubIdWithFeature(int subId, String callingPackage, + String callingFeatureId); + void overrideConfig(int subId, in PersistableBundle overrides, boolean persistent); void notifyConfigChangedForSubId(int subId); diff --git a/telephony/java/com/android/internal/telephony/IOns.aidl b/telephony/java/com/android/internal/telephony/IOns.aidl index 2c48b6512421..76b6951f213d 100755 --- a/telephony/java/com/android/internal/telephony/IOns.aidl +++ b/telephony/java/com/android/internal/telephony/IOns.aidl @@ -83,7 +83,7 @@ interface IOns { * subscription id * */ - int getPreferredDataSubscriptionId(String callingPackage); + int getPreferredDataSubscriptionId(String callingPackage, String callingFeatureId); /** * Update availability of a list of networks in the current location. diff --git a/telephony/java/com/android/internal/telephony/IPhoneSubInfo.aidl b/telephony/java/com/android/internal/telephony/IPhoneSubInfo.aidl index 5b509b7260ba..28ef235bf398 100644 --- a/telephony/java/com/android/internal/telephony/IPhoneSubInfo.aidl +++ b/telephony/java/com/android/internal/telephony/IPhoneSubInfo.aidl @@ -24,113 +24,128 @@ import android.telephony.ImsiEncryptionInfo; */ interface IPhoneSubInfo { + /** @deprecated Use {@link #getDeviceIdWithFeature(String, String) instead */ + @UnsupportedAppUsage + String getDeviceId(String callingPackage); + /** * Retrieves the unique device ID, e.g., IMEI for GSM phones. */ - String getDeviceId(String callingPackage); + String getDeviceIdWithFeature(String callingPackage, String callingFeatureId); /** * Retrieves the unique Network Access ID */ - String getNaiForSubscriber(int subId, String callingPackage); + String getNaiForSubscriber(int subId, String callingPackage, String callingFeatureId); /** * Retrieves the unique device ID of a phone for the device, e.g., IMEI * for GSM phones. */ - String getDeviceIdForPhone(int phoneId, String callingPackage); + String getDeviceIdForPhone(int phoneId, String callingPackage, String callingFeatureId); /** * Retrieves the IMEI. */ - String getImeiForSubscriber(int subId, String callingPackage); + String getImeiForSubscriber(int subId, String callingPackage, String callingFeatureId); /** * Retrieves the software version number for the device, e.g., IMEI/SV * for GSM phones. */ - String getDeviceSvn(String callingPackage); + String getDeviceSvn(String callingPackage, String callingFeatureId); /** * Retrieves the software version number of a subId for the device, e.g., IMEI/SV * for GSM phones. */ - String getDeviceSvnUsingSubId(int subId, String callingPackage); + String getDeviceSvnUsingSubId(int subId, String callingPackage, String callingFeatureId); + + /** @deprecated Use {@link #getSubscriberIdWithFeature(String, String) instead */ + @UnsupportedAppUsage + String getSubscriberId(String callingPackage); /** * Retrieves the unique sbuscriber ID, e.g., IMSI for GSM phones. */ - @UnsupportedAppUsage - String getSubscriberId(String callingPackage); + String getSubscriberIdWithFeature(String callingPackage, String callingComponenId); /** * Retrieves the unique subscriber ID of a given subId, e.g., IMSI for GSM phones. */ - String getSubscriberIdForSubscriber(int subId, String callingPackage); + String getSubscriberIdForSubscriber(int subId, String callingPackage, + String callingFeatureId); /** * Retrieves the Group Identifier Level1 for GSM phones of a subId. */ - String getGroupIdLevel1ForSubscriber(int subId, String callingPackage); + String getGroupIdLevel1ForSubscriber(int subId, String callingPackage, + String callingFeatureId); + + /** @deprecared Use {@link getIccSerialNumberWithFeature(String, String)} instead */ + @UnsupportedAppUsage + String getIccSerialNumber(String callingPackage); /** * Retrieves the serial number of the ICC, if applicable. */ - @UnsupportedAppUsage - String getIccSerialNumber(String callingPackage); + String getIccSerialNumberWithFeature(String callingPackage, String callingFeatureId); /** * Retrieves the serial number of a given subId. */ - String getIccSerialNumberForSubscriber(int subId, String callingPackage); + String getIccSerialNumberForSubscriber(int subId, String callingPackage, + String callingFeatureId); /** * Retrieves the phone number string for line 1. */ - String getLine1Number(String callingPackage); + String getLine1Number(String callingPackage, String callingFeatureId); /** * Retrieves the phone number string for line 1 of a subcription. */ - String getLine1NumberForSubscriber(int subId, String callingPackage); + String getLine1NumberForSubscriber(int subId, String callingPackage, String callingFeatureId); /** * Retrieves the alpha identifier for line 1. */ - String getLine1AlphaTag(String callingPackage); + String getLine1AlphaTag(String callingPackage, String callingFeatureId); /** * Retrieves the alpha identifier for line 1 of a subId. */ - String getLine1AlphaTagForSubscriber(int subId, String callingPackage); + String getLine1AlphaTagForSubscriber(int subId, String callingPackage, + String callingFeatureId); /** * Retrieves MSISDN Number. */ - String getMsisdn(String callingPackage); + String getMsisdn(String callingPackage, String callingFeatureId); /** * Retrieves the Msisdn of a subId. */ - String getMsisdnForSubscriber(int subId, String callingPackage); + String getMsisdnForSubscriber(int subId, String callingPackage, String callingFeatureId); /** * Retrieves the voice mail number. */ - String getVoiceMailNumber(String callingPackage); + String getVoiceMailNumber(String callingPackage, String callingFeatureId); /** * Retrieves the voice mail number of a given subId. */ - String getVoiceMailNumberForSubscriber(int subId, String callingPackage); + String getVoiceMailNumberForSubscriber(int subId, String callingPackage, + String callingFeatureId); /** * Retrieves the Carrier information used to encrypt IMSI and IMPI. */ ImsiEncryptionInfo getCarrierInfoForImsiEncryption(int subId, int keyType, - String callingPackage); + String callingPackage); /** * Stores the Carrier information used to encrypt IMSI and IMPI. @@ -148,13 +163,14 @@ interface IPhoneSubInfo { /** * Retrieves the alpha identifier associated with the voice mail number. */ - String getVoiceMailAlphaTag(String callingPackage); + String getVoiceMailAlphaTag(String callingPackage, String callingFeatureId); /** * Retrieves the alpha identifier associated with the voice mail number * of a subId. */ - String getVoiceMailAlphaTagForSubscriber(int subId, String callingPackage); + String getVoiceMailAlphaTagForSubscriber(int subId, String callingPackage, + String callingFeatureId); /** * Returns the IMS private user identity (IMPI) that was loaded from the ISIM. diff --git a/telephony/java/com/android/internal/telephony/ISms.aidl b/telephony/java/com/android/internal/telephony/ISms.aidl index 2dc59e6a7c3f..c07a1711b32e 100644 --- a/telephony/java/com/android/internal/telephony/ISms.aidl +++ b/telephony/java/com/android/internal/telephony/ISms.aidl @@ -580,7 +580,8 @@ interface ISms { * * @param destAddress the destination address to test for possible short code */ - int checkSmsShortCodeDestination(int subId, String callingApk, String destAddress, String countryIso); + int checkSmsShortCodeDestination(int subId, String callingApk, String callingFeatureId, + String destAddress, String countryIso); /** * Gets the SMSC address from (U)SIM. diff --git a/telephony/java/com/android/internal/telephony/ISmsImplBase.java b/telephony/java/com/android/internal/telephony/ISmsImplBase.java index 98095bbc12ac..ddd3457b3b4d 100644 --- a/telephony/java/com/android/internal/telephony/ISmsImplBase.java +++ b/telephony/java/com/android/internal/telephony/ISmsImplBase.java @@ -202,8 +202,8 @@ public class ISmsImplBase extends ISms.Stub { } @Override - public int checkSmsShortCodeDestination( - int subid, String callingApk, String destAddress, String countryIso) { + public int checkSmsShortCodeDestination(int subid, String callingPackage, + String callingFeatureId, String destAddress, String countryIso) { throw new UnsupportedOperationException(); } diff --git a/telephony/java/com/android/internal/telephony/ISub.aidl b/telephony/java/com/android/internal/telephony/ISub.aidl index 92aab4b12330..cc02a409c16d 100755 --- a/telephony/java/com/android/internal/telephony/ISub.aidl +++ b/telephony/java/com/android/internal/telephony/ISub.aidl @@ -23,47 +23,56 @@ import com.android.internal.telephony.ISetOpportunisticDataCallback; interface ISub { /** * @param callingPackage The package maing the call. + * @param callingFeatureId The feature in the package * @return a list of all subscriptions in the database, this includes * all subscriptions that have been seen. */ - List<SubscriptionInfo> getAllSubInfoList(String callingPackage); + List<SubscriptionInfo> getAllSubInfoList(String callingPackage, String callingFeatureId); /** * @param callingPackage The package maing the call. + * @param callingFeatureId The feature in the package * @return the count of all subscriptions in the database, this includes * all subscriptions that have been seen. */ - int getAllSubInfoCount(String callingPackage); + int getAllSubInfoCount(String callingPackage, String callingFeatureId); /** * Get the active SubscriptionInfo with the subId key * @param subId The unique SubscriptionInfo key in database * @param callingPackage The package maing the call. + * @param callingFeatureId The feature in the package * @return SubscriptionInfo, maybe null if its not active */ - SubscriptionInfo getActiveSubscriptionInfo(int subId, String callingPackage); + SubscriptionInfo getActiveSubscriptionInfo(int subId, String callingPackage, + String callingFeatureId); /** * Get the active SubscriptionInfo associated with the iccId * @param iccId the IccId of SIM card * @param callingPackage The package maing the call. + * @param callingFeatureId The feature in the package * @return SubscriptionInfo, maybe null if its not active */ - SubscriptionInfo getActiveSubscriptionInfoForIccId(String iccId, String callingPackage); + SubscriptionInfo getActiveSubscriptionInfoForIccId(String iccId, String callingPackage, + String callingFeatureId); /** * Get the active SubscriptionInfo associated with the slotIndex * @param slotIndex the slot which the subscription is inserted * @param callingPackage The package making the call. + * @param callingFeatureId The feature in the package * @return SubscriptionInfo, null for Remote-SIMs or non-active slotIndex. */ - SubscriptionInfo getActiveSubscriptionInfoForSimSlotIndex(int slotIndex, String callingPackage); + SubscriptionInfo getActiveSubscriptionInfoForSimSlotIndex(int slotIndex, String callingPackage, + String callingFeatureId); /** * Get the SubscriptionInfo(s) of the active subscriptions. The records will be sorted * by {@link SubscriptionInfo#getSimSlotIndex} then by {@link SubscriptionInfo#getSubscriptionId}. * * @param callingPackage The package maing the call. + * @param callingFeatureId The feature in the package * @return Sorted list of the currently {@link SubscriptionInfo} records available on the device. * <ul> * <li> @@ -80,13 +89,15 @@ interface ISub { * </li> * </ul> */ - List<SubscriptionInfo> getActiveSubscriptionInfoList(String callingPackage); + List<SubscriptionInfo> getActiveSubscriptionInfoList(String callingPackage, + String callingFeatureId); /** * @param callingPackage The package making the call. + * @param callingFeatureId The feature in the package. * @return the number of active subscriptions */ - int getActiveSubInfoCount(String callingPackage); + int getActiveSubInfoCount(String callingPackage, String callingFeatureId); /** * @return the maximum number of subscriptions this device will support at any one time. @@ -96,7 +107,8 @@ interface ISub { /** * @see android.telephony.SubscriptionManager#getAvailableSubscriptionInfoList */ - List<SubscriptionInfo> getAvailableSubscriptionInfoList(String callingPackage); + List<SubscriptionInfo> getAvailableSubscriptionInfoList(String callingPackage, + String callingFeatureId); /** * @see android.telephony.SubscriptionManager#getAccessibleSubscriptionInfoList @@ -225,7 +237,8 @@ interface ISub { * Return opportunistic subscriptions that can be visible to the caller. * @return the list of opportunistic subscription info. If none exists, an empty list. */ - List<SubscriptionInfo> getOpportunisticSubscriptions(String callingPackage); + List<SubscriptionInfo> getOpportunisticSubscriptions(String callingPackage, + String callingFeatureId); void removeSubscriptionsFromGroup(in int[] subIdList, in ParcelUuid groupUuid, String callingPackage); @@ -233,7 +246,8 @@ interface ISub { void addSubscriptionsIntoGroup(in int[] subIdList, in ParcelUuid groupUuid, String callingPackage); - List<SubscriptionInfo> getSubscriptionsInGroup(in ParcelUuid groupUuid, String callingPackage); + List<SubscriptionInfo> getSubscriptionsInGroup(in ParcelUuid groupUuid, String callingPackage, + String callingFeatureId); int getSlotIndex(int subId); @@ -265,7 +279,8 @@ interface ISub { int setSubscriptionProperty(int subId, String propKey, String propValue); - String getSubscriptionProperty(int subId, String propKey, String callingPackage); + String getSubscriptionProperty(int subId, String propKey, String callingPackage, + String callingFeatureId); boolean setSubscriptionEnabled(boolean enable, int subId); @@ -278,11 +293,13 @@ interface ISub { */ int getSimStateForSlotIndex(int slotIndex); - boolean isActiveSubId(int subId, String callingPackage); + boolean isActiveSubId(int subId, String callingPackage, String callingFeatureId); boolean setAlwaysAllowMmsData(int subId, boolean alwaysAllow); int getActiveDataSubscriptionId(); boolean canDisablePhysicalSubscription(); + + int setUiccApplicationsEnabled(boolean enabled, int subscriptionId); } diff --git a/telephony/java/com/android/internal/telephony/ITelephony.aidl b/telephony/java/com/android/internal/telephony/ITelephony.aidl index feb1368e7d47..1f84451a35e4 100644 --- a/telephony/java/com/android/internal/telephony/ITelephony.aidl +++ b/telephony/java/com/android/internal/telephony/ITelephony.aidl @@ -30,6 +30,7 @@ import android.service.carrier.CarrierIdentifier; import android.telecom.PhoneAccount; import android.telecom.PhoneAccountHandle; import android.telephony.CarrierRestrictionRules; +import android.telephony.CellIdentity; import android.telephony.CellInfo; import android.telephony.ClientRequestStats; import android.telephony.IccOpenLogicalChannelResponse; @@ -89,29 +90,33 @@ interface ITelephony { @UnsupportedAppUsage void call(String callingPackage, String number); + /** @deprecated Use {@link #isRadioOnWithFeature(String, String) instead */ + @UnsupportedAppUsage + boolean isRadioOn(String callingPackage); + /** * Check to see if the radio is on or not. * @param callingPackage the name of the package making the call. + * @param callingFeatureId The feature in the package. * @return returns true if the radio is on. */ - boolean isRadioOn(String callingPackage); + boolean isRadioOnWithFeature(String callingPackage, String callingFeatureId); /** - * Check to see if the radio is on or not on particular subId. - * @param subId user preferred subId. - * @param callingPackage the name of the package making the call. - * @return returns true if the radio is on. + * @deprecated Use {@link #isRadioOnForSubscriberWithFeature(int, String, String) instead */ @UnsupportedAppUsage boolean isRadioOnForSubscriber(int subId, String callingPackage); /** - * Supply a pin to unlock the SIM. Blocks until a result is determined. - * @param pin The pin to check. - * @return whether the operation was a success. + * Check to see if the radio is on or not on particular subId. + * @param subId user preferred subId. + * @param callingPackage the name of the package making the call. + * @param callingFeatureId The feature in the package. + * @return returns true if the radio is on. */ - @UnsupportedAppUsage - boolean supplyPin(String pin); + boolean isRadioOnForSubscriberWithFeature(int subId, String callingPackage, String callingFeatureId); + /** * Supply a pin to unlock the SIM for particular subId. @@ -127,15 +132,6 @@ interface ITelephony { * Blocks until a result is determined. * @param puk The puk to check. * pin The new pin to be set in SIM - * @return whether the operation was a success. - */ - boolean supplyPuk(String puk, String pin); - - /** - * Supply puk to unlock the SIM and set SIM pin to new pin. - * Blocks until a result is determined. - * @param puk The puk to check. - * pin The new pin to be set in SIM * @param subId user preferred subId. * @return whether the operation was a success. */ @@ -148,15 +144,6 @@ interface ITelephony { * @return retValue[0] = Phone.PIN_RESULT_SUCCESS on success. Otherwise error code * retValue[1] = number of attempts remaining if known otherwise -1 */ - int[] supplyPinReportResult(String pin); - - /** - * Supply a pin to unlock the SIM. Blocks until a result is determined. - * Returns a specific success/error code. - * @param pin The pin to check. - * @return retValue[0] = Phone.PIN_RESULT_SUCCESS on success. Otherwise error code - * retValue[1] = number of attempts remaining if known otherwise -1 - */ int[] supplyPinReportResultForSubscriber(int subId, String pin); /** @@ -168,17 +155,6 @@ interface ITelephony { * @return retValue[0] = Phone.PIN_RESULT_SUCCESS on success. Otherwise error code * retValue[1] = number of attempts remaining if known otherwise -1 */ - int[] supplyPukReportResult(String puk, String pin); - - /** - * Supply puk to unlock the SIM and set SIM pin to new pin. - * Blocks until a result is determined. - * Returns a specific success/error code - * @param puk The puk to check - * pin The pin to check. - * @return retValue[0] = Phone.PIN_RESULT_SUCCESS on success. Otherwise error code - * retValue[1] = number of attempts remaining if known otherwise -1 - */ int[] supplyPukReportResultForSubscriber(int subId, String puk, String pin); /** @@ -294,19 +270,20 @@ interface ITelephony { */ boolean isDataConnectivityPossible(int subId); - Bundle getCellLocation(String callingPkg); + // Uses CellIdentity which is Parcelable here; will convert to CellLocation in client. + CellIdentity getCellLocation(String callingPkg, String callingFeatureId); /** * Returns the ISO country code equivalent of the current registered * operator's MCC (Mobile Country Code). * @see android.telephony.TelephonyManager#getNetworkCountryIso */ - String getNetworkCountryIsoForPhone(int phoneId, String callingPkg); + String getNetworkCountryIsoForPhone(int phoneId, String callingPkg, String callingFeatureId); /** * Returns the neighboring cell information of the device. */ - List<NeighboringCellInfo> getNeighboringCellInfo(String callingPkg); + List<NeighboringCellInfo> getNeighboringCellInfo(String callingPkg, String callingFeatureId); @UnsupportedAppUsage int getCallState(); @@ -370,23 +347,27 @@ interface ITelephony { /** * Returns the CDMA ERI icon index to display * @param callingPackage package making the call. + * @param callingFeatureId The feature in the package. */ - int getCdmaEriIconIndex(String callingPackage); + int getCdmaEriIconIndex(String callingPackage, String callingFeatureId); /** * Returns the CDMA ERI icon index to display on particular subId. * @param subId user preferred subId. * @param callingPackage package making the call. + * @param callingFeatureId The feature in the package. */ - int getCdmaEriIconIndexForSubscriber(int subId, String callingPackage); + int getCdmaEriIconIndexForSubscriber(int subId, String callingPackage, + String callingFeatureId); /** * Returns the CDMA ERI icon mode, * 0 - ON * 1 - FLASHING * @param callingPackage package making the call. + * @param callingFeatureId The feature in the package. */ - int getCdmaEriIconMode(String callingPackage); + int getCdmaEriIconMode(String callingPackage, String callingFeatureId); /** * Returns the CDMA ERI icon mode on particular subId, @@ -394,21 +375,25 @@ interface ITelephony { * 1 - FLASHING * @param subId user preferred subId. * @param callingPackage package making the call. + * @param callingFeatureId The feature in the package. */ - int getCdmaEriIconModeForSubscriber(int subId, String callingPackage); + int getCdmaEriIconModeForSubscriber(int subId, String callingPackage, + String callingFeatureId); /** * Returns the CDMA ERI text, * @param callingPackage package making the call. + * @param callingFeatureId The feature in the package. */ - String getCdmaEriText(String callingPackage); + String getCdmaEriText(String callingPackage, String callingFeatureId); /** * Returns the CDMA ERI text for particular subId, * @param subId user preferred subId. * @param callingPackage package making the call. + * @param callingFeatureId The feature in the package. */ - String getCdmaEriTextForSubscriber(int subId, String callingPackage); + String getCdmaEriTextForSubscriber(int subId, String callingPackage, String callingFeatureId); /** * Returns true if OTA service provisioning needs to run. @@ -451,7 +436,8 @@ interface ITelephony { * @param subId user preferred subId. * Returns the unread count of voicemails */ - int getVoiceMessageCountForSubscriber(int subId, String callingPackage); + int getVoiceMessageCountForSubscriber(int subId, String callingPackage, + String callingFeatureId); /** * Returns true if current state supports both voice and data @@ -461,7 +447,7 @@ interface ITelephony { Bundle getVisualVoicemailSettings(String callingPackage, int subId); - String getVisualVoicemailPackageName(String callingPackage, int subId); + String getVisualVoicemailPackageName(String callingPackage, String callingFeatureId, int subId); // Not oneway, caller needs to make sure the vaule is set before receiving a SMS void enableVisualVoicemailSmsFilter(String callingPackage, int subId, @@ -493,29 +479,35 @@ interface ITelephony { * Returns the network type of a subId. * @param subId user preferred subId. * @param callingPackage package making the call. + * @param callingFeatureId The feature in the package. */ - int getNetworkTypeForSubscriber(int subId, String callingPackage); + int getNetworkTypeForSubscriber(int subId, String callingPackage, String callingFeatureId); /** * Returns the network type for data transmission * @param callingPackage package making the call. + * @param callingFeatureId The feature in the package. */ - int getDataNetworkType(String callingPackage); + int getDataNetworkType(String callingPackage, String callingFeatureId); /** * Returns the data network type of a subId * @param subId user preferred subId. * @param callingPackage package making the call. + * @param callingFeatureId The feature in the package. */ - int getDataNetworkTypeForSubscriber(int subId, String callingPackage); + int getDataNetworkTypeForSubscriber(int subId, String callingPackage, + String callingFeatureId); /** * Returns the voice network type of a subId * @param subId user preferred subId. - * @param callingPackage package making the call. + * @param callingPackage package making the call.getLteOnCdmaMode + * @param callingFeatureId The feature in the package. * Returns the network type */ - int getVoiceNetworkTypeForSubscriber(int subId, String callingPackage); + int getVoiceNetworkTypeForSubscriber(int subId, String callingPackage, + String callingFeatureId); /** * Return true if an ICC card is present @@ -536,10 +528,11 @@ interface ITelephony { * the mode may be unknown. * * @param callingPackage the name of the calling package + * @param callingFeatureId The feature in the package. * @return {@link Phone#LTE_ON_CDMA_UNKNOWN}, {@link Phone#LTE_ON_CDMA_FALSE} * or {@link PHone#LTE_ON_CDMA_TRUE} */ - int getLteOnCdmaMode(String callingPackage); + int getLteOnCdmaMode(String callingPackage, String callingFeatureId); /** * Return if the current radio is LTE on CDMA. This @@ -547,21 +540,23 @@ interface ITelephony { * the mode may be unknown. * * @param callingPackage the name of the calling package + * @param callingFeatureId The feature in the package. * @return {@link Phone#LTE_ON_CDMA_UNKNOWN}, {@link Phone#LTE_ON_CDMA_FALSE} * or {@link PHone#LTE_ON_CDMA_TRUE} */ - int getLteOnCdmaModeForSubscriber(int subId, String callingPackage); + int getLteOnCdmaModeForSubscriber(int subId, String callingPackage, String callingFeatureId); /** * Returns all observed cell information of the device. */ - List<CellInfo> getAllCellInfo(String callingPkg); + List<CellInfo> getAllCellInfo(String callingPkg, String callingFeatureId); /** * Request a cell information update for the specified subscription, * reported via the CellInfoCallback. */ - void requestCellInfoUpdate(int subId, in ICellInfoCallback cb, String callingPkg); + void requestCellInfoUpdate(int subId, in ICellInfoCallback cb, String callingPkg, + String callingFeatureId); /** * Request a cell information update for the specified subscription, @@ -569,8 +564,8 @@ interface ITelephony { * * @param workSource the requestor to whom the power consumption for this should be attributed. */ - void requestCellInfoUpdateWithWorkSource( - int subId, in ICellInfoCallback cb, in String callingPkg, in WorkSource ws); + void requestCellInfoUpdateWithWorkSource(int subId, in ICellInfoCallback cb, + in String callingPkg, String callingFeatureId, in WorkSource ws); /** * Sets minimum time in milli-seconds between onCellInfoChanged @@ -798,10 +793,11 @@ interface ITelephony { * Get the calculated preferred network type. * Used for device configuration by some CDMA operators. * @param callingPackage The package making the call. + * @param callingFeatureId The feature in the package. * * @return the calculated preferred network type, defined in RILConstants.java. */ - int getCalculatedPreferredNetworkType(String callingPackage); + int getCalculatedPreferredNetworkType(String callingPackage, String callingFeatureId); /* * Get the preferred network type. @@ -882,9 +878,12 @@ interface ITelephony { * Perform a radio scan and return the list of avialble networks. * * @param subId the id of the subscription. + * @param callingPackage the calling package + * @param callingFeatureId The feature in the package * @return CellNetworkScanResult containing status of scan and networks. */ - CellNetworkScanResult getCellNetworkScanResults(int subId, String callingPackage); + CellNetworkScanResult getCellNetworkScanResults(int subId, String callingPackage, + String callingFeatureId); /** * Perform a radio network scan and return the id of this scan. @@ -894,10 +893,11 @@ interface ITelephony { * @param messenger Callback messages will be sent using this messenger. * @param binder the binder object instantiated in TelephonyManager. * @param callingPackage the calling package + * @param callingFeatureId The feature in the package * @return An id for this scan. */ int requestNetworkScan(int subId, in NetworkScanRequest request, in Messenger messenger, - in IBinder binder, in String callingPackage); + in IBinder binder, in String callingPackage, String callingFeatureId); /** * Stop an existing radio network scan. @@ -976,8 +976,9 @@ interface ITelephony { * Get P-CSCF address from PCO after data connection is established or modified. * @param apnType the apnType, "ims" for IMS APN, "emergency" for EMERGENCY APN * @param callingPackage The package making the call. + * @param callingFeatureId The feature in the package. */ - String[] getPcscfAddress(String apnType, String callingPackage); + String[] getPcscfAddress(String apnType, String callingPackage, String callingFeatureId); /** * Set IMS registration state @@ -1067,9 +1068,10 @@ interface ITelephony { * * @param subId whose dialing number for line 1 is returned. * @param callingPackage The package making the call. + * @param callingFeatureId The feature in the package. * @return the displayed dialing number if set, or null if not set. */ - String getLine1NumberForDisplay(int subId, String callingPackage); + String getLine1NumberForDisplay(int subId, String callingPackage, String callingFeatureId); /** * Returns the displayed alphatag of the dialing number if it was set @@ -1077,10 +1079,11 @@ interface ITelephony { * * @param subId whose alphatag associated with line 1 is returned. * @param callingPackage The package making the call. + * @param callingFeatureId The feature in the package. * @return the displayed alphatag of the dialing number if set, or null if * not set. */ - String getLine1AlphaTagForDisplay(int subId, String callingPackage); + String getLine1AlphaTagForDisplay(int subId, String callingPackage, String callingFeatureId); /** * Return the set of subscriber IDs that should be considered "merged together" for data usage @@ -1092,7 +1095,7 @@ interface ITelephony { * * @hide */ - String[] getMergedSubscriberIds(int subId, String callingPackage); + String[] getMergedSubscriberIds(int subId, String callingPackage, String callingFeatureId); /** * @hide @@ -1191,26 +1194,29 @@ interface ITelephony { * Whether video calling has been enabled by the user. * * @param callingPackage The package making the call. + * @param callingFeatureId The feature in the package. * @return {@code true} if the user has enabled video calling, {@code false} otherwise. */ - boolean isVideoCallingEnabled(String callingPackage); + boolean isVideoCallingEnabled(String callingPackage, String callingFeatureId); /** * Whether the DTMF tone length can be changed. * * @param subId The subscription to use. * @param callingPackage The package making the call. + * @param callingFeatureId The feature in the package. * @return {@code true} if the DTMF tone length can be changed. */ - boolean canChangeDtmfToneLength(int subId, String callingPackage); + boolean canChangeDtmfToneLength(int subId, String callingPackage, String callingFeatureId); /** * Whether the device is a world phone. * * @param callingPackage The package making the call. + * @param callingFeatureId The feature in the package. * @return {@code true} if the devices is a world phone. */ - boolean isWorldPhone(int subId, String callingPackage); + boolean isWorldPhone(int subId, String callingPackage, String callingFeatureId); /** * Whether the phone supports TTY mode. @@ -1252,25 +1258,31 @@ interface ITelephony { */ int getImsRegTechnologyForMmTel(int subId); + /** @deprecated Use {@link #getDeviceIdWithFeature(String, String) instead */ + @UnsupportedAppUsage + String getDeviceId(String callingPackage); + /** * Returns the unique device ID of phone, for example, the IMEI for * GSM and the MEID for CDMA phones. Return null if device ID is not available. * * @param callingPackage The package making the call. + * @param callingFeatureId The feature in the package * <p>Requires Permission: * {@link android.Manifest.permission#READ_PHONE_STATE READ_PHONE_STATE} */ - String getDeviceId(String callingPackage); + String getDeviceIdWithFeature(String callingPackage, String callingFeatureId); /** * Returns the IMEI for the given slot. * * @param slotIndex - device slot. * @param callingPackage The package making the call. + * @param callingFeatureId The feature in the package * <p>Requires Permission: * {@link android.Manifest.permission#READ_PHONE_STATE READ_PHONE_STATE} */ - String getImeiForSlot(int slotIndex, String callingPackage); + String getImeiForSlot(int slotIndex, String callingPackage, String callingFeatureId); /** * Returns the Type Allocation Code from the IMEI for the given slot. @@ -1284,10 +1296,11 @@ interface ITelephony { * * @param slotIndex - device slot. * @param callingPackage The package making the call. + * @param callingFeatureId The feature in the package * <p>Requires Permission: * {@link android.Manifest.permission#READ_PHONE_STATE READ_PHONE_STATE} */ - String getMeidForSlot(int slotIndex, String callingPackage); + String getMeidForSlot(int slotIndex, String callingPackage, String callingFeatureId); /** * Returns the Manufacturer Code from the MEID for the given slot. @@ -1301,10 +1314,12 @@ interface ITelephony { * * @param slotIndex - device slot. * @param callingPackage The package making the call. + * @param callingFeatureId The feature in the package. * <p>Requires Permission: * {@link android.Manifest.permission#READ_PHONE_STATE READ_PHONE_STATE} */ - String getDeviceSoftwareVersionForSlot(int slotIndex, String callingPackage); + String getDeviceSoftwareVersionForSlot(int slotIndex, String callingPackage, + String callingFeatureId); /** * Returns the subscription ID associated with the specified PhoneAccount. @@ -1315,7 +1330,7 @@ interface ITelephony { * Returns the subscription ID associated with the specified PhoneAccountHandle. */ int getSubIdForPhoneAccountHandle(in PhoneAccountHandle phoneAccountHandle, - String callingPackage); + String callingPackage, String callingFeatureId); /** * Returns the PhoneAccountHandle associated with a subscription ID. @@ -1345,9 +1360,11 @@ interface ITelephony { * Get the service state on specified subscription * @param subId Subscription id * @param callingPackage The package making the call + * @param callingFeatureId The feature in the package * @return Service state on specified subscription. */ - ServiceState getServiceStateForSubscriber(int subId, String callingPackage); + ServiceState getServiceStateForSubscriber(int subId, String callingPackage, + String callingFeatureId); /** * Returns the URI for the per-account voicemail ringtone set in Phone settings. @@ -1597,10 +1614,12 @@ interface ITelephony { * Get Client request stats which will contain statistical information * on each request made by client. * @param callingPackage package making the call. + * @param callingFeatureId The feature in the package. * @param subId Subscription index * @hide */ - List<ClientRequestStats> getClientRequestStats(String callingPackage, int subid); + List<ClientRequestStats> getClientRequestStats(String callingPackage, String callingFeatureId, + int subid); /** * Set SIM card power state. @@ -1619,7 +1638,8 @@ interface ITelephony { * @param subId subscription ID used for authentication * @param appType the icc application type, like {@link #APPTYPE_USIM} */ - String[] getForbiddenPlmns(int subId, int appType, String callingPackage); + String[] getForbiddenPlmns(int subId, int appType, String callingPackage, + String callingFeatureId); /** * Set the forbidden PLMN list from the givven app type (ex APPTYPE_USIM) on a particular @@ -1628,10 +1648,12 @@ interface ITelephony { * @param subId subId the id of the subscription * @param appType appType the uicc app type, must be USIM or SIM. * @param fplmns plmns the Forbiden plmns list that needed to be written to the SIM. - * @param content callingPackage the op Package name. + * @param callingPackage the op Package name. + * @param callingFeatureId the feature in the package. * @return number of fplmns that is successfully written to the SIM */ - int setForbiddenPlmns(int subId, int appType, in List<String> fplmns, String callingPackage); + int setForbiddenPlmns(int subId, int appType, in List<String> fplmns, String callingPackage, + String callingFeatureId); /** * Check if phone is in emergency callback mode @@ -1775,7 +1797,8 @@ interface ITelephony { * How many modems can have simultaneous data connections. * @hide */ - int getNumberOfModemsWithSimultaneousDataConnections(int subId, String callingPackage); + int getNumberOfModemsWithSimultaneousDataConnections(int subId, String callingPackage, + String callingFeatureId); /** * Return the network selection mode on the subscription with id {@code subId}. @@ -1791,7 +1814,7 @@ interface ITelephony { * Return the modem radio power state for slot index. * */ - int getRadioPowerState(int slotIndex, String callingPackage); + int getRadioPowerState(int slotIndex, String callingPackage, String callingFeatureId); // IMS specific AIDL commands, see ImsMmTelManager.java @@ -1921,7 +1944,7 @@ interface ITelephony { /** * Return the emergency number list from all the active subscriptions. */ - Map getEmergencyNumberList(String callingPackage); + Map getEmergencyNumberList(String callingPackage, String callingFeatureId); /** * Identify if the number is emergency number, based on all the active subscriptions. @@ -1954,6 +1977,17 @@ interface ITelephony { */ boolean getImsProvisioningStatusForCapability(int subId, int capability, int tech); + /** + * Get the provisioning status for the IMS Rcs capability specified. + */ + boolean getRcsProvisioningStatusForCapability(int subId, int capability); + + /** + * Set the provisioning status for the IMS Rcs capability using the specified subscription. + */ + void setRcsProvisioningStatusForCapability(int subId, int capability, + boolean isProvisioned); + /** Is the capability and tech flagged as provisioned in the cache */ boolean isMmTelCapabilityProvisionedInCache(int subId, int capability, int tech); @@ -2021,12 +2055,13 @@ interface ITelephony { * Returns if the usage of multiple SIM cards at the same time is supported. * * @param callingPackage The package making the call. + * @param callingFeatureId The feature in the package. * @return {@link #MULTISIM_ALLOWED} if the device supports multiple SIMs. * {@link #MULTISIM_NOT_SUPPORTED_BY_HARDWARE} if the device does not support multiple SIMs. * {@link #MULTISIM_NOT_SUPPORTED_BY_CARRIER} in the device supports multiple SIMs, but the * functionality is restricted by the carrier. */ - int isMultiSimSupported(String callingPackage); + int isMultiSimSupported(String callingPackage, String callingFeatureId); /** * Switch configs to enable multi-sim or switch back to single-sim @@ -2038,7 +2073,8 @@ interface ITelephony { * Get if altering modems configurations will trigger reboot. * @hide */ - boolean doesSwitchMultiSimConfigTriggerReboot(int subId, String callingPackage); + boolean doesSwitchMultiSimConfigTriggerReboot(int subId, String callingPackage, + String callingFeatureId); /** * Get the mapping from logical slots to physical slots. @@ -2057,12 +2093,14 @@ interface ITelephony { */ boolean isApplicationOnUicc(int subId, int appType); - boolean isModemEnabledForSlot(int slotIndex, String callingPackage); + boolean isModemEnabledForSlot(int slotIndex, String callingPackage, String callingFeatureId); boolean isDataEnabledForApn(int apnType, int subId, String callingPackage); boolean isApnMetered(int apnType, int subId); + boolean isMvnoMatched(int subId, int mvnoType, String mvnoMatchData); + /** * Enqueue a pending sms Consumer, which will answer with the user specified selection for an * outgoing SmsManager operation. @@ -2094,4 +2132,9 @@ interface ITelephony { * Command line command to enable or disable handling of CEP data for test purposes. */ oneway void setCepEnabled(boolean isCepEnabled); + + /** + * Notify Rcs auto config received. + */ + void notifyRcsAutoConfigurationReceived(int subId, in byte[] config, boolean isCompressed); } diff --git a/telephony/java/com/android/internal/telephony/IccCardConstants.java b/telephony/java/com/android/internal/telephony/IccCardConstants.java index 25f03c200610..94dfae8a858a 100644 --- a/telephony/java/com/android/internal/telephony/IccCardConstants.java +++ b/telephony/java/com/android/internal/telephony/IccCardConstants.java @@ -15,11 +15,10 @@ */ package com.android.internal.telephony; +import android.compat.annotation.UnsupportedAppUsage; import android.content.Intent; import android.telephony.TelephonyManager; -import dalvik.annotation.compat.UnsupportedAppUsage; - /** * {@hide} */ diff --git a/telephony/java/com/android/internal/telephony/OperatorInfo.java b/telephony/java/com/android/internal/telephony/OperatorInfo.java index 59c39b158387..64d786391021 100644 --- a/telephony/java/com/android/internal/telephony/OperatorInfo.java +++ b/telephony/java/com/android/internal/telephony/OperatorInfo.java @@ -16,7 +16,7 @@ package com.android.internal.telephony; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.os.Build; import android.os.Parcel; import android.os.Parcelable; diff --git a/telephony/java/com/android/internal/telephony/PhoneConstants.java b/telephony/java/com/android/internal/telephony/PhoneConstants.java index 888746a53244..7ec22698edb4 100644 --- a/telephony/java/com/android/internal/telephony/PhoneConstants.java +++ b/telephony/java/com/android/internal/telephony/PhoneConstants.java @@ -15,7 +15,7 @@ */ package com.android.internal.telephony; -import dalvik.annotation.compat.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; /** * @hide diff --git a/telephony/java/com/android/internal/telephony/RILConstants.java b/telephony/java/com/android/internal/telephony/RILConstants.java index 9cbcd7fc6b04..284544b7f6f2 100644 --- a/telephony/java/com/android/internal/telephony/RILConstants.java +++ b/telephony/java/com/android/internal/telephony/RILConstants.java @@ -16,10 +16,9 @@ package com.android.internal.telephony; +import android.compat.annotation.UnsupportedAppUsage; import android.sysprop.TelephonyProperties; -import dalvik.annotation.compat.UnsupportedAppUsage; - import java.util.Optional; /** @@ -555,4 +554,5 @@ public interface RILConstants { int RIL_UNSOL_PHYSICAL_CHANNEL_CONFIG = 1101; int RIL_UNSOL_EMERGENCY_NUMBER_LIST = 1102; int RIL_UNSOL_UICC_APPLICATIONS_ENABLEMENT_CHANGED = 1103; + int RIL_UNSOL_REGISTRATION_FAILED = 1104; } diff --git a/telephony/java/com/android/internal/telephony/Sms7BitEncodingTranslator.java b/telephony/java/com/android/internal/telephony/Sms7BitEncodingTranslator.java index d672642b1158..8e86ff788a08 100644 --- a/telephony/java/com/android/internal/telephony/Sms7BitEncodingTranslator.java +++ b/telephony/java/com/android/internal/telephony/Sms7BitEncodingTranslator.java @@ -16,17 +16,16 @@ package com.android.internal.telephony; +import android.compat.annotation.UnsupportedAppUsage; import android.content.res.Resources; import android.content.res.XmlResourceParser; -import android.telephony.Rlog; +import com.android.telephony.Rlog; import android.util.SparseIntArray; import com.android.internal.telephony.cdma.sms.UserData; import com.android.internal.telephony.util.TelephonyUtils; import com.android.internal.telephony.util.XmlUtils; -import dalvik.annotation.compat.UnsupportedAppUsage; - public class Sms7BitEncodingTranslator { private static final String TAG = "Sms7BitEncodingTranslator"; @UnsupportedAppUsage diff --git a/telephony/java/com/android/internal/telephony/SmsAddress.java b/telephony/java/com/android/internal/telephony/SmsAddress.java index 2a8de8c8502e..f18256aabed4 100644 --- a/telephony/java/com/android/internal/telephony/SmsAddress.java +++ b/telephony/java/com/android/internal/telephony/SmsAddress.java @@ -16,7 +16,7 @@ package com.android.internal.telephony; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; public abstract class SmsAddress { // From TS 23.040 9.1.2.5 and TS 24.008 table 10.5.118 diff --git a/telephony/java/com/android/internal/telephony/SmsHeader.java b/telephony/java/com/android/internal/telephony/SmsHeader.java index dd77b0179487..ab3fdf4ebb41 100644 --- a/telephony/java/com/android/internal/telephony/SmsHeader.java +++ b/telephony/java/com/android/internal/telephony/SmsHeader.java @@ -16,7 +16,7 @@ package com.android.internal.telephony; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import com.android.internal.util.HexDump; diff --git a/telephony/java/com/android/internal/telephony/SmsMessageBase.java b/telephony/java/com/android/internal/telephony/SmsMessageBase.java index e396f0c3dc89..f21f8889fedb 100644 --- a/telephony/java/com/android/internal/telephony/SmsMessageBase.java +++ b/telephony/java/com/android/internal/telephony/SmsMessageBase.java @@ -16,7 +16,7 @@ package com.android.internal.telephony; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.os.Build; import android.telephony.SmsMessage; import android.text.TextUtils; diff --git a/telephony/java/com/android/internal/telephony/SmsRawData.java b/telephony/java/com/android/internal/telephony/SmsRawData.java index 18727f3a14fa..9776c8f51433 100644 --- a/telephony/java/com/android/internal/telephony/SmsRawData.java +++ b/telephony/java/com/android/internal/telephony/SmsRawData.java @@ -17,7 +17,7 @@ package com.android.internal.telephony; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.os.Parcel; import android.os.Parcelable; diff --git a/telephony/java/com/android/internal/telephony/TelephonyIntents.java b/telephony/java/com/android/internal/telephony/TelephonyIntents.java index 48fdca7d2b8e..b4d3ec9fc87d 100644 --- a/telephony/java/com/android/internal/telephony/TelephonyIntents.java +++ b/telephony/java/com/android/internal/telephony/TelephonyIntents.java @@ -18,6 +18,7 @@ package com.android.internal.telephony; import android.content.Intent; import android.telephony.SubscriptionManager; +import android.telephony.ims.ImsManager; /** * The intents that the telephony services broadcast. @@ -223,9 +224,11 @@ public class TelephonyIntents { * <p class="note"> * This is for the OEM applications to understand about possible provisioning issues. * Used in OMA-DM applications. + * @deprecated Use {@link ImsManager#ACTION_FORBIDDEN_NO_SERVICE_AUTHORIZATION} instead. */ - public static final String ACTION_FORBIDDEN_NO_SERVICE_AUTHORIZATION - = "com.android.internal.intent.action.ACTION_FORBIDDEN_NO_SERVICE_AUTHORIZATION"; + @Deprecated + public static final String ACTION_FORBIDDEN_NO_SERVICE_AUTHORIZATION = + ImsManager.ACTION_FORBIDDEN_NO_SERVICE_AUTHORIZATION; /** * Broadcast Action: A "secret code" has been entered in the dialer. Secret codes are diff --git a/telephony/java/com/android/internal/telephony/TelephonyProperties.java b/telephony/java/com/android/internal/telephony/TelephonyProperties.java index 4e42c20d28db..ff70f8ba3936 100644 --- a/telephony/java/com/android/internal/telephony/TelephonyProperties.java +++ b/telephony/java/com/android/internal/telephony/TelephonyProperties.java @@ -16,7 +16,7 @@ package com.android.internal.telephony; -import dalvik.annotation.compat.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; /** * Contains a list of string constants used to get or set telephone properties diff --git a/telephony/java/com/android/internal/telephony/cdma/SmsMessage.java b/telephony/java/com/android/internal/telephony/cdma/SmsMessage.java index 1f7715b59aff..832502cae37d 100644 --- a/telephony/java/com/android/internal/telephony/cdma/SmsMessage.java +++ b/telephony/java/com/android/internal/telephony/cdma/SmsMessage.java @@ -16,10 +16,11 @@ package com.android.internal.telephony.cdma; +import android.compat.annotation.UnsupportedAppUsage; import android.content.res.Resources; import android.sysprop.TelephonyProperties; import android.telephony.PhoneNumberUtils; -import android.telephony.Rlog; +import com.android.telephony.Rlog; import android.telephony.SmsCbLocation; import android.telephony.SmsCbMessage; import android.telephony.cdma.CdmaSmsCbProgramData; @@ -41,8 +42,6 @@ import com.android.internal.telephony.uicc.IccUtils; import com.android.internal.util.BitwiseInputStream; import com.android.internal.util.HexDump; -import dalvik.annotation.compat.UnsupportedAppUsage; - import java.io.BufferedOutputStream; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; diff --git a/telephony/java/com/android/internal/telephony/cdma/UserData.java b/telephony/java/com/android/internal/telephony/cdma/UserData.java index d960f05f3114..d7e296800a62 100644 --- a/telephony/java/com/android/internal/telephony/cdma/UserData.java +++ b/telephony/java/com/android/internal/telephony/cdma/UserData.java @@ -16,13 +16,12 @@ package com.android.internal.telephony.cdma.sms; +import android.compat.annotation.UnsupportedAppUsage; import android.util.SparseIntArray; import com.android.internal.telephony.SmsHeader; import com.android.internal.util.HexDump; -import dalvik.annotation.compat.UnsupportedAppUsage; - public class UserData { @UnsupportedAppUsage diff --git a/telephony/java/com/android/internal/telephony/cdma/sms/BearerData.java b/telephony/java/com/android/internal/telephony/cdma/sms/BearerData.java index e9378e7ba690..ca03333b99aa 100644 --- a/telephony/java/com/android/internal/telephony/cdma/sms/BearerData.java +++ b/telephony/java/com/android/internal/telephony/cdma/sms/BearerData.java @@ -16,8 +16,9 @@ package com.android.internal.telephony.cdma.sms; +import android.compat.annotation.UnsupportedAppUsage; import android.content.res.Resources; -import android.telephony.Rlog; +import com.android.telephony.Rlog; import android.telephony.SmsCbCmasInfo; import android.telephony.cdma.CdmaSmsCbProgramData; import android.telephony.cdma.CdmaSmsCbProgramResults; @@ -31,8 +32,6 @@ import com.android.internal.telephony.uicc.IccUtils; import com.android.internal.util.BitwiseInputStream; import com.android.internal.util.BitwiseOutputStream; -import dalvik.annotation.compat.UnsupportedAppUsage; - import java.time.Instant; import java.time.LocalDateTime; import java.time.ZoneId; diff --git a/telephony/java/com/android/internal/telephony/cdma/sms/CdmaSmsAddress.java b/telephony/java/com/android/internal/telephony/cdma/sms/CdmaSmsAddress.java index b268ee82529b..039b1769b487 100644 --- a/telephony/java/com/android/internal/telephony/cdma/sms/CdmaSmsAddress.java +++ b/telephony/java/com/android/internal/telephony/cdma/sms/CdmaSmsAddress.java @@ -16,14 +16,13 @@ package com.android.internal.telephony.cdma.sms; +import android.compat.annotation.UnsupportedAppUsage; import android.util.SparseBooleanArray; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.telephony.SmsAddress; import com.android.internal.util.HexDump; -import dalvik.annotation.compat.UnsupportedAppUsage; - public class CdmaSmsAddress extends SmsAddress { /** diff --git a/telephony/java/com/android/internal/telephony/cdma/sms/SmsEnvelope.java b/telephony/java/com/android/internal/telephony/cdma/sms/SmsEnvelope.java index be1eab1d4523..964e2fb32689 100644 --- a/telephony/java/com/android/internal/telephony/cdma/sms/SmsEnvelope.java +++ b/telephony/java/com/android/internal/telephony/cdma/sms/SmsEnvelope.java @@ -17,10 +17,9 @@ package com.android.internal.telephony.cdma.sms; +import android.compat.annotation.UnsupportedAppUsage; import android.telephony.cdma.CdmaSmsCbProgramData; -import dalvik.annotation.compat.UnsupportedAppUsage; - public final class SmsEnvelope { /** * Message Types diff --git a/telephony/java/com/android/internal/telephony/gsm/GsmSmsAddress.java b/telephony/java/com/android/internal/telephony/gsm/GsmSmsAddress.java index 19e0b2d1ba35..c2adbc214a79 100644 --- a/telephony/java/com/android/internal/telephony/gsm/GsmSmsAddress.java +++ b/telephony/java/com/android/internal/telephony/gsm/GsmSmsAddress.java @@ -16,13 +16,12 @@ package com.android.internal.telephony.gsm; +import android.compat.annotation.UnsupportedAppUsage; import android.telephony.PhoneNumberUtils; import com.android.internal.telephony.GsmAlphabet; import com.android.internal.telephony.SmsAddress; -import dalvik.annotation.compat.UnsupportedAppUsage; - import java.text.ParseException; public class GsmSmsAddress extends SmsAddress { diff --git a/telephony/java/com/android/internal/telephony/gsm/SmsCbHeader.java b/telephony/java/com/android/internal/telephony/gsm/SmsCbHeader.java index 11bc5de08c66..f29410d9fca3 100644 --- a/telephony/java/com/android/internal/telephony/gsm/SmsCbHeader.java +++ b/telephony/java/com/android/internal/telephony/gsm/SmsCbHeader.java @@ -16,13 +16,12 @@ package com.android.internal.telephony.gsm; +import android.compat.annotation.UnsupportedAppUsage; import android.telephony.SmsCbCmasInfo; import android.telephony.SmsCbEtwsInfo; import com.android.internal.telephony.SmsConstants; -import dalvik.annotation.compat.UnsupportedAppUsage; - import java.util.Arrays; import java.util.Locale; diff --git a/telephony/java/com/android/internal/telephony/gsm/SmsMessage.java b/telephony/java/com/android/internal/telephony/gsm/SmsMessage.java index e7b385c5444b..f54da3bf6c6b 100644 --- a/telephony/java/com/android/internal/telephony/gsm/SmsMessage.java +++ b/telephony/java/com/android/internal/telephony/gsm/SmsMessage.java @@ -25,9 +25,10 @@ import static com.android.internal.telephony.SmsConstants.MAX_USER_DATA_BYTES; import static com.android.internal.telephony.SmsConstants.MAX_USER_DATA_SEPTETS; import static com.android.internal.telephony.SmsConstants.MessageClass; +import android.compat.annotation.UnsupportedAppUsage; import android.content.res.Resources; import android.telephony.PhoneNumberUtils; -import android.telephony.Rlog; +import com.android.telephony.Rlog; import android.text.TextUtils; import com.android.internal.telephony.EncodeException; @@ -38,8 +39,6 @@ import com.android.internal.telephony.SmsHeader; import com.android.internal.telephony.SmsMessageBase; import com.android.internal.telephony.uicc.IccUtils; -import dalvik.annotation.compat.UnsupportedAppUsage; - import java.io.ByteArrayOutputStream; import java.io.UnsupportedEncodingException; import java.text.ParseException; diff --git a/telephony/java/com/android/internal/telephony/uicc/IccUtils.java b/telephony/java/com/android/internal/telephony/uicc/IccUtils.java index f2d46244d60e..0dc740194034 100644 --- a/telephony/java/com/android/internal/telephony/uicc/IccUtils.java +++ b/telephony/java/com/android/internal/telephony/uicc/IccUtils.java @@ -16,17 +16,16 @@ package com.android.internal.telephony.uicc; +import android.compat.annotation.UnsupportedAppUsage; import android.content.res.Resources; import android.content.res.Resources.NotFoundException; import android.graphics.Bitmap; import android.graphics.Color; -import android.telephony.Rlog; +import com.android.telephony.Rlog; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.telephony.GsmAlphabet; -import dalvik.annotation.compat.UnsupportedAppUsage; - import java.io.UnsupportedEncodingException; import java.util.List; diff --git a/telephony/java/com/android/telephony/Rlog.java b/telephony/java/com/android/telephony/Rlog.java new file mode 100644 index 000000000000..9d6c930de8f5 --- /dev/null +++ b/telephony/java/com/android/telephony/Rlog.java @@ -0,0 +1,154 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES 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.telephony; + +import android.text.TextUtils; +import android.util.Base64; +import android.util.Log; + +import com.android.internal.telephony.util.TelephonyUtils; + +import java.security.MessageDigest; +import java.security.NoSuchAlgorithmException; + +/** + * A copy of {@link android.telephony.Rlog} to be used within the telephony mainline module. + * + * @hide + */ +public final class Rlog { + + private static final boolean USER_BUILD = TelephonyUtils.IS_USER; + + private Rlog() { + } + + private static int log(int priority, String tag, String msg) { + return Log.logToRadioBuffer(priority, tag, msg); + } + + public static int v(String tag, String msg) { + return log(Log.VERBOSE, tag, msg); + } + + public static int v(String tag, String msg, Throwable tr) { + return log(Log.VERBOSE, tag, + msg + '\n' + Log.getStackTraceString(tr)); + } + + public static int d(String tag, String msg) { + return log(Log.DEBUG, tag, msg); + } + + public static int d(String tag, String msg, Throwable tr) { + return log(Log.DEBUG, tag, + msg + '\n' + Log.getStackTraceString(tr)); + } + + public static int i(String tag, String msg) { + return log(Log.INFO, tag, msg); + } + + public static int i(String tag, String msg, Throwable tr) { + return log(Log.INFO, tag, + msg + '\n' + Log.getStackTraceString(tr)); + } + + public static int w(String tag, String msg) { + return log(Log.WARN, tag, msg); + } + + public static int w(String tag, String msg, Throwable tr) { + return log(Log.WARN, tag, + msg + '\n' + Log.getStackTraceString(tr)); + } + + public static int w(String tag, Throwable tr) { + return log(Log.WARN, tag, Log.getStackTraceString(tr)); + } + + public static int e(String tag, String msg) { + return log(Log.ERROR, tag, msg); + } + + public static int e(String tag, String msg, Throwable tr) { + return log(Log.ERROR, tag, + msg + '\n' + Log.getStackTraceString(tr)); + } + + public static int println(int priority, String tag, String msg) { + return log(priority, tag, msg); + } + + public static boolean isLoggable(String tag, int level) { + return Log.isLoggable(tag, level); + } + + /** + * Redact personally identifiable information for production users. + * @param tag used to identify the source of a log message + * @param pii the personally identifiable information we want to apply secure hash on. + * @return If tag is loggable in verbose mode or pii is null, return the original input. + * otherwise return a secure Hash of input pii + */ + public static String pii(String tag, Object pii) { + String val = String.valueOf(pii); + if (pii == null || TextUtils.isEmpty(val) || isLoggable(tag, Log.VERBOSE)) { + return val; + } + return "[" + secureHash(val.getBytes()) + "]"; + } + + /** + * Redact personally identifiable information for production users. + * @param enablePiiLogging set when caller explicitly want to enable sensitive logging. + * @param pii the personally identifiable information we want to apply secure hash on. + * @return If enablePiiLogging is set to true or pii is null, return the original input. + * otherwise return a secure Hash of input pii + */ + public static String pii(boolean enablePiiLogging, Object pii) { + String val = String.valueOf(pii); + if (pii == null || TextUtils.isEmpty(val) || enablePiiLogging) { + return val; + } + return "[" + secureHash(val.getBytes()) + "]"; + } + + /** + * Returns a secure hash (using the SHA1 algorithm) of the provided input. + * + * @return "****" if the build type is user, otherwise the hash + * @param input the bytes for which the secure hash should be computed. + */ + private static String secureHash(byte[] input) { + // Refrain from logging user personal information in user build. + if (USER_BUILD) { + return "****"; + } + + MessageDigest messageDigest; + + try { + messageDigest = MessageDigest.getInstance("SHA-1"); + } catch (NoSuchAlgorithmException e) { + return "####"; + } + + byte[] result = messageDigest.digest(input); + return Base64.encodeToString( + result, Base64.URL_SAFE | Base64.NO_PADDING | Base64.NO_WRAP); + } +} diff --git a/test-base/hiddenapi/Android.bp b/test-base/hiddenapi/Android.bp index c4e0fab4a1a8..c202467517aa 100644 --- a/test-base/hiddenapi/Android.bp +++ b/test-base/hiddenapi/Android.bp @@ -25,5 +25,8 @@ java_library { srcs: ["src/**/*.java"], - libs: ["android.test.base"], + libs: [ + "android.test.base", + "unsupportedappusage", + ], } diff --git a/test-base/hiddenapi/src/android/test/AndroidTestCase.java b/test-base/hiddenapi/src/android/test/AndroidTestCase.java index 2b9beb160110..fcb8d432a631 100644 --- a/test-base/hiddenapi/src/android/test/AndroidTestCase.java +++ b/test-base/hiddenapi/src/android/test/AndroidTestCase.java @@ -16,7 +16,7 @@ package android.test; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; import junit.framework.TestCase; diff --git a/test-base/hiddenapi/src/android/test/InstrumentationTestCase.java b/test-base/hiddenapi/src/android/test/InstrumentationTestCase.java index 139cd18a176c..a48a56c612d6 100644 --- a/test-base/hiddenapi/src/android/test/InstrumentationTestCase.java +++ b/test-base/hiddenapi/src/android/test/InstrumentationTestCase.java @@ -16,7 +16,7 @@ package android.test; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import junit.framework.TestCase; diff --git a/test-base/hiddenapi/src/junit/framework/TestCase.java b/test-base/hiddenapi/src/junit/framework/TestCase.java index 5a5486108a7a..59fbe2b94561 100644 --- a/test-base/hiddenapi/src/junit/framework/TestCase.java +++ b/test-base/hiddenapi/src/junit/framework/TestCase.java @@ -16,7 +16,7 @@ package junit.framework; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; /** * Stub only diff --git a/test-base/hiddenapi/src/junit/framework/TestSuite.java b/test-base/hiddenapi/src/junit/framework/TestSuite.java index 368c661dbfa4..32305c9149c0 100644 --- a/test-base/hiddenapi/src/junit/framework/TestSuite.java +++ b/test-base/hiddenapi/src/junit/framework/TestSuite.java @@ -16,7 +16,7 @@ package junit.framework; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import java.lang.reflect.Method; diff --git a/tests/TelephonyCommonTests/Android.bp b/tests/TelephonyCommonTests/Android.bp index 61c3829e68a1..4f7569d4f451 100644 --- a/tests/TelephonyCommonTests/Android.bp +++ b/tests/TelephonyCommonTests/Android.bp @@ -44,5 +44,6 @@ android_test { "android.test.runner", "android.test.mock", "android.test.base", + "unsupportedappusage", ], } diff --git a/tests/libs-permissions/Android.bp b/tests/libs-permissions/Android.bp index 330bfc9022df..66a1f83dc308 100644 --- a/tests/libs-permissions/Android.bp +++ b/tests/libs-permissions/Android.bp @@ -2,6 +2,7 @@ java_library { name: "com.android.test.libs.product", installable: true, product_specific: true, + sdk_version: "current", srcs: ["product/java/**/*.java"], required: ["com.android.test.libs.product.xml"], } diff --git a/tests/net/common/java/android/net/CaptivePortalTest.java b/tests/net/common/java/android/net/CaptivePortalTest.java index eed7159ffddc..ca4ba63142a2 100644 --- a/tests/net/common/java/android/net/CaptivePortalTest.java +++ b/tests/net/common/java/android/net/CaptivePortalTest.java @@ -44,6 +44,11 @@ public class CaptivePortalTest { } @Override + public void appRequest(final int request) throws RemoteException { + mCode = request; + } + + @Override public void logEvent(int eventId, String packageName) throws RemoteException { mCode = eventId; mPackageName = packageName; @@ -80,6 +85,12 @@ public class CaptivePortalTest { } @Test + public void testReevaluateNetwork() { + final MyCaptivePortalImpl result = runCaptivePortalTest(c -> c.reevaluateNetwork()); + assertEquals(result.mCode, CaptivePortal.APP_REQUEST_REEVALUATION_REQUIRED); + } + + @Test public void testLogEvent() { final MyCaptivePortalImpl result = runCaptivePortalTest(c -> c.logEvent( MetricsEvent.ACTION_CAPTIVE_PORTAL_LOGIN_ACTIVITY, diff --git a/tests/net/integration/util/com/android/server/NetworkAgentWrapper.java b/tests/net/integration/util/com/android/server/NetworkAgentWrapper.java index 1e8d83c3c6cd..18474a83b368 100644 --- a/tests/net/integration/util/com/android/server/NetworkAgentWrapper.java +++ b/tests/net/integration/util/com/android/server/NetworkAgentWrapper.java @@ -36,9 +36,9 @@ import android.net.LinkProperties; import android.net.Network; import android.net.NetworkAgent; import android.net.NetworkCapabilities; -import android.net.NetworkFactory; import android.net.NetworkInfo; import android.net.NetworkMisc; +import android.net.NetworkProvider; import android.net.NetworkSpecifier; import android.net.SocketKeepalive; import android.net.UidRange; @@ -114,7 +114,7 @@ public class NetworkAgentWrapper implements TestableNetworkCallback.HasNetwork { public InstrumentedNetworkAgent(NetworkAgentWrapper wrapper, LinkProperties lp) { super(wrapper.mHandlerThread.getLooper(), wrapper.mContext, wrapper.mLogTag, wrapper.mNetworkInfo, wrapper.mNetworkCapabilities, lp, wrapper.mScore, - new NetworkMisc(), NetworkFactory.SerialNumber.NONE); + new NetworkMisc(), NetworkProvider.ID_NONE); mWrapper = wrapper; } diff --git a/tests/net/java/android/net/NetworkStatsTest.java b/tests/net/java/android/net/NetworkStatsTest.java index c16a0f446651..33d77d288e15 100644 --- a/tests/net/java/android/net/NetworkStatsTest.java +++ b/tests/net/java/android/net/NetworkStatsTest.java @@ -64,15 +64,15 @@ public class NetworkStatsTest { @Test public void testFindIndex() throws Exception { final NetworkStats stats = new NetworkStats(TEST_START, 5) - .addValues(TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO, + .addEntry(TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO, DEFAULT_NETWORK_YES, 1024L, 8L, 0L, 0L, 10) - .addValues(TEST_IFACE, 101, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO, + .addEntry(TEST_IFACE, 101, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO, DEFAULT_NETWORK_NO, 0L, 0L, 1024L, 8L, 11) - .addValues(TEST_IFACE, 101, SET_DEFAULT, TAG_NONE, METERED_YES, ROAMING_NO, + .addEntry(TEST_IFACE, 101, SET_DEFAULT, TAG_NONE, METERED_YES, ROAMING_NO, DEFAULT_NETWORK_YES, 0L, 0L, 1024L, 8L, 11) - .addValues(TEST_IFACE, 102, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO, + .addEntry(TEST_IFACE, 102, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO, DEFAULT_NETWORK_NO, 1024L, 8L, 1024L, 8L, 12) - .addValues(TEST_IFACE, 102, SET_DEFAULT, TAG_NONE, METERED_YES, ROAMING_YES, + .addEntry(TEST_IFACE, 102, SET_DEFAULT, TAG_NONE, METERED_YES, ROAMING_YES, DEFAULT_NETWORK_YES, 1024L, 8L, 1024L, 8L, 12); assertEquals(4, stats.findIndex(TEST_IFACE, 102, SET_DEFAULT, TAG_NONE, METERED_YES, @@ -94,21 +94,21 @@ public class NetworkStatsTest { @Test public void testFindIndexHinted() { final NetworkStats stats = new NetworkStats(TEST_START, 3) - .addValues(TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO, + .addEntry(TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO, DEFAULT_NETWORK_YES, 1024L, 8L, 0L, 0L, 10) - .addValues(TEST_IFACE, 101, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO, + .addEntry(TEST_IFACE, 101, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO, DEFAULT_NETWORK_NO, 0L, 0L, 1024L, 8L, 11) - .addValues(TEST_IFACE, 102, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO, + .addEntry(TEST_IFACE, 102, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO, DEFAULT_NETWORK_YES, 1024L, 8L, 1024L, 8L, 12) - .addValues(TEST_IFACE2, 100, SET_FOREGROUND, TAG_NONE, METERED_NO, ROAMING_NO, + .addEntry(TEST_IFACE2, 100, SET_FOREGROUND, TAG_NONE, METERED_NO, ROAMING_NO, DEFAULT_NETWORK_NO, 1024L, 8L, 0L, 0L, 10) - .addValues(TEST_IFACE2, 101, SET_DEFAULT, 0xF00D, METERED_NO, ROAMING_NO, + .addEntry(TEST_IFACE2, 101, SET_DEFAULT, 0xF00D, METERED_NO, ROAMING_NO, DEFAULT_NETWORK_YES, 0L, 0L, 1024L, 8L, 11) - .addValues(TEST_IFACE2, 101, SET_DEFAULT, 0xF00D, METERED_YES, ROAMING_NO, + .addEntry(TEST_IFACE2, 101, SET_DEFAULT, 0xF00D, METERED_YES, ROAMING_NO, DEFAULT_NETWORK_NO, 0L, 0L, 1024L, 8L, 11) - .addValues(TEST_IFACE2, 102, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO, + .addEntry(TEST_IFACE2, 102, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO, DEFAULT_NETWORK_YES, 1024L, 8L, 1024L, 8L, 12) - .addValues(TEST_IFACE2, 102, SET_DEFAULT, TAG_NONE, METERED_YES, ROAMING_YES, + .addEntry(TEST_IFACE2, 102, SET_DEFAULT, TAG_NONE, METERED_YES, ROAMING_YES, DEFAULT_NETWORK_NO, 1024L, 8L, 1024L, 8L, 12); // verify that we correctly find across regardless of hinting @@ -143,27 +143,27 @@ public class NetworkStatsTest { assertEquals(0, stats.size()); assertEquals(4, stats.internalSize()); - stats.addValues(TEST_IFACE, TEST_UID, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO, + stats.addEntry(TEST_IFACE, TEST_UID, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO, DEFAULT_NETWORK_YES, 1L, 1L, 2L, 2L, 3); - stats.addValues(TEST_IFACE, TEST_UID, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO, + stats.addEntry(TEST_IFACE, TEST_UID, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO, DEFAULT_NETWORK_NO, 2L, 2L, 2L, 2L, 4); - stats.addValues(TEST_IFACE, TEST_UID, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_YES, + stats.addEntry(TEST_IFACE, TEST_UID, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_YES, DEFAULT_NETWORK_YES, 3L, 3L, 2L, 2L, 5); - stats.addValues(TEST_IFACE, TEST_UID, SET_DEFAULT, TAG_NONE, METERED_YES, ROAMING_YES, + stats.addEntry(TEST_IFACE, TEST_UID, SET_DEFAULT, TAG_NONE, METERED_YES, ROAMING_YES, DEFAULT_NETWORK_NO, 3L, 3L, 2L, 2L, 5); assertEquals(4, stats.size()); assertEquals(4, stats.internalSize()); - stats.addValues(TEST_IFACE, TEST_UID, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO, + stats.addEntry(TEST_IFACE, TEST_UID, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO, DEFAULT_NETWORK_NO, 4L, 40L, 4L, 40L, 7); - stats.addValues(TEST_IFACE, TEST_UID, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO, + stats.addEntry(TEST_IFACE, TEST_UID, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO, DEFAULT_NETWORK_YES, 5L, 50L, 4L, 40L, 8); - stats.addValues(TEST_IFACE, TEST_UID, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO, + stats.addEntry(TEST_IFACE, TEST_UID, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO, DEFAULT_NETWORK_NO, 6L, 60L, 5L, 50L, 10); - stats.addValues(TEST_IFACE, TEST_UID, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_YES, + stats.addEntry(TEST_IFACE, TEST_UID, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_YES, DEFAULT_NETWORK_YES, 7L, 70L, 5L, 50L, 11); - stats.addValues(TEST_IFACE, TEST_UID, SET_DEFAULT, TAG_NONE, METERED_YES, ROAMING_YES, + stats.addEntry(TEST_IFACE, TEST_UID, SET_DEFAULT, TAG_NONE, METERED_YES, ROAMING_YES, DEFAULT_NETWORK_NO, 7L, 70L, 5L, 50L, 11); assertEquals(9, stats.size()); @@ -193,8 +193,8 @@ public class NetworkStatsTest { public void testCombineExisting() throws Exception { final NetworkStats stats = new NetworkStats(TEST_START, 10); - stats.addValues(TEST_IFACE, 1001, SET_DEFAULT, TAG_NONE, 512L, 4L, 256L, 2L, 10); - stats.addValues(TEST_IFACE, 1001, SET_DEFAULT, 0xff, 128L, 1L, 128L, 1L, 2); + stats.addEntry(TEST_IFACE, 1001, SET_DEFAULT, TAG_NONE, 512L, 4L, 256L, 2L, 10); + stats.addEntry(TEST_IFACE, 1001, SET_DEFAULT, 0xff, 128L, 1L, 128L, 1L, 2); stats.combineValues(TEST_IFACE, 1001, SET_DEFAULT, TAG_NONE, -128L, -1L, -128L, -1L, -1); @@ -215,12 +215,12 @@ public class NetworkStatsTest { @Test public void testSubtractIdenticalData() throws Exception { final NetworkStats before = new NetworkStats(TEST_START, 2) - .addValues(TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, 1024L, 8L, 0L, 0L, 11) - .addValues(TEST_IFACE, 101, SET_DEFAULT, TAG_NONE, 0L, 0L, 1024L, 8L, 12); + .addEntry(TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, 1024L, 8L, 0L, 0L, 11) + .addEntry(TEST_IFACE, 101, SET_DEFAULT, TAG_NONE, 0L, 0L, 1024L, 8L, 12); final NetworkStats after = new NetworkStats(TEST_START, 2) - .addValues(TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, 1024L, 8L, 0L, 0L, 11) - .addValues(TEST_IFACE, 101, SET_DEFAULT, TAG_NONE, 0L, 0L, 1024L, 8L, 12); + .addEntry(TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, 1024L, 8L, 0L, 0L, 11) + .addEntry(TEST_IFACE, 101, SET_DEFAULT, TAG_NONE, 0L, 0L, 1024L, 8L, 12); final NetworkStats result = after.subtract(before); @@ -234,12 +234,12 @@ public class NetworkStatsTest { @Test public void testSubtractIdenticalRows() throws Exception { final NetworkStats before = new NetworkStats(TEST_START, 2) - .addValues(TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, 1024L, 8L, 0L, 0L, 11) - .addValues(TEST_IFACE, 101, SET_DEFAULT, TAG_NONE, 0L, 0L, 1024L, 8L, 12); + .addEntry(TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, 1024L, 8L, 0L, 0L, 11) + .addEntry(TEST_IFACE, 101, SET_DEFAULT, TAG_NONE, 0L, 0L, 1024L, 8L, 12); final NetworkStats after = new NetworkStats(TEST_START, 2) - .addValues(TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, 1025L, 9L, 2L, 1L, 15) - .addValues(TEST_IFACE, 101, SET_DEFAULT, TAG_NONE, 3L, 1L, 1028L, 9L, 20); + .addEntry(TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, 1025L, 9L, 2L, 1L, 15) + .addEntry(TEST_IFACE, 101, SET_DEFAULT, TAG_NONE, 3L, 1L, 1028L, 9L, 20); final NetworkStats result = after.subtract(before); @@ -253,13 +253,13 @@ public class NetworkStatsTest { @Test public void testSubtractNewRows() throws Exception { final NetworkStats before = new NetworkStats(TEST_START, 2) - .addValues(TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, 1024L, 8L, 0L, 0L, 11) - .addValues(TEST_IFACE, 101, SET_DEFAULT, TAG_NONE, 0L, 0L, 1024L, 8L, 12); + .addEntry(TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, 1024L, 8L, 0L, 0L, 11) + .addEntry(TEST_IFACE, 101, SET_DEFAULT, TAG_NONE, 0L, 0L, 1024L, 8L, 12); final NetworkStats after = new NetworkStats(TEST_START, 3) - .addValues(TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, 1024L, 8L, 0L, 0L, 11) - .addValues(TEST_IFACE, 101, SET_DEFAULT, TAG_NONE, 0L, 0L, 1024L, 8L, 12) - .addValues(TEST_IFACE, 102, SET_DEFAULT, TAG_NONE, 1024L, 8L, 1024L, 8L, 20); + .addEntry(TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, 1024L, 8L, 0L, 0L, 11) + .addEntry(TEST_IFACE, 101, SET_DEFAULT, TAG_NONE, 0L, 0L, 1024L, 8L, 12) + .addEntry(TEST_IFACE, 102, SET_DEFAULT, TAG_NONE, 1024L, 8L, 1024L, 8L, 20); final NetworkStats result = after.subtract(before); @@ -275,11 +275,11 @@ public class NetworkStatsTest { @Test public void testSubtractMissingRows() throws Exception { final NetworkStats before = new NetworkStats(TEST_START, 2) - .addValues(TEST_IFACE, UID_ALL, SET_DEFAULT, TAG_NONE, 1024L, 0L, 0L, 0L, 0) - .addValues(TEST_IFACE2, UID_ALL, SET_DEFAULT, TAG_NONE, 2048L, 0L, 0L, 0L, 0); + .addEntry(TEST_IFACE, UID_ALL, SET_DEFAULT, TAG_NONE, 1024L, 0L, 0L, 0L, 0) + .addEntry(TEST_IFACE2, UID_ALL, SET_DEFAULT, TAG_NONE, 2048L, 0L, 0L, 0L, 0); final NetworkStats after = new NetworkStats(TEST_START, 1) - .addValues(TEST_IFACE2, UID_ALL, SET_DEFAULT, TAG_NONE, 2049L, 2L, 3L, 4L, 0); + .addEntry(TEST_IFACE2, UID_ALL, SET_DEFAULT, TAG_NONE, 2049L, 2L, 3L, 4L, 0); final NetworkStats result = after.subtract(before); @@ -293,40 +293,40 @@ public class NetworkStatsTest { @Test public void testTotalBytes() throws Exception { final NetworkStats iface = new NetworkStats(TEST_START, 2) - .addValues(TEST_IFACE, UID_ALL, SET_DEFAULT, TAG_NONE, 128L, 0L, 0L, 0L, 0L) - .addValues(TEST_IFACE2, UID_ALL, SET_DEFAULT, TAG_NONE, 256L, 0L, 0L, 0L, 0L); + .addEntry(TEST_IFACE, UID_ALL, SET_DEFAULT, TAG_NONE, 128L, 0L, 0L, 0L, 0L) + .addEntry(TEST_IFACE2, UID_ALL, SET_DEFAULT, TAG_NONE, 256L, 0L, 0L, 0L, 0L); assertEquals(384L, iface.getTotalBytes()); final NetworkStats uidSet = new NetworkStats(TEST_START, 3) - .addValues(TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, 32L, 0L, 0L, 0L, 0L) - .addValues(TEST_IFACE, 101, SET_DEFAULT, TAG_NONE, 32L, 0L, 0L, 0L, 0L) - .addValues(TEST_IFACE, 101, SET_FOREGROUND, TAG_NONE, 32L, 0L, 0L, 0L, 0L); + .addEntry(TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, 32L, 0L, 0L, 0L, 0L) + .addEntry(TEST_IFACE, 101, SET_DEFAULT, TAG_NONE, 32L, 0L, 0L, 0L, 0L) + .addEntry(TEST_IFACE, 101, SET_FOREGROUND, TAG_NONE, 32L, 0L, 0L, 0L, 0L); assertEquals(96L, uidSet.getTotalBytes()); final NetworkStats uidTag = new NetworkStats(TEST_START, 6) - .addValues(TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, 16L, 0L, 0L, 0L, 0L) - .addValues(TEST_IFACE2, 100, SET_DEFAULT, TAG_NONE, 16L, 0L, 0L, 0L, 0L) - .addValues(TEST_IFACE2, 100, SET_DEFAULT, 0xF00D, 8L, 0L, 0L, 0L, 0L) - .addValues(TEST_IFACE2, 100, SET_FOREGROUND, TAG_NONE, 16L, 0L, 0L, 0L, 0L) - .addValues(TEST_IFACE, 101, SET_DEFAULT, TAG_NONE, 16L, 0L, 0L, 0L, 0L) - .addValues(TEST_IFACE, 101, SET_DEFAULT, 0xF00D, 8L, 0L, 0L, 0L, 0L); + .addEntry(TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, 16L, 0L, 0L, 0L, 0L) + .addEntry(TEST_IFACE2, 100, SET_DEFAULT, TAG_NONE, 16L, 0L, 0L, 0L, 0L) + .addEntry(TEST_IFACE2, 100, SET_DEFAULT, 0xF00D, 8L, 0L, 0L, 0L, 0L) + .addEntry(TEST_IFACE2, 100, SET_FOREGROUND, TAG_NONE, 16L, 0L, 0L, 0L, 0L) + .addEntry(TEST_IFACE, 101, SET_DEFAULT, TAG_NONE, 16L, 0L, 0L, 0L, 0L) + .addEntry(TEST_IFACE, 101, SET_DEFAULT, 0xF00D, 8L, 0L, 0L, 0L, 0L); assertEquals(64L, uidTag.getTotalBytes()); final NetworkStats uidMetered = new NetworkStats(TEST_START, 3) - .addValues(TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO, + .addEntry(TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO, DEFAULT_NETWORK_YES, 32L, 0L, 0L, 0L, 0L) - .addValues(TEST_IFACE, 101, SET_DEFAULT, TAG_NONE, METERED_YES, ROAMING_NO, + .addEntry(TEST_IFACE, 101, SET_DEFAULT, TAG_NONE, METERED_YES, ROAMING_NO, DEFAULT_NETWORK_NO, 32L, 0L, 0L, 0L, 0L) - .addValues(TEST_IFACE, 101, SET_DEFAULT, TAG_NONE, METERED_YES, ROAMING_NO, + .addEntry(TEST_IFACE, 101, SET_DEFAULT, TAG_NONE, METERED_YES, ROAMING_NO, DEFAULT_NETWORK_YES, 32L, 0L, 0L, 0L, 0L); assertEquals(96L, uidMetered.getTotalBytes()); final NetworkStats uidRoaming = new NetworkStats(TEST_START, 3) - .addValues(TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO, + .addEntry(TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO, DEFAULT_NETWORK_YES, 32L, 0L, 0L, 0L, 0L) - .addValues(TEST_IFACE, 101, SET_DEFAULT, TAG_NONE, METERED_YES, ROAMING_NO, + .addEntry(TEST_IFACE, 101, SET_DEFAULT, TAG_NONE, METERED_YES, ROAMING_NO, DEFAULT_NETWORK_NO, 32L, 0L, 0L, 0L, 0L) - .addValues(TEST_IFACE, 101, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_YES, + .addEntry(TEST_IFACE, 101, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_YES, DEFAULT_NETWORK_YES, 32L, 0L, 0L, 0L, 0L); assertEquals(96L, uidRoaming.getTotalBytes()); } @@ -343,11 +343,11 @@ public class NetworkStatsTest { @Test public void testGroupedByIfaceAll() throws Exception { final NetworkStats uidStats = new NetworkStats(TEST_START, 3) - .addValues(IFACE_ALL, 100, SET_ALL, TAG_NONE, METERED_NO, ROAMING_NO, + .addEntry(IFACE_ALL, 100, SET_ALL, TAG_NONE, METERED_NO, ROAMING_NO, DEFAULT_NETWORK_YES, 128L, 8L, 0L, 2L, 20L) - .addValues(IFACE_ALL, 101, SET_FOREGROUND, TAG_NONE, METERED_YES, ROAMING_NO, + .addEntry(IFACE_ALL, 101, SET_FOREGROUND, TAG_NONE, METERED_YES, ROAMING_NO, DEFAULT_NETWORK_NO, 128L, 8L, 0L, 2L, 20L) - .addValues(IFACE_ALL, 101, SET_ALL, TAG_NONE, METERED_NO, ROAMING_YES, + .addEntry(IFACE_ALL, 101, SET_ALL, TAG_NONE, METERED_NO, ROAMING_YES, DEFAULT_NETWORK_YES, 128L, 8L, 0L, 2L, 20L); final NetworkStats grouped = uidStats.groupedByIface(); @@ -361,19 +361,19 @@ public class NetworkStatsTest { @Test public void testGroupedByIface() throws Exception { final NetworkStats uidStats = new NetworkStats(TEST_START, 7) - .addValues(TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO, + .addEntry(TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO, DEFAULT_NETWORK_YES, 128L, 8L, 0L, 2L, 20L) - .addValues(TEST_IFACE2, 100, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO, + .addEntry(TEST_IFACE2, 100, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO, DEFAULT_NETWORK_NO, 512L, 32L, 0L, 0L, 0L) - .addValues(TEST_IFACE2, 100, SET_DEFAULT, 0xF00D, METERED_NO, ROAMING_NO, + .addEntry(TEST_IFACE2, 100, SET_DEFAULT, 0xF00D, METERED_NO, ROAMING_NO, DEFAULT_NETWORK_YES, 64L, 4L, 0L, 0L, 0L) - .addValues(TEST_IFACE2, 100, SET_FOREGROUND, TAG_NONE, METERED_NO, ROAMING_NO, + .addEntry(TEST_IFACE2, 100, SET_FOREGROUND, TAG_NONE, METERED_NO, ROAMING_NO, DEFAULT_NETWORK_NO, 512L, 32L, 0L, 0L, 0L) - .addValues(TEST_IFACE, 101, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO, + .addEntry(TEST_IFACE, 101, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO, DEFAULT_NETWORK_YES, 128L, 8L, 0L, 0L, 0L) - .addValues(TEST_IFACE, 101, SET_DEFAULT, 0xF00D, METERED_YES, ROAMING_NO, + .addEntry(TEST_IFACE, 101, SET_DEFAULT, 0xF00D, METERED_YES, ROAMING_NO, DEFAULT_NETWORK_NO, 128L, 8L, 0L, 0L, 0L) - .addValues(TEST_IFACE, 101, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_YES, + .addEntry(TEST_IFACE, 101, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_YES, DEFAULT_NETWORK_YES, 128L, 8L, 0L, 0L, 0L); final NetworkStats grouped = uidStats.groupedByIface(); @@ -390,19 +390,19 @@ public class NetworkStatsTest { @Test public void testAddAllValues() { final NetworkStats first = new NetworkStats(TEST_START, 5) - .addValues(TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, METERED_YES, ROAMING_NO, + .addEntry(TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, METERED_YES, ROAMING_NO, DEFAULT_NETWORK_YES, 32L, 0L, 0L, 0L, 0L) - .addValues(TEST_IFACE, 100, SET_FOREGROUND, TAG_NONE, METERED_NO, ROAMING_NO, + .addEntry(TEST_IFACE, 100, SET_FOREGROUND, TAG_NONE, METERED_NO, ROAMING_NO, DEFAULT_NETWORK_NO, 32L, 0L, 0L, 0L, 0L) - .addValues(TEST_IFACE, 100, SET_FOREGROUND, TAG_NONE, METERED_YES, ROAMING_YES, + .addEntry(TEST_IFACE, 100, SET_FOREGROUND, TAG_NONE, METERED_YES, ROAMING_YES, DEFAULT_NETWORK_YES, 32L, 0L, 0L, 0L, 0L); final NetworkStats second = new NetworkStats(TEST_START, 2) - .addValues(TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, METERED_YES, ROAMING_NO, + .addEntry(TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, METERED_YES, ROAMING_NO, DEFAULT_NETWORK_YES, 32L, 0L, 0L, 0L, 0L) - .addValues(TEST_IFACE2, UID_ALL, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO, + .addEntry(TEST_IFACE2, UID_ALL, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO, DEFAULT_NETWORK_NO, 32L, 0L, 0L, 0L, 0L) - .addValues(TEST_IFACE, 100, SET_FOREGROUND, TAG_NONE, METERED_YES, ROAMING_YES, + .addEntry(TEST_IFACE, 100, SET_FOREGROUND, TAG_NONE, METERED_YES, ROAMING_YES, DEFAULT_NETWORK_YES, 32L, 0L, 0L, 0L, 0L); first.combineAllValues(second); @@ -421,19 +421,19 @@ public class NetworkStatsTest { @Test public void testGetTotal() { final NetworkStats stats = new NetworkStats(TEST_START, 7) - .addValues(TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO, + .addEntry(TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO, DEFAULT_NETWORK_YES, 128L, 8L, 0L, 2L, 20L) - .addValues(TEST_IFACE2, 100, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO, + .addEntry(TEST_IFACE2, 100, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO, DEFAULT_NETWORK_NO, 512L, 32L, 0L, 0L, 0L) - .addValues(TEST_IFACE2, 100, SET_DEFAULT, 0xF00D, METERED_NO, ROAMING_NO, + .addEntry(TEST_IFACE2, 100, SET_DEFAULT, 0xF00D, METERED_NO, ROAMING_NO, DEFAULT_NETWORK_YES, 64L, 4L, 0L, 0L, 0L) - .addValues(TEST_IFACE2, 100, SET_FOREGROUND, TAG_NONE, METERED_NO, ROAMING_NO, + .addEntry(TEST_IFACE2, 100, SET_FOREGROUND, TAG_NONE, METERED_NO, ROAMING_NO, DEFAULT_NETWORK_NO, 512L,32L, 0L, 0L, 0L) - .addValues(TEST_IFACE, 101, SET_DEFAULT, TAG_NONE, METERED_YES, ROAMING_NO, + .addEntry(TEST_IFACE, 101, SET_DEFAULT, TAG_NONE, METERED_YES, ROAMING_NO, DEFAULT_NETWORK_YES, 128L, 8L, 0L, 0L, 0L) - .addValues(TEST_IFACE, 101, SET_DEFAULT, 0xF00D, METERED_NO, ROAMING_NO, + .addEntry(TEST_IFACE, 101, SET_DEFAULT, 0xF00D, METERED_NO, ROAMING_NO, DEFAULT_NETWORK_NO, 128L, 8L, 0L, 0L, 0L) - .addValues(TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_YES, + .addEntry(TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_YES, DEFAULT_NETWORK_NO, 128L, 8L, 0L, 0L, 0L); assertValues(stats.getTotal(null), 1408L, 88L, 0L, 2L, 20L); @@ -459,7 +459,7 @@ public class NetworkStatsTest { assertEquals(0, after.size()); // Test 1 item stats. - before.addValues(TEST_IFACE, 99, SET_DEFAULT, TAG_NONE, 1L, 128L, 0L, 2L, 20L); + before.addEntry(TEST_IFACE, 99, SET_DEFAULT, TAG_NONE, 1L, 128L, 0L, 2L, 20L); after = before.clone(); after.removeUids(new int[0]); assertEquals(1, after.size()); @@ -469,12 +469,12 @@ public class NetworkStatsTest { assertEquals(0, after.size()); // Append remaining test items. - before.addValues(TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, 2L, 64L, 0L, 2L, 20L) - .addValues(TEST_IFACE2, 100, SET_DEFAULT, TAG_NONE, 4L, 32L, 0L, 0L, 0L) - .addValues(TEST_IFACE2, 100, SET_DEFAULT, 0xF00D, 8L, 16L, 0L, 0L, 0L) - .addValues(TEST_IFACE2, 100, SET_FOREGROUND, TAG_NONE, 16L, 8L, 0L, 0L, 0L) - .addValues(TEST_IFACE, 101, SET_DEFAULT, TAG_NONE, 32L, 4L, 0L, 0L, 0L) - .addValues(TEST_IFACE, 101, SET_DEFAULT, 0xF00D, 64L, 2L, 0L, 0L, 0L); + before.addEntry(TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, 2L, 64L, 0L, 2L, 20L) + .addEntry(TEST_IFACE2, 100, SET_DEFAULT, TAG_NONE, 4L, 32L, 0L, 0L, 0L) + .addEntry(TEST_IFACE2, 100, SET_DEFAULT, 0xF00D, 8L, 16L, 0L, 0L, 0L) + .addEntry(TEST_IFACE2, 100, SET_FOREGROUND, TAG_NONE, 16L, 8L, 0L, 0L, 0L) + .addEntry(TEST_IFACE, 101, SET_DEFAULT, TAG_NONE, 32L, 4L, 0L, 0L, 0L) + .addEntry(TEST_IFACE, 101, SET_DEFAULT, 0xF00D, 64L, 2L, 0L, 0L, 0L); assertEquals(7, before.size()); // Test remove with empty uid list. @@ -505,12 +505,12 @@ public class NetworkStatsTest { @Test public void testClone() throws Exception { final NetworkStats original = new NetworkStats(TEST_START, 5) - .addValues(TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, 128L, 8L, 0L, 2L, 20L) - .addValues(TEST_IFACE2, 100, SET_DEFAULT, TAG_NONE, 512L, 32L, 0L, 0L, 0L); + .addEntry(TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, 128L, 8L, 0L, 2L, 20L) + .addEntry(TEST_IFACE2, 100, SET_DEFAULT, TAG_NONE, 512L, 32L, 0L, 0L, 0L); // make clone and mutate original final NetworkStats clone = original.clone(); - original.addValues(TEST_IFACE, 101, SET_DEFAULT, TAG_NONE, 128L, 8L, 0L, 0L, 0L); + original.addEntry(TEST_IFACE, 101, SET_DEFAULT, TAG_NONE, 128L, 8L, 0L, 0L, 0L); assertEquals(3, original.size()); assertEquals(2, clone.size()); @@ -523,8 +523,8 @@ public class NetworkStatsTest { public void testAddWhenEmpty() throws Exception { final NetworkStats red = new NetworkStats(TEST_START, -1); final NetworkStats blue = new NetworkStats(TEST_START, 5) - .addValues(TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, 128L, 8L, 0L, 2L, 20L) - .addValues(TEST_IFACE2, 100, SET_DEFAULT, TAG_NONE, 512L, 32L, 0L, 0L, 0L); + .addEntry(TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, 128L, 8L, 0L, 2L, 20L) + .addEntry(TEST_IFACE2, 100, SET_DEFAULT, TAG_NONE, 512L, 32L, 0L, 0L, 0L); // We're mostly checking that we don't crash red.combineAllValues(blue); @@ -537,39 +537,39 @@ public class NetworkStatsTest { final String underlyingIface = "wlan0"; final int testTag1 = 8888; NetworkStats delta = new NetworkStats(TEST_START, 17) - .addValues(tunIface, 10100, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO, - DEFAULT_NETWORK_NO, 39605L, 46L, 12259L, 55L, 0L) - .addValues(tunIface, 10100, SET_FOREGROUND, TAG_NONE, METERED_NO, ROAMING_NO, - DEFAULT_NETWORK_NO, 0L, 0L, 0L, 0L, 0L) - .addValues(tunIface, 10120, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO, - DEFAULT_NETWORK_NO, 72667L, 197L, 43909L, 241L, 0L) - .addValues(tunIface, 10120, SET_FOREGROUND, TAG_NONE, METERED_NO, ROAMING_NO, - DEFAULT_NETWORK_NO, 9297L, 17L, 4128L, 21L, 0L) - // VPN package also uses some traffic through unprotected network. - .addValues(tunIface, tunUid, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO, - DEFAULT_NETWORK_NO, 4983L, 10L, 1801L, 12L, 0L) - .addValues(tunIface, tunUid, SET_FOREGROUND, TAG_NONE, METERED_NO, ROAMING_NO, - DEFAULT_NETWORK_NO, 0L, 0L, 0L, 0L, 0L) - // Tag entries - .addValues(tunIface, 10120, SET_DEFAULT, testTag1, METERED_NO, ROAMING_NO, - DEFAULT_NETWORK_NO, 21691L, 41L, 13820L, 51L, 0L) - .addValues(tunIface, 10120, SET_FOREGROUND, testTag1, METERED_NO, ROAMING_NO, - DEFAULT_NETWORK_NO, 1281L, 2L, 665L, 2L, 0L) - // Irrelevant entries - .addValues(TEST_IFACE, 10100, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO, - DEFAULT_NETWORK_NO, 1685L, 5L, 2070L, 6L, 0L) - // Underlying Iface entries - .addValues(underlyingIface, 10100, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO, - DEFAULT_NETWORK_NO, 5178L, 8L, 2139L, 11L, 0L) - .addValues(underlyingIface, 10100, SET_FOREGROUND, TAG_NONE, METERED_NO, ROAMING_NO, - DEFAULT_NETWORK_NO, 0L, 0L, 0L, 0L, 0L) - .addValues(underlyingIface, tunUid, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO, - DEFAULT_NETWORK_NO, 149873L, 287L, 59217L /* smaller than sum(tun0) */, - 299L /* smaller than sum(tun0) */, 0L) - .addValues(underlyingIface, tunUid, SET_FOREGROUND, TAG_NONE, METERED_NO, ROAMING_NO, - DEFAULT_NETWORK_NO, 0L, 0L, 0L, 0L, 0L); - - delta.migrateTun(tunUid, tunIface, new String[] {underlyingIface}); + .addEntry(tunIface, 10100, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO, + DEFAULT_NETWORK_NO, 39605L, 46L, 12259L, 55L, 0L) + .addEntry(tunIface, 10100, SET_FOREGROUND, TAG_NONE, METERED_NO, ROAMING_NO, + DEFAULT_NETWORK_NO, 0L, 0L, 0L, 0L, 0L) + .addEntry(tunIface, 10120, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO, + DEFAULT_NETWORK_NO, 72667L, 197L, 43909L, 241L, 0L) + .addEntry(tunIface, 10120, SET_FOREGROUND, TAG_NONE, METERED_NO, ROAMING_NO, + DEFAULT_NETWORK_NO, 9297L, 17L, 4128L, 21L, 0L) + // VPN package also uses some traffic through unprotected network. + .addEntry(tunIface, tunUid, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO, + DEFAULT_NETWORK_NO, 4983L, 10L, 1801L, 12L, 0L) + .addEntry(tunIface, tunUid, SET_FOREGROUND, TAG_NONE, METERED_NO, ROAMING_NO, + DEFAULT_NETWORK_NO, 0L, 0L, 0L, 0L, 0L) + // Tag entries + .addEntry(tunIface, 10120, SET_DEFAULT, testTag1, METERED_NO, ROAMING_NO, + DEFAULT_NETWORK_NO, 21691L, 41L, 13820L, 51L, 0L) + .addEntry(tunIface, 10120, SET_FOREGROUND, testTag1, METERED_NO, ROAMING_NO, + DEFAULT_NETWORK_NO, 1281L, 2L, 665L, 2L, 0L) + // Irrelevant entries + .addEntry(TEST_IFACE, 10100, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO, + DEFAULT_NETWORK_NO, 1685L, 5L, 2070L, 6L, 0L) + // Underlying Iface entries + .addEntry(underlyingIface, 10100, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO, + DEFAULT_NETWORK_NO, 5178L, 8L, 2139L, 11L, 0L) + .addEntry(underlyingIface, 10100, SET_FOREGROUND, TAG_NONE, METERED_NO, ROAMING_NO, + DEFAULT_NETWORK_NO, 0L, 0L, 0L, 0L, 0L) + .addEntry(underlyingIface, tunUid, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO, + DEFAULT_NETWORK_NO, 149873L, 287L, 59217L /* smaller than sum(tun0) */, + 299L /* smaller than sum(tun0) */, 0L) + .addEntry(underlyingIface, tunUid, SET_FOREGROUND, TAG_NONE, METERED_NO, ROAMING_NO, + DEFAULT_NETWORK_NO, 0L, 0L, 0L, 0L, 0L); + + delta.migrateTun(tunUid, tunIface, new String[]{underlyingIface}); assertEquals(20, delta.size()); // tunIface and TEST_IFACE entries are not changed. @@ -634,21 +634,21 @@ public class NetworkStatsTest { final String tunIface = "tun0"; final String underlyingIface = "wlan0"; NetworkStats delta = new NetworkStats(TEST_START, 9) - // 2 different apps sent/receive data via tun0. - .addValues(tunIface, 10100, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO, - DEFAULT_NETWORK_NO, 50000L, 25L, 100000L, 50L, 0L) - .addValues(tunIface, 20100, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO, - DEFAULT_NETWORK_NO, 500L, 2L, 200L, 5L, 0L) - // VPN package resends data through the tunnel (with exaggerated overhead) - .addValues(tunIface, tunUid, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO, - DEFAULT_NETWORK_NO, 240000, 100L, 120000L, 60L, 0L) - // 1 app already has some traffic on the underlying interface, the other doesn't yet - .addValues(underlyingIface, 10100, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO, - DEFAULT_NETWORK_NO, 1000L, 10L, 2000L, 20L, 0L) - // Traffic through the underlying interface via the vpn app. - // This test should redistribute this data correctly. - .addValues(underlyingIface, tunUid, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO, - DEFAULT_NETWORK_NO, 75500L, 37L, 130000L, 70L, 0L); + // 2 different apps sent/receive data via tun0. + .addEntry(tunIface, 10100, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO, + DEFAULT_NETWORK_NO, 50000L, 25L, 100000L, 50L, 0L) + .addEntry(tunIface, 20100, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO, + DEFAULT_NETWORK_NO, 500L, 2L, 200L, 5L, 0L) + // VPN package resends data through the tunnel (with exaggerated overhead) + .addEntry(tunIface, tunUid, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO, + DEFAULT_NETWORK_NO, 240000, 100L, 120000L, 60L, 0L) + // 1 app already has some traffic on the underlying interface, the other doesn't yet + .addEntry(underlyingIface, 10100, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO, + DEFAULT_NETWORK_NO, 1000L, 10L, 2000L, 20L, 0L) + // Traffic through the underlying interface via the vpn app. + // This test should redistribute this data correctly. + .addEntry(underlyingIface, tunUid, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO, + DEFAULT_NETWORK_NO, 75500L, 37L, 130000L, 70L, 0L); delta.migrateTun(tunUid, tunIface, new String[]{underlyingIface}); assertEquals(9, delta.size()); @@ -697,9 +697,9 @@ public class NetworkStatsTest { DEFAULT_NETWORK_NO, 50000L, 25L, 100000L, 50L, 0L); NetworkStats stats = new NetworkStats(TEST_START, 3) - .addValues(entry1) - .addValues(entry2) - .addValues(entry3); + .addEntry(entry1) + .addEntry(entry2) + .addEntry(entry3); stats.filter(UID_ALL, INTERFACES_ALL, TAG_ALL); assertEquals(3, stats.size()); @@ -724,9 +724,9 @@ public class NetworkStatsTest { DEFAULT_NETWORK_NO, 50000L, 25L, 100000L, 50L, 0L); NetworkStats stats = new NetworkStats(TEST_START, 3) - .addValues(entry1) - .addValues(entry2) - .addValues(entry3); + .addEntry(entry1) + .addEntry(entry2) + .addEntry(entry3); stats.filter(testUid, INTERFACES_ALL, TAG_ALL); assertEquals(2, stats.size()); @@ -755,10 +755,10 @@ public class NetworkStatsTest { DEFAULT_NETWORK_NO, 50000L, 25L, 100000L, 50L, 0L); NetworkStats stats = new NetworkStats(TEST_START, 4) - .addValues(entry1) - .addValues(entry2) - .addValues(entry3) - .addValues(entry4); + .addEntry(entry1) + .addEntry(entry2) + .addEntry(entry3) + .addEntry(entry4); stats.filter(UID_ALL, new String[] { testIf1, testIf2 }, TAG_ALL); assertEquals(3, stats.size()); @@ -778,8 +778,8 @@ public class NetworkStatsTest { DEFAULT_NETWORK_NO, 50000L, 25L, 100000L, 50L, 0L); NetworkStats stats = new NetworkStats(TEST_START, 3) - .addValues(entry1) - .addValues(entry2); + .addEntry(entry1) + .addEntry(entry2); stats.filter(UID_ALL, new String[] { }, TAG_ALL); assertEquals(0, stats.size()); @@ -802,9 +802,9 @@ public class NetworkStatsTest { DEFAULT_NETWORK_NO, 50000L, 25L, 100000L, 50L, 0L); NetworkStats stats = new NetworkStats(TEST_START, 3) - .addValues(entry1) - .addValues(entry2) - .addValues(entry3); + .addEntry(entry1) + .addEntry(entry2) + .addEntry(entry3); stats.filter(UID_ALL, INTERFACES_ALL, testTag); assertEquals(2, stats.size()); @@ -831,10 +831,10 @@ public class NetworkStatsTest { DEFAULT_NETWORK_NO, 50000L, 25L, 100000L, 50L, 0L); NetworkStats stats = new NetworkStats(TEST_START, 4) - .addValues(entry1) - .addValues(entry2) - .addValues(entry3) - .addValues(entry4); + .addEntry(entry1) + .addEntry(entry2) + .addEntry(entry3) + .addEntry(entry4); stats.filterDebugEntries(); @@ -891,14 +891,14 @@ public class NetworkStatsTest { 0 /* operations */); final NetworkStats statsXt = new NetworkStats(TEST_START, 3) - .addValues(appEntry) - .addValues(xtRootUidEntry) - .addValues(otherEntry); + .addEntry(appEntry) + .addEntry(xtRootUidEntry) + .addEntry(otherEntry); final NetworkStats statsEbpf = new NetworkStats(TEST_START, 3) - .addValues(appEntry) - .addValues(ebpfRootUidEntry) - .addValues(otherEntry); + .addEntry(appEntry) + .addEntry(ebpfRootUidEntry) + .addEntry(otherEntry); statsXt.apply464xlatAdjustments(stackedIface, false); statsEbpf.apply464xlatAdjustments(stackedIface, true); @@ -945,8 +945,8 @@ public class NetworkStatsTest { 0 /* operations */); NetworkStats stats = new NetworkStats(TEST_START, 2) - .addValues(firstEntry) - .addValues(secondEntry); + .addEntry(firstEntry) + .addEntry(secondEntry); // Empty map: no adjustment stats.apply464xlatAdjustments(new ArrayMap<>(), false); diff --git a/tests/net/java/android/net/TcpKeepalivePacketDataTest.java b/tests/net/java/android/net/TcpKeepalivePacketDataTest.java index 5cb0d7e7a1a9..e632aafde70e 100644 --- a/tests/net/java/android/net/TcpKeepalivePacketDataTest.java +++ b/tests/net/java/android/net/TcpKeepalivePacketDataTest.java @@ -22,8 +22,6 @@ import static org.junit.Assert.assertArrayEquals; import static org.junit.Assert.assertEquals; import static org.junit.Assert.fail; -import android.net.SocketKeepalive.InvalidPacketException; - import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; diff --git a/tests/net/java/android/net/TelephonyNetworkSpecifierTest.java b/tests/net/java/android/net/TelephonyNetworkSpecifierTest.java new file mode 100644 index 000000000000..47afed441ace --- /dev/null +++ b/tests/net/java/android/net/TelephonyNetworkSpecifierTest.java @@ -0,0 +1,82 @@ +/* + * 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; + +import static com.android.testutils.ParcelUtilsKt.assertParcelSane; + +import static org.junit.Assert.assertEquals; + +import android.telephony.SubscriptionManager; + +import androidx.test.filters.SmallTest; + +import org.junit.Test; + +/** + * Unit test for {@link android.net.TelephonyNetworkSpecifier}. + */ +@SmallTest +public class TelephonyNetworkSpecifierTest { + private static final int TEST_SUBID = 5; + + /** + * Validate that IllegalArgumentException will be thrown if build TelephonyNetworkSpecifier + * without calling {@link TelephonyNetworkSpecifier.Builder#setSubscriptionId(int)}. + */ + @Test + public void testBuilderBuildWithDefault() { + try { + new TelephonyNetworkSpecifier.Builder().build(); + } catch (IllegalArgumentException iae) { + // expected, test pass + } + } + + /** + * Validate that no exception will be thrown even if pass invalid subscription id to + * {@link TelephonyNetworkSpecifier.Builder#setSubscriptionId(int)}. + */ + @Test + public void testBuilderBuildWithInvalidSubId() { + TelephonyNetworkSpecifier specifier = new TelephonyNetworkSpecifier.Builder() + .setSubscriptionId(SubscriptionManager.INVALID_SUBSCRIPTION_ID) + .build(); + assertEquals(specifier.getSubscriptionId(), SubscriptionManager.INVALID_SUBSCRIPTION_ID); + } + + /** + * Validate the correctness of TelephonyNetworkSpecifier when provide valid subId. + */ + @Test + public void testBuilderBuildWithValidSubId() { + final TelephonyNetworkSpecifier specifier = new TelephonyNetworkSpecifier.Builder() + .setSubscriptionId(TEST_SUBID) + .build(); + assertEquals(TEST_SUBID, specifier.getSubscriptionId()); + } + + /** + * Validate that parcel marshalling/unmarshalling works. + */ + @Test + public void testParcel() { + TelephonyNetworkSpecifier specifier = new TelephonyNetworkSpecifier.Builder() + .setSubscriptionId(TEST_SUBID) + .build(); + assertParcelSane(specifier, 1 /* fieldCount */); + } +} diff --git a/tests/net/java/com/android/server/connectivity/LingerMonitorTest.java b/tests/net/java/com/android/server/connectivity/LingerMonitorTest.java index 535298f9b09a..82cb1932d2c1 100644 --- a/tests/net/java/com/android/server/connectivity/LingerMonitorTest.java +++ b/tests/net/java/com/android/server/connectivity/LingerMonitorTest.java @@ -36,9 +36,9 @@ import android.net.IDnsResolver; import android.net.INetd; import android.net.Network; import android.net.NetworkCapabilities; -import android.net.NetworkFactory; import android.net.NetworkInfo; import android.net.NetworkMisc; +import android.net.NetworkProvider; import android.net.NetworkScore; import android.os.INetworkManagementService; import android.text.format.DateUtils; @@ -359,7 +359,7 @@ public class LingerMonitorTest { ns.putIntExtension(NetworkScore.LEGACY_SCORE, 50); NetworkAgentInfo nai = new NetworkAgentInfo(null, null, new Network(netId), info, null, caps, ns, mCtx, null, mMisc, mConnService, mNetd, mDnsResolver, mNMS, - NetworkFactory.SerialNumber.NONE); + NetworkProvider.ID_NONE); nai.everValidated = true; return nai; } diff --git a/tests/net/java/com/android/server/connectivity/MultipathPolicyTrackerTest.java b/tests/net/java/com/android/server/connectivity/MultipathPolicyTrackerTest.java index b783467cfaf2..de1028cd2303 100644 --- a/tests/net/java/com/android/server/connectivity/MultipathPolicyTrackerTest.java +++ b/tests/net/java/com/android/server/connectivity/MultipathPolicyTrackerTest.java @@ -51,6 +51,7 @@ import android.net.NetworkPolicy; import android.net.NetworkPolicyManager; import android.net.NetworkTemplate; import android.net.StringNetworkSpecifier; +import android.net.TelephonyNetworkSpecifier; import android.os.Handler; import android.provider.Settings; import android.telephony.TelephonyManager; @@ -229,7 +230,7 @@ public class MultipathPolicyTrackerTest { verify(mCM).registerNetworkCallback(any(), networkCallback.capture(), any()); // Simulate callback after capability changes - final NetworkCapabilities capabilities = new NetworkCapabilities() + NetworkCapabilities capabilities = new NetworkCapabilities() .addCapability(NET_CAPABILITY_INTERNET) .addTransportType(TRANSPORT_CELLULAR) .setNetworkSpecifier(new StringNetworkSpecifier("234")); @@ -239,6 +240,19 @@ public class MultipathPolicyTrackerTest { networkCallback.getValue().onCapabilitiesChanged( TEST_NETWORK, capabilities); + + // make sure it also works with the new introduced TelephonyNetworkSpecifier + capabilities = new NetworkCapabilities() + .addCapability(NET_CAPABILITY_INTERNET) + .addTransportType(TRANSPORT_CELLULAR) + .setNetworkSpecifier(new TelephonyNetworkSpecifier.Builder() + .setSubscriptionId(234).build()); + if (!roaming) { + capabilities.addCapability(NET_CAPABILITY_NOT_ROAMING); + } + networkCallback.getValue().onCapabilitiesChanged( + TEST_NETWORK, + capabilities); } @Test diff --git a/tests/net/java/com/android/server/net/NetworkStatsObserversTest.java b/tests/net/java/com/android/server/net/NetworkStatsObserversTest.java index c0f9dc14869f..f0e5774a5dea 100644 --- a/tests/net/java/com/android/server/net/NetworkStatsObserversTest.java +++ b/tests/net/java/com/android/server/net/NetworkStatsObserversTest.java @@ -326,14 +326,14 @@ public class NetworkStatsObserversTest { // Baseline NetworkStats xtSnapshot = null; NetworkStats uidSnapshot = new NetworkStats(TEST_START, 2 /* initialSize */) - .addValues(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO, + .addEntry(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO, DEFAULT_NETWORK_YES, BASE_BYTES, 2L, BASE_BYTES, 2L, 0L); mStatsObservers.updateStats( xtSnapshot, uidSnapshot, mActiveIfaces, mActiveUidIfaces, TEST_START); // Delta uidSnapshot = new NetworkStats(TEST_START + 2 * MINUTE_IN_MILLIS, 2 /* initialSize */) - .addValues(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO, + .addEntry(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO, DEFAULT_NETWORK_NO, BASE_BYTES + THRESHOLD_BYTES, 2L, BASE_BYTES + THRESHOLD_BYTES, 2L, 0L); mStatsObservers.updateStats( @@ -359,14 +359,14 @@ public class NetworkStatsObserversTest { // Baseline NetworkStats xtSnapshot = null; NetworkStats uidSnapshot = new NetworkStats(TEST_START, 2 /* initialSize */) - .addValues(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO, + .addEntry(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO, DEFAULT_NETWORK_NO, BASE_BYTES, 2L, BASE_BYTES, 2L, 0L); mStatsObservers.updateStats( xtSnapshot, uidSnapshot, mActiveIfaces, mActiveUidIfaces, TEST_START); // Delta uidSnapshot = new NetworkStats(TEST_START + 2 * MINUTE_IN_MILLIS, 2 /* initialSize */) - .addValues(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO, + .addEntry(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO, DEFAULT_NETWORK_NO, BASE_BYTES + THRESHOLD_BYTES, 2L, BASE_BYTES + THRESHOLD_BYTES, 2L, 0L); mStatsObservers.updateStats( @@ -391,14 +391,14 @@ public class NetworkStatsObserversTest { // Baseline NetworkStats xtSnapshot = null; NetworkStats uidSnapshot = new NetworkStats(TEST_START, 2 /* initialSize */) - .addValues(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO, + .addEntry(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO, DEFAULT_NETWORK_YES, BASE_BYTES, 2L, BASE_BYTES, 2L, 0L); mStatsObservers.updateStats( xtSnapshot, uidSnapshot, mActiveIfaces, mActiveUidIfaces, TEST_START); // Delta uidSnapshot = new NetworkStats(TEST_START + 2 * MINUTE_IN_MILLIS, 2 /* initialSize */) - .addValues(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO, + .addEntry(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO, DEFAULT_NETWORK_YES, BASE_BYTES + THRESHOLD_BYTES, 2L, BASE_BYTES + THRESHOLD_BYTES, 2L, 0L); mStatsObservers.updateStats( @@ -424,14 +424,14 @@ public class NetworkStatsObserversTest { // Baseline NetworkStats xtSnapshot = null; NetworkStats uidSnapshot = new NetworkStats(TEST_START, 2 /* initialSize */) - .addValues(TEST_IFACE, UID_ANOTHER_USER, SET_DEFAULT, TAG_NONE, METERED_NO, + .addEntry(TEST_IFACE, UID_ANOTHER_USER, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO, DEFAULT_NETWORK_YES, BASE_BYTES, 2L, BASE_BYTES, 2L, 0L); mStatsObservers.updateStats( xtSnapshot, uidSnapshot, mActiveIfaces, mActiveUidIfaces, TEST_START); // Delta uidSnapshot = new NetworkStats(TEST_START + 2 * MINUTE_IN_MILLIS, 2 /* initialSize */) - .addValues(TEST_IFACE, UID_ANOTHER_USER, SET_DEFAULT, TAG_NONE, METERED_NO, + .addEntry(TEST_IFACE, UID_ANOTHER_USER, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO, DEFAULT_NETWORK_NO, BASE_BYTES + THRESHOLD_BYTES, 2L, BASE_BYTES + THRESHOLD_BYTES, 2L, 0L); mStatsObservers.updateStats( diff --git a/tests/net/java/com/android/server/net/NetworkStatsServiceTest.java b/tests/net/java/com/android/server/net/NetworkStatsServiceTest.java index 4d42a612030d..a9e0b9abba9c 100644 --- a/tests/net/java/com/android/server/net/NetworkStatsServiceTest.java +++ b/tests/net/java/com/android/server/net/NetworkStatsServiceTest.java @@ -80,6 +80,7 @@ import android.net.NetworkState; import android.net.NetworkStats; import android.net.NetworkStatsHistory; import android.net.NetworkTemplate; +import android.net.netstats.provider.INetworkStatsProviderCallback; import android.os.ConditionVariable; import android.os.Handler; import android.os.HandlerThread; @@ -102,6 +103,7 @@ import com.android.internal.util.test.BroadcastInterceptingContext; import com.android.server.net.NetworkStatsService.NetworkStatsSettings; import com.android.server.net.NetworkStatsService.NetworkStatsSettings.Config; import com.android.testutils.HandlerUtilsKt; +import com.android.testutils.TestableNetworkStatsProvider; import libcore.io.IoUtils; @@ -298,11 +300,11 @@ public class NetworkStatsServiceTest extends NetworkStatsBaseTest { expectNetworkStatsSummary(new NetworkStats(getElapsedRealtime(), 1) .addIfaceValues(TEST_IFACE, 1024L, 8L, 2048L, 16L)); expectNetworkStatsUidDetail(new NetworkStats(getElapsedRealtime(), 2) - .addValues(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, 512L, 4L, 256L, 2L, 0L) - .addValues(TEST_IFACE, UID_RED, SET_DEFAULT, 0xFAAD, 256L, 2L, 128L, 1L, 0L) - .addValues(TEST_IFACE, UID_RED, SET_FOREGROUND, TAG_NONE, 512L, 4L, 256L, 2L, 0L) - .addValues(TEST_IFACE, UID_RED, SET_FOREGROUND, 0xFAAD, 256L, 2L, 128L, 1L, 0L) - .addValues(TEST_IFACE, UID_BLUE, SET_DEFAULT, TAG_NONE, 128L, 1L, 128L, 1L, 0L)); + .addEntry(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, 512L, 4L, 256L, 2L, 0L) + .addEntry(TEST_IFACE, UID_RED, SET_DEFAULT, 0xFAAD, 256L, 2L, 128L, 1L, 0L) + .addEntry(TEST_IFACE, UID_RED, SET_FOREGROUND, TAG_NONE, 512L, 4L, 256L, 2L, 0L) + .addEntry(TEST_IFACE, UID_RED, SET_FOREGROUND, 0xFAAD, 256L, 2L, 128L, 1L, 0L) + .addEntry(TEST_IFACE, UID_BLUE, SET_DEFAULT, TAG_NONE, 128L, 1L, 128L, 1L, 0L)); mService.setUidForeground(UID_RED, false); mService.incrementOperationCount(UID_RED, 0xFAAD, 4); mService.setUidForeground(UID_RED, true); @@ -407,9 +409,9 @@ public class NetworkStatsServiceTest extends NetworkStatsBaseTest { expectNetworkStatsSummary(new NetworkStats(getElapsedRealtime(), 1) .addIfaceValues(TEST_IFACE, 2048L, 16L, 512L, 4L)); expectNetworkStatsUidDetail(new NetworkStats(getElapsedRealtime(), 3) - .addValues(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, 1536L, 12L, 512L, 4L, 0L) - .addValues(TEST_IFACE, UID_RED, SET_DEFAULT, 0xF00D, 512L, 4L, 512L, 4L, 0L) - .addValues(TEST_IFACE, UID_BLUE, SET_DEFAULT, TAG_NONE, 512L, 4L, 0L, 0L, 0L)); + .addEntry(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, 1536L, 12L, 512L, 4L, 0L) + .addEntry(TEST_IFACE, UID_RED, SET_DEFAULT, 0xF00D, 512L, 4L, 512L, 4L, 0L) + .addEntry(TEST_IFACE, UID_BLUE, SET_DEFAULT, TAG_NONE, 512L, 4L, 0L, 0L, 0L)); mService.incrementOperationCount(UID_RED, 0xF00D, 10); forcePollAndWaitForIdle(); @@ -429,9 +431,9 @@ public class NetworkStatsServiceTest extends NetworkStatsBaseTest { expectNetworkStatsSummary(new NetworkStats(getElapsedRealtime(), 1) .addIfaceValues(TEST_IFACE, 2048L, 16L, 512L, 4L)); expectNetworkStatsUidDetail(new NetworkStats(getElapsedRealtime(), 3) - .addValues(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, 1536L, 12L, 512L, 4L, 0L) - .addValues(TEST_IFACE, UID_RED, SET_DEFAULT, 0xF00D, 512L, 4L, 512L, 4L, 0L) - .addValues(TEST_IFACE, UID_BLUE, SET_DEFAULT, TAG_NONE, 512L, 4L, 0L, 0L, 0L)); + .addEntry(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, 1536L, 12L, 512L, 4L, 0L) + .addEntry(TEST_IFACE, UID_RED, SET_DEFAULT, 0xF00D, 512L, 4L, 512L, 4L, 0L) + .addEntry(TEST_IFACE, UID_BLUE, SET_DEFAULT, TAG_NONE, 512L, 4L, 0L, 0L, 0L)); mService.forceUpdateIfaces(NETWORKS_MOBILE, states, getActiveIface(states), new VpnInfo[0]); forcePollAndWaitForIdle(); @@ -443,10 +445,10 @@ public class NetworkStatsServiceTest extends NetworkStatsBaseTest { expectNetworkStatsSummary(new NetworkStats(getElapsedRealtime(), 1) .addIfaceValues(TEST_IFACE, 2176L, 17L, 1536L, 12L)); expectNetworkStatsUidDetail(new NetworkStats(getElapsedRealtime(), 1) - .addValues(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, 1536L, 12L, 512L, 4L, 0L) - .addValues(TEST_IFACE, UID_RED, SET_DEFAULT, 0xF00D, 512L, 4L, 512L, 4L, 0L) - .addValues(TEST_IFACE, UID_BLUE, SET_DEFAULT, TAG_NONE, 640L, 5L, 1024L, 8L, 0L) - .addValues(TEST_IFACE, UID_BLUE, SET_DEFAULT, 0xFAAD, 128L, 1L, 1024L, 8L, 0L)); + .addEntry(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, 1536L, 12L, 512L, 4L, 0L) + .addEntry(TEST_IFACE, UID_RED, SET_DEFAULT, 0xF00D, 512L, 4L, 512L, 4L, 0L) + .addEntry(TEST_IFACE, UID_BLUE, SET_DEFAULT, TAG_NONE, 640L, 5L, 1024L, 8L, 0L) + .addEntry(TEST_IFACE, UID_BLUE, SET_DEFAULT, 0xFAAD, 128L, 1L, 1024L, 8L, 0L)); mService.incrementOperationCount(UID_BLUE, 0xFAAD, 10); forcePollAndWaitForIdle(); @@ -480,10 +482,10 @@ public class NetworkStatsServiceTest extends NetworkStatsBaseTest { expectNetworkStatsSummary(new NetworkStats(getElapsedRealtime(), 1) .addIfaceValues(TEST_IFACE, 4128L, 258L, 544L, 34L)); expectNetworkStatsUidDetail(new NetworkStats(getElapsedRealtime(), 1) - .addValues(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, 16L, 1L, 16L, 1L, 0L) - .addValues(TEST_IFACE, UID_RED, SET_DEFAULT, 0xFAAD, 16L, 1L, 16L, 1L, 0L) - .addValues(TEST_IFACE, UID_BLUE, SET_DEFAULT, TAG_NONE, 4096L, 258L, 512L, 32L, 0L) - .addValues(TEST_IFACE, UID_GREEN, SET_DEFAULT, TAG_NONE, 16L, 1L, 16L, 1L, 0L)); + .addEntry(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, 16L, 1L, 16L, 1L, 0L) + .addEntry(TEST_IFACE, UID_RED, SET_DEFAULT, 0xFAAD, 16L, 1L, 16L, 1L, 0L) + .addEntry(TEST_IFACE, UID_BLUE, SET_DEFAULT, TAG_NONE, 4096L, 258L, 512L, 32L, 0L) + .addEntry(TEST_IFACE, UID_GREEN, SET_DEFAULT, TAG_NONE, 16L, 1L, 16L, 1L, 0L)); mService.incrementOperationCount(UID_RED, 0xFAAD, 10); forcePollAndWaitForIdle(); @@ -501,10 +503,10 @@ public class NetworkStatsServiceTest extends NetworkStatsBaseTest { expectNetworkStatsSummary(new NetworkStats(getElapsedRealtime(), 1) .addIfaceValues(TEST_IFACE, 4128L, 258L, 544L, 34L)); expectNetworkStatsUidDetail(new NetworkStats(getElapsedRealtime(), 1) - .addValues(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, 16L, 1L, 16L, 1L, 0L) - .addValues(TEST_IFACE, UID_RED, SET_DEFAULT, 0xFAAD, 16L, 1L, 16L, 1L, 0L) - .addValues(TEST_IFACE, UID_BLUE, SET_DEFAULT, TAG_NONE, 4096L, 258L, 512L, 32L, 0L) - .addValues(TEST_IFACE, UID_GREEN, SET_DEFAULT, TAG_NONE, 16L, 1L, 16L, 1L, 0L)); + .addEntry(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, 16L, 1L, 16L, 1L, 0L) + .addEntry(TEST_IFACE, UID_RED, SET_DEFAULT, 0xFAAD, 16L, 1L, 16L, 1L, 0L) + .addEntry(TEST_IFACE, UID_BLUE, SET_DEFAULT, TAG_NONE, 4096L, 258L, 512L, 32L, 0L) + .addEntry(TEST_IFACE, UID_GREEN, SET_DEFAULT, TAG_NONE, 16L, 1L, 16L, 1L, 0L)); final Intent intent = new Intent(ACTION_UID_REMOVED); intent.putExtra(EXTRA_UID, UID_BLUE); mServiceContext.sendBroadcast(intent); @@ -536,8 +538,8 @@ public class NetworkStatsServiceTest extends NetworkStatsBaseTest { expectDefaultSettings(); expectNetworkStatsSummary(buildEmptyStats()); expectNetworkStatsUidDetail(new NetworkStats(getElapsedRealtime(), 1) - .addValues(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, 1024L, 8L, 1024L, 8L, 0L) - .addValues(TEST_IFACE, UID_RED, SET_DEFAULT, 0xF00D, 512L, 4L, 512L, 4L, 0L)); + .addEntry(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, 1024L, 8L, 1024L, 8L, 0L) + .addEntry(TEST_IFACE, UID_RED, SET_DEFAULT, 0xF00D, 512L, 4L, 512L, 4L, 0L)); mService.incrementOperationCount(UID_RED, 0xF00D, 5); forcePollAndWaitForIdle(); @@ -552,8 +554,8 @@ public class NetworkStatsServiceTest extends NetworkStatsBaseTest { states = new NetworkState[] {buildMobile4gState(TEST_IFACE2)}; expectNetworkStatsSummary(buildEmptyStats()); expectNetworkStatsUidDetail(new NetworkStats(getElapsedRealtime(), 1) - .addValues(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, 1024L, 8L, 1024L, 8L, 0L) - .addValues(TEST_IFACE, UID_RED, SET_DEFAULT, 0xF00D, 512L, 4L, 512L, 4L, 0L)); + .addEntry(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, 1024L, 8L, 1024L, 8L, 0L) + .addEntry(TEST_IFACE, UID_RED, SET_DEFAULT, 0xF00D, 512L, 4L, 512L, 4L, 0L)); mService.forceUpdateIfaces(NETWORKS_MOBILE, states, getActiveIface(states), new VpnInfo[0]); forcePollAndWaitForIdle(); @@ -564,10 +566,10 @@ public class NetworkStatsServiceTest extends NetworkStatsBaseTest { expectDefaultSettings(); expectNetworkStatsSummary(buildEmptyStats()); expectNetworkStatsUidDetail(new NetworkStats(getElapsedRealtime(), 1) - .addValues(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, 1024L, 8L, 1024L, 8L, 0L) - .addValues(TEST_IFACE, UID_RED, SET_DEFAULT, 0xF00D, 512L, 4L, 512L, 4L, 0L) - .addValues(TEST_IFACE2, UID_RED, SET_DEFAULT, TAG_NONE, 512L, 4L, 256L, 2L, 0L) - .addValues(TEST_IFACE2, UID_RED, SET_DEFAULT, 0xFAAD, 512L, 4L, 256L, 2L, 0L)); + .addEntry(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, 1024L, 8L, 1024L, 8L, 0L) + .addEntry(TEST_IFACE, UID_RED, SET_DEFAULT, 0xF00D, 512L, 4L, 512L, 4L, 0L) + .addEntry(TEST_IFACE2, UID_RED, SET_DEFAULT, TAG_NONE, 512L, 4L, 256L, 2L, 0L) + .addEntry(TEST_IFACE2, UID_RED, SET_DEFAULT, 0xFAAD, 512L, 4L, 256L, 2L, 0L)); mService.incrementOperationCount(UID_RED, 0xFAAD, 5); forcePollAndWaitForIdle(); @@ -591,9 +593,9 @@ public class NetworkStatsServiceTest extends NetworkStatsBaseTest { expectDefaultSettings(); expectNetworkStatsSummary(buildEmptyStats()); expectNetworkStatsUidDetail(new NetworkStats(getElapsedRealtime(), 1) - .addValues(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, 50L, 5L, 50L, 5L, 0L) - .addValues(TEST_IFACE, UID_RED, SET_DEFAULT, 0xF00D, 10L, 1L, 10L, 1L, 0L) - .addValues(TEST_IFACE, UID_BLUE, SET_DEFAULT, TAG_NONE, 1024L, 8L, 512L, 4L, 0L)); + .addEntry(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, 50L, 5L, 50L, 5L, 0L) + .addEntry(TEST_IFACE, UID_RED, SET_DEFAULT, 0xF00D, 10L, 1L, 10L, 1L, 0L) + .addEntry(TEST_IFACE, UID_BLUE, SET_DEFAULT, TAG_NONE, 1024L, 8L, 512L, 4L, 0L)); mService.incrementOperationCount(UID_RED, 0xF00D, 1); forcePollAndWaitForIdle(); @@ -608,9 +610,9 @@ public class NetworkStatsServiceTest extends NetworkStatsBaseTest { expectDefaultSettings(); expectNetworkStatsSummary(buildEmptyStats()); expectNetworkStatsUidDetail(new NetworkStats(getElapsedRealtime(), 1) - .addValues(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, 50L, 5L, 50L, 5L, 0L) - .addValues(TEST_IFACE, UID_RED, SET_DEFAULT, 0xF00D, 10L, 1L, 10L, 1L, 0L) - .addValues(TEST_IFACE, UID_BLUE, SET_DEFAULT, TAG_NONE, 2048L, 16L, 1024L, 8L, 0L)); + .addEntry(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, 50L, 5L, 50L, 5L, 0L) + .addEntry(TEST_IFACE, UID_RED, SET_DEFAULT, 0xF00D, 10L, 1L, 10L, 1L, 0L) + .addEntry(TEST_IFACE, UID_BLUE, SET_DEFAULT, TAG_NONE, 2048L, 16L, 1024L, 8L, 0L)); forcePollAndWaitForIdle(); // first verify entire history present @@ -654,9 +656,9 @@ public class NetworkStatsServiceTest extends NetworkStatsBaseTest { expectDefaultSettings(); expectNetworkStatsSummary(buildEmptyStats()); expectNetworkStatsUidDetail(new NetworkStats(getElapsedRealtime(), 3) - .addValues(entry1) - .addValues(entry2) - .addValues(entry3)); + .addEntry(entry1) + .addEntry(entry2) + .addEntry(entry3)); mService.incrementOperationCount(UID_RED, 0xF00D, 1); NetworkStats stats = mService.getDetailedUidStats(INTERFACES_ALL); @@ -704,11 +706,11 @@ public class NetworkStatsServiceTest extends NetworkStatsBaseTest { .thenReturn(augmentedIfaceFilter); when(mStatsFactory.readNetworkStatsDetail(eq(UID_ALL), any(), eq(TAG_ALL))) .thenReturn(new NetworkStats(getElapsedRealtime(), 1) - .addValues(uidStats)); + .addEntry(uidStats)); when(mNetManager.getNetworkStatsTethering(STATS_PER_UID)) .thenReturn(new NetworkStats(getElapsedRealtime(), 2) - .addValues(tetheredStats1) - .addValues(tetheredStats2)); + .addEntry(tetheredStats1) + .addEntry(tetheredStats2)); NetworkStats stats = mService.getDetailedUidStats(ifaceFilter); @@ -745,8 +747,8 @@ public class NetworkStatsServiceTest extends NetworkStatsBaseTest { expectDefaultSettings(); expectNetworkStatsSummary(buildEmptyStats()); expectNetworkStatsUidDetail(new NetworkStats(getElapsedRealtime(), 1) - .addValues(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, 128L, 2L, 128L, 2L, 0L) - .addValues(TEST_IFACE, UID_RED, SET_DEFAULT, 0xF00D, 64L, 1L, 64L, 1L, 0L)); + .addEntry(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, 128L, 2L, 128L, 2L, 0L) + .addEntry(TEST_IFACE, UID_RED, SET_DEFAULT, 0xF00D, 64L, 1L, 64L, 1L, 0L)); mService.incrementOperationCount(UID_RED, 0xF00D, 1); forcePollAndWaitForIdle(); @@ -760,10 +762,10 @@ public class NetworkStatsServiceTest extends NetworkStatsBaseTest { expectDefaultSettings(); expectNetworkStatsSummary(buildEmptyStats()); expectNetworkStatsUidDetail(new NetworkStats(getElapsedRealtime(), 1) - .addValues(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, 128L, 2L, 128L, 2L, 0L) - .addValues(TEST_IFACE, UID_RED, SET_DEFAULT, 0xF00D, 64L, 1L, 64L, 1L, 0L) - .addValues(TEST_IFACE, UID_RED, SET_FOREGROUND, TAG_NONE, 32L, 2L, 32L, 2L, 0L) - .addValues(TEST_IFACE, UID_RED, SET_FOREGROUND, 0xFAAD, 1L, 1L, 1L, 1L, 0L)); + .addEntry(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, 128L, 2L, 128L, 2L, 0L) + .addEntry(TEST_IFACE, UID_RED, SET_DEFAULT, 0xF00D, 64L, 1L, 64L, 1L, 0L) + .addEntry(TEST_IFACE, UID_RED, SET_FOREGROUND, TAG_NONE, 32L, 2L, 32L, 2L, 0L) + .addEntry(TEST_IFACE, UID_RED, SET_FOREGROUND, 0xFAAD, 1L, 1L, 1L, 1L, 0L)); mService.setUidForeground(UID_RED, true); mService.incrementOperationCount(UID_RED, 0xFAAD, 1); @@ -804,9 +806,9 @@ public class NetworkStatsServiceTest extends NetworkStatsBaseTest { // and DEFAULT_NETWORK_YES, because these three properties aren't tracked at that layer. // We layer them on top by inspecting the iface properties. expectNetworkStatsUidDetail(new NetworkStats(getElapsedRealtime(), 1) - .addValues(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO, + .addEntry(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO, DEFAULT_NETWORK_YES, 128L, 2L, 128L, 2L, 0L) - .addValues(TEST_IFACE, UID_RED, SET_DEFAULT, 0xF00D, METERED_NO, ROAMING_NO, + .addEntry(TEST_IFACE, UID_RED, SET_DEFAULT, 0xF00D, METERED_NO, ROAMING_NO, DEFAULT_NETWORK_YES, 64L, 1L, 64L, 1L, 0L)); mService.incrementOperationCount(UID_RED, 0xF00D, 1); @@ -843,9 +845,9 @@ public class NetworkStatsServiceTest extends NetworkStatsBaseTest { // ROAMING_NO, because metered and roaming isn't tracked at that layer. We layer it // on top by inspecting the iface properties. expectNetworkStatsUidDetail(new NetworkStats(getElapsedRealtime(), 1) - .addValues(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, METERED_ALL, ROAMING_NO, + .addEntry(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, METERED_ALL, ROAMING_NO, DEFAULT_NETWORK_YES, 128L, 2L, 128L, 2L, 0L) - .addValues(TEST_IFACE, UID_RED, SET_DEFAULT, 0xF00D, METERED_ALL, ROAMING_NO, + .addEntry(TEST_IFACE, UID_RED, SET_DEFAULT, 0xF00D, METERED_ALL, ROAMING_NO, DEFAULT_NETWORK_YES, 64L, 1L, 64L, 1L, 0L)); forcePollAndWaitForIdle(); @@ -885,10 +887,10 @@ public class NetworkStatsServiceTest extends NetworkStatsBaseTest { // Traffic for UID_RED. final NetworkStats uidStats = new NetworkStats(getElapsedRealtime(), 1) - .addValues(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, 128L, 2L, 128L, 2L, 0L); + .addEntry(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, 128L, 2L, 128L, 2L, 0L); // All tethering traffic, both hardware and software. final NetworkStats tetherStats = new NetworkStats(getElapsedRealtime(), 1) - .addValues(TEST_IFACE, UID_TETHERING, SET_DEFAULT, TAG_NONE, 1920L, 14L, 384L, 2L, + .addEntry(TEST_IFACE, UID_TETHERING, SET_DEFAULT, TAG_NONE, 1920L, 14L, 384L, 2L, 0L); expectNetworkStatsSummary(ifaceStats, tetherStatsHardware); @@ -1001,6 +1003,88 @@ public class NetworkStatsServiceTest extends NetworkStatsBaseTest { mService.unregisterUsageRequest(unknownRequest); } + @Test + public void testStatsProviderUpdateStats() throws Exception { + // Pretend that network comes online. + expectDefaultSettings(); + final NetworkState[] states = new NetworkState[]{buildWifiState(true /* isMetered */)}; + expectNetworkStatsSummary(buildEmptyStats()); + expectNetworkStatsUidDetail(buildEmptyStats()); + + // Register custom provider and retrieve callback. + final TestableNetworkStatsProvider provider = new TestableNetworkStatsProvider(); + final INetworkStatsProviderCallback cb = + mService.registerNetworkStatsProvider("TEST", provider); + assertNotNull(cb); + + mService.forceUpdateIfaces(NETWORKS_WIFI, states, getActiveIface(states), new VpnInfo[0]); + + // Verifies that one requestStatsUpdate will be called during iface update. + provider.expectStatsUpdate(0 /* unused */); + + // Create some initial traffic and report to the service. + incrementCurrentTime(HOUR_IN_MILLIS); + final NetworkStats expectedStats = new NetworkStats(0L, 1) + .addValues(new NetworkStats.Entry(TEST_IFACE, UID_RED, SET_DEFAULT, + TAG_NONE, METERED_YES, ROAMING_NO, DEFAULT_NETWORK_YES, + 128L, 2L, 128L, 2L, 1L)) + .addValues(new NetworkStats.Entry(TEST_IFACE, UID_RED, SET_DEFAULT, + 0xF00D, METERED_YES, ROAMING_NO, DEFAULT_NETWORK_YES, + 64L, 1L, 64L, 1L, 1L)); + cb.onStatsUpdated(0 /* unused */, expectedStats, expectedStats); + + // Make another empty mutable stats object. This is necessary since the new NetworkStats + // object will be used to compare with the old one in NetworkStatsRecoder, two of them + // cannot be the same object. + expectNetworkStatsUidDetail(buildEmptyStats()); + + forcePollAndWaitForIdle(); + + // Verifies that one requestStatsUpdate and setAlert will be called during polling. + provider.expectStatsUpdate(0 /* unused */); + provider.expectSetAlert(MB_IN_BYTES); + + // Verifies that service recorded history, does not verify uid tag part. + assertUidTotal(sTemplateWifi, UID_RED, 128L, 2L, 128L, 2L, 1); + + // Verifies that onStatsUpdated updates the stats accordingly. + final NetworkStats stats = mSession.getSummaryForAllUid( + sTemplateWifi, Long.MIN_VALUE, Long.MAX_VALUE, true); + assertEquals(2, stats.size()); + assertValues(stats, IFACE_ALL, UID_RED, SET_DEFAULT, TAG_NONE, METERED_YES, ROAMING_NO, + DEFAULT_NETWORK_YES, 128L, 2L, 128L, 2L, 1L); + assertValues(stats, IFACE_ALL, UID_RED, SET_DEFAULT, 0xF00D, METERED_YES, ROAMING_NO, + DEFAULT_NETWORK_YES, 64L, 1L, 64L, 1L, 1L); + + // Verifies that unregister the callback will remove the provider from service. + cb.unregister(); + forcePollAndWaitForIdle(); + provider.assertNoCallback(); + } + + @Test + public void testStatsProviderSetAlert() throws Exception { + // Pretend that network comes online. + expectDefaultSettings(); + NetworkState[] states = new NetworkState[]{buildWifiState(true /* isMetered */)}; + mService.forceUpdateIfaces(NETWORKS_WIFI, states, getActiveIface(states), new VpnInfo[0]); + + // Register custom provider and retrieve callback. + final TestableNetworkStatsProvider provider = new TestableNetworkStatsProvider(); + final INetworkStatsProviderCallback cb = + mService.registerNetworkStatsProvider("TEST", provider); + assertNotNull(cb); + + // Simulates alert quota of the provider has been reached. + cb.onAlertReached(); + HandlerUtilsKt.waitForIdle(mHandler, WAIT_TIMEOUT); + + // Verifies that polling is triggered by alert reached. + provider.expectStatsUpdate(0 /* unused */); + // Verifies that global alert will be re-armed. + provider.expectSetAlert(MB_IN_BYTES); + } + private static File getBaseDir(File statsDir) { File baseDir = new File(statsDir, "netstats"); baseDir.mkdirs(); @@ -1102,6 +1186,7 @@ public class NetworkStatsServiceTest extends NetworkStatsBaseTest { private void expectSettings(long persistBytes, long bucketDuration, long deleteAge) throws Exception { when(mSettings.getPollInterval()).thenReturn(HOUR_IN_MILLIS); + when(mSettings.getPollDelay()).thenReturn(0L); when(mSettings.getSampleEnabled()).thenReturn(true); final Config config = new Config(bucketDuration, deleteAge, deleteAge); diff --git a/tools/hiddenapi/generate_hiddenapi_lists.py b/tools/hiddenapi/generate_hiddenapi_lists.py index 46105f4d66b0..0b2077d9bba0 100755 --- a/tools/hiddenapi/generate_hiddenapi_lists.py +++ b/tools/hiddenapi/generate_hiddenapi_lists.py @@ -149,7 +149,12 @@ def extract_package(signature): The package name of the class containing the field/method. """ full_class_name = signature.split(";->")[0] - package_name = full_class_name[1:full_class_name.rindex("/")] + # Example: Landroid/hardware/radio/V1_2/IRadio$Proxy + if (full_class_name[0] != "L"): + raise ValueError("Expected to start with 'L': %s" % full_class_name) + full_class_name = full_class_name[1:] + # If full_class_name doesn't contain '/', then package_name will be ''. + package_name = full_class_name.rpartition("/")[0] return package_name.replace('/', '.') class FlagsDict: diff --git a/tools/lock_agent/Android.bp b/tools/lock_agent/Android.bp index 79dce4a8ce09..7b2ca9a65242 100644 --- a/tools/lock_agent/Android.bp +++ b/tools/lock_agent/Android.bp @@ -25,6 +25,7 @@ cc_binary_host { srcs: ["agent.cpp"], static_libs: [ "libbase", + "liblog", "libz", "slicer", ], diff --git a/tools/stats_log_api_gen/Android.bp b/tools/stats_log_api_gen/Android.bp index c08f9b04f0df..d3958a65c704 100644 --- a/tools/stats_log_api_gen/Android.bp +++ b/tools/stats_log_api_gen/Android.bp @@ -21,9 +21,16 @@ cc_binary_host { name: "stats-log-api-gen", srcs: [ "Collation.cpp", + "atoms_info_writer.cpp", + "java_writer.cpp", + "java_writer_q.cpp", "main.cpp", + "native_writer.cpp", + "native_writer_q.cpp", + "utils.cpp", ], cflags: [ + "-DSTATS_SCHEMA_LEGACY", "-Wall", "-Werror", ], @@ -98,28 +105,23 @@ genrule { cc_library { name: "libstatslog", host_supported: true, - generated_sources: ["statslog.cpp"], - generated_headers: ["statslog.h"], + generated_sources: [ + "statslog.cpp", + ], + generated_headers: [ + "statslog.h" + ], cflags: [ "-Wall", "-Werror", ], - export_generated_headers: ["statslog.h"], + export_generated_headers: [ + "statslog.h" + ], shared_libs: [ "liblog", "libcutils", ], static_libs: ["libstatssocket"], - target: { - android: { - shared_libs: [ - "libutils", - ], - }, - host: { - static_libs: [ - "libutils", - ], - }, - }, } + diff --git a/tools/stats_log_api_gen/Collation.cpp b/tools/stats_log_api_gen/Collation.cpp index 373adca994a1..fa556010646c 100644 --- a/tools/stats_log_api_gen/Collation.cpp +++ b/tools/stats_log_api_gen/Collation.cpp @@ -379,6 +379,7 @@ int collate_atoms(const Descriptor *descriptor, Atoms *atoms) { int errorCount = 0; const bool dbg = false; + int maxPushedAtomId = 2; for (int i = 0; i < descriptor->field_count(); i++) { const FieldDescriptor *atomField = descriptor->field(i); @@ -447,8 +448,14 @@ int collate_atoms(const Descriptor *descriptor, Atoms *atoms) { } atoms->non_chained_decls.insert(nonChainedAtomDecl); } + + if (atomDecl.code < PULL_ATOM_START_ID && atomDecl.code > maxPushedAtomId) { + maxPushedAtomId = atomDecl.code; + } } + atoms->maxPushedAtomId = maxPushedAtomId; + if (dbg) { printf("signatures = [\n"); for (map<vector<java_type_t>, set<string>>::const_iterator it = diff --git a/tools/stats_log_api_gen/Collation.h b/tools/stats_log_api_gen/Collation.h index 44746c96df1b..3efdd520d7f5 100644 --- a/tools/stats_log_api_gen/Collation.h +++ b/tools/stats_log_api_gen/Collation.h @@ -111,6 +111,7 @@ struct Atoms { set<AtomDecl> decls; set<AtomDecl> non_chained_decls; map<vector<java_type_t>, set<string>> non_chained_signatures_to_modules; + int maxPushedAtomId; }; /** @@ -123,4 +124,4 @@ int collate_atom(const Descriptor *atom, AtomDecl *atomDecl, vector<java_type_t> } // namespace android -#endif // ANDROID_STATS_LOG_API_GEN_COLLATION_H
\ No newline at end of file +#endif // ANDROID_STATS_LOG_API_GEN_COLLATION_H diff --git a/tools/stats_log_api_gen/atoms_info_writer.cpp b/tools/stats_log_api_gen/atoms_info_writer.cpp new file mode 100644 index 000000000000..54a9982bb5c2 --- /dev/null +++ b/tools/stats_log_api_gen/atoms_info_writer.cpp @@ -0,0 +1,227 @@ +/* + * 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 "atoms_info_writer.h" +#include "utils.h" + +#include <map> +#include <set> +#include <vector> + +namespace android { +namespace stats_log_api_gen { + +static void write_atoms_info_header_body(FILE* out, const Atoms& atoms) { + fprintf(out, "struct StateAtomFieldOptions {\n"); + fprintf(out, " std::vector<int> primaryFields;\n"); + fprintf(out, " int exclusiveField;\n"); + fprintf(out, "};\n"); + fprintf(out, "\n"); + + fprintf(out, "struct AtomsInfo {\n"); + fprintf(out, + " const static std::set<int> " + "kTruncatingTimestampAtomBlackList;\n"); + fprintf(out, " const static std::map<int, int> kAtomsWithUidField;\n"); + fprintf(out, + " const static std::set<int> kAtomsWithAttributionChain;\n"); + fprintf(out, + " const static std::map<int, StateAtomFieldOptions> " + "kStateAtomsFieldOptions;\n"); + fprintf(out, + " const static std::map<int, std::vector<int>> " + "kBytesFieldAtoms;\n"); + fprintf(out, + " const static std::set<int> kWhitelistedAtoms;\n"); + fprintf(out, "};\n"); + fprintf(out, "const static int kMaxPushedAtomId = %d;\n\n", atoms.maxPushedAtomId); + +} + +static void write_atoms_info_cpp_body(FILE* out, const Atoms& atoms) { + std::set<string> kTruncatingAtomNames = {"mobile_radio_power_state_changed", + "audio_state_changed", + "call_state_changed", + "phone_signal_strength_changed", + "mobile_bytes_transfer_by_fg_bg", + "mobile_bytes_transfer"}; + fprintf(out, + "const std::set<int> " + "AtomsInfo::kTruncatingTimestampAtomBlackList = {\n"); + for (set<string>::const_iterator blacklistedAtom = kTruncatingAtomNames.begin(); + blacklistedAtom != kTruncatingAtomNames.end(); blacklistedAtom++) { + fprintf(out, " %s,\n", make_constant_name(*blacklistedAtom).c_str()); + } + fprintf(out, "};\n"); + fprintf(out, "\n"); + + fprintf(out, + "const std::set<int> AtomsInfo::kAtomsWithAttributionChain = {\n"); + for (set<AtomDecl>::const_iterator atom = atoms.decls.begin(); + atom != atoms.decls.end(); atom++) { + for (vector<AtomField>::const_iterator field = atom->fields.begin(); + field != atom->fields.end(); field++) { + if (field->javaType == JAVA_TYPE_ATTRIBUTION_CHAIN) { + string constant = make_constant_name(atom->name); + fprintf(out, " %s,\n", constant.c_str()); + break; + } + } + } + + fprintf(out, "};\n"); + fprintf(out, "\n"); + + fprintf(out, + "const std::set<int> AtomsInfo::kWhitelistedAtoms = {\n"); + for (set<AtomDecl>::const_iterator atom = atoms.decls.begin(); + atom != atoms.decls.end(); atom++) { + if (atom->whitelisted) { + string constant = make_constant_name(atom->name); + fprintf(out, " %s,\n", constant.c_str()); + } + } + + fprintf(out, "};\n"); + fprintf(out, "\n"); + + fprintf(out, "static std::map<int, int> getAtomUidField() {\n"); + fprintf(out, " std::map<int, int> uidField;\n"); + for (set<AtomDecl>::const_iterator atom = atoms.decls.begin(); + atom != atoms.decls.end(); atom++) { + if (atom->uidField == 0) { + continue; + } + fprintf(out, + "\n // Adding uid field for atom " + "(%d)%s\n", + atom->code, atom->name.c_str()); + fprintf(out, " uidField[static_cast<int>(%s)] = %d;\n", + make_constant_name(atom->name).c_str(), atom->uidField); + } + + fprintf(out, " return uidField;\n"); + fprintf(out, "};\n"); + + fprintf(out, + "const std::map<int, int> AtomsInfo::kAtomsWithUidField = " + "getAtomUidField();\n"); + + fprintf(out, + "static std::map<int, StateAtomFieldOptions> " + "getStateAtomFieldOptions() {\n"); + fprintf(out, " std::map<int, StateAtomFieldOptions> options;\n"); + fprintf(out, " StateAtomFieldOptions opt;\n"); + for (set<AtomDecl>::const_iterator atom = atoms.decls.begin(); + atom != atoms.decls.end(); atom++) { + if (atom->primaryFields.size() == 0 && atom->exclusiveField == 0) { + continue; + } + fprintf(out, + "\n // Adding primary and exclusive fields for atom " + "(%d)%s\n", + atom->code, atom->name.c_str()); + fprintf(out, " opt.primaryFields.clear();\n"); + for (const auto& field : atom->primaryFields) { + fprintf(out, " opt.primaryFields.push_back(%d);\n", field); + } + + fprintf(out, " opt.exclusiveField = %d;\n", atom->exclusiveField); + fprintf(out, " options[static_cast<int>(%s)] = opt;\n", + make_constant_name(atom->name).c_str()); + } + + fprintf(out, " return options;\n"); + fprintf(out, "}\n"); + + fprintf(out, + "const std::map<int, StateAtomFieldOptions> " + "AtomsInfo::kStateAtomsFieldOptions = " + "getStateAtomFieldOptions();\n"); + + fprintf(out, + "static std::map<int, std::vector<int>> " + "getBinaryFieldAtoms() {\n"); + fprintf(out, " std::map<int, std::vector<int>> options;\n"); + for (set<AtomDecl>::const_iterator atom = atoms.decls.begin(); + atom != atoms.decls.end(); atom++) { + if (atom->binaryFields.size() == 0) { + continue; + } + fprintf(out, + "\n // Adding binary fields for atom " + "(%d)%s\n", + atom->code, atom->name.c_str()); + + for (const auto& field : atom->binaryFields) { + fprintf(out, " options[static_cast<int>(%s)].push_back(%d);\n", + make_constant_name(atom->name).c_str(), field); + } + } + + fprintf(out, " return options;\n"); + fprintf(out, "}\n"); + + fprintf(out, + "const std::map<int, std::vector<int>> " + "AtomsInfo::kBytesFieldAtoms = " + "getBinaryFieldAtoms();\n"); + +} + +int write_atoms_info_header(FILE* out, const Atoms &atoms, const string& namespaceStr) { + // Print prelude + fprintf(out, "// This file is autogenerated\n"); + fprintf(out, "\n"); + fprintf(out, "#pragma once\n"); + fprintf(out, "\n"); + fprintf(out, "#include <vector>\n"); + fprintf(out, "#include <map>\n"); + fprintf(out, "#include <set>\n"); + fprintf(out, "\n"); + + write_namespace(out, namespaceStr); + + write_atoms_info_header_body(out, atoms); + + fprintf(out, "\n"); + write_closing_namespace(out, namespaceStr); + + return 0; +} + +int write_atoms_info_cpp(FILE *out, const Atoms &atoms, const string& namespaceStr, + const string& importHeader, const string& statslogHeader) { + // Print prelude + fprintf(out, "// This file is autogenerated\n"); + fprintf(out, "\n"); + fprintf(out, "#include <%s>\n", importHeader.c_str()); + fprintf(out, "#include <%s>\n", statslogHeader.c_str()); + fprintf(out, "\n"); + + write_namespace(out, namespaceStr); + + write_atoms_info_cpp_body(out, atoms); + + // Print footer + fprintf(out, "\n"); + write_closing_namespace(out, namespaceStr); + + return 0; +} + +} // namespace stats_log_api_gen +} // namespace android diff --git a/tools/stats_log_api_gen/atoms_info_writer.h b/tools/stats_log_api_gen/atoms_info_writer.h new file mode 100644 index 000000000000..12ac862871ef --- /dev/null +++ b/tools/stats_log_api_gen/atoms_info_writer.h @@ -0,0 +1,35 @@ +/* + * 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 "Collation.h" + +#include <stdio.h> +#include <string.h> + +namespace android { +namespace stats_log_api_gen { + +using namespace std; + +int write_atoms_info_cpp(FILE* out, const Atoms& atoms, const string& namespaceStr, + const string& importHeader, const string& statslogHeader); + +int write_atoms_info_header(FILE* out, const Atoms& atoms, const string& namespaceStr); + +} // namespace stats_log_api_gen +} // namespace android diff --git a/tools/stats_log_api_gen/java_writer.cpp b/tools/stats_log_api_gen/java_writer.cpp new file mode 100644 index 000000000000..fef490c7e5f9 --- /dev/null +++ b/tools/stats_log_api_gen/java_writer.cpp @@ -0,0 +1,298 @@ +/* + * 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 map<vector<java_type_t>, set<string>>& signatures_to_modules, + const AtomDecl &attributionDecl, + const string& moduleName + ) { + 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, signatures_to_modules, attributionDecl, moduleName, " "); + + fprintf(out, " }\n"); + return 0; +} + + +static int write_java_methods( + FILE* out, + const map<vector<java_type_t>, set<string>>& signatures_to_modules, + const AtomDecl &attributionDecl, + const string& moduleName, + const bool supportQ + ) { + for (auto signature_to_modules_it = signatures_to_modules.begin(); + signature_to_modules_it != signatures_to_modules.end(); signature_to_modules_it++) { + // Skip if this signature is not needed for the module. + if (!signature_needed_for_module(signature_to_modules_it->second, moduleName)) { + continue; + } + + // Print method signature. + if (DEFAULT_MODULE_NAME == moduleName) { + fprintf(out, " /** @hide */\n"); + } + fprintf(out, " public static void write(int code"); + vector<java_type_t> signature = signature_to_modules_it->first; + 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, ", 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) { + // TODO(b/146235828): Use just SDK_INT check once it is incremented from Q. + fprintf(out, " if (Build.VERSION.SDK_INT > Build.VERSION_CODES.Q ||\n"); + fprintf(out, " Build.VERSION.CODENAME.equals(\"R\")) {\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 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 final SparseIntArray intMap = new SparseIntArray();\n", + indent.c_str()); + fprintf(out, + "%s final SparseLongArray longMap = new SparseLongArray();\n", + indent.c_str()); + fprintf(out, + "%s final SparseArray<String> stringMap = new SparseArray<>();\n", + indent.c_str()); + fprintf(out, + "%s final SparseArray<Float> floatMap = new SparseArray<>();\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 intMap.put(key, (Integer) value);\n", indent.c_str()); + fprintf(out, + "%s } else if (value instanceof Long) {\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 stringMap.put(key, (String) value);\n", indent.c_str()); + fprintf(out, + "%s } else if (value instanceof Float) {\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; + } + 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& moduleName, const string& javaClass, + const string& javaPackage, const bool supportQ) { + // 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"); + } + + if (DEFAULT_MODULE_NAME == moduleName) { + // Mainline modules don't use WorkSource logging. + fprintf(out, "import android.os.WorkSource;\n"); + + // SparseArray is used for writing KeyValuePairs; not supported for Mainline modules. + fprintf(out, "import android.util.SparseArray;\n"); + fprintf(out, "import android.util.SparseIntArray;\n"); + fprintf(out, "import android.util.SparseLongArray;\n"); + } + + fprintf(out, "import android.util.StatsEvent;\n"); + fprintf(out, "import android.util.StatsLog;\n"); + + if (DEFAULT_MODULE_NAME == moduleName) { + // List is used for WorkSource writing. Only needed for default module. + fprintf(out, "\n"); + fprintf(out, "import java.util.ArrayList;\n"); + } + + fprintf(out, "\n"); + fprintf(out, "\n"); + fprintf(out, "/**\n"); + fprintf(out, " * Utility class for logging statistics events.\n"); + if (DEFAULT_MODULE_NAME == moduleName) { + fprintf(out, " * @hide\n"); + } + fprintf(out, " */\n"); + fprintf(out, "public class %s {\n", javaClass.c_str()); + + write_java_atom_codes(out, atoms, moduleName); + write_java_enum_values(out, atoms, moduleName); + + int errors = 0; + + // Print write methods. + fprintf(out, " // Write methods\n"); + errors += write_java_methods( + out, atoms.signatures_to_modules, attributionDecl, moduleName, supportQ); + errors += write_java_non_chained_methods( + out, atoms.non_chained_signatures_to_modules, moduleName); + if (DEFAULT_MODULE_NAME == moduleName) { + errors += write_java_work_source_methods(out, atoms.signatures_to_modules, moduleName); + } + + if (supportQ) { + errors += write_java_q_logger_class( + out, atoms.signatures_to_modules, attributionDecl, moduleName); + } + + 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 new file mode 100644 index 000000000000..9324b23e4025 --- /dev/null +++ b/tools/stats_log_api_gen/java_writer.h @@ -0,0 +1,39 @@ +/* + * 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 "Collation.h" + +#include <map> +#include <set> +#include <vector> + +#include <stdio.h> +#include <string.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& moduleName, const string& javaClass, + const string& javaPackage, const bool supportQ); + +} // 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 new file mode 100644 index 000000000000..d6899f6131c6 --- /dev/null +++ b/tools/stats_log_api_gen/java_writer_q.cpp @@ -0,0 +1,470 @@ +/* + * 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 map<vector<java_type_t>, set<string>>& signatures_to_modules, + const AtomDecl &attributionDecl, + const string& moduleName, + const string& indent) { + int requiredHelpers = 0; + for (auto signature_to_modules_it = signatures_to_modules.begin(); + signature_to_modules_it != signatures_to_modules.end(); signature_to_modules_it++) { + // Skip if this signature is not needed for the module. + if (!signature_needed_for_module(signature_to_modules_it->second, moduleName)) { + continue; + } + + // Print method signature. + vector<java_type_t> signature = signature_to_modules_it->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) { + // Module logging does not yet support key value pair. + fprintf(stderr, "Module logging does not yet support key value pair.\n"); + continue; + } 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; + } + default: + // Unsupported types: OBJECT, DOUBLE, KEY_VALUE_PAIR. + fprintf(stderr, "Module logging does not yet support key value pair.\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; + } + default: + // Unsupported types: OBJECT, DOUBLE, KEY_VALUE_PAIR. + fprintf(stderr, + "Object, Double, and KeyValuePairs 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 defined(STATS_SCHEMA_LEGACY) +static void write_java_method( + FILE* out, + const string& method_name, + const map<vector<java_type_t>, set<string>>& signatures_to_modules, + const AtomDecl &attributionDecl) { + + for (auto signature_to_modules_it = signatures_to_modules.begin(); + signature_to_modules_it != signatures_to_modules.end(); signature_to_modules_it++) { + vector<java_type_t> signature = signature_to_modules_it->first; + fprintf(out, " /** @hide */\n"); + fprintf(out, " public static native int %s(int code", method_name.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, ", SparseArray<Object> value_map"); + } else { + fprintf(out, ", %s arg%d", java_type_name(*arg), argIndex); + } + argIndex++; + } + fprintf(out, ");\n"); + fprintf(out, "\n"); + } +} + +int write_stats_log_java_q(FILE* out, const Atoms& atoms, const AtomDecl &attributionDecl) { + // Print prelude + fprintf(out, "// This file is autogenerated\n"); + fprintf(out, "\n"); + fprintf(out, "package android.util;\n"); + fprintf(out, "\n"); + fprintf(out, "import android.os.WorkSource;\n"); + fprintf(out, "import android.util.SparseArray;\n"); + fprintf(out, "import java.util.ArrayList;\n"); + fprintf(out, "\n"); + fprintf(out, "\n"); + fprintf(out, "/**\n"); + fprintf(out, " * API For logging statistics events.\n"); + fprintf(out, " * @hide\n"); + fprintf(out, " */\n"); + fprintf(out, "public class StatsLogInternal {\n"); + write_java_atom_codes(out, atoms, DEFAULT_MODULE_NAME); + + write_java_enum_values(out, atoms, DEFAULT_MODULE_NAME); + + // Print write methods + fprintf(out, " // Write methods\n"); + write_java_method(out, "write", atoms.signatures_to_modules, attributionDecl); + write_java_method(out, "write_non_chained", atoms.non_chained_signatures_to_modules, + attributionDecl); + write_java_work_source_methods(out, atoms.signatures_to_modules, DEFAULT_MODULE_NAME); + + fprintf(out, "}\n"); + + return 0; +} + +int write_stats_log_java_q_for_module(FILE* out, const Atoms& atoms, const AtomDecl &attributionDecl, + const string& moduleName, const string& javaClass, + const string& javaPackage) { + // 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, "import java.util.ArrayList;\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, moduleName); + + write_java_enum_values(out, atoms, moduleName); + + int errors = 0; + // Print write methods + fprintf(out, " // Write methods\n"); + errors += write_java_methods_q_schema(out, atoms.signatures_to_modules, attributionDecl, + moduleName, " "); + errors += write_java_non_chained_methods(out, atoms.non_chained_signatures_to_modules, + moduleName); + + fprintf(out, "}\n"); + + return errors; +} +#endif + +} // 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 new file mode 100644 index 000000000000..96ac745beef8 --- /dev/null +++ b/tools/stats_log_api_gen/java_writer_q.h @@ -0,0 +1,56 @@ +/* + * 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 "Collation.h" + +#include <map> +#include <set> +#include <vector> + +#include <stdio.h> +#include <string.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 map<vector<java_type_t>, set<string>>& signatures_to_modules, + const AtomDecl &attributionDecl, + const string& moduleName, + const string& indent); + +void write_java_helpers_for_q_schema_methods( + FILE * out, + const AtomDecl &attributionDecl, + const int requiredHelpers, + const string& indent); + +#if defined(STATS_SCHEMA_LEGACY) +int write_stats_log_java_q(FILE* out, const Atoms& atoms, const AtomDecl &attributionDecl); + +int write_stats_log_java_q_for_module(FILE* out, const Atoms& atoms, + const AtomDecl &attributionDecl, const string& moduleName, const string& javaClass, + const string& javaPackage); +#endif +} // 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 index f62fef076f48..00a370484823 100644 --- a/tools/stats_log_api_gen/main.cpp +++ b/tools/stats_log_api_gen/main.cpp @@ -1,9 +1,17 @@ #include "Collation.h" +#include "atoms_info_writer.h" +#if !defined(STATS_SCHEMA_LEGACY) +#include "java_writer.h" +#endif +#include "java_writer_q.h" +#include "native_writer.h" +#include "utils.h" #include "frameworks/base/cmds/statsd/src/atoms.pb.h" +#include <map> #include <set> #include <vector> @@ -12,1490 +20,19 @@ #include <stdlib.h> #include <string.h> -#include "android-base/strings.h" - using namespace google::protobuf; using namespace std; namespace android { namespace stats_log_api_gen { -int maxPushedAtomId = 2; - -const string DEFAULT_MODULE_NAME = "DEFAULT"; -const string DEFAULT_CPP_NAMESPACE = "android,util"; -const string DEFAULT_CPP_HEADER_IMPORT = "statslog.h"; -const string DEFAULT_JAVA_PACKAGE = "android.util"; -const string DEFAULT_JAVA_CLASS = "StatsLogInternal"; - -const int JAVA_MODULE_REQUIRES_FLOAT = 0x01; -const int JAVA_MODULE_REQUIRES_ATTRIBUTION = 0x02; - using android::os::statsd::Atom; -/** - * Turn lower and camel case into upper case with underscores. - */ -static 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; -} - -static 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"; - } -} - -static 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"; - } -} - -static bool atom_needed_for_module(const AtomDecl& atomDecl, const string& moduleName) { - if (moduleName == DEFAULT_MODULE_NAME) { - return true; - } - return atomDecl.hasModule && (moduleName == atomDecl.moduleName); -} - -static bool signature_needed_for_module(const set<string>& modules, const string& moduleName) { - if (moduleName == DEFAULT_MODULE_NAME) { - return true; - } - return modules.find(moduleName) != modules.end(); -} - -static void write_atoms_info_cpp(FILE *out, const Atoms &atoms) { - std::set<string> kTruncatingAtomNames = {"mobile_radio_power_state_changed", - "audio_state_changed", - "call_state_changed", - "phone_signal_strength_changed", - "mobile_bytes_transfer_by_fg_bg", - "mobile_bytes_transfer"}; - fprintf(out, - "const std::set<int> " - "AtomsInfo::kTruncatingTimestampAtomBlackList = {\n"); - for (set<string>::const_iterator blacklistedAtom = kTruncatingAtomNames.begin(); - blacklistedAtom != kTruncatingAtomNames.end(); blacklistedAtom++) { - fprintf(out, " %s,\n", make_constant_name(*blacklistedAtom).c_str()); - } - fprintf(out, "};\n"); - fprintf(out, "\n"); - - fprintf(out, - "const std::set<int> AtomsInfo::kAtomsWithAttributionChain = {\n"); - for (set<AtomDecl>::const_iterator atom = atoms.decls.begin(); - atom != atoms.decls.end(); atom++) { - for (vector<AtomField>::const_iterator field = atom->fields.begin(); - field != atom->fields.end(); field++) { - if (field->javaType == JAVA_TYPE_ATTRIBUTION_CHAIN) { - string constant = make_constant_name(atom->name); - fprintf(out, " %s,\n", constant.c_str()); - break; - } - } - } - - fprintf(out, "};\n"); - fprintf(out, "\n"); - - fprintf(out, - "const std::set<int> AtomsInfo::kWhitelistedAtoms = {\n"); - for (set<AtomDecl>::const_iterator atom = atoms.decls.begin(); - atom != atoms.decls.end(); atom++) { - if (atom->whitelisted) { - string constant = make_constant_name(atom->name); - fprintf(out, " %s,\n", constant.c_str()); - } - } - - fprintf(out, "};\n"); - fprintf(out, "\n"); - - fprintf(out, "static std::map<int, int> getAtomUidField() {\n"); - fprintf(out, " std::map<int, int> uidField;\n"); - for (set<AtomDecl>::const_iterator atom = atoms.decls.begin(); - atom != atoms.decls.end(); atom++) { - if (atom->uidField == 0) { - continue; - } - fprintf(out, - "\n // Adding uid field for atom " - "(%d)%s\n", - atom->code, atom->name.c_str()); - fprintf(out, " uidField[static_cast<int>(%s)] = %d;\n", - make_constant_name(atom->name).c_str(), atom->uidField); - } - - fprintf(out, " return uidField;\n"); - fprintf(out, "};\n"); - - fprintf(out, - "const std::map<int, int> AtomsInfo::kAtomsWithUidField = " - "getAtomUidField();\n"); - - fprintf(out, - "static std::map<int, StateAtomFieldOptions> " - "getStateAtomFieldOptions() {\n"); - fprintf(out, " std::map<int, StateAtomFieldOptions> options;\n"); - fprintf(out, " StateAtomFieldOptions opt;\n"); - for (set<AtomDecl>::const_iterator atom = atoms.decls.begin(); - atom != atoms.decls.end(); atom++) { - if (atom->primaryFields.size() == 0 && atom->exclusiveField == 0) { - continue; - } - fprintf(out, - "\n // Adding primary and exclusive fields for atom " - "(%d)%s\n", - atom->code, atom->name.c_str()); - fprintf(out, " opt.primaryFields.clear();\n"); - for (const auto& field : atom->primaryFields) { - fprintf(out, " opt.primaryFields.push_back(%d);\n", field); - } - - fprintf(out, " opt.exclusiveField = %d;\n", atom->exclusiveField); - fprintf(out, " options[static_cast<int>(%s)] = opt;\n", - make_constant_name(atom->name).c_str()); - } - - fprintf(out, " return options;\n"); - fprintf(out, "}\n"); - - fprintf(out, - "const std::map<int, StateAtomFieldOptions> " - "AtomsInfo::kStateAtomsFieldOptions = " - "getStateAtomFieldOptions();\n"); - - fprintf(out, - "static std::map<int, std::vector<int>> " - "getBinaryFieldAtoms() {\n"); - fprintf(out, " std::map<int, std::vector<int>> options;\n"); - for (set<AtomDecl>::const_iterator atom = atoms.decls.begin(); - atom != atoms.decls.end(); atom++) { - if (atom->binaryFields.size() == 0) { - continue; - } - fprintf(out, - "\n // Adding binary fields for atom " - "(%d)%s\n", - atom->code, atom->name.c_str()); - - for (const auto& field : atom->binaryFields) { - fprintf(out, " options[static_cast<int>(%s)].push_back(%d);\n", - make_constant_name(atom->name).c_str(), field); - } - } - - fprintf(out, " return options;\n"); - fprintf(out, "}\n"); - - fprintf(out, - "const std::map<int, std::vector<int>> " - "AtomsInfo::kBytesFieldAtoms = " - "getBinaryFieldAtoms();\n"); -} - -// 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 int write_stats_log_cpp(FILE *out, const Atoms &atoms, const AtomDecl &attributionDecl, - const string& moduleName, const string& cppNamespace, - const string& importHeader) { - // Print prelude - fprintf(out, "// This file is autogenerated\n"); - fprintf(out, "\n"); - - fprintf(out, "#include <mutex>\n"); - fprintf(out, "#include <chrono>\n"); - fprintf(out, "#include <thread>\n"); - fprintf(out, "#ifdef __ANDROID__\n"); - fprintf(out, "#include <cutils/properties.h>\n"); - fprintf(out, "#endif\n"); - fprintf(out, "#include <stats_event_list.h>\n"); - fprintf(out, "#include <log/log.h>\n"); - fprintf(out, "#include <%s>\n", importHeader.c_str()); - fprintf(out, "#include <utils/SystemClock.h>\n"); - fprintf(out, "\n"); - - write_namespace(out, cppNamespace); - fprintf(out, "// the single event tag id for all stats logs\n"); - fprintf(out, "const static int kStatsEventTag = 1937006964;\n"); - fprintf(out, "#ifdef __ANDROID__\n"); - fprintf(out, "const static bool kStatsdEnabled = property_get_bool(\"ro.statsd.enable\", true);\n"); - fprintf(out, "#else\n"); - fprintf(out, "const static bool kStatsdEnabled = false;\n"); - fprintf(out, "#endif\n"); - - // AtomsInfo is only used by statsd internally and is not needed for other modules. - if (moduleName == DEFAULT_MODULE_NAME) { - write_atoms_info_cpp(out, atoms); - } - - fprintf(out, "int64_t lastRetryTimestampNs = -1;\n"); - fprintf(out, "const int64_t kMinRetryIntervalNs = NS_PER_SEC * 60 * 20; // 20 minutes\n"); - fprintf(out, "static std::mutex mLogdRetryMutex;\n"); - - // Print write methods - fprintf(out, "\n"); - for (auto signature_to_modules_it = atoms.signatures_to_modules.begin(); - signature_to_modules_it != atoms.signatures_to_modules.end(); signature_to_modules_it++) { - if (!signature_needed_for_module(signature_to_modules_it->second, moduleName)) { - continue; - } - vector<java_type_t> signature = signature_to_modules_it->first; - int argIndex; - - fprintf(out, "int\n"); - fprintf(out, "try_stats_write(int32_t code"); - 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, ")\n"); - - fprintf(out, "{\n"); - argIndex = 1; - fprintf(out, " if (kStatsdEnabled) {\n"); - fprintf(out, " stats_event_list event(kStatsEventTag);\n"); - fprintf(out, " event << android::elapsedRealtimeNano();\n\n"); - fprintf(out, " event << code;\n\n"); - for (vector<java_type_t>::const_iterator arg = signature.begin(); - arg != signature.end(); arg++) { - if (*arg == JAVA_TYPE_ATTRIBUTION_CHAIN) { - for (const auto &chainField : attributionDecl.fields) { - if (chainField.javaType == JAVA_TYPE_STRING) { - fprintf(out, " if (%s_length != %s.size()) {\n", - attributionDecl.fields.front().name.c_str(), chainField.name.c_str()); - fprintf(out, " return -EINVAL;\n"); - fprintf(out, " }\n"); - } - } - fprintf(out, "\n event.begin();\n"); - fprintf(out, " for (size_t i = 0; i < %s_length; ++i) {\n", - attributionDecl.fields.front().name.c_str()); - fprintf(out, " event.begin();\n"); - for (const auto &chainField : attributionDecl.fields) { - if (chainField.javaType == JAVA_TYPE_STRING) { - fprintf(out, " if (%s[i] != NULL) {\n", chainField.name.c_str()); - fprintf(out, " event << %s[i];\n", chainField.name.c_str()); - fprintf(out, " } else {\n"); - fprintf(out, " event << \"\";\n"); - fprintf(out, " }\n"); - } else { - fprintf(out, " event << %s[i];\n", chainField.name.c_str()); - } - } - fprintf(out, " event.end();\n"); - fprintf(out, " }\n"); - fprintf(out, " event.end();\n\n"); - } else if (*arg == JAVA_TYPE_KEY_VALUE_PAIR) { - fprintf(out, " event.begin();\n\n"); - fprintf(out, " for (const auto& it : arg%d_1) {\n", argIndex); - fprintf(out, " event.begin();\n"); - fprintf(out, " event << it.first;\n"); - fprintf(out, " event << it.second;\n"); - fprintf(out, " event.end();\n"); - fprintf(out, " }\n"); - - fprintf(out, " for (const auto& it : arg%d_2) {\n", argIndex); - fprintf(out, " event.begin();\n"); - fprintf(out, " event << it.first;\n"); - fprintf(out, " event << it.second;\n"); - fprintf(out, " event.end();\n"); - fprintf(out, " }\n"); - - fprintf(out, " for (const auto& it : arg%d_3) {\n", argIndex); - fprintf(out, " event.begin();\n"); - fprintf(out, " event << it.first;\n"); - fprintf(out, " event << it.second;\n"); - fprintf(out, " event.end();\n"); - fprintf(out, " }\n"); - - fprintf(out, " for (const auto& it : arg%d_4) {\n", argIndex); - fprintf(out, " event.begin();\n"); - fprintf(out, " event << it.first;\n"); - fprintf(out, " event << it.second;\n"); - fprintf(out, " event.end();\n"); - fprintf(out, " }\n"); - - fprintf(out, " event.end();\n\n"); - } else if (*arg == JAVA_TYPE_BYTE_ARRAY) { - fprintf(out, - " event.AppendCharArray(arg%d.arg, " - "arg%d.arg_length);\n", - argIndex, argIndex); - } else { - if (*arg == JAVA_TYPE_STRING) { - fprintf(out, " if (arg%d == NULL) {\n", argIndex); - fprintf(out, " arg%d = \"\";\n", argIndex); - fprintf(out, " }\n"); - } - fprintf(out, " event << arg%d;\n", argIndex); - } - argIndex++; - } - - fprintf(out, " return event.write(LOG_ID_STATS);\n"); - fprintf(out, " } else {\n"); - fprintf(out, " return 1;\n"); - fprintf(out, " }\n"); - fprintf(out, "}\n"); - fprintf(out, "\n"); - } - - for (auto signature_to_modules_it = atoms.signatures_to_modules.begin(); - signature_to_modules_it != atoms.signatures_to_modules.end(); signature_to_modules_it++) { - if (!signature_needed_for_module(signature_to_modules_it->second, moduleName)) { - continue; - } - vector<java_type_t> signature = signature_to_modules_it->first; - int argIndex; - - fprintf(out, "int\n"); - fprintf(out, "stats_write(int32_t code"); - 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, ")\n"); - - fprintf(out, "{\n"); - fprintf(out, " int ret = 0;\n"); - - fprintf(out, " for(int retry = 0; retry < 2; ++retry) {\n"); - fprintf(out, " ret = try_stats_write(code"); - - 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, ", %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"); - fprintf(out, " if (ret >= 0) { break; }\n"); - - fprintf(out, " {\n"); - fprintf(out, " std::lock_guard<std::mutex> lock(mLogdRetryMutex);\n"); - fprintf(out, " if ((android::elapsedRealtimeNano() - lastRetryTimestampNs) <= " - "kMinRetryIntervalNs) break;\n"); - fprintf(out, " lastRetryTimestampNs = android::elapsedRealtimeNano();\n"); - fprintf(out, " }\n"); - fprintf(out, " std::this_thread::sleep_for(std::chrono::milliseconds(10));\n"); - fprintf(out, " }\n"); - fprintf(out, " if (ret < 0) {\n"); - fprintf(out, " note_log_drop(ret, code);\n"); - fprintf(out, " }\n"); - fprintf(out, " return ret;\n"); - fprintf(out, "}\n"); - fprintf(out, "\n"); - } - - for (auto signature_it = atoms.non_chained_signatures_to_modules.begin(); - signature_it != atoms.non_chained_signatures_to_modules.end(); signature_it++) { - if (!signature_needed_for_module(signature_it->second, moduleName)) { - continue; - } - vector<java_type_t> signature = signature_it->first; - int argIndex; - - fprintf(out, "int\n"); - fprintf(out, "try_stats_write_non_chained(int32_t code"); - argIndex = 1; - for (vector<java_type_t>::const_iterator arg = signature.begin(); - arg != signature.end(); arg++) { - fprintf(out, ", %s arg%d", cpp_type_name(*arg), argIndex); - argIndex++; - } - fprintf(out, ")\n"); - - fprintf(out, "{\n"); - argIndex = 1; - fprintf(out, " if (kStatsdEnabled) {\n"); - fprintf(out, " stats_event_list event(kStatsEventTag);\n"); - fprintf(out, " event << android::elapsedRealtimeNano();\n\n"); - fprintf(out, " event << code;\n\n"); - for (vector<java_type_t>::const_iterator arg = signature.begin(); - arg != signature.end(); arg++) { - if (argIndex == 1) { - fprintf(out, " event.begin();\n\n"); - fprintf(out, " event.begin();\n"); - } - if (*arg == JAVA_TYPE_STRING) { - fprintf(out, " if (arg%d == NULL) {\n", argIndex); - fprintf(out, " arg%d = \"\";\n", argIndex); - fprintf(out, " }\n"); - } - if (*arg == JAVA_TYPE_BYTE_ARRAY) { - fprintf(out, - " event.AppendCharArray(arg%d.arg, " - "arg%d.arg_length);", - argIndex, argIndex); - } else { - fprintf(out, " event << arg%d;\n", argIndex); - } - if (argIndex == 2) { - fprintf(out, " event.end();\n\n"); - fprintf(out, " event.end();\n\n"); - } - argIndex++; - } - - fprintf(out, " return event.write(LOG_ID_STATS);\n"); - fprintf(out, " } else {\n"); - fprintf(out, " return 1;\n"); - fprintf(out, " }\n"); - fprintf(out, "}\n"); - fprintf(out, "\n"); - } - - for (auto signature_it = atoms.non_chained_signatures_to_modules.begin(); - signature_it != atoms.non_chained_signatures_to_modules.end(); signature_it++) { - if (!signature_needed_for_module(signature_it->second, moduleName)) { - continue; - } - vector<java_type_t> signature = signature_it->first; - int argIndex; - - fprintf(out, "int\n"); - fprintf(out, "stats_write_non_chained(int32_t code"); - argIndex = 1; - for (vector<java_type_t>::const_iterator arg = signature.begin(); - arg != signature.end(); arg++) { - fprintf(out, ", %s arg%d", cpp_type_name(*arg), argIndex); - argIndex++; - } - fprintf(out, ")\n"); - - fprintf(out, "{\n"); - - fprintf(out, " int ret = 0;\n"); - fprintf(out, " for(int retry = 0; retry < 2; ++retry) {\n"); - fprintf(out, " ret = try_stats_write_non_chained(code"); - - argIndex = 1; - for (vector<java_type_t>::const_iterator arg = signature.begin(); - arg != signature.end(); arg++) { - fprintf(out, ", arg%d", argIndex); - argIndex++; - } - fprintf(out, ");\n"); - fprintf(out, " if (ret >= 0) { break; }\n"); - - fprintf(out, " {\n"); - fprintf(out, " std::lock_guard<std::mutex> lock(mLogdRetryMutex);\n"); - fprintf(out, " if ((android::elapsedRealtimeNano() - lastRetryTimestampNs) <= " - "kMinRetryIntervalNs) break;\n"); - fprintf(out, " lastRetryTimestampNs = android::elapsedRealtimeNano();\n"); - fprintf(out, " }\n"); - - fprintf(out, " std::this_thread::sleep_for(std::chrono::milliseconds(10));\n"); - fprintf(out, " }\n"); - fprintf(out, " if (ret < 0) {\n"); - fprintf(out, " note_log_drop(ret, code);\n"); - fprintf(out, " }\n"); - fprintf(out, " return ret;\n\n"); - fprintf(out, "}\n"); - - fprintf(out, "\n"); - } - - - // Print footer - fprintf(out, "\n"); - write_closing_namespace(out, cppNamespace); - - return 0; -} - -void build_non_chained_decl_map(const Atoms& atoms, - std::map<int, set<AtomDecl>::const_iterator>* decl_map){ - for (set<AtomDecl>::const_iterator atom = atoms.non_chained_decls.begin(); - atom != atoms.non_chained_decls.end(); atom++) { - decl_map->insert(std::make_pair(atom->code, atom)); - } -} - -static void write_cpp_usage( - FILE* out, const string& method_name, const string& atom_code_name, - const 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"); -} - -static void write_cpp_method_header( - FILE* out, - const string& method_name, - const map<vector<java_type_t>, set<string>>& signatures_to_modules, - const AtomDecl &attributionDecl, const string& moduleName) { - - for (auto signature_to_modules_it = signatures_to_modules.begin(); - signature_to_modules_it != signatures_to_modules.end(); signature_to_modules_it++) { - // Skip if this signature is not needed for the module. - if (!signature_needed_for_module(signature_to_modules_it->second, moduleName)) { - continue; - } - - vector<java_type_t> signature = signature_to_modules_it->first; - fprintf(out, "int %s(int32_t code", method_name.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, ");\n"); - - } -} - -static int -write_stats_log_header(FILE* out, const Atoms& atoms, const AtomDecl &attributionDecl, - const string& moduleName, 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"); - fprintf(out, "/**\n"); - fprintf(out, " * Constants for atom codes.\n"); - fprintf(out, " */\n"); - fprintf(out, "enum {\n"); - - std::map<int, set<AtomDecl>::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 (set<AtomDecl>::const_iterator atom = atoms.decls.begin(); - atom != atoms.decls.end(); atom++) { - // Skip if the atom is not needed for the module. - if (!atom_needed_for_module(*atom, moduleName)) { - continue; - } - string constant = make_constant_name(atom->name); - fprintf(out, "\n"); - fprintf(out, " /**\n"); - fprintf(out, " * %s %s\n", atom->message.c_str(), atom->name.c_str()); - write_cpp_usage(out, "stats_write", constant, *atom, attributionDecl); - - auto non_chained_decl = atom_code_to_non_chained_decl_map.find(atom->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(), atom->code, comma); - if (atom->code < PULL_ATOM_START_ID && atom->code > maxPushedAtomId) { - maxPushedAtomId = atom->code; - } - i++; - } - fprintf(out, "\n"); - fprintf(out, "};\n"); - fprintf(out, "\n"); - - // Print constants for the enum values. - fprintf(out, "//\n"); - fprintf(out, "// Constants for enum values\n"); - fprintf(out, "//\n\n"); - for (set<AtomDecl>::const_iterator atom = atoms.decls.begin(); - atom != atoms.decls.end(); atom++) { - // Skip if the atom is not needed for the module. - if (!atom_needed_for_module(*atom, moduleName)) { - continue; - } - - for (vector<AtomField>::const_iterator field = atom->fields.begin(); - field != atom->fields.end(); field++) { - if (field->javaType == JAVA_TYPE_ENUM) { - fprintf(out, "// Values for %s.%s\n", atom->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(atom->message).c_str(), - make_constant_name(field->name).c_str(), - make_constant_name(value->second).c_str(), - value->first); - } - fprintf(out, "\n"); - } - } - } - - 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"); - - // This metadata is only used by statsd, which uses the default libstatslog. - if (moduleName == DEFAULT_MODULE_NAME) { - - fprintf(out, "struct StateAtomFieldOptions {\n"); - fprintf(out, " std::vector<int> primaryFields;\n"); - fprintf(out, " int exclusiveField;\n"); - fprintf(out, "};\n"); - fprintf(out, "\n"); - - fprintf(out, "struct AtomsInfo {\n"); - fprintf(out, - " const static std::set<int> " - "kTruncatingTimestampAtomBlackList;\n"); - fprintf(out, " const static std::map<int, int> kAtomsWithUidField;\n"); - fprintf(out, - " const static std::set<int> kAtomsWithAttributionChain;\n"); - fprintf(out, - " const static std::map<int, StateAtomFieldOptions> " - "kStateAtomsFieldOptions;\n"); - fprintf(out, - " const static std::map<int, std::vector<int>> " - "kBytesFieldAtoms;"); - fprintf(out, - " const static std::set<int> kWhitelistedAtoms;\n"); - fprintf(out, "};\n"); - - fprintf(out, "const static int kMaxPushedAtomId = %d;\n\n", - maxPushedAtomId); - } - - // Print write methods - fprintf(out, "//\n"); - fprintf(out, "// Write methods\n"); - fprintf(out, "//\n"); - write_cpp_method_header(out, "stats_write", atoms.signatures_to_modules, attributionDecl, - moduleName); - - fprintf(out, "//\n"); - fprintf(out, "// Write flattened methods\n"); - fprintf(out, "//\n"); - write_cpp_method_header(out, "stats_write_non_chained", atoms.non_chained_signatures_to_modules, - attributionDecl, moduleName); - - fprintf(out, "\n"); - write_closing_namespace(out, cppNamespace); - - return 0; -} - -static 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, ", 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"); -} - -static void write_java_method( - FILE* out, - const string& method_name, - const map<vector<java_type_t>, set<string>>& signatures_to_modules, - const AtomDecl &attributionDecl) { - - for (auto signature_to_modules_it = signatures_to_modules.begin(); - signature_to_modules_it != signatures_to_modules.end(); signature_to_modules_it++) { - vector<java_type_t> signature = signature_to_modules_it->first; - fprintf(out, " /** @hide */\n"); - fprintf(out, " public static native int %s(int code", method_name.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, ", SparseArray<Object> value_map"); - } else { - fprintf(out, ", %s arg%d", java_type_name(*arg), argIndex); - } - argIndex++; - } - fprintf(out, ");\n"); - } -} - -static void write_java_helpers_for_module( - FILE * out, - const AtomDecl &attributionDecl, - const int requiredHelpers) { - fprintf(out, " private static void copyInt(byte[] buff, int pos, int val) {\n"); - fprintf(out, " buff[pos] = (byte) (val);\n"); - fprintf(out, " buff[pos + 1] = (byte) (val >> 8);\n"); - fprintf(out, " buff[pos + 2] = (byte) (val >> 16);\n"); - fprintf(out, " buff[pos + 3] = (byte) (val >> 24);\n"); - fprintf(out, " return;\n"); - fprintf(out, " }\n"); - fprintf(out, "\n"); - - fprintf(out, " private static void copyLong(byte[] buff, int pos, long val) {\n"); - fprintf(out, " buff[pos] = (byte) (val);\n"); - fprintf(out, " buff[pos + 1] = (byte) (val >> 8);\n"); - fprintf(out, " buff[pos + 2] = (byte) (val >> 16);\n"); - fprintf(out, " buff[pos + 3] = (byte) (val >> 24);\n"); - fprintf(out, " buff[pos + 4] = (byte) (val >> 32);\n"); - fprintf(out, " buff[pos + 5] = (byte) (val >> 40);\n"); - fprintf(out, " buff[pos + 6] = (byte) (val >> 48);\n"); - fprintf(out, " buff[pos + 7] = (byte) (val >> 56);\n"); - fprintf(out, " return;\n"); - fprintf(out, " }\n"); - fprintf(out, "\n"); - - if (requiredHelpers & JAVA_MODULE_REQUIRES_FLOAT) { - fprintf(out, " private static void copyFloat(byte[] buff, int pos, float val) {\n"); - fprintf(out, " copyInt(buff, pos, Float.floatToIntBits(val));\n"); - fprintf(out, " return;\n"); - fprintf(out, " }\n"); - fprintf(out, "\n"); - } - - if (requiredHelpers & JAVA_MODULE_REQUIRES_ATTRIBUTION) { - fprintf(out, " private static void writeAttributionChain(byte[] buff, int pos"); - 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, " buff[pos] = LIST_TYPE;\n"); - fprintf(out, " buff[pos + 1] = (byte) (%s.length);\n", tagName); - fprintf(out, " pos += LIST_TYPE_OVERHEAD;\n"); - - // Iterate through the attribution chain and write the nodes. - fprintf(out, " for (int i = 0; i < %s.length; i++) {\n", tagName); - // Write the list begin. - fprintf(out, " buff[pos] = LIST_TYPE;\n"); - fprintf(out, " buff[pos + 1] = %lu;\n", attributionDecl.fields.size()); - fprintf(out, " pos += LIST_TYPE_OVERHEAD;\n"); - - // Write the uid. - fprintf(out, " buff[pos] = INT_TYPE;\n"); - fprintf(out, " copyInt(buff, pos + 1, %s[i]);\n", uidName); - fprintf(out, " pos += INT_TYPE_SIZE;\n"); - - // Write the tag. - fprintf(out, " String %sStr = (%s[i] == null) ? \"\" : %s[i];\n", - tagName, tagName, tagName); - fprintf(out, " byte[] %sByte = %sStr.getBytes(UTF_8);\n", tagName, tagName); - fprintf(out, " buff[pos] = STRING_TYPE;\n"); - fprintf(out, " copyInt(buff, pos + 1, %sByte.length);\n", tagName); - fprintf(out, " System.arraycopy(" - "%sByte, 0, buff, pos + STRING_TYPE_OVERHEAD, %sByte.length);\n", - tagName, tagName); - fprintf(out, " pos += STRING_TYPE_OVERHEAD + %sByte.length;\n", tagName); - fprintf(out, " }\n"); - fprintf(out, " }\n"); - fprintf(out, "\n"); - } -} - - -static int write_java_non_chained_method_for_module( - FILE* out, - const map<vector<java_type_t>, set<string>>& signatures_to_modules, - const string& moduleName - ) { - for (auto signature_to_modules_it = signatures_to_modules.begin(); - signature_to_modules_it != signatures_to_modules.end(); signature_to_modules_it++) { - // Skip if this signature is not needed for the module. - if (!signature_needed_for_module(signature_to_modules_it->second, moduleName)) { - continue; - } - - // Print method signature. - vector<java_type_t> signature = signature_to_modules_it->first; - fprintf(out, " public static void write_non_chained(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) { - // Non chained signatures should not have attribution chains. - return 1; - } else if (*arg == JAVA_TYPE_KEY_VALUE_PAIR) { - // Module logging does not yet support key value pair. - 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; -} - -static int write_java_method_for_module( - FILE* out, - const map<vector<java_type_t>, set<string>>& signatures_to_modules, - const AtomDecl &attributionDecl, - const string& moduleName, - int* requiredHelpers - ) { - - for (auto signature_to_modules_it = signatures_to_modules.begin(); - signature_to_modules_it != signatures_to_modules.end(); signature_to_modules_it++) { - // Skip if this signature is not needed for the module. - if (!signature_needed_for_module(signature_to_modules_it->second, moduleName)) { - continue; - } - - // Print method signature. - vector<java_type_t> signature = signature_to_modules_it->first; - 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) { - 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) { - // Module logging does not yet support key value pair. - return 1; - } else { - fprintf(out, ", %s arg%d", java_type_name(*arg), argIndex); - } - argIndex++; - } - fprintf(out, ") {\n"); - - // Calculate the size of the buffer. - fprintf(out, " // Initial overhead of the list, timestamp, and atom tag.\n"); - fprintf(out, " int needed = LIST_TYPE_OVERHEAD + LONG_TYPE_SIZE + INT_TYPE_SIZE;\n"); - 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, " needed += INT_TYPE_SIZE;\n"); - break; - case JAVA_TYPE_LONG: - // Longs take 9 bytes, 1 for the type and 8 for the value. - fprintf(out, " needed += LONG_TYPE_SIZE;\n"); - break; - case JAVA_TYPE_STRING: - // Strings take 5 metadata bytes + length of byte encoded string. - fprintf(out, " if (arg%d == null) {\n", argIndex); - fprintf(out, " arg%d = \"\";\n", argIndex); - fprintf(out, " }\n"); - fprintf(out, " byte[] arg%dBytes= arg%d.getBytes(UTF_8);\n", - argIndex, argIndex); - fprintf(out, " needed += STRING_TYPE_OVERHEAD + arg%dBytes.length;\n", - argIndex); - break; - case JAVA_TYPE_BYTE_ARRAY: - // Byte arrays take 5 metadata bytes + length of byte array. - fprintf(out, " if (arg%d == null) {\n", argIndex); - fprintf(out, " arg%d = new byte[0];\n", argIndex); - fprintf(out, " }\n"); - fprintf(out, " needed += STRING_TYPE_OVERHEAD + arg%d.length;\n", 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, " if (%s == null) {\n", uidName); - fprintf(out, " %s = new %s[0];\n", uidName, - java_type_name(attributionDecl.fields.front().javaType)); - fprintf(out, " }\n"); - fprintf(out, " if (%s == null) {\n", tagName); - fprintf(out, " %s = new %s[0];\n", tagName, - java_type_name(attributionDecl.fields.back().javaType)); - fprintf(out, " }\n"); - - // First check that the lengths of the uid and tag arrays are the same. - fprintf(out, " if (%s.length != %s.length) {\n", uidName, tagName); - fprintf(out, " return;\n"); - fprintf(out, " }\n"); - fprintf(out, " int attrSize = LIST_TYPE_OVERHEAD;\n"); - fprintf(out, " for (int i = 0; i < %s.length; i++) {\n", tagName); - fprintf(out, " String str%d = (%s[i] == null) ? \"\" : %s[i];\n", - argIndex, tagName, tagName); - fprintf(out, " int str%dlen = str%d.getBytes(UTF_8).length;\n", - argIndex, argIndex); - fprintf(out, - " attrSize += " - "LIST_TYPE_OVERHEAD + INT_TYPE_SIZE + STRING_TYPE_OVERHEAD + str%dlen;\n", - argIndex); - fprintf(out, " }\n"); - fprintf(out, " needed += attrSize;\n"); - break; - } - default: - // Unsupported types: OBJECT, DOUBLE, KEY_VALUE_PAIR. - return 1; - } - argIndex++; - } - - // Now we have the size that is needed. Check for overflow and return if needed. - fprintf(out, " if (needed > MAX_EVENT_PAYLOAD) {\n"); - fprintf(out, " return;\n"); - fprintf(out, " }\n"); - - // Create new buffer, and associated data types. - fprintf(out, " byte[] buff = new byte[needed];\n"); - fprintf(out, " int pos = 0;\n"); - - // Initialize the buffer with list data type. - fprintf(out, " buff[pos] = LIST_TYPE;\n"); - fprintf(out, " buff[pos + 1] = %zu;\n", signature.size() + 2); - fprintf(out, " pos += LIST_TYPE_OVERHEAD;\n"); - - // Write timestamp. - fprintf(out, " long elapsedRealtime = SystemClock.elapsedRealtimeNanos();\n"); - fprintf(out, " buff[pos] = LONG_TYPE;\n"); - fprintf(out, " copyLong(buff, pos + 1, elapsedRealtime);\n"); - fprintf(out, " pos += LONG_TYPE_SIZE;\n"); - - // Write atom code. - fprintf(out, " buff[pos] = INT_TYPE;\n"); - fprintf(out, " copyInt(buff, pos + 1, code);\n"); - fprintf(out, " pos += INT_TYPE_SIZE;\n"); - - // 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, " buff[pos] = INT_TYPE;\n"); - fprintf(out, " copyInt(buff, pos + 1, arg%d? 1 : 0);\n", argIndex); - fprintf(out, " pos += INT_TYPE_SIZE;\n"); - break; - case JAVA_TYPE_INT: - case JAVA_TYPE_ENUM: - fprintf(out, " buff[pos] = INT_TYPE;\n"); - fprintf(out, " copyInt(buff, pos + 1, arg%d);\n", argIndex); - fprintf(out, " pos += INT_TYPE_SIZE;\n"); - break; - case JAVA_TYPE_FLOAT: - *requiredHelpers |= JAVA_MODULE_REQUIRES_FLOAT; - fprintf(out, " buff[pos] = FLOAT_TYPE;\n"); - fprintf(out, " copyFloat(buff, pos + 1, arg%d);\n", argIndex); - fprintf(out, " pos += FLOAT_TYPE_SIZE;\n"); - break; - case JAVA_TYPE_LONG: - fprintf(out, " buff[pos] = LONG_TYPE;\n"); - fprintf(out, " copyLong(buff, pos + 1, arg%d);\n", argIndex); - fprintf(out, " pos += LONG_TYPE_SIZE;\n"); - break; - case JAVA_TYPE_STRING: - fprintf(out, " buff[pos] = STRING_TYPE;\n"); - fprintf(out, " copyInt(buff, pos + 1, arg%dBytes.length);\n", argIndex); - fprintf(out, " System.arraycopy(" - "arg%dBytes, 0, buff, pos + STRING_TYPE_OVERHEAD, arg%dBytes.length);\n", - argIndex, argIndex); - fprintf(out, " pos += STRING_TYPE_OVERHEAD + arg%dBytes.length;\n", - argIndex); - break; - case JAVA_TYPE_BYTE_ARRAY: - fprintf(out, " buff[pos] = STRING_TYPE;\n"); - fprintf(out, " copyInt(buff, pos + 1, arg%d.length);\n", argIndex); - fprintf(out, " System.arraycopy(" - "arg%d, 0, buff, pos + STRING_TYPE_OVERHEAD, arg%d.length);\n", - argIndex, argIndex); - fprintf(out, " pos += STRING_TYPE_OVERHEAD + arg%d.length;\n", 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, " writeAttributionChain(buff, pos, %s, %s);\n", - uidName, tagName); - fprintf(out, " pos += attrSize;\n"); - break; - } - default: - // Unsupported types: OBJECT, DOUBLE, KEY_VALUE_PAIR. - return 1; - } - argIndex++; - } - - fprintf(out, " StatsLog.writeRaw(buff, pos);\n"); - fprintf(out, " }\n"); - fprintf(out, "\n"); - } - return 0; -} - -static void write_java_work_source_method(FILE* out, - const map<vector<java_type_t>, set<string>>& signatures_to_modules, - const string& moduleName) { - fprintf(out, "\n // WorkSource methods.\n"); - for (auto signature_to_modules_it = signatures_to_modules.begin(); - signature_to_modules_it != signatures_to_modules.end(); signature_to_modules_it++) { - // Skip if this signature is not needed for the module. - if (!signature_needed_for_module(signature_to_modules_it->second, moduleName)) { - continue; - } - vector<java_type_t> signature = signature_to_modules_it->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; - } - attributionArg = argIndexMax; - } - } - if (attributionArg < 0) { - continue; - } - - // Method header (signature) - if (moduleName == DEFAULT_MODULE_NAME) { - fprintf(out, " /** @hide */\n"); - } - 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, ", 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.get(i), ws.getName(i)"); - } else { - fprintf(out, ", arg%d", argIndex); - } - } - fprintf(out, ");\n"); - fprintf(out, " }\n"); // close for-loop - - // write() component. - fprintf(out, " ArrayList<WorkSource.WorkChain> workChains = ws.getWorkChains();\n"); - fprintf(out, " if (workChains != null) {\n"); - fprintf(out, " for (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 - } -} - -static void write_java_atom_codes(FILE* out, const Atoms& atoms, const string& moduleName) { - fprintf(out, " // Constants for atom codes.\n"); - - std::map<int, set<AtomDecl>::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 (set<AtomDecl>::const_iterator atom = atoms.decls.begin(); - atom != atoms.decls.end(); atom++) { - // Skip if the atom is not needed for the module. - if (!atom_needed_for_module(*atom, moduleName)) { - continue; - } - string constant = make_constant_name(atom->name); - fprintf(out, "\n"); - fprintf(out, " /**\n"); - fprintf(out, " * %s %s<br>\n", atom->message.c_str(), atom->name.c_str()); - write_java_usage(out, "write", constant, *atom); - auto non_chained_decl = atom_code_to_non_chained_decl_map.find(atom->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); - } - if (moduleName == DEFAULT_MODULE_NAME) { - fprintf(out, " * @hide\n"); - } - fprintf(out, " */\n"); - fprintf(out, " public static final int %s = %d;\n", constant.c_str(), atom->code); - } - fprintf(out, "\n"); -} - -static void write_java_enum_values(FILE* out, const Atoms& atoms, const string& moduleName) { - fprintf(out, " // Constants for enum values.\n\n"); - for (set<AtomDecl>::const_iterator atom = atoms.decls.begin(); - atom != atoms.decls.end(); atom++) { - // Skip if the atom is not needed for the module. - if (!atom_needed_for_module(*atom, moduleName)) { - continue; - } - for (vector<AtomField>::const_iterator field = atom->fields.begin(); - field != atom->fields.end(); field++) { - if (field->javaType == JAVA_TYPE_ENUM) { - fprintf(out, " // Values for %s.%s\n", atom->message.c_str(), - field->name.c_str()); - for (map<int, string>::const_iterator value = field->enumValues.begin(); - value != field->enumValues.end(); value++) { - if (moduleName == DEFAULT_MODULE_NAME) { - fprintf(out, " /** @hide */\n"); - } - fprintf(out, " public static final int %s__%s__%s = %d;\n", - make_constant_name(atom->message).c_str(), - make_constant_name(field->name).c_str(), - make_constant_name(value->second).c_str(), - value->first); - } - fprintf(out, "\n"); - } - } - } -} - -static int -write_stats_log_java(FILE* out, const Atoms& atoms, const AtomDecl &attributionDecl) -{ - // Print prelude - fprintf(out, "// This file is autogenerated\n"); - fprintf(out, "\n"); - fprintf(out, "package android.util;\n"); - fprintf(out, "\n"); - fprintf(out, "import android.os.WorkSource;\n"); - fprintf(out, "import android.util.SparseArray;\n"); - fprintf(out, "import java.util.ArrayList;\n"); - fprintf(out, "\n"); - fprintf(out, "\n"); - fprintf(out, "/**\n"); - fprintf(out, " * API For logging statistics events.\n"); - fprintf(out, " * @hide\n"); - fprintf(out, " */\n"); - fprintf(out, "public class StatsLogInternal {\n"); - write_java_atom_codes(out, atoms, DEFAULT_MODULE_NAME); - - write_java_enum_values(out, atoms, DEFAULT_MODULE_NAME); - - // Print write methods - fprintf(out, " // Write methods\n"); - write_java_method(out, "write", atoms.signatures_to_modules, attributionDecl); - write_java_method(out, "write_non_chained", atoms.non_chained_signatures_to_modules, - attributionDecl); - write_java_work_source_method(out, atoms.signatures_to_modules, DEFAULT_MODULE_NAME); - - fprintf(out, "}\n"); - - return 0; -} - -// TODO: Merge this with write_stats_log_java so that we can get rid of StatsLogInternal JNI. -static int -write_stats_log_java_for_module(FILE* out, const Atoms& atoms, const AtomDecl &attributionDecl, - const string& moduleName, const string& javaClass, const string& javaPackage) -{ - // 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, "import java.util.ArrayList;\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()); - - // TODO: ideally these match with the native values (and automatically change if they change). - fprintf(out, " private static final int LOGGER_ENTRY_MAX_PAYLOAD = 4068;\n"); - fprintf(out, - " private static final int MAX_EVENT_PAYLOAD = LOGGER_ENTRY_MAX_PAYLOAD - 4;\n"); - // Value types. Must match with EventLog.java and log.h. - fprintf(out, " private static final byte INT_TYPE = 0;\n"); - fprintf(out, " private static final byte LONG_TYPE = 1;\n"); - fprintf(out, " private static final byte STRING_TYPE = 2;\n"); - fprintf(out, " private static final byte LIST_TYPE = 3;\n"); - fprintf(out, " private static final byte FLOAT_TYPE = 4;\n"); - - // Size of each value type. - // Booleans, ints, floats, and enums take 5 bytes, 1 for the type and 4 for the value. - fprintf(out, " private static final int INT_TYPE_SIZE = 5;\n"); - fprintf(out, " private static final int FLOAT_TYPE_SIZE = 5;\n"); - // Longs take 9 bytes, 1 for the type and 8 for the value. - fprintf(out, " private static final int LONG_TYPE_SIZE = 9;\n"); - // Strings take 5 metadata bytes: 1 byte is for the type, 4 are for the length. - fprintf(out, " private static final int STRING_TYPE_OVERHEAD = 5;\n"); - fprintf(out, " private static final int LIST_TYPE_OVERHEAD = 2;\n"); - - write_java_atom_codes(out, atoms, moduleName); - - write_java_enum_values(out, atoms, moduleName); - - int errors = 0; - int requiredHelpers = 0; - // Print write methods - fprintf(out, " // Write methods\n"); - errors += write_java_method_for_module(out, atoms.signatures_to_modules, attributionDecl, - moduleName, &requiredHelpers); - errors += write_java_non_chained_method_for_module(out, atoms.non_chained_signatures_to_modules, - moduleName); - - fprintf(out, " // Helper methods for copying primitives\n"); - write_java_helpers_for_module(out, attributionDecl, requiredHelpers); - - fprintf(out, "}\n"); - - return errors; -} - +// Hide the JNI write helpers that are not used in the new schema. +// TODO(b/145100015): Remove this and other JNI related functionality once StatsEvent migration is +// complete. +#if defined(STATS_SCHEMA_LEGACY) +// JNI helpers. static const char* jni_type_name(java_type_t type) { @@ -1666,7 +203,7 @@ static void write_key_value_map_jni(FILE* out) { } static int -write_stats_log_jni(FILE* out, const string& java_method_name, const string& cpp_method_name, +write_stats_log_jni_method(FILE* out, const string& java_method_name, const string& cpp_method_name, const map<vector<java_type_t>, set<string>>& signatures_to_modules, const AtomDecl &attributionDecl) { // Print write methods @@ -1882,40 +419,56 @@ void write_jni_registration(FILE* out, const string& java_method_name, jni_function_name(java_method_name, signature).c_str()); } } +#endif // JNI helpers. static int +#if defined(STATS_SCHEMA_LEGACY) write_stats_log_jni(FILE* out, const Atoms& atoms, const AtomDecl &attributionDecl) +#else +// Write empty JNI file that doesn't contain any JNI methods. +// TODO(b/145100015): remove this function and all JNI autogen code once StatsEvent migration is +// complete. +write_stats_log_jni(FILE* out) +#endif { // Print prelude fprintf(out, "// This file is autogenerated\n"); fprintf(out, "\n"); +#if defined(STATS_SCHEMA_LEGACY) fprintf(out, "#include <statslog.h>\n"); fprintf(out, "\n"); fprintf(out, "#include <nativehelper/JNIHelp.h>\n"); fprintf(out, "#include <nativehelper/ScopedUtfChars.h>\n"); fprintf(out, "#include <utils/Vector.h>\n"); +#endif fprintf(out, "#include \"core_jni_helpers.h\"\n"); fprintf(out, "#include \"jni.h\"\n"); fprintf(out, "\n"); +#if defined(STATS_SCHEMA_LEGACY) fprintf(out, "#define UNUSED __attribute__((__unused__))\n"); fprintf(out, "\n"); +#endif fprintf(out, "namespace android {\n"); fprintf(out, "\n"); - write_stats_log_jni(out, "write", "stats_write", atoms.signatures_to_modules, attributionDecl); - write_stats_log_jni(out, "write_non_chained", "stats_write_non_chained", +#if defined(STATS_SCHEMA_LEGACY) + write_stats_log_jni_method(out, "write", "stats_write", atoms.signatures_to_modules, attributionDecl); + write_stats_log_jni_method(out, "write_non_chained", "stats_write_non_chained", atoms.non_chained_signatures_to_modules, attributionDecl); +#endif // Print registration function table fprintf(out, "/*\n"); fprintf(out, " * JNI registration.\n"); fprintf(out, " */\n"); fprintf(out, "static const JNINativeMethod gRegisterMethods[] = {\n"); +#if defined(STATS_SCHEMA_LEGACY) write_jni_registration(out, "write", atoms.signatures_to_modules, attributionDecl); write_jni_registration(out, "write_non_chained", atoms.non_chained_signatures_to_modules, attributionDecl); +#endif fprintf(out, "};\n"); fprintf(out, "\n"); @@ -1938,20 +491,28 @@ 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\n"); - fprintf(stderr, " --header FILENAME the cpp file to output\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, + " --atomsInfoCpp FILENAME the header file to output for statsd metadata\n"); + fprintf(stderr, " --atomsInfoHeader FILENAME the cpp file to output for statsd metadata\n"); fprintf(stderr, " --help this message\n"); fprintf(stderr, " --java FILENAME the java file to output\n"); fprintf(stderr, " --jni FILENAME the jni 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\n"); + fprintf(stderr," --importHeader NAME required for cpp/jni to say which header to import " + "for write helpers\n"); + fprintf(stderr," --atomsInfoImportHeader NAME required for cpp to say which header to import " + "for statsd metadata\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, " Default is \"StatsLogInternal\"\n"); + fprintf(stderr, " --supportQ Include support for Android Q.\n"); +} /** * Do the argument parsing and execute the tasks. @@ -1963,12 +524,16 @@ run(int argc, char const*const* argv) string headerFilename; string javaFilename; string jniFilename; + string atomsInfoCppFilename; + string atomsInfoHeaderFilename; string moduleName = DEFAULT_MODULE_NAME; string cppNamespace = DEFAULT_CPP_NAMESPACE; string cppHeaderImport = DEFAULT_CPP_HEADER_IMPORT; + string atomsInfoCppHeaderImport = DEFAULT_ATOMS_INFO_CPP_HEADER_IMPORT; string javaPackage = DEFAULT_JAVA_PACKAGE; string javaClass = DEFAULT_JAVA_CLASS; + bool supportQ = false; int index = 1; while (index < argc) { @@ -2038,18 +603,50 @@ run(int argc, char const*const* argv) return 1; } javaClass = argv[index]; + } else if (0 == strcmp("--atomsInfoHeader", argv[index])) { + index++; + if (index >= argc) { + print_usage(); + return 1; + } + atomsInfoHeaderFilename = argv[index]; + } else if (0 == strcmp("--atomsInfoCpp", argv[index])) { + index++; + if (index >= argc) { + print_usage(); + return 1; + } + atomsInfoCppFilename = argv[index]; + } else if (0 == strcmp("--atomsInfoImportHeader", argv[index])) { + index++; + if (index >= argc) { + print_usage(); + return 1; + } + atomsInfoCppHeaderImport = argv[index]; + } else if (0 == strcmp("--supportQ", argv[index])) { + supportQ = true; } + index++; } if (cppFilename.size() == 0 && headerFilename.size() == 0 && javaFilename.size() == 0 - && jniFilename.size() == 0) { + && jniFilename.size() == 0 + && atomsInfoHeaderFilename.size() == 0 + && atomsInfoCppFilename.size() == 0) { print_usage(); return 1; } + if (DEFAULT_MODULE_NAME == moduleName && supportQ) { + // Support for Q schema is not needed for default module. + fprintf(stderr, "%s cannot support Q schema\n", moduleName.c_str()); + return 1; + } + // Collate the parameters Atoms atoms; int errorCount = collate_atoms(Atom::descriptor(), &atoms); @@ -2062,6 +659,30 @@ run(int argc, char const*const* argv) collate_atom(android::os::statsd::AttributionNode::descriptor(), &attributionDecl, &attributionSignature); + // Write the atoms info .cpp file + if (atomsInfoCppFilename.size() != 0) { + FILE* out = fopen(atomsInfoCppFilename.c_str(), "w"); + if (out == NULL) { + fprintf(stderr, "Unable to open file for write: %s\n", atomsInfoCppFilename.c_str()); + return 1; + } + errorCount = android::stats_log_api_gen::write_atoms_info_cpp( + out, atoms, cppNamespace, atomsInfoCppHeaderImport, cppHeaderImport); + fclose(out); + } + + // Write the atoms info .h file + if (atomsInfoHeaderFilename.size() != 0) { + FILE* out = fopen(atomsInfoHeaderFilename.c_str(), "w"); + if (out == NULL) { + fprintf(stderr, "Unable to open file for write: %s\n", atomsInfoHeaderFilename.c_str()); + return 1; + } + errorCount = android::stats_log_api_gen::write_atoms_info_header(out, atoms, cppNamespace); + fclose(out); + } + + // Write the .cpp file if (cppFilename.size() != 0) { FILE* out = fopen(cppFilename.c_str(), "w"); @@ -2080,7 +701,7 @@ run(int argc, char const*const* argv) return 1; } errorCount = android::stats_log_api_gen::write_stats_log_cpp( - out, atoms, attributionDecl, moduleName, cppNamespace, cppHeaderImport); + out, atoms, attributionDecl, moduleName, cppNamespace, cppHeaderImport, supportQ); fclose(out); } @@ -2112,13 +733,25 @@ run(int argc, char const*const* argv) fprintf(stderr, "Must supply --javaPackage if supplying a specific module\n"); return 1; } + +#if defined(STATS_SCHEMA_LEGACY) if (moduleName == DEFAULT_MODULE_NAME) { - errorCount = android::stats_log_api_gen::write_stats_log_java( + errorCount = android::stats_log_api_gen::write_stats_log_java_q( out, atoms, attributionDecl); } else { - errorCount = android::stats_log_api_gen::write_stats_log_java_for_module( + errorCount = android::stats_log_api_gen::write_stats_log_java_q_for_module( out, atoms, attributionDecl, moduleName, javaClass, javaPackage); + + } +#else + if (moduleName == DEFAULT_MODULE_NAME) { + javaClass = "StatsLogInternal"; + javaPackage = "android.util"; } + errorCount = android::stats_log_api_gen::write_stats_log_java( + out, atoms, attributionDecl, moduleName, javaClass, javaPackage, supportQ); +#endif + fclose(out); } @@ -2129,16 +762,22 @@ run(int argc, char const*const* argv) fprintf(stderr, "Unable to open file for write: %s\n", jniFilename.c_str()); return 1; } + +#if defined(STATS_SCHEMA_LEGACY) errorCount = android::stats_log_api_gen::write_stats_log_jni( out, atoms, attributionDecl); +#else + errorCount = android::stats_log_api_gen::write_stats_log_jni(out); +#endif + fclose(out); } return errorCount; } -} -} +} // namespace stats_log_api_gen +} // namespace android /** * Main. diff --git a/tools/stats_log_api_gen/native_writer.cpp b/tools/stats_log_api_gen/native_writer.cpp new file mode 100644 index 000000000000..c7a34feff94b --- /dev/null +++ b/tools/stats_log_api_gen/native_writer.cpp @@ -0,0 +1,342 @@ +/* + * 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 "native_writer_q.h" +#include "utils.h" + +namespace android { +namespace stats_log_api_gen { + +#if !defined(STATS_SCHEMA_LEGACY) +static void write_native_key_value_pairs_for_type(FILE* out, const int argIndex, + const int typeIndex, const string& type, const string& valueFieldName) { + fprintf(out, " for (const auto& it : arg%d_%d) {\n", argIndex, typeIndex); + fprintf(out, " pairs.push_back(" + "{ .key = it.first, .valueType = %s, .%s = it.second });\n", + type.c_str(), valueFieldName.c_str()); + fprintf(out, " }\n"); + +} + +static int write_native_stats_write_methods(FILE* out, const Atoms& atoms, + const AtomDecl& attributionDecl, const string& moduleName, const bool supportQ) { + fprintf(out, "\n"); + for (auto signature_to_modules_it = atoms.signatures_to_modules.begin(); + signature_to_modules_it != atoms.signatures_to_modules.end(); signature_to_modules_it++) { + if (!signature_needed_for_module(signature_to_modules_it->second, moduleName)) { + continue; + } + vector<java_type_t> signature = signature_to_modules_it->first; + + 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"); + 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_KEY_VALUE_PAIR: + fprintf(out, " event.writeKeyValuePairs(" + "arg%d_1, arg%d_2, arg%d_3, arg%d_4);\n", + argIndex, argIndex, argIndex, argIndex); + 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. + fprintf(stderr, "Encountered unsupported type."); + return 1; + } + argIndex++; + } + fprintf(out, " return event.writeToSocket();\n"); + } else { + fprintf(out, " struct stats_event* event = stats_event_obtain();\n"); + fprintf(out, " stats_event_set_atom_id(event, code);\n"); + 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, + " stats_event_write_attribution_chain(event, " + "reinterpret_cast<const uint32_t*>(%s), %s.data(), " + "static_cast<uint8_t>(%s_length));\n", + uidName, tagName, uidName); + break; + } + case JAVA_TYPE_KEY_VALUE_PAIR: + fprintf(out, " std::vector<key_value_pair> pairs;\n"); + write_native_key_value_pairs_for_type( + out, argIndex, 1, "INT32_TYPE", "int32Value"); + write_native_key_value_pairs_for_type( + out, argIndex, 2, "INT64_TYPE", "int64Value"); + write_native_key_value_pairs_for_type( + out, argIndex, 3, "STRING_TYPE", "stringValue"); + write_native_key_value_pairs_for_type( + out, argIndex, 4, "FLOAT_TYPE", "floatValue"); + fprintf(out, + " stats_event_write_key_value_pairs(event, pairs.data(), " + "static_cast<uint8_t>(pairs.size()));\n"); + break; + case JAVA_TYPE_BYTE_ARRAY: + fprintf(out, + " stats_event_write_byte_array(event, " + "reinterpret_cast<const uint8_t*>(arg%d.arg), arg%d.arg_length);\n", + argIndex, argIndex); + break; + case JAVA_TYPE_BOOLEAN: + fprintf(out, " stats_event_write_bool(event, arg%d);\n", argIndex); + break; + case JAVA_TYPE_INT: // Fall through. + case JAVA_TYPE_ENUM: + fprintf(out, " stats_event_write_int32(event, arg%d);\n", argIndex); + break; + case JAVA_TYPE_FLOAT: + fprintf(out, " stats_event_write_float(event, arg%d);\n", argIndex); + break; + case JAVA_TYPE_LONG: + fprintf(out, " stats_event_write_int64(event, arg%d);\n", argIndex); + break; + case JAVA_TYPE_STRING: + fprintf(out, " stats_event_write_string8(event, arg%d);\n", argIndex); + break; + default: + // Unsupported types: OBJECT, DOUBLE. + fprintf(stderr, "Encountered unsupported type."); + return 1; + } + argIndex++; + } + fprintf(out, " const int ret = stats_event_write(event);\n"); + fprintf(out, " stats_event_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, const string& moduleName) { + fprintf(out, "\n"); + for (auto signature_it = atoms.non_chained_signatures_to_modules.begin(); + signature_it != atoms.non_chained_signatures_to_modules.end(); signature_it++) { + if (!signature_needed_for_module(signature_it->second, moduleName)) { + continue; + } + vector<java_type_t> signature = signature_it->first; + + 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"); + } + +} +#endif + +static void write_native_method_header( + FILE* out, + const string& methodName, + const map<vector<java_type_t>, set<string>>& signatures_to_modules, + const AtomDecl &attributionDecl, const string& moduleName) { + + for (auto signature_to_modules_it = signatures_to_modules.begin(); + signature_to_modules_it != signatures_to_modules.end(); signature_to_modules_it++) { + // Skip if this signature is not needed for the module. + if (!signature_needed_for_module(signature_to_modules_it->second, moduleName)) { + continue; + } + + vector<java_type_t> signature = signature_to_modules_it->first; + write_native_method_signature(out, methodName, signature, attributionDecl, ";"); + } +} + +int write_stats_log_cpp(FILE *out, const Atoms &atoms, const AtomDecl &attributionDecl, + const string& moduleName, 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 defined(STATS_SCHEMA_LEGACY) + (void)supportQ; // Workaround for unused parameter error. + write_native_cpp_includes_q(out); +#else + if (supportQ) { + fprintf(out, "#include <StatsEventCompat.h>\n"); + } else { + fprintf(out, "#include <stats_event.h>\n"); + } +#endif + + fprintf(out, "\n"); + write_namespace(out, cppNamespace); + +#if defined(STATS_SCHEMA_LEGACY) + write_native_stats_log_cpp_globals_q(out); + write_native_get_timestamp_ns_q(out); + write_native_try_stats_write_methods_q(out, atoms, attributionDecl, moduleName); + write_native_stats_write_methods_q(out, "int stats_write", atoms, attributionDecl, moduleName, + "try_stats_write"); + write_native_try_stats_write_non_chained_methods_q(out, atoms, attributionDecl, moduleName); + write_native_stats_write_non_chained_methods_q(out, "int stats_write_non_chained", atoms, + attributionDecl, moduleName, "try_stats_write_non_chained"); +#else + write_native_stats_write_methods(out, atoms, attributionDecl, moduleName, supportQ); + write_native_stats_write_non_chained_methods(out, atoms, attributionDecl, moduleName); +#endif + + // 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& moduleName, 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, moduleName); + + // Print constants for the enum values. + fprintf(out, "//\n"); + fprintf(out, "// Constants for enum values\n"); + fprintf(out, "//\n\n"); + for (set<AtomDecl>::const_iterator atom = atoms.decls.begin(); + atom != atoms.decls.end(); atom++) { + // Skip if the atom is not needed for the module. + if (!atom_needed_for_module(*atom, moduleName)) { + continue; + } + + for (vector<AtomField>::const_iterator field = atom->fields.begin(); + field != atom->fields.end(); field++) { + if (field->javaType == JAVA_TYPE_ENUM) { + fprintf(out, "// Values for %s.%s\n", atom->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(atom->message).c_str(), + make_constant_name(field->name).c_str(), + make_constant_name(value->second).c_str(), + value->first); + } + fprintf(out, "\n"); + } + } + } + + 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.signatures_to_modules, attributionDecl, + moduleName); + + fprintf(out, "//\n"); + fprintf(out, "// Write flattened methods\n"); + fprintf(out, "//\n"); + write_native_method_header(out, "int stats_write_non_chained", + atoms.non_chained_signatures_to_modules, attributionDecl, moduleName); + + 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 new file mode 100644 index 000000000000..aafa96ece2d0 --- /dev/null +++ b/tools/stats_log_api_gen/native_writer.h @@ -0,0 +1,37 @@ +/* + * 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 "Collation.h" + +#include <stdio.h> +#include <string.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& moduleName, const string& cppNamespace, const string& importHeader, + const bool supportQ); + +int write_stats_log_header(FILE* out, const Atoms& atoms, const AtomDecl &attributionDecl, + const string& moduleName, const string& cppNamespace); + +} // namespace stats_log_api_gen +} // namespace android diff --git a/tools/stats_log_api_gen/native_writer_q.cpp b/tools/stats_log_api_gen/native_writer_q.cpp new file mode 100644 index 000000000000..299873dad975 --- /dev/null +++ b/tools/stats_log_api_gen/native_writer_q.cpp @@ -0,0 +1,276 @@ +/* + * 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_q.h" +#include "utils.h" + +namespace android { +namespace stats_log_api_gen { + +static void write_native_stats_write_body_q(FILE* out, const vector<java_type_t>& signature, + const AtomDecl& attributionDecl, const string& indent, const string& tryMethodName) { + fprintf(out, "%sint ret = 0;\n", indent.c_str()); + + fprintf(out, "%sfor(int retry = 0; retry < 2; ++retry) {\n", indent.c_str()); + fprintf(out, "%s ret = ", indent.c_str()); + write_native_method_call(out, tryMethodName, signature, attributionDecl); + fprintf(out, "%s if (ret >= 0) { break; }\n", indent.c_str()); + + fprintf(out, "%s {\n", indent.c_str()); + fprintf(out, "%s std::lock_guard<std::mutex> lock(mLogdRetryMutex);\n", indent.c_str()); + fprintf(out, "%s if ((get_elapsed_realtime_ns() - lastRetryTimestampNs) <= " + "kMinRetryIntervalNs) break;\n", indent.c_str()); + fprintf(out, "%s lastRetryTimestampNs = get_elapsed_realtime_ns();\n", + indent.c_str()); + fprintf(out, "%s }\n", indent.c_str()); + fprintf(out, "%s std::this_thread::sleep_for(std::chrono::milliseconds(10));\n", + indent.c_str()); + fprintf(out, "%s}\n", indent.c_str()); + fprintf(out, "%sif (ret < 0) {\n", indent.c_str()); + fprintf(out, "%s note_log_drop(ret, code);\n", indent.c_str()); + fprintf(out, "%s}\n", indent.c_str()); + fprintf(out, "%sreturn ret;\n", indent.c_str()); +} + +void write_native_cpp_includes_q(FILE* out) { + fprintf(out, "#include <mutex>\n"); + fprintf(out, "#include <chrono>\n"); + fprintf(out, "#include <thread>\n"); + fprintf(out, "#ifdef __ANDROID__\n"); + fprintf(out, "#include <cutils/properties.h>\n"); + fprintf(out, "#endif\n"); + fprintf(out, "#include <stats_event_list.h>\n"); + fprintf(out, "#include <log/log.h>\n"); + fprintf(out, "#include <time.h>\n"); +} + +void write_native_get_timestamp_ns_q(FILE* out) { + fprintf(out, "\n"); + fprintf(out, "static int64_t get_elapsed_realtime_ns() {\n"); + fprintf(out, " struct timespec t;\n"); + fprintf(out, " t.tv_sec = t.tv_nsec = 0;\n"); + fprintf(out, " clock_gettime(CLOCK_BOOTTIME, &t);\n"); + fprintf(out, " return (int64_t)t.tv_sec * 1000000000LL + t.tv_nsec;\n"); + fprintf(out, "}\n"); +} + +void write_native_stats_log_cpp_globals_q(FILE* out) { + fprintf(out, "// the single event tag id for all stats logs\n"); + fprintf(out, "const static int kStatsEventTag = 1937006964;\n"); + fprintf(out, "#ifdef __ANDROID__\n"); + fprintf(out, + "const static bool kStatsdEnabled = property_get_bool(\"ro.statsd.enable\", true);\n"); + fprintf(out, "#else\n"); + fprintf(out, "const static bool kStatsdEnabled = false;\n"); + fprintf(out, "#endif\n"); + + fprintf(out, "int64_t lastRetryTimestampNs = -1;\n"); + fprintf(out, "const int64_t kMinRetryIntervalNs = NS_PER_SEC * 60 * 20; // 20 minutes\n"); + fprintf(out, "static std::mutex mLogdRetryMutex;\n"); +} + +void write_native_try_stats_write_methods_q(FILE* out, const Atoms& atoms, + const AtomDecl& attributionDecl, const string& moduleName) { + fprintf(out, "\n"); + for (auto signature_to_modules_it = atoms.signatures_to_modules.begin(); + signature_to_modules_it != atoms.signatures_to_modules.end(); signature_to_modules_it++) { + if (!signature_needed_for_module(signature_to_modules_it->second, moduleName)) { + continue; + } + vector<java_type_t> signature = signature_to_modules_it->first; + + write_native_method_signature(out, "static int try_stats_write", signature, + attributionDecl, " {"); + + int argIndex = 1; + fprintf(out, " if (kStatsdEnabled) {\n"); + fprintf(out, " stats_event_list event(kStatsEventTag);\n"); + fprintf(out, " event << get_elapsed_realtime_ns();\n\n"); + fprintf(out, " event << code;\n\n"); + for (vector<java_type_t>::const_iterator arg = signature.begin(); + arg != signature.end(); arg++) { + if (*arg == JAVA_TYPE_ATTRIBUTION_CHAIN) { + for (const auto &chainField : attributionDecl.fields) { + if (chainField.javaType == JAVA_TYPE_STRING) { + fprintf(out, " if (%s_length != %s.size()) {\n", + attributionDecl.fields.front().name.c_str(), chainField.name.c_str()); + fprintf(out, " return -EINVAL;\n"); + fprintf(out, " }\n"); + } + } + fprintf(out, "\n event.begin();\n"); + fprintf(out, " for (size_t i = 0; i < %s_length; ++i) {\n", + attributionDecl.fields.front().name.c_str()); + fprintf(out, " event.begin();\n"); + for (const auto &chainField : attributionDecl.fields) { + if (chainField.javaType == JAVA_TYPE_STRING) { + fprintf(out, " if (%s[i] != NULL) {\n", chainField.name.c_str()); + fprintf(out, " event << %s[i];\n", chainField.name.c_str()); + fprintf(out, " } else {\n"); + fprintf(out, " event << \"\";\n"); + fprintf(out, " }\n"); + } else { + fprintf(out, " event << %s[i];\n", chainField.name.c_str()); + } + } + fprintf(out, " event.end();\n"); + fprintf(out, " }\n"); + fprintf(out, " event.end();\n\n"); + } else if (*arg == JAVA_TYPE_KEY_VALUE_PAIR) { + fprintf(out, " event.begin();\n\n"); + fprintf(out, " for (const auto& it : arg%d_1) {\n", argIndex); + fprintf(out, " event.begin();\n"); + fprintf(out, " event << it.first;\n"); + fprintf(out, " event << it.second;\n"); + fprintf(out, " event.end();\n"); + fprintf(out, " }\n"); + + fprintf(out, " for (const auto& it : arg%d_2) {\n", argIndex); + fprintf(out, " event.begin();\n"); + fprintf(out, " event << it.first;\n"); + fprintf(out, " event << it.second;\n"); + fprintf(out, " event.end();\n"); + fprintf(out, " }\n"); + + fprintf(out, " for (const auto& it : arg%d_3) {\n", argIndex); + fprintf(out, " event.begin();\n"); + fprintf(out, " event << it.first;\n"); + fprintf(out, " event << it.second;\n"); + fprintf(out, " event.end();\n"); + fprintf(out, " }\n"); + + fprintf(out, " for (const auto& it : arg%d_4) {\n", argIndex); + fprintf(out, " event.begin();\n"); + fprintf(out, " event << it.first;\n"); + fprintf(out, " event << it.second;\n"); + fprintf(out, " event.end();\n"); + fprintf(out, " }\n"); + + fprintf(out, " event.end();\n\n"); + } else if (*arg == JAVA_TYPE_BYTE_ARRAY) { + fprintf(out, + " event.AppendCharArray(arg%d.arg, " + "arg%d.arg_length);\n", + argIndex, argIndex); + } else { + if (*arg == JAVA_TYPE_STRING) { + fprintf(out, " if (arg%d == NULL) {\n", argIndex); + fprintf(out, " arg%d = \"\";\n", argIndex); + fprintf(out, " }\n"); + } + fprintf(out, " event << arg%d;\n", argIndex); + } + argIndex++; + } + + fprintf(out, " return event.write(LOG_ID_STATS);\n"); + fprintf(out, " } else {\n"); + fprintf(out, " return 1;\n"); + fprintf(out, " }\n"); + fprintf(out, "}\n"); + fprintf(out, "\n"); + } + +} + +void write_native_stats_write_methods_q(FILE* out, const string& methodName, const Atoms& atoms, + const AtomDecl& attributionDecl, const string& moduleName, const string& tryMethodName) { + for (auto signature_to_modules_it = atoms.signatures_to_modules.begin(); + signature_to_modules_it != atoms.signatures_to_modules.end(); + signature_to_modules_it++) { + if (!signature_needed_for_module(signature_to_modules_it->second, moduleName)) { + continue; + } + vector<java_type_t> signature = signature_to_modules_it->first; + + write_native_method_signature(out, methodName, signature, attributionDecl, " {"); + + write_native_stats_write_body_q(out, signature, attributionDecl, " ", tryMethodName); + fprintf(out, "}\n\n"); + } +} + +void write_native_stats_write_non_chained_methods_q(FILE* out, const string& methodName, + const Atoms& atoms, const AtomDecl& attributionDecl, const string& moduleName, + const string& tryMethodName) { + for (auto signature_it = atoms.non_chained_signatures_to_modules.begin(); + signature_it != atoms.non_chained_signatures_to_modules.end(); signature_it++) { + if (!signature_needed_for_module(signature_it->second, moduleName)) { + continue; + } + vector<java_type_t> signature = signature_it->first; + + write_native_method_signature(out, methodName, signature, attributionDecl, " {"); + + write_native_stats_write_body_q(out, signature, attributionDecl, " ", tryMethodName); + fprintf(out, "}\n\n"); + } +} + +void write_native_try_stats_write_non_chained_methods_q(FILE* out, const Atoms& atoms, + const AtomDecl& attributionDecl, const string& moduleName) { + for (auto signature_it = atoms.non_chained_signatures_to_modules.begin(); + signature_it != atoms.non_chained_signatures_to_modules.end(); signature_it++) { + if (!signature_needed_for_module(signature_it->second, moduleName)) { + continue; + } + vector<java_type_t> signature = signature_it->first; + + write_native_method_signature(out, "static int try_stats_write_non_chained", signature, + attributionDecl, " {"); + + int argIndex = 1; + fprintf(out, " if (kStatsdEnabled) {\n"); + fprintf(out, " stats_event_list event(kStatsEventTag);\n"); + fprintf(out, " event << get_elapsed_realtime_ns();\n\n"); + fprintf(out, " event << code;\n\n"); + for (vector<java_type_t>::const_iterator arg = signature.begin(); + arg != signature.end(); arg++) { + if (argIndex == 1) { + fprintf(out, " event.begin();\n\n"); + fprintf(out, " event.begin();\n"); + } + if (*arg == JAVA_TYPE_STRING) { + fprintf(out, " if (arg%d == NULL) {\n", argIndex); + fprintf(out, " arg%d = \"\";\n", argIndex); + fprintf(out, " }\n"); + } + if (*arg == JAVA_TYPE_BYTE_ARRAY) { + fprintf(out, + " event.AppendCharArray(arg%d.arg, " + "arg%d.arg_length);\n", + argIndex, argIndex); + } else { + fprintf(out, " event << arg%d;\n", argIndex); + } + if (argIndex == 2) { + fprintf(out, " event.end();\n\n"); + fprintf(out, " event.end();\n\n"); + } + argIndex++; + } + + fprintf(out, " return event.write(LOG_ID_STATS);\n"); + fprintf(out, " } else {\n"); + fprintf(out, " return 1;\n"); + fprintf(out, " }\n"); + fprintf(out, "}\n"); + fprintf(out, "\n"); + } +} + +} // namespace stats_log_api_gen +} // namespace android diff --git a/tools/stats_log_api_gen/native_writer_q.h b/tools/stats_log_api_gen/native_writer_q.h new file mode 100644 index 000000000000..a2ab1ae5d5e2 --- /dev/null +++ b/tools/stats_log_api_gen/native_writer_q.h @@ -0,0 +1,49 @@ +/* + * 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 "Collation.h" + +#include <stdio.h> +#include <string.h> + +namespace android { +namespace stats_log_api_gen { + +using namespace std; + +void write_native_cpp_includes_q(FILE* out); + +void write_native_stats_log_cpp_globals_q(FILE* out); + +void write_native_try_stats_write_methods_q(FILE* out, const Atoms& atoms, + const AtomDecl& attributionDecl, const string& moduleName); + +void write_native_stats_write_methods_q(FILE* out, const string& methodName, const Atoms& atoms, + const AtomDecl& attributionDecl, const string& moduleName, const string& tryMethodName); + +void write_native_try_stats_write_non_chained_methods_q(FILE* out, const Atoms& atoms, + const AtomDecl& attributionDecl, const string& moduleName); + +void write_native_stats_write_non_chained_methods_q(FILE* out, const string& methodName, + const Atoms& atoms, const AtomDecl& attributionDecl, const string& moduleName, + const string& tryMethodName); + +void write_native_get_timestamp_ns_q(FILE* out); + +} // 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 new file mode 100644 index 000000000000..5b830eef0603 --- /dev/null +++ b/tools/stats_log_api_gen/utils.cpp @@ -0,0 +1,487 @@ +/* + * 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, set<AtomDecl>::const_iterator>* decl_map) { + for (set<AtomDecl>::const_iterator atom = atoms.non_chained_decls.begin(); + atom != atoms.non_chained_decls.end(); atom++) { + decl_map->insert(std::make_pair(atom->code, atom)); + } +} + +/** + * 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"; + } +} + +bool atom_needed_for_module(const AtomDecl& atomDecl, const string& moduleName) { + if (moduleName == DEFAULT_MODULE_NAME) { + return true; + } + return atomDecl.hasModule && (moduleName == atomDecl.moduleName); +} + +bool signature_needed_for_module(const set<string>& modules, const string& moduleName) { + if (moduleName == DEFAULT_MODULE_NAME) { + return true; + } + return modules.find(moduleName) != modules.end(); +} + +// 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 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, + const string& moduleName) { + fprintf(out, "/**\n"); + fprintf(out, " * Constants for atom codes.\n"); + fprintf(out, " */\n"); + fprintf(out, "enum {\n"); + + std::map<int, set<AtomDecl>::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 (set<AtomDecl>::const_iterator atom = atoms.decls.begin(); + atom != atoms.decls.end(); atom++) { + // Skip if the atom is not needed for the module. + if (!atom_needed_for_module(*atom, moduleName)) { + continue; + } + string constant = make_constant_name(atom->name); + fprintf(out, "\n"); + fprintf(out, " /**\n"); + fprintf(out, " * %s %s\n", atom->message.c_str(), atom->name.c_str()); + write_cpp_usage(out, "stats_write", constant, *atom, attributionDecl); + + auto non_chained_decl = atom_code_to_non_chained_decl_map.find(atom->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(), atom->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, const string& moduleName) { + fprintf(out, " // Constants for atom codes.\n"); + + std::map<int, set<AtomDecl>::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 (set<AtomDecl>::const_iterator atom = atoms.decls.begin(); + atom != atoms.decls.end(); atom++) { + // Skip if the atom is not needed for the module. + if (!atom_needed_for_module(*atom, moduleName)) { + continue; + } + string constant = make_constant_name(atom->name); + fprintf(out, "\n"); + fprintf(out, " /**\n"); + fprintf(out, " * %s %s<br>\n", atom->message.c_str(), atom->name.c_str()); + write_java_usage(out, "write", constant, *atom); + auto non_chained_decl = atom_code_to_non_chained_decl_map.find(atom->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); + } + if (moduleName == DEFAULT_MODULE_NAME) { + fprintf(out, " * @hide\n"); + } + fprintf(out, " */\n"); + fprintf(out, " public static final int %s = %d;\n", constant.c_str(), atom->code); + } + fprintf(out, "\n"); +} + +void write_java_enum_values(FILE* out, const Atoms& atoms, const string& moduleName) { + fprintf(out, " // Constants for enum values.\n\n"); + for (set<AtomDecl>::const_iterator atom = atoms.decls.begin(); + atom != atoms.decls.end(); atom++) { + // Skip if the atom is not needed for the module. + if (!atom_needed_for_module(*atom, moduleName)) { + continue; + } + for (vector<AtomField>::const_iterator field = atom->fields.begin(); + field != atom->fields.end(); field++) { + if (field->javaType == JAVA_TYPE_ENUM) { + fprintf(out, " // Values for %s.%s\n", atom->message.c_str(), + field->name.c_str()); + for (map<int, string>::const_iterator value = field->enumValues.begin(); + value != field->enumValues.end(); value++) { + if (moduleName == DEFAULT_MODULE_NAME) { + fprintf(out, " /** @hide */\n"); + } + fprintf(out, " public static final int %s__%s__%s = %d;\n", + make_constant_name(atom->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, ", 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 map<vector<java_type_t>, set<string>>& signatures_to_modules, + const string& moduleName + ) { + for (auto signature_to_modules_it = signatures_to_modules.begin(); + signature_to_modules_it != signatures_to_modules.end(); signature_to_modules_it++) { + // Skip if this signature is not needed for the module. + if (!signature_needed_for_module(signature_to_modules_it->second, moduleName)) { + continue; + } + + // Print method signature. + if (DEFAULT_MODULE_NAME == moduleName) { + fprintf(out, " /** @hide */\n"); + } + fprintf(out, " public static void write_non_chained(int code"); + vector<java_type_t> signature = signature_to_modules_it->first; + int argIndex = 1; + for (vector<java_type_t>::const_iterator arg = signature.begin(); + arg != signature.end(); arg++) { + if (*arg == JAVA_TYPE_ATTRIBUTION_CHAIN) { + // Non chained signatures should not have attribution chains. + return 1; + } else if (*arg == JAVA_TYPE_KEY_VALUE_PAIR) { + // Module logging does not yet support key value pair. + 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 map<vector<java_type_t>, set<string>>& signatures_to_modules, + const string& moduleName + ) { + fprintf(out, " // WorkSource methods.\n"); + for (auto signature_to_modules_it = signatures_to_modules.begin(); + signature_to_modules_it != signatures_to_modules.end(); signature_to_modules_it++) { + // Skip if this signature is not needed for the module. + if (!signature_needed_for_module(signature_to_modules_it->second, moduleName)) { + continue; + } + vector<java_type_t> signature = signature_to_modules_it->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) + if (DEFAULT_MODULE_NAME == moduleName) { + fprintf(out, " /** @hide */\n"); + } + 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, ", 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.get(i), ws.getName(i)"); + } else { + fprintf(out, ", arg%d", argIndex); + } + } + fprintf(out, ");\n"); + fprintf(out, " }\n"); // close for-loop + + // write() component. + fprintf(out, " ArrayList<WorkSource.WorkChain> workChains = ws.getWorkChains();\n"); + fprintf(out, " if (workChains != null) {\n"); + fprintf(out, " for (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 new file mode 100644 index 000000000000..50737a68bf89 --- /dev/null +++ b/tools/stats_log_api_gen/utils.h @@ -0,0 +1,86 @@ +/* + * 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 "Collation.h" + +#include <map> +#include <set> +#include <vector> + +#include <stdio.h> +#include <string.h> + +namespace android { +namespace stats_log_api_gen { + +using namespace std; + +const string DEFAULT_MODULE_NAME = "DEFAULT"; +const string DEFAULT_CPP_NAMESPACE = "android,util"; +const string DEFAULT_CPP_HEADER_IMPORT = "statslog.h"; +const string DEFAULT_ATOMS_INFO_CPP_HEADER_IMPORT = "atoms_info.h"; +const string DEFAULT_JAVA_PACKAGE = "android.util"; +const string DEFAULT_JAVA_CLASS = "StatsLogInternal"; + +const int JAVA_MODULE_REQUIRES_FLOAT = 0x01; +const int JAVA_MODULE_REQUIRES_ATTRIBUTION = 0x02; + +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); + +bool atom_needed_for_module(const AtomDecl& atomDecl, const string& moduleName); + +bool signature_needed_for_module(const set<string>& modules, const string& moduleName); + +// 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, + const string& moduleName); + +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, const string& moduleName); + +void write_java_enum_values(FILE* out, const Atoms& atoms, const string& moduleName); + +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 map<vector<java_type_t>, + set<string>>& signatures_to_modules, + const string& moduleName); + +int write_java_work_source_methods( + FILE* out, + const map<vector<java_type_t>, set<string>>& signatures_to_modules, + const string& moduleName); + +} // namespace stats_log_api_gen +} // namespace android diff --git a/wifi/java/android/net/wifi/ScanResult.java b/wifi/java/android/net/wifi/ScanResult.java index c0c0361dd92f..2901bd8cbb48 100644 --- a/wifi/java/android/net/wifi/ScanResult.java +++ b/wifi/java/android/net/wifi/ScanResult.java @@ -17,7 +17,7 @@ package android.net.wifi; import android.annotation.SystemApi; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.os.Parcel; import android.os.Parcelable; diff --git a/wifi/java/android/net/wifi/WifiConfiguration.java b/wifi/java/android/net/wifi/WifiConfiguration.java index ed416429a279..933dded815b9 100644 --- a/wifi/java/android/net/wifi/WifiConfiguration.java +++ b/wifi/java/android/net/wifi/WifiConfiguration.java @@ -19,7 +19,7 @@ package android.net.wifi; import android.annotation.IntDef; import android.annotation.NonNull; import android.annotation.SystemApi; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.pm.PackageManager; import android.net.IpConfiguration; import android.net.IpConfiguration.ProxySettings; diff --git a/wifi/java/android/net/wifi/WifiEnterpriseConfig.java b/wifi/java/android/net/wifi/WifiEnterpriseConfig.java index 9d4b837ce2d1..a9c2eb57291a 100644 --- a/wifi/java/android/net/wifi/WifiEnterpriseConfig.java +++ b/wifi/java/android/net/wifi/WifiEnterpriseConfig.java @@ -16,7 +16,7 @@ package android.net.wifi; import android.annotation.Nullable; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.os.Parcel; import android.os.Parcelable; import android.security.Credentials; diff --git a/wifi/java/android/net/wifi/WifiInfo.java b/wifi/java/android/net/wifi/WifiInfo.java index 0b557942c87b..8bad71ba747b 100644 --- a/wifi/java/android/net/wifi/WifiInfo.java +++ b/wifi/java/android/net/wifi/WifiInfo.java @@ -19,7 +19,7 @@ package android.net.wifi; import android.annotation.IntRange; import android.annotation.Nullable; import android.annotation.SystemApi; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.net.NetworkInfo.DetailedState; import android.net.NetworkUtils; import android.os.Build; diff --git a/wifi/java/android/net/wifi/WifiManager.java b/wifi/java/android/net/wifi/WifiManager.java index 671b3c715012..f85bb5f8ad59 100644 --- a/wifi/java/android/net/wifi/WifiManager.java +++ b/wifi/java/android/net/wifi/WifiManager.java @@ -29,8 +29,8 @@ import android.annotation.SdkConstant; import android.annotation.SdkConstant.SdkConstantType; import android.annotation.SystemApi; import android.annotation.SystemService; -import android.annotation.UnsupportedAppUsage; import android.app.ActivityManager; +import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; import android.content.pm.ParceledListSlice; import android.net.ConnectivityManager; diff --git a/wifi/java/android/net/wifi/WifiSsid.java b/wifi/java/android/net/wifi/WifiSsid.java index f187e1042c58..a591f312028e 100644 --- a/wifi/java/android/net/wifi/WifiSsid.java +++ b/wifi/java/android/net/wifi/WifiSsid.java @@ -16,7 +16,7 @@ package android.net.wifi; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.os.Parcel; import android.os.Parcelable; diff --git a/wifi/java/android/net/wifi/p2p/WifiP2pConfig.java b/wifi/java/android/net/wifi/p2p/WifiP2pConfig.java index c3cfb0266328..b0ea7202b7ba 100644 --- a/wifi/java/android/net/wifi/p2p/WifiP2pConfig.java +++ b/wifi/java/android/net/wifi/p2p/WifiP2pConfig.java @@ -19,7 +19,7 @@ package android.net.wifi.p2p; import android.annotation.IntDef; import android.annotation.NonNull; import android.annotation.Nullable; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.net.MacAddress; import android.net.wifi.WpsInfo; import android.os.Parcel; diff --git a/wifi/java/android/net/wifi/p2p/WifiP2pDevice.java b/wifi/java/android/net/wifi/p2p/WifiP2pDevice.java index c5318a9e275a..69aefcce4f5b 100644 --- a/wifi/java/android/net/wifi/p2p/WifiP2pDevice.java +++ b/wifi/java/android/net/wifi/p2p/WifiP2pDevice.java @@ -16,7 +16,7 @@ package android.net.wifi.p2p; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.os.Parcel; import android.os.Parcelable; import android.util.Log; diff --git a/wifi/java/android/net/wifi/p2p/WifiP2pDeviceList.java b/wifi/java/android/net/wifi/p2p/WifiP2pDeviceList.java index acf06fbac681..ededf67fec7f 100644 --- a/wifi/java/android/net/wifi/p2p/WifiP2pDeviceList.java +++ b/wifi/java/android/net/wifi/p2p/WifiP2pDeviceList.java @@ -16,10 +16,9 @@ package android.net.wifi.p2p; -import android.annotation.UnsupportedAppUsage; -import android.os.Parcelable; +import android.compat.annotation.UnsupportedAppUsage; import android.os.Parcel; -import android.net.wifi.p2p.WifiP2pDevice; +import android.os.Parcelable; import android.text.TextUtils; import java.util.ArrayList; diff --git a/wifi/java/android/net/wifi/p2p/WifiP2pGroup.java b/wifi/java/android/net/wifi/p2p/WifiP2pGroup.java index 4866bd4b2ce9..b292da193a89 100644 --- a/wifi/java/android/net/wifi/p2p/WifiP2pGroup.java +++ b/wifi/java/android/net/wifi/p2p/WifiP2pGroup.java @@ -16,7 +16,7 @@ package android.net.wifi.p2p; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.os.Parcel; import android.os.Parcelable; diff --git a/wifi/java/android/net/wifi/p2p/WifiP2pGroupList.java b/wifi/java/android/net/wifi/p2p/WifiP2pGroupList.java index 62524d9c2bd6..6068d3a2f697 100644 --- a/wifi/java/android/net/wifi/p2p/WifiP2pGroupList.java +++ b/wifi/java/android/net/wifi/p2p/WifiP2pGroupList.java @@ -15,14 +15,14 @@ */ package android.net.wifi.p2p; -import java.util.Collection; -import java.util.Map; - -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.os.Parcel; import android.os.Parcelable; import android.util.LruCache; +import java.util.Collection; +import java.util.Map; + /** * A class representing a Wi-Fi P2p group list diff --git a/wifi/java/android/net/wifi/p2p/WifiP2pManager.java b/wifi/java/android/net/wifi/p2p/WifiP2pManager.java index d37c4a2e78db..eec4a0007d8e 100644 --- a/wifi/java/android/net/wifi/p2p/WifiP2pManager.java +++ b/wifi/java/android/net/wifi/p2p/WifiP2pManager.java @@ -23,7 +23,7 @@ import android.annotation.RequiresPermission; import android.annotation.SdkConstant; import android.annotation.SdkConstant.SdkConstantType; import android.annotation.SystemService; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; import android.net.NetworkInfo; import android.net.wifi.WpsInfo; diff --git a/wifi/java/android/net/wifi/p2p/WifiP2pProvDiscEvent.java b/wifi/java/android/net/wifi/p2p/WifiP2pProvDiscEvent.java index 153e03cc4d9d..d0fe92d5249d 100644 --- a/wifi/java/android/net/wifi/p2p/WifiP2pProvDiscEvent.java +++ b/wifi/java/android/net/wifi/p2p/WifiP2pProvDiscEvent.java @@ -16,7 +16,7 @@ package android.net.wifi.p2p; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; /** * A class representing a Wi-Fi p2p provisional discovery request/response diff --git a/wifi/java/android/net/wifi/p2p/WifiP2pWfdInfo.java b/wifi/java/android/net/wifi/p2p/WifiP2pWfdInfo.java index 3caa280ef62a..7a5f909f93ae 100644 --- a/wifi/java/android/net/wifi/p2p/WifiP2pWfdInfo.java +++ b/wifi/java/android/net/wifi/p2p/WifiP2pWfdInfo.java @@ -16,10 +16,10 @@ package android.net.wifi.p2p; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.os.Build; -import android.os.Parcelable; import android.os.Parcel; +import android.os.Parcelable; import java.util.Locale; diff --git a/wifi/java/android/net/wifi/p2p/nsd/WifiP2pDnsSdServiceInfo.java b/wifi/java/android/net/wifi/p2p/nsd/WifiP2pDnsSdServiceInfo.java index e32c8e80ad1c..0de7ba6439eb 100644 --- a/wifi/java/android/net/wifi/p2p/nsd/WifiP2pDnsSdServiceInfo.java +++ b/wifi/java/android/net/wifi/p2p/nsd/WifiP2pDnsSdServiceInfo.java @@ -16,7 +16,7 @@ package android.net.wifi.p2p.nsd; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.net.nsd.DnsSdTxtRecord; import android.os.Build; import android.text.TextUtils; diff --git a/wifi/java/android/net/wifi/p2p/nsd/WifiP2pServiceInfo.java b/wifi/java/android/net/wifi/p2p/nsd/WifiP2pServiceInfo.java index db0bdb81fef3..37b442baeb3f 100644 --- a/wifi/java/android/net/wifi/p2p/nsd/WifiP2pServiceInfo.java +++ b/wifi/java/android/net/wifi/p2p/nsd/WifiP2pServiceInfo.java @@ -16,7 +16,7 @@ package android.net.wifi.p2p.nsd; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.os.Build; import android.os.Parcel; import android.os.Parcelable; diff --git a/wifi/java/android/net/wifi/p2p/nsd/WifiP2pServiceRequest.java b/wifi/java/android/net/wifi/p2p/nsd/WifiP2pServiceRequest.java index 87528c4180af..68cbb88037b0 100644 --- a/wifi/java/android/net/wifi/p2p/nsd/WifiP2pServiceRequest.java +++ b/wifi/java/android/net/wifi/p2p/nsd/WifiP2pServiceRequest.java @@ -16,7 +16,7 @@ package android.net.wifi.p2p.nsd; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.net.wifi.p2p.WifiP2pManager; import android.os.Build; import android.os.Parcel; |