diff options
229 files changed, 10651 insertions, 1935 deletions
diff --git a/Android.bp b/Android.bp index 0b0a9b7b8455..084c9f51d12e 100644 --- a/Android.bp +++ b/Android.bp @@ -252,42 +252,6 @@ java_library { installable: false, } -filegroup { - name: "framework-jarjar-rules", - srcs: ["framework-jarjar-rules.txt"], -} - -filegroup { - name: "libincident_aidl", - srcs: [ - "core/java/android/os/IIncidentDumpCallback.aidl", - "core/java/android/os/IIncidentManager.aidl", - "core/java/android/os/IIncidentReportStatusListener.aidl", - ], - path: "core/java", -} - -filegroup { - name: "libvibrator_aidl", - srcs: [ - "core/java/android/os/IExternalVibrationController.aidl", - "core/java/android/os/IExternalVibratorService.aidl", - ], - path: "core/java", -} - -filegroup { - name: "libpowermanager_aidl", - srcs: [ - "core/java/android/os/Temperature.aidl", - "core/java/android/os/CoolingDevice.aidl", - "core/java/android/os/IThermalEventListener.aidl", - "core/java/android/os/IThermalStatusListener.aidl", - "core/java/android/os/IThermalService.aidl", - ], - path: "core/java", -} - java_library { name: "framework-minus-apex", defaults: ["framework-aidl-export-defaults"], @@ -304,7 +268,7 @@ java_library { "--multi-dex", ], installable: true, - jarjar_rules: ":framework-jarjar-rules", + jarjar_rules: "framework-jarjar-rules.txt", javac_shard_size: 150, plugins: [ "view-inspector-annotation-processor", @@ -376,84 +340,6 @@ platform_compat_config { src: ":framework-minus-apex", } -genrule { - name: "statslog-framework-java-gen", - tools: ["stats-log-api-gen"], - cmd: "$(location stats-log-api-gen) --java $(out) --module framework" + - " --javaPackage com.android.internal.util --javaClass FrameworkStatsLog --worksource", - out: ["com/android/internal/util/FrameworkStatsLog.java"], -} - -java_library { - name: "uieventloggerlib", - srcs: [ - "core/java/com/android/internal/logging/UiEvent.java", - "core/java/com/android/internal/logging/UiEventLogger.java", - "core/java/com/android/internal/logging/UiEventLoggerImpl.java", - "core/java/com/android/internal/logging/InstanceId.java", - "core/java/com/android/internal/logging/InstanceIdSequence.java", - ":statslog-framework-java-gen", - ], -} - -gensrcs { - name: "framework-javastream-protos", - depfile: true, - - tools: [ - "aprotoc", - "protoc-gen-javastream", - "soong_zip", - ], - - cmd: "mkdir -p $(genDir)/$(in) " + - "&& $(location aprotoc) " + - " --plugin=$(location protoc-gen-javastream) " + - " --dependency_out=$(depfile) " + - " --javastream_out=$(genDir)/$(in) " + - " -Iexternal/protobuf/src " + - " -I . " + - " $(in) " + - "&& $(location soong_zip) -jar -o $(out) -C $(genDir)/$(in) -D $(genDir)/$(in)", - - srcs: [ - ":ipconnectivity-proto-src", - ":libstats_atom_enum_protos", - ":libtombstone_proto-src", - "core/proto/**/*.proto", - "libs/incident/**/*.proto", - ], - output_extension: "srcjar", -} - -gensrcs { - name: "framework-cppstream-protos", - depfile: true, - - tools: [ - "aprotoc", - "protoc-gen-cppstream", - ], - - cmd: "mkdir -p $(genDir) " + - "&& $(location aprotoc) " + - " --plugin=$(location protoc-gen-cppstream) " + - " --dependency_out=$(depfile) " + - " --cppstream_out=$(genDir) " + - " -Iexternal/protobuf/src " + - " -I . " + - " $(in)", - - srcs: [ - ":ipconnectivity-proto-src", - ":libstats_atom_enum_protos", - "core/proto/**/*.proto", - "libs/incident/**/*.proto", - ], - - output_extension: "proto.h", -} - filegroup { name: "framework-annotations", srcs: [ @@ -528,30 +414,6 @@ filegroup { ], } -filegroup { - name: "framework-services-net-module-wifi-shared-srcs", - srcs: [ - "core/java/android/net/DhcpResults.java", - "core/java/android/util/LocalLog.java", - ], -} - -// keep these files in sync with the package/Tethering/jarjar-rules.txt and -// package/Connectivity/jarjar-rules.txt for the tethering module and connectivity module. -filegroup { - name: "framework-connectivity-shared-srcs", - srcs: [ - "core/java/android/util/LocalLog.java", - // This should be android.util.IndentingPrintWriter, but it's not available in all branches. - "core/java/com/android/internal/util/IndentingPrintWriter.java", - "core/java/com/android/internal/util/IState.java", - "core/java/com/android/internal/util/MessageUtils.java", - "core/java/com/android/internal/util/State.java", - "core/java/com/android/internal/util/StateMachine.java", - "core/java/com/android/internal/util/WakeupMessage.java", - ], -} - // Build ext.jar // ============================================================ java_library { @@ -566,371 +428,6 @@ java_library { dxflags: ["--core-library"], } -// ==== java proto host library ============================== -java_library_host { - name: "platformprotos", - srcs: [ - ":ipconnectivity-proto-src", - ":libstats_atom_enum_protos", - ":libstats_internal_protos", - ":statsd_internal_protos", - "cmds/am/proto/instrumentation_data.proto", - "cmds/statsd/src/**/*.proto", - "core/proto/**/*.proto", - "libs/incident/proto/**/*.proto", - ], - proto: { - include_dirs: [ - "external/protobuf/src", - "frameworks/proto_logging/stats", - ], - type: "full", - }, - errorprone: { - javacflags: ["-Xep:MissingOverride:OFF"], // b/72714520 - }, -} - -// ==== java proto device library (for test only) ============================== -java_library { - name: "platformprotosnano", - proto: { - type: "nano", - output_params: ["store_unknown_fields=true"], - include_dirs: ["external/protobuf/src"], - }, - exclude_srcs: [ - "core/proto/android/privacy.proto", - "core/proto/android/section.proto", - ], - sdk_version: "9", - srcs: [ - ":ipconnectivity-proto-src", - ":libstats_atom_enum_protos", - "core/proto/**/*.proto", - "libs/incident/proto/android/os/**/*.proto", - ], -} - -// ==== java proto device library (for test only) ============================== -java_library { - name: "platformprotoslite", - proto: { - type: "lite", - include_dirs: ["external/protobuf/src"], - }, - - srcs: [ - ":ipconnectivity-proto-src", - ":libstats_atom_enum_protos", - "core/proto/**/*.proto", - "libs/incident/proto/android/os/**/*.proto", - ], - exclude_srcs: [ - "core/proto/android/privacy.proto", - "core/proto/android/section.proto", - ], - sdk_version: "core_current", - // Protos have lots of MissingOverride and similar. - errorprone: { - javacflags: ["-XepDisableAllChecks"], - }, -} - -// ==== c++ proto device library ============================== -cc_defaults { - name: "libplatformprotos-defaults", - - proto: { - export_proto_headers: true, - include_dirs: [ - "external/protobuf/src", - ], - }, - - cflags: [ - "-Wall", - "-Werror", - "-Wno-unused-parameter", - ], - - srcs: [ - ":ipconnectivity-proto-src", - ":libstats_atom_enum_protos", - "core/proto/**/*.proto", - ], -} - -cc_library { - name: "libplatformprotos", - defaults: ["libplatformprotos-defaults"], - host_supported: true, - - target: { - host: { - proto: { - type: "full", - }, - }, - android: { - proto: { - type: "lite", - }, - shared_libs: [ - "libprotobuf-cpp-lite", - ], - shared: { - enabled: false, - }, - }, - }, -} - -// This library is meant for vendor code that needs to output protobuf. It links -// against the static version of libprotobuf-cpp-lite, for which we can not guarantee -// binary compatibility. -cc_library { - name: "libplatformprotos-static", - defaults: ["libplatformprotos-defaults"], - host_supported: false, - - // This is okay because this library is only built as a static library. The C++ - // API is not guaranteed. The proto API is guaranteed to be stable via Metrics Council, - // but is not authorized to be used outside of debugging. - vendor_available: true, - - target: { - android: { - proto: { - type: "lite", - }, - static_libs: [ - "libprotobuf-cpp-lite", - ], - shared: { - enabled: false, - }, - }, - }, -} - -// This is the full proto version of libplatformprotos. It may only -// be used by test code that is not shipped on the device. -cc_library { - name: "libplatformprotos-test", - defaults: ["libplatformprotos-defaults"], - host_supported: false, - - target: { - android: { - proto: { - type: "full", - }, - shared: { - enabled: false, - }, - }, - }, -} - -filegroup { - name: "incremental_aidl", - srcs: [ - "core/java/android/os/incremental/IIncrementalServiceConnector.aidl", - "core/java/android/os/incremental/IncrementalFileSystemControlParcel.aidl", - ], - path: "core/java", -} - -filegroup { - name: "dataloader_aidl", - srcs: [ - "core/java/android/content/pm/DataLoaderParamsParcel.aidl", - "core/java/android/content/pm/DataLoaderType.aidl", - "core/java/android/content/pm/FileSystemControlParcel.aidl", - "core/java/android/content/pm/IDataLoader.aidl", - "core/java/android/content/pm/IDataLoaderManager.aidl", - "core/java/android/content/pm/InstallationFileParcel.aidl", - "core/java/android/content/pm/InstallationFileLocation.aidl", - "core/java/android/content/pm/IDataLoaderStatusListener.aidl", - "core/java/android/content/pm/IPackageInstallerSessionFileSystemConnector.aidl", - ], - path: "core/java", -} - -filegroup { - name: "incremental_manager_aidl", - srcs: [ - "core/java/android/os/incremental/IIncrementalService.aidl", - "core/java/android/os/incremental/IncrementalNewFileParams.aidl", - "core/java/android/os/incremental/IStorageHealthListener.aidl", - "core/java/android/os/incremental/StorageHealthCheckParams.aidl", - ], - path: "core/java", -} - -filegroup { - name: "activity_manager_procstate_aidl", - srcs: [ - // internal only - ], - path: "core/java", -} - -aidl_interface { - name: "libincremental_aidl", - unstable: true, - srcs: [ - ":incremental_aidl", - ], - backend: { - java: { - sdk_version: "28", - }, - cpp: { - enabled: true, - }, - ndk: { - enabled: true, - }, - }, -} - -aidl_interface { - name: "libdataloader_aidl", - unstable: true, - srcs: [ - ":dataloader_aidl", - ], - imports: [ - "libincremental_aidl", - ], - backend: { - java: { - sdk_version: "28", - }, - cpp: { - enabled: true, - }, - ndk: { - enabled: false, - }, - }, -} - -aidl_interface { - name: "libincremental_manager_aidl", - unstable: true, - srcs: [ - ":incremental_manager_aidl", - ], - imports: [ - "libincremental_aidl", - "libdataloader_aidl", - ], - backend: { - java: { - sdk_version: "28", - }, - cpp: { - enabled: true, - }, - ndk: { - enabled: false, - }, - }, -} - -// Build Rust bindings for PermissionController. Needed by keystore2. -aidl_interface { - name: "android.os.permissions_aidl", - unstable: true, - local_include_dir: "core/java", - srcs: [ - "core/java/android/os/IPermissionController.aidl", - ], - backend: { - rust: { - enabled: true, - }, - }, -} - -python_defaults { - name: "base_default", - version: { - py2: { - enabled: false, - embedded_launcher: false, - }, - py3: { - enabled: true, - embedded_launcher: true, - }, - }, -} - -python_binary_host { - name: "fontchain_linter", - defaults: ["base_default"], - main: "tools/fonts/fontchain_linter.py", - srcs: [ - "tools/fonts/fontchain_linter.py", - ], - libs: [ - "fontTools", - ], -} - -// Avoid including Parcelable classes as we don't want to have two copies of -// Parcelable cross the libraries. This is used by telephony-common (frameworks/opt/telephony) -// and TeleService app (packages/services/Telephony). -filegroup { - name: "framework-telephony-common-shared-srcs", - srcs: [ - "core/java/android/os/RegistrantList.java", - "core/java/android/os/Registrant.java", - "core/java/android/util/LocalLog.java", - "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", - "core/java/com/android/internal/util/IState.java", - "core/java/com/android/internal/util/IndentingPrintWriter.java", - "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/UserIcons.java", - ], -} - -// Avoid including Parcelable classes as we don't want to have two copies of -// Parcelable cross the process. -filegroup { - name: "framework-cellbroadcast-shared-srcs", - srcs: [ - "core/java/android/os/HandlerExecutor.java", - "core/java/android/util/LocalLog.java", - "core/java/com/android/internal/util/IState.java", - "core/java/com/android/internal/util/Preconditions.java", - "core/java/com/android/internal/util/State.java", - "core/java/com/android/internal/util/StateMachine.java", - ], -} - -filegroup { - name: "framework-ims-common-shared-srcs", - srcs: [ - "core/java/android/os/RegistrantList.java", - "core/java/android/os/Registrant.java", - "core/java/com/android/internal/os/SomeArgs.java", - "core/java/com/android/internal/util/Preconditions.java", - ], -} - // utility classes statically linked into framework-wifi and dynamically linked // into wifi-service java_library { @@ -959,33 +456,6 @@ java_library { ], } -filegroup { - name: "framework-wifi-util-lib-aidls", - srcs: ["core/java/android/content/pm/ParceledListSlice.aidl"], - path: "core/java", -} - -// utility classes statically linked into wifi-service -filegroup { - name: "framework-wifi-service-shared-srcs", - srcs: [ - "core/java/android/net/InterfaceConfiguration.java", - "core/java/android/util/BackupUtils.java", - "core/java/android/util/Rational.java", - "core/java/com/android/internal/util/FastXmlSerializer.java", - "core/java/com/android/internal/util/HexDump.java", - "core/java/com/android/internal/util/IState.java", - "core/java/com/android/internal/util/MessageUtils.java", - "core/java/com/android/internal/util/State.java", - "core/java/com/android/internal/util/StateMachine.java", - "core/java/com/android/internal/util/WakeupMessage.java", - ], - visibility: [ - "//frameworks/opt/net/wifi/service", - "//packages/modules/Wifi/service", - ], -} - // TODO(b/145644363): move this to under StubLibraries.bp or ApiDocs.bp metalava_framework_docs_args = "--manifest $(location core/res/AndroidManifest.xml) " + "--hide-package com.android.server " + @@ -1019,4 +489,5 @@ filegroup { build = [ "StubLibraries.bp", "ApiDocs.bp", + "ProtoLibraries.bp", ] @@ -30,3 +30,4 @@ per-file Android.bp = file:platform/build/soong:/OWNERS per-file Android.mk = file:platform/build/soong:/OWNERS per-file ApiDocs.bp = file:platform/build/soong:/OWNERS per-file StubLibraries.bp = file:platform/build/soong:/OWNERS +per-file ProtoLibraries.bp = file:platform/build/soong:/OWNERS diff --git a/PREUPLOAD.cfg b/PREUPLOAD.cfg index 2fd2e33bbc37..f67174ac1e1a 100644 --- a/PREUPLOAD.cfg +++ b/PREUPLOAD.cfg @@ -1,5 +1,6 @@ [Builtin Hooks] clang_format = true +bpfmt = true [Builtin Hooks Options] # Only turn on clang-format check for the following subfolders. @@ -16,7 +17,7 @@ checkstyle_hook = ${REPO_ROOT}/prebuilts/checkstyle/checkstyle.py --sha ${PREUPL strings_lint_hook = ${REPO_ROOT}/frameworks/base/tools/stringslint/stringslint_sha.sh ${PREUPLOAD_COMMIT} -hidden_api_txt_checksorted_hook = ${REPO_ROOT}/frameworks/base/tools/hiddenapi/checksorted_sha.sh ${PREUPLOAD_COMMIT} ${REPO_ROOT} +hidden_api_txt_checksorted_hook = ${REPO_ROOT}/tools/platform-compat/hiddenapi/checksorted_sha.sh ${PREUPLOAD_COMMIT} ${REPO_ROOT} hidden_api_txt_exclude_hook = ${REPO_ROOT}/frameworks/base/tools/hiddenapi/exclude.sh ${PREUPLOAD_COMMIT} ${REPO_ROOT} diff --git a/ProtoLibraries.bp b/ProtoLibraries.bp new file mode 100644 index 000000000000..c127449fce37 --- /dev/null +++ b/ProtoLibraries.bp @@ -0,0 +1,238 @@ +// Copyright (C) 2021 The Android Open Source Project +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +gensrcs { + name: "framework-javastream-protos", + depfile: true, + + tools: [ + "aprotoc", + "protoc-gen-javastream", + "soong_zip", + ], + + cmd: "mkdir -p $(genDir)/$(in) " + + "&& $(location aprotoc) " + + " --plugin=$(location protoc-gen-javastream) " + + " --dependency_out=$(depfile) " + + " --javastream_out=$(genDir)/$(in) " + + " -Iexternal/protobuf/src " + + " -I . " + + " $(in) " + + "&& $(location soong_zip) -jar -o $(out) -C $(genDir)/$(in) -D $(genDir)/$(in)", + + srcs: [ + ":ipconnectivity-proto-src", + ":libstats_atom_enum_protos", + ":libtombstone_proto-src", + "core/proto/**/*.proto", + "libs/incident/**/*.proto", + ], + output_extension: "srcjar", +} + +gensrcs { + name: "framework-cppstream-protos", + depfile: true, + + tools: [ + "aprotoc", + "protoc-gen-cppstream", + ], + + cmd: "mkdir -p $(genDir) " + + "&& $(location aprotoc) " + + " --plugin=$(location protoc-gen-cppstream) " + + " --dependency_out=$(depfile) " + + " --cppstream_out=$(genDir) " + + " -Iexternal/protobuf/src " + + " -I . " + + " $(in)", + + srcs: [ + ":ipconnectivity-proto-src", + ":libstats_atom_enum_protos", + "core/proto/**/*.proto", + "libs/incident/**/*.proto", + ], + + output_extension: "proto.h", +} + +// ==== java proto host library ============================== +java_library_host { + name: "platformprotos", + srcs: [ + ":ipconnectivity-proto-src", + ":libstats_atom_enum_protos", + ":libstats_internal_protos", + ":statsd_internal_protos", + "cmds/am/proto/instrumentation_data.proto", + "cmds/statsd/src/**/*.proto", + "core/proto/**/*.proto", + "libs/incident/proto/**/*.proto", + ], + proto: { + include_dirs: [ + "external/protobuf/src", + "frameworks/proto_logging/stats", + ], + type: "full", + }, + errorprone: { + javacflags: ["-Xep:MissingOverride:OFF"], // b/72714520 + }, +} + +// ==== java proto device library (for test only) ============================== +java_library { + name: "platformprotosnano", + proto: { + type: "nano", + output_params: ["store_unknown_fields=true"], + include_dirs: ["external/protobuf/src"], + }, + exclude_srcs: [ + "core/proto/android/privacy.proto", + "core/proto/android/section.proto", + ], + sdk_version: "9", + srcs: [ + ":ipconnectivity-proto-src", + ":libstats_atom_enum_protos", + "core/proto/**/*.proto", + "libs/incident/proto/android/os/**/*.proto", + ], +} + +// ==== java proto device library (for test only) ============================== +java_library { + name: "platformprotoslite", + proto: { + type: "lite", + include_dirs: ["external/protobuf/src"], + }, + + srcs: [ + ":ipconnectivity-proto-src", + ":libstats_atom_enum_protos", + "core/proto/**/*.proto", + "libs/incident/proto/android/os/**/*.proto", + ], + exclude_srcs: [ + "core/proto/android/privacy.proto", + "core/proto/android/section.proto", + ], + sdk_version: "core_current", + // Protos have lots of MissingOverride and similar. + errorprone: { + javacflags: ["-XepDisableAllChecks"], + }, +} + +// ==== c++ proto device library ============================== +cc_defaults { + name: "libplatformprotos-defaults", + + proto: { + export_proto_headers: true, + include_dirs: [ + "external/protobuf/src", + ], + }, + + cflags: [ + "-Wall", + "-Werror", + "-Wno-unused-parameter", + ], + + srcs: [ + ":ipconnectivity-proto-src", + ":libstats_atom_enum_protos", + "core/proto/**/*.proto", + ], +} + +cc_library { + name: "libplatformprotos", + defaults: ["libplatformprotos-defaults"], + host_supported: true, + + target: { + host: { + proto: { + type: "full", + }, + }, + android: { + proto: { + type: "lite", + }, + shared_libs: [ + "libprotobuf-cpp-lite", + ], + shared: { + enabled: false, + }, + }, + }, +} + +// This library is meant for vendor code that needs to output protobuf. It links +// against the static version of libprotobuf-cpp-lite, for which we can not guarantee +// binary compatibility. +cc_library { + name: "libplatformprotos-static", + defaults: ["libplatformprotos-defaults"], + host_supported: false, + + // This is okay because this library is only built as a static library. The C++ + // API is not guaranteed. The proto API is guaranteed to be stable via Metrics Council, + // but is not authorized to be used outside of debugging. + vendor_available: true, + + target: { + android: { + proto: { + type: "lite", + }, + static_libs: [ + "libprotobuf-cpp-lite", + ], + shared: { + enabled: false, + }, + }, + }, +} + +// This is the full proto version of libplatformprotos. It may only +// be used by test code that is not shipped on the device. +cc_library { + name: "libplatformprotos-test", + defaults: ["libplatformprotos-defaults"], + host_supported: false, + + target: { + android: { + proto: { + type: "full", + }, + shared: { + enabled: false, + }, + }, + }, +} diff --git a/StubLibraries.bp b/StubLibraries.bp index 1644a550aca5..3f4e68965f4c 100644 --- a/StubLibraries.bp +++ b/StubLibraries.bp @@ -93,6 +93,8 @@ stubs_defaults { ], api_levels_annotations_enabled: false, filter_packages: packages_to_document, + defaults_visibility: ["//visibility:private"], + visibility: ["//frameworks/base/api"], } ///////////////////////////////////////////////////////////////////// @@ -111,7 +113,7 @@ droidstubs { last_released: { api_file: ":android-non-updatable.api.public.latest", removed_api_file: ":android-non-updatable-removed.api.public.latest", - baseline_file: ":android-incompatibilities.api.public.latest", + baseline_file: ":android-non-updatable-incompatibilities.api.public.latest", }, api_lint: { enabled: true, @@ -120,13 +122,19 @@ droidstubs { }, dists: [ { - targets: ["sdk", "win_sdk"], + targets: [ + "sdk", + "win_sdk", + ], dir: "apistubs/android/public/api", dest: "android-non-updatable.txt", tag: ".api.txt", }, { - targets: ["sdk", "win_sdk"], + targets: [ + "sdk", + "win_sdk", + ], dir: "apistubs/android/public/api", dest: "android-non-updatable-removed.txt", tag: ".removed-api.txt", @@ -134,21 +142,18 @@ droidstubs { ], } -priv_apps = - " --show-annotation android.annotation.SystemApi\\(" + - "client=android.annotation.SystemApi.Client.PRIVILEGED_APPS" + +priv_apps = " --show-annotation android.annotation.SystemApi\\(" + + "client=android.annotation.SystemApi.Client.PRIVILEGED_APPS" + "\\)" -priv_apps_in_stubs = - " --show-for-stub-purposes-annotation android.annotation.SystemApi\\(" + - "client=android.annotation.SystemApi.Client.PRIVILEGED_APPS" + +priv_apps_in_stubs = " --show-for-stub-purposes-annotation android.annotation.SystemApi\\(" + + "client=android.annotation.SystemApi.Client.PRIVILEGED_APPS" + "\\)" test = " --show-annotation android.annotation.TestApi" -module_libs = - " --show-annotation android.annotation.SystemApi\\(" + - "client=android.annotation.SystemApi.Client.MODULE_LIBRARIES" + +module_libs = " --show-annotation android.annotation.SystemApi\\(" + + "client=android.annotation.SystemApi.Client.MODULE_LIBRARIES" + "\\)" droidstubs { @@ -163,7 +168,7 @@ droidstubs { last_released: { api_file: ":android-non-updatable.api.system.latest", removed_api_file: ":android-non-updatable-removed.api.system.latest", - baseline_file: ":android-incompatibilities.api.system.latest" + baseline_file: ":android-non-updatable-incompatibilities.api.system.latest", }, api_lint: { enabled: true, @@ -173,13 +178,19 @@ droidstubs { }, dists: [ { - targets: ["sdk", "win_sdk"], + targets: [ + "sdk", + "win_sdk", + ], dir: "apistubs/android/system/api", dest: "android-non-updatable.txt", tag: ".api.txt", }, { - targets: ["sdk", "win_sdk"], + targets: [ + "sdk", + "win_sdk", + ], dir: "apistubs/android/system/api", dest: "android-non-updatable-removed.txt", tag: ".removed-api.txt", @@ -203,25 +214,37 @@ droidstubs { }, dists: [ { - targets: ["sdk", "win_sdk"], + targets: [ + "sdk", + "win_sdk", + ], dir: "apistubs/android/test/api", dest: "android.txt", tag: ".api.txt", }, { - targets: ["sdk", "win_sdk"], + targets: [ + "sdk", + "win_sdk", + ], dir: "apistubs/android/test/api", dest: "removed.txt", tag: ".removed-api.txt", }, { - targets: ["sdk", "win_sdk"], + targets: [ + "sdk", + "win_sdk", + ], dir: "apistubs/android/test/api", dest: "android-non-updatable.txt", tag: ".api.txt", }, { - targets: ["sdk", "win_sdk"], + targets: [ + "sdk", + "win_sdk", + ], dir: "apistubs/android/test/api", dest: "android-non-updatable-removed.txt", tag: ".removed-api.txt", @@ -249,13 +272,19 @@ droidstubs { }, dists: [ { - targets: ["sdk", "win_sdk"], + targets: [ + "sdk", + "win_sdk", + ], dir: "apistubs/android/module-lib/api", dest: "android-non-updatable.txt", tag: ".api.txt", }, { - targets: ["sdk", "win_sdk"], + targets: [ + "sdk", + "win_sdk", + ], dir: "apistubs/android/module-lib/api", dest: "android-non-updatable-removed.txt", tag: ".removed-api.txt", @@ -268,50 +297,128 @@ droidstubs { // from stub sources ///////////////////////////////////////////////////////////////////// +modules_public_stubs = [ + "android.net.ipsec.ike.stubs", + "art.module.public.api.stubs", + "conscrypt.module.public.api.stubs", + "framework-connectivity.stubs", + "framework-media.stubs", + "framework-mediaprovider.stubs", + "framework-permission.stubs", + "framework-sdkextensions.stubs", + "framework-statsd.stubs", + "framework-tethering.stubs", + "framework-wifi.stubs", + "i18n.module.public.api.stubs", +] + +modules_system_stubs = [ + "android.net.ipsec.ike.stubs.system", + "art.module.public.api.stubs", // Only has public stubs + "conscrypt.module.public.api.stubs", // Only has public stubs + "framework-connectivity.stubs.system", + "framework-media.stubs.system", + "framework-mediaprovider.stubs.system", + "framework-permission.stubs.system", + "framework-sdkextensions.stubs.system", + "framework-statsd.stubs.system", + "framework-tethering.stubs.system", + "framework-wifi.stubs.system", + "i18n.module.public.api.stubs", // Only has public stubs +] + java_defaults { - name: "android_defaults_stubs_current", - libs: [ "stub-annotations" ], - static_libs: [ - // License notices from art module - "art-notices-for-framework-stubs-jar", - "framework-res-package-jar", // Export package of framework-res - ], - errorprone: { - javacflags: [ - "-XepDisableAllChecks", + name: "android-non-updatable_defaults_stubs_current", + libs: ["stub-annotations"], + static_libs: ["framework-res-package-jar"], // Export package of framework-res + sdk_version: "none", + system_modules: "none", + java_version: "1.8", + compile_dex: true, + dist: { + targets: [ + "sdk", + "win_sdk", ], + tag: ".jar", + dest: "android-non-updatable.jar", + }, + defaults_visibility: ["//visibility:private"], + visibility: ["//visibility:private"], +} + +java_library_static { + name: "android-non-updatable.stubs", + defaults: ["android-non-updatable_defaults_stubs_current"], + srcs: [":api-stubs-docs-non-updatable"], + libs: modules_public_stubs, + dist: { + dir: "apistubs/android/public", + }, +} + +java_library_static { + name: "android-non-updatable.stubs.system", + defaults: ["android-non-updatable_defaults_stubs_current"], + srcs: [":system-api-stubs-docs-non-updatable"], + libs: modules_system_stubs, + dist: { + dir: "apistubs/android/system", + }, +} + +java_library_static { + name: "android-non-updatable.stubs.module_lib", + defaults: ["android-non-updatable_defaults_stubs_current"], + srcs: [":module-lib-api-stubs-docs-non-updatable"], + libs: [ + "sdk_system_current_android", + // NOTE: The below can be removed once the prebuilt stub contains IKE. + "sdk_system_current_android.net.ipsec.ike", + ], + dist: { + dir: "apistubs/android/module-lib", + }, +} + +java_library_static { + name: "android-non-updatable.stubs.test", + defaults: ["android-non-updatable_defaults_stubs_current"], + srcs: [":test-api-stubs-docs-non-updatable"], + libs: modules_system_stubs, + dist: { + dir: "apistubs/android/test", }, +} + +java_defaults { + name: "android_defaults_stubs_current", + static_libs: ["art-notices-for-framework-stubs-jar"], // License notices from art module sdk_version: "none", system_modules: "none", java_version: "1.8", compile_dex: true, + defaults_visibility: ["//visibility:private"], + visibility: ["//visibility:public"], } java_defaults { name: "android_stubs_dists_default", dist: { - targets: ["sdk", "win_sdk"], + targets: [ + "sdk", + "win_sdk", + ], tag: ".jar", dest: "android.jar", }, + defaults_visibility: ["//frameworks/base/services"], } java_library_static { name: "android_stubs_current", - srcs: [ ":api-stubs-docs-non-updatable" ], - static_libs: [ - "android.net.ipsec.ike.stubs", - "art.module.public.api.stubs", - "conscrypt.module.public.api.stubs", - "framework-connectivity.stubs", - "framework-media.stubs", - "framework-mediaprovider.stubs", - "framework-permission.stubs", - "framework-sdkextensions.stubs", - "framework-statsd.stubs", - "framework-tethering.stubs", - "framework-wifi.stubs", - "i18n.module.public.api.stubs", + static_libs: modules_public_stubs + [ + "android-non-updatable.stubs", "private-stub-annotations-jar", ], defaults: ["android_defaults_stubs_current"], @@ -319,20 +426,8 @@ java_library_static { java_library_static { name: "android_system_stubs_current", - srcs: [ ":system-api-stubs-docs-non-updatable" ], - static_libs: [ - "android.net.ipsec.ike.stubs.system", - "art.module.public.api.stubs", - "conscrypt.module.public.api.stubs", - "framework-connectivity.stubs.system", - "framework-media.stubs.system", - "framework-mediaprovider.stubs.system", - "framework-permission.stubs.system", - "framework-sdkextensions.stubs.system", - "framework-statsd.stubs.system", - "framework-tethering.stubs.system", - "framework-wifi.stubs.system", - "i18n.module.public.api.stubs", + static_libs: modules_system_stubs + [ + "android-non-updatable.stubs.system", "private-stub-annotations-jar", ], defaults: [ @@ -345,7 +440,10 @@ java_library_static { dists: [ { // Legacy dist path - targets: ["sdk", "win_sdk"], + targets: [ + "sdk", + "win_sdk", + ], tag: ".jar", dest: "android_system.jar", }, @@ -354,22 +452,10 @@ java_library_static { java_library_static { name: "android_test_stubs_current", - srcs: [ ":test-api-stubs-docs-non-updatable" ], - static_libs: [ - // Modules do not have test APIs, but we want to include their SystemApis, like we include - // the SystemApi of framework-non-updatable-sources. - "android.net.ipsec.ike.stubs.system", - "art.module.public.api.stubs", - "conscrypt.module.public.api.stubs", - "framework-connectivity.stubs.system", - "framework-media.stubs.system", - "framework-mediaprovider.stubs.system", - "framework-permission.stubs.system", - "framework-sdkextensions.stubs.system", - "framework-statsd.stubs.system", - "framework-tethering.stubs.system", - "framework-wifi.stubs.system", - "i18n.module.public.api.stubs", + // Modules do not have test APIs, but we want to include their SystemApis, like we include + // the SystemApi of framework-non-updatable-sources. + static_libs: modules_system_stubs + [ + "android-non-updatable.stubs.test", "private-stub-annotations-jar", ], defaults: [ @@ -379,29 +465,18 @@ java_library_static { dist: { dir: "apistubs/android/test", }, - dists: [ - { - // Legacy dist path - targets: ["sdk", "win_sdk"], - tag: ".jar", - dest: "android_test.jar", - }, - ], } java_library_static { name: "android_module_lib_stubs_current", - srcs: [ ":module-lib-api-stubs-docs-non-updatable" ], defaults: [ "android_defaults_stubs_current", "android_stubs_dists_default", ], - libs: [ - "sdk_system_current_android", - // NOTE: The below can be removed once the prebuilt stub contains IKE. - "sdk_system_current_android.net.ipsec.ike", + static_libs: [ + "android-non-updatable.stubs.module_lib", + "art.module.public.api.stubs", ], - static_libs: ["art.module.public.api.stubs"], dist: { dir: "apistubs/android/module-lib", }, @@ -437,6 +512,7 @@ droidstubs { "metalava-manual", ], args: priv_apps, + visibility: ["//visibility:private"], } java_library_static { @@ -446,4 +522,5 @@ java_library_static { srcs: [ ":hwbinder-stubs-docs", ], + visibility: ["//visibility:public"], } diff --git a/apex/jobscheduler/service/java/com/android/server/job/controllers/ConnectivityController.java b/apex/jobscheduler/service/java/com/android/server/job/controllers/ConnectivityController.java index a52223792b7a..5487e8788b9a 100644 --- a/apex/jobscheduler/service/java/com/android/server/job/controllers/ConnectivityController.java +++ b/apex/jobscheduler/service/java/com/android/server/job/controllers/ConnectivityController.java @@ -693,13 +693,6 @@ public final class ConnectivityController extends RestrictingController implemen StateControllerProto.ConnectivityController.REQUESTED_STANDBY_EXCEPTION_UIDS, mRequestedWhitelistJobs.keyAt(i)); } - for (int i = 0; i < mAvailableNetworks.size(); i++) { - Network network = mAvailableNetworks.keyAt(i); - if (network != null) { - network.dumpDebug(proto, - StateControllerProto.ConnectivityController.AVAILABLE_NETWORKS); - } - } for (int i = 0; i < mTrackedJobs.size(); i++) { final ArraySet<JobStatus> jobs = mTrackedJobs.valueAt(i); for (int j = 0; j < jobs.size(); j++) { @@ -713,12 +706,6 @@ public final class ConnectivityController extends RestrictingController implemen StateControllerProto.ConnectivityController.TrackedJob.INFO); proto.write(StateControllerProto.ConnectivityController.TrackedJob.SOURCE_UID, js.getSourceUid()); - NetworkRequest rn = js.getJob().getRequiredNetwork(); - if (rn != null) { - rn.dumpDebug(proto, - StateControllerProto.ConnectivityController.TrackedJob - .REQUIRED_NETWORK); - } proto.end(jsToken); } } diff --git a/apex/jobscheduler/service/java/com/android/server/job/controllers/JobStatus.java b/apex/jobscheduler/service/java/com/android/server/job/controllers/JobStatus.java index ea8e7bc4ab06..a346812ff5f5 100644 --- a/apex/jobscheduler/service/java/com/android/server/job/controllers/JobStatus.java +++ b/apex/jobscheduler/service/java/com/android/server/job/controllers/JobStatus.java @@ -1911,9 +1911,6 @@ public final class JobStatus { if (uriPerms != null) { uriPerms.dump(proto, JobStatusDumpProto.JobInfo.GRANTED_URI_PERMISSIONS); } - if (job.getRequiredNetwork() != null) { - job.getRequiredNetwork().dumpDebug(proto, JobStatusDumpProto.JobInfo.REQUIRED_NETWORK); - } if (mTotalNetworkDownloadBytes != JobInfo.NETWORK_BYTES_UNKNOWN) { proto.write(JobStatusDumpProto.JobInfo.TOTAL_NETWORK_DOWNLOAD_BYTES, mTotalNetworkDownloadBytes); @@ -2002,10 +1999,6 @@ public final class JobStatus { } } - if (network != null) { - network.dumpDebug(proto, JobStatusDumpProto.NETWORK); - } - if (pendingWork != null) { for (int i = 0; i < pendingWork.size(); i++) { dumpJobWorkItem(proto, JobStatusDumpProto.PENDING_WORK, pendingWork.get(i)); diff --git a/apex/media/framework/lint-baseline.xml b/apex/media/framework/lint-baseline.xml new file mode 100644 index 000000000000..29adf1d2ad4b --- /dev/null +++ b/apex/media/framework/lint-baseline.xml @@ -0,0 +1,246 @@ +<?xml version="1.0" encoding="UTF-8"?> +<issues format="5" by="lint 4.1.0" client="cli" variant="all" version="4.1.0"> + + <issue + id="NewApi" + message="Field requires API level R (current min is 29): `android.media.MediaParser.TrackData#mediaFormat`" + errorLine1=" this.mediaFormat = mediaFormat;" + errorLine2=" ~~~~~~~~~~~~~~~~"> + <location + file="frameworks/base/apex/media/framework/java/android/media/MediaParser.java" + line="271" + column="13"/> + </issue> + + <issue + id="NewApi" + message="Field requires API level R (current min is 29): `android.media.MediaParser.TrackData#drmInitData`" + errorLine1=" this.drmInitData = drmInitData;" + errorLine2=" ~~~~~~~~~~~~~~~~"> + <location + file="frameworks/base/apex/media/framework/java/android/media/MediaParser.java" + line="272" + column="13"/> + </issue> + + <issue + id="NewApi" + message="Field requires API level R (current min is 29): `android.media.MediaParser.SeekPoint#timeMicros`" + errorLine1=" this.timeMicros = timeMicros;" + errorLine2=" ~~~~~~~~~~~~~~~"> + <location + file="frameworks/base/apex/media/framework/java/android/media/MediaParser.java" + line="293" + column="13"/> + </issue> + + <issue + id="NewApi" + message="Field requires API level R (current min is 29): `android.media.MediaParser.SeekPoint#position`" + errorLine1=" this.position = position;" + errorLine2=" ~~~~~~~~~~~~~"> + <location + file="frameworks/base/apex/media/framework/java/android/media/MediaParser.java" + line="294" + column="13"/> + </issue> + + <issue + id="NewApi" + message="Field requires API level R (current min is 29): `android.media.MediaParser.SeekPoint#position`" + errorLine1=" return "[timeMicros=" + timeMicros + ", position=" + position + "]";" + errorLine2=" ~~~~~~~~"> + <location + file="frameworks/base/apex/media/framework/java/android/media/MediaParser.java" + line="300" + column="66"/> + </issue> + + <issue + id="NewApi" + message="Field requires API level R (current min is 29): `android.media.MediaParser.SeekPoint#timeMicros`" + errorLine1=" return "[timeMicros=" + timeMicros + ", position=" + position + "]";" + errorLine2=" ~~~~~~~~~~"> + <location + file="frameworks/base/apex/media/framework/java/android/media/MediaParser.java" + line="300" + column="37"/> + </issue> + + <issue + id="NewApi" + message="Class requires API level R (current min is 29): `android.media.MediaParser.SeekPoint`" + errorLine1=" SeekPoint other = (SeekPoint) obj;" + errorLine2=" ~~~~~~~~~"> + <location + file="frameworks/base/apex/media/framework/java/android/media/MediaParser.java" + line="311" + column="32"/> + </issue> + + <issue + id="NewApi" + message="Field requires API level R (current min is 29): `android.media.MediaParser.SeekPoint#position`" + errorLine1=" return timeMicros == other.timeMicros && position == other.position;" + errorLine2=" ~~~~~~~~"> + <location + file="frameworks/base/apex/media/framework/java/android/media/MediaParser.java" + line="312" + column="54"/> + </issue> + + <issue + id="NewApi" + message="Field requires API level R (current min is 29): `android.media.MediaParser.SeekPoint#position`" + errorLine1=" return timeMicros == other.timeMicros && position == other.position;" + errorLine2=" ~~~~~~~~~~~~~~"> + <location + file="frameworks/base/apex/media/framework/java/android/media/MediaParser.java" + line="312" + column="66"/> + </issue> + + <issue + id="NewApi" + message="Field requires API level R (current min is 29): `android.media.MediaParser.SeekPoint#timeMicros`" + errorLine1=" return timeMicros == other.timeMicros && position == other.position;" + errorLine2=" ~~~~~~~~~~"> + <location + file="frameworks/base/apex/media/framework/java/android/media/MediaParser.java" + line="312" + column="20"/> + </issue> + + <issue + id="NewApi" + message="Field requires API level R (current min is 29): `android.media.MediaParser.SeekPoint#timeMicros`" + errorLine1=" return timeMicros == other.timeMicros && position == other.position;" + errorLine2=" ~~~~~~~~~~~~~~~~"> + <location + file="frameworks/base/apex/media/framework/java/android/media/MediaParser.java" + line="312" + column="34"/> + </issue> + + <issue + id="NewApi" + message="Field requires API level R (current min is 29): `android.media.MediaParser.SeekPoint#timeMicros`" + errorLine1=" int result = (int) timeMicros;" + errorLine2=" ~~~~~~~~~~"> + <location + file="frameworks/base/apex/media/framework/java/android/media/MediaParser.java" + line="317" + column="32"/> + </issue> + + <issue + id="NewApi" + message="Field requires API level R (current min is 29): `android.media.MediaParser.SeekPoint#position`" + errorLine1=" result = 31 * result + (int) position;" + errorLine2=" ~~~~~~~~"> + <location + file="frameworks/base/apex/media/framework/java/android/media/MediaParser.java" + line="318" + column="42"/> + </issue> + + <issue + id="NewApi" + message="Class requires API level R (current min is 29): `android.media.MediaParser.InputReader`" + errorLine1=" public interface SeekableInputReader extends InputReader {" + errorLine2=" ~~~~~~~~~~~"> + <location + file="frameworks/base/apex/media/framework/java/android/media/MediaParser.java" + line="350" + column="50"/> + </issue> + + <issue + id="NewApi" + message="Cast from `SeekableInputReader` to `InputReader` requires API level 30 (current min is 29)" + errorLine1=" mExoDataReader.mInputReader = seekableInputReader;" + errorLine2=" ~~~~~~~~~~~~~~~~~~~"> + <location + file="frameworks/base/apex/media/framework/java/android/media/MediaParser.java" + line="1198" + column="39"/> + </issue> + + <issue + id="NewApi" + message="Field requires API level R (current min is 29): `android.media.MediaParser.SeekPoint#position`" + errorLine1=" mPendingSeekPosition = seekPoint.position;" + errorLine2=" ~~~~~~~~~~~~~~~~~~"> + <location + file="frameworks/base/apex/media/framework/java/android/media/MediaParser.java" + line="1284" + column="36"/> + </issue> + + <issue + id="NewApi" + message="Field requires API level R (current min is 29): `android.media.MediaParser.SeekPoint#timeMicros`" + errorLine1=" mPendingSeekTimeMicros = seekPoint.timeMicros;" + errorLine2=" ~~~~~~~~~~~~~~~~~~~~"> + <location + file="frameworks/base/apex/media/framework/java/android/media/MediaParser.java" + line="1285" + column="38"/> + </issue> + + <issue + id="NewApi" + message="Field requires API level R (current min is 29): `android.media.MediaParser.SeekPoint#position`" + errorLine1=" mExtractor.seek(seekPoint.position, seekPoint.timeMicros);" + errorLine2=" ~~~~~~~~~~~~~~~~~~"> + <location + file="frameworks/base/apex/media/framework/java/android/media/MediaParser.java" + line="1287" + column="29"/> + </issue> + + <issue + id="NewApi" + message="Field requires API level R (current min is 29): `android.media.MediaParser.SeekPoint#timeMicros`" + errorLine1=" mExtractor.seek(seekPoint.position, seekPoint.timeMicros);" + errorLine2=" ~~~~~~~~~~~~~~~~~~~~"> + <location + file="frameworks/base/apex/media/framework/java/android/media/MediaParser.java" + line="1287" + column="49"/> + </issue> + + <issue + id="NewApi" + message="Field requires API level R (current min is 29): `android.media.DrmInitData.SchemeInitData#uuid`" + errorLine1=" if (schemeInitData.uuid.equals(schemeUuid)) {" + errorLine2=" ~~~~~~~~~~~~~~~~~~~"> + <location + file="frameworks/base/apex/media/framework/java/android/media/MediaParser.java" + line="1566" + column="21"/> + </issue> + + <issue + id="NewApi" + message="Class requires API level R (current min is 29): `android.media.MediaParser.InputReader`" + errorLine1=" private static final class DataReaderAdapter implements InputReader {" + errorLine2=" ~~~~~~~~~~~"> + <location + file="frameworks/base/apex/media/framework/java/android/media/MediaParser.java" + line="1859" + column="61"/> + </issue> + + <issue + id="NewApi" + message="Class requires API level R (current min is 29): `android.media.MediaParser.InputReader`" + errorLine1=" private static final class ParsableByteArrayAdapter implements InputReader {" + errorLine2=" ~~~~~~~~~~~"> + <location + file="frameworks/base/apex/media/framework/java/android/media/MediaParser.java" + line="1892" + column="68"/> + </issue> + +</issues> diff --git a/api/Android.bp b/api/Android.bp index 485255f32537..6e83c083245a 100644 --- a/api/Android.bp +++ b/api/Android.bp @@ -308,6 +308,9 @@ genrule { genrule { name: "combined-removed-dex", + visibility: [ + "//frameworks/base/boot", + ], srcs: [ ":frameworks-base-api-removed.txt", ":frameworks-base-api-system-removed.txt", diff --git a/api/dump_api_shas.sh b/api/dump_api_shas.sh new file mode 100755 index 000000000000..c023b312b471 --- /dev/null +++ b/api/dump_api_shas.sh @@ -0,0 +1,56 @@ +#!/bin/bash -e +# This script dumps the git SHAs of all commits inside api tracking directories. +# It can used by tools wanting to track API changes, and the primary original +# purpose is to verify verify all API change SHAs have been tracked by the +# server-side API-council tools. +# +# The only argument is used to specify a git commit range to filter by. +# +# Example invocation (API changes between O and P): +# frameworks/base/api/dump_api_shas.sh origin/oreo-dev..origin/pie-dev + +set -o pipefail + +eecho() { echo $@ >&2 ; } + +if [[ $1 == *..* ]]; then + exclude=${1/..*} + include=${1/*..} +else + eecho No range or invalid range specified, defaulting to all commits from HEAD. + exclude= + include=HEAD +fi + +eecho -n building queryview... +{ source build/envsetup.sh && lunch aosp_arm && m queryview; } >/dev/null 2>&1 \ + || { eecho failed; exit 1; } +eecho "done" + +# This finds the directories where the dependant java_sdk_libs are defined +bpdirs=$( + bazel query --config=queryview --output=package \ + 'kind(java_sdk_library, deps(//frameworks/base/api/..., 1))' 2>/dev/null + echo frameworks/base/core/api # Not a java_sdk_library. + echo frameworks/base/services/api # Not a java_sdk_library. +) + +# Find relevant api subdirectories +apidirs=$( + find $bpdirs -type f -name '*current.txt' -path '*/api/*' \ + | xargs realpath --relative-to=$(pwd) | xargs dirname | sort | uniq +) + +# Dump sorted SHAs of commits in these directories +{ for d in $apidirs; do + ( cd $d + eecho inspecting $d + exclude_arg=$(test -n "$exclude" && { + git rev-parse -q --verify $exclude > /dev/null && echo "--not $exclude" \ + || eecho "$d has no revision $exclude, including all commits"; } || true) + for f in $(find . -name '*current.txt'); do + git --no-pager log --pretty=format:%H --no-merges --follow $include $exclude_arg -- $f + echo # No trailing newline with --no-pager + done + ) +done; } | sort | uniq diff --git a/boot/Android.bp b/boot/Android.bp index 71edea27ada6..844dd64ce8d7 100644 --- a/boot/Android.bp +++ b/boot/Android.bp @@ -43,4 +43,49 @@ package { // done correctly. platform_bootclasspath { name: "platform-bootclasspath", + + // Additional information needed by hidden api processing. + hidden_api: { + unsupported: [ + "hiddenapi/hiddenapi-unsupported.txt", + ], + removed: [ + ":combined-removed-dex", + ], + max_target_r_low_priority: [ + "hiddenapi/hiddenapi-max-target-r-loprio.txt", + ], + max_target_q: [ + "hiddenapi/hiddenapi-max-target-q.txt", + ], + max_target_p: [ + "hiddenapi/hiddenapi-max-target-p.txt", + ], + max_target_o_low_priority: [ + "hiddenapi/hiddenapi-max-target-o.txt", + ], + blocked: [ + "hiddenapi/hiddenapi-force-blocked.txt", + ], + unsupported_packages: [ + "hiddenapi/hiddenapi-unsupported-packages.txt", + ], + }, + + dists: [ + { + targets: ["droidcore"], + tag: "hiddenapi-flags.csv", + }, + { + targets: ["droidcore"], + tag: "hiddenapi-index.csv", + }, + { + targets: ["droidcore"], + tag: "hiddenapi-metadata.csv", + // Legacy name + dest: "hiddenapi-unsupported.csv", + }, + ], } diff --git a/boot/hiddenapi/OWNERS b/boot/hiddenapi/OWNERS index 5d869fc12ebd..74a3dc05f0da 100644 --- a/boot/hiddenapi/OWNERS +++ b/boot/hiddenapi/OWNERS @@ -1,7 +1,5 @@ # compat-team@ for changes to hiddenapi files -andreionea@google.com -mathewi@google.com -satayev@google.com +file:tools/platform-compat:/OWNERS # Escalations: per-file hiddenapi-* = bdc@google.com, narayan@google.com diff --git a/config/hiddenapi-force-blocked.txt b/boot/hiddenapi/hiddenapi-force-blocked.txt index b328f2ac1955..b328f2ac1955 100644 --- a/config/hiddenapi-force-blocked.txt +++ b/boot/hiddenapi/hiddenapi-force-blocked.txt diff --git a/config/hiddenapi-max-target-o.txt b/boot/hiddenapi/hiddenapi-max-target-o.txt index 023bf3876228..023bf3876228 100644 --- a/config/hiddenapi-max-target-o.txt +++ b/boot/hiddenapi/hiddenapi-max-target-o.txt diff --git a/config/hiddenapi-max-target-p.txt b/boot/hiddenapi/hiddenapi-max-target-p.txt index 351e71dd9538..351e71dd9538 100644 --- a/config/hiddenapi-max-target-p.txt +++ b/boot/hiddenapi/hiddenapi-max-target-p.txt diff --git a/config/hiddenapi-max-target-q.txt b/boot/hiddenapi/hiddenapi-max-target-q.txt index 4832dd184ec5..4832dd184ec5 100644 --- a/config/hiddenapi-max-target-q.txt +++ b/boot/hiddenapi/hiddenapi-max-target-q.txt diff --git a/config/hiddenapi-max-target-r-loprio.txt b/boot/hiddenapi/hiddenapi-max-target-r-loprio.txt index 246eeea35a19..246eeea35a19 100644 --- a/config/hiddenapi-max-target-r-loprio.txt +++ b/boot/hiddenapi/hiddenapi-max-target-r-loprio.txt diff --git a/config/hiddenapi-unsupported-packages.txt b/boot/hiddenapi/hiddenapi-unsupported-packages.txt index 986d2591a007..986d2591a007 100644 --- a/config/hiddenapi-unsupported-packages.txt +++ b/boot/hiddenapi/hiddenapi-unsupported-packages.txt diff --git a/config/hiddenapi-unsupported.txt b/boot/hiddenapi/hiddenapi-unsupported.txt index 48a9782c83df..48a9782c83df 100644 --- a/config/hiddenapi-unsupported.txt +++ b/boot/hiddenapi/hiddenapi-unsupported.txt diff --git a/cmds/statsd/src/external/StatsPullerManager.cpp b/cmds/statsd/src/external/StatsPullerManager.cpp new file mode 100644 index 000000000000..99c39f6017b1 --- /dev/null +++ b/cmds/statsd/src/external/StatsPullerManager.cpp @@ -0,0 +1,392 @@ +/* + * Copyright (C) 2017 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#define DEBUG false +#include "Log.h" + +#include "StatsPullerManager.h" + +#include <cutils/log.h> +#include <math.h> +#include <stdint.h> + +#include <algorithm> +#include <iostream> + +#include "../StatsService.h" +#include "../logd/LogEvent.h" +#include "../stats_log_util.h" +#include "../statscompanion_util.h" +#include "StatsCallbackPuller.h" +#include "TrainInfoPuller.h" +#include "statslog_statsd.h" + +using std::shared_ptr; +using std::vector; + +namespace android { +namespace os { +namespace statsd { + +// Stores the puller as a wp to avoid holding a reference in case it is unregistered and +// pullAtomCallbackDied is never called. +struct PullAtomCallbackDeathCookie { + PullAtomCallbackDeathCookie(const wp<StatsPullerManager>& pullerManager, + const PullerKey& pullerKey, const wp<StatsPuller>& puller) : + mPullerManager(pullerManager), mPullerKey(pullerKey), mPuller(puller) { + } + + wp<StatsPullerManager> mPullerManager; + PullerKey mPullerKey; + wp<StatsPuller> mPuller; +}; + +void StatsPullerManager::pullAtomCallbackDied(void* cookie) { + PullAtomCallbackDeathCookie* cookie_ = static_cast<PullAtomCallbackDeathCookie*>(cookie); + sp<StatsPullerManager> thiz = cookie_->mPullerManager.promote(); + if (!thiz) { + return; + } + + const PullerKey& pullerKey = cookie_->mPullerKey; + wp<StatsPuller> puller = cookie_->mPuller; + + // Erase the mapping from the puller key to the puller if the mapping still exists. + // Note that we are removing the StatsPuller object, which internally holds the binder + // IPullAtomCallback. However, each new registration creates a new StatsPuller, so this works. + lock_guard<mutex> lock(thiz->mLock); + const auto& it = thiz->kAllPullAtomInfo.find(pullerKey); + if (it != thiz->kAllPullAtomInfo.end() && puller != nullptr && puller == it->second) { + StatsdStats::getInstance().notePullerCallbackRegistrationChanged(pullerKey.atomTag, + /*registered=*/false); + thiz->kAllPullAtomInfo.erase(pullerKey); + } + // The death recipient corresponding to this specific IPullAtomCallback can never + // be triggered again, so free up resources. + delete cookie_; +} + +// Values smaller than this may require to update the alarm. +const int64_t NO_ALARM_UPDATE = INT64_MAX; + +StatsPullerManager::StatsPullerManager() + : kAllPullAtomInfo({ + // TrainInfo. + {{.atomTag = util::TRAIN_INFO, .uid = AID_STATSD}, new TrainInfoPuller()}, + }), + mNextPullTimeNs(NO_ALARM_UPDATE), + mPullAtomCallbackDeathRecipient(AIBinder_DeathRecipient_new(pullAtomCallbackDied)) { +} + +bool StatsPullerManager::Pull(int tagId, const ConfigKey& configKey, const int64_t eventTimeNs, + vector<shared_ptr<LogEvent>>* data, bool useUids) { + std::lock_guard<std::mutex> _l(mLock); + return PullLocked(tagId, configKey, eventTimeNs, data, useUids); +} + +bool StatsPullerManager::Pull(int tagId, const vector<int32_t>& uids, const int64_t eventTimeNs, + vector<std::shared_ptr<LogEvent>>* data, bool useUids) { + std::lock_guard<std::mutex> _l(mLock); + return PullLocked(tagId, uids, eventTimeNs, data, useUids); +} + +bool StatsPullerManager::PullLocked(int tagId, const ConfigKey& configKey, + const int64_t eventTimeNs, vector<shared_ptr<LogEvent>>* data, + bool useUids) { + vector<int32_t> uids; + if (useUids) { + auto uidProviderIt = mPullUidProviders.find(configKey); + if (uidProviderIt == mPullUidProviders.end()) { + ALOGE("Error pulling tag %d. No pull uid provider for config key %s", tagId, + configKey.ToString().c_str()); + StatsdStats::getInstance().notePullUidProviderNotFound(tagId); + return false; + } + sp<PullUidProvider> pullUidProvider = uidProviderIt->second.promote(); + if (pullUidProvider == nullptr) { + ALOGE("Error pulling tag %d, pull uid provider for config %s is gone.", tagId, + configKey.ToString().c_str()); + StatsdStats::getInstance().notePullUidProviderNotFound(tagId); + return false; + } + uids = pullUidProvider->getPullAtomUids(tagId); + } + return PullLocked(tagId, uids, eventTimeNs, data, useUids); +} + +bool StatsPullerManager::PullLocked(int tagId, const vector<int32_t>& uids, + const int64_t eventTimeNs, vector<shared_ptr<LogEvent>>* data, + bool useUids) { + VLOG("Initiating pulling %d", tagId); + if (useUids) { + for (int32_t uid : uids) { + PullerKey key = {.atomTag = tagId, .uid = uid}; + auto pullerIt = kAllPullAtomInfo.find(key); + if (pullerIt != kAllPullAtomInfo.end()) { + bool ret = pullerIt->second->Pull(eventTimeNs, data); + VLOG("pulled %zu items", data->size()); + if (!ret) { + StatsdStats::getInstance().notePullFailed(tagId); + } + return ret; + } + } + StatsdStats::getInstance().notePullerNotFound(tagId); + ALOGW("StatsPullerManager: Unknown tagId %d", tagId); + return false; // Return early since we don't know what to pull. + } else { + PullerKey key = {.atomTag = tagId, .uid = -1}; + auto pullerIt = kAllPullAtomInfo.find(key); + if (pullerIt != kAllPullAtomInfo.end()) { + bool ret = pullerIt->second->Pull(eventTimeNs, data); + VLOG("pulled %zu items", data->size()); + if (!ret) { + StatsdStats::getInstance().notePullFailed(tagId); + } + return ret; + } + ALOGW("StatsPullerManager: Unknown tagId %d", tagId); + return false; // Return early since we don't know what to pull. + } +} + +bool StatsPullerManager::PullerForMatcherExists(int tagId) const { + // Pulled atoms might be registered after we parse the config, so just make sure the id is in + // an appropriate range. + return isVendorPulledAtom(tagId) || isPulledAtom(tagId); +} + +void StatsPullerManager::updateAlarmLocked() { + if (mNextPullTimeNs == NO_ALARM_UPDATE) { + VLOG("No need to set alarms. Skipping"); + return; + } + + // TODO(b/151045771): do not hold a lock while making a binder call + if (mStatsCompanionService != nullptr) { + mStatsCompanionService->setPullingAlarm(mNextPullTimeNs / 1000000); + } else { + VLOG("StatsCompanionService not available. Alarm not set."); + } + return; +} + +void StatsPullerManager::SetStatsCompanionService( + shared_ptr<IStatsCompanionService> statsCompanionService) { + std::lock_guard<std::mutex> _l(mLock); + shared_ptr<IStatsCompanionService> tmpForLock = mStatsCompanionService; + mStatsCompanionService = statsCompanionService; + for (const auto& pulledAtom : kAllPullAtomInfo) { + pulledAtom.second->SetStatsCompanionService(statsCompanionService); + } + if (mStatsCompanionService != nullptr) { + updateAlarmLocked(); + } +} + +void StatsPullerManager::RegisterReceiver(int tagId, const ConfigKey& configKey, + wp<PullDataReceiver> receiver, int64_t nextPullTimeNs, + int64_t intervalNs) { + std::lock_guard<std::mutex> _l(mLock); + auto& receivers = mReceivers[{.atomTag = tagId, .configKey = configKey}]; + for (auto it = receivers.begin(); it != receivers.end(); it++) { + if (it->receiver == receiver) { + VLOG("Receiver already registered of %d", (int)receivers.size()); + return; + } + } + ReceiverInfo receiverInfo; + receiverInfo.receiver = receiver; + + // Round it to the nearest minutes. This is the limit of alarm manager. + // In practice, we should always have larger buckets. + int64_t roundedIntervalNs = intervalNs / NS_PER_SEC / 60 * NS_PER_SEC * 60; + // Scheduled pulling should be at least 1 min apart. + // This can be lower in cts tests, in which case we round it to 1 min. + if (roundedIntervalNs < 60 * (int64_t)NS_PER_SEC) { + roundedIntervalNs = 60 * (int64_t)NS_PER_SEC; + } + + receiverInfo.intervalNs = roundedIntervalNs; + receiverInfo.nextPullTimeNs = nextPullTimeNs; + receivers.push_back(receiverInfo); + + // There is only one alarm for all pulled events. So only set it to the smallest denom. + if (nextPullTimeNs < mNextPullTimeNs) { + VLOG("Updating next pull time %lld", (long long)mNextPullTimeNs); + mNextPullTimeNs = nextPullTimeNs; + updateAlarmLocked(); + } + VLOG("Puller for tagId %d registered of %d", tagId, (int)receivers.size()); +} + +void StatsPullerManager::UnRegisterReceiver(int tagId, const ConfigKey& configKey, + wp<PullDataReceiver> receiver) { + std::lock_guard<std::mutex> _l(mLock); + auto receiversIt = mReceivers.find({.atomTag = tagId, .configKey = configKey}); + if (receiversIt == mReceivers.end()) { + VLOG("Unknown pull code or no receivers: %d", tagId); + return; + } + std::list<ReceiverInfo>& receivers = receiversIt->second; + for (auto it = receivers.begin(); it != receivers.end(); it++) { + if (receiver == it->receiver) { + receivers.erase(it); + VLOG("Puller for tagId %d unregistered of %d", tagId, (int)receivers.size()); + return; + } + } +} + +void StatsPullerManager::RegisterPullUidProvider(const ConfigKey& configKey, + wp<PullUidProvider> provider) { + std::lock_guard<std::mutex> _l(mLock); + mPullUidProviders[configKey] = provider; +} + +void StatsPullerManager::UnregisterPullUidProvider(const ConfigKey& configKey, + wp<PullUidProvider> provider) { + std::lock_guard<std::mutex> _l(mLock); + const auto& it = mPullUidProviders.find(configKey); + if (it != mPullUidProviders.end() && it->second == provider) { + mPullUidProviders.erase(it); + } +} + +void StatsPullerManager::OnAlarmFired(int64_t elapsedTimeNs) { + std::lock_guard<std::mutex> _l(mLock); + int64_t wallClockNs = getWallClockNs(); + + int64_t minNextPullTimeNs = NO_ALARM_UPDATE; + + vector<pair<const ReceiverKey*, vector<ReceiverInfo*>>> needToPull; + for (auto& pair : mReceivers) { + vector<ReceiverInfo*> receivers; + if (pair.second.size() != 0) { + for (ReceiverInfo& receiverInfo : pair.second) { + if (receiverInfo.nextPullTimeNs <= elapsedTimeNs) { + receivers.push_back(&receiverInfo); + } else { + if (receiverInfo.nextPullTimeNs < minNextPullTimeNs) { + minNextPullTimeNs = receiverInfo.nextPullTimeNs; + } + } + } + if (receivers.size() > 0) { + needToPull.push_back(make_pair(&pair.first, receivers)); + } + } + } + for (const auto& pullInfo : needToPull) { + vector<shared_ptr<LogEvent>> data; + bool pullSuccess = PullLocked(pullInfo.first->atomTag, pullInfo.first->configKey, + elapsedTimeNs, &data); + if (!pullSuccess) { + VLOG("pull failed at %lld, will try again later", (long long)elapsedTimeNs); + } + + // Convention is to mark pull atom timestamp at request time. + // If we pull at t0, puller starts at t1, finishes at t2, and send back + // at t3, we mark t0 as its timestamp, which should correspond to its + // triggering event, such as condition change at t0. + // Here the triggering event is alarm fired from AlarmManager. + // In ValueMetricProducer and GaugeMetricProducer we do same thing + // when pull on condition change, etc. + for (auto& event : data) { + event->setElapsedTimestampNs(elapsedTimeNs); + event->setLogdWallClockTimestampNs(wallClockNs); + } + + for (const auto& receiverInfo : pullInfo.second) { + sp<PullDataReceiver> receiverPtr = receiverInfo->receiver.promote(); + if (receiverPtr != nullptr) { + receiverPtr->onDataPulled(data, pullSuccess, elapsedTimeNs); + // We may have just come out of a coma, compute next pull time. + int numBucketsAhead = + (elapsedTimeNs - receiverInfo->nextPullTimeNs) / receiverInfo->intervalNs; + receiverInfo->nextPullTimeNs += (numBucketsAhead + 1) * receiverInfo->intervalNs; + if (receiverInfo->nextPullTimeNs < minNextPullTimeNs) { + minNextPullTimeNs = receiverInfo->nextPullTimeNs; + } + } else { + VLOG("receiver already gone."); + } + } + } + + VLOG("mNextPullTimeNs: %lld updated to %lld", (long long)mNextPullTimeNs, + (long long)minNextPullTimeNs); + mNextPullTimeNs = minNextPullTimeNs; + updateAlarmLocked(); +} + +int StatsPullerManager::ForceClearPullerCache() { + std::lock_guard<std::mutex> _l(mLock); + int totalCleared = 0; + for (const auto& pulledAtom : kAllPullAtomInfo) { + totalCleared += pulledAtom.second->ForceClearCache(); + } + return totalCleared; +} + +int StatsPullerManager::ClearPullerCacheIfNecessary(int64_t timestampNs) { + std::lock_guard<std::mutex> _l(mLock); + int totalCleared = 0; + for (const auto& pulledAtom : kAllPullAtomInfo) { + totalCleared += pulledAtom.second->ClearCacheIfNecessary(timestampNs); + } + return totalCleared; +} + +void StatsPullerManager::RegisterPullAtomCallback(const int uid, const int32_t atomTag, + const int64_t coolDownNs, const int64_t timeoutNs, + const vector<int32_t>& additiveFields, + const shared_ptr<IPullAtomCallback>& callback, + bool useUid) { + std::lock_guard<std::mutex> _l(mLock); + VLOG("RegisterPullerCallback: adding puller for tag %d", atomTag); + + if (callback == nullptr) { + ALOGW("SetPullAtomCallback called with null callback for atom %d.", atomTag); + return; + } + + StatsdStats::getInstance().notePullerCallbackRegistrationChanged(atomTag, /*registered=*/true); + int64_t actualCoolDownNs = coolDownNs < kMinCoolDownNs ? kMinCoolDownNs : coolDownNs; + int64_t actualTimeoutNs = timeoutNs > kMaxTimeoutNs ? kMaxTimeoutNs : timeoutNs; + + sp<StatsCallbackPuller> puller = new StatsCallbackPuller(atomTag, callback, actualCoolDownNs, + actualTimeoutNs, additiveFields); + PullerKey key = {.atomTag = atomTag, .uid = useUid ? uid : -1}; + AIBinder_linkToDeath(callback->asBinder().get(), mPullAtomCallbackDeathRecipient.get(), + new PullAtomCallbackDeathCookie(this, key, puller)); + kAllPullAtomInfo[key] = puller; +} + +void StatsPullerManager::UnregisterPullAtomCallback(const int uid, const int32_t atomTag, + bool useUids) { + std::lock_guard<std::mutex> _l(mLock); + PullerKey key = {.atomTag = atomTag, .uid = useUids ? uid : -1}; + if (kAllPullAtomInfo.find(key) != kAllPullAtomInfo.end()) { + StatsdStats::getInstance().notePullerCallbackRegistrationChanged(atomTag, + /*registered=*/false); + kAllPullAtomInfo.erase(key); + } +} + +} // namespace statsd +} // namespace os +} // namespace android diff --git a/cmds/statsd/src/logd/LogEvent.cpp b/cmds/statsd/src/logd/LogEvent.cpp new file mode 100644 index 000000000000..4f031724763f --- /dev/null +++ b/cmds/statsd/src/logd/LogEvent.cpp @@ -0,0 +1,618 @@ +/* + * Copyright (C) 2017 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#define DEBUG false // STOPSHIP if true +#include "logd/LogEvent.h" + +#include <android-base/stringprintf.h> +#include <android/binder_ibinder.h> +#include <log/log.h> +#include <private/android_filesystem_config.h> + +#include "annotations.h" +#include "stats_log_util.h" +#include "statslog_statsd.h" + +namespace android { +namespace os { +namespace statsd { + +// for TrainInfo experiment id serialization +const int FIELD_ID_EXPERIMENT_ID = 1; + +using namespace android::util; +using android::base::StringPrintf; +using android::util::ProtoOutputStream; +using std::string; +using std::vector; + +// stats_event.h socket types. Keep in sync. +/* ERRORS */ +#define ERROR_NO_TIMESTAMP 0x1 +#define ERROR_NO_ATOM_ID 0x2 +#define ERROR_OVERFLOW 0x4 +#define ERROR_ATTRIBUTION_CHAIN_TOO_LONG 0x8 +#define ERROR_TOO_MANY_KEY_VALUE_PAIRS 0x10 +#define ERROR_ANNOTATION_DOES_NOT_FOLLOW_FIELD 0x20 +#define ERROR_INVALID_ANNOTATION_ID 0x40 +#define ERROR_ANNOTATION_ID_TOO_LARGE 0x80 +#define ERROR_TOO_MANY_ANNOTATIONS 0x100 +#define ERROR_TOO_MANY_FIELDS 0x200 +#define ERROR_INVALID_VALUE_TYPE 0x400 +#define ERROR_STRING_NOT_NULL_TERMINATED 0x800 + +/* TYPE IDS */ +#define INT32_TYPE 0x00 +#define INT64_TYPE 0x01 +#define STRING_TYPE 0x02 +#define LIST_TYPE 0x03 +#define FLOAT_TYPE 0x04 +#define BOOL_TYPE 0x05 +#define BYTE_ARRAY_TYPE 0x06 +#define OBJECT_TYPE 0x07 +#define KEY_VALUE_PAIRS_TYPE 0x08 +#define ATTRIBUTION_CHAIN_TYPE 0x09 +#define ERROR_TYPE 0x0F + +LogEvent::LogEvent(int32_t uid, int32_t pid) + : mLogdTimestampNs(time(nullptr)), mLogUid(uid), mLogPid(pid) { +} + +LogEvent::LogEvent(const string& trainName, int64_t trainVersionCode, bool requiresStaging, + bool rollbackEnabled, bool requiresLowLatencyMonitor, int32_t state, + const std::vector<uint8_t>& experimentIds, int32_t userId) { + mLogdTimestampNs = getWallClockNs(); + mElapsedTimestampNs = getElapsedRealtimeNs(); + mTagId = util::BINARY_PUSH_STATE_CHANGED; + mLogUid = AIBinder_getCallingUid(); + mLogPid = AIBinder_getCallingPid(); + + mValues.push_back(FieldValue(Field(mTagId, getSimpleField(1)), Value(trainName))); + mValues.push_back(FieldValue(Field(mTagId, getSimpleField(2)), Value(trainVersionCode))); + mValues.push_back(FieldValue(Field(mTagId, getSimpleField(3)), Value((int)requiresStaging))); + mValues.push_back(FieldValue(Field(mTagId, getSimpleField(4)), Value((int)rollbackEnabled))); + mValues.push_back( + FieldValue(Field(mTagId, getSimpleField(5)), Value((int)requiresLowLatencyMonitor))); + mValues.push_back(FieldValue(Field(mTagId, getSimpleField(6)), Value(state))); + mValues.push_back(FieldValue(Field(mTagId, getSimpleField(7)), Value(experimentIds))); + mValues.push_back(FieldValue(Field(mTagId, getSimpleField(8)), Value(userId))); +} + +LogEvent::LogEvent(int64_t wallClockTimestampNs, int64_t elapsedTimestampNs, + const InstallTrainInfo& trainInfo) { + mLogdTimestampNs = wallClockTimestampNs; + mElapsedTimestampNs = elapsedTimestampNs; + mTagId = util::TRAIN_INFO; + + mValues.push_back( + FieldValue(Field(mTagId, getSimpleField(1)), Value(trainInfo.trainVersionCode))); + std::vector<uint8_t> experimentIdsProto; + writeExperimentIdsToProto(trainInfo.experimentIds, &experimentIdsProto); + mValues.push_back(FieldValue(Field(mTagId, getSimpleField(2)), Value(experimentIdsProto))); + mValues.push_back(FieldValue(Field(mTagId, getSimpleField(3)), Value(trainInfo.trainName))); + mValues.push_back(FieldValue(Field(mTagId, getSimpleField(4)), Value(trainInfo.status))); +} + +void LogEvent::parseInt32(int32_t* pos, int32_t depth, bool* last, uint8_t numAnnotations) { + int32_t value = readNextValue<int32_t>(); + addToValues(pos, depth, value, last); + parseAnnotations(numAnnotations); +} + +void LogEvent::parseInt64(int32_t* pos, int32_t depth, bool* last, uint8_t numAnnotations) { + int64_t value = readNextValue<int64_t>(); + addToValues(pos, depth, value, last); + parseAnnotations(numAnnotations); +} + +void LogEvent::parseString(int32_t* pos, int32_t depth, bool* last, uint8_t numAnnotations) { + int32_t numBytes = readNextValue<int32_t>(); + if ((uint32_t)numBytes > mRemainingLen) { + mValid = false; + return; + } + + string value = string((char*)mBuf, numBytes); + mBuf += numBytes; + mRemainingLen -= numBytes; + addToValues(pos, depth, value, last); + parseAnnotations(numAnnotations); +} + +void LogEvent::parseFloat(int32_t* pos, int32_t depth, bool* last, uint8_t numAnnotations) { + float value = readNextValue<float>(); + addToValues(pos, depth, value, last); + parseAnnotations(numAnnotations); +} + +void LogEvent::parseBool(int32_t* pos, int32_t depth, bool* last, uint8_t numAnnotations) { + // cast to int32_t because FieldValue does not support bools + int32_t value = (int32_t)readNextValue<uint8_t>(); + addToValues(pos, depth, value, last); + parseAnnotations(numAnnotations); +} + +void LogEvent::parseByteArray(int32_t* pos, int32_t depth, bool* last, uint8_t numAnnotations) { + int32_t numBytes = readNextValue<int32_t>(); + if ((uint32_t)numBytes > mRemainingLen) { + mValid = false; + return; + } + + vector<uint8_t> value(mBuf, mBuf + numBytes); + mBuf += numBytes; + mRemainingLen -= numBytes; + addToValues(pos, depth, value, last); + parseAnnotations(numAnnotations); +} + +void LogEvent::parseKeyValuePairs(int32_t* pos, int32_t depth, bool* last, uint8_t numAnnotations) { + int32_t numPairs = readNextValue<uint8_t>(); + + for (pos[1] = 1; pos[1] <= numPairs; pos[1]++) { + last[1] = (pos[1] == numPairs); + + // parse key + pos[2] = 1; + parseInt32(pos, /*depth=*/2, last, /*numAnnotations=*/0); + + // parse value + last[2] = true; + + uint8_t typeInfo = readNextValue<uint8_t>(); + switch (getTypeId(typeInfo)) { + case INT32_TYPE: + pos[2] = 2; // pos[2] determined by index of type in KeyValuePair in atoms.proto + parseInt32(pos, /*depth=*/2, last, /*numAnnotations=*/0); + break; + case INT64_TYPE: + pos[2] = 3; + parseInt64(pos, /*depth=*/2, last, /*numAnnotations=*/0); + break; + case STRING_TYPE: + pos[2] = 4; + parseString(pos, /*depth=*/2, last, /*numAnnotations=*/0); + break; + case FLOAT_TYPE: + pos[2] = 5; + parseFloat(pos, /*depth=*/2, last, /*numAnnotations=*/0); + break; + default: + mValid = false; + } + } + + parseAnnotations(numAnnotations); + + pos[1] = pos[2] = 1; + last[1] = last[2] = false; +} + +void LogEvent::parseAttributionChain(int32_t* pos, int32_t depth, bool* last, + uint8_t numAnnotations) { + const unsigned int firstUidInChainIndex = mValues.size(); + const int32_t numNodes = readNextValue<uint8_t>(); + for (pos[1] = 1; pos[1] <= numNodes; pos[1]++) { + last[1] = (pos[1] == numNodes); + + // parse uid + pos[2] = 1; + parseInt32(pos, /*depth=*/2, last, /*numAnnotations=*/0); + + // parse tag + pos[2] = 2; + last[2] = true; + parseString(pos, /*depth=*/2, last, /*numAnnotations=*/0); + } + + if (mValues.size() - 1 > INT8_MAX) { + mValid = false; + } else if (mValues.size() - 1 > firstUidInChainIndex) { + // At least one node was successfully parsed. + mAttributionChainStartIndex = static_cast<int8_t>(firstUidInChainIndex); + mAttributionChainEndIndex = static_cast<int8_t>(mValues.size() - 1); + } + + if (mValid) { + parseAnnotations(numAnnotations, firstUidInChainIndex); + } + + pos[1] = pos[2] = 1; + last[1] = last[2] = false; +} + +// Assumes that mValues is not empty +bool LogEvent::checkPreviousValueType(Type expected) { + return mValues[mValues.size() - 1].mValue.getType() == expected; +} + +void LogEvent::parseIsUidAnnotation(uint8_t annotationType) { + if (mValues.empty() || mValues.size() - 1 > INT8_MAX || !checkPreviousValueType(INT) + || annotationType != BOOL_TYPE) { + mValid = false; + return; + } + + bool isUid = readNextValue<uint8_t>(); + if (isUid) mUidFieldIndex = static_cast<int8_t>(mValues.size() - 1); + mValues[mValues.size() - 1].mAnnotations.setUidField(isUid); +} + +void LogEvent::parseTruncateTimestampAnnotation(uint8_t annotationType) { + if (!mValues.empty() || annotationType != BOOL_TYPE) { + mValid = false; + return; + } + + mTruncateTimestamp = readNextValue<uint8_t>(); +} + +void LogEvent::parsePrimaryFieldAnnotation(uint8_t annotationType) { + if (mValues.empty() || annotationType != BOOL_TYPE) { + mValid = false; + return; + } + + const bool primaryField = readNextValue<uint8_t>(); + mValues[mValues.size() - 1].mAnnotations.setPrimaryField(primaryField); +} + +void LogEvent::parsePrimaryFieldFirstUidAnnotation(uint8_t annotationType, + int firstUidInChainIndex) { + if (mValues.empty() || annotationType != BOOL_TYPE || -1 == firstUidInChainIndex) { + mValid = false; + return; + } + + if (static_cast<int>(mValues.size() - 1) < firstUidInChainIndex) { // AttributionChain is empty. + mValid = false; + android_errorWriteLog(0x534e4554, "174485572"); + return; + } + + const bool primaryField = readNextValue<uint8_t>(); + mValues[firstUidInChainIndex].mAnnotations.setPrimaryField(primaryField); +} + +void LogEvent::parseExclusiveStateAnnotation(uint8_t annotationType) { + if (mValues.empty() || annotationType != BOOL_TYPE) { + mValid = false; + return; + } + + if (mValues.size() - 1 > INT8_MAX) { + android_errorWriteLog(0x534e4554, "174488848"); + mValid = false; + return; + } + + const bool exclusiveState = readNextValue<uint8_t>(); + mExclusiveStateFieldIndex = static_cast<int8_t>(mValues.size() - 1); + mValues[getExclusiveStateFieldIndex()].mAnnotations.setExclusiveState(exclusiveState); +} + +void LogEvent::parseTriggerStateResetAnnotation(uint8_t annotationType) { + if (mValues.empty() || annotationType != INT32_TYPE) { + mValid = false; + return; + } + + mResetState = readNextValue<int32_t>(); +} + +void LogEvent::parseStateNestedAnnotation(uint8_t annotationType) { + if (mValues.empty() || annotationType != BOOL_TYPE) { + mValid = false; + return; + } + + bool nested = readNextValue<uint8_t>(); + mValues[mValues.size() - 1].mAnnotations.setNested(nested); +} + +// firstUidInChainIndex is a default parameter that is only needed when parsing +// annotations for attribution chains. +void LogEvent::parseAnnotations(uint8_t numAnnotations, int firstUidInChainIndex) { + for (uint8_t i = 0; i < numAnnotations; i++) { + uint8_t annotationId = readNextValue<uint8_t>(); + uint8_t annotationType = readNextValue<uint8_t>(); + + switch (annotationId) { + case ANNOTATION_ID_IS_UID: + parseIsUidAnnotation(annotationType); + break; + case ANNOTATION_ID_TRUNCATE_TIMESTAMP: + parseTruncateTimestampAnnotation(annotationType); + break; + case ANNOTATION_ID_PRIMARY_FIELD: + parsePrimaryFieldAnnotation(annotationType); + break; + case ANNOTATION_ID_PRIMARY_FIELD_FIRST_UID: + parsePrimaryFieldFirstUidAnnotation(annotationType, firstUidInChainIndex); + break; + case ANNOTATION_ID_EXCLUSIVE_STATE: + parseExclusiveStateAnnotation(annotationType); + break; + case ANNOTATION_ID_TRIGGER_STATE_RESET: + parseTriggerStateResetAnnotation(annotationType); + break; + case ANNOTATION_ID_STATE_NESTED: + parseStateNestedAnnotation(annotationType); + break; + default: + mValid = false; + return; + } + } +} + +// This parsing logic is tied to the encoding scheme used in StatsEvent.java and +// stats_event.c +bool LogEvent::parseBuffer(uint8_t* buf, size_t len) { + mBuf = buf; + mRemainingLen = (uint32_t)len; + + int32_t pos[] = {1, 1, 1}; + bool last[] = {false, false, false}; + + // Beginning of buffer is OBJECT_TYPE | NUM_FIELDS | TIMESTAMP | ATOM_ID + uint8_t typeInfo = readNextValue<uint8_t>(); + if (getTypeId(typeInfo) != OBJECT_TYPE) mValid = false; + + uint8_t numElements = readNextValue<uint8_t>(); + if (numElements < 2 || numElements > 127) mValid = false; + + typeInfo = readNextValue<uint8_t>(); + if (getTypeId(typeInfo) != INT64_TYPE) mValid = false; + mElapsedTimestampNs = readNextValue<int64_t>(); + numElements--; + + typeInfo = readNextValue<uint8_t>(); + if (getTypeId(typeInfo) != INT32_TYPE) mValid = false; + mTagId = readNextValue<int32_t>(); + numElements--; + parseAnnotations(getNumAnnotations(typeInfo)); // atom-level annotations + + for (pos[0] = 1; pos[0] <= numElements && mValid; pos[0]++) { + last[0] = (pos[0] == numElements); + + typeInfo = readNextValue<uint8_t>(); + uint8_t typeId = getTypeId(typeInfo); + + switch (typeId) { + case BOOL_TYPE: + parseBool(pos, /*depth=*/0, last, getNumAnnotations(typeInfo)); + break; + case INT32_TYPE: + parseInt32(pos, /*depth=*/0, last, getNumAnnotations(typeInfo)); + break; + case INT64_TYPE: + parseInt64(pos, /*depth=*/0, last, getNumAnnotations(typeInfo)); + break; + case FLOAT_TYPE: + parseFloat(pos, /*depth=*/0, last, getNumAnnotations(typeInfo)); + break; + case BYTE_ARRAY_TYPE: + parseByteArray(pos, /*depth=*/0, last, getNumAnnotations(typeInfo)); + break; + case STRING_TYPE: + parseString(pos, /*depth=*/0, last, getNumAnnotations(typeInfo)); + break; + case KEY_VALUE_PAIRS_TYPE: + parseKeyValuePairs(pos, /*depth=*/0, last, getNumAnnotations(typeInfo)); + break; + case ATTRIBUTION_CHAIN_TYPE: + parseAttributionChain(pos, /*depth=*/0, last, getNumAnnotations(typeInfo)); + break; + case ERROR_TYPE: + /* mErrorBitmask =*/ readNextValue<int32_t>(); + mValid = false; + break; + default: + mValid = false; + break; + } + } + + if (mRemainingLen != 0) mValid = false; + mBuf = nullptr; + return mValid; +} + +uint8_t LogEvent::getTypeId(uint8_t typeInfo) { + return typeInfo & 0x0F; // type id in lower 4 bytes +} + +uint8_t LogEvent::getNumAnnotations(uint8_t typeInfo) { + return (typeInfo >> 4) & 0x0F; // num annotations in upper 4 bytes +} + +int64_t LogEvent::GetLong(size_t key, status_t* err) const { + // TODO(b/110561208): encapsulate the magical operations in Field struct as static functions + int field = getSimpleField(key); + for (const auto& value : mValues) { + if (value.mField.getField() == field) { + if (value.mValue.getType() == LONG) { + return value.mValue.long_value; + } else if (value.mValue.getType() == INT) { + return value.mValue.int_value; + } else { + *err = BAD_TYPE; + return 0; + } + } + if ((size_t)value.mField.getPosAtDepth(0) > key) { + break; + } + } + + *err = BAD_INDEX; + return 0; +} + +int LogEvent::GetInt(size_t key, status_t* err) const { + int field = getSimpleField(key); + for (const auto& value : mValues) { + if (value.mField.getField() == field) { + if (value.mValue.getType() == INT) { + return value.mValue.int_value; + } else { + *err = BAD_TYPE; + return 0; + } + } + if ((size_t)value.mField.getPosAtDepth(0) > key) { + break; + } + } + + *err = BAD_INDEX; + return 0; +} + +const char* LogEvent::GetString(size_t key, status_t* err) const { + int field = getSimpleField(key); + for (const auto& value : mValues) { + if (value.mField.getField() == field) { + if (value.mValue.getType() == STRING) { + return value.mValue.str_value.c_str(); + } else { + *err = BAD_TYPE; + return 0; + } + } + if ((size_t)value.mField.getPosAtDepth(0) > key) { + break; + } + } + + *err = BAD_INDEX; + return NULL; +} + +bool LogEvent::GetBool(size_t key, status_t* err) const { + int field = getSimpleField(key); + for (const auto& value : mValues) { + if (value.mField.getField() == field) { + if (value.mValue.getType() == INT) { + return value.mValue.int_value != 0; + } else if (value.mValue.getType() == LONG) { + return value.mValue.long_value != 0; + } else { + *err = BAD_TYPE; + return false; + } + } + if ((size_t)value.mField.getPosAtDepth(0) > key) { + break; + } + } + + *err = BAD_INDEX; + return false; +} + +float LogEvent::GetFloat(size_t key, status_t* err) const { + int field = getSimpleField(key); + for (const auto& value : mValues) { + if (value.mField.getField() == field) { + if (value.mValue.getType() == FLOAT) { + return value.mValue.float_value; + } else { + *err = BAD_TYPE; + return 0.0; + } + } + if ((size_t)value.mField.getPosAtDepth(0) > key) { + break; + } + } + + *err = BAD_INDEX; + return 0.0; +} + +std::vector<uint8_t> LogEvent::GetStorage(size_t key, status_t* err) const { + int field = getSimpleField(key); + for (const auto& value : mValues) { + if (value.mField.getField() == field) { + if (value.mValue.getType() == STORAGE) { + return value.mValue.storage_value; + } else { + *err = BAD_TYPE; + return vector<uint8_t>(); + } + } + if ((size_t)value.mField.getPosAtDepth(0) > key) { + break; + } + } + + *err = BAD_INDEX; + return vector<uint8_t>(); +} + +string LogEvent::ToString() const { + string result; + result += StringPrintf("{ uid(%d) %lld %lld (%d)", mLogUid, (long long)mLogdTimestampNs, + (long long)mElapsedTimestampNs, mTagId); + for (const auto& value : mValues) { + result += + StringPrintf("%#x", value.mField.getField()) + "->" + value.mValue.toString() + " "; + } + result += " }"; + return result; +} + +void LogEvent::ToProto(ProtoOutputStream& protoOutput) const { + writeFieldValueTreeToStream(mTagId, getValues(), &protoOutput); +} + +bool LogEvent::hasAttributionChain(std::pair<int, int>* indexRange) const { + if (mAttributionChainStartIndex == -1 || mAttributionChainEndIndex == -1) { + return false; + } + + if (nullptr != indexRange) { + indexRange->first = static_cast<int>(mAttributionChainStartIndex); + indexRange->second = static_cast<int>(mAttributionChainEndIndex); + } + + return true; +} + +void writeExperimentIdsToProto(const std::vector<int64_t>& experimentIds, + std::vector<uint8_t>* protoOut) { + ProtoOutputStream proto; + for (const auto& expId : experimentIds) { + proto.write(FIELD_TYPE_INT64 | FIELD_COUNT_REPEATED | FIELD_ID_EXPERIMENT_ID, + (long long)expId); + } + + protoOut->resize(proto.size()); + size_t pos = 0; + sp<ProtoReader> reader = proto.data(); + while (reader->readBuffer() != NULL) { + size_t toRead = reader->currentToRead(); + std::memcpy(protoOut->data() + pos, reader->readBuffer(), toRead); + pos += toRead; + reader->move(toRead); + } +} + +} // namespace statsd +} // namespace os +} // namespace android diff --git a/cmds/statsd/tests/LogEvent_test.cpp b/cmds/statsd/tests/LogEvent_test.cpp new file mode 100644 index 000000000000..aed25475da11 --- /dev/null +++ b/cmds/statsd/tests/LogEvent_test.cpp @@ -0,0 +1,481 @@ +// Copyright (C) 2017 The Android Open Source Project +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "src/logd/LogEvent.h" + +#include <gtest/gtest.h> + +#include "frameworks/base/cmds/statsd/src/atoms.pb.h" +#include "frameworks/base/core/proto/android/stats/launcher/launcher.pb.h" +#include "log/log_event_list.h" +#include "stats_event.h" + +#ifdef __ANDROID__ + +namespace android { +namespace os { +namespace statsd { + +using std::string; +using std::vector; +using util::ProtoOutputStream; +using util::ProtoReader; + +namespace { + +Field getField(int32_t tag, const vector<int32_t>& pos, int32_t depth, const vector<bool>& last) { + Field f(tag, (int32_t*)pos.data(), depth); + + // For loop starts at 1 because the last field at depth 0 is not decorated. + for (int i = 1; i < depth; i++) { + if (last[i]) f.decorateLastPos(i); + } + + return f; +} + +void createIntWithBoolAnnotationLogEvent(LogEvent* logEvent, uint8_t annotationId, + bool annotationValue) { + AStatsEvent* statsEvent = AStatsEvent_obtain(); + AStatsEvent_setAtomId(statsEvent, /*atomId=*/100); + AStatsEvent_writeInt32(statsEvent, 10); + AStatsEvent_addBoolAnnotation(statsEvent, annotationId, annotationValue); + AStatsEvent_build(statsEvent); + + size_t size; + uint8_t* buf = AStatsEvent_getBuffer(statsEvent, &size); + EXPECT_TRUE(logEvent->parseBuffer(buf, size)); + + AStatsEvent_release(statsEvent); +} + +void createIntWithIntAnnotationLogEvent(LogEvent* logEvent, uint8_t annotationId, + int annotationValue) { + AStatsEvent* statsEvent = AStatsEvent_obtain(); + AStatsEvent_setAtomId(statsEvent, /*atomId=*/100); + AStatsEvent_writeInt32(statsEvent, 10); + AStatsEvent_addInt32Annotation(statsEvent, annotationId, annotationValue); + AStatsEvent_build(statsEvent); + + size_t size; + uint8_t* buf = AStatsEvent_getBuffer(statsEvent, &size); + EXPECT_TRUE(logEvent->parseBuffer(buf, size)); + + AStatsEvent_release(statsEvent); +} + +} // anonymous namespace + +TEST(LogEventTest, TestPrimitiveParsing) { + AStatsEvent* event = AStatsEvent_obtain(); + AStatsEvent_setAtomId(event, 100); + AStatsEvent_writeInt32(event, 10); + AStatsEvent_writeInt64(event, 0x123456789); + AStatsEvent_writeFloat(event, 2.0); + AStatsEvent_writeBool(event, true); + AStatsEvent_build(event); + + size_t size; + uint8_t* buf = AStatsEvent_getBuffer(event, &size); + + LogEvent logEvent(/*uid=*/1000, /*pid=*/1001); + EXPECT_TRUE(logEvent.parseBuffer(buf, size)); + + EXPECT_EQ(100, logEvent.GetTagId()); + EXPECT_EQ(1000, logEvent.GetUid()); + EXPECT_EQ(1001, logEvent.GetPid()); + EXPECT_FALSE(logEvent.hasAttributionChain()); + + const vector<FieldValue>& values = logEvent.getValues(); + ASSERT_EQ(4, values.size()); + + const FieldValue& int32Item = values[0]; + Field expectedField = getField(100, {1, 1, 1}, 0, {false, false, false}); + EXPECT_EQ(expectedField, int32Item.mField); + EXPECT_EQ(Type::INT, int32Item.mValue.getType()); + EXPECT_EQ(10, int32Item.mValue.int_value); + + const FieldValue& int64Item = values[1]; + expectedField = getField(100, {2, 1, 1}, 0, {false, false, false}); + EXPECT_EQ(expectedField, int64Item.mField); + EXPECT_EQ(Type::LONG, int64Item.mValue.getType()); + EXPECT_EQ(0x123456789, int64Item.mValue.long_value); + + const FieldValue& floatItem = values[2]; + expectedField = getField(100, {3, 1, 1}, 0, {false, false, false}); + EXPECT_EQ(expectedField, floatItem.mField); + EXPECT_EQ(Type::FLOAT, floatItem.mValue.getType()); + EXPECT_EQ(2.0, floatItem.mValue.float_value); + + const FieldValue& boolItem = values[3]; + expectedField = getField(100, {4, 1, 1}, 0, {true, false, false}); + EXPECT_EQ(expectedField, boolItem.mField); + EXPECT_EQ(Type::INT, boolItem.mValue.getType()); // FieldValue does not support boolean type + EXPECT_EQ(1, boolItem.mValue.int_value); + + AStatsEvent_release(event); +} + +TEST(LogEventTest, TestStringAndByteArrayParsing) { + AStatsEvent* event = AStatsEvent_obtain(); + AStatsEvent_setAtomId(event, 100); + string str = "test"; + AStatsEvent_writeString(event, str.c_str()); + AStatsEvent_writeByteArray(event, (uint8_t*)str.c_str(), str.length()); + AStatsEvent_build(event); + + size_t size; + uint8_t* buf = AStatsEvent_getBuffer(event, &size); + + LogEvent logEvent(/*uid=*/1000, /*pid=*/1001); + EXPECT_TRUE(logEvent.parseBuffer(buf, size)); + + EXPECT_EQ(100, logEvent.GetTagId()); + EXPECT_EQ(1000, logEvent.GetUid()); + EXPECT_EQ(1001, logEvent.GetPid()); + EXPECT_FALSE(logEvent.hasAttributionChain()); + + const vector<FieldValue>& values = logEvent.getValues(); + ASSERT_EQ(2, values.size()); + + const FieldValue& stringItem = values[0]; + Field expectedField = getField(100, {1, 1, 1}, 0, {false, false, false}); + EXPECT_EQ(expectedField, stringItem.mField); + EXPECT_EQ(Type::STRING, stringItem.mValue.getType()); + EXPECT_EQ(str, stringItem.mValue.str_value); + + const FieldValue& storageItem = values[1]; + expectedField = getField(100, {2, 1, 1}, 0, {true, false, false}); + EXPECT_EQ(expectedField, storageItem.mField); + EXPECT_EQ(Type::STORAGE, storageItem.mValue.getType()); + vector<uint8_t> expectedValue = {'t', 'e', 's', 't'}; + EXPECT_EQ(expectedValue, storageItem.mValue.storage_value); + + AStatsEvent_release(event); +} + +TEST(LogEventTest, TestEmptyString) { + AStatsEvent* event = AStatsEvent_obtain(); + AStatsEvent_setAtomId(event, 100); + string empty = ""; + AStatsEvent_writeString(event, empty.c_str()); + AStatsEvent_build(event); + + size_t size; + uint8_t* buf = AStatsEvent_getBuffer(event, &size); + + LogEvent logEvent(/*uid=*/1000, /*pid=*/1001); + EXPECT_TRUE(logEvent.parseBuffer(buf, size)); + + EXPECT_EQ(100, logEvent.GetTagId()); + EXPECT_EQ(1000, logEvent.GetUid()); + EXPECT_EQ(1001, logEvent.GetPid()); + EXPECT_FALSE(logEvent.hasAttributionChain()); + + const vector<FieldValue>& values = logEvent.getValues(); + ASSERT_EQ(1, values.size()); + + const FieldValue& item = values[0]; + Field expectedField = getField(100, {1, 1, 1}, 0, {true, false, false}); + EXPECT_EQ(expectedField, item.mField); + EXPECT_EQ(Type::STRING, item.mValue.getType()); + EXPECT_EQ(empty, item.mValue.str_value); + + AStatsEvent_release(event); +} + +TEST(LogEventTest, TestByteArrayWithNullCharacter) { + AStatsEvent* event = AStatsEvent_obtain(); + AStatsEvent_setAtomId(event, 100); + uint8_t message[] = {'\t', 'e', '\0', 's', 't'}; + AStatsEvent_writeByteArray(event, message, 5); + AStatsEvent_build(event); + + size_t size; + uint8_t* buf = AStatsEvent_getBuffer(event, &size); + + LogEvent logEvent(/*uid=*/1000, /*pid=*/1001); + EXPECT_TRUE(logEvent.parseBuffer(buf, size)); + + EXPECT_EQ(100, logEvent.GetTagId()); + EXPECT_EQ(1000, logEvent.GetUid()); + EXPECT_EQ(1001, logEvent.GetPid()); + + const vector<FieldValue>& values = logEvent.getValues(); + ASSERT_EQ(1, values.size()); + + const FieldValue& item = values[0]; + Field expectedField = getField(100, {1, 1, 1}, 0, {true, false, false}); + EXPECT_EQ(expectedField, item.mField); + EXPECT_EQ(Type::STORAGE, item.mValue.getType()); + vector<uint8_t> expectedValue(message, message + 5); + EXPECT_EQ(expectedValue, item.mValue.storage_value); + + AStatsEvent_release(event); +} + +TEST(LogEventTest, TestAttributionChain) { + AStatsEvent* event = AStatsEvent_obtain(); + AStatsEvent_setAtomId(event, 100); + + string tag1 = "tag1"; + string tag2 = "tag2"; + + uint32_t uids[] = {1001, 1002}; + const char* tags[] = {tag1.c_str(), tag2.c_str()}; + + AStatsEvent_writeAttributionChain(event, uids, tags, 2); + AStatsEvent_build(event); + + size_t size; + uint8_t* buf = AStatsEvent_getBuffer(event, &size); + + LogEvent logEvent(/*uid=*/1000, /*pid=*/1001); + EXPECT_TRUE(logEvent.parseBuffer(buf, size)); + + EXPECT_EQ(100, logEvent.GetTagId()); + EXPECT_EQ(1000, logEvent.GetUid()); + EXPECT_EQ(1001, logEvent.GetPid()); + + const vector<FieldValue>& values = logEvent.getValues(); + ASSERT_EQ(4, values.size()); // 2 per attribution node + + std::pair<int, int> attrIndexRange; + EXPECT_TRUE(logEvent.hasAttributionChain(&attrIndexRange)); + EXPECT_EQ(0, attrIndexRange.first); + EXPECT_EQ(3, attrIndexRange.second); + + // Check first attribution node + const FieldValue& uid1Item = values[0]; + Field expectedField = getField(100, {1, 1, 1}, 2, {true, false, false}); + EXPECT_EQ(expectedField, uid1Item.mField); + EXPECT_EQ(Type::INT, uid1Item.mValue.getType()); + EXPECT_EQ(1001, uid1Item.mValue.int_value); + + const FieldValue& tag1Item = values[1]; + expectedField = getField(100, {1, 1, 2}, 2, {true, false, true}); + EXPECT_EQ(expectedField, tag1Item.mField); + EXPECT_EQ(Type::STRING, tag1Item.mValue.getType()); + EXPECT_EQ(tag1, tag1Item.mValue.str_value); + + // Check second attribution nodes + const FieldValue& uid2Item = values[2]; + expectedField = getField(100, {1, 2, 1}, 2, {true, true, false}); + EXPECT_EQ(expectedField, uid2Item.mField); + EXPECT_EQ(Type::INT, uid2Item.mValue.getType()); + EXPECT_EQ(1002, uid2Item.mValue.int_value); + + const FieldValue& tag2Item = values[3]; + expectedField = getField(100, {1, 2, 2}, 2, {true, true, true}); + EXPECT_EQ(expectedField, tag2Item.mField); + EXPECT_EQ(Type::STRING, tag2Item.mValue.getType()); + EXPECT_EQ(tag2, tag2Item.mValue.str_value); + + AStatsEvent_release(event); +} + +TEST(LogEventTest, TestAnnotationIdIsUid) { + LogEvent event(/*uid=*/0, /*pid=*/0); + createIntWithBoolAnnotationLogEvent(&event, ANNOTATION_ID_IS_UID, true); + + const vector<FieldValue>& values = event.getValues(); + ASSERT_EQ(values.size(), 1); + EXPECT_EQ(event.getUidFieldIndex(), 0); +} + +TEST(LogEventTest, TestAnnotationIdStateNested) { + LogEvent event(/*uid=*/0, /*pid=*/0); + createIntWithBoolAnnotationLogEvent(&event, ANNOTATION_ID_STATE_NESTED, true); + + const vector<FieldValue>& values = event.getValues(); + ASSERT_EQ(values.size(), 1); + EXPECT_TRUE(values[0].mAnnotations.isNested()); +} + +TEST(LogEventTest, TestPrimaryFieldAnnotation) { + LogEvent event(/*uid=*/0, /*pid=*/0); + createIntWithBoolAnnotationLogEvent(&event, ANNOTATION_ID_PRIMARY_FIELD, true); + + const vector<FieldValue>& values = event.getValues(); + ASSERT_EQ(values.size(), 1); + EXPECT_TRUE(values[0].mAnnotations.isPrimaryField()); +} + +TEST(LogEventTest, TestExclusiveStateAnnotation) { + LogEvent event(/*uid=*/0, /*pid=*/0); + createIntWithBoolAnnotationLogEvent(&event, ANNOTATION_ID_EXCLUSIVE_STATE, true); + + const vector<FieldValue>& values = event.getValues(); + ASSERT_EQ(values.size(), 1); + EXPECT_TRUE(values[0].mAnnotations.isExclusiveState()); +} + +TEST(LogEventTest, TestPrimaryFieldFirstUidAnnotation) { + // Event has 10 ints and then an attribution chain + int numInts = 10; + int firstUidInChainIndex = numInts; + string tag1 = "tag1"; + string tag2 = "tag2"; + uint32_t uids[] = {1001, 1002}; + const char* tags[] = {tag1.c_str(), tag2.c_str()}; + + // Construct AStatsEvent + AStatsEvent* statsEvent = AStatsEvent_obtain(); + AStatsEvent_setAtomId(statsEvent, 100); + for (int i = 0; i < numInts; i++) { + AStatsEvent_writeInt32(statsEvent, 10); + } + AStatsEvent_writeAttributionChain(statsEvent, uids, tags, 2); + AStatsEvent_addBoolAnnotation(statsEvent, ANNOTATION_ID_PRIMARY_FIELD_FIRST_UID, true); + AStatsEvent_build(statsEvent); + + // Construct LogEvent + size_t size; + uint8_t* buf = AStatsEvent_getBuffer(statsEvent, &size); + LogEvent logEvent(/*uid=*/0, /*pid=*/0); + EXPECT_TRUE(logEvent.parseBuffer(buf, size)); + AStatsEvent_release(statsEvent); + + // Check annotation + const vector<FieldValue>& values = logEvent.getValues(); + ASSERT_EQ(values.size(), numInts + 4); + EXPECT_TRUE(values[firstUidInChainIndex].mAnnotations.isPrimaryField()); +} + +TEST(LogEventTest, TestResetStateAnnotation) { + int32_t resetState = 10; + LogEvent event(/*uid=*/0, /*pid=*/0); + createIntWithIntAnnotationLogEvent(&event, ANNOTATION_ID_TRIGGER_STATE_RESET, resetState); + + const vector<FieldValue>& values = event.getValues(); + ASSERT_EQ(values.size(), 1); + EXPECT_EQ(event.getResetState(), resetState); +} + +TEST(LogEventTest, TestExclusiveStateAnnotationAfterTooManyFields) { + AStatsEvent* event = AStatsEvent_obtain(); + AStatsEvent_setAtomId(event, 100); + + const unsigned int numAttributionNodes = 64; + + uint32_t uids[numAttributionNodes]; + const char* tags[numAttributionNodes]; + + for (unsigned int i = 1; i <= numAttributionNodes; i++) { + uids[i-1] = i; + tags[i-1] = std::to_string(i).c_str(); + } + + AStatsEvent_writeAttributionChain(event, uids, tags, numAttributionNodes); + AStatsEvent_writeInt32(event, 1); + AStatsEvent_addBoolAnnotation(event, ANNOTATION_ID_EXCLUSIVE_STATE, true); + + AStatsEvent_build(event); + + size_t size; + uint8_t* buf = AStatsEvent_getBuffer(event, &size); + + LogEvent logEvent(/*uid=*/1000, /*pid=*/1001); + EXPECT_FALSE(logEvent.parseBuffer(buf, size)); + EXPECT_EQ(-1, logEvent.getExclusiveStateFieldIndex()); + + AStatsEvent_release(event); +} + +TEST(LogEventTest, TestUidAnnotationAfterTooManyFields) { + AStatsEvent* event = AStatsEvent_obtain(); + AStatsEvent_setAtomId(event, 100); + + const unsigned int numAttributionNodes = 64; + + uint32_t uids[numAttributionNodes]; + const char* tags[numAttributionNodes]; + + for (unsigned int i = 1; i <= numAttributionNodes; i++) { + uids[i-1] = i; + tags[i-1] = std::to_string(i).c_str(); + } + + AStatsEvent_writeAttributionChain(event, uids, tags, numAttributionNodes); + AStatsEvent_writeInt32(event, 1); + AStatsEvent_addBoolAnnotation(event, ANNOTATION_ID_IS_UID, true); + + AStatsEvent_build(event); + + size_t size; + uint8_t* buf = AStatsEvent_getBuffer(event, &size); + + LogEvent logEvent(/*uid=*/1000, /*pid=*/1001); + EXPECT_FALSE(logEvent.parseBuffer(buf, size)); + EXPECT_EQ(-1, logEvent.getUidFieldIndex()); + + AStatsEvent_release(event); +} + +TEST(LogEventTest, TestAttributionChainEndIndexAfterTooManyFields) { + AStatsEvent* event = AStatsEvent_obtain(); + AStatsEvent_setAtomId(event, 100); + + const unsigned int numAttributionNodes = 65; + + uint32_t uids[numAttributionNodes]; + const char* tags[numAttributionNodes]; + + for (unsigned int i = 1; i <= numAttributionNodes; i++) { + uids[i-1] = i; + tags[i-1] = std::to_string(i).c_str(); + } + + AStatsEvent_writeAttributionChain(event, uids, tags, numAttributionNodes); + + AStatsEvent_build(event); + + size_t size; + uint8_t* buf = AStatsEvent_getBuffer(event, &size); + + LogEvent logEvent(/*uid=*/1000, /*pid=*/1001); + EXPECT_FALSE(logEvent.parseBuffer(buf, size)); + EXPECT_FALSE(logEvent.hasAttributionChain()); + + AStatsEvent_release(event); +} + +TEST(LogEventTest, TestEmptyAttributionChainWithPrimaryFieldFirstUidAnnotation) { + AStatsEvent* event = AStatsEvent_obtain(); + AStatsEvent_setAtomId(event, 100); + + uint32_t uids[] = {}; + const char* tags[] = {}; + + AStatsEvent_writeInt32(event, 10); + AStatsEvent_writeAttributionChain(event, uids, tags, 0); + AStatsEvent_addBoolAnnotation(event, ANNOTATION_ID_PRIMARY_FIELD_FIRST_UID, true); + + AStatsEvent_build(event); + + size_t size; + uint8_t* buf = AStatsEvent_getBuffer(event, &size); + + LogEvent logEvent(/*uid=*/1000, /*pid=*/1001); + EXPECT_FALSE(logEvent.parseBuffer(buf, size)); + + AStatsEvent_release(event); +} + +} // namespace statsd +} // namespace os +} // namespace android +#else +GTEST_LOG_(INFO) << "This test does nothing.\n"; +#endif diff --git a/config/OWNERS b/config/OWNERS index 001038d139c4..0691dbc4dcb0 100644 --- a/config/OWNERS +++ b/config/OWNERS @@ -1,14 +1,8 @@ include /ZYGOTE_OWNERS -# compat-team@ for changes to hiddenapi files - -per-file hiddenapi-* = andreionea@google.com, mathewi@google.com, satayev@google.com - # art-team@ manages the boot image profiles per-file boot-* = calin@google.com, mathieuc@google.com, ngeoffray@google.com per-file dirty-image-objects = calin@google.com, mathieuc@google.com, ngeoffray@google.com per-file generate-preloaded-classes.sh = calin@google.com, mathieuc@google.com, ngeoffray@google.com per-file preloaded-classes* = calin@google.com, mathieuc@google.com, ngeoffray@google.com -# Escalations: -per-file hiddenapi-* = bdc@google.com, narayan@google.com diff --git a/core/api/current.txt b/core/api/current.txt index b944ac98bb79..2a16084f348e 100644 --- a/core/api/current.txt +++ b/core/api/current.txt @@ -978,7 +978,7 @@ package android { field public static final int multiArch = 16843918; // 0x101048e field public static final int multiprocess = 16842771; // 0x1010013 field public static final int name = 16842755; // 0x1010003 - field public static final int nativeHeapZeroInit = 16844314; // 0x101061a + field public static final int nativeHeapZeroInitialized = 16844314; // 0x101061a field public static final int navigationBarColor = 16843858; // 0x1010452 field public static final int navigationBarDividerColor = 16844141; // 0x101056d field public static final int navigationContentDescription = 16843969; // 0x10104c1 @@ -11466,7 +11466,7 @@ package android.content.pm { method public static CharSequence getCategoryTitle(android.content.Context, int); method public int getGwpAsanMode(); method public int getMemtagMode(); - method @Nullable public Boolean isNativeHeapZeroInit(); + method public int getNativeHeapZeroInitialized(); method public boolean isProfileableByShell(); method public boolean isResourceOverlay(); method public boolean isVirtualPreload(); @@ -11520,6 +11520,9 @@ package android.content.pm { field public static final int MEMTAG_DEFAULT = -1; // 0xffffffff field public static final int MEMTAG_OFF = 0; // 0x0 field public static final int MEMTAG_SYNC = 2; // 0x2 + field public static final int ZEROINIT_DEFAULT = -1; // 0xffffffff + field public static final int ZEROINIT_DISABLED = 0; // 0x0 + field public static final int ZEROINIT_ENABLED = 1; // 0x1 field public String appComponentFactory; field public String backupAgentName; field public int category; @@ -29284,7 +29287,6 @@ package android.os { field public static final String HARDWARE; field public static final String HOST; field public static final String ID; - field public static final boolean IS_DEBUGGABLE; field public static final String MANUFACTURER; field public static final String MODEL; field @NonNull public static final String ODM_SKU; @@ -33998,8 +34000,8 @@ package android.provider { public static final class SimPhonebookContract.SimRecords { method @NonNull public static android.net.Uri getContentUri(int, int); - method @WorkerThread public static int getEncodedNameLength(@NonNull android.content.ContentResolver, @NonNull String); - method @NonNull public static android.net.Uri getItemUri(int, int, int); + method @IntRange(from=0) @WorkerThread public static int getEncodedNameLength(@NonNull android.content.ContentResolver, @NonNull String); + method @NonNull public static android.net.Uri getItemUri(int, int, @IntRange(from=1) int); field public static final String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/sim-contact_v2"; field public static final String CONTENT_TYPE = "vnd.android.cursor.dir/sim-contact_v2"; field public static final String ELEMENTARY_FILE_TYPE = "elementary_file_type"; diff --git a/core/api/module-lib-current.txt b/core/api/module-lib-current.txt index fe8b9d6e4fa0..b1e3e1464e3b 100644 --- a/core/api/module-lib-current.txt +++ b/core/api/module-lib-current.txt @@ -27,10 +27,6 @@ package android.content { field public static final String TEST_NETWORK_SERVICE = "test_network"; } - public class Intent implements java.lang.Cloneable android.os.Parcelable { - field public static final String ACTION_CLEAR_DNS_CACHE = "android.intent.action.CLEAR_DNS_CACHE"; - } - } package android.net { @@ -102,7 +98,7 @@ package android.net { } public class VpnManager { - field @Deprecated public static final int TYPE_VPN_LEGACY = 3; // 0x3 + field public static final int TYPE_VPN_LEGACY = 3; // 0x3 field public static final int TYPE_VPN_NONE = -1; // 0xffffffff field public static final int TYPE_VPN_OEM = 4; // 0x4 field public static final int TYPE_VPN_PLATFORM = 2; // 0x2 @@ -121,6 +117,10 @@ package android.os { method public final void markVintfStability(); } + public class Build { + method public static boolean isDebuggable(); + } + public static class Build.VERSION { field public static final int FIRST_SDK_INT; } diff --git a/core/api/system-current.txt b/core/api/system-current.txt index e6624cdb865a..9e82cfb3257c 100644 --- a/core/api/system-current.txt +++ b/core/api/system-current.txt @@ -1480,6 +1480,7 @@ package android.bluetooth { method public boolean disableBLE(); method public boolean enableBLE(); method @RequiresPermission(android.Manifest.permission.BLUETOOTH_ADMIN) public boolean enableNoAutoConnect(); + method @RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED) public void generateLocalOobData(int, @NonNull java.util.concurrent.Executor, @NonNull android.bluetooth.BluetoothAdapter.OobDataCallback); method @RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED) public long getDiscoveryEndMillis(); method public boolean isBleScanAlwaysAvailable(); method public boolean isLeEnabled(); @@ -1491,12 +1492,20 @@ package android.bluetooth { field public static final int ACTIVE_DEVICE_ALL = 2; // 0x2 field public static final int ACTIVE_DEVICE_AUDIO = 0; // 0x0 field public static final int ACTIVE_DEVICE_PHONE_CALL = 1; // 0x1 + field public static final int OOB_ERROR_ADAPTER_DISABLED = 2; // 0x2 + field public static final int OOB_ERROR_ANOTHER_ACTIVE_REQUEST = 1; // 0x1 + field public static final int OOB_ERROR_UNKNOWN = 0; // 0x0 } public static interface BluetoothAdapter.OnMetadataChangedListener { method public void onMetadataChanged(@NonNull android.bluetooth.BluetoothDevice, int, @Nullable byte[]); } + public static interface BluetoothAdapter.OobDataCallback { + method public void onError(int); + method public void onOobData(int, @Nullable android.bluetooth.OobData); + } + public final class BluetoothDevice implements android.os.Parcelable { method @RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED) public boolean cancelBondProcess(); method @RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED) public boolean createBondOutOfBand(int, @Nullable android.bluetooth.OobData, @Nullable android.bluetooth.OobData); @@ -6092,10 +6101,6 @@ package android.metrics { package android.net { - public class DnsResolverServiceManager { - method @NonNull @RequiresPermission(android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK) public static android.os.IBinder getService(@NonNull android.content.Context); - } - public class EthernetManager { method @NonNull @RequiresPermission(anyOf={android.Manifest.permission.NETWORK_STACK, android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK}) public android.net.EthernetManager.TetheredInterfaceRequest requestTetheredInterface(@NonNull java.util.concurrent.Executor, @NonNull android.net.EthernetManager.TetheredInterfaceCallback); } @@ -6728,12 +6733,18 @@ package android.nfc { method @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public boolean enableSecureNfc(boolean); method @RequiresPermission(android.Manifest.permission.NFC_SET_CONTROLLER_ALWAYS_ON) public boolean isControllerAlwaysOn(); method @RequiresPermission(android.Manifest.permission.NFC_SET_CONTROLLER_ALWAYS_ON) public boolean isControllerAlwaysOnSupported(); + method @RequiresPermission(android.Manifest.permission.NFC_SET_CONTROLLER_ALWAYS_ON) public void registerControllerAlwaysOnListener(@NonNull java.util.concurrent.Executor, @NonNull android.nfc.NfcAdapter.ControllerAlwaysOnListener); method @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public boolean removeNfcUnlockHandler(android.nfc.NfcAdapter.NfcUnlockHandler); method @RequiresPermission(android.Manifest.permission.NFC_SET_CONTROLLER_ALWAYS_ON) public boolean setControllerAlwaysOn(boolean); method public void setNdefPushMessage(android.nfc.NdefMessage, android.app.Activity, int); + method @RequiresPermission(android.Manifest.permission.NFC_SET_CONTROLLER_ALWAYS_ON) public void unregisterControllerAlwaysOnListener(@NonNull android.nfc.NfcAdapter.ControllerAlwaysOnListener); field public static final int FLAG_NDEF_PUSH_NO_CONFIRM = 1; // 0x1 } + public static interface NfcAdapter.ControllerAlwaysOnListener { + method public void onControllerAlwaysOnChanged(boolean); + } + public static interface NfcAdapter.NfcUnlockHandler { method public boolean onUnlockAttempted(android.nfc.Tag); } @@ -6802,14 +6813,14 @@ package android.os { method @NonNull @RequiresPermission(android.Manifest.permission.UPDATE_DEVICE_STATS) public android.os.connectivity.WifiBatteryStats getWifiBatteryStats(); method @RequiresPermission(android.Manifest.permission.UPDATE_DEVICE_STATS) public void reportFullWifiLockAcquiredFromSource(@NonNull android.os.WorkSource); method @RequiresPermission(android.Manifest.permission.UPDATE_DEVICE_STATS) public void reportFullWifiLockReleasedFromSource(@NonNull android.os.WorkSource); - method @RequiresPermission(android.Manifest.permission.UPDATE_DEVICE_STATS) public void reportMobileRadioPowerState(boolean, int) throws java.lang.RuntimeException; + method @RequiresPermission(android.Manifest.permission.UPDATE_DEVICE_STATS) public void reportMobileRadioPowerState(boolean, int); method @RequiresPermission(android.Manifest.permission.UPDATE_DEVICE_STATS) public void reportWifiBatchedScanStartedFromSource(@NonNull android.os.WorkSource, @IntRange(from=0) int); method @RequiresPermission(android.Manifest.permission.UPDATE_DEVICE_STATS) public void reportWifiBatchedScanStoppedFromSource(@NonNull android.os.WorkSource); method @RequiresPermission(android.Manifest.permission.UPDATE_DEVICE_STATS) public void reportWifiMulticastDisabled(@NonNull android.os.WorkSource); method @RequiresPermission(android.Manifest.permission.UPDATE_DEVICE_STATS) public void reportWifiMulticastEnabled(@NonNull android.os.WorkSource); method @RequiresPermission(android.Manifest.permission.UPDATE_DEVICE_STATS) public void reportWifiOff(); method @RequiresPermission(android.Manifest.permission.UPDATE_DEVICE_STATS) public void reportWifiOn(); - method @RequiresPermission(android.Manifest.permission.UPDATE_DEVICE_STATS) public void reportWifiRadioPowerState(boolean, int) throws java.lang.RuntimeException; + method @RequiresPermission(android.Manifest.permission.UPDATE_DEVICE_STATS) public void reportWifiRadioPowerState(boolean, int); method @RequiresPermission(android.Manifest.permission.UPDATE_DEVICE_STATS) public void reportWifiRssiChanged(@IntRange(from=0xffffff81, to=0) int); method @RequiresPermission(android.Manifest.permission.UPDATE_DEVICE_STATS) public void reportWifiScanStartedFromSource(@NonNull android.os.WorkSource); method @RequiresPermission(android.Manifest.permission.UPDATE_DEVICE_STATS) public void reportWifiScanStoppedFromSource(@NonNull android.os.WorkSource); @@ -7177,10 +7188,15 @@ package android.os { method @RequiresPermission(android.Manifest.permission.RECOVERY) public static void processPackage(android.content.Context, java.io.File, android.os.RecoverySystem.ProgressListener, android.os.Handler) throws java.io.IOException; method @RequiresPermission(android.Manifest.permission.RECOVERY) public static void processPackage(android.content.Context, java.io.File, android.os.RecoverySystem.ProgressListener) throws java.io.IOException; method @Deprecated @RequiresPermission(android.Manifest.permission.RECOVERY) public static void rebootAndApply(@NonNull android.content.Context, @NonNull String, @NonNull String) throws java.io.IOException; - method @RequiresPermission(anyOf={android.Manifest.permission.RECOVERY, android.Manifest.permission.REBOOT}) public static void rebootAndApply(@NonNull android.content.Context, @NonNull String, boolean) throws java.io.IOException; + method @RequiresPermission(anyOf={android.Manifest.permission.RECOVERY, android.Manifest.permission.REBOOT}) public static int rebootAndApply(@NonNull android.content.Context, @NonNull String, boolean) throws java.io.IOException; method @RequiresPermission(allOf={android.Manifest.permission.RECOVERY, android.Manifest.permission.REBOOT}) public static void rebootWipeAb(android.content.Context, java.io.File, String) throws java.io.IOException; method @RequiresPermission(android.Manifest.permission.RECOVERY) public static void scheduleUpdateOnBoot(android.content.Context, java.io.File) throws java.io.IOException; method public static boolean verifyPackageCompatibility(java.io.File) throws java.io.IOException; + field public static final int RESUME_ON_REBOOT_REBOOT_ERROR_INVALID_PACKAGE_NAME = 2000; // 0x7d0 + field public static final int RESUME_ON_REBOOT_REBOOT_ERROR_LSKF_NOT_CAPTURED = 3000; // 0xbb8 + field public static final int RESUME_ON_REBOOT_REBOOT_ERROR_PROVIDER_PREPARATION_FAILURE = 5000; // 0x1388 + field public static final int RESUME_ON_REBOOT_REBOOT_ERROR_SLOT_MISMATCH = 4000; // 0xfa0 + field public static final int RESUME_ON_REBOOT_REBOOT_ERROR_UNSPECIFIED = 1000; // 0x3e8 } public final class RemoteCallback implements android.os.Parcelable { @@ -7296,7 +7312,7 @@ package android.os { method @NonNull public static String formatUid(int); method public static int getAppId(int); method public int getIdentifier(); - method public static int getUid(@NonNull android.os.UserHandle, int); + method public int getUid(int); method @Deprecated public boolean isOwner(); method public boolean isSystem(); method public static int myUserId(); @@ -8117,7 +8133,7 @@ package android.security.keystore { } public final class KeyGenParameterSpec implements java.security.spec.AlgorithmParameterSpec { - method @Nullable public int[] getAttestationIds(); + method @NonNull public int[] getAttestationIds(); method public int getNamespace(); } @@ -11884,7 +11900,8 @@ package android.telephony.ims { } public interface SipDelegateConnection { - method public void closeDialog(@NonNull String); + method public default void cleanupSession(@NonNull String); + method @Deprecated public default void closeDialog(@NonNull String); method public void notifyMessageReceiveError(@NonNull String, int); method public void notifyMessageReceived(@NonNull String); method public void sendMessage(@NonNull android.telephony.ims.SipMessage, long); @@ -11985,10 +12002,10 @@ package android.telephony.ims { method public int describeContents(); method @Nullable public String getCallIdParameter(); method @NonNull public byte[] getContent(); - method @NonNull public byte[] getEncodedMessage(); method @NonNull public String getHeaderSection(); method @NonNull public String getStartLine(); method @NonNull public String getViaBranchParameter(); + method @NonNull public byte[] toEncodedMessage(); method public void writeToParcel(@NonNull android.os.Parcel, int); field @NonNull public static final android.os.Parcelable.Creator<android.telephony.ims.SipMessage> CREATOR; } @@ -12333,7 +12350,8 @@ package android.telephony.ims.stub { } public interface SipDelegate { - method public void closeDialog(@NonNull String); + method public default void cleanupSession(@NonNull String); + method @Deprecated public default void closeDialog(@NonNull String); method public void notifyMessageReceiveError(@NonNull String, int); method public void notifyMessageReceived(@NonNull String); method public void sendMessage(@NonNull android.telephony.ims.SipMessage, long); @@ -12492,7 +12510,7 @@ package android.uwb { public final class DistanceMeasurement implements android.os.Parcelable { method public int describeContents(); method @FloatRange(from=0.0, to=1.0) public double getConfidenceLevel(); - method public double getErrorMeters(); + method @FloatRange(from=0.0) public double getErrorMeters(); method public double getMeters(); method public void writeToParcel(@NonNull android.os.Parcel, int); field @NonNull public static final android.os.Parcelable.Creator<android.uwb.DistanceMeasurement> CREATOR; @@ -12501,8 +12519,8 @@ package android.uwb { public static final class DistanceMeasurement.Builder { ctor public DistanceMeasurement.Builder(); method @NonNull public android.uwb.DistanceMeasurement build(); - method @NonNull public android.uwb.DistanceMeasurement.Builder setConfidenceLevel(double); - method @NonNull public android.uwb.DistanceMeasurement.Builder setErrorMeters(double); + method @NonNull public android.uwb.DistanceMeasurement.Builder setConfidenceLevel(@FloatRange(from=0.0, to=1.0) double); + method @NonNull public android.uwb.DistanceMeasurement.Builder setErrorMeters(@FloatRange(from=0.0) double); method @NonNull public android.uwb.DistanceMeasurement.Builder setMeters(double); } @@ -12561,7 +12579,7 @@ package android.uwb { method public void onStartFailed(int, @NonNull android.os.PersistableBundle); method public void onStarted(@NonNull android.os.PersistableBundle); method public void onStopFailed(int, @NonNull android.os.PersistableBundle); - method public void onStopped(); + method public void onStopped(int, @NonNull android.os.PersistableBundle); field public static final int REASON_BAD_PARAMETERS = 3; // 0x3 field public static final int REASON_GENERIC_ERROR = 4; // 0x4 field public static final int REASON_LOCAL_REQUEST = 1; // 0x1 diff --git a/core/api/test-current.txt b/core/api/test-current.txt index 0c57f4e3b557..fd6d47e56b52 100644 --- a/core/api/test-current.txt +++ b/core/api/test-current.txt @@ -1009,6 +1009,10 @@ package android.net { method public static void setServiceForTest(@Nullable android.os.IBinder); } + public class NetworkWatchlistManager { + method @Nullable public byte[] getWatchlistConfigHash(); + } + public class TrafficStats { method public static long getLoopbackRxBytes(); method public static long getLoopbackRxPackets(); @@ -1022,6 +1026,7 @@ package android.os { public class Build { method public static boolean is64BitAbi(String); + method public static boolean isDebuggable(); field public static final boolean IS_EMULATOR; } diff --git a/core/java/Android.bp b/core/java/Android.bp index 919f1e2e85fb..965665d3184a 100644 --- a/core/java/Android.bp +++ b/core/java/Android.bp @@ -127,3 +127,269 @@ filegroup { ], visibility: ["//frameworks/base/test-mock"], } + +filegroup { + name: "libincident_aidl", + srcs: [ + "android/os/IIncidentDumpCallback.aidl", + "android/os/IIncidentManager.aidl", + "android/os/IIncidentReportStatusListener.aidl", + ], +} + +filegroup { + name: "libvibrator_aidl", + srcs: [ + "android/os/IExternalVibrationController.aidl", + "android/os/IExternalVibratorService.aidl", + ], +} + +filegroup { + name: "libpowermanager_aidl", + srcs: [ + "android/os/Temperature.aidl", + "android/os/CoolingDevice.aidl", + "android/os/IThermalEventListener.aidl", + "android/os/IThermalStatusListener.aidl", + "android/os/IThermalService.aidl", + ], +} + +genrule { + name: "statslog-framework-java-gen", + tools: ["stats-log-api-gen"], + cmd: "$(location stats-log-api-gen) --java $(out) --module framework" + + " --javaPackage com.android.internal.util --javaClass FrameworkStatsLog --worksource", + out: ["com/android/internal/util/FrameworkStatsLog.java"], +} + +java_library { + name: "uieventloggerlib", + srcs: [ + "com/android/internal/logging/UiEvent.java", + "com/android/internal/logging/UiEventLogger.java", + "com/android/internal/logging/UiEventLoggerImpl.java", + "com/android/internal/logging/InstanceId.java", + "com/android/internal/logging/InstanceIdSequence.java", + ":statslog-framework-java-gen", + ], +} + +filegroup { + name: "framework-services-net-module-wifi-shared-srcs", + srcs: [ + "android/net/DhcpResults.java", + "android/util/LocalLog.java", + ], +} + +// keep these files in sync with the package/Tethering/jarjar-rules.txt and +// package/Connectivity/jarjar-rules.txt for the tethering module and connectivity module. +filegroup { + name: "framework-connectivity-shared-srcs", + srcs: [ + "android/util/LocalLog.java", + // This should be android.util.IndentingPrintWriter, but it's not available in all branches. + "com/android/internal/util/IndentingPrintWriter.java", + "com/android/internal/util/IState.java", + "com/android/internal/util/MessageUtils.java", + "com/android/internal/util/State.java", + "com/android/internal/util/StateMachine.java", + "com/android/internal/util/WakeupMessage.java", + ], +} + +filegroup { + name: "incremental_aidl", + srcs: [ + "android/os/incremental/IIncrementalServiceConnector.aidl", + "android/os/incremental/IncrementalFileSystemControlParcel.aidl", + ], +} + +filegroup { + name: "dataloader_aidl", + srcs: [ + "android/content/pm/DataLoaderParamsParcel.aidl", + "android/content/pm/DataLoaderType.aidl", + "android/content/pm/FileSystemControlParcel.aidl", + "android/content/pm/IDataLoader.aidl", + "android/content/pm/IDataLoaderManager.aidl", + "android/content/pm/InstallationFileParcel.aidl", + "android/content/pm/InstallationFileLocation.aidl", + "android/content/pm/IDataLoaderStatusListener.aidl", + "android/content/pm/IPackageInstallerSessionFileSystemConnector.aidl", + ], +} + +filegroup { + name: "incremental_manager_aidl", + srcs: [ + "android/os/incremental/IIncrementalService.aidl", + "android/os/incremental/IncrementalNewFileParams.aidl", + "android/os/incremental/IStorageHealthListener.aidl", + "android/os/incremental/StorageHealthCheckParams.aidl", + ], +} + +filegroup { + name: "activity_manager_procstate_aidl", + srcs: [ + // internal only + ], +} + +aidl_interface { + name: "libincremental_aidl", + unstable: true, + srcs: [ + ":incremental_aidl", + ], + backend: { + java: { + sdk_version: "28", + }, + cpp: { + enabled: true, + }, + ndk: { + enabled: true, + }, + }, +} + +aidl_interface { + name: "libdataloader_aidl", + unstable: true, + srcs: [ + ":dataloader_aidl", + ], + imports: [ + "libincremental_aidl", + ], + backend: { + java: { + sdk_version: "28", + }, + cpp: { + enabled: true, + }, + ndk: { + enabled: false, + }, + }, +} + +aidl_interface { + name: "libincremental_manager_aidl", + unstable: true, + srcs: [ + ":incremental_manager_aidl", + ], + imports: [ + "libincremental_aidl", + "libdataloader_aidl", + ], + backend: { + java: { + sdk_version: "28", + }, + cpp: { + enabled: true, + }, + ndk: { + enabled: false, + }, + }, +} + +// Build Rust bindings for PermissionController. Needed by keystore2. +aidl_interface { + name: "android.os.permissions_aidl", + unstable: true, + local_include_dir: ".", + srcs: [ + "android/os/IPermissionController.aidl", + ], + backend: { + rust: { + enabled: true, + }, + }, +} + +// Avoid including Parcelable classes as we don't want to have two copies of +// Parcelable cross the libraries. This is used by telephony-common (frameworks/opt/telephony) +// and TeleService app (packages/services/Telephony). +filegroup { + name: "framework-telephony-common-shared-srcs", + srcs: [ + "android/os/RegistrantList.java", + "android/os/Registrant.java", + "android/util/LocalLog.java", + "android/util/TimeUtils.java", + "com/android/internal/os/SomeArgs.java", + "com/android/internal/util/AsyncChannel.java", + "com/android/internal/util/AsyncService.java", + "com/android/internal/util/BitwiseInputStream.java", + "com/android/internal/util/FastXmlSerializer.java", + "com/android/internal/util/HexDump.java", + "com/android/internal/util/IState.java", + "com/android/internal/util/IndentingPrintWriter.java", + "com/android/internal/util/Preconditions.java", + "com/android/internal/util/State.java", + "com/android/internal/util/StateMachine.java", + "com/android/internal/util/UserIcons.java", + ], +} + +// Avoid including Parcelable classes as we don't want to have two copies of +// Parcelable cross the process. +filegroup { + name: "framework-cellbroadcast-shared-srcs", + srcs: [ + "android/os/HandlerExecutor.java", + "android/util/LocalLog.java", + "com/android/internal/util/IState.java", + "com/android/internal/util/Preconditions.java", + "com/android/internal/util/State.java", + "com/android/internal/util/StateMachine.java", + ], +} + +filegroup { + name: "framework-ims-common-shared-srcs", + srcs: [ + "android/os/RegistrantList.java", + "android/os/Registrant.java", + "com/android/internal/os/SomeArgs.java", + "com/android/internal/util/Preconditions.java", + ], +} + +filegroup { + name: "framework-wifi-util-lib-aidls", + srcs: ["android/content/pm/ParceledListSlice.aidl"], +} + +// utility classes statically linked into wifi-service +filegroup { + name: "framework-wifi-service-shared-srcs", + srcs: [ + "android/net/InterfaceConfiguration.java", + "android/util/BackupUtils.java", + "android/util/Rational.java", + "com/android/internal/util/FastXmlSerializer.java", + "com/android/internal/util/HexDump.java", + "com/android/internal/util/IState.java", + "com/android/internal/util/MessageUtils.java", + "com/android/internal/util/State.java", + "com/android/internal/util/StateMachine.java", + "com/android/internal/util/WakeupMessage.java", + ], + visibility: [ + "//frameworks/opt/net/wifi/service", + "//packages/modules/Wifi/service", + ], +} diff --git a/core/java/android/app/AppOpsManager.java b/core/java/android/app/AppOpsManager.java index 694c51980e21..c4cdbbcbf9d2 100644 --- a/core/java/android/app/AppOpsManager.java +++ b/core/java/android/app/AppOpsManager.java @@ -7636,8 +7636,8 @@ public class AppOpsManager { } else if (collectionMode == COLLECT_SYNC // Only collect app-ops when the proxy is trusted && (mContext.checkPermission(Manifest.permission.UPDATE_APP_OPS_STATS, -1, - myUid) == PackageManager.PERMISSION_GRANTED - || isTrustedVoiceServiceProxy(mContext, mContext.getOpPackageName(), op))) { + myUid) == PackageManager.PERMISSION_GRANTED || isTrustedVoiceServiceProxy( + mContext, mContext.getOpPackageName(), op, mContext.getUserId()))) { collectNotedOpSync(op, proxiedAttributionTag); } } @@ -7655,7 +7655,7 @@ public class AppOpsManager { * @hide */ public static boolean isTrustedVoiceServiceProxy(Context context, String packageName, - int code) { + int code, int userId) { // This is a workaround for R QPR, new API change is not allowed. We only allow the current // voice recognizer is also the voice interactor to noteproxy op. if (code != OP_RECORD_AUDIO) { @@ -7667,7 +7667,7 @@ public class AppOpsManager { final String voiceRecognitionServicePackageName = getComponentPackageNameFromString(voiceRecognitionComponent); return (Objects.equals(packageName, voiceRecognitionServicePackageName)) - && isPackagePreInstalled(context, packageName); + && isPackagePreInstalled(context, packageName, userId); } private static String getComponentPackageNameFromString(String from) { @@ -7675,10 +7675,10 @@ public class AppOpsManager { return componentName != null ? componentName.getPackageName() : ""; } - private static boolean isPackagePreInstalled(Context context, String packageName) { + private static boolean isPackagePreInstalled(Context context, String packageName, int userId) { try { final PackageManager pm = context.getPackageManager(); - final ApplicationInfo info = pm.getApplicationInfo(packageName, 0); + final ApplicationInfo info = pm.getApplicationInfoAsUser(packageName, 0, userId); return ((info.flags & ApplicationInfo.FLAG_SYSTEM) != 0); } catch (PackageManager.NameNotFoundException e) { return false; diff --git a/core/java/android/app/ApplicationExitInfo.java b/core/java/android/app/ApplicationExitInfo.java index 854f5a4ab724..87f48c0b9fb9 100644 --- a/core/java/android/app/ApplicationExitInfo.java +++ b/core/java/android/app/ApplicationExitInfo.java @@ -614,7 +614,7 @@ public final class ApplicationExitInfo implements Parcelable { * tombstone traces will be returned for * {@link #REASON_CRASH_NATIVE}, with an InputStream containing a protobuf with * <a href="https://android.googlesource.com/platform/system/core/+/refs/heads/master/debuggerd/proto/tombstone.proto">this schema</a>. - * Note thatbecause these traces are kept in a separate global circular buffer, crashes may be + * Note that because these traces are kept in a separate global circular buffer, crashes may be * overwritten by newer crashes (including from other applications), so this may still return * null. * diff --git a/core/java/android/app/IUidObserver.aidl b/core/java/android/app/IUidObserver.aidl index 7713e25d5ecd..74018a8ab1f8 100644 --- a/core/java/android/app/IUidObserver.aidl +++ b/core/java/android/app/IUidObserver.aidl @@ -24,7 +24,7 @@ oneway interface IUidObserver { // below block of transactions. // Since these transactions are also called from native code, these must be kept in sync with - // the ones in frameworks/native/include/binder/IActivityManager.h + // the ones in frameworks/native/include_activitymanager/binder/IActivityManager.h // =============== Beginning of transactions used on native side as well ====================== /** diff --git a/core/java/android/bluetooth/BluetoothAdapter.java b/core/java/android/bluetooth/BluetoothAdapter.java index 38863c2c8ccf..3802289dd6d6 100644 --- a/core/java/android/bluetooth/BluetoothAdapter.java +++ b/core/java/android/bluetooth/BluetoothAdapter.java @@ -28,6 +28,7 @@ import android.annotation.SdkConstant.SdkConstantType; import android.annotation.SystemApi; import android.app.ActivityThread; import android.app.PropertyInvalidatedCache; +import android.bluetooth.BluetoothDevice.Transport; import android.bluetooth.BluetoothProfile.ConnectionPolicy; import android.bluetooth.le.BluetoothLeAdvertiser; import android.bluetooth.le.BluetoothLeScanner; @@ -3013,6 +3014,164 @@ public final class BluetoothAdapter { return false; } + /** @hide */ + @Retention(RetentionPolicy.SOURCE) + @IntDef(prefix = { "OOB_ERROR_" }, value = { + OOB_ERROR_UNKNOWN, + OOB_ERROR_ANOTHER_ACTIVE_REQUEST, + OOB_ERROR_ADAPTER_DISABLED + }) + public @interface OobError {} + + /** + * An unknown error has occurred in the controller, stack, or callback pipeline. + * + * @hide + */ + @SystemApi + public static final int OOB_ERROR_UNKNOWN = 0; + + /** + * If another application has already requested {@link OobData} then another fetch will be + * disallowed until the callback is removed. + * + * @hide + */ + @SystemApi + public static final int OOB_ERROR_ANOTHER_ACTIVE_REQUEST = 1; + + /** + * The adapter is currently disabled, please enable it. + * + * @hide + */ + @SystemApi + public static final int OOB_ERROR_ADAPTER_DISABLED = 2; + + /** + * Provides callback methods for receiving {@link OobData} from the host stack, as well as an + * error interface in order to allow the caller to determine next steps based on the {@link + * ErrorCode}. + * + * @hide + */ + @SystemApi + public interface OobDataCallback { + /** + * Handles the {@link OobData} received from the host stack. + * + * @param transport - whether the {@link OobData} is generated for LE or Classic. + * @param oobData - data generated in the host stack(LE) or controller (Classic) + */ + void onOobData(@Transport int transport, @Nullable OobData oobData); + + /** + * Provides feedback when things don't go as expected. + * + * @param errorCode - the code descibing the type of error that occurred. + */ + void onError(@OobError int errorCode); + } + + /** + * Wraps an AIDL interface around an {@link OobDataCallback} interface. + * + * @see {@link IBluetoothOobDataCallback} for interface definition. + * + * @hide + */ + public class WrappedOobDataCallback extends IBluetoothOobDataCallback.Stub { + private final OobDataCallback mCallback; + private final Executor mExecutor; + + /** + * @param callback - object to receive {@link OobData} must be a non null argument + * + * @throws NullPointerException if the callback is null. + */ + WrappedOobDataCallback(@NonNull OobDataCallback callback, + @NonNull @CallbackExecutor Executor executor) { + Preconditions.checkNotNull(callback); + Preconditions.checkNotNull(executor); + mCallback = callback; + mExecutor = executor; + } + /** + * Wrapper function to relay to the {@link OobDataCallback#onOobData} + * + * @param transport - whether the {@link OobData} is generated for LE or Classic. + * @param oobData - data generated in the host stack(LE) or controller (Classic) + * + * @hide + */ + public void onOobData(@Transport int transport, OobData oobData) { + mExecutor.execute(new Runnable() { + public void run() { + mCallback.onOobData(transport, oobData); + } + }); + } + /** + * Wrapper function to relay to the {@link OobDataCallback#onError} + * + * @param errorCode - the code descibing the type of error that occurred. + * + * @hide + */ + public void onError(@OobError int errorCode) { + mExecutor.execute(new Runnable() { + public void run() { + mCallback.onError(errorCode); + } + }); + } + } + + /** + * Fetches a secret data value that can be used for a secure and simple pairing experience. + * + * <p>This is the Local Out of Band data the comes from the + * + * <p>This secret is the local Out of Band data. This data is used to securely and quickly + * pair two devices with minimal user interaction. + * + * <p>For example, this secret can be transferred to a remote device out of band (meaning any + * other way besides using bluetooth). Once the remote device finds this device using the + * information given in the data, such as the PUBLIC ADDRESS, the remote device could then + * connect to this device using this secret when the pairing sequenece asks for the secret. + * This device will respond by automatically accepting the pairing due to the secret being so + * trustworthy. + * + * @param transport - provide type of transport (e.g. LE or Classic). + * @param callback - target object to receive the {@link OobData} value. + * + * @throws NullPointerException if callback is null. + * @throws IllegalArgumentException if the transport is not valid. + * + * @hide + */ + @SystemApi + @RequiresPermission(Manifest.permission.BLUETOOTH_PRIVILEGED) + public void generateLocalOobData(@Transport int transport, + @NonNull @CallbackExecutor Executor executor, @NonNull OobDataCallback callback) { + if (transport != BluetoothDevice.TRANSPORT_BREDR && transport + != BluetoothDevice.TRANSPORT_LE) { + throw new IllegalArgumentException("Invalid transport '" + transport + "'!"); + } + Preconditions.checkNotNull(callback); + if (!isEnabled()) { + Log.w(TAG, "generateLocalOobData(): Adapter isn't enabled!"); + callback.onError(OOB_ERROR_ADAPTER_DISABLED); + } else { + try { + mService.generateLocalOobData(transport, new WrappedOobDataCallback(callback, + executor)); + } catch (RemoteException e) { + Log.e(TAG, "", e); + } + } + } + /** * Enable control of the Bluetooth Adapter for a single application. * diff --git a/core/java/android/bluetooth/BluetoothDevice.java b/core/java/android/bluetooth/BluetoothDevice.java index c30b8af3da53..a40bf343239e 100644 --- a/core/java/android/bluetooth/BluetoothDevice.java +++ b/core/java/android/bluetooth/BluetoothDevice.java @@ -931,6 +931,21 @@ public final class BluetoothDevice implements Parcelable { @SystemApi public static final int ACCESS_REJECTED = 2; + /** @hide */ + @Retention(RetentionPolicy.SOURCE) + @IntDef( + prefix = { "TRANSPORT_" }, + value = { + /** Allow host to automatically select a transport (dual-mode only) */ + TRANSPORT_AUTO, + /** Use Classic or BR/EDR transport.*/ + TRANSPORT_BREDR, + /** Use Low Energy transport.*/ + TRANSPORT_LE, + } + ) + public @interface Transport {} + /** * No preference of physical transport for GATT connections to remote dual-mode devices */ @@ -1063,6 +1078,10 @@ public final class BluetoothDevice implements Parcelable { public void onBrEdrDown() { if (DBG) Log.d(TAG, "onBrEdrDown: reached BLE ON state"); } + + public void onOobData(@Transport int transport, OobData oobData) { + if (DBG) Log.d(TAG, "onOobData: got data"); + } }; /** diff --git a/core/java/android/bluetooth/OobData.java b/core/java/android/bluetooth/OobData.java index 08d694eb93e2..d6868e0ffd5c 100644 --- a/core/java/android/bluetooth/OobData.java +++ b/core/java/android/bluetooth/OobData.java @@ -830,7 +830,7 @@ public final class OobData implements Parcelable { @Nullable @SystemApi public byte[] getLeAppearance() { - return mLeTemporaryKey; + return mLeAppearance; } /** diff --git a/core/java/android/content/Intent.java b/core/java/android/content/Intent.java index 4d68e90437be..0fad63f192bb 100644 --- a/core/java/android/content/Intent.java +++ b/core/java/android/content/Intent.java @@ -2324,14 +2324,6 @@ public class Intent implements Parcelable, Cloneable { @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) public static final String ACTION_TIMEZONE_CHANGED = "android.intent.action.TIMEZONE_CHANGED"; /** - * Clear DNS Cache Action: This is broadcast when networks have changed and old - * DNS entries should be tossed. - * @hide - */ - @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) - @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES) - public static final String ACTION_CLEAR_DNS_CACHE = "android.intent.action.CLEAR_DNS_CACHE"; - /** * Alarm Changed Action: This is broadcast when the AlarmClock * application's alarm is set or unset. It is used by the * AlarmClock application and the StatusBar service. diff --git a/core/java/android/content/OWNERS b/core/java/android/content/OWNERS index 01b554a56720..1735aa2a338d 100644 --- a/core/java/android/content/OWNERS +++ b/core/java/android/content/OWNERS @@ -5,6 +5,7 @@ per-file IntentFilter.java = toddke@google.com per-file IntentFilter.java = patb@google.com per-file Intent.java = toddke@google.com per-file Intent.java = patb@google.com +per-file Intent.java = file:/services/core/java/com/android/server/wm/OWNERS per-file AutofillOptions* = file:/core/java/android/service/autofill/OWNERS per-file ContentCaptureOptions* = file:/core/java/android/service/contentcapture/OWNERS per-file LocusId* = file:/core/java/android/service/contentcapture/OWNERS diff --git a/core/java/android/content/pm/ApplicationInfo.java b/core/java/android/content/pm/ApplicationInfo.java index ad9e31b6cbf4..fc5ca6147496 100644 --- a/core/java/android/content/pm/ApplicationInfo.java +++ b/core/java/android/content/pm/ApplicationInfo.java @@ -1337,7 +1337,7 @@ public class ApplicationInfo extends PackageItemInfo implements Parcelable { * Indicates if the application has requested GWP-ASan to be enabled, disabled, or left * unspecified. Processes can override this setting. */ - private @GwpAsanMode int gwpAsanMode; + private @GwpAsanMode int gwpAsanMode = GWP_ASAN_DEFAULT; /** * Default (unspecified) setting of Memtag. @@ -1376,13 +1376,38 @@ public class ApplicationInfo extends PackageItemInfo implements Parcelable { * Indicates if the application has requested Memtag to be enabled, disabled, or left * unspecified. Processes can override this setting. */ - private @MemtagMode int memtagMode; + private @MemtagMode int memtagMode = MEMTAG_DEFAULT; + + /** + * Default (unspecified) setting of nativeHeapZeroInitialized. + */ + public static final int ZEROINIT_DEFAULT = -1; + + /** + * Disable zero-initialization of the native heap in this application or process. + */ + public static final int ZEROINIT_DISABLED = 0; + + /** + * Enable zero-initialization of the native heap in this application or process. + */ + public static final int ZEROINIT_ENABLED = 1; + + /** + * @hide + */ + @IntDef(prefix = {"ZEROINIT_"}, value = { + ZEROINIT_DEFAULT, + ZEROINIT_DISABLED, + ZEROINIT_ENABLED, + }) + @Retention(RetentionPolicy.SOURCE) + public @interface NativeHeapZeroInitialized {} /** * Enable automatic zero-initialization of native heap memory allocations. */ - @Nullable - private Boolean nativeHeapZeroInit; + private @NativeHeapZeroInitialized int nativeHeapZeroInitialized = ZEROINIT_DEFAULT; /** * Represents the default policy. The actual policy used will depend on other properties of @@ -1531,8 +1556,8 @@ public class ApplicationInfo extends PackageItemInfo implements Parcelable { if (memtagMode != MEMTAG_DEFAULT) { pw.println(prefix + "memtagMode=" + memtagMode); } - if (nativeHeapZeroInit != null) { - pw.println(prefix + "nativeHeapZeroInit=" + nativeHeapZeroInit); + if (nativeHeapZeroInitialized != ZEROINIT_DEFAULT) { + pw.println(prefix + "nativeHeapZeroInitialized=" + nativeHeapZeroInitialized); } } super.dumpBack(pw, prefix); @@ -1638,8 +1663,9 @@ public class ApplicationInfo extends PackageItemInfo implements Parcelable { if (memtagMode != MEMTAG_DEFAULT) { proto.write(ApplicationInfoProto.Detail.ENABLE_MEMTAG, memtagMode); } - if (nativeHeapZeroInit != null) { - proto.write(ApplicationInfoProto.Detail.NATIVE_HEAP_ZERO_INIT, nativeHeapZeroInit); + if (nativeHeapZeroInitialized != ZEROINIT_DEFAULT) { + proto.write(ApplicationInfoProto.Detail.NATIVE_HEAP_ZERO_INIT, + nativeHeapZeroInitialized); } proto.end(detailToken); } @@ -1752,7 +1778,7 @@ public class ApplicationInfo extends PackageItemInfo implements Parcelable { zygotePreloadName = orig.zygotePreloadName; gwpAsanMode = orig.gwpAsanMode; memtagMode = orig.memtagMode; - nativeHeapZeroInit = orig.nativeHeapZeroInit; + nativeHeapZeroInitialized = orig.nativeHeapZeroInitialized; } public String toString() { @@ -1838,7 +1864,7 @@ public class ApplicationInfo extends PackageItemInfo implements Parcelable { dest.writeString8(zygotePreloadName); dest.writeInt(gwpAsanMode); dest.writeInt(memtagMode); - sForBoolean.parcel(nativeHeapZeroInit, dest, parcelableFlags); + dest.writeInt(nativeHeapZeroInitialized); } public static final @android.annotation.NonNull Parcelable.Creator<ApplicationInfo> CREATOR @@ -1921,7 +1947,7 @@ public class ApplicationInfo extends PackageItemInfo implements Parcelable { zygotePreloadName = source.readString8(); gwpAsanMode = source.readInt(); memtagMode = source.readInt(); - nativeHeapZeroInit = sForBoolean.unparcel(source); + nativeHeapZeroInitialized = source.readInt(); } /** @@ -2314,7 +2340,9 @@ public class ApplicationInfo extends PackageItemInfo implements Parcelable { /** {@hide} */ public void setSplitResourcePaths(String[] splitResourcePaths) { splitPublicSourceDirs = splitResourcePaths; } /** {@hide} */ public void setGwpAsanMode(@GwpAsanMode int value) { gwpAsanMode = value; } /** {@hide} */ public void setMemtagMode(@MemtagMode int value) { memtagMode = value; } - /** {@hide} */ public void setNativeHeapZeroInit(@Nullable Boolean value) { nativeHeapZeroInit = value; } + /** {@hide} */ public void setNativeHeapZeroInitialized(@NativeHeapZeroInitialized int value) { + nativeHeapZeroInitialized = value; + } /** {@hide} */ @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) @@ -2328,8 +2356,22 @@ public class ApplicationInfo extends PackageItemInfo implements Parcelable { /** {@hide} */ public String[] getSplitResourcePaths() { return splitPublicSourceDirs; } @GwpAsanMode public int getGwpAsanMode() { return gwpAsanMode; } + + /** + * Returns whether the application has requested Memtag to be enabled, disabled, or left + * unspecified. Processes can override this setting. + */ @MemtagMode - public int getMemtagMode() { return memtagMode; } - @Nullable - public Boolean isNativeHeapZeroInit() { return nativeHeapZeroInit; } + public int getMemtagMode() { + return memtagMode; + } + + /** + * Returns whether the application has requested automatic zero-initialization of native heap + * memory allocations to be enabled or disabled. + */ + @NativeHeapZeroInitialized + public int getNativeHeapZeroInitialized() { + return nativeHeapZeroInitialized; + } } diff --git a/core/java/android/content/pm/ProcessInfo.java b/core/java/android/content/pm/ProcessInfo.java index 3dd5ee102090..632c0f54375c 100644 --- a/core/java/android/content/pm/ProcessInfo.java +++ b/core/java/android/content/pm/ProcessInfo.java @@ -62,8 +62,7 @@ public class ProcessInfo implements Parcelable { /** * Enable automatic zero-initialization of native heap memory allocations. */ - @Nullable - public Boolean nativeHeapZeroInit; + public @ApplicationInfo.NativeHeapZeroInitialized int nativeHeapZeroInitialized; @Deprecated public ProcessInfo(@NonNull ProcessInfo orig) { @@ -71,7 +70,7 @@ public class ProcessInfo implements Parcelable { this.deniedPermissions = orig.deniedPermissions; this.gwpAsanMode = orig.gwpAsanMode; this.memtagMode = orig.memtagMode; - this.nativeHeapZeroInit = orig.nativeHeapZeroInit; + this.nativeHeapZeroInitialized = orig.nativeHeapZeroInitialized; } @@ -101,7 +100,7 @@ public class ProcessInfo implements Parcelable { * @param memtagMode * Indicates if the process has requested Memtag to be enabled (in sync or async mode), * disabled, or left unspecified. - * @param nativeHeapZeroInit + * @param nativeHeapZeroInitialized * Enable automatic zero-initialization of native heap memory allocations. */ @DataClass.Generated.Member @@ -110,7 +109,7 @@ public class ProcessInfo implements Parcelable { @Nullable ArraySet<String> deniedPermissions, @ApplicationInfo.GwpAsanMode int gwpAsanMode, @ApplicationInfo.MemtagMode int memtagMode, - @Nullable Boolean nativeHeapZeroInit) { + @ApplicationInfo.NativeHeapZeroInitialized int nativeHeapZeroInitialized) { this.name = name; com.android.internal.util.AnnotationValidations.validate( NonNull.class, null, name); @@ -121,7 +120,9 @@ public class ProcessInfo implements Parcelable { this.memtagMode = memtagMode; com.android.internal.util.AnnotationValidations.validate( ApplicationInfo.MemtagMode.class, null, memtagMode); - this.nativeHeapZeroInit = nativeHeapZeroInit; + this.nativeHeapZeroInitialized = nativeHeapZeroInitialized; + com.android.internal.util.AnnotationValidations.validate( + ApplicationInfo.NativeHeapZeroInitialized.class, null, nativeHeapZeroInitialized); // onConstructed(); // You can define this method to get a callback } @@ -145,13 +146,12 @@ public class ProcessInfo implements Parcelable { byte flg = 0; if (deniedPermissions != null) flg |= 0x2; - if (nativeHeapZeroInit != null) flg |= 0x10; dest.writeByte(flg); dest.writeString(name); sParcellingForDeniedPermissions.parcel(deniedPermissions, dest, flags); dest.writeInt(gwpAsanMode); dest.writeInt(memtagMode); - if (nativeHeapZeroInit != null) dest.writeBoolean(nativeHeapZeroInit); + dest.writeInt(nativeHeapZeroInitialized); } @Override @@ -170,7 +170,7 @@ public class ProcessInfo implements Parcelable { ArraySet<String> _deniedPermissions = sParcellingForDeniedPermissions.unparcel(in); int _gwpAsanMode = in.readInt(); int _memtagMode = in.readInt(); - Boolean _nativeHeapZeroInit = (flg & 0x10) == 0 ? null : (Boolean) in.readBoolean(); + int _nativeHeapZeroInitialized = in.readInt(); this.name = _name; com.android.internal.util.AnnotationValidations.validate( @@ -182,7 +182,9 @@ public class ProcessInfo implements Parcelable { this.memtagMode = _memtagMode; com.android.internal.util.AnnotationValidations.validate( ApplicationInfo.MemtagMode.class, null, memtagMode); - this.nativeHeapZeroInit = _nativeHeapZeroInit; + this.nativeHeapZeroInitialized = _nativeHeapZeroInitialized; + com.android.internal.util.AnnotationValidations.validate( + ApplicationInfo.NativeHeapZeroInitialized.class, null, nativeHeapZeroInitialized); // onConstructed(); // You can define this method to get a callback } @@ -202,10 +204,10 @@ public class ProcessInfo implements Parcelable { }; @DataClass.Generated( - time = 1611614699049L, + time = 1615850184524L, codegenVersion = "1.0.22", sourceFile = "frameworks/base/core/java/android/content/pm/ProcessInfo.java", - inputSignatures = "public @android.annotation.NonNull java.lang.String name\npublic @android.annotation.Nullable @com.android.internal.util.DataClass.ParcelWith(com.android.internal.util.Parcelling.BuiltIn.ForInternedStringArraySet.class) android.util.ArraySet<java.lang.String> deniedPermissions\npublic @android.content.pm.ApplicationInfo.GwpAsanMode int gwpAsanMode\npublic @android.content.pm.ApplicationInfo.MemtagMode int memtagMode\npublic @android.annotation.Nullable java.lang.Boolean nativeHeapZeroInit\nclass ProcessInfo extends java.lang.Object implements [android.os.Parcelable]\n@com.android.internal.util.DataClass(genGetters=true, genSetters=false, genParcelable=true, genAidl=false, genBuilder=false)") + inputSignatures = "public @android.annotation.NonNull java.lang.String name\npublic @android.annotation.Nullable @com.android.internal.util.DataClass.ParcelWith(com.android.internal.util.Parcelling.BuiltIn.ForInternedStringArraySet.class) android.util.ArraySet<java.lang.String> deniedPermissions\npublic @android.content.pm.ApplicationInfo.GwpAsanMode int gwpAsanMode\npublic @android.content.pm.ApplicationInfo.MemtagMode int memtagMode\npublic @android.content.pm.ApplicationInfo.NativeHeapZeroInitialized int nativeHeapZeroInitialized\nclass ProcessInfo extends java.lang.Object implements [android.os.Parcelable]\n@com.android.internal.util.DataClass(genGetters=true, genSetters=false, genParcelable=true, genAidl=false, genBuilder=false)") @Deprecated private void __metadata() {} diff --git a/core/java/android/content/pm/parsing/ParsingPackage.java b/core/java/android/content/pm/parsing/ParsingPackage.java index 983a02ca6576..61b5b72b5594 100644 --- a/core/java/android/content/pm/parsing/ParsingPackage.java +++ b/core/java/android/content/pm/parsing/ParsingPackage.java @@ -19,6 +19,7 @@ package android.content.pm.parsing; import android.annotation.NonNull; import android.annotation.Nullable; import android.content.Intent; +import android.content.pm.ApplicationInfo; import android.content.pm.ConfigurationInfo; import android.content.pm.FeatureGroupInfo; import android.content.pm.FeatureInfo; @@ -239,11 +240,12 @@ public interface ParsingPackage extends ParsingPackageRead { ParsingPackage setEnabled(boolean enabled); - ParsingPackage setGwpAsanMode(int gwpAsanMode); + ParsingPackage setGwpAsanMode(@ApplicationInfo.GwpAsanMode int gwpAsanMode); - ParsingPackage setMemtagMode(int memtagMode); + ParsingPackage setMemtagMode(@ApplicationInfo.MemtagMode int memtagMode); - ParsingPackage setNativeHeapZeroInit(@Nullable Boolean nativeHeapZeroInit); + ParsingPackage setNativeHeapZeroInitialized( + @ApplicationInfo.NativeHeapZeroInitialized int nativeHeapZeroInitialized); ParsingPackage setCrossProfile(boolean crossProfile); diff --git a/core/java/android/content/pm/parsing/ParsingPackageImpl.java b/core/java/android/content/pm/parsing/ParsingPackageImpl.java index bb4480ec61d2..c9a03c19b8a0 100644 --- a/core/java/android/content/pm/parsing/ParsingPackageImpl.java +++ b/core/java/android/content/pm/parsing/ParsingPackageImpl.java @@ -417,12 +417,14 @@ public class ParsingPackageImpl implements ParsingPackage, Parcelable { private int autoRevokePermissions; private boolean preserveLegacyExternalStorage; - protected int gwpAsanMode; - protected int memtagMode; + @ApplicationInfo.GwpAsanMode + private int gwpAsanMode; - @Nullable - @DataClass.ParcelWith(ForBoolean.class) - private Boolean nativeHeapZeroInit; + @ApplicationInfo.MemtagMode + private int memtagMode; + + @ApplicationInfo.NativeHeapZeroInitialized + private int nativeHeapZeroInitialized; // TODO(chiuwinson): Non-null @Nullable @@ -934,7 +936,7 @@ public class ParsingPackageImpl implements ParsingPackage, Parcelable { appInfo.crossProfile = isCrossProfile(); appInfo.setGwpAsanMode(gwpAsanMode); appInfo.setMemtagMode(memtagMode); - appInfo.setNativeHeapZeroInit(nativeHeapZeroInit); + appInfo.setNativeHeapZeroInitialized(nativeHeapZeroInitialized); appInfo.setBaseCodePath(baseCodePath); appInfo.setBaseResourcePath(baseCodePath); appInfo.setCodePath(codePath); @@ -1121,7 +1123,7 @@ public class ParsingPackageImpl implements ParsingPackage, Parcelable { dest.writeInt(this.gwpAsanMode); dest.writeSparseIntArray(this.minExtensionVersions); dest.writeInt(this.memtagMode); - sForBoolean.parcel(this.nativeHeapZeroInit, dest, flags); + dest.writeInt(this.nativeHeapZeroInitialized); } public ParsingPackageImpl(Parcel in) { @@ -1284,7 +1286,7 @@ public class ParsingPackageImpl implements ParsingPackage, Parcelable { this.gwpAsanMode = in.readInt(); this.minExtensionVersions = in.readSparseIntArray(); this.memtagMode = in.readInt(); - this.nativeHeapZeroInit = sForBoolean.unparcel(in); + this.nativeHeapZeroInitialized = in.readInt(); } public static final Parcelable.Creator<ParsingPackageImpl> CREATOR = @@ -2012,20 +2014,22 @@ public class ParsingPackageImpl implements ParsingPackage, Parcelable { return directBootAware; } + @ApplicationInfo.GwpAsanMode @Override public int getGwpAsanMode() { return gwpAsanMode; } + @ApplicationInfo.MemtagMode @Override public int getMemtagMode() { return memtagMode; } - @Nullable + @ApplicationInfo.NativeHeapZeroInitialized @Override - public Boolean isNativeHeapZeroInit() { - return nativeHeapZeroInit; + public int getNativeHeapZeroInitialized() { + return nativeHeapZeroInitialized; } @Override @@ -2495,20 +2499,21 @@ public class ParsingPackageImpl implements ParsingPackage, Parcelable { } @Override - public ParsingPackageImpl setGwpAsanMode(int value) { + public ParsingPackageImpl setGwpAsanMode(@ApplicationInfo.GwpAsanMode int value) { gwpAsanMode = value; return this; } @Override - public ParsingPackageImpl setMemtagMode(int value) { + public ParsingPackageImpl setMemtagMode(@ApplicationInfo.MemtagMode int value) { memtagMode = value; return this; } @Override - public ParsingPackageImpl setNativeHeapZeroInit(@Nullable Boolean value) { - nativeHeapZeroInit = value; + public ParsingPackageImpl setNativeHeapZeroInitialized( + @ApplicationInfo.NativeHeapZeroInitialized int value) { + nativeHeapZeroInitialized = value; return this; } diff --git a/core/java/android/content/pm/parsing/ParsingPackageRead.java b/core/java/android/content/pm/parsing/ParsingPackageRead.java index cd91e280b695..03117744d4ec 100644 --- a/core/java/android/content/pm/parsing/ParsingPackageRead.java +++ b/core/java/android/content/pm/parsing/ParsingPackageRead.java @@ -854,20 +854,22 @@ public interface ParsingPackageRead extends Parcelable { * @see ApplicationInfo#gwpAsanMode * @see R.styleable#AndroidManifest_gwpAsanMode */ - public int getGwpAsanMode(); + @ApplicationInfo.GwpAsanMode + int getGwpAsanMode(); /** * @see ApplicationInfo#memtagMode * @see R.styleable#AndroidManifest_memtagMode */ + @ApplicationInfo.MemtagMode int getMemtagMode(); - /** - * @see ApplicationInfo#nativeHeapZeroInit - * @see R.styleable#AndroidManifest_nativeHeapZeroInit + /** + * @see ApplicationInfo#nativeHeapZeroInitialized + * @see R.styleable#AndroidManifest_nativeHeapZeroInitialized */ - @Nullable - Boolean isNativeHeapZeroInit(); + @ApplicationInfo.NativeHeapZeroInitialized + int getNativeHeapZeroInitialized(); // TODO(b/135203078): Hide and enforce going through PackageInfoUtils ApplicationInfo toAppInfoWithoutState(); diff --git a/core/java/android/content/pm/parsing/ParsingPackageUtils.java b/core/java/android/content/pm/parsing/ParsingPackageUtils.java index 890ba8a59a89..c6a335a0c0fa 100644 --- a/core/java/android/content/pm/parsing/ParsingPackageUtils.java +++ b/core/java/android/content/pm/parsing/ParsingPackageUtils.java @@ -1800,9 +1800,11 @@ public class ParsingPackageUtils { pkg.setGwpAsanMode(sa.getInt(R.styleable.AndroidManifestApplication_gwpAsanMode, -1)); pkg.setMemtagMode(sa.getInt(R.styleable.AndroidManifestApplication_memtagMode, -1)); - if (sa.hasValue(R.styleable.AndroidManifestApplication_nativeHeapZeroInit)) { - pkg.setNativeHeapZeroInit(sa.getBoolean( - R.styleable.AndroidManifestApplication_nativeHeapZeroInit, false)); + if (sa.hasValue(R.styleable.AndroidManifestApplication_nativeHeapZeroInitialized)) { + Boolean v = sa.getBoolean( + R.styleable.AndroidManifestApplication_nativeHeapZeroInitialized, false); + pkg.setNativeHeapZeroInitialized( + v ? ApplicationInfo.ZEROINIT_ENABLED : ApplicationInfo.ZEROINIT_DISABLED); } } finally { sa.recycle(); diff --git a/core/java/android/content/pm/parsing/component/ParsedProcess.java b/core/java/android/content/pm/parsing/component/ParsedProcess.java index 89fef9d8e0dd..54a60d349331 100644 --- a/core/java/android/content/pm/parsing/component/ParsedProcess.java +++ b/core/java/android/content/pm/parsing/component/ParsedProcess.java @@ -42,10 +42,12 @@ public class ParsedProcess implements Parcelable { @DataClass.ParcelWith(Parcelling.BuiltIn.ForInternedStringSet.class) protected Set<String> deniedPermissions = emptySet(); + @ApplicationInfo.GwpAsanMode protected int gwpAsanMode = ApplicationInfo.GWP_ASAN_DEFAULT; + @ApplicationInfo.MemtagMode protected int memtagMode = ApplicationInfo.MEMTAG_DEFAULT; - @Nullable - protected Boolean nativeHeapZeroInit = null; + @ApplicationInfo.NativeHeapZeroInitialized + protected int nativeHeapZeroInitialized = ApplicationInfo.ZEROINIT_DEFAULT; public ParsedProcess() { } @@ -78,9 +80,9 @@ public class ParsedProcess implements Parcelable { public ParsedProcess( @NonNull String name, @NonNull Set<String> deniedPermissions, - int gwpAsanMode, - int memtagMode, - @Nullable Boolean nativeHeapZeroInit) { + @ApplicationInfo.GwpAsanMode int gwpAsanMode, + @ApplicationInfo.MemtagMode int memtagMode, + @ApplicationInfo.NativeHeapZeroInitialized int nativeHeapZeroInitialized) { this.name = name; com.android.internal.util.AnnotationValidations.validate( NonNull.class, null, name); @@ -88,8 +90,14 @@ public class ParsedProcess implements Parcelable { com.android.internal.util.AnnotationValidations.validate( NonNull.class, null, deniedPermissions); this.gwpAsanMode = gwpAsanMode; + com.android.internal.util.AnnotationValidations.validate( + ApplicationInfo.GwpAsanMode.class, null, gwpAsanMode); this.memtagMode = memtagMode; - this.nativeHeapZeroInit = nativeHeapZeroInit; + com.android.internal.util.AnnotationValidations.validate( + ApplicationInfo.MemtagMode.class, null, memtagMode); + this.nativeHeapZeroInitialized = nativeHeapZeroInitialized; + com.android.internal.util.AnnotationValidations.validate( + ApplicationInfo.NativeHeapZeroInitialized.class, null, nativeHeapZeroInitialized); // onConstructed(); // You can define this method to get a callback } @@ -105,18 +113,18 @@ public class ParsedProcess implements Parcelable { } @DataClass.Generated.Member - public int getGwpAsanMode() { + public @ApplicationInfo.GwpAsanMode int getGwpAsanMode() { return gwpAsanMode; } @DataClass.Generated.Member - public int getMemtagMode() { + public @ApplicationInfo.MemtagMode int getMemtagMode() { return memtagMode; } @DataClass.Generated.Member - public @Nullable Boolean getNativeHeapZeroInit() { - return nativeHeapZeroInit; + public @ApplicationInfo.NativeHeapZeroInitialized int getNativeHeapZeroInitialized() { + return nativeHeapZeroInitialized; } @DataClass.Generated.Member @@ -136,14 +144,11 @@ public class ParsedProcess implements Parcelable { // You can override field parcelling by defining methods like: // void parcelFieldName(Parcel dest, int flags) { ... } - byte flg = 0; - if (nativeHeapZeroInit != null) flg |= 0x10; - dest.writeByte(flg); dest.writeString(name); sParcellingForDeniedPermissions.parcel(deniedPermissions, dest, flags); dest.writeInt(gwpAsanMode); dest.writeInt(memtagMode); - if (nativeHeapZeroInit != null) dest.writeBoolean(nativeHeapZeroInit); + dest.writeInt(nativeHeapZeroInitialized); } @Override @@ -157,12 +162,11 @@ public class ParsedProcess implements Parcelable { // You can override field unparcelling by defining methods like: // static FieldType unparcelFieldName(Parcel in) { ... } - byte flg = in.readByte(); String _name = in.readString(); Set<String> _deniedPermissions = sParcellingForDeniedPermissions.unparcel(in); int _gwpAsanMode = in.readInt(); int _memtagMode = in.readInt(); - Boolean _nativeHeapZeroInit = (flg & 0x10) == 0 ? null : (Boolean) in.readBoolean(); + int _nativeHeapZeroInitialized = in.readInt(); this.name = _name; com.android.internal.util.AnnotationValidations.validate( @@ -171,8 +175,14 @@ public class ParsedProcess implements Parcelable { com.android.internal.util.AnnotationValidations.validate( NonNull.class, null, deniedPermissions); this.gwpAsanMode = _gwpAsanMode; + com.android.internal.util.AnnotationValidations.validate( + ApplicationInfo.GwpAsanMode.class, null, gwpAsanMode); this.memtagMode = _memtagMode; - this.nativeHeapZeroInit = _nativeHeapZeroInit; + com.android.internal.util.AnnotationValidations.validate( + ApplicationInfo.MemtagMode.class, null, memtagMode); + this.nativeHeapZeroInitialized = _nativeHeapZeroInitialized; + com.android.internal.util.AnnotationValidations.validate( + ApplicationInfo.NativeHeapZeroInitialized.class, null, nativeHeapZeroInitialized); // onConstructed(); // You can define this method to get a callback } @@ -192,10 +202,10 @@ public class ParsedProcess implements Parcelable { }; @DataClass.Generated( - time = 1611615591258L, + time = 1615850515058L, codegenVersion = "1.0.22", sourceFile = "frameworks/base/core/java/android/content/pm/parsing/component/ParsedProcess.java", - inputSignatures = "protected @android.annotation.NonNull java.lang.String name\nprotected @android.annotation.NonNull @com.android.internal.util.DataClass.ParcelWith(com.android.internal.util.Parcelling.BuiltIn.ForInternedStringSet.class) java.util.Set<java.lang.String> deniedPermissions\nprotected int gwpAsanMode\nprotected int memtagMode\nprotected @android.annotation.Nullable java.lang.Boolean nativeHeapZeroInit\npublic void addStateFrom(android.content.pm.parsing.component.ParsedProcess)\nclass ParsedProcess extends java.lang.Object implements [android.os.Parcelable]\n@com.android.internal.util.DataClass(genGetters=true, genSetters=false, genParcelable=true, genAidl=false, genBuilder=false)") + inputSignatures = "protected @android.annotation.NonNull java.lang.String name\nprotected @android.annotation.NonNull @com.android.internal.util.DataClass.ParcelWith(com.android.internal.util.Parcelling.BuiltIn.ForInternedStringSet.class) java.util.Set<java.lang.String> deniedPermissions\nprotected @android.content.pm.ApplicationInfo.GwpAsanMode int gwpAsanMode\nprotected @android.content.pm.ApplicationInfo.MemtagMode int memtagMode\nprotected @android.content.pm.ApplicationInfo.NativeHeapZeroInitialized int nativeHeapZeroInitialized\npublic void addStateFrom(android.content.pm.parsing.component.ParsedProcess)\nclass ParsedProcess extends java.lang.Object implements [android.os.Parcelable]\n@com.android.internal.util.DataClass(genGetters=true, genSetters=false, genParcelable=true, genAidl=false, genBuilder=false)") @Deprecated private void __metadata() {} diff --git a/core/java/android/content/pm/parsing/component/ParsedProcessUtils.java b/core/java/android/content/pm/parsing/component/ParsedProcessUtils.java index 082593efd498..c81d942c26d1 100644 --- a/core/java/android/content/pm/parsing/component/ParsedProcessUtils.java +++ b/core/java/android/content/pm/parsing/component/ParsedProcessUtils.java @@ -17,6 +17,7 @@ package android.content.pm.parsing.component; import android.annotation.NonNull; +import android.content.pm.ApplicationInfo; import android.content.pm.parsing.ParsingPackage; import android.content.pm.parsing.ParsingUtils; import android.content.pm.parsing.result.ParseInput; @@ -106,9 +107,11 @@ public class ParsedProcessUtils { proc.gwpAsanMode = sa.getInt(R.styleable.AndroidManifestProcess_gwpAsanMode, -1); proc.memtagMode = sa.getInt(R.styleable.AndroidManifestProcess_memtagMode, -1); - if (sa.hasValue(R.styleable.AndroidManifestProcess_nativeHeapZeroInit)) { - proc.nativeHeapZeroInit = - sa.getBoolean(R.styleable.AndroidManifestProcess_nativeHeapZeroInit, false); + if (sa.hasValue(R.styleable.AndroidManifestProcess_nativeHeapZeroInitialized)) { + Boolean v = sa.getBoolean( + R.styleable.AndroidManifestProcess_nativeHeapZeroInitialized, false); + proc.nativeHeapZeroInitialized = + v ? ApplicationInfo.ZEROINIT_ENABLED : ApplicationInfo.ZEROINIT_DISABLED; } } finally { sa.recycle(); diff --git a/core/java/android/hardware/biometrics/CryptoObject.java b/core/java/android/hardware/biometrics/CryptoObject.java index 0af18dfb0e3a..7648cf241298 100644 --- a/core/java/android/hardware/biometrics/CryptoObject.java +++ b/core/java/android/hardware/biometrics/CryptoObject.java @@ -18,7 +18,7 @@ package android.hardware.biometrics; import android.annotation.NonNull; import android.security.identity.IdentityCredential; -import android.security.keystore.AndroidKeyStoreProvider; +import android.security.keystore2.AndroidKeyStoreProvider; import java.security.Signature; diff --git a/core/java/android/hardware/camera2/CameraManager.java b/core/java/android/hardware/camera2/CameraManager.java index 933dee3a6470..609da3125485 100644 --- a/core/java/android/hardware/camera2/CameraManager.java +++ b/core/java/android/hardware/camera2/CameraManager.java @@ -1363,6 +1363,8 @@ public final class CameraManager { // devices going offline (in real world scenarios, these permissions aren't // changeable). Future calls to getCameraIdList() will reflect the changes in // the camera id list after getCameraIdListNoLazy() is called. + // We need to remove the torch ids which may have been associated with the + // devices removed as well. This is the same situation. cameraStatuses = mCameraService.addListener(testListener); mCameraService.removeListener(testListener); for (CameraStatus c : cameraStatuses) { @@ -1381,6 +1383,7 @@ public final class CameraManager { } for (String id : deviceIdsToRemove) { onStatusChangedLocked(ICameraServiceListener.STATUS_NOT_PRESENT, id); + mTorchStatus.remove(id); } } catch (ServiceSpecificException e) { // Unexpected failure diff --git a/core/java/android/hardware/hdmi/HdmiAudioSystemClient.java b/core/java/android/hardware/hdmi/HdmiAudioSystemClient.java index bdd5ab67af48..e7d76f66230d 100644 --- a/core/java/android/hardware/hdmi/HdmiAudioSystemClient.java +++ b/core/java/android/hardware/hdmi/HdmiAudioSystemClient.java @@ -63,7 +63,6 @@ public final class HdmiAudioSystemClient extends HdmiClient { * * @hide */ - // TODO(b/110094868): unhide and add @SystemApi for Q public interface SetSystemAudioModeCallback { /** * Called when the input was changed. @@ -74,7 +73,6 @@ public final class HdmiAudioSystemClient extends HdmiClient { } /** @hide */ - // TODO(b/110094868): unhide and add @SystemApi for Q @Override public int getDeviceType() { return HdmiDeviceInfo.DEVICE_AUDIO_SYSTEM; @@ -143,7 +141,6 @@ public final class HdmiAudioSystemClient extends HdmiClient { * * @hide */ - // TODO(b/110094868): unhide and add @SystemApi for Q public void setSystemAudioMode(boolean state, @NonNull SetSystemAudioModeCallback callback) { // TODO(amyjojo): implement this when needed. } @@ -156,7 +153,6 @@ public final class HdmiAudioSystemClient extends HdmiClient { * * @hide */ - // TODO(b/110094868): unhide and add @SystemApi for Q public void setSystemAudioModeOnForAudioOnlySource() { try { mService.setSystemAudioModeOnForAudioOnlySource(); diff --git a/core/java/android/hardware/hdmi/HdmiClient.java b/core/java/android/hardware/hdmi/HdmiClient.java index a921215c6133..0c21746ea412 100644 --- a/core/java/android/hardware/hdmi/HdmiClient.java +++ b/core/java/android/hardware/hdmi/HdmiClient.java @@ -65,7 +65,6 @@ public abstract class HdmiClient { * @param isPressed true if this is key press event * * @hide - * TODO(b/110094868): unhide for Q */ public void sendVolumeKeyEvent(int keyCode, boolean isPressed) { try { diff --git a/core/java/android/hardware/hdmi/HdmiControlManager.java b/core/java/android/hardware/hdmi/HdmiControlManager.java index f25b06b5dc45..980c11a0b95b 100644 --- a/core/java/android/hardware/hdmi/HdmiControlManager.java +++ b/core/java/android/hardware/hdmi/HdmiControlManager.java @@ -472,7 +472,6 @@ public final class HdmiControlManager { * * @return {@link HdmiAudioSystemClient} instance. {@code null} on failure. * - * TODO(b/110094868): unhide for Q * @hide */ @Nullable diff --git a/core/java/android/hardware/hdmi/HdmiPlaybackClient.java b/core/java/android/hardware/hdmi/HdmiPlaybackClient.java index f13326b71ce6..d06bc1d2053d 100644 --- a/core/java/android/hardware/hdmi/HdmiPlaybackClient.java +++ b/core/java/android/hardware/hdmi/HdmiPlaybackClient.java @@ -84,7 +84,6 @@ public final class HdmiPlaybackClient extends HdmiClient { * of the result */ public void oneTouchPlay(OneTouchPlayCallback callback) { - // TODO: Use PendingResult. try { mService.oneTouchPlay(getCallbackWrapper(callback)); } catch (RemoteException e) { diff --git a/core/java/android/hardware/hdmi/HdmiUtils.java b/core/java/android/hardware/hdmi/HdmiUtils.java index 8c94b7841a80..2f4378ebed9d 100644 --- a/core/java/android/hardware/hdmi/HdmiUtils.java +++ b/core/java/android/hardware/hdmi/HdmiUtils.java @@ -24,7 +24,6 @@ import java.lang.annotation.RetentionPolicy; /** * Various utilities related to HDMI CEC. * - * TODO(b/110094868): unhide for Q * @hide */ public final class HdmiUtils { @@ -84,7 +83,6 @@ public final class HdmiUtils { } /** - * TODO(b/110094868): unhide for Q * @hide */ @Retention(RetentionPolicy.SOURCE) @@ -95,49 +93,49 @@ public final class HdmiUtils { public @interface HdmiAddressRelativePosition {} /** * HDMI relative position is not determined. - * TODO(b/110094868): unhide for Q + * * @hide */ public static final int HDMI_RELATIVE_POSITION_UNKNOWN = 0; /** * HDMI relative position: directly blow the device. - * TODO(b/110094868): unhide for Q + * * @hide */ public static final int HDMI_RELATIVE_POSITION_DIRECTLY_BELOW = 1; /** * HDMI relative position: indirectly below the device. - * TODO(b/110094868): unhide for Q + * * @hide */ public static final int HDMI_RELATIVE_POSITION_BELOW = 2; /** * HDMI relative position: the same device. - * TODO(b/110094868): unhide for Q + * * @hide */ public static final int HDMI_RELATIVE_POSITION_SAME = 3; /** * HDMI relative position: directly above the device. - * TODO(b/110094868): unhide for Q + * * @hide */ public static final int HDMI_RELATIVE_POSITION_DIRECTLY_ABOVE = 4; /** * HDMI relative position: indirectly above the device. - * TODO(b/110094868): unhide for Q + * * @hide */ public static final int HDMI_RELATIVE_POSITION_ABOVE = 5; /** * HDMI relative position: directly below a same device. - * TODO(b/110094868): unhide for Q + * * @hide */ public static final int HDMI_RELATIVE_POSITION_SIBLING = 6; /** * HDMI relative position: different branch. - * TODO(b/110094868): unhide for Q + * * @hide */ public static final int HDMI_RELATIVE_POSITION_DIFFERENT_BRANCH = 7; diff --git a/core/java/android/net/DnsResolverServiceManager.java b/core/java/android/net/DnsResolverServiceManager.java deleted file mode 100644 index 15973224f10b..000000000000 --- a/core/java/android/net/DnsResolverServiceManager.java +++ /dev/null @@ -1,63 +0,0 @@ -/* - * Copyright (C) 2020 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package android.net; - -import android.annotation.NonNull; -import android.annotation.RequiresPermission; -import android.annotation.SystemApi; -import android.content.Context; -import android.os.IBinder; -import android.os.ServiceManager; - -import java.util.Objects; - -/** - * Provides a way to obtain the DnsResolver binder objects. - * - * @hide - */ -@SystemApi -public class DnsResolverServiceManager { - /** - * Name to retrieve a {@link android.net.IDnsResolver} IBinder. - */ - private static final String DNS_RESOLVER_SERVICE = "dnsresolver"; - - private DnsResolverServiceManager() {} - - /** - * Get an {@link IBinder} representing the DnsResolver stable AIDL interface - * - * @param context the context for permission check. - * @return {@link android.net.IDnsResolver} IBinder. - */ - @NonNull - @RequiresPermission(NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK) - public static IBinder getService(@NonNull final Context context) { - Objects.requireNonNull(context); - context.enforceCallingOrSelfPermission(NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK, - "DnsResolverServiceManager"); - try { - return ServiceManager.getServiceOrThrow(DNS_RESOLVER_SERVICE); - } catch (ServiceManager.ServiceNotFoundException e) { - // Catch ServiceManager#ServiceNotFoundException and rethrow IllegalStateException - // because ServiceManager#ServiceNotFoundException is @hide so that it can't be listed - // on the system api. Thus, rethrow IllegalStateException if dns resolver service cannot - // be found. - throw new IllegalStateException("Cannot find dns resolver service."); - } - } -} diff --git a/core/java/android/net/EthernetNetworkSpecifier.java b/core/java/android/net/EthernetNetworkSpecifier.java index e1685887e806..62c576144221 100644 --- a/core/java/android/net/EthernetNetworkSpecifier.java +++ b/core/java/android/net/EthernetNetworkSpecifier.java @@ -42,15 +42,22 @@ public final class EthernetNetworkSpecifier extends NetworkSpecifier implements @NonNull private final String mInterfaceName; + /** + * Create a new EthernetNetworkSpecifier. + * @param interfaceName Name of the ethernet interface the specifier refers to. + */ public EthernetNetworkSpecifier(@NonNull String interfaceName) { Preconditions.checkStringNotEmpty(interfaceName); mInterfaceName = interfaceName; } - // This may be null in the future to support specifiers based on data other than the interface - // name. + /** + * Get the name of the ethernet interface the specifier refers to. + */ @Nullable public String getInterfaceName() { + // This may be null in the future to support specifiers based on data other than the + // interface name. return mInterfaceName; } diff --git a/core/java/android/net/NetworkPolicyManager.java b/core/java/android/net/NetworkPolicyManager.java index da3febddd973..b074fada66bd 100644 --- a/core/java/android/net/NetworkPolicyManager.java +++ b/core/java/android/net/NetworkPolicyManager.java @@ -772,6 +772,12 @@ public class NetworkPolicyManager { return DebugUtils.flagsToString(NetworkPolicyManager.class, "BLOCKED_", blockedReasons); } + /** @hide */ + @NonNull + public static String allowedReasonsToString(int allowedReasons) { + return DebugUtils.flagsToString(NetworkPolicyManager.class, "ALLOWED_", allowedReasons); + } + /** * Register a {@link NetworkPolicyCallback} to listen for changes to network blocked status * of apps. diff --git a/core/java/android/net/NetworkWatchlistManager.java b/core/java/android/net/NetworkWatchlistManager.java index 8f6510ed3ea5..da01dcb83de4 100644 --- a/core/java/android/net/NetworkWatchlistManager.java +++ b/core/java/android/net/NetworkWatchlistManager.java @@ -19,6 +19,7 @@ package android.net; import android.annotation.Nullable; import android.annotation.SystemApi; import android.annotation.SystemService; +import android.annotation.TestApi; import android.content.Context; import android.os.RemoteException; import android.os.ServiceManager; @@ -31,6 +32,7 @@ import com.android.internal.util.Preconditions; * Class that manage network watchlist in system. * @hide */ +@TestApi @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES) @SystemService(Context.NETWORK_WATCHLIST_SERVICE) public class NetworkWatchlistManager { diff --git a/core/java/android/net/VpnManager.java b/core/java/android/net/VpnManager.java index 5f65d46f3b1e..662ebb356f4c 100644 --- a/core/java/android/net/VpnManager.java +++ b/core/java/android/net/VpnManager.java @@ -78,10 +78,8 @@ public class VpnManager { /** * An IPsec VPN created by the built-in LegacyVpnRunner. - * @deprecated new Android devices should use VPN_TYPE_PLATFORM instead. * @hide */ - @Deprecated @SystemApi(client = MODULE_LIBRARIES) public static final int TYPE_VPN_LEGACY = 3; @@ -418,4 +416,4 @@ public class VpnManager { throw e.rethrowFromSystemServer(); } } -}
\ No newline at end of file +} diff --git a/core/java/android/net/vcn/persistablebundleutils/IkeSessionParamsUtils.java b/core/java/android/net/vcn/persistablebundleutils/IkeSessionParamsUtils.java index 9d3462cb0b2e..8950c4bf2089 100644 --- a/core/java/android/net/vcn/persistablebundleutils/IkeSessionParamsUtils.java +++ b/core/java/android/net/vcn/persistablebundleutils/IkeSessionParamsUtils.java @@ -83,7 +83,7 @@ public final class IkeSessionParamsUtils { /** Serializes an IkeSessionParams to a PersistableBundle. */ @NonNull public static PersistableBundle toPersistableBundle(@NonNull IkeSessionParams params) { - if (params.getConfiguredNetwork() != null || params.getIke3gppExtension() != null) { + if (params.getNetwork() != null || params.getIke3gppExtension() != null) { throw new IllegalStateException( "Cannot convert a IkeSessionParams with a caller configured network or with" + " 3GPP extension enabled"); diff --git a/core/java/android/nfc/INfcAdapter.aidl b/core/java/android/nfc/INfcAdapter.aidl index 11445e9aec5a..cb9a3e43db81 100644 --- a/core/java/android/nfc/INfcAdapter.aidl +++ b/core/java/android/nfc/INfcAdapter.aidl @@ -24,6 +24,7 @@ import android.nfc.Tag; import android.nfc.TechListParcel; import android.nfc.IAppCallback; import android.nfc.INfcAdapterExtras; +import android.nfc.INfcControllerAlwaysOnListener; import android.nfc.INfcTag; import android.nfc.INfcCardEmulation; import android.nfc.INfcFCardEmulation; @@ -75,4 +76,6 @@ interface INfcAdapter boolean setControllerAlwaysOn(boolean value); boolean isControllerAlwaysOn(); boolean isControllerAlwaysOnSupported(); + void registerControllerAlwaysOnListener(in INfcControllerAlwaysOnListener listener); + void unregisterControllerAlwaysOnListener(in INfcControllerAlwaysOnListener listener); } diff --git a/core/java/android/nfc/INfcControllerAlwaysOnListener.aidl b/core/java/android/nfc/INfcControllerAlwaysOnListener.aidl new file mode 100644 index 000000000000..1bb7680d2fed --- /dev/null +++ b/core/java/android/nfc/INfcControllerAlwaysOnListener.aidl @@ -0,0 +1,29 @@ +/* + * Copyright 2021 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.nfc; + +/** + * @hide + */ +oneway interface INfcControllerAlwaysOnListener { + /** + * Called whenever the controller always on state changes + * + * @param isEnabled true if the state is enabled, false otherwise + */ + void onControllerAlwaysOnChanged(boolean isEnabled); +} diff --git a/core/java/android/nfc/NfcAdapter.java b/core/java/android/nfc/NfcAdapter.java index eed2c77b06b9..64c121194932 100644 --- a/core/java/android/nfc/NfcAdapter.java +++ b/core/java/android/nfc/NfcAdapter.java @@ -16,6 +16,7 @@ package android.nfc; +import android.annotation.CallbackExecutor; import android.annotation.NonNull; import android.annotation.RequiresPermission; import android.annotation.SdkConstant; @@ -47,6 +48,7 @@ import java.io.IOException; import java.util.ArrayList; import java.util.HashMap; import java.util.List; +import java.util.concurrent.Executor; /** * Represents the local NFC adapter. @@ -65,6 +67,8 @@ import java.util.List; public final class NfcAdapter { static final String TAG = "NFC"; + private final NfcControllerAlwaysOnListener mControllerAlwaysOnListener; + /** * Intent to start an activity when a tag with NDEF payload is discovered. * @@ -350,22 +354,6 @@ public final class NfcAdapter { "android.nfc.extra.HANDOVER_TRANSFER_STATUS"; /** @hide */ - public static final String ACTION_ALWAYS_ON_STATE_CHANGED = - "android.nfc.action.ALWAYS_ON_STATE_CHANGED"; - - /** - * Used as an int extra field in {@link #ACTION_ALWAYS_ON_STATE_CHANGED} - * intents to request the current power state. Possible values are: - * {@link #STATE_OFF}, - * {@link #STATE_TURNING_ON}, - * {@link #STATE_ON}, - * {@link #STATE_TURNING_OFF}, - * @hide - */ - public static final String EXTRA_ALWAYS_ON_STATE = - "android.nfc.extra.ALWAYS_ON_STATE"; - - /** @hide */ public static final int HANDOVER_TRANSFER_STATUS_SUCCESS = 0; /** @hide */ public static final int HANDOVER_TRANSFER_STATUS_FAILURE = 1; @@ -430,6 +418,22 @@ public final class NfcAdapter { } /** + * A listener to be invoked when NFC controller always on state changes. + * <p>Register your {@code ControllerAlwaysOnListener} implementation with {@link + * NfcAdapter#registerControllerAlwaysOnListener} and disable it with {@link + * NfcAdapter#unregisterControllerAlwaysOnListener}. + * @see #registerControllerAlwaysOnListener + * @hide + */ + @SystemApi + public interface ControllerAlwaysOnListener { + /** + * Called on NFC controller always on state changes + */ + void onControllerAlwaysOnChanged(boolean isEnabled); + } + + /** * A callback to be invoked when the system successfully delivers your {@link NdefMessage} * to another device. * @see #setOnNdefPushCompleteCallback @@ -744,6 +748,7 @@ public final class NfcAdapter { mNfcUnlockHandlers = new HashMap<NfcUnlockHandler, INfcUnlockHandler>(); mTagRemovedListener = null; mLock = new Object(); + mControllerAlwaysOnListener = new NfcControllerAlwaysOnListener(getService()); } /** @@ -2239,14 +2244,16 @@ public final class NfcAdapter { /** * Sets NFC controller always on feature. * <p>This API is for the NFCC internal state management. It allows to discriminate - * the controller function from the NFC function by keeping the NFC Controller on without + * the controller function from the NFC function by keeping the NFC controller on without * any NFC RF enabled if necessary. - * <p>This call is asynchronous. Listen for {@link #ACTION_ALWAYS_ON_STATE_CHANGED} - * broadcasts to find out when the operation is complete. - * <p>If this returns true, then either NFCC is already on, or - * a {@link #ACTION_ALWAYS_ON_STATE_CHANGED} broadcast will be sent to indicate - * a state transition. - * If this returns false, then there is some problem that prevents an attempt to turn NFCC on. + * <p>This call is asynchronous. Register a listener {@link #ControllerAlwaysOnListener} + * by {@link #registerControllerAlwaysOnListener} to find out when the operation is + * complete. + * <p>If this returns true, then either NFCC always on state has been set based on the value, + * or a {@link ControllerAlwaysOnListener#onControllerAlwaysOnChanged(boolean)} will be invoked + * to indicate the state change. + * If this returns false, then there is some problem that prevents an attempt to turn NFCC + * always on. * @param value if true the NFCC will be kept on (with no RF enabled if NFC adapter is * disabled), if false the NFCC will follow completely the Nfc adapter state. * @throws UnsupportedOperationException if FEATURE_NFC is unavailable. @@ -2284,7 +2291,6 @@ public final class NfcAdapter { * @throws UnsupportedOperationException if FEATURE_NFC is unavailable. * @hide */ - @SystemApi @RequiresPermission(android.Manifest.permission.NFC_SET_CONTROLLER_ALWAYS_ON) public boolean isControllerAlwaysOn() { @@ -2313,7 +2319,6 @@ public final class NfcAdapter { * @throws UnsupportedOperationException if FEATURE_NFC is unavailable. * @hide */ - @SystemApi @RequiresPermission(android.Manifest.permission.NFC_SET_CONTROLLER_ALWAYS_ON) public boolean isControllerAlwaysOnSupported() { @@ -2337,4 +2342,39 @@ public final class NfcAdapter { return false; } } + + /** + * Register a {@link ControllerAlwaysOnListener} to listen for NFC controller always on + * state changes + * <p>The provided listener will be invoked by the given {@link Executor}. + * + * @param executor an {@link Executor} to execute given listener + * @param listener user implementation of the {@link ControllerAlwaysOnListener} + * @hide + */ + @SystemApi + @RequiresPermission(android.Manifest.permission.NFC_SET_CONTROLLER_ALWAYS_ON) + public void registerControllerAlwaysOnListener( + @NonNull @CallbackExecutor Executor executor, + @NonNull ControllerAlwaysOnListener listener) { + mControllerAlwaysOnListener.register(executor, listener); + } + + /** + * Unregister the specified {@link ControllerAlwaysOnListener} + * <p>The same {@link ControllerAlwaysOnListener} object used when calling + * {@link #registerControllerAlwaysOnListener(Executor, ControllerAlwaysOnListener)} + * must be used. + * + * <p>Listeners are automatically unregistered when application process goes away + * + * @param listener user implementation of the {@link ControllerAlwaysOnListener} + * @hide + */ + @SystemApi + @RequiresPermission(android.Manifest.permission.NFC_SET_CONTROLLER_ALWAYS_ON) + public void unregisterControllerAlwaysOnListener( + @NonNull ControllerAlwaysOnListener listener) { + mControllerAlwaysOnListener.unregister(listener); + } } diff --git a/core/java/android/nfc/NfcControllerAlwaysOnListener.java b/core/java/android/nfc/NfcControllerAlwaysOnListener.java new file mode 100644 index 000000000000..96707bb432db --- /dev/null +++ b/core/java/android/nfc/NfcControllerAlwaysOnListener.java @@ -0,0 +1,120 @@ +/* + * Copyright 2021 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.nfc; + +import android.annotation.NonNull; +import android.nfc.NfcAdapter.ControllerAlwaysOnListener; +import android.os.Binder; +import android.os.RemoteException; +import android.util.Log; + +import java.util.HashMap; +import java.util.Map; +import java.util.concurrent.Executor; + +/** + * @hide + */ +public class NfcControllerAlwaysOnListener extends INfcControllerAlwaysOnListener.Stub { + private static final String TAG = NfcControllerAlwaysOnListener.class.getSimpleName(); + + private final INfcAdapter mAdapter; + + private final Map<ControllerAlwaysOnListener, Executor> mListenerMap = new HashMap<>(); + + private boolean mCurrentState = false; + private boolean mIsRegistered = false; + + public NfcControllerAlwaysOnListener(@NonNull INfcAdapter adapter) { + mAdapter = adapter; + } + + /** + * Register a {@link ControllerAlwaysOnListener} with this + * {@link NfcControllerAlwaysOnListener} + * + * @param executor an {@link Executor} to execute given listener + * @param listener user implementation of the {@link ControllerAlwaysOnListener} + */ + public void register(@NonNull Executor executor, + @NonNull ControllerAlwaysOnListener listener) { + synchronized (this) { + if (mListenerMap.containsKey(listener)) { + return; + } + + mListenerMap.put(listener, executor); + if (!mIsRegistered) { + try { + mAdapter.registerControllerAlwaysOnListener(this); + mIsRegistered = true; + } catch (RemoteException e) { + Log.w(TAG, "Failed to register"); + } + } + } + } + + /** + * Unregister the specified {@link ControllerAlwaysOnListener} + * + * @param listener user implementation of the {@link ControllerAlwaysOnListener} + */ + public void unregister(@NonNull ControllerAlwaysOnListener listener) { + synchronized (this) { + if (!mListenerMap.containsKey(listener)) { + return; + } + + mListenerMap.remove(listener); + + if (mListenerMap.isEmpty() && mIsRegistered) { + try { + mAdapter.unregisterControllerAlwaysOnListener(this); + } catch (RemoteException e) { + Log.w(TAG, "Failed to unregister"); + } + mIsRegistered = false; + } + } + } + + private void sendCurrentState(@NonNull ControllerAlwaysOnListener listener) { + synchronized (this) { + Executor executor = mListenerMap.get(listener); + + final long identity = Binder.clearCallingIdentity(); + try { + executor.execute(() -> listener.onControllerAlwaysOnChanged( + mCurrentState)); + } finally { + Binder.restoreCallingIdentity(identity); + } + } + } + + @Override + public void onControllerAlwaysOnChanged(boolean isEnabled) { + synchronized (this) { + mCurrentState = isEnabled; + for (ControllerAlwaysOnListener cb : mListenerMap.keySet()) { + sendCurrentState(cb); + } + } + } +} + diff --git a/core/java/android/nfc/TEST_MAPPING b/core/java/android/nfc/TEST_MAPPING new file mode 100644 index 000000000000..71ad687b7889 --- /dev/null +++ b/core/java/android/nfc/TEST_MAPPING @@ -0,0 +1,7 @@ +{ + "presubmit": [ + { + "name": "NfcManagerTests" + } + ] +} diff --git a/core/java/android/os/BatteryStatsManager.java b/core/java/android/os/BatteryStatsManager.java index 3f4a21878687..f5172cf0fb69 100644 --- a/core/java/android/os/BatteryStatsManager.java +++ b/core/java/android/os/BatteryStatsManager.java @@ -386,10 +386,9 @@ public final class BatteryStatsManager { * @param uid Uid of this event. For the active state it represents the uid that was responsible * for waking the radio, or -1 if the system was responsible for waking the radio. * For inactive state, the UID should always be -1. - * @throws RuntimeException if there are binder remote-invocation errors. */ @RequiresPermission(android.Manifest.permission.UPDATE_DEVICE_STATS) - public void reportMobileRadioPowerState(boolean isActive, int uid) throws RuntimeException { + public void reportMobileRadioPowerState(boolean isActive, int uid) { try { mBatteryStats.noteMobileRadioPowerState(getDataConnectionPowerState(isActive), SystemClock.elapsedRealtimeNanos(), uid); @@ -405,10 +404,9 @@ public final class BatteryStatsManager { * @param uid Uid of this event. For the active state it represents the uid that was responsible * for waking the radio, or -1 if the system was responsible for waking the radio. * For inactive state, the UID should always be -1. - * @throws RuntimeException if there are binder remote-invocation errors. */ @RequiresPermission(android.Manifest.permission.UPDATE_DEVICE_STATS) - public void reportWifiRadioPowerState(boolean isActive, int uid) throws RuntimeException { + public void reportWifiRadioPowerState(boolean isActive, int uid) { try { mBatteryStats.noteWifiRadioPowerState(getDataConnectionPowerState(isActive), SystemClock.elapsedRealtimeNanos(), uid); diff --git a/core/java/android/os/Build.java b/core/java/android/os/Build.java index 03caafda2b13..e47ffcc4ff4c 100755 --- a/core/java/android/os/Build.java +++ b/core/java/android/os/Build.java @@ -1309,10 +1309,25 @@ public class Build { * Debuggable builds allow users to gain root access via local shell, attach debuggers to any * application regardless of whether they have the "debuggable" attribute set, or downgrade * selinux into "permissive" mode in particular. + * @hide */ public static final boolean IS_DEBUGGABLE = SystemProperties.getInt("ro.debuggable", 0) == 1; + /** + * Returns true if the device is running a debuggable build such as "userdebug" or "eng". + * + * Debuggable builds allow users to gain root access via local shell, attach debuggers to any + * application regardless of whether they have the "debuggable" attribute set, or downgrade + * selinux into "permissive" mode in particular. + * @hide + */ + @TestApi + @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES) + public static boolean isDebuggable() { + return IS_DEBUGGABLE; + } + /** {@hide} */ public static final boolean IS_ENG = "eng".equals(TYPE); /** {@hide} */ diff --git a/core/java/android/os/IRecoverySystem.aidl b/core/java/android/os/IRecoverySystem.aidl index 205288303b1e..9368b68a91c6 100644 --- a/core/java/android/os/IRecoverySystem.aidl +++ b/core/java/android/os/IRecoverySystem.aidl @@ -30,6 +30,6 @@ interface IRecoverySystem { boolean requestLskf(in String packageName, in IntentSender sender); boolean clearLskf(in String packageName); boolean isLskfCaptured(in String packageName); - boolean rebootWithLskfAssumeSlotSwitch(in String packageName, in String reason); - boolean rebootWithLskf(in String packageName, in String reason, in boolean slotSwitch); + int rebootWithLskfAssumeSlotSwitch(in String packageName, in String reason); + int rebootWithLskf(in String packageName, in String reason, in boolean slotSwitch); } diff --git a/core/java/android/os/RecoverySystem.java b/core/java/android/os/RecoverySystem.java index 43184ea4b9a9..b474d7c95996 100644 --- a/core/java/android/os/RecoverySystem.java +++ b/core/java/android/os/RecoverySystem.java @@ -20,6 +20,7 @@ import static android.view.Display.DEFAULT_DISPLAY; import static java.nio.charset.StandardCharsets.UTF_8; +import android.annotation.IntDef; import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.RequiresPermission; @@ -155,6 +156,66 @@ public class RecoverySystem { private final IRecoverySystem mService; /** + * The error codes for reboots initiated by resume on reboot clients. + * @hide + */ + @IntDef(prefix = { "RESUME_ON_REBOOT_REBOOT_ERROR_" }, value = { + RESUME_ON_REBOOT_REBOOT_ERROR_NONE, + RESUME_ON_REBOOT_REBOOT_ERROR_UNSPECIFIED, + RESUME_ON_REBOOT_REBOOT_ERROR_INVALID_PACKAGE_NAME, + RESUME_ON_REBOOT_REBOOT_ERROR_LSKF_NOT_CAPTURED, + RESUME_ON_REBOOT_REBOOT_ERROR_SLOT_MISMATCH, + RESUME_ON_REBOOT_REBOOT_ERROR_PROVIDER_PREPARATION_FAILURE}) + public @interface ResumeOnRebootRebootErrorCode {} + + /** + * The preparation of resume on reboot succeeds. + * + * <p> Don't expose it because a successful reboot should just reboot the device. + * @hide + */ + public static final int RESUME_ON_REBOOT_REBOOT_ERROR_NONE = 0; + + /** + * The resume on reboot fails due to an unknown reason. + * @hide + */ + @SystemApi + public static final int RESUME_ON_REBOOT_REBOOT_ERROR_UNSPECIFIED = 1000; + + /** + * The resume on reboot fails because the package name of the client is invalid, e.g. null + * packageName, name contains invalid characters, etc. + * @hide + */ + @SystemApi + public static final int RESUME_ON_REBOOT_REBOOT_ERROR_INVALID_PACKAGE_NAME = 2000; + + /** + * The resume on reboot fails because the Lock Screen Knowledge Factor hasn't been captured. + * This error is also reported if the client attempts to reboot without preparing RoR. + * @hide + */ + @SystemApi + public static final int RESUME_ON_REBOOT_REBOOT_ERROR_LSKF_NOT_CAPTURED = 3000; + + /** + * The resume on reboot fails because the client expects a different boot slot for the next boot + * on A/B devices. + * @hide + */ + @SystemApi + public static final int RESUME_ON_REBOOT_REBOOT_ERROR_SLOT_MISMATCH = 4000; + + /** + * The resume on reboot fails because the resume on reboot provider, e.g. HAL / server based, + * fails to arm/store the escrow key. + * @hide + */ + @SystemApi + public static final int RESUME_ON_REBOOT_REBOOT_ERROR_PROVIDER_PREPARATION_FAILURE = 5000; + + /** * Interface definition for a callback to be invoked regularly as * verification proceeds. */ @@ -723,7 +784,8 @@ public class RecoverySystem { } RecoverySystem rs = (RecoverySystem) context.getSystemService(Context.RECOVERY_SERVICE); // OTA is the sole user, who expects a slot switch. - if (!rs.rebootWithLskfAssumeSlotSwitch(context.getPackageName(), reason)) { + if (rs.rebootWithLskfAssumeSlotSwitch(context.getPackageName(), reason) + != RESUME_ON_REBOOT_REBOOT_ERROR_NONE) { throw new IOException("system not prepared to apply update"); } } @@ -752,19 +814,19 @@ public class RecoverySystem { * @param context the Context to use. * @param reason the reboot reason to give to the {@link PowerManager} * @param slotSwitch true if the caller expects the slot to be switched on A/B devices. - * @throws IOException if the reboot couldn't proceed because the device wasn't ready for an - * unattended reboot. + * + * @return 0 on success, and a non-zero error code if the reboot couldn't proceed because the + * device wasn't ready for an unattended reboot. + * @throws IOException on remote exceptions from the RecoverySystemService * @hide */ @SystemApi @RequiresPermission(anyOf = {android.Manifest.permission.RECOVERY, android.Manifest.permission.REBOOT}) - public static void rebootAndApply(@NonNull Context context, + public static @ResumeOnRebootRebootErrorCode int rebootAndApply(@NonNull Context context, @NonNull String reason, boolean slotSwitch) throws IOException { RecoverySystem rs = context.getSystemService(RecoverySystem.class); - if (!rs.rebootWithLskf(context.getPackageName(), reason, slotSwitch)) { - throw new IOException("system not prepared to apply update"); - } + return rs.rebootWithLskf(context.getPackageName(), reason, slotSwitch); } /** @@ -1399,8 +1461,8 @@ public class RecoverySystem { * Calls the recovery system service to reboot and apply update. * */ - private boolean rebootWithLskf(String packageName, String reason, boolean slotSwitch) - throws IOException { + private @ResumeOnRebootRebootErrorCode int rebootWithLskf(String packageName, String reason, + boolean slotSwitch) throws IOException { try { return mService.rebootWithLskf(packageName, reason, slotSwitch); } catch (RemoteException e) { @@ -1414,8 +1476,8 @@ public class RecoverySystem { * expects a slot switch for A/B devices. * */ - private boolean rebootWithLskfAssumeSlotSwitch(String packageName, String reason) - throws IOException { + private @ResumeOnRebootRebootErrorCode int rebootWithLskfAssumeSlotSwitch(String packageName, + String reason) throws IOException { try { return mService.rebootWithLskfAssumeSlotSwitch(packageName, reason); } catch (RemoteException e) { diff --git a/core/java/android/os/UserHandle.java b/core/java/android/os/UserHandle.java index 7b62e6652a04..d065d7a0df83 100644 --- a/core/java/android/os/UserHandle.java +++ b/core/java/android/os/UserHandle.java @@ -303,16 +303,15 @@ public final class UserHandle implements Parcelable { } /** - * Returns the uid that is composed from the userHandle and the appId. + * Returns the uid representing the given appId for this UserHandle. * - * @param userHandle the UserHandle to compose the uid * @param appId the AppId to compose the uid - * @return the uid that is composed from the userHandle and the appId + * @return the uid representing the given appId for this UserHandle * @hide */ @SystemApi - public static int getUid(@NonNull UserHandle userHandle, @AppIdInt int appId) { - return getUid(userHandle.getIdentifier(), appId); + public int getUid(@AppIdInt int appId) { + return getUid(getIdentifier(), appId); } /** diff --git a/core/java/android/provider/SimPhonebookContract.java b/core/java/android/provider/SimPhonebookContract.java index 030b86339822..fb89eb038558 100644 --- a/core/java/android/provider/SimPhonebookContract.java +++ b/core/java/android/provider/SimPhonebookContract.java @@ -17,13 +17,14 @@ package android.provider; import static android.provider.SimPhonebookContract.ElementaryFiles.EF_ADN; -import static android.provider.SimPhonebookContract.ElementaryFiles.EF_ADN_PATH_SEGMENT; import static android.provider.SimPhonebookContract.ElementaryFiles.EF_FDN; -import static android.provider.SimPhonebookContract.ElementaryFiles.EF_FDN_PATH_SEGMENT; import static android.provider.SimPhonebookContract.ElementaryFiles.EF_SDN; -import static android.provider.SimPhonebookContract.ElementaryFiles.EF_SDN_PATH_SEGMENT; +import static android.provider.SimPhonebookContract.ElementaryFiles.PATH_SEGMENT_EF_ADN; +import static android.provider.SimPhonebookContract.ElementaryFiles.PATH_SEGMENT_EF_FDN; +import static android.provider.SimPhonebookContract.ElementaryFiles.PATH_SEGMENT_EF_SDN; import android.annotation.IntDef; +import android.annotation.IntRange; import android.annotation.NonNull; import android.annotation.SystemApi; import android.annotation.WorkerThread; @@ -78,11 +79,11 @@ public final class SimPhonebookContract { public static String getEfUriPath(@ElementaryFiles.EfType int efType) { switch (efType) { case EF_ADN: - return EF_ADN_PATH_SEGMENT; + return PATH_SEGMENT_EF_ADN; case EF_FDN: - return EF_FDN_PATH_SEGMENT; + return PATH_SEGMENT_EF_FDN; case EF_SDN: - return EF_SDN_PATH_SEGMENT; + return PATH_SEGMENT_EF_SDN; default: throw new IllegalArgumentException("Unsupported EfType " + efType); } @@ -109,9 +110,9 @@ public final class SimPhonebookContract { * the phone number can contain at most {@link ElementaryFiles#PHONE_NUMBER_MAX_LENGTH} * characters. The {@link SimRecords#NAME} column can contain at most * {@link ElementaryFiles#NAME_MAX_LENGTH} bytes when it is encoded for storage on the SIM. - * Encoding is done internally and so the name should be provided unencoded but the number of - * bytes required to encode it will vary depending on the characters it contains. This length - * can be determined by calling + * Encoding is done internally and so the name should be provided to these provider APIs as a + * Java String but the number of bytes required to encode it for storage will vary depending on + * the characters it contains. This length can be determined by calling * {@link SimRecords#getEncodedNameLength(ContentResolver, String)}. * </p> * <h3>Operations </h3> @@ -308,7 +309,8 @@ public final class SimPhonebookContract { */ @NonNull public static Uri getItemUri( - int subscriptionId, @ElementaryFiles.EfType int efType, int recordNumber) { + int subscriptionId, @ElementaryFiles.EfType int efType, + @IntRange(from = 1) int recordNumber) { // Elementary file record indices are 1-based. Preconditions.checkArgument(recordNumber > 0, "Invalid recordNumber"); @@ -332,6 +334,7 @@ public final class SimPhonebookContract { * @see ElementaryFiles#NAME_MAX_LENGTH */ @WorkerThread + @IntRange(from = 0) public static int getEncodedNameLength( @NonNull ContentResolver resolver, @NonNull String name) { Objects.requireNonNull(name); @@ -442,12 +445,27 @@ public final class SimPhonebookContract { * methods operating on this Uri will throw UnsupportedOperationException */ public static final int EF_SDN = 3; - /** @hide */ - public static final String EF_ADN_PATH_SEGMENT = "adn"; - /** @hide */ - public static final String EF_FDN_PATH_SEGMENT = "fdn"; - /** @hide */ - public static final String EF_SDN_PATH_SEGMENT = "sdn"; + /** + * The Uri path segment used to target the ADN elementary file for SimPhonebookProvider + * content operations. + * + * @hide + */ + public static final String PATH_SEGMENT_EF_ADN = "adn"; + /** + * The Uri path segment used to target the FDN elementary file for SimPhonebookProvider + * content operations. + * + * @hide + */ + public static final String PATH_SEGMENT_EF_FDN = "fdn"; + /** + * The Uri path segment used to target the SDN elementary file for SimPhonebookProvider + * content operations. + * + * @hide + */ + public static final String PATH_SEGMENT_EF_SDN = "sdn"; /** The MIME type of CONTENT_URI providing a directory of ADN-like elementary files. */ public static final String CONTENT_TYPE = "vnd.android.cursor.dir/sim-elementary-file"; /** The MIME type of a CONTENT_URI subdirectory of a single ADN-like elementary file. */ diff --git a/core/java/android/telephony/TelephonyRegistryManager.java b/core/java/android/telephony/TelephonyRegistryManager.java index b111ec339ed7..161d10a9090c 100644 --- a/core/java/android/telephony/TelephonyRegistryManager.java +++ b/core/java/android/telephony/TelephonyRegistryManager.java @@ -796,13 +796,14 @@ public class TelephonyRegistryManager { /** * Notify {@link PhysicalChannelConfig} has changed for a specific subscription. * + * @param slotIndex for which physical channel configs changed. * @param subId the subId * @param configs a list of {@link PhysicalChannelConfig}, the configs of physical channel. */ - public void notifyPhysicalChannelConfigForSubscriber( - int subId, List<PhysicalChannelConfig> configs) { + public void notifyPhysicalChannelConfigForSubscriber(int slotIndex, int subId, + List<PhysicalChannelConfig> configs) { try { - sRegistry.notifyPhysicalChannelConfigForSubscriber(subId, configs); + sRegistry.notifyPhysicalChannelConfigForSubscriber(slotIndex, subId, configs); } catch (RemoteException ex) { // system server crash } diff --git a/core/java/android/uwb/DistanceMeasurement.java b/core/java/android/uwb/DistanceMeasurement.java index 2a9bbdf3ec5d..98565536e64a 100644 --- a/core/java/android/uwb/DistanceMeasurement.java +++ b/core/java/android/uwb/DistanceMeasurement.java @@ -60,6 +60,7 @@ public final class DistanceMeasurement implements Parcelable { * * @return error of distance measurement in meters */ + @FloatRange(from = 0.0) public double getErrorMeters() { return mErrorMeters; } @@ -162,7 +163,7 @@ public final class DistanceMeasurement implements Parcelable { * @throws IllegalArgumentException if error is negative or NaN */ @NonNull - public Builder setErrorMeters(double errorMeters) { + public Builder setErrorMeters(@FloatRange(from = 0.0) double errorMeters) { if (Double.isNaN(errorMeters) || errorMeters < 0.0) { throw new IllegalArgumentException( "errorMeters must be >= 0.0 and not NaN: " + errorMeters); @@ -178,7 +179,8 @@ public final class DistanceMeasurement implements Parcelable { * @throws IllegalArgumentException if confidence level is not in the range of [0.0, 1.0] */ @NonNull - public Builder setConfidenceLevel(double confidenceLevel) { + public Builder setConfidenceLevel( + @FloatRange(from = 0.0, to = 1.0) double confidenceLevel) { if (confidenceLevel < 0.0 || confidenceLevel > 1.0) { throw new IllegalArgumentException( "confidenceLevel must be in the range [0.0, 1.0]: " + confidenceLevel); diff --git a/core/java/android/uwb/IUwbAdapter.aidl b/core/java/android/uwb/IUwbAdapter.aidl index 4036892fb9e7..30da248e9e87 100644 --- a/core/java/android/uwb/IUwbAdapter.aidl +++ b/core/java/android/uwb/IUwbAdapter.aidl @@ -160,14 +160,4 @@ interface IUwbAdapter { * closed. */ const int RANGING_SESSION_CLOSE_THRESHOLD_MS = 3000; // Value TBD - - /** - * Ranging scheduling time unit (RSTU) for High Rate Pulse (HRP) PHY - */ - const int HIGH_RATE_PULSE_CHIRPS_PER_RSTU = 416; - - /** - * Ranging scheduling time unit (RSTU) for Low Rate Pulse (LRP) PHY - */ - const int LOW_RATE_PULSE_CHIRPS_PER_RSTU = 1; } diff --git a/core/java/android/uwb/IUwbRangingCallbacks.aidl b/core/java/android/uwb/IUwbRangingCallbacks.aidl index f71f3ff7ad44..f15debbf3e6f 100644 --- a/core/java/android/uwb/IUwbRangingCallbacks.aidl +++ b/core/java/android/uwb/IUwbRangingCallbacks.aidl @@ -92,9 +92,13 @@ interface IUwbRangingCallbacks { * Called when the ranging session has been stopped * * @param sessionHandle the session the callback is being invoked for + * @param reason the reason the session was stopped + * @param parameters protocol specific parameters */ - void onRangingStopped(in SessionHandle sessionHandle); + void onRangingStopped(in SessionHandle sessionHandle, + RangingChangeReason reason, + in PersistableBundle parameters); /** * Called when a ranging session fails to stop diff --git a/core/java/android/uwb/RangingManager.java b/core/java/android/uwb/RangingManager.java index 85f2c1ccc180..e2c64a709922 100644 --- a/core/java/android/uwb/RangingManager.java +++ b/core/java/android/uwb/RangingManager.java @@ -165,7 +165,8 @@ public class RangingManager extends android.uwb.IUwbRangingCallbacks.Stub { } @Override - public void onRangingStopped(SessionHandle sessionHandle) { + public void onRangingStopped(SessionHandle sessionHandle, @RangingChangeReason int reason, + PersistableBundle params) { synchronized (this) { if (!hasSession(sessionHandle)) { Log.w(TAG, "onRangingStopped - received unexpected SessionHandle: " @@ -174,7 +175,7 @@ public class RangingManager extends android.uwb.IUwbRangingCallbacks.Stub { } RangingSession session = mRangingSessionTable.get(sessionHandle); - session.onRangingStopped(); + session.onRangingStopped(convertToReason(reason), params); } } diff --git a/core/java/android/uwb/RangingSession.java b/core/java/android/uwb/RangingSession.java index 52ec5bde0dac..345b69df84d5 100644 --- a/core/java/android/uwb/RangingSession.java +++ b/core/java/android/uwb/RangingSession.java @@ -191,8 +191,11 @@ public final class RangingSession implements AutoCloseable { /** * Invoked when a request to stop the session succeeds + * + * @param reason reason for the session stop + * @param parameters protocol specific parameters related to the stop reason */ - void onStopped(); + void onStopped(@Reason int reason, @NonNull PersistableBundle parameters); /** * Invoked when a request to stop the session fails @@ -434,14 +437,15 @@ public final class RangingSession implements AutoCloseable { /** * @hide */ - public void onRangingStopped() { + public void onRangingStopped(@Callback.Reason int reason, + @NonNull PersistableBundle params) { if (mState == State.CLOSED) { Log.w(TAG, "onRangingStopped invoked for a closed session"); return; } mState = State.IDLE; - executeCallback(() -> mCallback.onStopped()); + executeCallback(() -> mCallback.onStopped(reason, params)); } /** diff --git a/core/java/com/android/internal/app/IAppOpsCallback.aidl b/core/java/com/android/internal/app/IAppOpsCallback.aidl index 15221b1f0fa7..024ff66a67f6 100644 --- a/core/java/com/android/internal/app/IAppOpsCallback.aidl +++ b/core/java/com/android/internal/app/IAppOpsCallback.aidl @@ -17,7 +17,7 @@ package com.android.internal.app; // This interface is also used by native code, so must -// be kept in sync with frameworks/native/libs/binder/include/binder/IAppOpsCallback.h +// be kept in sync with frameworks/native/libs/permission/include/binder/IAppOpsCallback.h oneway interface IAppOpsCallback { void opChanged(int op, int uid, String packageName); } diff --git a/core/java/com/android/internal/app/IAppOpsService.aidl b/core/java/com/android/internal/app/IAppOpsService.aidl index aca5926464d4..eae650faef08 100644 --- a/core/java/com/android/internal/app/IAppOpsService.aidl +++ b/core/java/com/android/internal/app/IAppOpsService.aidl @@ -32,7 +32,7 @@ import com.android.internal.app.MessageSamplingConfig; interface IAppOpsService { // These methods are also called by native code, so must - // be kept in sync with frameworks/native/libs/binder/include/binder/IAppOpsService.h + // be kept in sync with frameworks/native/libs/permission/include/binder/IAppOpsService.h // and not be reordered int checkOperation(int code, int uid, String packageName); int noteOperation(int code, int uid, String packageName, @nullable String attributionTag, diff --git a/core/java/com/android/internal/os/BINDER_OWNERS b/core/java/com/android/internal/os/BINDER_OWNERS new file mode 100644 index 000000000000..9f68a322058b --- /dev/null +++ b/core/java/com/android/internal/os/BINDER_OWNERS @@ -0,0 +1,2 @@ +dplotnikov@google.com +gaillard@google.com diff --git a/core/java/com/android/internal/os/OWNERS b/core/java/com/android/internal/os/OWNERS index 3f01ebb1afe7..ea3b3a7b4056 100644 --- a/core/java/com/android/internal/os/OWNERS +++ b/core/java/com/android/internal/os/OWNERS @@ -1,6 +1,7 @@ per-file *Power* = file:/services/core/java/com/android/server/power/OWNERS per-file *Zygote* = file:/ZYGOTE_OWNERS per-file *Cpu* = file:CPU_OWNERS +per-file *Binder* = file:BINDER_OWNERS # BatteryStats per-file BatterySipper.java = file:/BATTERY_STATS_OWNERS diff --git a/core/java/com/android/internal/os/ZygoteCommandBuffer.java b/core/java/com/android/internal/os/ZygoteCommandBuffer.java index b61ae7acfacd..83a68ca3ab7e 100644 --- a/core/java/com/android/internal/os/ZygoteCommandBuffer.java +++ b/core/java/com/android/internal/os/ZygoteCommandBuffer.java @@ -176,7 +176,7 @@ class ZygoteCommandBuffer implements AutoCloseable { /* * Repeatedly fork children as above. It commonly does not return in the parent, but it may. - * @return true in the chaild, false in the parent if we encounter a command we couldn't handle. + * @return true in the child, false in the parent if we encounter a command we couldn't handle. */ private static native boolean nativeForkRepeatedly(long /* NativeCommandBuffer* */ nbuffer, int zygoteSocketRawFd, diff --git a/core/java/com/android/internal/telephony/ITelephonyRegistry.aidl b/core/java/com/android/internal/telephony/ITelephonyRegistry.aidl index 965971d18241..7a3fd91c1378 100644 --- a/core/java/com/android/internal/telephony/ITelephonyRegistry.aidl +++ b/core/java/com/android/internal/telephony/ITelephonyRegistry.aidl @@ -91,7 +91,7 @@ interface ITelephonyRegistry { void notifyRegistrationFailed(int slotIndex, int subId, in CellIdentity cellIdentity, String chosenPlmn, int domain, int causeCode, int additionalCauseCode); void notifyBarringInfoChanged(int slotIndex, int subId, in BarringInfo barringInfo); - void notifyPhysicalChannelConfigForSubscriber(in int subId, + void notifyPhysicalChannelConfigForSubscriber(in int phoneId, in int subId, in List<PhysicalChannelConfig> configs); void notifyDataEnabled(in int phoneId, int subId, boolean enabled, int reason); void notifyAllowedNetworkTypesChanged(in int phoneId, in int subId, in int reason, in long allowedNetworkType); diff --git a/core/java/com/android/internal/util/ScreenshotHelper.java b/core/java/com/android/internal/util/ScreenshotHelper.java index a23fc4b57b45..7ee846e9d8c1 100644 --- a/core/java/com/android/internal/util/ScreenshotHelper.java +++ b/core/java/com/android/internal/util/ScreenshotHelper.java @@ -1,12 +1,15 @@ package com.android.internal.util; +import static android.content.Intent.ACTION_USER_SWITCHED; import static android.view.WindowManager.ScreenshotSource.SCREENSHOT_OTHER; import android.annotation.NonNull; import android.annotation.Nullable; +import android.content.BroadcastReceiver; import android.content.ComponentName; import android.content.Context; import android.content.Intent; +import android.content.IntentFilter; import android.content.ServiceConnection; import android.graphics.Insets; import android.graphics.Rect; @@ -161,8 +164,21 @@ public class ScreenshotHelper { private ServiceConnection mScreenshotConnection = null; private final Context mContext; + private final BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() { + @Override + public void onReceive(Context context, Intent intent) { + synchronized (mScreenshotLock) { + if (ACTION_USER_SWITCHED.equals(intent.getAction())) { + resetConnection(); + } + } + } + }; + public ScreenshotHelper(Context context) { mContext = context; + IntentFilter filter = new IntentFilter(ACTION_USER_SWITCHED); + mContext.registerReceiver(mBroadcastReceiver, filter); } /** @@ -279,9 +295,8 @@ public class ScreenshotHelper { final Runnable mScreenshotTimeout = () -> { synchronized (mScreenshotLock) { if (mScreenshotConnection != null) { - mContext.unbindService(mScreenshotConnection); - mScreenshotConnection = null; - mScreenshotService = null; + Log.e(TAG, "Timed out before getting screenshot capture response"); + resetConnection(); notifyScreenshotError(); } } @@ -304,11 +319,7 @@ public class ScreenshotHelper { break; case SCREENSHOT_MSG_PROCESS_COMPLETE: synchronized (mScreenshotLock) { - if (mScreenshotConnection != null) { - mContext.unbindService(mScreenshotConnection); - mScreenshotConnection = null; - mScreenshotService = null; - } + resetConnection(); } break; } @@ -348,9 +359,7 @@ public class ScreenshotHelper { public void onServiceDisconnected(ComponentName name) { synchronized (mScreenshotLock) { if (mScreenshotConnection != null) { - mContext.unbindService(mScreenshotConnection); - mScreenshotConnection = null; - mScreenshotService = null; + resetConnection(); // only log an error if we're still within the timeout period if (handler.hasCallbacks(mScreenshotTimeout)) { handler.removeCallbacks(mScreenshotTimeout); @@ -383,6 +392,17 @@ public class ScreenshotHelper { } /** + * Unbinds the current screenshot connection (if any). + */ + private void resetConnection() { + if (mScreenshotConnection != null) { + mContext.unbindService(mScreenshotConnection); + mScreenshotConnection = null; + mScreenshotService = null; + } + } + + /** * Notifies the screenshot service to show an error. */ private void notifyScreenshotError() { diff --git a/core/java/com/android/internal/widget/LockSettingsInternal.java b/core/java/com/android/internal/widget/LockSettingsInternal.java index f5df3abad658..940979d7cd1f 100644 --- a/core/java/com/android/internal/widget/LockSettingsInternal.java +++ b/core/java/com/android/internal/widget/LockSettingsInternal.java @@ -16,15 +16,41 @@ package com.android.internal.widget; +import android.annotation.IntDef; import android.annotation.Nullable; import android.app.admin.PasswordMetrics; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; /** * LockSettingsService local system service interface. * * @hide Only for use within the system server. */ public abstract class LockSettingsInternal { + /** ErrorCode for armRebootEscrow failures. **/ + @IntDef(prefix = {"ARM_REBOOT_ERROR_"}, value = { + ARM_REBOOT_ERROR_NONE, + ARM_REBOOT_ERROR_UNSPECIFIED, + ARM_REBOOT_ERROR_ESCROW_NOT_READY, + ARM_REBOOT_ERROR_NO_PROVIDER, + ARM_REBOOT_ERROR_PROVIDER_MISMATCH, + ARM_REBOOT_ERROR_NO_ESCROW_KEY, + ARM_REBOOT_ERROR_KEYSTORE_FAILURE, + ARM_REBOOT_ERROR_STORE_ESCROW_KEY, + }) + @Retention(RetentionPolicy.SOURCE) + public @interface ArmRebootEscrowErrorCode {} + + public static final int ARM_REBOOT_ERROR_NONE = 0; + public static final int ARM_REBOOT_ERROR_UNSPECIFIED = 1; + public static final int ARM_REBOOT_ERROR_ESCROW_NOT_READY = 2; + public static final int ARM_REBOOT_ERROR_NO_PROVIDER = 3; + public static final int ARM_REBOOT_ERROR_PROVIDER_MISMATCH = 4; + public static final int ARM_REBOOT_ERROR_NO_ESCROW_KEY = 5; + public static final int ARM_REBOOT_ERROR_KEYSTORE_FAILURE = 6; + public static final int ARM_REBOOT_ERROR_STORE_ESCROW_KEY = 7; + // TODO(b/183140900) split store escrow key errors into detailed ones. /** * Create an escrow token for the current user, which can later be used to unlock FBE @@ -104,9 +130,9 @@ public abstract class LockSettingsInternal { * Should be called immediately before rebooting for an update. This depends on {@link * #prepareRebootEscrow()} having been called and the escrow completing. * - * @return true if the arming worked + * @return ARM_ERROR_NONE if the arming worked */ - public abstract boolean armRebootEscrow(); + public abstract @ArmRebootEscrowErrorCode int armRebootEscrow(); /** diff --git a/core/jni/AndroidRuntime.cpp b/core/jni/AndroidRuntime.cpp index ed84434adff5..855448b21069 100644 --- a/core/jni/AndroidRuntime.cpp +++ b/core/jni/AndroidRuntime.cpp @@ -50,6 +50,7 @@ #include "jni.h" using namespace android; +using android::base::GetBoolProperty; using android::base::GetProperty; extern int register_android_os_Binder(JNIEnv* env); @@ -727,17 +728,7 @@ int AndroidRuntime::startVm(JavaVM** pJavaVM, JNIEnv** pEnv, bool zygote, bool p ALOGI("Leaving lock profiling enabled"); } - bool checkJni = false; - property_get("dalvik.vm.checkjni", propBuf, ""); - if (strcmp(propBuf, "true") == 0) { - checkJni = true; - } else if (strcmp(propBuf, "false") != 0) { - /* property is neither true nor false; fall back on kernel parameter */ - property_get("ro.kernel.android.checkjni", propBuf, ""); - if (propBuf[0] == '1') { - checkJni = true; - } - } + const bool checkJni = GetBoolProperty("dalvik.vm.checkjni", false); ALOGV("CheckJNI is %s\n", checkJni ? "ON" : "OFF"); if (checkJni) { /* extended JNI checking */ diff --git a/core/jni/com_android_internal_os_Zygote.cpp b/core/jni/com_android_internal_os_Zygote.cpp index 836074f1d5f7..6ac43bd30973 100644 --- a/core/jni/com_android_internal_os_Zygote.cpp +++ b/core/jni/com_android_internal_os_Zygote.cpp @@ -1015,21 +1015,6 @@ static void ClearUsapTable() { gUsapPoolCount = 0; } -NO_PAC_FUNC -static void PAuthKeyChange(JNIEnv* env) { -#ifdef __aarch64__ - unsigned long int hwcaps = getauxval(AT_HWCAP); - if (hwcaps & HWCAP_PACA) { - const unsigned long key_mask = PR_PAC_APIAKEY | PR_PAC_APIBKEY | - PR_PAC_APDAKEY | PR_PAC_APDBKEY | PR_PAC_APGAKEY; - if (prctl(PR_PAC_RESET_KEYS, key_mask, 0, 0, 0) != 0) { - ALOGE("Failed to change the PAC keys: %s", strerror(errno)); - RuntimeAbort(env, __LINE__, "PAC key change failed."); - } - } -#endif -} - // Create an app data directory over tmpfs overlayed CE / DE storage, and bind mount it // from the actual app data directory in data mirror. static bool createAndMountAppData(std::string_view package_name, @@ -1980,7 +1965,6 @@ void zygote::ZygoteFailure(JNIEnv* env, } // Utility routine to fork a process from the zygote. -NO_PAC_FUNC pid_t zygote::ForkCommon(JNIEnv* env, bool is_system_server, const std::vector<int>& fds_to_close, const std::vector<int>& fds_to_ignore, @@ -2035,7 +2019,6 @@ pid_t zygote::ForkCommon(JNIEnv* env, bool is_system_server, } // The child process. - PAuthKeyChange(env); PreApplicationInit(); // Clean up any descriptors which must be closed immediately @@ -2067,7 +2050,6 @@ static void com_android_internal_os_Zygote_nativePreApplicationInit(JNIEnv*, jcl PreApplicationInit(); } -NO_PAC_FUNC static jint com_android_internal_os_Zygote_nativeForkAndSpecialize( JNIEnv* env, jclass, jint uid, jint gid, jintArray gids, jint runtime_flags, jobjectArray rlimits, jint mount_external, jstring se_info, jstring nice_name, @@ -2117,7 +2099,6 @@ static jint com_android_internal_os_Zygote_nativeForkAndSpecialize( return pid; } -NO_PAC_FUNC static jint com_android_internal_os_Zygote_nativeForkSystemServer( JNIEnv* env, jclass, uid_t uid, gid_t gid, jintArray gids, jint runtime_flags, jobjectArray rlimits, jlong permitted_capabilities, @@ -2189,7 +2170,6 @@ static jint com_android_internal_os_Zygote_nativeForkSystemServer( * @param is_priority_fork Controls the nice level assigned to the newly created process * @return child pid in the parent, 0 in the child */ -NO_PAC_FUNC static jint com_android_internal_os_Zygote_nativeForkApp(JNIEnv* env, jclass, jint read_pipe_fd, @@ -2204,7 +2184,6 @@ static jint com_android_internal_os_Zygote_nativeForkApp(JNIEnv* env, args_known == JNI_TRUE, is_priority_fork == JNI_TRUE, true); } -NO_PAC_FUNC int zygote::forkApp(JNIEnv* env, int read_pipe_fd, int write_pipe_fd, diff --git a/core/jni/com_android_internal_os_Zygote.h b/core/jni/com_android_internal_os_Zygote.h index d2da91476bc7..b87396cbd5f5 100644 --- a/core/jni/com_android_internal_os_Zygote.h +++ b/core/jni/com_android_internal_os_Zygote.h @@ -20,18 +20,6 @@ #define LOG_TAG "Zygote" #define ATRACE_TAG ATRACE_TAG_DALVIK -/* Functions in the callchain during the fork shall not be protected with - Armv8.3-A Pointer Authentication, otherwise child will not be able to return. */ -#ifdef __ARM_FEATURE_PAC_DEFAULT -#ifdef __ARM_FEATURE_BTI_DEFAULT -#define NO_PAC_FUNC __attribute__((target("branch-protection=bti"))) -#else -#define NO_PAC_FUNC __attribute__((target("branch-protection=none"))) -#endif /* __ARM_FEATURE_BTI_DEFAULT */ -#else /* !__ARM_FEATURE_PAC_DEFAULT */ -#define NO_PAC_FUNC -#endif /* __ARM_FEATURE_PAC_DEFAULT */ - #include <jni.h> #include <vector> #include <android-base/stringprintf.h> @@ -42,7 +30,6 @@ namespace android { namespace zygote { -NO_PAC_FUNC pid_t ForkCommon(JNIEnv* env,bool is_system_server, const std::vector<int>& fds_to_close, const std::vector<int>& fds_to_ignore, @@ -57,7 +44,6 @@ pid_t ForkCommon(JNIEnv* env,bool is_system_server, * communication is required. Is_priority_fork should be true if this is on the app startup * critical path. Purge specifies that unused pages should be purged before the fork. */ -NO_PAC_FUNC int forkApp(JNIEnv* env, int read_pipe_fd, int write_pipe_fd, diff --git a/core/jni/com_android_internal_os_ZygoteCommandBuffer.cpp b/core/jni/com_android_internal_os_ZygoteCommandBuffer.cpp index 011e8f8f1b8c..24fef4881e4c 100644 --- a/core/jni/com_android_internal_os_ZygoteCommandBuffer.cpp +++ b/core/jni/com_android_internal_os_ZygoteCommandBuffer.cpp @@ -365,7 +365,6 @@ void com_android_internal_os_ZygoteCommandBuffer_nativeReadFullyAndReset(JNIEnv* // We only process fork commands if the peer uid matches expected_uid. // For every fork command after the first, we check that the requested uid is at // least minUid. -NO_PAC_FUNC jboolean com_android_internal_os_ZygoteCommandBuffer_nativeForkRepeatedly( JNIEnv* env, jclass, diff --git a/core/proto/android/internal/OWNERS b/core/proto/android/internal/OWNERS new file mode 100644 index 000000000000..24e24c20a9cd --- /dev/null +++ b/core/proto/android/internal/OWNERS @@ -0,0 +1,2 @@ +# Binder +per-file binder_latency.proto = file:/core/java/com/android/internal/os/BINDER_OWNERS
\ No newline at end of file diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml index 1f7695eb7fc0..cc4e2bb59787 100644 --- a/core/res/AndroidManifest.xml +++ b/core/res/AndroidManifest.xml @@ -313,7 +313,6 @@ <protected-broadcast android:name="android.se.omapi.action.SECURE_ELEMENT_STATE_CHANGED" /> <protected-broadcast android:name="android.nfc.action.ADAPTER_STATE_CHANGED" /> - <protected-broadcast android:name="android.nfc.action.ALWAYS_ON_STATE_CHANGED" /> <protected-broadcast android:name="android.nfc.action.PREFERRED_PAYMENT_CHANGED" /> <protected-broadcast android:name="android.nfc.action.TRANSACTION_DETECTED" /> <protected-broadcast android:name="android.nfc.action.REQUIRE_UNLOCK_FOR_NFC" /> @@ -333,7 +332,7 @@ <protected-broadcast android:name="android.nfc.handover.intent.action.HANDOVER_SEND_MULTIPLE" /> <protected-broadcast android:name="com.android.nfc.handover.action.CANCEL_HANDOVER_TRANSFER" /> - <protected-broadcast android:name="android.intent.action.CLEAR_DNS_CACHE" /> + <protected-broadcast android:name="android.net.action.CLEAR_DNS_CACHE" /> <protected-broadcast android:name="android.intent.action.PROXY_CHANGE" /> <protected-broadcast android:name="android.os.UpdateLock.UPDATE_LOCK_CHANGED" /> diff --git a/core/res/res/values/attrs_manifest.xml b/core/res/res/values/attrs_manifest.xml index 47dbd64c0402..41cd3715ac5d 100644 --- a/core/res/res/values/attrs_manifest.xml +++ b/core/res/res/values/attrs_manifest.xml @@ -1560,6 +1560,20 @@ <enum name="always" value="1" /> </attr> + <!-- Enable hardware memory tagging (ARM MTE) in this process. + When enabled, heap memory bugs like use-after-free and buffer overlow + are detected and result in an immediate ("sync" mode) or delayed ("async" + mode) crash instead of a silent memory corruption. Sync mode, while slower, + provides enhanced bug reports including stack traces at the time of allocation + and deallocation of memory, similar to AddressSanitizer. + + See the <a href="https://community.arm.com/developer/ip-products/processors/b/processors-ip-blog/posts/enhancing-memory-safety">ARM announcement</a> + for more details. + + <p>This attribute can be applied to a + {@link android.R.styleable#AndroidManifestProcess process} tag, or to an + {@link android.R.styleable#AndroidManifestApplication application} tag (to supply + a default setting for all application components). --> <attr name="memtagMode"> <enum name="default" value="-1" /> <enum name="off" value="0" /> @@ -1836,7 +1850,9 @@ <attr name="memtagMode" /> - <attr name="nativeHeapZeroInit" format="boolean" /> + <!-- If {@code true} enables automatic zero initialization of all native heap + allocations. --> + <attr name="nativeHeapZeroInitialized" format="boolean" /> <!-- @hide no longer used, kept to preserve padding --> <attr name="allowAutoRevokePermissionsExemption" format="boolean" /> @@ -2362,7 +2378,7 @@ <attr name="process" /> <attr name="gwpAsanMode" /> <attr name="memtagMode" /> - <attr name="nativeHeapZeroInit" /> + <attr name="nativeHeapZeroInitialized" /> </declare-styleable> <!-- The <code>deny-permission</code> tag specifies that a permission is to be denied diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml index bfe7802726a3..58eb93f6f7d4 100644 --- a/core/res/res/values/config.xml +++ b/core/res/res/values/config.xml @@ -1834,7 +1834,7 @@ <string name="config_systemGallery" translatable="false">com.android.gallery3d</string> <!-- The name of the package that will be allowed to change its components' label/icon. --> - <string name="config_overrideComponentUiPackage" translatable="false"></string> + <string name="config_overrideComponentUiPackage" translatable="false">com.android.stk</string> <!-- Enable/disable default bluetooth profiles: HSP_AG, ObexObjectPush, Audio, NAP --> diff --git a/core/res/res/values/public.xml b/core/res/res/values/public.xml index 0f846d3dbad9..6a4702be35c9 100644 --- a/core/res/res/values/public.xml +++ b/core/res/res/values/public.xml @@ -3047,7 +3047,7 @@ <!-- attribute definitions go here --> <public name="requireDeviceScreenOn" /> <public name="memtagMode" /> - <public name="nativeHeapZeroInit" /> + <public name="nativeHeapZeroInitialized" /> </public-group> <public-group type="drawable" first-id="0x010800b5"> diff --git a/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/ConnectivityManagerTestBase.java b/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/ConnectivityManagerTestBase.java index b0c1f25ad030..100eb999f592 100644 --- a/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/ConnectivityManagerTestBase.java +++ b/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/ConnectivityManagerTestBase.java @@ -76,6 +76,7 @@ public class ConnectivityManagerTestBase extends InstrumentationTestCase { private Context mContext; protected List<ScanResult> mLastScanResult; protected Object mWifiScanResultLock = new Object(); + public TetheringManager mTetheringManager; /* Control Wifi States */ public WifiManager mWifiManager; @@ -129,6 +130,7 @@ public class ConnectivityManagerTestBase extends InstrumentationTestCase { mCm = (ConnectivityManager)mContext.getSystemService(Context.CONNECTIVITY_SERVICE); // Get an instance of WifiManager mWifiManager =(WifiManager)mContext.getSystemService(Context.WIFI_SERVICE); + mTetheringManager = mContext.getSystemService(TetheringManager.class); // register a connectivity receiver for CONNECTIVITY_ACTION; mConnectivityReceiver = new ConnectivityReceiver(); @@ -216,13 +218,13 @@ public class ConnectivityManagerTestBase extends InstrumentationTestCase { */ protected boolean waitForTetherStateChange(long timeout) { long startTime = SystemClock.uptimeMillis(); - String[] wifiRegexes = mCm.getTetherableWifiRegexs(); + String[] wifiRegexes = mTetheringManager.getTetherableWifiRegexs(); while (true) { if ((SystemClock.uptimeMillis() - startTime) > timeout) { return false; } - String[] active = mCm.getTetheredIfaces(); - String[] error = mCm.getTetheringErroredIfaces(); + String[] active = mTetheringManager.getTetheredIfaces(); + String[] error = mTetheringManager.getTetheringErroredIfaces(); for (String iface: active) { for (String regex: wifiRegexes) { if (iface.matches(regex)) { diff --git a/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/WifiConfigurationHelper.java b/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/WifiConfigurationHelper.java index a296ca27e268..09ea34e49be2 100644 --- a/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/WifiConfigurationHelper.java +++ b/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/WifiConfigurationHelper.java @@ -244,17 +244,19 @@ public class WifiConfigurationHelper { IpConfiguration ipConfiguration = config.getIpConfiguration(); if (jsonConfig.has("ip")) { - StaticIpConfiguration staticIpConfig = new StaticIpConfiguration(); - InetAddress ipAddress = getInetAddress(jsonConfig.getString("ip")); int prefixLength = getPrefixLength(jsonConfig.getInt("prefix_length")); - staticIpConfig.ipAddress = new LinkAddress(ipAddress, prefixLength); - staticIpConfig.gateway = getInetAddress(jsonConfig.getString("gateway")); - staticIpConfig.dnsServers.add(getInetAddress(jsonConfig.getString("dns1"))); - staticIpConfig.dnsServers.add(getInetAddress(jsonConfig.getString("dns2"))); + + final StaticIpConfiguration.Builder builder = new StaticIpConfiguration.Builder(); + builder.setIpAddress(new LinkAddress(ipAddress, prefixLength)); + builder.setGateway(getInetAddress(jsonConfig.getString("gateway"))); + final ArrayList<InetAddress> dnsServers = new ArrayList<>(); + dnsServers.add(getInetAddress(jsonConfig.getString("dns1"))); + dnsServers.add(getInetAddress(jsonConfig.getString("dns2"))); + builder.setDnsServers(dnsServers); + ipConfiguration.setStaticIpConfiguration(builder.build()); ipConfiguration.setIpAssignment(IpAssignment.STATIC); - ipConfiguration.setStaticIpConfiguration(staticIpConfig); } else { ipConfiguration.setIpAssignment(IpAssignment.DHCP); } diff --git a/core/tests/coretests/src/android/app/admin/OWNERS b/core/tests/coretests/src/android/app/admin/OWNERS new file mode 100644 index 000000000000..e95633abe79a --- /dev/null +++ b/core/tests/coretests/src/android/app/admin/OWNERS @@ -0,0 +1 @@ +include /core/java/android/app/admin/OWNERS diff --git a/core/tests/coretests/src/android/view/OWNERS b/core/tests/coretests/src/android/view/OWNERS index fa1aa5eab26c..74cdd2146937 100644 --- a/core/tests/coretests/src/android/view/OWNERS +++ b/core/tests/coretests/src/android/view/OWNERS @@ -1,3 +1,6 @@ +# Accessibility +per-file WindowInfoTest.java = file:/services/accessibility/OWNERS + # Input per-file *MotionEventTest.* = file:/services/core/java/com/android/server/input/OWNERS per-file *KeyEventTest.* = file:/services/core/java/com/android/server/input/OWNERS @@ -9,6 +12,7 @@ per-file *Focus* = file:/services/core/java/com/android/server/wm/OWNERS per-file *Insets* = file:/services/core/java/com/android/server/wm/OWNERS per-file *View* = file:/services/core/java/com/android/server/wm/OWNERS per-file *Visibility* = file:/services/core/java/com/android/server/wm/OWNERS +per-file *Window* = file:/services/core/java/com/android/server/wm/OWNERS # Scroll Capture per-file *ScrollCapture*.java = file:/packages/SystemUI/src/com/android/systemui/screenshot/OWNERS diff --git a/core/tests/nfctests/Android.bp b/core/tests/nfctests/Android.bp new file mode 100644 index 000000000000..335cea140df6 --- /dev/null +++ b/core/tests/nfctests/Android.bp @@ -0,0 +1,38 @@ +// Copyright 2021 The Android Open Source Project +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package { + // See: http://go/android-license-faq + // A large-scale-change added 'default_applicable_licenses' to import + // all of the 'license_kinds' from "frameworks_base_license" + // to get the below license kinds: + // SPDX-license-identifier-Apache-2.0 + default_applicable_licenses: ["frameworks_base_license"], +} + +android_test { + name: "NfcManagerTests", + static_libs: [ + "androidx.test.ext.junit", + "androidx.test.rules", + "mockito-target-minus-junit4", + ], + libs: [ + "android.test.runner", + ], + srcs: ["src/**/*.java"], + platform_apis: true, + certificate: "platform", + test_suites: ["device-tests"], +} diff --git a/core/tests/nfctests/AndroidManifest.xml b/core/tests/nfctests/AndroidManifest.xml new file mode 100644 index 000000000000..99e2c34c656b --- /dev/null +++ b/core/tests/nfctests/AndroidManifest.xml @@ -0,0 +1,31 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- Copyright 2021 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> + +<manifest xmlns:android="http://schemas.android.com/apk/res/android" + package="android.nfc"> + + <application> + <uses-library android:name="android.test.runner" /> + </application> + + <!-- This is a self-instrumenting test package. --> + <instrumentation android:name="androidx.test.runner.AndroidJUnitRunner" + android:targetPackage="android.nfc" + android:label="NFC Manager Tests"> + </instrumentation> + +</manifest> + diff --git a/core/tests/nfctests/AndroidTest.xml b/core/tests/nfctests/AndroidTest.xml new file mode 100644 index 000000000000..490d6f5df197 --- /dev/null +++ b/core/tests/nfctests/AndroidTest.xml @@ -0,0 +1,32 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- Copyright 2021 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> +<configuration description="Config for NFC Manager test cases"> + <option name="test-suite-tag" value="apct"/> + <option name="test-suite-tag" value="apct-instrumentation"/> + <target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller"> + <option name="cleanup-apks" value="true" /> + <option name="test-file-name" value="NfcManagerTests.apk" /> + </target_preparer> + + <option name="test-suite-tag" value="apct"/> + <option name="test-tag" value="NfcManagerTests"/> + + <test class="com.android.tradefed.testtype.AndroidJUnitTest" > + <option name="package" value="android.nfc" /> + <option name="hidden-api-checks" value="false"/> + <option name="runner" value="androidx.test.runner.AndroidJUnitRunner"/> + </test> +</configuration> diff --git a/core/tests/nfctests/OWNERS b/core/tests/nfctests/OWNERS new file mode 100644 index 000000000000..34b095c7fda0 --- /dev/null +++ b/core/tests/nfctests/OWNERS @@ -0,0 +1 @@ +include /core/java/android/nfc/OWNERS diff --git a/core/tests/nfctests/src/android/nfc/NfcControllerAlwaysOnListenerTest.java b/core/tests/nfctests/src/android/nfc/NfcControllerAlwaysOnListenerTest.java new file mode 100644 index 000000000000..43f9b6feea45 --- /dev/null +++ b/core/tests/nfctests/src/android/nfc/NfcControllerAlwaysOnListenerTest.java @@ -0,0 +1,166 @@ +/* + * Copyright 2021 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.nfc; + +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyBoolean; +import static org.mockito.Mockito.doNothing; +import static org.mockito.Mockito.doThrow; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; + +import android.nfc.NfcAdapter.ControllerAlwaysOnListener; +import android.os.RemoteException; + +import androidx.test.ext.junit.runners.AndroidJUnit4; +import androidx.test.filters.SmallTest; + +import org.junit.Test; +import org.junit.runner.RunWith; + +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.Executor; + +/** + * Test of {@link NfcControllerAlwaysOnListener}. + */ +@SmallTest +@RunWith(AndroidJUnit4.class) +public class NfcControllerAlwaysOnListenerTest { + + private INfcAdapter mNfcAdapter = mock(INfcAdapter.class); + + private Throwable mThrowRemoteException = new RemoteException("RemoteException"); + + private static Executor getExecutor() { + return new Executor() { + @Override + public void execute(Runnable command) { + command.run(); + } + }; + } + + private static void verifyListenerInvoked(ControllerAlwaysOnListener listener) { + verify(listener, times(1)).onControllerAlwaysOnChanged(anyBoolean()); + } + + @Test + public void testRegister_RegisterUnregister() throws RemoteException { + NfcControllerAlwaysOnListener mListener = + new NfcControllerAlwaysOnListener(mNfcAdapter); + ControllerAlwaysOnListener mockListener1 = mock(ControllerAlwaysOnListener.class); + ControllerAlwaysOnListener mockListener2 = mock(ControllerAlwaysOnListener.class); + + // Verify that the state listener registered with the NFC Adapter + mListener.register(getExecutor(), mockListener1); + verify(mNfcAdapter, times(1)).registerControllerAlwaysOnListener(any()); + + // Register a second client and no new call to NFC Adapter + mListener.register(getExecutor(), mockListener2); + verify(mNfcAdapter, times(1)).registerControllerAlwaysOnListener(any()); + + // Unregister first listener + mListener.unregister(mockListener1); + verify(mNfcAdapter, times(1)).registerControllerAlwaysOnListener(any()); + verify(mNfcAdapter, times(0)).unregisterControllerAlwaysOnListener(any()); + + // Unregister second listener and the state listener registered with the NFC Adapter + mListener.unregister(mockListener2); + verify(mNfcAdapter, times(1)).registerControllerAlwaysOnListener(any()); + verify(mNfcAdapter, times(1)).unregisterControllerAlwaysOnListener(any()); + } + + @Test + public void testRegister_FirstRegisterFails() throws RemoteException { + NfcControllerAlwaysOnListener mListener = + new NfcControllerAlwaysOnListener(mNfcAdapter); + ControllerAlwaysOnListener mockListener1 = mock(ControllerAlwaysOnListener.class); + ControllerAlwaysOnListener mockListener2 = mock(ControllerAlwaysOnListener.class); + + // Throw a remote exception whenever first registering + doThrow(mThrowRemoteException).when(mNfcAdapter).registerControllerAlwaysOnListener( + any()); + + mListener.register(getExecutor(), mockListener1); + verify(mNfcAdapter, times(1)).registerControllerAlwaysOnListener(any()); + + // No longer throw an exception, instead succeed + doNothing().when(mNfcAdapter).registerControllerAlwaysOnListener(any()); + + // Register a different listener + mListener.register(getExecutor(), mockListener2); + verify(mNfcAdapter, times(2)).registerControllerAlwaysOnListener(any()); + + // Ensure first and second listener were invoked + mListener.onControllerAlwaysOnChanged(true); + verifyListenerInvoked(mockListener1); + verifyListenerInvoked(mockListener2); + } + + @Test + public void testRegister_RegisterSameListenerTwice() throws RemoteException { + NfcControllerAlwaysOnListener mListener = + new NfcControllerAlwaysOnListener(mNfcAdapter); + ControllerAlwaysOnListener mockListener = mock(ControllerAlwaysOnListener.class); + + // Register the same listener Twice + mListener.register(getExecutor(), mockListener); + mListener.register(getExecutor(), mockListener); + verify(mNfcAdapter, times(1)).registerControllerAlwaysOnListener(any()); + + // Invoke a state change and ensure the listener is only called once + mListener.onControllerAlwaysOnChanged(true); + verifyListenerInvoked(mockListener); + } + + @Test + public void testNotify_AllListenersNotified() throws RemoteException { + + NfcControllerAlwaysOnListener listener = new NfcControllerAlwaysOnListener(mNfcAdapter); + List<ControllerAlwaysOnListener> mockListeners = new ArrayList<>(); + for (int i = 0; i < 10; i++) { + ControllerAlwaysOnListener mockListener = mock(ControllerAlwaysOnListener.class); + listener.register(getExecutor(), mockListener); + mockListeners.add(mockListener); + } + + // Invoke a state change and ensure all listeners are invoked + listener.onControllerAlwaysOnChanged(true); + for (ControllerAlwaysOnListener mListener : mockListeners) { + verifyListenerInvoked(mListener); + } + } + + @Test + public void testStateChange_CorrectValue() { + runStateChangeValue(true, true); + runStateChangeValue(false, false); + + } + + private void runStateChangeValue(boolean isEnabledIn, boolean isEnabledOut) { + NfcControllerAlwaysOnListener listener = new NfcControllerAlwaysOnListener(mNfcAdapter); + ControllerAlwaysOnListener mockListener = mock(ControllerAlwaysOnListener.class); + listener.register(getExecutor(), mockListener); + listener.onControllerAlwaysOnChanged(isEnabledIn); + verify(mockListener, times(1)).onControllerAlwaysOnChanged(isEnabledOut); + verify(mockListener, times(0)).onControllerAlwaysOnChanged(!isEnabledOut); + } +} diff --git a/core/tests/uwbtests/src/android/uwb/RangingManagerTest.java b/core/tests/uwbtests/src/android/uwb/RangingManagerTest.java index e41805dd3a59..21ef083bcdbc 100644 --- a/core/tests/uwbtests/src/android/uwb/RangingManagerTest.java +++ b/core/tests/uwbtests/src/android/uwb/RangingManagerTest.java @@ -123,8 +123,8 @@ public class RangingManagerTest { rangingManager.onRangingReconfigureFailed(handle, REASON, PARAMS); verify(callback, times(1)).onReconfigureFailed(eq(REASON), eq(PARAMS)); - rangingManager.onRangingStopped(handle); - verify(callback, times(1)).onStopped(); + rangingManager.onRangingStopped(handle, REASON, PARAMS); + verify(callback, times(1)).onStopped(eq(REASON), eq(PARAMS)); rangingManager.onRangingStopFailed(handle, REASON, PARAMS); verify(callback, times(1)).onStopFailed(eq(REASON), eq(PARAMS)); diff --git a/data/etc/privapp-permissions-platform.xml b/data/etc/privapp-permissions-platform.xml index 43fdedc41e9f..4d418c36b50e 100644 --- a/data/etc/privapp-permissions-platform.xml +++ b/data/etc/privapp-permissions-platform.xml @@ -383,6 +383,7 @@ applications that come with the platform <permission name="android.permission.SUSPEND_APPS" /> <permission name="android.permission.UPDATE_APP_OPS_STATS"/> <permission name="android.permission.USE_RESERVED_DISK"/> + <permission name="android.permission.UWB_PRIVILEGED"/> <permission name="android.permission.WIFI_UPDATE_USABILITY_STATS_SCORE"/> <permission name="android.permission.WRITE_MEDIA_STORAGE"/> <permission name="android.permission.MANAGE_EXTERNAL_STORAGE"/> @@ -410,6 +411,7 @@ applications that come with the platform <permission name="android.permission.LOG_COMPAT_CHANGE" /> <permission name="android.permission.READ_COMPAT_CHANGE_CONFIG" /> <permission name="android.permission.OVERRIDE_COMPAT_CHANGE_CONFIG" /> + <permission name="android.permission.OVERRIDE_COMPAT_CHANGE_CONFIG_ON_RELEASE_BUILD" /> <!-- Permissions required to test ambient display. --> <permission name="android.permission.READ_DREAM_STATE" /> <permission name="android.permission.WRITE_DREAM_STATE" /> @@ -458,6 +460,15 @@ applications that come with the platform <permission name="android.permission.REGISTER_MEDIA_RESOURCE_OBSERVER" /> <!-- Permission required for CTS test - CtsAlarmManagerTestCases --> <permission name="android.permission.SCHEDULE_PRIORITIZED_ALARM" /> + <permission name="android.permission.WRITE_EMBEDDED_SUBSCRIPTIONS" /> + <permission name="android.permission.GET_PROCESS_STATE_AND_OOM_SCORE" /> + <permission name="android.permission.READ_LOGS" /> + <permission name="android.permission.BRIGHTNESS_SLIDER_USAGE" /> + <permission name="android.permission.ACCESS_AMBIENT_LIGHT_STATS" /> + <permission name="android.permission.CONFIGURE_DISPLAY_BRIGHTNESS" /> + <permission name="android.permission.SET_VOLUME_KEY_LONG_PRESS_LISTENER" /> + <permission name="android.permission.SET_MEDIA_KEY_LISTENER" /> + <permission name="android.permission.SET_VOLUME_KEY_LONG_PRESS_LISTENER" /> </privapp-permissions> <privapp-permissions package="com.android.statementservice"> diff --git a/keystore/java/android/security/keystore/AndroidKeyStoreProvider.java b/keystore/java/android/security/keystore/AndroidKeyStoreProvider.java index ecb082e71321..62fe54f1f089 100644 --- a/keystore/java/android/security/keystore/AndroidKeyStoreProvider.java +++ b/keystore/java/android/security/keystore/AndroidKeyStoreProvider.java @@ -62,10 +62,8 @@ public class AndroidKeyStoreProvider extends Provider { */ @UnsupportedAppUsage public static long getKeyStoreOperationHandle(Object cryptoPrimitive) { - if (cryptoPrimitive == null) { - throw new NullPointerException(); - } - return 0; + return android.security.keystore2.AndroidKeyStoreProvider + .getKeyStoreOperationHandle(cryptoPrimitive); } /** diff --git a/keystore/java/android/security/keystore/KeyGenParameterSpec.java b/keystore/java/android/security/keystore/KeyGenParameterSpec.java index 1f9022b4ad3d..a6aa4f21e53b 100644 --- a/keystore/java/android/security/keystore/KeyGenParameterSpec.java +++ b/keystore/java/android/security/keystore/KeyGenParameterSpec.java @@ -353,7 +353,7 @@ public final class KeyGenParameterSpec implements AlgorithmParameterSpec, UserAu boolean userPresenceRequired, byte[] attestationChallenge, boolean devicePropertiesAttestationIncluded, - int[] attestationIds, + @NonNull int[] attestationIds, boolean uniqueIdIncluded, boolean userAuthenticationValidWhileOnBody, boolean invalidatedByBiometricEnrollment, @@ -779,9 +779,8 @@ public final class KeyGenParameterSpec implements AlgorithmParameterSpec, UserAu * @return integer array representing the requested device IDs to attest. */ @SystemApi - @Nullable - public int[] getAttestationIds() { - return Utils.cloneIfNotNull(mAttestationIds); + public @NonNull int[] getAttestationIds() { + return mAttestationIds.clone(); } /** @@ -911,7 +910,7 @@ public final class KeyGenParameterSpec implements AlgorithmParameterSpec, UserAu private boolean mUserPresenceRequired = false; private byte[] mAttestationChallenge = null; private boolean mDevicePropertiesAttestationIncluded = false; - private int[] mAttestationIds = null; + private int[] mAttestationIds = new int[0]; private boolean mUniqueIdIncluded = false; private boolean mUserAuthenticationValidWhileOnBody; private boolean mInvalidatedByBiometricEnrollment = true; diff --git a/keystore/java/android/security/keystore2/AndroidKeyStoreKeyPairGeneratorSpi.java b/keystore/java/android/security/keystore2/AndroidKeyStoreKeyPairGeneratorSpi.java index c26d9f583fd4..dc7f3dda35c0 100644 --- a/keystore/java/android/security/keystore2/AndroidKeyStoreKeyPairGeneratorSpi.java +++ b/keystore/java/android/security/keystore2/AndroidKeyStoreKeyPairGeneratorSpi.java @@ -655,7 +655,7 @@ public abstract class AndroidKeyStoreKeyPairGeneratorSpi extends KeyPairGenerato } int[] idTypes = mSpec.getAttestationIds(); - if (idTypes == null) { + if (idTypes.length == 0) { return; } final Set<Integer> idTypesSet = new ArraySet<>(idTypes.length); diff --git a/media/java/android/media/MediaCodec.java b/media/java/android/media/MediaCodec.java index 5633236a122e..54d065969228 100644 --- a/media/java/android/media/MediaCodec.java +++ b/media/java/android/media/MediaCodec.java @@ -4607,6 +4607,25 @@ final public class MediaCodec { return mType; } + @Override + public boolean equals(Object o) { + if (o == null) { + return false; + } + if (!(o instanceof ParameterDescriptor)) { + return false; + } + ParameterDescriptor other = (ParameterDescriptor) o; + return this.mName.equals(other.mName) && this.mType == other.mType; + } + + @Override + public int hashCode() { + return Arrays.asList( + (Object) mName, + (Object) Integer.valueOf(mType)).hashCode(); + } + private String mName; private @MediaFormat.Type int mType; } @@ -4631,7 +4650,8 @@ final public class MediaCodec { private native ParameterDescriptor native_getParameterDescriptor(@NonNull String name); /** - * Subscribe to vendor parameters, so that changes to these parameters generate + * Subscribe to vendor parameters, so that these parameters will be present in + * {@link #getOutputFormat} and changes to these parameters generate * output format change event. * <p> * Unrecognized parameter names or standard (non-vendor) parameter names will be ignored. @@ -4660,8 +4680,9 @@ final public class MediaCodec { private native void native_subscribeToVendorParameters(@NonNull List<String> names); /** - * Unsubscribe from vendor parameters, so that changes to these parameters - * no longer generate output format change event. + * Unsubscribe from vendor parameters, so that these parameters will not be present in + * {@link #getOutputFormat} and changes to these parameters no longer generate + * output format change event. * <p> * Unrecognized parameter names, standard (non-vendor) parameter names will be ignored. * {@link #reset} also resets the list of subscribed parameters. @@ -4669,7 +4690,8 @@ final public class MediaCodec { * <p> * This method can be called in any codec state except for released state. When called in * running state with newly unsubscribed parameters, it takes effect no later than the - * processing of the subsequently queued buffer. + * processing of the subsequently queued buffer. For the removed parameters, the codec will + * generate output format change event. * <p> * Note that any vendor parameters set in a {@link #configure} or * {@link #setParameters} call are automatically subscribed, and with this method diff --git a/media/jni/android_media_tv_Tuner.cpp b/media/jni/android_media_tv_Tuner.cpp index 3976086ea495..49ef504f6b03 100644 --- a/media/jni/android_media_tv_Tuner.cpp +++ b/media/jni/android_media_tv_Tuner.cpp @@ -3258,7 +3258,7 @@ static jint android_media_tv_Tuner_descrambler_add_pid( if (descramblerSp == NULL) { return (jint) Result::NOT_INITIALIZED; } - sp<IFilter> iFilterSp = getFilter(env, filter)->getIFilter(); + sp<IFilter> iFilterSp = (filter == NULL) ? NULL : getFilter(env, filter)->getIFilter(); Result result = descramblerSp->addPid(getDemuxPid((int)pidType, (int)pid), iFilterSp); return (jint) result; } @@ -3269,7 +3269,7 @@ static jint android_media_tv_Tuner_descrambler_remove_pid( if (descramblerSp == NULL) { return (jint) Result::NOT_INITIALIZED; } - sp<IFilter> iFilterSp = getFilter(env, filter)->getIFilter(); + sp<IFilter> iFilterSp = (filter == NULL) ? NULL : getFilter(env, filter)->getIFilter(); Result result = descramblerSp->removePid(getDemuxPid((int)pidType, (int)pid), iFilterSp); return (jint) result; } diff --git a/native/android/Android.bp b/native/android/Android.bp index d1dddbd52265..34b9fced5bee 100644 --- a/native/android/Android.bp +++ b/native/android/Android.bp @@ -77,6 +77,7 @@ cc_library_shared { "libgui", "libharfbuzz_ng", // Only for including hb.h via minikin "libsensor", + "libactivitymanager_aidl", "libandroid_runtime", "libminikin", "libnetd_client", diff --git a/packages/CompanionDeviceManager/AndroidManifest.xml b/packages/CompanionDeviceManager/AndroidManifest.xml index ea9b52cbf3d5..e4e5b9fa781a 100644 --- a/packages/CompanionDeviceManager/AndroidManifest.xml +++ b/packages/CompanionDeviceManager/AndroidManifest.xml @@ -31,6 +31,7 @@ <uses-permission android:name="android.permission.CHANGE_WIFI_STATE"/> <uses-permission android:name="android.permission.RADIO_SCAN_WITHOUT_LOCATION"/> <uses-permission android:name="android.permission.QUERY_ALL_PACKAGES"/> + <uses-permission android:name="android.permission.HIDE_NON_SYSTEM_OVERLAY_WINDOWS"/> <application android:allowClearUserData="true" diff --git a/packages/CompanionDeviceManager/src/com/android/companiondevicemanager/DeviceChooserActivity.java b/packages/CompanionDeviceManager/src/com/android/companiondevicemanager/DeviceChooserActivity.java index e501e1269aeb..5ac059be2010 100644 --- a/packages/CompanionDeviceManager/src/com/android/companiondevicemanager/DeviceChooserActivity.java +++ b/packages/CompanionDeviceManager/src/com/android/companiondevicemanager/DeviceChooserActivity.java @@ -17,6 +17,7 @@ package com.android.companiondevicemanager; import static android.companion.BluetoothDeviceFilterUtils.getDeviceMacAddress; +import static android.view.WindowManager.LayoutParams.SYSTEM_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS; import static java.util.Objects.requireNonNull; @@ -58,6 +59,8 @@ public class DeviceChooserActivity extends Activity { Log.e(LOG_TAG, "About to show UI, but no devices to show"); } + getWindow().addSystemFlags(SYSTEM_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS); + if (getService().mRequest.isSingleDevice()) { setContentView(R.layout.device_confirmation); final DeviceFilterPair selectedDevice = getService().mDevicesFound.get(0); diff --git a/packages/Connectivity/framework/api/current.txt b/packages/Connectivity/framework/api/current.txt index ab290f9d706a..7692e30c31fb 100644 --- a/packages/Connectivity/framework/api/current.txt +++ b/packages/Connectivity/framework/api/current.txt @@ -410,6 +410,8 @@ package android.net { } public class ParseException extends java.lang.RuntimeException { + ctor public ParseException(@NonNull String); + ctor public ParseException(@NonNull String, @NonNull Throwable); field public String response; } diff --git a/packages/Connectivity/framework/api/module-lib-current.txt b/packages/Connectivity/framework/api/module-lib-current.txt index f95d377d5ac9..9e2cd3e8a7fd 100644 --- a/packages/Connectivity/framework/api/module-lib-current.txt +++ b/packages/Connectivity/framework/api/module-lib-current.txt @@ -13,7 +13,7 @@ package android.net { method @NonNull public static String getPrivateDnsMode(@NonNull android.content.Context); method @RequiresPermission(anyOf={android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK, android.Manifest.permission.NETWORK_SETTINGS}) public void registerDefaultNetworkCallbackAsUid(int, @NonNull android.net.ConnectivityManager.NetworkCallback, @NonNull android.os.Handler); method @RequiresPermission(anyOf={android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK, android.Manifest.permission.NETWORK_SETTINGS}) public void registerSystemDefaultNetworkCallback(@NonNull android.net.ConnectivityManager.NetworkCallback, @NonNull android.os.Handler); - method @RequiresPermission(anyOf={android.Manifest.permission.NETWORK_SETTINGS, android.Manifest.permission.NETWORK_STACK, android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK}) public void requestBackgroundNetwork(@NonNull android.net.NetworkRequest, @NonNull android.os.Handler, @NonNull android.net.ConnectivityManager.NetworkCallback); + method @RequiresPermission(anyOf={android.Manifest.permission.NETWORK_SETTINGS, android.Manifest.permission.NETWORK_STACK, android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK}) public void requestBackgroundNetwork(@NonNull android.net.NetworkRequest, @NonNull android.net.ConnectivityManager.NetworkCallback, @NonNull android.os.Handler); method @Deprecated public boolean requestRouteToHostAddress(int, java.net.InetAddress); method @RequiresPermission(anyOf={android.Manifest.permission.NETWORK_SETTINGS, android.Manifest.permission.NETWORK_SETUP_WIZARD, android.Manifest.permission.NETWORK_STACK, android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK}) public void setAcceptPartialConnectivity(@NonNull android.net.Network, boolean, boolean); method @RequiresPermission(anyOf={android.Manifest.permission.NETWORK_SETTINGS, android.Manifest.permission.NETWORK_SETUP_WIZARD, android.Manifest.permission.NETWORK_STACK, android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK}) public void setAcceptUnvalidated(@NonNull android.net.Network, boolean, boolean); @@ -26,6 +26,10 @@ package android.net { method @RequiresPermission(anyOf={android.Manifest.permission.MANAGE_TEST_NETWORKS, android.Manifest.permission.NETWORK_STACK}) public void simulateDataStall(int, long, @NonNull android.net.Network, @NonNull android.os.PersistableBundle); method @RequiresPermission(anyOf={android.Manifest.permission.NETWORK_SETTINGS, android.Manifest.permission.NETWORK_STACK, android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK}) public void startCaptivePortalApp(@NonNull android.net.Network); method public void systemReady(); + field public static final String ACTION_CLEAR_DNS_CACHE = "android.net.action.CLEAR_DNS_CACHE"; + field public static final String ACTION_PROMPT_LOST_VALIDATION = "android.net.action.PROMPT_LOST_VALIDATION"; + field public static final String ACTION_PROMPT_PARTIAL_CONNECTIVITY = "android.net.action.PROMPT_PARTIAL_CONNECTIVITY"; + field public static final String ACTION_PROMPT_UNVALIDATED = "android.net.action.PROMPT_UNVALIDATED"; field public static final int BLOCKED_METERED_REASON_ADMIN_DISABLED = 262144; // 0x40000 field public static final int BLOCKED_METERED_REASON_DATA_SAVER = 65536; // 0x10000 field public static final int BLOCKED_METERED_REASON_MASK = -65536; // 0xffff0000 @@ -129,21 +133,6 @@ package android.net { method @NonNull public android.net.NetworkRequest.Builder setUids(@Nullable java.util.Set<android.util.Range<java.lang.Integer>>); } - public class ParseException extends java.lang.RuntimeException { - ctor public ParseException(@NonNull String); - ctor public ParseException(@NonNull String, @NonNull Throwable); - } - - public final class TcpRepairWindow { - ctor public TcpRepairWindow(int, int, int, int, int, int); - field public final int maxWindow; - field public final int rcvWnd; - field public final int rcvWndScale; - field public final int rcvWup; - field public final int sndWl1; - field public final int sndWnd; - } - public final class TestNetworkInterface implements android.os.Parcelable { ctor public TestNetworkInterface(@NonNull android.os.ParcelFileDescriptor, @NonNull String); method public int describeContents(); @@ -154,10 +143,10 @@ package android.net { } public class TestNetworkManager { - method @NonNull public android.net.TestNetworkInterface createTapInterface(); - method @NonNull public android.net.TestNetworkInterface createTunInterface(@NonNull java.util.Collection<android.net.LinkAddress>); - method public void setupTestNetwork(@NonNull String, @NonNull android.os.IBinder); - method public void teardownTestNetwork(@NonNull android.net.Network); + method @NonNull @RequiresPermission(android.Manifest.permission.MANAGE_TEST_NETWORKS) public android.net.TestNetworkInterface createTapInterface(); + method @NonNull @RequiresPermission(android.Manifest.permission.MANAGE_TEST_NETWORKS) public android.net.TestNetworkInterface createTunInterface(@NonNull java.util.Collection<android.net.LinkAddress>); + method @RequiresPermission(android.Manifest.permission.MANAGE_TEST_NETWORKS) public void setupTestNetwork(@NonNull String, @NonNull android.os.IBinder); + method @RequiresPermission(android.Manifest.permission.MANAGE_TEST_NETWORKS) public void teardownTestNetwork(@NonNull android.net.Network); field public static final String TEST_TAP_PREFIX = "testtap"; } diff --git a/packages/Connectivity/framework/api/system-current.txt b/packages/Connectivity/framework/api/system-current.txt index 0a82cb7cfee1..de673ee9715e 100644 --- a/packages/Connectivity/framework/api/system-current.txt +++ b/packages/Connectivity/framework/api/system-current.txt @@ -259,15 +259,15 @@ package android.net { public static final class NetworkAgentConfig.Builder { ctor public NetworkAgentConfig.Builder(); method @NonNull public android.net.NetworkAgentConfig build(); - method @NonNull public android.net.NetworkAgentConfig.Builder disableNat64Detection(); - method @NonNull public android.net.NetworkAgentConfig.Builder disableProvisioningNotification(); method @NonNull public android.net.NetworkAgentConfig.Builder setExplicitlySelected(boolean); method @NonNull public android.net.NetworkAgentConfig.Builder setLegacyExtraInfo(@NonNull String); method @NonNull public android.net.NetworkAgentConfig.Builder setLegacySubType(int); method @NonNull public android.net.NetworkAgentConfig.Builder setLegacySubTypeName(@NonNull String); method @NonNull public android.net.NetworkAgentConfig.Builder setLegacyType(int); method @NonNull public android.net.NetworkAgentConfig.Builder setLegacyTypeName(@NonNull String); + method @NonNull public android.net.NetworkAgentConfig.Builder setNat64DetectionEnabled(boolean); method @NonNull public android.net.NetworkAgentConfig.Builder setPartialConnectivityAcceptable(boolean); + method @NonNull public android.net.NetworkAgentConfig.Builder setProvisioningNotificationEnabled(boolean); method @NonNull public android.net.NetworkAgentConfig.Builder setUnvalidatedConnectivityAcceptable(boolean); } @@ -455,14 +455,14 @@ package android.net { public final class TcpKeepalivePacketData extends android.net.KeepalivePacketData implements android.os.Parcelable { ctor public TcpKeepalivePacketData(@NonNull java.net.InetAddress, int, @NonNull java.net.InetAddress, int, @NonNull byte[], int, int, int, int, int, int) throws android.net.InvalidPacketException; method public int describeContents(); + method public int getIpTos(); + method public int getIpTtl(); + method public int getTcpAck(); + method public int getTcpSeq(); + method public int getTcpWindow(); + method public int getTcpWindowScale(); method public void writeToParcel(@NonNull android.os.Parcel, int); field @NonNull public static final android.os.Parcelable.Creator<android.net.TcpKeepalivePacketData> CREATOR; - field public final int ipTos; - field public final int ipTtl; - field public final int tcpAck; - field public final int tcpSeq; - field public final int tcpWindow; - field public final int tcpWindowScale; } } diff --git a/packages/Connectivity/framework/src/android/net/CaptivePortalData.java b/packages/Connectivity/framework/src/android/net/CaptivePortalData.java index 82dbd0fb1f87..53aa1b92edca 100644 --- a/packages/Connectivity/framework/src/android/net/CaptivePortalData.java +++ b/packages/Connectivity/framework/src/android/net/CaptivePortalData.java @@ -42,7 +42,7 @@ public final class CaptivePortalData implements Parcelable { private final long mByteLimit; private final long mExpiryTimeMillis; private final boolean mCaptive; - private final CharSequence mVenueFriendlyName; + private final String mVenueFriendlyName; private final int mVenueInfoUrlSource; private final int mUserPortalUrlSource; @@ -73,14 +73,14 @@ public final class CaptivePortalData implements Parcelable { mByteLimit = byteLimit; mExpiryTimeMillis = expiryTimeMillis; mCaptive = captive; - mVenueFriendlyName = venueFriendlyName; + mVenueFriendlyName = venueFriendlyName == null ? null : venueFriendlyName.toString(); mVenueInfoUrlSource = venueInfoUrlSource; mUserPortalUrlSource = userPortalUrlSource; } private CaptivePortalData(Parcel p) { this(p.readLong(), p.readParcelable(null), p.readParcelable(null), p.readBoolean(), - p.readLong(), p.readLong(), p.readBoolean(), p.readCharSequence(), p.readInt(), + p.readLong(), p.readLong(), p.readBoolean(), p.readString(), p.readInt(), p.readInt()); } @@ -98,7 +98,7 @@ public final class CaptivePortalData implements Parcelable { dest.writeLong(mByteLimit); dest.writeLong(mExpiryTimeMillis); dest.writeBoolean(mCaptive); - dest.writeCharSequence(mVenueFriendlyName); + dest.writeString(mVenueFriendlyName); dest.writeInt(mVenueInfoUrlSource); dest.writeInt(mUserPortalUrlSource); } diff --git a/packages/Connectivity/framework/src/android/net/ConnectivityFrameworkInitializer.java b/packages/Connectivity/framework/src/android/net/ConnectivityFrameworkInitializer.java index 92a792b78410..a2e218dcbb4b 100644 --- a/packages/Connectivity/framework/src/android/net/ConnectivityFrameworkInitializer.java +++ b/packages/Connectivity/framework/src/android/net/ConnectivityFrameworkInitializer.java @@ -68,5 +68,11 @@ public final class ConnectivityFrameworkInitializer { return cm.startOrGetTestNetworkManager(); } ); + + SystemServiceRegistry.registerContextAwareService( + DnsResolverServiceManager.DNS_RESOLVER_SERVICE, + DnsResolverServiceManager.class, + (context, serviceBinder) -> new DnsResolverServiceManager(serviceBinder) + ); } } diff --git a/packages/Connectivity/framework/src/android/net/ConnectivityManager.java b/packages/Connectivity/framework/src/android/net/ConnectivityManager.java index 92ed7fc29eb2..043ff383e766 100644 --- a/packages/Connectivity/framework/src/android/net/ConnectivityManager.java +++ b/packages/Connectivity/framework/src/android/net/ConnectivityManager.java @@ -44,6 +44,7 @@ import android.content.ComponentName; import android.content.ContentResolver; import android.content.Context; import android.content.Intent; +import android.net.ConnectivityDiagnosticsManager.DataStallReport.DetectionMethod; import android.net.IpSecManager.UdpEncapsulationSocket; import android.net.SocketKeepalive.Callback; import android.net.TetheringManager.StartTetheringCallback; @@ -425,7 +426,8 @@ public class ConnectivityManager { * * @hide */ - public static final String ACTION_PROMPT_UNVALIDATED = "android.net.conn.PROMPT_UNVALIDATED"; + @SystemApi(client = MODULE_LIBRARIES) + public static final String ACTION_PROMPT_UNVALIDATED = "android.net.action.PROMPT_UNVALIDATED"; /** * Action used to display a dialog that asks the user whether to avoid a network that is no @@ -433,8 +435,9 @@ public class ConnectivityManager { * * @hide */ + @SystemApi(client = MODULE_LIBRARIES) public static final String ACTION_PROMPT_LOST_VALIDATION = - "android.net.conn.PROMPT_LOST_VALIDATION"; + "android.net.action.PROMPT_LOST_VALIDATION"; /** * Action used to display a dialog that asks the user whether to stay connected to a network @@ -443,8 +446,18 @@ public class ConnectivityManager { * * @hide */ + @SystemApi(client = MODULE_LIBRARIES) public static final String ACTION_PROMPT_PARTIAL_CONNECTIVITY = - "android.net.conn.PROMPT_PARTIAL_CONNECTIVITY"; + "android.net.action.PROMPT_PARTIAL_CONNECTIVITY"; + + /** + * Clear DNS Cache Action: This is broadcast when networks have changed and old + * DNS entries should be cleared. + * @hide + */ + @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) + @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES) + public static final String ACTION_CLEAR_DNS_CACHE = "android.net.action.CLEAR_DNS_CACHE"; /** * Invalid tethering type. @@ -3418,6 +3431,8 @@ public class ConnectivityManager { * not include location sensitive info. * </p> */ + // Note: Some existing fields which are location sensitive may still be included without + // this flag if the app targets SDK < S (to maintain backwards compatibility). public static final int FLAG_INCLUDE_LOCATION_INFO = 1 << 0; /** @hide */ @@ -5090,10 +5105,13 @@ public class ConnectivityManager { * * <p>This method should only be used for tests. * - * <p>The caller must be the owner of the specified Network. + * <p>The caller must be the owner of the specified Network. This simulates a data stall to + * have the system behave as if it had happened, but does not actually stall connectivity. * * @param detectionMethod The detection method used to identify the Data Stall. - * @param timestampMillis The timestamp at which the stall 'occurred', in milliseconds. + * See ConnectivityDiagnosticsManager.DataStallReport.DETECTION_METHOD_*. + * @param timestampMillis The timestamp at which the stall 'occurred', in milliseconds, as per + * SystemClock.elapsedRealtime. * @param network The Network for which a Data Stall is being simluated. * @param extras The PersistableBundle of extras included in the Data Stall notification. * @throws SecurityException if the caller is not the owner of the given network. @@ -5102,7 +5120,7 @@ public class ConnectivityManager { @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES) @RequiresPermission(anyOf = {android.Manifest.permission.MANAGE_TEST_NETWORKS, android.Manifest.permission.NETWORK_STACK}) - public void simulateDataStall(int detectionMethod, long timestampMillis, + public void simulateDataStall(@DetectionMethod int detectionMethod, long timestampMillis, @NonNull Network network, @NonNull PersistableBundle extras) { try { mService.simulateDataStall(detectionMethod, timestampMillis, network, extras); @@ -5289,10 +5307,10 @@ public class ConnectivityManager { * {@link #unregisterNetworkCallback(NetworkCallback)}. * * @param request {@link NetworkRequest} describing this request. - * @param handler {@link Handler} to specify the thread upon which the callback will be invoked. - * If null, the callback is invoked on the default internal Handler. * @param networkCallback The {@link NetworkCallback} to be utilized for this request. Note * the callback must not be shared - it uniquely specifies this request. + * @param handler {@link Handler} to specify the thread upon which the callback will be invoked. + * If null, the callback is invoked on the default internal Handler. * @throws IllegalArgumentException if {@code request} contains invalid network capabilities. * @throws SecurityException if missing the appropriate permissions. * @throws RuntimeException if the app already has too many callbacks registered. @@ -5307,7 +5325,8 @@ public class ConnectivityManager { NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK }) public void requestBackgroundNetwork(@NonNull NetworkRequest request, - @NonNull Handler handler, @NonNull NetworkCallback networkCallback) { + @NonNull NetworkCallback networkCallback, + @SuppressLint("ListenerLast") @NonNull Handler handler) { final NetworkCapabilities nc = request.networkCapabilities; sendRequestForNetwork(nc, networkCallback, 0, BACKGROUND_REQUEST, TYPE_NONE, new CallbackHandler(handler)); diff --git a/packages/Connectivity/framework/src/android/net/DnsResolverServiceManager.java b/packages/Connectivity/framework/src/android/net/DnsResolverServiceManager.java new file mode 100644 index 000000000000..79009e8d629e --- /dev/null +++ b/packages/Connectivity/framework/src/android/net/DnsResolverServiceManager.java @@ -0,0 +1,45 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR 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.IBinder; + +/** + * Provides a way to obtain the DnsResolver binder objects. + * + * @hide + */ +public class DnsResolverServiceManager { + /** Service name for the DNS resolver. Keep in sync with DnsResolverService.h */ + public static final String DNS_RESOLVER_SERVICE = "dnsresolver"; + + private final IBinder mResolver; + + DnsResolverServiceManager(IBinder resolver) { + mResolver = resolver; + } + + /** + * Get an {@link IBinder} representing the DnsResolver stable AIDL interface + * + * @return {@link android.net.IDnsResolver} IBinder. + */ + @NonNull + public IBinder getService() { + return mResolver; + } +} diff --git a/packages/Connectivity/framework/src/android/net/LinkProperties.java b/packages/Connectivity/framework/src/android/net/LinkProperties.java index e41ed72b259c..99f48b49c6b5 100644 --- a/packages/Connectivity/framework/src/android/net/LinkProperties.java +++ b/packages/Connectivity/framework/src/android/net/LinkProperties.java @@ -686,8 +686,8 @@ public final class LinkProperties implements Parcelable { } /** - * Adds a {@link RouteInfo} to this {@code LinkProperties}, if a {@link RouteInfo} - * with the same {@link RouteInfo.RouteKey} with different properties + * Adds a {@link RouteInfo} to this {@code LinkProperties}. If there is a {@link RouteInfo} + * with the same destination, gateway and interface with different properties * (e.g., different MTU), it will be updated. If the {@link RouteInfo} had an * interface name set and that differs from the interface set for this * {@code LinkProperties} an {@link IllegalArgumentException} will be thrown. diff --git a/packages/Connectivity/framework/src/android/net/Network.java b/packages/Connectivity/framework/src/android/net/Network.java index 0741414ab3aa..41fad6317a20 100644 --- a/packages/Connectivity/framework/src/android/net/Network.java +++ b/packages/Connectivity/framework/src/android/net/Network.java @@ -27,7 +27,6 @@ import android.os.Parcelable; import android.system.ErrnoException; import android.system.Os; import android.system.OsConstants; -import android.util.proto.ProtoOutputStream; import com.android.internal.annotations.GuardedBy; @@ -526,11 +525,4 @@ public class Network implements Parcelable { public String toString() { return Integer.toString(netId); } - - /** @hide */ - public void dumpDebug(ProtoOutputStream proto, long fieldId) { - final long token = proto.start(fieldId); - proto.write(NetworkProto.NET_ID, netId); - proto.end(token); - } } diff --git a/packages/Connectivity/framework/src/android/net/NetworkAgentConfig.java b/packages/Connectivity/framework/src/android/net/NetworkAgentConfig.java index 3f058d8cbf12..ad8396b06ddf 100644 --- a/packages/Connectivity/framework/src/android/net/NetworkAgentConfig.java +++ b/packages/Connectivity/framework/src/android/net/NetworkAgentConfig.java @@ -311,26 +311,28 @@ public final class NetworkAgentConfig implements Parcelable { } /** - * Disables active detection of NAT64 (e.g., via RFC 7050 DNS lookups). Used to save power - * and reduce idle traffic on networks that are known to be IPv6-only without a NAT64. + * Enables or disables active detection of NAT64 (e.g., via RFC 7050 DNS lookups). Used to + * save power and reduce idle traffic on networks that are known to be IPv6-only without a + * NAT64. By default, NAT64 detection is enabled. * * @return this builder, to facilitate chaining. */ @NonNull - public Builder disableNat64Detection() { - mConfig.skip464xlat = true; + public Builder setNat64DetectionEnabled(boolean enabled) { + mConfig.skip464xlat = !enabled; return this; } /** - * Disables the "Sign in to network" notification. Used if the network transport will - * perform its own carrier-specific provisioning procedure. + * Enables or disables the "Sign in to network" notification. Used if the network transport + * will perform its own carrier-specific provisioning procedure. By default, the + * notification is enabled. * * @return this builder, to facilitate chaining. */ @NonNull - public Builder disableProvisioningNotification() { - mConfig.provisioningNotificationDisabled = true; + public Builder setProvisioningNotificationEnabled(boolean enabled) { + mConfig.provisioningNotificationDisabled = !enabled; return this; } diff --git a/packages/Connectivity/framework/src/android/net/NetworkCapabilities.java b/packages/Connectivity/framework/src/android/net/NetworkCapabilities.java index 0619bbd9e178..a43dd15a8765 100644 --- a/packages/Connectivity/framework/src/android/net/NetworkCapabilities.java +++ b/packages/Connectivity/framework/src/android/net/NetworkCapabilities.java @@ -35,7 +35,6 @@ import android.os.Process; import android.text.TextUtils; import android.util.ArraySet; import android.util.Range; -import android.util.proto.ProtoOutputStream; import com.android.internal.annotations.VisibleForTesting; import com.android.net.module.util.CollectionUtils; @@ -592,8 +591,9 @@ public final class NetworkCapabilities implements Parcelable { // TODO: Consider adding unwanted capabilities to the public API and mention this // in the documentation. checkValidCapability(capability); - mNetworkCapabilities |= 1 << capability; - mUnwantedNetworkCapabilities &= ~(1 << capability); // remove from unwanted capability list + mNetworkCapabilities |= 1L << capability; + // remove from unwanted capability list + mUnwantedNetworkCapabilities &= ~(1L << capability); return this; } @@ -612,8 +612,8 @@ public final class NetworkCapabilities implements Parcelable { */ public void addUnwantedCapability(@NetCapability int capability) { checkValidCapability(capability); - mUnwantedNetworkCapabilities |= 1 << capability; - mNetworkCapabilities &= ~(1 << capability); // remove from requested capabilities + mUnwantedNetworkCapabilities |= 1L << capability; + mNetworkCapabilities &= ~(1L << capability); // remove from requested capabilities } /** @@ -626,7 +626,7 @@ public final class NetworkCapabilities implements Parcelable { */ public @NonNull NetworkCapabilities removeCapability(@NetCapability int capability) { checkValidCapability(capability); - final long mask = ~(1 << capability); + final long mask = ~(1L << capability); mNetworkCapabilities &= mask; return this; } @@ -641,7 +641,7 @@ public final class NetworkCapabilities implements Parcelable { */ public @NonNull NetworkCapabilities removeUnwantedCapability(@NetCapability int capability) { checkValidCapability(capability); - mUnwantedNetworkCapabilities &= ~(1 << capability); + mUnwantedNetworkCapabilities &= ~(1L << capability); return this; } @@ -709,14 +709,14 @@ public final class NetworkCapabilities implements Parcelable { */ public boolean hasCapability(@NetCapability int capability) { return isValidCapability(capability) - && ((mNetworkCapabilities & (1 << capability)) != 0); + && ((mNetworkCapabilities & (1L << capability)) != 0); } /** @hide */ @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES) public boolean hasUnwantedCapability(@NetCapability int capability) { return isValidCapability(capability) - && ((mUnwantedNetworkCapabilities & (1 << capability)) != 0); + && ((mUnwantedNetworkCapabilities & (1L << capability)) != 0); } /** @@ -1111,7 +1111,9 @@ public final class NetworkCapabilities implements Parcelable { * app needs to hold {@link android.Manifest.permission#ACCESS_FINE_LOCATION} permission. If the * app targets SDK version greater than or equal to {@link Build.VERSION_CODES#S}, then they * also need to use {@link NetworkCallback#FLAG_INCLUDE_LOCATION_INFO} to get the info in their - * callback. The app will be blamed for location access if this field is included. + * callback. If the apps targets SDK version equal to {{@link Build.VERSION_CODES#R}, this field + * will always be included. The app will be blamed for location access if this field is + * included. * </p> */ public int getOwnerUid() { @@ -2057,34 +2059,6 @@ public final class NetworkCapabilities implements Parcelable { } } - /** @hide */ - public void dumpDebug(@NonNull ProtoOutputStream proto, long fieldId) { - final long token = proto.start(fieldId); - - for (int transport : getTransportTypes()) { - proto.write(NetworkCapabilitiesProto.TRANSPORTS, transport); - } - - for (int capability : getCapabilities()) { - proto.write(NetworkCapabilitiesProto.CAPABILITIES, capability); - } - - proto.write(NetworkCapabilitiesProto.LINK_UP_BANDWIDTH_KBPS, mLinkUpBandwidthKbps); - proto.write(NetworkCapabilitiesProto.LINK_DOWN_BANDWIDTH_KBPS, mLinkDownBandwidthKbps); - - if (mNetworkSpecifier != null) { - proto.write(NetworkCapabilitiesProto.NETWORK_SPECIFIER, mNetworkSpecifier.toString()); - } - if (mTransportInfo != null) { - // TODO b/120653863: write transport-specific info to proto? - } - - proto.write(NetworkCapabilitiesProto.CAN_REPORT_SIGNAL_STRENGTH, hasSignalStrength()); - proto.write(NetworkCapabilitiesProto.SIGNAL_STRENGTH, mSignalStrength); - - proto.end(token); - } - /** * @hide */ diff --git a/packages/Connectivity/framework/src/android/net/NetworkRequest.java b/packages/Connectivity/framework/src/android/net/NetworkRequest.java index 5d40417440d4..3a8a07a55ad4 100644 --- a/packages/Connectivity/framework/src/android/net/NetworkRequest.java +++ b/packages/Connectivity/framework/src/android/net/NetworkRequest.java @@ -47,7 +47,6 @@ import android.os.Parcelable; import android.os.Process; import android.text.TextUtils; import android.util.Range; -import android.util.proto.ProtoOutputStream; import java.util.Arrays; import java.util.List; @@ -680,18 +679,6 @@ public class NetworkRequest implements Parcelable { } } - /** @hide */ - public void dumpDebug(ProtoOutputStream proto, long fieldId) { - final long token = proto.start(fieldId); - - proto.write(NetworkRequestProto.TYPE, typeToProtoEnum(type)); - proto.write(NetworkRequestProto.REQUEST_ID, requestId); - proto.write(NetworkRequestProto.LEGACY_TYPE, legacyType); - networkCapabilities.dumpDebug(proto, NetworkRequestProto.NETWORK_CAPABILITIES); - - proto.end(token); - } - public boolean equals(@Nullable Object obj) { if (obj instanceof NetworkRequest == false) return false; NetworkRequest that = (NetworkRequest)obj; diff --git a/packages/Connectivity/framework/src/android/net/OemNetworkPreferences.java b/packages/Connectivity/framework/src/android/net/OemNetworkPreferences.java index 5a76cd6d6b0f..2bb006df82e0 100644 --- a/packages/Connectivity/framework/src/android/net/OemNetworkPreferences.java +++ b/packages/Connectivity/framework/src/android/net/OemNetworkPreferences.java @@ -40,6 +40,23 @@ import java.util.Objects; */ @SystemApi public final class OemNetworkPreferences implements Parcelable { + // Valid production preferences must be > 0, negative values reserved for testing + /** + * This preference is only to be used for testing and nothing else. + * Use only TRANSPORT_TEST transport networks. + * @hide + */ + public static final int OEM_NETWORK_PREFERENCE_TEST_ONLY = -2; + + /** + * This preference is only to be used for testing and nothing else. + * If an unmetered network is available, use it. + * Otherwise, if a network with the TRANSPORT_TEST transport is available, use it. + * Otherwise, use the general default network. + * @hide + */ + public static final int OEM_NETWORK_PREFERENCE_TEST = -1; + /** * Default in case this value is not set. Using it will result in an error. */ @@ -69,6 +86,12 @@ public final class OemNetworkPreferences implements Parcelable { */ public static final int OEM_NETWORK_PREFERENCE_OEM_PRIVATE_ONLY = 4; + /** + * The max allowed value for an OEM network preference. + * @hide + */ + public static final int OEM_NETWORK_PREFERENCE_MAX = OEM_NETWORK_PREFERENCE_OEM_PRIVATE_ONLY; + @NonNull private final Bundle mNetworkMappings; @@ -96,7 +119,7 @@ public final class OemNetworkPreferences implements Parcelable { @Override public String toString() { - return "OemNetworkPreferences{" + "mNetworkMappings=" + mNetworkMappings + '}'; + return "OemNetworkPreferences{" + "mNetworkMappings=" + getNetworkPreferences() + '}'; } @Override @@ -185,6 +208,8 @@ public final class OemNetworkPreferences implements Parcelable { /** @hide */ @IntDef(prefix = "OEM_NETWORK_PREFERENCE_", value = { + OEM_NETWORK_PREFERENCE_TEST_ONLY, + OEM_NETWORK_PREFERENCE_TEST, OEM_NETWORK_PREFERENCE_UNINITIALIZED, OEM_NETWORK_PREFERENCE_OEM_PAID, OEM_NETWORK_PREFERENCE_OEM_PAID_NO_FALLBACK, @@ -205,6 +230,10 @@ public final class OemNetworkPreferences implements Parcelable { @NonNull public static String oemNetworkPreferenceToString(@OemNetworkPreference int value) { switch (value) { + case OEM_NETWORK_PREFERENCE_TEST_ONLY: + return "OEM_NETWORK_PREFERENCE_TEST_ONLY"; + case OEM_NETWORK_PREFERENCE_TEST: + return "OEM_NETWORK_PREFERENCE_TEST"; case OEM_NETWORK_PREFERENCE_UNINITIALIZED: return "OEM_NETWORK_PREFERENCE_UNINITIALIZED"; case OEM_NETWORK_PREFERENCE_OEM_PAID: diff --git a/packages/Connectivity/framework/src/android/net/ParseException.java b/packages/Connectivity/framework/src/android/net/ParseException.java index ca6d012dfe7c..9d4727a84bc0 100644 --- a/packages/Connectivity/framework/src/android/net/ParseException.java +++ b/packages/Connectivity/framework/src/android/net/ParseException.java @@ -17,7 +17,6 @@ package android.net; import android.annotation.NonNull; -import android.annotation.SystemApi; /** * Thrown when parsing failed. @@ -26,15 +25,11 @@ import android.annotation.SystemApi; public class ParseException extends RuntimeException { public String response; - /** @hide */ - @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES) public ParseException(@NonNull String response) { super(response); this.response = response; } - /** @hide */ - @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES) public ParseException(@NonNull String response, @NonNull Throwable cause) { super(response, cause); this.response = response; diff --git a/packages/Connectivity/framework/src/android/net/TcpKeepalivePacketData.java b/packages/Connectivity/framework/src/android/net/TcpKeepalivePacketData.java index ddb3a6a72fb4..c2c4f32ca673 100644 --- a/packages/Connectivity/framework/src/android/net/TcpKeepalivePacketData.java +++ b/packages/Connectivity/framework/src/android/net/TcpKeepalivePacketData.java @@ -32,22 +32,39 @@ import java.util.Objects; public final class TcpKeepalivePacketData extends KeepalivePacketData implements Parcelable { private static final String TAG = "TcpKeepalivePacketData"; - /** TCP sequence number. */ + /** + * TCP sequence number. + * @hide + */ public final int tcpSeq; - /** TCP ACK number. */ + /** + * TCP ACK number. + * @hide + */ public final int tcpAck; - /** TCP RCV window. */ + /** + * TCP RCV window. + * @hide + */ public final int tcpWindow; - /** TCP RCV window scale. */ + /** TCP RCV window scale. + * @hide + */ public final int tcpWindowScale; - /** IP TOS. */ + /** + * IP TOS. + * @hide + */ public final int ipTos; - /** IP TTL. */ + /** + * IP TTL. + * @hide + */ public final int ipTtl; public TcpKeepalivePacketData(@NonNull final InetAddress srcAddress, int srcPort, @@ -63,6 +80,56 @@ public final class TcpKeepalivePacketData extends KeepalivePacketData implements this.ipTtl = ipTtl; } + /** + * Get the TCP sequence number. + * + * See https://tools.ietf.org/html/rfc793#page-15. + */ + public int getTcpSeq() { + return tcpSeq; + } + + /** + * Get the TCP ACK number. + * + * See https://tools.ietf.org/html/rfc793#page-15. + */ + public int getTcpAck() { + return tcpAck; + } + + /** + * Get the TCP RCV window. + * + * See https://tools.ietf.org/html/rfc793#page-15. + */ + public int getTcpWindow() { + return tcpWindow; + } + + /** + * Get the TCP RCV window scale. + * + * See https://tools.ietf.org/html/rfc793#page-15. + */ + public int getTcpWindowScale() { + return tcpWindowScale; + } + + /** + * Get the IP type of service. + */ + public int getIpTos() { + return ipTos; + } + + /** + * Get the IP TTL. + */ + public int getIpTtl() { + return ipTtl; + } + @Override public boolean equals(@Nullable final Object o) { if (!(o instanceof TcpKeepalivePacketData)) return false; diff --git a/packages/Connectivity/framework/src/android/net/TcpRepairWindow.java b/packages/Connectivity/framework/src/android/net/TcpRepairWindow.java index f062fa9034ea..86034f0a76ed 100644 --- a/packages/Connectivity/framework/src/android/net/TcpRepairWindow.java +++ b/packages/Connectivity/framework/src/android/net/TcpRepairWindow.java @@ -16,15 +16,12 @@ package android.net; -import android.annotation.SystemApi; - /** * Corresponds to C's {@code struct tcp_repair_window} from * include/uapi/linux/tcp.h * * @hide */ -@SystemApi(client = SystemApi.Client.MODULE_LIBRARIES) public final class TcpRepairWindow { public final int sndWl1; public final int sndWnd; diff --git a/packages/Connectivity/framework/src/android/net/TestNetworkManager.java b/packages/Connectivity/framework/src/android/net/TestNetworkManager.java index a7a62351e5be..9ddd2f57679b 100644 --- a/packages/Connectivity/framework/src/android/net/TestNetworkManager.java +++ b/packages/Connectivity/framework/src/android/net/TestNetworkManager.java @@ -15,8 +15,10 @@ */ package android.net; +import android.Manifest; import android.annotation.NonNull; import android.annotation.Nullable; +import android.annotation.RequiresPermission; import android.annotation.SystemApi; import android.os.IBinder; import android.os.RemoteException; @@ -58,6 +60,7 @@ public class TestNetworkManager { * @param network The test network that should be torn down * @hide */ + @RequiresPermission(Manifest.permission.MANAGE_TEST_NETWORKS) @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES) public void teardownTestNetwork(@NonNull Network network) { try { @@ -103,6 +106,7 @@ public class TestNetworkManager { * @param binder A binder object guarding the lifecycle of this test network. * @hide */ + @RequiresPermission(Manifest.permission.MANAGE_TEST_NETWORKS) @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES) public void setupTestNetwork(@NonNull String iface, @NonNull IBinder binder) { setupTestNetwork(iface, null, true, new int[0], binder); @@ -145,6 +149,7 @@ public class TestNetworkManager { * TUN interface. * @hide */ + @RequiresPermission(Manifest.permission.MANAGE_TEST_NETWORKS) @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES) @NonNull public TestNetworkInterface createTunInterface(@NonNull Collection<LinkAddress> linkAddrs) { @@ -163,6 +168,7 @@ public class TestNetworkManager { * TAP interface. * @hide */ + @RequiresPermission(Manifest.permission.MANAGE_TEST_NETWORKS) @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES) @NonNull public TestNetworkInterface createTapInterface() { diff --git a/packages/Connectivity/framework/src/android/net/UidRange.java b/packages/Connectivity/framework/src/android/net/UidRange.java index bc67c745c98f..bd332928f463 100644 --- a/packages/Connectivity/framework/src/android/net/UidRange.java +++ b/packages/Connectivity/framework/src/android/net/UidRange.java @@ -46,8 +46,8 @@ public final class UidRange implements Parcelable { /** Creates a UidRange for the specified user. */ public static UidRange createForUser(UserHandle user) { final UserHandle nextUser = UserHandle.of(user.getIdentifier() + 1); - final int start = UserHandle.getUid(user, 0 /* appId */); - final int end = UserHandle.getUid(nextUser, 0) - 1; + final int start = user.getUid(0 /* appId */); + final int end = nextUser.getUid(0 /* appId */) - 1; return new UidRange(start, end); } diff --git a/packages/Connectivity/framework/src/android/net/VpnTransportInfo.java b/packages/Connectivity/framework/src/android/net/VpnTransportInfo.java index ba83a44d0d6c..efd336377114 100644 --- a/packages/Connectivity/framework/src/android/net/VpnTransportInfo.java +++ b/packages/Connectivity/framework/src/android/net/VpnTransportInfo.java @@ -22,6 +22,7 @@ import static android.net.NetworkCapabilities.REDACT_FOR_NETWORK_SETTINGS; import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.SystemApi; +import android.net.NetworkCapabilities.RedactionType; import android.os.Parcel; import android.os.Parcelable; import android.text.TextUtils; @@ -45,7 +46,7 @@ public final class VpnTransportInfo implements TransportInfo, Parcelable { public final String sessionId; @Override - public long getApplicableRedactions() { + public @RedactionType long getApplicableRedactions() { return REDACT_FOR_NETWORK_SETTINGS; } @@ -53,7 +54,7 @@ public final class VpnTransportInfo implements TransportInfo, Parcelable { * Create a copy of a {@link VpnTransportInfo} with the sessionId redacted if necessary. */ @NonNull - public VpnTransportInfo makeCopy(long redactions) { + public VpnTransportInfo makeCopy(@RedactionType long redactions) { return new VpnTransportInfo(type, ((redactions & REDACT_FOR_NETWORK_SETTINGS) != 0) ? null : sessionId); } diff --git a/packages/SettingsLib/ActionBarShadow/lint-baseline.xml b/packages/SettingsLib/ActionBarShadow/lint-baseline.xml new file mode 100644 index 000000000000..4d5de5f46894 --- /dev/null +++ b/packages/SettingsLib/ActionBarShadow/lint-baseline.xml @@ -0,0 +1,37 @@ +<?xml version="1.0" encoding="UTF-8"?> +<issues format="5" by="lint 4.1.0" client="cli" variant="all" version="4.1.0"> + + <issue + id="NewApi" + message="Call requires API level 23 (current min is 21): `android.view.View#setOnScrollChangeListener`" + errorLine1=" mScrollView.setOnScrollChangeListener(mScrollChangeWatcher);" + errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~"> + <location + file="frameworks/base/packages/SettingsLib/ActionBarShadow/src/com/android/settingslib/widget/ActionBarShadowController.java" + line="81" + column="25"/> + </issue> + + <issue + id="NewApi" + message="Call requires API level 23 (current min is 21): `android.view.View#setOnScrollChangeListener`" + errorLine1=" mScrollView.setOnScrollChangeListener(null);" + errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~"> + <location + file="frameworks/base/packages/SettingsLib/ActionBarShadow/src/com/android/settingslib/widget/ActionBarShadowController.java" + line="88" + column="21"/> + </issue> + + <issue + id="NewApi" + message="Class requires API level 23 (current min is 21): `android.view.View.OnScrollChangeListener`" + errorLine1=" final class ScrollChangeWatcher implements View.OnScrollChangeListener {" + errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~"> + <location + file="frameworks/base/packages/SettingsLib/ActionBarShadow/src/com/android/settingslib/widget/ActionBarShadowController.java" + line="95" + column="48"/> + </issue> + +</issues> diff --git a/packages/SettingsLib/ActionButtonsPreference/lint-baseline.xml b/packages/SettingsLib/ActionButtonsPreference/lint-baseline.xml new file mode 100644 index 000000000000..a19f7afbb5f8 --- /dev/null +++ b/packages/SettingsLib/ActionButtonsPreference/lint-baseline.xml @@ -0,0 +1,26 @@ +<?xml version="1.0" encoding="UTF-8"?> +<issues format="5" by="lint 4.1.0" client="cli" variant="all" version="4.1.0"> + + <issue + id="NewApi" + message="`android:Widget.DeviceDefault.Button.Borderless.Colored` requires API level 28 (current min is 21)" + errorLine1=" <style name="SettingsActionButton" parent="android:Widget.DeviceDefault.Button.Borderless.Colored">" + errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"> + <location + file="frameworks/base/packages/SettingsLib/ActionButtonsPreference/res/values/styles.xml" + line="19" + column="40"/> + </issue> + + <issue + id="NewApi" + message="`android:drawableTint` requires API level 23 (current min is 21)" + errorLine1=" <item name="android:drawableTint">@*android:color/btn_colored_borderless_text_material</item>" + errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~"> + <location + file="frameworks/base/packages/SettingsLib/ActionButtonsPreference/res/values/styles.xml" + line="21" + column="15"/> + </issue> + +</issues> diff --git a/packages/SettingsLib/AdaptiveIcon/lint-baseline.xml b/packages/SettingsLib/AdaptiveIcon/lint-baseline.xml new file mode 100644 index 000000000000..01a0495f417d --- /dev/null +++ b/packages/SettingsLib/AdaptiveIcon/lint-baseline.xml @@ -0,0 +1,81 @@ +<?xml version="1.0" encoding="UTF-8"?> +<issues format="5" by="lint 4.1.0" client="cli" variant="all" version="4.1.0"> + + <issue + id="NewApi" + message="Call requires API level 23 (current min is 21): `android.content.res.Resources#getColor`" + errorLine1=" .getColor(colorRes, null /* theme */);" + errorLine2=" ~~~~~~~~"> + <location + file="frameworks/base/packages/SettingsLib/AdaptiveIcon/src/com/android/settingslib/widget/AdaptiveIcon.java" + line="75" + column="34"/> + </issue> + + <issue + id="NewApi" + message="Call requires API level 23 (current min is 21): `android.content.Context#getColor`" + errorLine1=" setBackgroundColor(context.getColor(R.color.homepage_generic_icon_background));" + errorLine2=" ~~~~~~~~"> + <location + file="frameworks/base/packages/SettingsLib/AdaptiveIcon/src/com/android/settingslib/widget/AdaptiveIcon.java" + line="87" + column="36"/> + </issue> + + <issue + id="NewApi" + message="Class requires API level 23 (current min is 21): `android.graphics.drawable.DrawableWrapper`" + errorLine1="public class AdaptiveOutlineDrawable extends DrawableWrapper {" + errorLine2=" ~~~~~~~~~~~~~~~"> + <location + file="frameworks/base/packages/SettingsLib/AdaptiveIcon/src/com/android/settingslib/widget/AdaptiveOutlineDrawable.java" + line="46" + column="46"/> + </issue> + + <issue + id="NewApi" + message="Call requires API level 23 (current min is 21): `new android.graphics.drawable.DrawableWrapper`" + errorLine1=" super(new AdaptiveIconShapeDrawable(resources));" + errorLine2=" ~~~~~"> + <location + file="frameworks/base/packages/SettingsLib/AdaptiveIcon/src/com/android/settingslib/widget/AdaptiveOutlineDrawable.java" + line="67" + column="9"/> + </issue> + + <issue + id="NewApi" + message="Call requires API level 23 (current min is 21): `new android.graphics.drawable.DrawableWrapper`" + errorLine1=" super(new AdaptiveIconShapeDrawable(resources));" + errorLine2=" ~~~~~"> + <location + file="frameworks/base/packages/SettingsLib/AdaptiveIcon/src/com/android/settingslib/widget/AdaptiveOutlineDrawable.java" + line="74" + column="9"/> + </issue> + + <issue + id="NewApi" + message="Call requires API level 23 (current min is 21): `android.graphics.drawable.DrawableWrapper#getDrawable`" + errorLine1=" getDrawable().setTint(Color.WHITE);" + errorLine2=" ~~~~~~~~~~~"> + <location + file="frameworks/base/packages/SettingsLib/AdaptiveIcon/src/com/android/settingslib/widget/AdaptiveOutlineDrawable.java" + line="82" + column="9"/> + </issue> + + <issue + id="NewApi" + message="Call requires API level 23 (current min is 21): `android.content.res.Resources#getColor`" + errorLine1=" return resources.getColor(resId, /* theme */ null);" + errorLine2=" ~~~~~~~~"> + <location + file="frameworks/base/packages/SettingsLib/AdaptiveIcon/src/com/android/settingslib/widget/AdaptiveOutlineDrawable.java" + line="107" + column="26"/> + </issue> + +</issues> diff --git a/packages/SettingsLib/BarChartPreference/lint-baseline.xml b/packages/SettingsLib/BarChartPreference/lint-baseline.xml new file mode 100644 index 000000000000..f1043bb62fe1 --- /dev/null +++ b/packages/SettingsLib/BarChartPreference/lint-baseline.xml @@ -0,0 +1,15 @@ +<?xml version="1.0" encoding="UTF-8"?> +<issues format="5" by="lint 4.1.0" client="cli" variant="all" version="4.1.0"> + + <issue + id="NewApi" + message="`@android:style/Widget.DeviceDefault.Button.Borderless.Colored` requires API level 28 (current min is 21)" + errorLine1=" parent="@android:style/Widget.DeviceDefault.Button.Borderless.Colored">" + errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"> + <location + file="frameworks/base/packages/SettingsLib/BarChartPreference/res/values/styles.xml" + line="35" + column="12"/> + </issue> + +</issues> diff --git a/packages/SettingsLib/HelpUtils/lint-baseline.xml b/packages/SettingsLib/HelpUtils/lint-baseline.xml new file mode 100644 index 000000000000..940f027295a7 --- /dev/null +++ b/packages/SettingsLib/HelpUtils/lint-baseline.xml @@ -0,0 +1,15 @@ +<?xml version="1.0" encoding="UTF-8"?> +<issues format="5" by="lint 4.1.0" client="cli" variant="all" version="4.1.0"> + + <issue + id="NewApi" + message="Call requires API level 28 (current min is 21): `android.content.pm.PackageInfo#getLongVersionCode`" + errorLine1=" sCachedVersionCode = Long.toString(info.getLongVersionCode());" + errorLine2=" ~~~~~~~~~~~~~~~~~~"> + <location + file="frameworks/base/packages/SettingsLib/HelpUtils/src/com/android/settingslib/HelpUtils.java" + line="239" + column="57"/> + </issue> + +</issues> diff --git a/packages/SettingsLib/ProgressBar/lint-baseline.xml b/packages/SettingsLib/ProgressBar/lint-baseline.xml new file mode 100644 index 000000000000..03d0f3f43986 --- /dev/null +++ b/packages/SettingsLib/ProgressBar/lint-baseline.xml @@ -0,0 +1,15 @@ +<?xml version="1.0" encoding="UTF-8"?> +<issues format="5" by="lint 4.1.0" client="cli" variant="all" version="4.1.0"> + + <issue + id="NewApi" + message="`?android:attr/colorSecondary` requires API level 25 (current min is 21)" + errorLine1=" android:background="?android:attr/colorSecondary" />" + errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"> + <location + file="frameworks/base/packages/SettingsLib/ProgressBar/res/layout/progress_header.xml" + line="27" + column="9"/> + </issue> + +</issues> diff --git a/packages/SettingsLib/RestrictedLockUtils/lint-baseline.xml b/packages/SettingsLib/RestrictedLockUtils/lint-baseline.xml new file mode 100644 index 000000000000..173c7353ae8c --- /dev/null +++ b/packages/SettingsLib/RestrictedLockUtils/lint-baseline.xml @@ -0,0 +1,26 @@ +<?xml version="1.0" encoding="UTF-8"?> +<issues format="5" by="lint 4.1.0" client="cli" variant="all" version="4.1.0"> + + <issue + id="NewApi" + message="Call requires API level 23 (current min is 21): `android.content.Context#getSystemService`" + errorLine1=" ComponentName adminComponent = userContext.getSystemService(" + errorLine2=" ~~~~~~~~~~~~~~~~"> + <location + file="frameworks/base/packages/SettingsLib/RestrictedLockUtils/src/com/android/settingslib/RestrictedLockUtils.java" + line="59" + column="52"/> + </issue> + + <issue + id="NewApi" + message="Call requires API level 23 (current min is 21): `android.content.Context#getSystemService`" + errorLine1=" UserManager um = context.getSystemService(UserManager.class);" + errorLine2=" ~~~~~~~~~~~~~~~~"> + <location + file="frameworks/base/packages/SettingsLib/RestrictedLockUtils/src/com/android/settingslib/RestrictedLockUtils.java" + line="101" + column="34"/> + </issue> + +</issues> diff --git a/packages/SettingsLib/SettingsSpinner/lint-baseline.xml b/packages/SettingsLib/SettingsSpinner/lint-baseline.xml new file mode 100644 index 000000000000..ae1ed38e9288 --- /dev/null +++ b/packages/SettingsLib/SettingsSpinner/lint-baseline.xml @@ -0,0 +1,15 @@ +<?xml version="1.0" encoding="UTF-8"?> +<issues format="5" by="lint 4.1.0" client="cli" variant="all" version="4.1.0"> + + <issue + id="NewApi" + message="Call requires API level 23 (current min is 21): `new android.widget.Spinner`" + errorLine1=" super(context, attrs, defStyleAttr, defStyleRes, mode, null);" + errorLine2=" ~~~~~"> + <location + file="frameworks/base/packages/SettingsLib/SettingsSpinner/src/com/android/settingslib/widget/settingsspinner/SettingsSpinner.java" + line="122" + column="9"/> + </issue> + +</issues> diff --git a/packages/SettingsLib/Tile/lint-baseline.xml b/packages/SettingsLib/Tile/lint-baseline.xml new file mode 100644 index 000000000000..2b093ddfbc24 --- /dev/null +++ b/packages/SettingsLib/Tile/lint-baseline.xml @@ -0,0 +1,81 @@ +<?xml version="1.0" encoding="UTF-8"?> +<issues format="5" by="lint 4.1.0" client="cli" variant="all" version="4.1.0"> + + <issue + id="NewApi" + message="Call requires API level 24 (current min is 21): `java.lang.Iterable#forEach`" + errorLine1=" controllers.forEach(controller -> {" + errorLine2=" ~~~~~~~"> + <location + file="frameworks/base/packages/SettingsLib/Tile/src/com/android/settingslib/drawer/SwitchesProvider.java" + line="79" + column="21"/> + </issue> + + <issue + id="NewApi" + message="Call requires API level 29 (current min is 21): `android.os.Parcel#readBoolean`" + errorLine1=" final boolean isProviderTile = in.readBoolean();" + errorLine2=" ~~~~~~~~~~~"> + <location + file="frameworks/base/packages/SettingsLib/Tile/src/com/android/settingslib/drawer/Tile.java" + line="83" + column="43"/> + </issue> + + <issue + id="NewApi" + message="Call requires API level 29 (current min is 21): `android.os.Parcel#writeBoolean`" + errorLine1=" dest.writeBoolean(this instanceof ProviderTile);" + errorLine2=" ~~~~~~~~~~~~"> + <location + file="frameworks/base/packages/SettingsLib/Tile/src/com/android/settingslib/drawer/Tile.java" + line="102" + column="14"/> + </issue> + + <issue + id="NewApi" + message="Call requires API level 23 (current min is 21): `android.graphics.drawable.Icon#createWithResource`" + errorLine1=" final Icon icon = Icon.createWithResource(componentInfo.packageName, iconResId);" + errorLine2=" ~~~~~~~~~~~~~~~~~~"> + <location + file="frameworks/base/packages/SettingsLib/Tile/src/com/android/settingslib/drawer/Tile.java" + line="314" + column="36"/> + </issue> + + <issue + id="NewApi" + message="Call requires API level 23 (current min is 21): `android.graphics.drawable.Icon#setTint`" + errorLine1=" icon.setTint(tintColor);" + errorLine2=" ~~~~~~~"> + <location + file="frameworks/base/packages/SettingsLib/Tile/src/com/android/settingslib/drawer/Tile.java" + line="320" + column="22"/> + </issue> + + <issue + id="NewApi" + message="Call requires API level 29 (current min is 21): `android.os.Parcel#readBoolean`" + errorLine1=" final boolean isProviderTile = source.readBoolean();" + errorLine2=" ~~~~~~~~~~~"> + <location + file="frameworks/base/packages/SettingsLib/Tile/src/com/android/settingslib/drawer/Tile.java" + line="364" + column="51"/> + </issue> + + <issue + id="NewApi" + message="Call requires API level R (current min is 21): `android.content.Context#getAttributionTag`" + errorLine1=" return provider.call(context.getPackageName(), context.getAttributionTag()," + errorLine2=" ~~~~~~~~~~~~~~~~~"> + <location + file="frameworks/base/packages/SettingsLib/Tile/src/com/android/settingslib/drawer/TileUtils.java" + line="558" + column="68"/> + </issue> + +</issues> diff --git a/packages/SettingsLib/Utils/lint-baseline.xml b/packages/SettingsLib/Utils/lint-baseline.xml new file mode 100644 index 000000000000..93cf3cc4d5d6 --- /dev/null +++ b/packages/SettingsLib/Utils/lint-baseline.xml @@ -0,0 +1,15 @@ +<?xml version="1.0" encoding="UTF-8"?> +<issues format="5" by="lint 4.1.0" client="cli" variant="all" version="4.1.0"> + + <issue + id="NewApi" + message="Call requires API level 23 (current min is 21): `android.content.Context#getSystemService`" + errorLine1=" return context.getSystemService(UserManager.class).isManagedProfile(userId)" + errorLine2=" ~~~~~~~~~~~~~~~~"> + <location + file="frameworks/base/packages/SettingsLib/Utils/src/com/android/settingslib/utils/applications/AppUtils.java" + line="55" + column="24"/> + </issue> + +</issues> diff --git a/packages/SettingsLib/lint-baseline.xml b/packages/SettingsLib/lint-baseline.xml new file mode 100644 index 000000000000..403de43e9fe6 --- /dev/null +++ b/packages/SettingsLib/lint-baseline.xml @@ -0,0 +1,4118 @@ +<?xml version="1.0" encoding="UTF-8"?> +<issues format="5" by="lint 4.1.0" client="cli" variant="all" version="4.1.0"> + + <issue + id="NewApi" + message="Call requires API level 23 (current min is 21): `android.content.Context#getSystemService`" + errorLine1=" return mContext.getSystemService(UserManager.class).isAdminUser();" + errorLine2=" ~~~~~~~~~~~~~~~~"> + <location + file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/development/AbstractEnableAdbPreferenceController.java" + line="63" + column="25"/> + </issue> + + <issue + id="NewApi" + message="Call requires API level 23 (current min is 21): `android.content.Context#getSystemService`" + errorLine1=" mContext.getSystemService(CarrierConfigManager.class);" + errorLine2=" ~~~~~~~~~~~~~~~~"> + <location + file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/deviceinfo/AbstractImsStatusPreferenceController.java" + line="74" + column="26"/> + </issue> + + <issue + id="NewApi" + message="Class requires API level 23 (current min is 21): `android.telephony.CarrierConfigManager`" + errorLine1=" mContext.getSystemService(CarrierConfigManager.class);" + errorLine2=" ~~~~~~~~~~~~~~~~~~~~"> + <location + file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/deviceinfo/AbstractImsStatusPreferenceController.java" + line="74" + column="43"/> + </issue> + + <issue + id="NewApi" + message="Call requires API level 24 (current min is 21): `android.telephony.SubscriptionManager#getDefaultDataSubscriptionId`" + errorLine1=" final int subId = SubscriptionManager.getDefaultDataSubscriptionId();" + errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~"> + <location + file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/deviceinfo/AbstractImsStatusPreferenceController.java" + line="75" + column="47"/> + </issue> + + <issue + id="NewApi" + message="Call requires API level 23 (current min is 21): `android.telephony.CarrierConfigManager#getConfigForSubId`" + errorLine1=" config = configManager.getConfigForSubId(subId);" + errorLine2=" ~~~~~~~~~~~~~~~~~"> + <location + file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/deviceinfo/AbstractImsStatusPreferenceController.java" + line="78" + column="36"/> + </issue> + + <issue + id="NewApi" + message="Call requires API level 22 (current min is 21): `android.os.BaseBundle#getBoolean`" + errorLine1=" return config != null && config.getBoolean(" + errorLine2=" ~~~~~~~~~~"> + <location + file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/deviceinfo/AbstractImsStatusPreferenceController.java" + line="80" + column="41"/> + </issue> + + <issue + id="NewApi" + message="Call requires API level 24 (current min is 21): `android.telephony.SubscriptionManager#getDefaultDataSubscriptionId`" + errorLine1=" final int subId = SubscriptionManager.getDefaultDataSubscriptionId();" + errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~"> + <location + file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/deviceinfo/AbstractImsStatusPreferenceController.java" + line="106" + column="47"/> + </issue> + + <issue + id="NewApi" + message="Call requires API level 29 (current min is 21): `android.telephony.SubscriptionManager#isValidSubscriptionId`" + errorLine1=" if (!SubscriptionManager.isValidSubscriptionId(subId)) {" + errorLine2=" ~~~~~~~~~~~~~~~~~~~~~"> + <location + file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/deviceinfo/AbstractImsStatusPreferenceController.java" + line="107" + column="34"/> + </issue> + + <issue + id="NewApi" + message="Call requires API level R (current min is 21): `android.telephony.ims.ImsMmTelManager#getRegistrationState`" + errorLine1=" imsMmTelManager.getRegistrationState(executors, stateCallback);" + errorLine2=" ~~~~~~~~~~~~~~~~~~~~"> + <location + file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/deviceinfo/AbstractImsStatusPreferenceController.java" + line="116" + column="29"/> + </issue> + + <issue + id="NewApi" + message="Call requires API level 23 (current min is 21): `android.content.Context#getSystemService`" + errorLine1=" mCM = context.getSystemService(ConnectivityManager.class);" + errorLine2=" ~~~~~~~~~~~~~~~~"> + <location + file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/deviceinfo/AbstractIpAddressPreferenceController.java" + line="54" + column="23"/> + </issue> + + <issue + id="NewApi" + message="Call requires API level 23 (current min is 21): `android.net.ConnectivityManager#getActiveNetwork`" + errorLine1=" LinkProperties prop = cm.getLinkProperties(cm.getActiveNetwork());" + errorLine2=" ~~~~~~~~~~~~~~~~"> + <location + file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/deviceinfo/AbstractIpAddressPreferenceController.java" + line="96" + column="55"/> + </issue> + + <issue + id="NewApi" + message="Call requires API level 26 (current min is 21): `android.os.Build#getSerial`" + errorLine1=" this(context, Build.getSerial());" + errorLine2=" ~~~~~~~~~"> + <location + file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/deviceinfo/AbstractSerialNumberPreferenceController.java" + line="40" + column="29"/> + </issue> + + <issue + id="NewApi" + message="Call requires API level 23 (current min is 21): `android.content.Context#getSystemService`" + errorLine1=" return mContext.getSystemService(UserManager.class).isAdminUser()" + errorLine2=" ~~~~~~~~~~~~~~~~"> + <location + file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/deviceinfo/AbstractSimStatusImeiInfoPreferenceController.java" + line="33" + column="25"/> + </issue> + + <issue + id="NewApi" + message="Call requires API level 23 (current min is 21): `android.content.Context#getSystemService`" + errorLine1=" mWifiManager = context.getSystemService(WifiManager.class);" + errorLine2=" ~~~~~~~~~~~~~~~~"> + <location + file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/deviceinfo/AbstractWifiMacAddressPreferenceController.java" + line="56" + column="32"/> + </issue> + + <issue + id="NewApi" + message="Call requires API level 23 (current min is 21): `new android.util.ArraySet`" + errorLine1=" private final ArraySet<ScanResult> mScanResults = new ArraySet<>();" + errorLine2=" ~~~~~~~~~~~~~~"> + <location + file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/wifi/AccessPoint.java" + line="167" + column="55"/> + </issue> + + <issue + id="NewApi" + message="Call requires API level 23 (current min is 21): `new android.util.ArraySet`" + errorLine1=" private final ArraySet<ScanResult> mExtraScanResults = new ArraySet<>();" + errorLine2=" ~~~~~~~~~~~~~~"> + <location + file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/wifi/AccessPoint.java" + line="174" + column="60"/> + </issue> + + <issue + id="NewApi" + message="Call requires API level R (current min is 21): `android.net.wifi.hotspot2.PasspointConfiguration#getUniqueId`" + errorLine1=" mPasspointUniqueId = config.getUniqueId();" + errorLine2=" ~~~~~~~~~~~"> + <location + file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/wifi/AccessPoint.java" + line="368" + column="37"/> + </issue> + + <issue + id="NewApi" + message="Call requires API level 26 (current min is 21): `android.net.wifi.hotspot2.PasspointConfiguration#getHomeSp`" + errorLine1=" mFqdn = config.getHomeSp().getFqdn();" + errorLine2=" ~~~~~~~~~"> + <location + file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/wifi/AccessPoint.java" + line="369" + column="24"/> + </issue> + + <issue + id="NewApi" + message="Call requires API level 26 (current min is 21): `android.net.wifi.hotspot2.pps.HomeSp#getFqdn`" + errorLine1=" mFqdn = config.getHomeSp().getFqdn();" + errorLine2=" ~~~~~~~"> + <location + file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/wifi/AccessPoint.java" + line="369" + column="36"/> + </issue> + + <issue + id="NewApi" + message="Call requires API level 26 (current min is 21): `android.net.wifi.hotspot2.PasspointConfiguration#getHomeSp`" + errorLine1=" mProviderFriendlyName = config.getHomeSp().getFriendlyName();" + errorLine2=" ~~~~~~~~~"> + <location + file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/wifi/AccessPoint.java" + line="370" + column="40"/> + </issue> + + <issue + id="NewApi" + message="Call requires API level 26 (current min is 21): `android.net.wifi.hotspot2.pps.HomeSp#getFriendlyName`" + errorLine1=" mProviderFriendlyName = config.getHomeSp().getFriendlyName();" + errorLine2=" ~~~~~~~~~~~~~~~"> + <location + file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/wifi/AccessPoint.java" + line="370" + column="52"/> + </issue> + + <issue + id="NewApi" + message="Call requires API level R (current min is 21): `android.net.wifi.hotspot2.PasspointConfiguration#getSubscriptionExpirationTimeMillis`" + errorLine1=" mSubscriptionExpirationTimeInMillis = config.getSubscriptionExpirationTimeMillis();" + errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"> + <location + file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/wifi/AccessPoint.java" + line="371" + column="54"/> + </issue> + + <issue + id="NewApi" + message="Call requires API level R (current min is 21): `android.net.wifi.hotspot2.PasspointConfiguration#isOsuProvisioned`" + errorLine1=" if (config.isOsuProvisioned()) {" + errorLine2=" ~~~~~~~~~~~~~~~~"> + <location + file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/wifi/AccessPoint.java" + line="372" + column="20"/> + </issue> + + <issue + id="NewApi" + message="Call requires API level R (current min is 21): `android.net.wifi.WifiConfiguration#getKey`" + errorLine1=" mPasspointUniqueId = config.getKey();" + errorLine2=" ~~~~~~"> + <location + file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/wifi/AccessPoint.java" + line="389" + column="37"/> + </issue> + + <issue + id="NewApi" + message="Call requires API level R (current min is 21): `android.net.wifi.WifiManager#calculateSignalLevel`" + errorLine1=" int difference = wifiManager.calculateSignalLevel(other.mRssi)" + errorLine2=" ~~~~~~~~~~~~~~~~~~~~"> + <location + file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/wifi/AccessPoint.java" + line="470" + column="38"/> + </issue> + + <issue + id="NewApi" + message="Call requires API level R (current min is 21): `android.net.wifi.WifiManager#calculateSignalLevel`" + errorLine1=" - wifiManager.calculateSignalLevel(mRssi);" + errorLine2=" ~~~~~~~~~~~~~~~~~~~~"> + <location + file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/wifi/AccessPoint.java" + line="471" + column="31"/> + </issue> + + <issue + id="NewApi" + message="The type of the for loop iterated value is android.util.ArraySet<android.net.wifi.ScanResult>, which requires API level 23 (current min is 21)" + errorLine1=" for (ScanResult result : mScanResults) {" + errorLine2=" ~~~~~~~~~~~~"> + <location + file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/wifi/AccessPoint.java" + line="578" + column="38"/> + </issue> + + <issue + id="NewApi" + message="The type of the for loop iterated value is android.util.ArraySet<android.net.wifi.ScanResult>, which requires API level 23 (current min is 21)" + errorLine1=" for (ScanResult result : mScanResults) {" + errorLine2=" ~~~~~~~~~~~~"> + <location + file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/wifi/AccessPoint.java" + line="667" + column="42"/> + </issue> + + <issue + id="NewApi" + message="Call requires API level 23 (current min is 21): `android.net.wifi.WifiConfiguration#isPasspoint`" + errorLine1=" if (config.isPasspoint()) {" + errorLine2=" ~~~~~~~~~~~"> + <location + file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/wifi/AccessPoint.java" + line="695" + column="20"/> + </issue> + + <issue + id="NewApi" + message="Call requires API level R (current min is 21): `android.net.wifi.WifiConfiguration#getKey`" + errorLine1=" return getKey(config.getKey());" + errorLine2=" ~~~~~~"> + <location + file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/wifi/AccessPoint.java" + line="696" + column="34"/> + </issue> + + <issue + id="NewApi" + message="Call requires API level 29 (current min is 21): `android.net.wifi.WifiManager#isWpa3SaeSupported`" + errorLine1=" if (otherApSecurity == SECURITY_SAE && getWifiManager().isWpa3SaeSupported()) {" + errorLine2=" ~~~~~~~~~~~~~~~~~~"> + <location + file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/wifi/AccessPoint.java" + line="755" + column="69"/> + </issue> + + <issue + id="NewApi" + message="Call requires API level 29 (current min is 21): `android.net.wifi.WifiManager#isEnhancedOpenSupported`" + errorLine1=" if (otherApSecurity == SECURITY_OWE && getWifiManager().isEnhancedOpenSupported()) {" + errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~"> + <location + file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/wifi/AccessPoint.java" + line="768" + column="69"/> + </issue> + + <issue + id="NewApi" + message="Call requires API level 23 (current min is 21): `android.net.wifi.WifiConfiguration#isPasspoint`" + errorLine1=" if (config.isPasspoint()) {" + errorLine2=" ~~~~~~~~~~~"> + <location + file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/wifi/AccessPoint.java" + line="784" + column="20"/> + </issue> + + <issue + id="NewApi" + message="Call requires API level R (current min is 21): `android.net.wifi.WifiConfiguration#getKey`" + errorLine1=" return (isPasspoint() && config.getKey().equals(mConfig.getKey()));" + errorLine2=" ~~~~~~"> + <location + file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/wifi/AccessPoint.java" + line="785" + column="45"/> + </issue> + + <issue + id="NewApi" + message="Call requires API level R (current min is 21): `android.net.wifi.WifiConfiguration#getKey`" + errorLine1=" return (isPasspoint() && config.getKey().equals(mConfig.getKey()));" + errorLine2=" ~~~~~~"> + <location + file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/wifi/AccessPoint.java" + line="785" + column="69"/> + </issue> + + <issue + id="NewApi" + message="Call requires API level 29 (current min is 21): `android.net.wifi.WifiManager#isWpa3SaeSupported`" + errorLine1=" if (configSecurity == SECURITY_SAE && getWifiManager().isWpa3SaeSupported()) {" + errorLine2=" ~~~~~~~~~~~~~~~~~~"> + <location + file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/wifi/AccessPoint.java" + line="795" + column="68"/> + </issue> + + <issue + id="NewApi" + message="Call requires API level 29 (current min is 21): `android.net.wifi.WifiManager#isEnhancedOpenSupported`" + errorLine1=" if (configSecurity == SECURITY_OWE && getWifiManager().isEnhancedOpenSupported()) {" + errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~"> + <location + file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/wifi/AccessPoint.java" + line="803" + column="68"/> + </issue> + + <issue + id="NewApi" + message="Call requires API level 23 (current min is 21): `android.net.wifi.WifiConfiguration#isPasspoint`" + errorLine1=" if (!config.isPasspoint() && !isSameSsidOrBssid(wifiInfo)) {" + errorLine2=" ~~~~~~~~~~~"> + <location + file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/wifi/AccessPoint.java" + line="817" + column="21"/> + </issue> + + <issue + id="NewApi" + message="Call requires API level 29 (current min is 21): `android.net.wifi.WifiManager#isWpa3SaeSupported`" + errorLine1=" && getWifiManager().isWpa3SaeSupported()) {" + errorLine2=" ~~~~~~~~~~~~~~~~~~"> + <location + file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/wifi/AccessPoint.java" + line="838" + column="41"/> + </issue> + + <issue + id="NewApi" + message="Call requires API level 29 (current min is 21): `android.net.wifi.WifiManager#isEnhancedOpenSupported`" + errorLine1=" if (scanResultSccurity == SECURITY_OWE && getWifiManager().isEnhancedOpenSupported()) {" + errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~"> + <location + file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/wifi/AccessPoint.java" + line="852" + column="72"/> + </issue> + + <issue + id="NewApi" + message="Call requires API level R (current min is 21): `android.net.wifi.WifiManager#calculateSignalLevel`" + errorLine1=" return getWifiManager().calculateSignalLevel(mRssi);" + errorLine2=" ~~~~~~~~~~~~~~~~~~~~"> + <location + file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/wifi/AccessPoint.java" + line="892" + column="33"/> + </issue> + + <issue + id="NewApi" + message="Call requires API level 23 (current min is 21): `new android.util.ArraySet`" + errorLine1=" Set<ScanResult> allScans = new ArraySet<>();" + errorLine2=" ~~~~~~~~~~~~~~"> + <location + file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/wifi/AccessPoint.java" + line="905" + column="36"/> + </issue> + + <issue + id="NewApi" + message="Cast from `ArraySet` to `Set` requires API level 23 (current min is 21)" + errorLine1=" Set<ScanResult> allScans = new ArraySet<>();" + errorLine2=" ~~~~~~~~~~~~~~~~"> + <location + file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/wifi/AccessPoint.java" + line="905" + column="36"/> + </issue> + + <issue + id="NewApi" + message="Cast from `ArraySet` to `Collection` requires API level 23 (current min is 21)" + errorLine1=" allScans.addAll(mScanResults);" + errorLine2=" ~~~~~~~~~~~~"> + <location + file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/wifi/AccessPoint.java" + line="907" + column="29"/> + </issue> + + <issue + id="NewApi" + message="Cast from `ArraySet` to `Collection` requires API level 23 (current min is 21)" + errorLine1=" allScans.addAll(mExtraScanResults);" + errorLine2=" ~~~~~~~~~~~~~~~~~"> + <location + file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/wifi/AccessPoint.java" + line="908" + column="29"/> + </issue> + + <issue + id="NewApi" + message="The type of the for loop iterated value is android.util.ArraySet<android.net.wifi.ScanResult>, which requires API level 23 (current min is 21)" + errorLine1=" for (ScanResult result : mScanResults) {" + errorLine2=" ~~~~~~~~~~~~"> + <location + file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/wifi/AccessPoint.java" + line="934" + column="38"/> + </issue> + + <issue + id="NewApi" + message="Call requires API level 23 (current min is 21): `android.net.wifi.WifiConfiguration#isPasspoint`" + errorLine1=" if (mConfig != null && mConfig.isPasspoint()) {" + errorLine2=" ~~~~~~~~~~~"> + <location + file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/wifi/AccessPoint.java" + line="1069" + column="40"/> + </issue> + + <issue + id="NewApi" + message="Field requires API level 23 (current min is 21): `android.net.wifi.WifiConfiguration#providerFriendlyName`" + errorLine1=" return mConfig.providerFriendlyName;" + errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~"> + <location + file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/wifi/AccessPoint.java" + line="1070" + column="20"/> + </issue> + + <issue + id="NewApi" + message="Field requires API level 23 (current min is 21): `android.net.wifi.WifiConfiguration#providerFriendlyName`" + errorLine1=" return mConfig.providerFriendlyName;" + errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~"> + <location + file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/wifi/AccessPoint.java" + line="1121" + column="20"/> + </issue> + + <issue + id="NewApi" + message="Call requires API level 23 (current min is 21): `android.net.wifi.WifiConfiguration#isPasspoint`" + errorLine1=" return mConfig != null && mConfig.isPasspoint();" + errorLine2=" ~~~~~~~~~~~"> + <location + file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/wifi/AccessPoint.java" + line="1266" + column="43"/> + </issue> + + <issue + id="NewApi" + message="Call requires API level 28 (current min is 21): `android.content.Context#getMainExecutor`" + errorLine1=" mContext.getMainExecutor()," + errorLine2=" ~~~~~~~~~~~~~~~"> + <location + file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/wifi/AccessPoint.java" + line="1315" + column="26"/> + </issue> + + <issue + id="NewApi" + message="Call requires API level 29 (current min is 21): `android.net.wifi.WifiInfo#getPasspointFqdn`" + errorLine1=" && TextUtils.equals(info.getPasspointFqdn(), mConfig.FQDN)" + errorLine2=" ~~~~~~~~~~~~~~~~"> + <location + file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/wifi/AccessPoint.java" + line="1332" + column="46"/> + </issue> + + <issue + id="NewApi" + message="Call requires API level 29 (current min is 21): `android.net.wifi.WifiInfo#getPasspointProviderFriendlyName`" + errorLine1=" && TextUtils.equals(info.getPasspointProviderFriendlyName()," + errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"> + <location + file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/wifi/AccessPoint.java" + line="1333" + column="46"/> + </issue> + + <issue + id="NewApi" + message="Field requires API level 23 (current min is 21): `android.net.wifi.WifiConfiguration#providerFriendlyName`" + errorLine1=" mConfig.providerFriendlyName));" + errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~"> + <location + file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/wifi/AccessPoint.java" + line="1334" + column="21"/> + </issue> + + <issue + id="NewApi" + message="Call requires API level 23 (current min is 21): `android.content.Context#getSystemService`" + errorLine1=" final NetworkScoreManager networkScoreManager = context.getSystemService(" + errorLine2=" ~~~~~~~~~~~~~~~~"> + <location + file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/wifi/AccessPoint.java" + line="1654" + column="73"/> + </issue> + + <issue + id="NewApi" + message="Call requires API level 23 (current min is 21): `android.content.Context#getSystemService`" + errorLine1=" WifiManager wifiManager = context.getSystemService(WifiManager.class);" + errorLine2=" ~~~~~~~~~~~~~~~~"> + <location + file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/wifi/AccessPoint.java" + line="1670" + column="47"/> + </issue> + + <issue + id="NewApi" + message="Call requires API level 29 (current min is 21): `android.net.wifi.WifiManager#isWpa3SaeSupported`" + errorLine1=" return wifiManager.isWpa3SaeSupported() ? SECURITY_SAE : SECURITY_PSK;" + errorLine2=" ~~~~~~~~~~~~~~~~~~"> + <location + file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/wifi/AccessPoint.java" + line="1753" + column="32"/> + </issue> + + <issue + id="NewApi" + message="Call requires API level 29 (current min is 21): `android.net.wifi.WifiManager#isEnhancedOpenSupported`" + errorLine1=" return wifiManager.isEnhancedOpenSupported() ? SECURITY_OWE : SECURITY_NONE;" + errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~"> + <location + file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/wifi/AccessPoint.java" + line="1758" + column="32"/> + </issue> + + <issue + id="NewApi" + message="Call requires API level R (current min is 21): `android.net.wifi.hotspot2.PasspointConfiguration#getUniqueId`" + errorLine1=" String uniqueId = passpointConfig.getUniqueId();" + errorLine2=" ~~~~~~~~~~~"> + <location + file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/wifi/AccessPoint.java" + line="1975" + column="47"/> + </issue> + + <issue + id="NewApi" + message="Call requires API level R (current min is 21): `android.net.wifi.WifiConfiguration#getKey`" + errorLine1=" if (TextUtils.equals(config.getKey(), uniqueId)) {" + errorLine2=" ~~~~~~"> + <location + file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/wifi/AccessPoint.java" + line="1979" + column="45"/> + </issue> + + <issue + id="NewApi" + message="Call requires API level 23 (current min is 21): `android.content.Context#getSystemService`" + errorLine1=" final AccessibilityManager accessibilityManager = ctx.getSystemService(" + errorLine2=" ~~~~~~~~~~~~~~~~"> + <location + file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/accessibility/AccessibilityButtonHelper.java" + line="37" + column="63"/> + </issue> + + <issue + id="NewApi" + message="Call requires API level 23 (current min is 21): `new android.util.ArraySet`" + errorLine1=" enabledServices = new ArraySet<>(1);" + errorLine2=" ~~~~~~~~~~~~~~"> + <location + file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/accessibility/AccessibilityUtils.java" + line="131" + column="31"/> + </issue> + + <issue + id="NewApi" + message="Cast from `ArraySet` to `Set` requires API level 23 (current min is 21)" + errorLine1=" enabledServices = new ArraySet<>(1);" + errorLine2=" ~~~~~~~~~~~~~~~~~"> + <location + file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/accessibility/AccessibilityUtils.java" + line="131" + column="31"/> + </issue> + + <issue + id="NewApi" + message="Call requires API level 23 (current min is 21): `android.content.Context#getSystemService`" + errorLine1=" return mContext.getSystemService(UserManager.class);" + errorLine2=" ~~~~~~~~~~~~~~~~"> + <location + file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/users/AppRestrictionsHelper.java" + line="418" + column="29"/> + </issue> + + <issue + id="NewApi" + message="Call requires API level 29 (current min is 21): `android.content.pm.PackageManager#getModuleInfo`" + errorLine1=" pm.getModuleInfo(packageName, 0 /* flags */);" + errorLine2=" ~~~~~~~~~~~~~"> + <location + file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/applications/AppUtils.java" + line="154" + column="16"/> + </issue> + + <issue + id="NewApi" + message="Call requires API level 23 (current min is 21): `android.content.Context#getSystemService`" + errorLine1=" mUm = mContext.getSystemService(UserManager.class);" + errorLine2=" ~~~~~~~~~~~~~~~~"> + <location + file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/applications/ApplicationsState.java" + line="198" + column="24"/> + </issue> + + <issue + id="NewApi" + message="Call requires API level 23 (current min is 21): `android.content.Context#getSystemService`" + errorLine1=" mStats = mContext.getSystemService(StorageStatsManager.class);" + errorLine2=" ~~~~~~~~~~~~~~~~"> + <location + file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/applications/ApplicationsState.java" + line="199" + column="27"/> + </issue> + + <issue + id="NewApi" + message="Class requires API level 26 (current min is 21): `android.app.usage.StorageStatsManager`" + errorLine1=" mStats = mContext.getSystemService(StorageStatsManager.class);" + errorLine2=" ~~~~~~~~~~~~~~~~~~~"> + <location + file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/applications/ApplicationsState.java" + line="199" + column="44"/> + </issue> + + <issue + id="NewApi" + message="Call requires API level 29 (current min is 21): `android.content.pm.PackageManager#getInstalledModules`" + errorLine1=" final List<ModuleInfo> moduleInfos = mPm.getInstalledModules(0 /* flags */);" + errorLine2=" ~~~~~~~~~~~~~~~~~~~"> + <location + file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/applications/ApplicationsState.java" + line="215" + column="50"/> + </issue> + + <issue + id="NewApi" + message="Call requires API level 29 (current min is 21): `android.content.pm.ModuleInfo#getPackageName`" + errorLine1=" mSystemModules.put(info.getPackageName(), info.isHidden());" + errorLine2=" ~~~~~~~~~~~~~~"> + <location + file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/applications/ApplicationsState.java" + line="217" + column="37"/> + </issue> + + <issue + id="NewApi" + message="Call requires API level 29 (current min is 21): `android.content.pm.ModuleInfo#isHidden`" + errorLine1=" mSystemModules.put(info.getPackageName(), info.isHidden());" + errorLine2=" ~~~~~~~~"> + <location + file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/applications/ApplicationsState.java" + line="217" + column="60"/> + </issue> + + <issue + id="NewApi" + message="Call requires API level 26 (current min is 21): `android.app.usage.StorageStatsManager#queryStatsForPackage`" + errorLine1=" mStats.queryStatsForPackage(" + errorLine2=" ~~~~~~~~~~~~~~~~~~~~"> + <location + file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/applications/ApplicationsState.java" + line="527" + column="48"/> + </issue> + + <issue + id="NewApi" + message="Field requires API level 26 (current min is 21): `android.content.pm.ApplicationInfo#storageUuid`" + errorLine1=" entry.info.storageUuid," + errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~"> + <location + file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/applications/ApplicationsState.java" + line="528" + column="49"/> + </issue> + + <issue + id="NewApi" + message="Field requires API level 26 (current min is 21): `android.content.pm.ApplicationInfo#storageUuid`" + errorLine1=" entry.info.storageUuid.toString(), entry.info.uid);" + errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~"> + <location + file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/applications/ApplicationsState.java" + line="533" + column="49"/> + </issue> + + <issue + id="NewApi" + message="Call requires API level 26 (current min is 21): `android.app.usage.StorageStats#getDataBytes`" + errorLine1=" legacy.dataSize = stats.getDataBytes();" + errorLine2=" ~~~~~~~~~~~~"> + <location + file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/applications/ApplicationsState.java" + line="536" + column="57"/> + </issue> + + <issue + id="NewApi" + message="Call requires API level 26 (current min is 21): `android.app.usage.StorageStats#getCacheBytes`" + errorLine1=" legacy.cacheSize = Math.min(stats.getCacheBytes(), cacheQuota);" + errorLine2=" ~~~~~~~~~~~~~"> + <location + file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/applications/ApplicationsState.java" + line="537" + column="67"/> + </issue> + + <issue + id="NewApi" + message="Field requires API level 26 (current min is 21): `android.content.pm.ApplicationInfo#storageUuid`" + errorLine1=" mCurComputingSizeUuid = entry.info.storageUuid;" + errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~"> + <location + file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/applications/ApplicationsState.java" + line="1287" + column="65"/> + </issue> + + <issue + id="NewApi" + message="Call requires API level 26 (current min is 21): `android.app.usage.StorageStatsManager#queryStatsForPackage`" + errorLine1=" mStats.queryStatsForPackage(" + errorLine2=" ~~~~~~~~~~~~~~~~~~~~"> + <location + file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/applications/ApplicationsState.java" + line="1295" + column="64"/> + </issue> + + <issue + id="NewApi" + message="Call requires API level 26 (current min is 21): `android.app.usage.StorageStats#getDataBytes`" + errorLine1=" legacy.dataSize = stats.getDataBytes();" + errorLine2=" ~~~~~~~~~~~~"> + <location + file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/applications/ApplicationsState.java" + line="1304" + column="73"/> + </issue> + + <issue + id="NewApi" + message="Call requires API level 26 (current min is 21): `android.app.usage.StorageStats#getCacheBytes`" + errorLine1=" legacy.cacheSize = stats.getCacheBytes();" + errorLine2=" ~~~~~~~~~~~~~"> + <location + file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/applications/ApplicationsState.java" + line="1305" + column="74"/> + </issue> + + <issue + id="NewApi" + message="Field requires API level 26 (current min is 21): `android.content.pm.ApplicationInfo#category`" + errorLine1=" || info.info.category == ApplicationInfo.CATEGORY_GAME;" + errorLine2=" ~~~~~~~~~~~~~~~~~~"> + <location + file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/applications/ApplicationsState.java" + line="1927" + column="28"/> + </issue> + + <issue + id="NewApi" + message="Field requires API level 26 (current min is 21): `android.content.pm.ApplicationInfo#category`" + errorLine1=" isMusicApp = entry.info.category == ApplicationInfo.CATEGORY_AUDIO;" + errorLine2=" ~~~~~~~~~~~~~~~~~~~"> + <location + file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/applications/ApplicationsState.java" + line="1986" + column="30"/> + </issue> + + <issue + id="NewApi" + message="Field requires API level 26 (current min is 21): `android.content.pm.ApplicationInfo#category`" + errorLine1=" isMovieApp = entry.info.category == ApplicationInfo.CATEGORY_VIDEO;" + errorLine2=" ~~~~~~~~~~~~~~~~~~~"> + <location + file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/applications/ApplicationsState.java" + line="2001" + column="30"/> + </issue> + + <issue + id="NewApi" + message="Field requires API level 26 (current min is 21): `android.content.pm.ApplicationInfo#category`" + errorLine1=" isPhotosApp = entry.info.category == ApplicationInfo.CATEGORY_IMAGE;" + errorLine2=" ~~~~~~~~~~~~~~~~~~~"> + <location + file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/applications/ApplicationsState.java" + line="2017" + column="39"/> + </issue> + + <issue + id="NewApi" + message="Call requires API level 23 (current min is 21): `android.content.Context#getSystemService`" + errorLine1=" if (context.getSystemService(PowerManager.class).setPowerSaveModeEnabled(enable)) {" + errorLine2=" ~~~~~~~~~~~~~~~~"> + <location + file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/fuelgauge/BatterySaverUtils.java" + line="132" + column="21"/> + </issue> + + <issue + id="NewApi" + message="Call requires API level 23 (current min is 21): `android.content.Context#getColor`" + errorLine1=" context.getColor(R.color.meter_background_color), batteryLevel);" + errorLine2=" ~~~~~~~~"> + <location + file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/graph/BluetoothDeviceLayerDrawable.java" + line="71" + column="25"/> + </issue> + + <issue + id="NewApi" + message="Call requires API level 23 (current min is 21): `android.graphics.drawable.LayerDrawable#setLayerGravity`" + errorLine1=" drawable.setLayerGravity(0 /* index of deviceDrawable */, Gravity.START);" + errorLine2=" ~~~~~~~~~~~~~~~"> + <location + file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/graph/BluetoothDeviceLayerDrawable.java" + line="78" + column="18"/> + </issue> + + <issue + id="NewApi" + message="Call requires API level 23 (current min is 21): `android.graphics.drawable.LayerDrawable#setLayerInsetStart`" + errorLine1=" drawable.setLayerInsetStart(1 /* index of batteryDrawable */," + errorLine2=" ~~~~~~~~~~~~~~~~~~"> + <location + file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/graph/BluetoothDeviceLayerDrawable.java" + line="80" + column="18"/> + </issue> + + <issue + id="NewApi" + message="Call requires API level 23 (current min is 21): `android.graphics.drawable.LayerDrawable#setLayerInsetTop`" + errorLine1=" drawable.setLayerInsetTop(1 /* index of batteryDrawable */," + errorLine2=" ~~~~~~~~~~~~~~~~"> + <location + file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/graph/BluetoothDeviceLayerDrawable.java" + line="82" + column="18"/> + </issue> + + <issue + id="NewApi" + message="Call requires API level R (current min is 21): `android.bluetooth.BluetoothDevice#getAlias`" + errorLine1=" + mDevice.getAlias() + ", newProfileState " + newProfileState);" + errorLine2=" ~~~~~~~~"> + <location + file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDevice.java" + line="155" + column="31"/> + </issue> + + <issue + id="NewApi" + message="Call requires API level R (current min is 21): `android.bluetooth.BluetoothDevice#getAlias`" + errorLine1=" final String aliasName = mDevice.getAlias();" + errorLine2=" ~~~~~~~~"> + <location + file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDevice.java" + line="431" + column="42"/> + </issue> + + <issue + id="NewApi" + message="Call requires API level R (current min is 21): `android.bluetooth.BluetoothDevice#getAlias`" + errorLine1=" return !TextUtils.isEmpty(mDevice.getAlias());" + errorLine2=" ~~~~~~~~"> + <location + file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDevice.java" + line="489" + column="43"/> + </issue> + + <issue + id="NewApi" + message="Call requires API level R (current min is 21): `android.bluetooth.BluetoothDevice#getAlias`" + errorLine1=" Log.d(TAG, "updating profiles for " + mDevice.getAlias());" + errorLine2=" ~~~~~~~~"> + <location + file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDevice.java" + line="638" + column="59"/> + </issue> + + <issue + id="NewApi" + message="Call requires API level R (current min is 21): `android.bluetooth.BluetoothDevice#getAlias`" + errorLine1=" String name = device.getAlias();" + errorLine2=" ~~~~~~~~"> + <location + file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDeviceManager.java" + line="171" + column="30"/> + </issue> + + <issue + id="NewApi" + message="Call requires API level 23 (current min is 21): `android.content.res.Resources#getColor`" + errorLine1=" mImportantConversationColor = context.getResources().getColor(" + errorLine2=" ~~~~~~~~"> + <location + file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/notification/ConversationIconFactory.java" + line="82" + column="62"/> + </issue> + + <issue + id="NewApi" + message="Call requires API level 25 (current min is 21): `android.content.pm.LauncherApps#getShortcutIconDrawable`" + errorLine1=" return mLauncherApps.getShortcutIconDrawable(shortcutInfo, mFillResIconDpi);" + errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~"> + <location + file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/notification/ConversationIconFactory.java" + line="90" + column="30"/> + </issue> + + <issue + id="NewApi" + message="Call requires API level 23 (current min is 21): `android.content.Context#getSystemService`" + errorLine1=" mNetworkStatsManager = context.getSystemService(NetworkStatsManager.class);" + errorLine2=" ~~~~~~~~~~~~~~~~"> + <location + file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/net/DataUsageController.java" + line="75" + column="40"/> + </issue> + + <issue + id="NewApi" + message="Class requires API level 23 (current min is 21): `android.app.usage.NetworkStatsManager`" + errorLine1=" mNetworkStatsManager = context.getSystemService(NetworkStatsManager.class);" + errorLine2=" ~~~~~~~~~~~~~~~~~~~"> + <location + file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/net/DataUsageController.java" + line="75" + column="57"/> + </issue> + + <issue + id="NewApi" + message="Call requires API level 23 (current min is 21): `android.app.usage.NetworkStats.Bucket#getRxBytes`" + errorLine1=" return bucket.getRxBytes() + bucket.getTxBytes();" + errorLine2=" ~~~~~~~~~~"> + <location + file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/net/DataUsageController.java" + line="171" + column="31"/> + </issue> + + <issue + id="NewApi" + message="Call requires API level 23 (current min is 21): `android.app.usage.NetworkStats.Bucket#getTxBytes`" + errorLine1=" return bucket.getRxBytes() + bucket.getTxBytes();" + errorLine2=" ~~~~~~~~~~"> + <location + file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/net/DataUsageController.java" + line="171" + column="53"/> + </issue> + + <issue + id="NewApi" + message="Call requires API level 23 (current min is 21): `android.app.usage.NetworkStats.Bucket#getEndTimeStamp`" + errorLine1=" .append("bucketDuration=").append(bucket.getEndTimeStamp() - bucket.getStartTimeStamp())" + errorLine2=" ~~~~~~~~~~~~~~~"> + <location + file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/net/DataUsageController.java" + line="196" + column="54"/> + </issue> + + <issue + id="NewApi" + message="Call requires API level 23 (current min is 21): `android.app.usage.NetworkStats.Bucket#getStartTimeStamp`" + errorLine1=" .append("bucketDuration=").append(bucket.getEndTimeStamp() - bucket.getStartTimeStamp())" + errorLine2=" ~~~~~~~~~~~~~~~~~"> + <location + file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/net/DataUsageController.java" + line="196" + column="81"/> + </issue> + + <issue + id="NewApi" + message="Call requires API level 23 (current min is 21): `android.app.usage.NetworkStats.Bucket#getStartTimeStamp`" + errorLine1=" .append(",bucketStart=").append(bucket.getStartTimeStamp())" + errorLine2=" ~~~~~~~~~~~~~~~~~"> + <location + file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/net/DataUsageController.java" + line="197" + column="52"/> + </issue> + + <issue + id="NewApi" + message="Call requires API level 23 (current min is 21): `android.app.usage.NetworkStats.Bucket#getRxBytes`" + errorLine1=" .append(",rxBytes=").append(bucket.getRxBytes())" + errorLine2=" ~~~~~~~~~~"> + <location + file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/net/DataUsageController.java" + line="198" + column="48"/> + </issue> + + <issue + id="NewApi" + message="Call requires API level 23 (current min is 21): `android.app.usage.NetworkStats.Bucket#getRxPackets`" + errorLine1=" .append(",rxPackets=").append(bucket.getRxPackets())" + errorLine2=" ~~~~~~~~~~~~"> + <location + file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/net/DataUsageController.java" + line="199" + column="50"/> + </issue> + + <issue + id="NewApi" + message="Call requires API level 23 (current min is 21): `android.app.usage.NetworkStats.Bucket#getTxBytes`" + errorLine1=" .append(",txBytes=").append(bucket.getTxBytes())" + errorLine2=" ~~~~~~~~~~"> + <location + file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/net/DataUsageController.java" + line="200" + column="48"/> + </issue> + + <issue + id="NewApi" + message="Call requires API level 23 (current min is 21): `android.app.usage.NetworkStats.Bucket#getTxPackets`" + errorLine1=" .append(",txPackets=").append(bucket.getTxPackets())" + errorLine2=" ~~~~~~~~~~~~"> + <location + file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/net/DataUsageController.java" + line="201" + column="50"/> + </issue> + + <issue + id="NewApi" + message="Call requires API level 29 (current min is 21): `android.telephony.SubscriptionManager#isValidSubscriptionId`" + errorLine1=" if (!SubscriptionManager.isValidSubscriptionId(subscriptionId)) {" + errorLine2=" ~~~~~~~~~~~~~~~~~~~~~"> + <location + file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/net/DataUsageController.java" + line="210" + column="34"/> + </issue> + + <issue + id="NewApi" + message="Call requires API level 24 (current min is 21): `android.telephony.SubscriptionManager#getDefaultDataSubscriptionId`" + errorLine1=" subscriptionId = SubscriptionManager.getDefaultDataSubscriptionId();" + errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~"> + <location + file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/net/DataUsageController.java" + line="211" + column="50"/> + </issue> + + <issue + id="NewApi" + message="Call requires API level 29 (current min is 21): `android.telephony.SubscriptionManager#isValidSubscriptionId`" + errorLine1=" if (!SubscriptionManager.isValidSubscriptionId(subscriptionId)) {" + errorLine2=" ~~~~~~~~~~~~~~~~~~~~~"> + <location + file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/net/DataUsageController.java" + line="215" + column="34"/> + </issue> + + <issue + id="NewApi" + message="Call requires API level 22 (current min is 21): `android.telephony.SubscriptionManager#from`" + errorLine1=" int[] activeSubIds = SubscriptionManager.from(mContext).getActiveSubscriptionIdList();" + errorLine2=" ~~~~"> + <location + file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/net/DataUsageController.java" + line="216" + column="54"/> + </issue> + + <issue + id="NewApi" + message="Call requires API level 23 (current min is 21): `android.content.Context#getSystemService`" + errorLine1=" return mContext.getSystemService(" + errorLine2=" ~~~~~~~~~~~~~~~~"> + <location + file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/net/DataUsageController.java" + line="222" + column="25"/> + </issue> + + <issue + id="NewApi" + message="Call requires API level 24 (current min is 21): `android.telephony.TelephonyManager#createForSubscriptionId`" + errorLine1=" TelephonyManager.class).createForSubscriptionId(subscriptionId);" + errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~"> + <location + file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/net/DataUsageController.java" + line="223" + column="41"/> + </issue> + + <issue + id="NewApi" + message="Call requires API level 26 (current min is 21): `android.telephony.TelephonyManager#setDataEnabled`" + errorLine1=" getTelephonyManager().setDataEnabled(enabled);" + errorLine2=" ~~~~~~~~~~~~~~"> + <location + file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/net/DataUsageController.java" + line="228" + column="31"/> + </issue> + + <issue + id="NewApi" + message="Call requires API level 31 (current min is 21): `android.telephony.TelephonyManager#isDataCapable`" + errorLine1=" return getTelephonyManager().isDataCapable()" + errorLine2=" ~~~~~~~~~~~~~"> + <location + file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/net/DataUsageController.java" + line="236" + column="38"/> + </issue> + + <issue + id="NewApi" + message="Call requires API level 26 (current min is 21): `android.telephony.TelephonyManager#isDataEnabled`" + errorLine1=" return getTelephonyManager().isDataEnabled();" + errorLine2=" ~~~~~~~~~~~~~"> + <location + file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/net/DataUsageController.java" + line="241" + column="38"/> + </issue> + + <issue + id="NewApi" + message="Call requires API level 23 (current min is 21): `android.content.Context#getSystemService`" + errorLine1=" final TelephonyManager telephonyManager = context.getSystemService(TelephonyManager.class);" + errorLine2=" ~~~~~~~~~~~~~~~~"> + <location + file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/net/DataUsageUtils.java" + line="40" + column="59"/> + </issue> + + <issue + id="NewApi" + message="Call requires API level R (current min is 21): `android.telephony.TelephonyManager#getSubscriptionId`" + errorLine1=" final int mobileDefaultSubId = telephonyManager.getSubscriptionId();" + errorLine2=" ~~~~~~~~~~~~~~~~~"> + <location + file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/net/DataUsageUtils.java" + line="41" + column="57"/> + </issue> + + <issue + id="NewApi" + message="Call requires API level 23 (current min is 21): `android.content.Context#getSystemService`" + errorLine1=" context.getSystemService(SubscriptionManager.class);" + errorLine2=" ~~~~~~~~~~~~~~~~"> + <location + file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/net/DataUsageUtils.java" + line="44" + column="25"/> + </issue> + + <issue + id="NewApi" + message="Class requires API level 22 (current min is 21): `android.telephony.SubscriptionManager`" + errorLine1=" context.getSystemService(SubscriptionManager.class);" + errorLine2=" ~~~~~~~~~~~~~~~~~~~"> + <location + file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/net/DataUsageUtils.java" + line="44" + column="42"/> + </issue> + + <issue + id="NewApi" + message="Call requires API level 22 (current min is 21): `android.telephony.SubscriptionInfo#getSubscriptionId`" + errorLine1=" if ((subInfo != null) && (subInfo.getSubscriptionId() == subId)) {" + errorLine2=" ~~~~~~~~~~~~~~~~~"> + <location + file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/net/DataUsageUtils.java" + line="53" + column="47"/> + </issue> + + <issue + id="NewApi" + message="Call requires API level 24 (current min is 21): `android.telephony.TelephonyManager#createForSubscriptionId`" + errorLine1=" .createForSubscriptionId(subId).getMergedImsisFromGroup();" + errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~"> + <location + file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/net/DataUsageUtils.java" + line="65" + column="18"/> + </issue> + + <issue + id="NewApi" + message="Call requires API level 23 (current min is 21): `android.content.Context#getSystemService`" + errorLine1=" final TelephonyManager telephonyManager = context.getSystemService(" + errorLine2=" ~~~~~~~~~~~~~~~~"> + <location + file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/DeviceInfoUtils.java" + line="182" + column="63"/> + </issue> + + <issue + id="NewApi" + message="Call requires API level 24 (current min is 21): `android.telephony.TelephonyManager#createForSubscriptionId`" + errorLine1=" final String rawNumber = telephonyManager.createForSubscriptionId(" + errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~"> + <location + file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/DeviceInfoUtils.java" + line="184" + column="55"/> + </issue> + + <issue + id="NewApi" + message="Call requires API level 22 (current min is 21): `android.telephony.SubscriptionInfo#getSubscriptionId`" + errorLine1=" subscriptionInfo.getSubscriptionId()).getLine1Number();" + errorLine2=" ~~~~~~~~~~~~~~~~~"> + <location + file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/DeviceInfoUtils.java" + line="185" + column="38"/> + </issue> + + <issue + id="NewApi" + message="Call requires API level 23 (current min is 21): `android.content.Context#getSystemService`" + errorLine1=" final TelephonyManager telephonyManager = context.getSystemService(" + errorLine2=" ~~~~~~~~~~~~~~~~"> + <location + file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/DeviceInfoUtils.java" + line="197" + column="63"/> + </issue> + + <issue + id="NewApi" + message="Call requires API level 24 (current min is 21): `android.telephony.TelephonyManager#createForSubscriptionId`" + errorLine1=" final String rawNumber = telephonyManager.createForSubscriptionId(" + errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~"> + <location + file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/DeviceInfoUtils.java" + line="201" + column="59"/> + </issue> + + <issue + id="NewApi" + message="Call requires API level 22 (current min is 21): `android.telephony.SubscriptionInfo#getSubscriptionId`" + errorLine1=" subscriptionInfo.getSubscriptionId()).getLine1Number();" + errorLine2=" ~~~~~~~~~~~~~~~~~"> + <location + file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/DeviceInfoUtils.java" + line="202" + column="42"/> + </issue> + + <issue + id="NewApi" + message="Call requires API level 24 (current min is 21): `android.service.notification.Condition#newId`" + errorLine1=" mForeverId = Condition.newId(mContext).appendPath("forever").build();" + errorLine2=" ~~~~~"> + <location + file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/notification/EnableZenModeDialog.java" + line="106" + column="33"/> + </issue> + + <issue + id="NewApi" + message="Field requires API level 24 (current min is 21): `android.service.notification.Condition#state`" + errorLine1=" final boolean enabled = condition.state == Condition.STATE_TRUE;" + errorLine2=" ~~~~~~~~~~~~~~~"> + <location + file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/notification/EnableZenModeDialog.java" + line="190" + column="33"/> + </issue> + + <issue + id="NewApi" + message="Field requires API level 24 (current min is 21): `android.service.notification.Condition#id`" + errorLine1=" return condition != null ? condition.id : null;" + errorLine2=" ~~~~~~~~~~~~"> + <location + file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/notification/EnableZenModeDialog.java" + line="254" + column="36"/> + </issue> + + <issue + id="NewApi" + message="Call requires API level 24 (current min is 21): `android.service.notification.Condition#newId`" + errorLine1=" Uri foreverId = Condition.newId(mContext).appendPath("forever").build();" + errorLine2=" ~~~~~"> + <location + file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/notification/EnableZenModeDialog.java" + line="258" + column="35"/> + </issue> + + <issue + id="NewApi" + message="Call requires API level 24 (current min is 21): `new android.service.notification.Condition`" + errorLine1=" return new Condition(foreverId, foreverSummary(mContext), "", "", 0 /*icon*/," + errorLine2=" ~~~~~~~~~~~~~"> + <location + file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/notification/EnableZenModeDialog.java" + line="259" + column="16"/> + </issue> + + <issue + id="NewApi" + message="Field requires API level 24 (current min is 21): `android.service.notification.Condition#id`" + errorLine1=" return c != null && ZenModeConfig.isValidCountdownToAlarmConditionId(c.id);" + errorLine2=" ~~~~"> + <location + file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/notification/EnableZenModeDialog.java" + line="270" + column="78"/> + </issue> + + <issue + id="NewApi" + message="Field requires API level 24 (current min is 21): `android.service.notification.Condition#id`" + errorLine1=" return c != null && ZenModeConfig.isValidCountdownConditionId(c.id);" + errorLine2=" ~~~~"> + <location + file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/notification/EnableZenModeDialog.java" + line="275" + column="71"/> + </issue> + + <issue + id="NewApi" + message="Field requires API level 24 (current min is 21): `android.service.notification.Condition#id`" + errorLine1=" return c != null && mForeverId.equals(c.id);" + errorLine2=" ~~~~"> + <location + file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/notification/EnableZenModeDialog.java" + line="279" + column="47"/> + </issue> + + <issue + id="NewApi" + message="Field requires API level 24 (current min is 21): `android.service.notification.Condition#line1`" + errorLine1=" final String line1 = !TextUtils.isEmpty(condition.line1) ? condition.line1" + errorLine2=" ~~~~~~~~~~~~~~~"> + <location + file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/notification/EnableZenModeDialog.java" + line="341" + column="49"/> + </issue> + + <issue + id="NewApi" + message="Field requires API level 24 (current min is 21): `android.service.notification.Condition#line1`" + errorLine1=" final String line1 = !TextUtils.isEmpty(condition.line1) ? condition.line1" + errorLine2=" ~~~~~~~~~~~~~~~"> + <location + file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/notification/EnableZenModeDialog.java" + line="341" + column="68"/> + </issue> + + <issue + id="NewApi" + message="Field requires API level 24 (current min is 21): `android.service.notification.Condition#summary`" + errorLine1=" : condition.summary;" + errorLine2=" ~~~~~~~~~~~~~~~~~"> + <location + file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/notification/EnableZenModeDialog.java" + line="342" + column="19"/> + </issue> + + <issue + id="NewApi" + message="Field requires API level 24 (current min is 21): `android.service.notification.Condition#line2`" + errorLine1=" final String line2 = condition.line2;" + errorLine2=" ~~~~~~~~~~~~~~~"> + <location + file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/notification/EnableZenModeDialog.java" + line="343" + column="30"/> + </issue> + + <issue + id="NewApi" + message="Field requires API level 24 (current min is 21): `android.service.notification.Condition#summary`" + errorLine1=" plusButton.setEnabled(!Objects.equals(condition.summary, maxCondition.summary));" + errorLine2=" ~~~~~~~~~~~~~~~~~"> + <location + file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/notification/EnableZenModeDialog.java" + line="388" + column="55"/> + </issue> + + <issue + id="NewApi" + message="Field requires API level 24 (current min is 21): `android.service.notification.Condition#summary`" + errorLine1=" plusButton.setEnabled(!Objects.equals(condition.summary, maxCondition.summary));" + errorLine2=" ~~~~~~~~~~~~~~~~~~~~"> + <location + file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/notification/EnableZenModeDialog.java" + line="388" + column="74"/> + </issue> + + <issue + id="NewApi" + message="Call requires API level 23 (current min is 21): `android.app.NotificationManager#getNotificationPolicy`" + errorLine1=" boolean allowAlarms = (mNotificationManager.getNotificationPolicy().priorityCategories" + errorLine2=" ~~~~~~~~~~~~~~~~~~~~~"> + <location + file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/notification/EnableZenModeDialog.java" + line="466" + column="53"/> + </issue> + + <issue + id="NewApi" + message="Field requires API level 23 (current min is 21): `android.app.NotificationManager.Policy#priorityCategories`" + errorLine1=" boolean allowAlarms = (mNotificationManager.getNotificationPolicy().priorityCategories" + errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"> + <location + file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/notification/EnableZenModeDialog.java" + line="466" + column="32"/> + </issue> + + <issue + id="NewApi" + message="Field requires API level 24 (current min is 21): `android.service.notification.Condition#id`" + errorLine1=" final long time = ZenModeConfig.tryParseCountdownConditionId(condition.id);" + errorLine2=" ~~~~~~~~~~~~"> + <location + file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/notification/EnableZenModeDialog.java" + line="483" + column="74"/> + </issue> + + <issue + id="NewApi" + message="Class requires API level 29 (current min is 21): `android.bluetooth.BluetoothHearingAid`" + errorLine1=" mService = (BluetoothHearingAid) proxy;" + errorLine2=" ~~~~~~~~~~~~~~~~~~~"> + <location + file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/bluetooth/HearingAidProfile.java" + line="59" + column="25"/> + </issue> + + <issue + id="NewApi" + message="Cast from `BluetoothHearingAid` to `BluetoothProfile` requires API level 29 (current min is 21)" + errorLine1=" mService);" + errorLine2=" ~~~~~~~~"> + <location + file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/bluetooth/HearingAidProfile.java" + line="257" + column="72"/> + </issue> + + <issue + id="NewApi" + message="Class requires API level 28 (current min is 21): `android.bluetooth.BluetoothHidDevice`" + errorLine1=" mService = (BluetoothHidDevice) proxy;" + errorLine2=" ~~~~~~~~~~~~~~~~~~"> + <location + file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/bluetooth/HidDeviceProfile.java" + line="63" + column="25"/> + </issue> + + <issue + id="NewApi" + message="Cast from `BluetoothHidDevice` to `BluetoothProfile` requires API level 28 (current min is 21)" + errorLine1=" mService);" + errorLine2=" ~~~~~~~~"> + <location + file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/bluetooth/HidDeviceProfile.java" + line="173" + column="25"/> + </issue> + + <issue + id="NewApi" + message="Call requires API level 23 (current min is 21): `android.graphics.drawable.Icon#loadDrawable`" + errorLine1=" drawable = icon.loadDrawable(mContext);" + errorLine2=" ~~~~~~~~~~~~"> + <location + file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/utils/IconCache.java" + line="45" + column="29"/> + </issue> + + <issue + id="NewApi" + message="Call requires API level R (current min is 21): `android.media.MediaRoute2Info#getName`" + errorLine1=" return mRouteInfo.getName().toString();" + errorLine2=" ~~~~~~~"> + <location + file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/media/InfoMediaDevice.java" + line="51" + column="27"/> + </issue> + + <issue + id="NewApi" + message="Call requires API level R (current min is 21): `android.media.MediaRoute2Info#getClientPackageName`" + errorLine1=" return mRouteInfo.getClientPackageName() != null" + errorLine2=" ~~~~~~~~~~~~~~~~~~~~"> + <location + file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/media/InfoMediaDevice.java" + line="56" + column="27"/> + </issue> + + <issue + id="NewApi" + message="Call requires API level R (current min is 21): `android.media.MediaRoute2Info#getFeatures`" + errorLine1=" final List<String> features = mRouteInfo.getFeatures();" + errorLine2=" ~~~~~~~~~~~"> + <location + file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/media/InfoMediaDevice.java" + line="93" + column="50"/> + </issue> + + <issue + id="NewApi" + message="Call requires API level R (current min is 21): `android.media.MediaRoute2Info#getId`" + errorLine1=" if (info != null && info.getSelectableRoutes().contains(device.mRouteInfo.getId())) {" + errorLine2=" ~~~~~"> + <location + file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/media/InfoMediaManager.java" + line="131" + column="83"/> + </issue> + + <issue + id="NewApi" + message="Call requires API level R (current min is 21): `android.media.RoutingSessionInfo#getSelectableRoutes`" + errorLine1=" if (info != null && info.getSelectableRoutes().contains(device.mRouteInfo.getId())) {" + errorLine2=" ~~~~~~~~~~~~~~~~~~~"> + <location + file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/media/InfoMediaManager.java" + line="131" + column="34"/> + </issue> + + <issue + id="NewApi" + message="Call requires API level R (current min is 21): `android.media.MediaRoute2Info#getId`" + errorLine1=" if (info != null && info.getSelectedRoutes().contains(device.mRouteInfo.getId())) {" + errorLine2=" ~~~~~"> + <location + file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/media/InfoMediaManager.java" + line="162" + column="81"/> + </issue> + + <issue + id="NewApi" + message="Call requires API level R (current min is 21): `android.media.RoutingSessionInfo#getSelectedRoutes`" + errorLine1=" if (info != null && info.getSelectedRoutes().contains(device.mRouteInfo.getId())) {" + errorLine2=" ~~~~~~~~~~~~~~~~~"> + <location + file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/media/InfoMediaManager.java" + line="162" + column="34"/> + </issue> + + <issue + id="NewApi" + message="Call requires API level R (current min is 21): `android.media.MediaRoute2Info#getName`" + errorLine1=" Log.d(TAG, route.getName() + " is deselectable for " + mPackageName);" + errorLine2=" ~~~~~~~"> + <location + file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/media/InfoMediaManager.java" + line="238" + column="34"/> + </issue> + + <issue + id="NewApi" + message="Call requires API level R (current min is 21): `android.media.RoutingSessionInfo#getVolumeMax`" + errorLine1=" return info.getVolumeMax();" + errorLine2=" ~~~~~~~~~~~~"> + <location + file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/media/InfoMediaManager.java" + line="320" + column="25"/> + </issue> + + <issue + id="NewApi" + message="Call requires API level R (current min is 21): `android.media.RoutingSessionInfo#getVolume`" + errorLine1=" return info.getVolume();" + errorLine2=" ~~~~~~~~~"> + <location + file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/media/InfoMediaManager.java" + line="341" + column="25"/> + </issue> + + <issue + id="NewApi" + message="Call requires API level R (current min is 21): `android.media.RoutingSessionInfo#getName`" + errorLine1=" return info.getName();" + errorLine2=" ~~~~~~~"> + <location + file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/media/InfoMediaManager.java" + line="357" + column="25"/> + </issue> + + <issue + id="NewApi" + message="Call requires API level R (current min is 21): `android.media.MediaRoute2Info#getName`" + errorLine1=" Log.d(TAG, "buildAllRoutes() route : " + route.getName() + ", volume : "" + errorLine2=" ~~~~~~~"> + <location + file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/media/InfoMediaManager.java" + line="378" + column="64"/> + </issue> + + <issue + id="NewApi" + message="Call requires API level R (current min is 21): `android.media.MediaRoute2Info#getVolume`" + errorLine1=" + route.getVolume() + ", type : " + route.getType());" + errorLine2=" ~~~~~~~~~"> + <location + file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/media/InfoMediaManager.java" + line="379" + column="33"/> + </issue> + + <issue + id="NewApi" + message="Call requires API level R (current min is 21): `android.media.MediaRoute2Info#isSystemRoute`" + errorLine1=" if (route.isSystemRoute()) {" + errorLine2=" ~~~~~~~~~~~~~"> + <location + file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/media/InfoMediaManager.java" + line="381" + column="23"/> + </issue> + + <issue + id="NewApi" + message="Call requires API level R (current min is 21): `android.media.MediaRoute2Info#getName`" + errorLine1=" Log.d(TAG, "buildAvailableRoutes() route : " + route.getName() + ", volume : "" + errorLine2=" ~~~~~~~"> + <location + file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/media/InfoMediaManager.java" + line="394" + column="70"/> + </issue> + + <issue + id="NewApi" + message="Call requires API level R (current min is 21): `android.media.MediaRoute2Info#getVolume`" + errorLine1=" + route.getVolume() + ", type : " + route.getType());" + errorLine2=" ~~~~~~~~~"> + <location + file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/media/InfoMediaManager.java" + line="395" + column="33"/> + </issue> + + <issue + id="NewApi" + message="Call requires API level R (current min is 21): `android.media.MediaRoute2Info#getId`" + errorLine1=" && getRoutingSessionInfo().getSelectedRoutes().contains(route.getId())" + errorLine2=" ~~~~~"> + <location + file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/media/InfoMediaManager.java" + line="414" + column="87"/> + </issue> + + <issue + id="NewApi" + message="Call requires API level R (current min is 21): `android.media.RoutingSessionInfo#getSelectedRoutes`" + errorLine1=" && getRoutingSessionInfo().getSelectedRoutes().contains(route.getId())" + errorLine2=" ~~~~~~~~~~~~~~~~~"> + <location + file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/media/InfoMediaManager.java" + line="414" + column="52"/> + </issue> + + <issue + id="NewApi" + message="Call requires API level R (current min is 21): `android.media.RoutingSessionInfo#getName`" + errorLine1=" Log.d(TAG, "onTransferred() oldSession : " + oldSession.getName()" + errorLine2=" ~~~~~~~"> + <location + file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/media/InfoMediaManager.java" + line="479" + column="73"/> + </issue> + + <issue + id="NewApi" + message="Call requires API level R (current min is 21): `android.media.RoutingSessionInfo#getName`" + errorLine1=" + ", newSession : " + newSession.getName());" + errorLine2=" ~~~~~~~"> + <location + file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/media/InfoMediaManager.java" + line="480" + column="58"/> + </issue> + + <issue + id="NewApi" + message="Call requires API level 23 (current min is 21): `android.app.Fragment#getContext`" + errorLine1=" mImm = fragment.getContext().getSystemService(InputMethodManager.class);" + errorLine2=" ~~~~~~~~~~"> + <location + file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/inputmethod/InputMethodAndSubtypeEnablerManager.java" + line="55" + column="25"/> + </issue> + + <issue + id="NewApi" + message="Call requires API level 23 (current min is 21): `android.content.Context#getSystemService`" + errorLine1=" mImm = fragment.getContext().getSystemService(InputMethodManager.class);" + errorLine2=" ~~~~~~~~~~~~~~~~"> + <location + file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/inputmethod/InputMethodAndSubtypeEnablerManager.java" + line="55" + column="38"/> + </issue> + + <issue + id="NewApi" + message="Call requires API level 24 (current min is 21): `java.util.ArrayList#sort`" + errorLine1=" subtypePreferences.sort((lhs, rhs) -> {" + errorLine2=" ~~~~"> + <location + file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/inputmethod/InputMethodAndSubtypeEnablerManager.java" + line="161" + column="28"/> + </issue> + + <issue + id="NewApi" + message="Call requires API level 23 (current min is 21): `android.app.Fragment#getContext`" + errorLine1=" mFragment, mFragment.getContext().getContentResolver()," + errorLine2=" ~~~~~~~~~~"> + <location + file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/inputmethod/InputMethodAndSubtypeEnablerManager.java" + line="212" + column="42"/> + </issue> + + <issue + id="NewApi" + message="Call requires API level 23 (current min is 21): `android.content.Context#getSystemService`" + errorLine1=" mImm = fragment.getContext().getSystemService(InputMethodManager.class);" + errorLine2=" ~~~~~~~~~~~~~~~~"> + <location + file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/inputmethod/InputMethodAndSubtypeEnablerManagerCompat.java" + line="56" + column="38"/> + </issue> + + <issue + id="NewApi" + message="Call requires API level 24 (current min is 21): `java.util.ArrayList#sort`" + errorLine1=" subtypePreferences.sort((lhs, rhs) -> {" + errorLine2=" ~~~~"> + <location + file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/inputmethod/InputMethodAndSubtypeEnablerManagerCompat.java" + line="162" + column="28"/> + </issue> + + <issue + id="NewApi" + message="Call requires API level 26 (current min is 21): `android.icu.text.ListFormatter#format`" + errorLine1=" ListFormatter.getInstance(locale).format((Object[]) subtypeNames), locale);" + errorLine2=" ~~~~~~"> + <location + file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/inputmethod/InputMethodAndSubtypeUtil.java" + line="400" + column="51"/> + </issue> + + <issue + id="NewApi" + message="Call requires API level 26 (current min is 21): `android.icu.text.ListFormatter#getInstance`" + errorLine1=" ListFormatter.getInstance(locale).format((Object[]) subtypeNames), locale);" + errorLine2=" ~~~~~~~~~~~"> + <location + file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/inputmethod/InputMethodAndSubtypeUtil.java" + line="400" + column="31"/> + </issue> + + <issue + id="NewApi" + message="Call requires API level 24 (current min is 21): `android.content.res.Configuration#getLocales`" + errorLine1=" final Locale configurationLocale = configuration.getLocales().get(0);" + errorLine2=" ~~~~~~~~~~"> + <location + file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/inputmethod/InputMethodAndSubtypeUtil.java" + line="415" + column="58"/> + </issue> + + <issue + id="NewApi" + message="Call requires API level 24 (current min is 21): `android.os.LocaleList#get`" + errorLine1=" final Locale configurationLocale = configuration.getLocales().get(0);" + errorLine2=" ~~~"> + <location + file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/inputmethod/InputMethodAndSubtypeUtil.java" + line="415" + column="71"/> + </issue> + + <issue + id="NewApi" + message="Call requires API level 26 (current min is 21): `android.icu.text.ListFormatter#format`" + errorLine1=" ListFormatter.getInstance(locale).format((Object[]) subtypeNames), locale);" + errorLine2=" ~~~~~~"> + <location + file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/inputmethod/InputMethodAndSubtypeUtilCompat.java" + line="400" + column="51"/> + </issue> + + <issue + id="NewApi" + message="Call requires API level 26 (current min is 21): `android.icu.text.ListFormatter#getInstance`" + errorLine1=" ListFormatter.getInstance(locale).format((Object[]) subtypeNames), locale);" + errorLine2=" ~~~~~~~~~~~"> + <location + file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/inputmethod/InputMethodAndSubtypeUtilCompat.java" + line="400" + column="31"/> + </issue> + + <issue + id="NewApi" + message="Call requires API level 24 (current min is 21): `android.content.res.Configuration#getLocales`" + errorLine1=" final Locale configurationLocale = configuration.getLocales().get(0);" + errorLine2=" ~~~~~~~~~~"> + <location + file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/inputmethod/InputMethodAndSubtypeUtilCompat.java" + line="415" + column="58"/> + </issue> + + <issue + id="NewApi" + message="Call requires API level 24 (current min is 21): `android.os.LocaleList#get`" + errorLine1=" final Locale configurationLocale = configuration.getLocales().get(0);" + errorLine2=" ~~~"> + <location + file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/inputmethod/InputMethodAndSubtypeUtilCompat.java" + line="415" + column="71"/> + </issue> + + <issue + id="NewApi" + message="Field requires API level 24 (current min is 21): `android.content.pm.ComponentInfo#directBootAware`" + errorLine1=" if (mImi.getServiceInfo().directBootAware || isTv()) {" + errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"> + <location + file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/inputmethod/InputMethodPreference.java" + line="162" + column="17"/> + </issue> + + <issue + id="NewApi" + message="Field requires API level 24 (current min is 21): `android.content.pm.ComponentInfo#directBootAware`" + errorLine1=" if (mImi.getServiceInfo().directBootAware || isTv()) {" + errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"> + <location + file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/inputmethod/InputMethodPreference.java" + line="257" + column="17"/> + </issue> + + <issue + id="NewApi" + message="Call requires API level 23 (current min is 21): `android.content.Context#getSystemService`" + errorLine1=" mImm = context.getSystemService(InputMethodManager.class);" + errorLine2=" ~~~~~~~~~~~~~~~~"> + <location + file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/inputmethod/InputMethodSettingValuesWrapper.java" + line="61" + column="24"/> + </issue> + + <issue + id="NewApi" + message="Call requires API level R (current min is 21): `android.media.RoutingSessionInfo#getId`" + errorLine1=" if (TextUtils.equals(sessionId, info.getId())) {" + errorLine2=" ~~~~~"> + <location + file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/media/LocalMediaManager.java" + line="343" + column="50"/> + </issue> + + <issue + id="NewApi" + message="Call requires API level 23 (current min is 21): `android.content.res.Resources#getColorStateList`" + errorLine1=" mContext.getResources().getColorStateList(" + errorLine2=" ~~~~~~~~~~~~~~~~~"> + <location + file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/media/MediaDevice.java" + line="142" + column="41"/> + </issue> + + <issue + id="NewApi" + message="Call requires API level R (current min is 21): `android.media.MediaRoute2Info#getVolumeMax`" + errorLine1=" return mRouteInfo.getVolumeMax();" + errorLine2=" ~~~~~~~~~~~~"> + <location + file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/media/MediaDevice.java" + line="211" + column="27"/> + </issue> + + <issue + id="NewApi" + message="Call requires API level R (current min is 21): `android.media.MediaRoute2Info#getVolume`" + errorLine1=" return mRouteInfo.getVolume();" + errorLine2=" ~~~~~~~~~"> + <location + file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/media/MediaDevice.java" + line="220" + column="27"/> + </issue> + + <issue + id="NewApi" + message="Call requires API level R (current min is 21): `android.media.MediaRoute2Info#getClientPackageName`" + errorLine1=" return mRouteInfo.getClientPackageName();" + errorLine2=" ~~~~~~~~~~~~~~~~~~~~"> + <location + file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/media/MediaDevice.java" + line="229" + column="27"/> + </issue> + + <issue + id="NewApi" + message="Call requires API level R (current min is 21): `android.media.MediaRoute2Info#getFeatures`" + errorLine1=" return mRouteInfo.getFeatures();" + errorLine2=" ~~~~~~~~~~~"> + <location + file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/media/MediaDevice.java" + line="361" + column="27"/> + </issue> + + <issue + id="NewApi" + message="Call requires API level R (current min is 21): `android.media.MediaRoute2Info#getId`" + errorLine1=" return route.getId();" + errorLine2=" ~~~~~"> + <location + file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/media/MediaDeviceUtils.java" + line="57" + column="22"/> + </issue> + + <issue + id="NewApi" + message="Call requires API level 23 (current min is 21): `android.app.usage.NetworkStats.Bucket#getRxBytes`" + errorLine1=" final long total = bucket == null ? 0L : bucket.getRxBytes() + bucket.getTxBytes();" + errorLine2=" ~~~~~~~~~~"> + <location + file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/net/NetworkCycleChartDataLoader.java" + line="48" + column="61"/> + </issue> + + <issue + id="NewApi" + message="Call requires API level 23 (current min is 21): `android.app.usage.NetworkStats.Bucket#getTxBytes`" + errorLine1=" final long total = bucket == null ? 0L : bucket.getRxBytes() + bucket.getTxBytes();" + errorLine2=" ~~~~~~~~~~"> + <location + file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/net/NetworkCycleChartDataLoader.java" + line="48" + column="83"/> + </issue> + + <issue + id="NewApi" + message="Call requires API level 23 (current min is 21): `android.app.usage.NetworkStats.Bucket#getRxBytes`" + errorLine1=" usage = bucket.getRxBytes() + bucket.getTxBytes();" + errorLine2=" ~~~~~~~~~~"> + <location + file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/net/NetworkCycleChartDataLoader.java" + line="86" + column="36"/> + </issue> + + <issue + id="NewApi" + message="Call requires API level 23 (current min is 21): `android.app.usage.NetworkStats.Bucket#getTxBytes`" + errorLine1=" usage = bucket.getRxBytes() + bucket.getTxBytes();" + errorLine2=" ~~~~~~~~~~"> + <location + file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/net/NetworkCycleChartDataLoader.java" + line="86" + column="58"/> + </issue> + + <issue + id="NewApi" + message="Class requires API level 23 (current min is 21): `android.app.usage.NetworkStatsManager`" + errorLine1=" mNetworkStatsManager = (NetworkStatsManager)" + errorLine2=" ~~~~~~~~~~~~~~~~~~~"> + <location + file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/net/NetworkCycleDataLoader.java" + line="62" + column="33"/> + </issue> + + <issue + id="NewApi" + message="Call requires API level 23 (current min is 21): `new android.app.usage.NetworkStats.Bucket`" + errorLine1=" final NetworkStats.Bucket bucket = new NetworkStats.Bucket();" + errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~"> + <location + file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/net/NetworkCycleDataLoader.java" + line="163" + column="48"/> + </issue> + + <issue + id="NewApi" + message="Call requires API level 23 (current min is 21): `android.app.usage.NetworkStats#getNextBucket`" + errorLine1=" while (stats.hasNextBucket() && stats.getNextBucket(bucket)) {" + errorLine2=" ~~~~~~~~~~~~~"> + <location + file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/net/NetworkCycleDataLoader.java" + line="164" + column="51"/> + </issue> + + <issue + id="NewApi" + message="Call requires API level 23 (current min is 21): `android.app.usage.NetworkStats#hasNextBucket`" + errorLine1=" while (stats.hasNextBucket() && stats.getNextBucket(bucket)) {" + errorLine2=" ~~~~~~~~~~~~~"> + <location + file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/net/NetworkCycleDataLoader.java" + line="164" + column="26"/> + </issue> + + <issue + id="NewApi" + message="Call requires API level 23 (current min is 21): `android.app.usage.NetworkStats.Bucket#getRxBytes`" + errorLine1=" bytes += bucket.getRxBytes() + bucket.getTxBytes();" + errorLine2=" ~~~~~~~~~~"> + <location + file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/net/NetworkCycleDataLoader.java" + line="165" + column="33"/> + </issue> + + <issue + id="NewApi" + message="Call requires API level 23 (current min is 21): `android.app.usage.NetworkStats.Bucket#getTxBytes`" + errorLine1=" bytes += bucket.getRxBytes() + bucket.getTxBytes();" + errorLine2=" ~~~~~~~~~~"> + <location + file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/net/NetworkCycleDataLoader.java" + line="165" + column="55"/> + </issue> + + <issue + id="NewApi" + message="Call requires API level 31 (current min is 21): `com.google.android.collect.Lists#newArrayList`" + errorLine1=" private ArrayList<NetworkPolicy> mPolicies = Lists.newArrayList();" + errorLine2=" ~~~~~~~~~~~~"> + <location + file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/NetworkPolicyEditor.java" + line="54" + column="56"/> + </issue> + + <issue + id="NewApi" + message="Class requires API level 23 (current min is 21): `android.app.usage.NetworkStatsManager`" + errorLine1=" mNetworkStatsManager = (NetworkStatsManager)" + errorLine2=" ~~~~~~~~~~~~~~~~~~~"> + <location + file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/net/NetworkStatsSummaryLoader.java" + line="44" + column="33"/> + </issue> + + <issue + id="NewApi" + message="Call requires API level 23 (current min is 21): `android.content.Context#getSystemService`" + errorLine1=" context.getSystemService(PermissionControllerManager.class);" + errorLine2=" ~~~~~~~~~~~~~~~~"> + <location + file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/applications/PermissionsSummaryHelper.java" + line="32" + column="25"/> + </issue> + + <issue + id="NewApi" + message="Call requires API level R (current min is 21): `android.media.MediaRoute2Info#getName`" + errorLine1=" name = mRouteInfo.getName();" + errorLine2=" ~~~~~~~"> + <location + file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/media/PhoneMediaDevice.java" + line="71" + column="35"/> + </issue> + + <issue + id="NewApi" + message="Call requires API level 24 (current min is 21): `android.content.res.Configuration#getLocales`" + errorLine1=" final Locale currentLocale = context.getResources().getConfiguration().getLocales().get(0);" + errorLine2=" ~~~~~~~~~~"> + <location + file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/utils/PowerUtil.java" + line="179" + column="80"/> + </issue> + + <issue + id="NewApi" + message="Call requires API level 24 (current min is 21): `android.os.LocaleList#get`" + errorLine1=" final Locale currentLocale = context.getResources().getConfiguration().getLocales().get(0);" + errorLine2=" ~~~"> + <location + file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/utils/PowerUtil.java" + line="179" + column="93"/> + </issue> + + <issue + id="NewApi" + message="Call requires API level 24 (current min is 21): `android.icu.text.MeasureFormat#getInstance`" + errorLine1=" final MeasureFormat frmt = MeasureFormat.getInstance(currentLocale, FormatWidth.SHORT);" + errorLine2=" ~~~~~~~~~~~"> + <location + file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/utils/PowerUtil.java" + line="180" + column="50"/> + </issue> + + <issue + id="NewApi" + message="Field requires API level 24 (current min is 21): `android.icu.text.MeasureFormat.FormatWidth#SHORT`" + errorLine1=" final MeasureFormat frmt = MeasureFormat.getInstance(currentLocale, FormatWidth.SHORT);" + errorLine2=" ~~~~~~~~~~~~~~~~~"> + <location + file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/utils/PowerUtil.java" + line="180" + column="77"/> + </issue> + + <issue + id="NewApi" + message="Call requires API level 24 (current min is 21): `new android.icu.util.Measure`" + errorLine1=" final Measure daysMeasure = new Measure(2, MeasureUnit.DAY);" + errorLine2=" ~~~~~~~~~~~"> + <location + file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/utils/PowerUtil.java" + line="182" + column="37"/> + </issue> + + <issue + id="NewApi" + message="Cast from `TimeUnit` to `MeasureUnit` requires API level 24 (current min is 21)" + errorLine1=" final Measure daysMeasure = new Measure(2, MeasureUnit.DAY);" + errorLine2=" ~~~~~~~~~~~~~~~"> + <location + file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/utils/PowerUtil.java" + line="182" + column="52"/> + </issue> + + <issue + id="NewApi" + message="Field requires API level 24 (current min is 21): `android.icu.util.MeasureUnit#DAY`" + errorLine1=" final Measure daysMeasure = new Measure(2, MeasureUnit.DAY);" + errorLine2=" ~~~~~~~~~~~~~~~"> + <location + file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/utils/PowerUtil.java" + line="182" + column="52"/> + </issue> + + <issue + id="NewApi" + message="Call requires API level 24 (current min is 21): `android.icu.text.MeasureFormat#formatMeasures`" + errorLine1=" frmt.formatMeasures(daysMeasure))" + errorLine2=" ~~~~~~~~~~~~~~"> + <location + file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/utils/PowerUtil.java" + line="186" + column="30"/> + </issue> + + <issue + id="NewApi" + message="Call requires API level 24 (current min is 21): `android.icu.text.MeasureFormat#formatMeasures`" + errorLine1=" frmt.formatMeasures(daysMeasure)," + errorLine2=" ~~~~~~~~~~~~~~"> + <location + file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/utils/PowerUtil.java" + line="189" + column="30"/> + </issue> + + <issue + id="NewApi" + message="Call requires API level 24 (current min is 21): `android.icu.text.DateFormat#getInstanceForSkeleton`" + errorLine1=" DateFormat fmt = DateFormat.getInstanceForSkeleton(skeleton);" + errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~"> + <location + file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/utils/PowerUtil.java" + line="220" + column="37"/> + </issue> + + <issue + id="NewApi" + message="Call requires API level 24 (current min is 21): `android.icu.text.DateFormat#format`" + errorLine1=" return fmt.format(date);" + errorLine2=" ~~~~~~"> + <location + file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/utils/PowerUtil.java" + line="222" + column="20"/> + </issue> + + <issue + id="NewApi" + message="Call requires API level 24 (current min is 21): `android.icu.text.DateFormat#getInstanceForSkeleton`" + errorLine1=" DateFormat fmt = DateFormat.getInstanceForSkeleton(skeleton);" + errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~"> + <location + file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/utils/PowerUtil.java" + line="234" + column="37"/> + </issue> + + <issue + id="NewApi" + message="Call requires API level 24 (current min is 21): `android.icu.text.DateFormat#format`" + errorLine1=" CharSequence timeString = fmt.format(date);" + errorLine2=" ~~~~~~"> + <location + file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/utils/PowerUtil.java" + line="236" + column="39"/> + </issue> + + <issue + id="NewApi" + message="Call requires API level 23 (current min is 21): `new android.util.ArraySet`" + errorLine1=" private final ArraySet<String> mWhitelistedApps = new ArraySet<>();" + errorLine2=" ~~~~~~~~~~~~~~"> + <location + file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/fuelgauge/PowerWhitelistBackend.java" + line="49" + column="55"/> + </issue> + + <issue + id="NewApi" + message="Call requires API level 23 (current min is 21): `new android.util.ArraySet`" + errorLine1=" private final ArraySet<String> mSysWhitelistedApps = new ArraySet<>();" + errorLine2=" ~~~~~~~~~~~~~~"> + <location + file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/fuelgauge/PowerWhitelistBackend.java" + line="50" + column="58"/> + </issue> + + <issue + id="NewApi" + message="Call requires API level 23 (current min is 21): `new android.util.ArraySet`" + errorLine1=" private final ArraySet<String> mSysWhitelistedAppsExceptIdle = new ArraySet<>();" + errorLine2=" ~~~~~~~~~~~~~~"> + <location + file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/fuelgauge/PowerWhitelistBackend.java" + line="51" + column="68"/> + </issue> + + <issue + id="NewApi" + message="Call requires API level 23 (current min is 21): `new android.util.ArraySet`" + errorLine1=" private final ArraySet<String> mDefaultActiveApps = new ArraySet<>();" + errorLine2=" ~~~~~~~~~~~~~~"> + <location + file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/fuelgauge/PowerWhitelistBackend.java" + line="52" + column="57"/> + </issue> + + <issue + id="NewApi" + message="Call requires API level 23 (current min is 21): `android.content.Context#getSystemService`" + errorLine1=" final DevicePolicyManager devicePolicyManager = mAppContext.getSystemService(" + errorLine2=" ~~~~~~~~~~~~~~~~"> + <location + file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/fuelgauge/PowerWhitelistBackend.java" + line="98" + column="69"/> + </issue> + + <issue + id="NewApi" + message="Call requires API level 23 (current min is 21): `android.content.Context#getSystemService`" + errorLine1=" final StorageStatsManager stats = context.getSystemService(StorageStatsManager.class);" + errorLine2=" ~~~~~~~~~~~~~~~~"> + <location + file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/deviceinfo/PrivateStorageInfo.java" + line="43" + column="51"/> + </issue> + + <issue + id="NewApi" + message="Class requires API level 26 (current min is 21): `android.app.usage.StorageStatsManager`" + errorLine1=" final StorageStatsManager stats = context.getSystemService(StorageStatsManager.class);" + errorLine2=" ~~~~~~~~~~~~~~~~~~~"> + <location + file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/deviceinfo/PrivateStorageInfo.java" + line="43" + column="68"/> + </issue> + + <issue + id="NewApi" + message="Call requires API level 23 (current min is 21): `android.content.Context#getSystemService`" + errorLine1=" final StorageStatsManager stats = context.getSystemService(StorageStatsManager.class);" + errorLine2=" ~~~~~~~~~~~~~~~~"> + <location + file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/deviceinfo/PrivateStorageInfo.java" + line="62" + column="51"/> + </issue> + + <issue + id="NewApi" + message="Class requires API level 26 (current min is 21): `android.app.usage.StorageStatsManager`" + errorLine1=" final StorageStatsManager stats = context.getSystemService(StorageStatsManager.class);" + errorLine2=" ~~~~~~~~~~~~~~~~~~~"> + <location + file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/deviceinfo/PrivateStorageInfo.java" + line="62" + column="68"/> + </issue> + + <issue + id="NewApi" + message="Call requires API level 24 (current min is 21): `android.os.UserHandle#getUserHandleForUid`" + errorLine1=" UserHandle user = UserHandle.getUserHandleForUid(uid);" + errorLine2=" ~~~~~~~~~~~~~~~~~~~"> + <location + file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/location/RecentLocationAccesses.java" + line="102" + column="42"/> + </issue> + + <issue + id="NewApi" + message="Call requires API level 24 (current min is 21): `android.os.UserHandle#getUserHandleForUid`" + errorLine1=" final UserHandle user = UserHandle.getUserHandleForUid(uid);" + errorLine2=" ~~~~~~~~~~~~~~~~~~~"> + <location + file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/location/RecentLocationApps.java" + line="97" + column="48"/> + </issue> + + <issue + id="NewApi" + message="Call requires API level 23 (current min is 21): `android.content.Context#getColor`" + errorLine1=" final int disabledColor = context.getColor(R.color.disabled_text_color);" + errorLine2=" ~~~~~~~~"> + <location + file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/RestrictedLockUtilsInternal.java" + line="581" + column="47"/> + </issue> + + <issue + id="NewApi" + message="Call requires API level 23 (current min is 21): `new android.util.ArraySet`" + errorLine1=" private Set<Setting> mSettingsBeingLoaded = new ArraySet<Setting>();" + errorLine2=" ~~~~~~~~~~~~~~~~~~~~~"> + <location + file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/location/SettingsInjector.java" + line="361" + column="53"/> + </issue> + + <issue + id="NewApi" + message="Class requires API level 23 (current min is 21): `android.graphics.drawable.DrawableWrapper`" + errorLine1="public class SignalDrawable extends DrawableWrapper {" + errorLine2=" ~~~~~~~~~~~~~~~"> + <location + file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/graph/SignalDrawable.java" + line="45" + column="37"/> + </issue> + + <issue + id="NewApi" + message="Call requires API level 23 (current min is 21): `new android.graphics.drawable.DrawableWrapper`" + errorLine1=" super(context.getDrawable(com.android.internal.R.drawable.ic_signal_cellular));" + errorLine2=" ~~~~~"> + <location + file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/graph/SignalDrawable.java" + line="87" + column="9"/> + </issue> + + <issue + id="NewApi" + message="Call requires API level 29 (current min is 21): `android.content.res.Resources#getFloat`" + errorLine1=" mCutoutWidthFraction = context.getResources().getFloat(" + errorLine2=" ~~~~~~~~"> + <location + file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/graph/SignalDrawable.java" + line="92" + column="55"/> + </issue> + + <issue + id="NewApi" + message="Call requires API level 29 (current min is 21): `android.content.res.Resources#getFloat`" + errorLine1=" mCutoutHeightFraction = context.getResources().getFloat(" + errorLine2=" ~~~~~~~~"> + <location + file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/graph/SignalDrawable.java" + line="94" + column="56"/> + </issue> + + <issue + id="NewApi" + message="Call requires API level 23 (current min is 21): `android.content.Context#getColor`" + errorLine1=" mTransparentPaint.setColor(context.getColor(android.R.color.transparent));" + errorLine2=" ~~~~~~~~"> + <location + file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/graph/SignalDrawable.java" + line="101" + column="44"/> + </issue> + + <issue + id="NewApi" + message="Call requires API level 23 (current min is 21): `android.graphics.drawable.Drawable#getLayoutDirection`" + errorLine1=" boolean isRtl = getLayoutDirection() == LayoutDirection.RTL;" + errorLine2=" ~~~~~~~~~~~~~~~~~~"> + <location + file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/graph/SignalDrawable.java" + line="190" + column="25"/> + </issue> + + <issue + id="NewApi" + message="Call requires API level 23 (current min is 21): `android.content.Context#getSystemService`" + errorLine1=" context.getSystemService(CarrierConfigManager.class);" + errorLine2=" ~~~~~~~~~~~~~~~~"> + <location + file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/net/SignalStrengthUtil.java" + line="33" + column="25"/> + </issue> + + <issue + id="NewApi" + message="Class requires API level 23 (current min is 21): `android.telephony.CarrierConfigManager`" + errorLine1=" context.getSystemService(CarrierConfigManager.class);" + errorLine2=" ~~~~~~~~~~~~~~~~~~~~"> + <location + file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/net/SignalStrengthUtil.java" + line="33" + column="42"/> + </issue> + + <issue + id="NewApi" + message="Call requires API level 23 (current min is 21): `android.telephony.CarrierConfigManager#getConfigForSubId`" + errorLine1=" bundle = carrierConfigMgr.getConfigForSubId(subscriptionId);" + errorLine2=" ~~~~~~~~~~~~~~~~~"> + <location + file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/net/SignalStrengthUtil.java" + line="36" + column="39"/> + </issue> + + <issue + id="NewApi" + message="Call requires API level 22 (current min is 21): `android.os.BaseBundle#getBoolean`" + errorLine1=" return (bundle != null && bundle.getBoolean(" + errorLine2=" ~~~~~~~~~~"> + <location + file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/net/SignalStrengthUtil.java" + line="38" + column="42"/> + </issue> + + <issue + id="NewApi" + message="Call requires API level 23 (current min is 21): `new android.util.ArraySet`" + errorLine1=" private static final Set<Uri> sRegisteredUris = new ArraySet<>();" + errorLine2=" ~~~~~~~~~~~~~~"> + <location + file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/SliceBroadcastRelay.java" + line="47" + column="53"/> + </issue> + + <issue + id="NewApi" + message="Call requires API level 23 (current min is 21): `android.content.Context#getSystemService`" + errorLine1=" mUser = mContext.getSystemService(UserManager.class);" + errorLine2=" ~~~~~~~~~~~~~~~~"> + <location + file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/deviceinfo/StorageMeasurement.java" + line="107" + column="26"/> + </issue> + + <issue + id="NewApi" + message="Call requires API level 23 (current min is 21): `android.content.Context#getSystemService`" + errorLine1=" mStats = mContext.getSystemService(StorageStatsManager.class);" + errorLine2=" ~~~~~~~~~~~~~~~~"> + <location + file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/deviceinfo/StorageMeasurement.java" + line="108" + column="27"/> + </issue> + + <issue + id="NewApi" + message="Class requires API level 26 (current min is 21): `android.app.usage.StorageStatsManager`" + errorLine1=" mStats = mContext.getSystemService(StorageStatsManager.class);" + errorLine2=" ~~~~~~~~~~~~~~~~~~~"> + <location + file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/deviceinfo/StorageMeasurement.java" + line="108" + column="44"/> + </issue> + + <issue + id="NewApi" + message="Call requires API level 26 (current min is 21): `android.app.usage.ExternalStorageStats#getTotalBytes`" + errorLine1=" addValue(details.usersSize, user.id, stats.getTotalBytes());" + errorLine2=" ~~~~~~~~~~~~~"> + <location + file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/deviceinfo/StorageMeasurement.java" + line="188" + column="60"/> + </issue> + + <issue + id="NewApi" + message="Call requires API level 26 (current min is 21): `android.app.usage.ExternalStorageStats#getAudioBytes`" + errorLine1=" mediaMap.put(Environment.DIRECTORY_MUSIC, stats.getAudioBytes());" + errorLine2=" ~~~~~~~~~~~~~"> + <location + file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/deviceinfo/StorageMeasurement.java" + line="191" + column="65"/> + </issue> + + <issue + id="NewApi" + message="Call requires API level 26 (current min is 21): `android.app.usage.ExternalStorageStats#getVideoBytes`" + errorLine1=" mediaMap.put(Environment.DIRECTORY_MOVIES, stats.getVideoBytes());" + errorLine2=" ~~~~~~~~~~~~~"> + <location + file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/deviceinfo/StorageMeasurement.java" + line="192" + column="66"/> + </issue> + + <issue + id="NewApi" + message="Call requires API level 26 (current min is 21): `android.app.usage.ExternalStorageStats#getImageBytes`" + errorLine1=" mediaMap.put(Environment.DIRECTORY_PICTURES, stats.getImageBytes());" + errorLine2=" ~~~~~~~~~~~~~"> + <location + file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/deviceinfo/StorageMeasurement.java" + line="193" + column="68"/> + </issue> + + <issue + id="NewApi" + message="Call requires API level 26 (current min is 21): `android.app.usage.ExternalStorageStats#getAudioBytes`" + errorLine1=" final long miscBytes = stats.getTotalBytes() - stats.getAudioBytes()" + errorLine2=" ~~~~~~~~~~~~~"> + <location + file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/deviceinfo/StorageMeasurement.java" + line="195" + column="70"/> + </issue> + + <issue + id="NewApi" + message="Call requires API level 26 (current min is 21): `android.app.usage.ExternalStorageStats#getTotalBytes`" + errorLine1=" final long miscBytes = stats.getTotalBytes() - stats.getAudioBytes()" + errorLine2=" ~~~~~~~~~~~~~"> + <location + file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/deviceinfo/StorageMeasurement.java" + line="195" + column="46"/> + </issue> + + <issue + id="NewApi" + message="Call requires API level 26 (current min is 21): `android.app.usage.ExternalStorageStats#getImageBytes`" + errorLine1=" - stats.getVideoBytes() - stats.getImageBytes();" + errorLine2=" ~~~~~~~~~~~~~"> + <location + file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/deviceinfo/StorageMeasurement.java" + line="196" + column="57"/> + </issue> + + <issue + id="NewApi" + message="Call requires API level 26 (current min is 21): `android.app.usage.ExternalStorageStats#getVideoBytes`" + errorLine1=" - stats.getVideoBytes() - stats.getImageBytes();" + errorLine2=" ~~~~~~~~~~~~~"> + <location + file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/deviceinfo/StorageMeasurement.java" + line="196" + column="33"/> + </issue> + + <issue + id="NewApi" + message="Call requires API level 26 (current min is 21): `android.app.usage.StorageStats#getDataBytes`" + errorLine1=" addValue(details.usersSize, user.id, stats.getDataBytes());" + errorLine2=" ~~~~~~~~~~~~"> + <location + file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/deviceinfo/StorageMeasurement.java" + line="219" + column="60"/> + </issue> + + <issue + id="NewApi" + message="Call requires API level 26 (current min is 21): `android.app.usage.StorageStats#getDataBytes`" + errorLine1=" addValue(details.appsSize, user.id, stats.getCodeBytes() + stats.getDataBytes());" + errorLine2=" ~~~~~~~~~~~~"> + <location + file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/deviceinfo/StorageMeasurement.java" + line="220" + column="82"/> + </issue> + + <issue + id="NewApi" + message="Call requires API level 26 (current min is 21): `android.app.usage.StorageStats#getCacheBytes`" + errorLine1=" details.cacheSize += stats.getCacheBytes();" + errorLine2=" ~~~~~~~~~~~~~"> + <location + file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/deviceinfo/StorageMeasurement.java" + line="222" + column="44"/> + </issue> + + <issue + id="NewApi" + message="Call requires API level 23 (current min is 21): `android.content.Context#getSystemService`" + errorLine1=" mStorageStatsManager = context.getSystemService(StorageStatsManager.class);" + errorLine2=" ~~~~~~~~~~~~~~~~"> + <location + file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/applications/StorageStatsSource.java" + line="36" + column="40"/> + </issue> + + <issue + id="NewApi" + message="Class requires API level 26 (current min is 21): `android.app.usage.StorageStatsManager`" + errorLine1=" mStorageStatsManager = context.getSystemService(StorageStatsManager.class);" + errorLine2=" ~~~~~~~~~~~~~~~~~~~"> + <location + file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/applications/StorageStatsSource.java" + line="36" + column="57"/> + </issue> + + <issue + id="NewApi" + message="Call requires API level 26 (current min is 21): `android.app.usage.ExternalStorageStats#getTotalBytes`" + errorLine1=" totalBytes = stats.getTotalBytes();" + errorLine2=" ~~~~~~~~~~~~~"> + <location + file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/applications/StorageStatsSource.java" + line="90" + column="32"/> + </issue> + + <issue + id="NewApi" + message="Call requires API level 26 (current min is 21): `android.app.usage.ExternalStorageStats#getAudioBytes`" + errorLine1=" audioBytes = stats.getAudioBytes();" + errorLine2=" ~~~~~~~~~~~~~"> + <location + file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/applications/StorageStatsSource.java" + line="91" + column="32"/> + </issue> + + <issue + id="NewApi" + message="Call requires API level 26 (current min is 21): `android.app.usage.ExternalStorageStats#getVideoBytes`" + errorLine1=" videoBytes = stats.getVideoBytes();" + errorLine2=" ~~~~~~~~~~~~~"> + <location + file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/applications/StorageStatsSource.java" + line="92" + column="32"/> + </issue> + + <issue + id="NewApi" + message="Call requires API level 26 (current min is 21): `android.app.usage.ExternalStorageStats#getImageBytes`" + errorLine1=" imageBytes = stats.getImageBytes();" + errorLine2=" ~~~~~~~~~~~~~"> + <location + file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/applications/StorageStatsSource.java" + line="93" + column="32"/> + </issue> + + <issue + id="NewApi" + message="Call requires API level 26 (current min is 21): `android.app.usage.ExternalStorageStats#getAppBytes`" + errorLine1=" appBytes = stats.getAppBytes();" + errorLine2=" ~~~~~~~~~~~"> + <location + file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/applications/StorageStatsSource.java" + line="94" + column="30"/> + </issue> + + <issue + id="NewApi" + message="Call requires API level 26 (current min is 21): `android.app.usage.StorageStats#getDataBytes`" + errorLine1=" return mStats.getDataBytes();" + errorLine2=" ~~~~~~~~~~~~"> + <location + file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/applications/StorageStatsSource.java" + line="127" + column="27"/> + </issue> + + <issue + id="NewApi" + message="Call requires API level 26 (current min is 21): `android.app.usage.StorageStats#getCacheBytes`" + errorLine1=" return mStats.getCacheBytes();" + errorLine2=" ~~~~~~~~~~~~~"> + <location + file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/applications/StorageStatsSource.java" + line="131" + column="27"/> + </issue> + + <issue + id="NewApi" + message="Call requires API level 26 (current min is 21): `android.app.usage.StorageStats#getAppBytes`" + errorLine1=" return mStats.getAppBytes() + mStats.getDataBytes();" + errorLine2=" ~~~~~~~~~~~"> + <location + file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/applications/StorageStatsSource.java" + line="135" + column="27"/> + </issue> + + <issue + id="NewApi" + message="Call requires API level 26 (current min is 21): `android.app.usage.StorageStats#getDataBytes`" + errorLine1=" return mStats.getAppBytes() + mStats.getDataBytes();" + errorLine2=" ~~~~~~~~~~~~"> + <location + file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/applications/StorageStatsSource.java" + line="135" + column="50"/> + </issue> + + <issue + id="NewApi" + message="Call requires API level 24 (current min is 21): `new android.icu.util.Measure`" + errorLine1=" measureList.add(new Measure(days, MeasureUnit.DAY));" + errorLine2=" ~~~~~~~~~~~"> + <location + file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/utils/StringUtil.java" + line="77" + column="29"/> + </issue> + + <issue + id="NewApi" + message="Cast from `TimeUnit` to `MeasureUnit` requires API level 24 (current min is 21)" + errorLine1=" measureList.add(new Measure(days, MeasureUnit.DAY));" + errorLine2=" ~~~~~~~~~~~~~~~"> + <location + file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/utils/StringUtil.java" + line="77" + column="47"/> + </issue> + + <issue + id="NewApi" + message="Field requires API level 24 (current min is 21): `android.icu.util.MeasureUnit#DAY`" + errorLine1=" measureList.add(new Measure(days, MeasureUnit.DAY));" + errorLine2=" ~~~~~~~~~~~~~~~"> + <location + file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/utils/StringUtil.java" + line="77" + column="47"/> + </issue> + + <issue + id="NewApi" + message="Call requires API level 24 (current min is 21): `new android.icu.util.Measure`" + errorLine1=" measureList.add(new Measure(hours, MeasureUnit.HOUR));" + errorLine2=" ~~~~~~~~~~~"> + <location + file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/utils/StringUtil.java" + line="80" + column="29"/> + </issue> + + <issue + id="NewApi" + message="Cast from `TimeUnit` to `MeasureUnit` requires API level 24 (current min is 21)" + errorLine1=" measureList.add(new Measure(hours, MeasureUnit.HOUR));" + errorLine2=" ~~~~~~~~~~~~~~~~"> + <location + file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/utils/StringUtil.java" + line="80" + column="48"/> + </issue> + + <issue + id="NewApi" + message="Field requires API level 24 (current min is 21): `android.icu.util.MeasureUnit#HOUR`" + errorLine1=" measureList.add(new Measure(hours, MeasureUnit.HOUR));" + errorLine2=" ~~~~~~~~~~~~~~~~"> + <location + file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/utils/StringUtil.java" + line="80" + column="48"/> + </issue> + + <issue + id="NewApi" + message="Call requires API level 24 (current min is 21): `new android.icu.util.Measure`" + errorLine1=" measureList.add(new Measure(minutes, MeasureUnit.MINUTE));" + errorLine2=" ~~~~~~~~~~~"> + <location + file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/utils/StringUtil.java" + line="83" + column="29"/> + </issue> + + <issue + id="NewApi" + message="Cast from `TimeUnit` to `MeasureUnit` requires API level 24 (current min is 21)" + errorLine1=" measureList.add(new Measure(minutes, MeasureUnit.MINUTE));" + errorLine2=" ~~~~~~~~~~~~~~~~~~"> + <location + file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/utils/StringUtil.java" + line="83" + column="50"/> + </issue> + + <issue + id="NewApi" + message="Field requires API level 24 (current min is 21): `android.icu.util.MeasureUnit#MINUTE`" + errorLine1=" measureList.add(new Measure(minutes, MeasureUnit.MINUTE));" + errorLine2=" ~~~~~~~~~~~~~~~~~~"> + <location + file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/utils/StringUtil.java" + line="83" + column="50"/> + </issue> + + <issue + id="NewApi" + message="Call requires API level 24 (current min is 21): `new android.icu.util.Measure`" + errorLine1=" measureList.add(new Measure(seconds, MeasureUnit.SECOND));" + errorLine2=" ~~~~~~~~~~~"> + <location + file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/utils/StringUtil.java" + line="86" + column="29"/> + </issue> + + <issue + id="NewApi" + message="Cast from `TimeUnit` to `MeasureUnit` requires API level 24 (current min is 21)" + errorLine1=" measureList.add(new Measure(seconds, MeasureUnit.SECOND));" + errorLine2=" ~~~~~~~~~~~~~~~~~~"> + <location + file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/utils/StringUtil.java" + line="86" + column="50"/> + </issue> + + <issue + id="NewApi" + message="Field requires API level 24 (current min is 21): `android.icu.util.MeasureUnit#SECOND`" + errorLine1=" measureList.add(new Measure(seconds, MeasureUnit.SECOND));" + errorLine2=" ~~~~~~~~~~~~~~~~~~"> + <location + file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/utils/StringUtil.java" + line="86" + column="50"/> + </issue> + + <issue + id="NewApi" + message="Call requires API level 24 (current min is 21): `new android.icu.util.Measure`" + errorLine1=" measureList.add(new Measure(0, withSeconds ? MeasureUnit.SECOND : MeasureUnit.MINUTE));" + errorLine2=" ~~~~~~~~~~~"> + <location + file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/utils/StringUtil.java" + line="90" + column="29"/> + </issue> + + <issue + id="NewApi" + message="Cast from `TimeUnit` to `MeasureUnit` requires API level 24 (current min is 21)" + errorLine1=" measureList.add(new Measure(0, withSeconds ? MeasureUnit.SECOND : MeasureUnit.MINUTE));" + errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"> + <location + file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/utils/StringUtil.java" + line="90" + column="44"/> + </issue> + + <issue + id="NewApi" + message="Field requires API level 24 (current min is 21): `android.icu.util.MeasureUnit#MINUTE`" + errorLine1=" measureList.add(new Measure(0, withSeconds ? MeasureUnit.SECOND : MeasureUnit.MINUTE));" + errorLine2=" ~~~~~~~~~~~~~~~~~~"> + <location + file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/utils/StringUtil.java" + line="90" + column="79"/> + </issue> + + <issue + id="NewApi" + message="Field requires API level 24 (current min is 21): `android.icu.util.MeasureUnit#SECOND`" + errorLine1=" measureList.add(new Measure(0, withSeconds ? MeasureUnit.SECOND : MeasureUnit.MINUTE));" + errorLine2=" ~~~~~~~~~~~~~~~~~~"> + <location + file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/utils/StringUtil.java" + line="90" + column="58"/> + </issue> + + <issue + id="NewApi" + message="Call requires API level 24 (current min is 21): `android.icu.text.MeasureFormat#getInstance`" + errorLine1=" final MeasureFormat measureFormat = MeasureFormat.getInstance(" + errorLine2=" ~~~~~~~~~~~"> + <location + file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/utils/StringUtil.java" + line="95" + column="59"/> + </issue> + + <issue + id="NewApi" + message="Field requires API level 24 (current min is 21): `android.icu.text.MeasureFormat.FormatWidth#SHORT`" + errorLine1=" locale, FormatWidth.SHORT);" + errorLine2=" ~~~~~~~~~~~~~~~~~"> + <location + file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/utils/StringUtil.java" + line="96" + column="25"/> + </issue> + + <issue + id="NewApi" + message="Call requires API level 24 (current min is 21): `android.icu.text.MeasureFormat#formatMeasures`" + errorLine1=" sb.append(measureFormat.formatMeasures(measureArray));" + errorLine2=" ~~~~~~~~~~~~~~"> + <location + file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/utils/StringUtil.java" + line="97" + column="33"/> + </issue> + + <issue + id="NewApi" + message="Call requires API level 24 (current min is 21): `android.icu.util.Measure#getUnit`" + errorLine1=" if (measureArray.length == 1 && MeasureUnit.MINUTE.equals(measureArray[0].getUnit())) {" + errorLine2=" ~~~~~~~"> + <location + file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/utils/StringUtil.java" + line="99" + column="83"/> + </issue> + + <issue + id="NewApi" + message="Field requires API level 24 (current min is 21): `android.icu.util.MeasureUnit#MINUTE`" + errorLine1=" if (measureArray.length == 1 && MeasureUnit.MINUTE.equals(measureArray[0].getUnit())) {" + errorLine2=" ~~~~~~~~~~~~~~~~~~"> + <location + file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/utils/StringUtil.java" + line="99" + column="41"/> + </issue> + + <issue + id="NewApi" + message="Field requires API level 24 (current min is 21): `android.icu.text.RelativeDateTimeFormatter.RelativeUnit#MINUTES`" + errorLine1=" unit = RelativeUnit.MINUTES;" + errorLine2=" ~~~~~~~~~~~~~~~~~~~~"> + <location + file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/utils/StringUtil.java" + line="132" + column="20"/> + </issue> + + <issue + id="NewApi" + message="Field requires API level 24 (current min is 21): `android.icu.text.RelativeDateTimeFormatter.RelativeUnit#HOURS`" + errorLine1=" unit = RelativeUnit.HOURS;" + errorLine2=" ~~~~~~~~~~~~~~~~~~"> + <location + file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/utils/StringUtil.java" + line="136" + column="20"/> + </issue> + + <issue + id="NewApi" + message="Field requires API level 24 (current min is 21): `android.icu.text.RelativeDateTimeFormatter.RelativeUnit#DAYS`" + errorLine1=" unit = RelativeUnit.DAYS;" + errorLine2=" ~~~~~~~~~~~~~~~~~"> + <location + file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/utils/StringUtil.java" + line="140" + column="20"/> + </issue> + + <issue + id="NewApi" + message="Call requires API level 24 (current min is 21): `android.icu.text.RelativeDateTimeFormatter#getInstance`" + errorLine1=" final RelativeDateTimeFormatter formatter = RelativeDateTimeFormatter.getInstance(" + errorLine2=" ~~~~~~~~~~~"> + <location + file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/utils/StringUtil.java" + line="146" + column="79"/> + </issue> + + <issue + id="NewApi" + message="Call requires API level 24 (current min is 21): `android.icu.util.ULocale#forLocale`" + errorLine1=" ULocale.forLocale(locale)," + errorLine2=" ~~~~~~~~~"> + <location + file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/utils/StringUtil.java" + line="147" + column="25"/> + </issue> + + <issue + id="NewApi" + message="Field requires API level 24 (current min is 21): `android.icu.text.DisplayContext#CAPITALIZATION_FOR_MIDDLE_OF_SENTENCE`" + errorLine1=" android.icu.text.DisplayContext.CAPITALIZATION_FOR_MIDDLE_OF_SENTENCE);" + errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"> + <location + file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/utils/StringUtil.java" + line="150" + column="17"/> + </issue> + + <issue + id="NewApi" + message="Call requires API level 24 (current min is 21): `android.icu.text.RelativeDateTimeFormatter#format`" + errorLine1=" return formatter.format(value, RelativeDateTimeFormatter.Direction.LAST, unit);" + errorLine2=" ~~~~~~"> + <location + file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/utils/StringUtil.java" + line="152" + column="26"/> + </issue> + + <issue + id="NewApi" + message="Field requires API level 24 (current min is 21): `android.icu.text.RelativeDateTimeFormatter.Direction#LAST`" + errorLine1=" return formatter.format(value, RelativeDateTimeFormatter.Direction.LAST, unit);" + errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"> + <location + file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/utils/StringUtil.java" + line="152" + column="40"/> + </issue> + + <issue + id="NewApi" + message="Field requires API level 24 (current min is 21): `android.icu.text.RelativeDateTimeFormatter.Style#LONG`" + errorLine1=" RelativeDateTimeFormatter.Style.LONG);" + errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"> + <location + file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/utils/StringUtil.java" + line="174" + column="17"/> + </issue> + + <issue + id="NewApi" + message="Call requires API level R (current min is 21): `android.content.Context#bindServiceAsUser`" + errorLine1=" mContext.bindServiceAsUser(mServiceIntent, mServiceConnection, Context.BIND_AUTO_CREATE," + errorLine2=" ~~~~~~~~~~~~~~~~~"> + <location + file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/suggestions/SuggestionController.java" + line="83" + column="18"/> + </issue> + + <issue + id="NewApi" + message="Call requires API level R (current min is 21): `new android.net.NetworkInfo`" + errorLine1=" mNetworkInfo = new NetworkInfo(" + errorLine2=" ~~~~~~~~~~~~~~~"> + <location + file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/wifi/TestAccessPointBuilder.java" + line="110" + column="28"/> + </issue> + + <issue + id="NewApi" + message="Call requires API level 23 (current min is 21): `android.content.Context#getSystemService`" + errorLine1=" WifiManager wifiManager = mContext.getSystemService(WifiManager.class);" + errorLine2=" ~~~~~~~~~~~~~~~~"> + <location + file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/wifi/TestAccessPointBuilder.java" + line="130" + column="44"/> + </issue> + + <issue + id="NewApi" + message="Call requires API level R (current min is 21): `android.net.wifi.WifiManager#getMaxSignalLevel`" + errorLine1=" int maxSignalLevel = wifiManager.getMaxSignalLevel();" + errorLine2=" ~~~~~~~~~~~~~~~~~"> + <location + file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/wifi/TestAccessPointBuilder.java" + line="131" + column="42"/> + </issue> + + <issue + id="NewApi" + message="Call requires API level 23 (current min is 21): `android.content.Context#getSystemService`" + errorLine1=" final ConnectivityManager cm = context.getSystemService(ConnectivityManager.class);" + errorLine2=" ~~~~~~~~~~~~~~~~"> + <location + file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/TetherUtil.java" + line="26" + column="48"/> + </issue> + + <issue + id="NewApi" + message="Call requires API level 29 (current min is 21): `android.graphics.Paint#setBlendMode`" + errorLine1=" p.blendMode = BlendMode.SRC" + errorLine2=" ~~~~~~~~~"> + <location + file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/graph/ThemedBatteryDrawable.kt" + line="115" + column="11"/> + </issue> + + <issue + id="NewApi" + message="Field requires API level 29 (current min is 21): `android.graphics.BlendMode#SRC`" + errorLine1=" p.blendMode = BlendMode.SRC" + errorLine2=" ~~~~~~~~~~~~~"> + <location + file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/graph/ThemedBatteryDrawable.kt" + line="115" + column="23"/> + </issue> + + <issue + id="NewApi" + message="Field requires API level 29 (current min is 21): `android.graphics.BlendMode#SRC`" + errorLine1=" p.blendMode = BlendMode.SRC" + errorLine2=" ~~~~~~~~~~~~~"> + <location + file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/graph/ThemedBatteryDrawable.kt" + line="115" + column="23"/> + </issue> + + <issue + id="NewApi" + message="Call requires API level 29 (current min is 21): `android.graphics.Paint#setBlendMode`" + errorLine1=" p.blendMode = BlendMode.CLEAR" + errorLine2=" ~~~~~~~~~"> + <location + file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/graph/ThemedBatteryDrawable.kt" + line="124" + column="11"/> + </issue> + + <issue + id="NewApi" + message="Field requires API level 29 (current min is 21): `android.graphics.BlendMode#CLEAR`" + errorLine1=" p.blendMode = BlendMode.CLEAR" + errorLine2=" ~~~~~~~~~~~~~~~"> + <location + file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/graph/ThemedBatteryDrawable.kt" + line="124" + column="23"/> + </issue> + + <issue + id="NewApi" + message="Field requires API level 29 (current min is 21): `android.graphics.BlendMode#CLEAR`" + errorLine1=" p.blendMode = BlendMode.CLEAR" + errorLine2=" ~~~~~~~~~~~~~~~"> + <location + file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/graph/ThemedBatteryDrawable.kt" + line="124" + column="23"/> + </issue> + + <issue + id="NewApi" + message="Call requires API level 29 (current min is 21): `android.graphics.Paint#setBlendMode`" + errorLine1=" p.blendMode = BlendMode.SRC" + errorLine2=" ~~~~~~~~~"> + <location + file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/graph/ThemedBatteryDrawable.kt" + line="143" + column="11"/> + </issue> + + <issue + id="NewApi" + message="Field requires API level 29 (current min is 21): `android.graphics.BlendMode#SRC`" + errorLine1=" p.blendMode = BlendMode.SRC" + errorLine2=" ~~~~~~~~~~~~~"> + <location + file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/graph/ThemedBatteryDrawable.kt" + line="143" + column="23"/> + </issue> + + <issue + id="NewApi" + message="Field requires API level 29 (current min is 21): `android.graphics.BlendMode#SRC`" + errorLine1=" p.blendMode = BlendMode.SRC" + errorLine2=" ~~~~~~~~~~~~~"> + <location + file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/graph/ThemedBatteryDrawable.kt" + line="143" + column="23"/> + </issue> + + <issue + id="NewApi" + message="Call requires API level 26 (current min is 21): `android.graphics.Canvas#clipOutPath`" + errorLine1=" c.clipOutPath(scaledBolt)" + errorLine2=" ~~~~~~~~~~~"> + <location + file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/graph/ThemedBatteryDrawable.kt" + line="240" + column="15"/> + </issue> + + <issue + id="NewApi" + message="Call requires API level 24 (current min is 21): `android.os.UserManager#supportsMultipleUsers`" + errorLine1=" detail.label = res.getString(UserManager.supportsMultipleUsers()" + errorLine2=" ~~~~~~~~~~~~~~~~~~~~~"> + <location + file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/net/UidDetailProvider.java" + line="120" + column="58"/> + </issue> + + <issue + id="NewApi" + message="Call requires API level 23 (current min is 21): `android.content.Context#getSystemService`" + errorLine1=" final TetheringManager tm = mContext.getSystemService(TetheringManager.class);" + errorLine2=" ~~~~~~~~~~~~~~~~"> + <location + file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/net/UidDetailProvider.java" + line="126" + column="54"/> + </issue> + + <issue + id="NewApi" + message="Call requires API level 23 (current min is 21): `android.content.Context#getSystemService`" + errorLine1=" boolean isManaged = context.getSystemService(DevicePolicyManager.class)" + errorLine2=" ~~~~~~~~~~~~~~~~"> + <location + file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/drawable/UserIconDrawable.java" + line="176" + column="41"/> + </issue> + + <issue + id="NewApi" + message="Call requires API level 22 (current min is 21): `android.telephony.TelephonyManager#isVoiceCapable`" + errorLine1=" return telephony != null && telephony.isVoiceCapable();" + errorLine2=" ~~~~~~~~~~~~~~"> + <location + file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/volume/Util.java" + line="185" + column="47"/> + </issue> + + <issue + id="NewApi" + message="Call requires API level 23 (current min is 21): `android.content.Context#getSystemService`" + errorLine1=" LocationManager locationManager = context.getSystemService(LocationManager.class);" + errorLine2=" ~~~~~~~~~~~~~~~~"> + <location + file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/Utils.java" + line="82" + column="51"/> + </issue> + + <issue + id="NewApi" + message="Call requires API level 23 (current min is 21): `android.content.res.Resources#getColorStateList`" + errorLine1=" context.getResources().getColorStateList(resId, context.getTheme());" + errorLine2=" ~~~~~~~~~~~~~~~~~"> + <location + file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/Utils.java" + line="246" + column="40"/> + </issue> + + <issue + id="NewApi" + message="Call requires API level 23 (current min is 21): `android.content.Context#getSystemService`" + errorLine1=" return !context.getSystemService(TelephonyManager.class).isDataCapable();" + errorLine2=" ~~~~~~~~~~~~~~~~"> + <location + file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/Utils.java" + line="438" + column="25"/> + </issue> + + <issue + id="NewApi" + message="Call requires API level 31 (current min is 21): `android.telephony.TelephonyManager#isDataCapable`" + errorLine1=" return !context.getSystemService(TelephonyManager.class).isDataCapable();" + errorLine2=" ~~~~~~~~~~~~~"> + <location + file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/Utils.java" + line="438" + column="66"/> + </issue> + + <issue + id="NewApi" + message="Call requires API level 23 (current min is 21): `android.content.Context#getSystemService`" + errorLine1=" final AudioManager audioManager = context.getSystemService(AudioManager.class);" + errorLine2=" ~~~~~~~~~~~~~~~~"> + <location + file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/Utils.java" + line="459" + column="51"/> + </issue> + + <issue + id="NewApi" + message="Call requires API level 22 (current min is 21): `android.content.pm.PackageItemInfo#loadUnbadgedIcon`" + errorLine1=" return getBadgedIcon(context, appInfo.loadUnbadgedIcon(context.getPackageManager())," + errorLine2=" ~~~~~~~~~~~~~~~~"> + <location + file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/Utils.java" + line="527" + column="47"/> + </issue> + + <issue + id="NewApi" + message="Call requires API level 24 (current min is 21): `android.os.UserHandle#getUserHandleForUid`" + errorLine1=" UserHandle.getUserHandleForUid(appInfo.uid));" + errorLine2=" ~~~~~~~~~~~~~~~~~~~"> + <location + file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/Utils.java" + line="528" + column="28"/> + </issue> + + <issue + id="NewApi" + message="Call requires API level 23 (current min is 21): `android.net.wifi.WifiConfiguration#isPasspoint`" + errorLine1=" if (network.isPasspoint()) {" + errorLine2=" ~~~~~~~~~~~"> + <location + file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/wifi/WifiSavedConfigUtils.java" + line="46" + column="25"/> + </issue> + + <issue + id="NewApi" + message="Call requires API level 26 (current min is 21): `android.net.wifi.WifiManager#getPasspointConfigurations`" + errorLine1=" wifiManager.getPasspointConfigurations();" + errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~"> + <location + file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/wifi/WifiSavedConfigUtils.java" + line="57" + column="33"/> + </issue> + + <issue + id="NewApi" + message="Call requires API level R (current min is 21): `android.net.NetworkRequest.Builder#clearCapabilities`" + errorLine1=" .clearCapabilities()" + errorLine2=" ~~~~~~~~~~~~~~~~~"> + <location + file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/wifi/WifiStatusTracker.java" + line="60" + column="14"/> + </issue> + + <issue + id="NewApi" + message="Call requires API level 29 (current min is 21): `android.net.NetworkCapabilities#getTransportInfo`" + errorLine1=" WifiInfo wifiInfo = (WifiInfo) networkCapabilities.getTransportInfo();" + errorLine2=" ~~~~~~~~~~~~~~~~"> + <location + file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/wifi/WifiStatusTracker.java" + line="69" + column="64"/> + </issue> + + <issue + id="NewApi" + message="Cast from `TransportInfo` to `WifiInfo` requires API level 29 (current min is 21)" + errorLine1=" WifiInfo wifiInfo = (WifiInfo) networkCapabilities.getTransportInfo();" + errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"> + <location + file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/wifi/WifiStatusTracker.java" + line="69" + column="33"/> + </issue> + + <issue + id="NewApi" + message="Call requires API level 26 (current min is 21): `android.net.ConnectivityManager#registerNetworkCallback`" + errorLine1=" mConnectivityManager.registerNetworkCallback(" + errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~"> + <location + file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/wifi/WifiStatusTracker.java" + line="134" + column="34"/> + </issue> + + <issue + id="NewApi" + message="Call requires API level 26 (current min is 21): `android.net.ConnectivityManager#registerDefaultNetworkCallback`" + errorLine1=" mConnectivityManager.registerDefaultNetworkCallback(mDefaultNetworkCallback, mHandler);" + errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"> + <location + file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/wifi/WifiStatusTracker.java" + line="136" + column="34"/> + </issue> + + <issue + id="NewApi" + message="Call requires API level 29 (current min is 21): `android.net.wifi.WifiInfo#getPasspointProviderFriendlyName`" + errorLine1=" ssid = mWifiInfo.getPasspointProviderFriendlyName();" + errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"> + <location + file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/wifi/WifiStatusTracker.java" + line="164" + column="38"/> + </issue> + + <issue + id="NewApi" + message="Call requires API level 29 (current min is 21): `android.net.wifi.WifiInfo#getPasspointProviderFriendlyName`" + errorLine1=" ssid = mWifiInfo.getPasspointProviderFriendlyName();" + errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"> + <location + file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/wifi/WifiStatusTracker.java" + line="192" + column="34"/> + </issue> + + <issue + id="NewApi" + message="Call requires API level R (current min is 21): `android.net.wifi.WifiManager#calculateSignalLevel`" + errorLine1=" level = mWifiManager.calculateSignalLevel(rssi);" + errorLine2=" ~~~~~~~~~~~~~~~~~~~~"> + <location + file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/wifi/WifiStatusTracker.java" + line="208" + column="30"/> + </issue> + + <issue + id="NewApi" + message="Call requires API level 23 (current min is 21): `new android.util.ArraySet`" + errorLine1=" private final Set<NetworkKey> mRequestedScores = new ArraySet<>();" + errorLine2=" ~~~~~~~~~~~~~~"> + <location + file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/wifi/WifiTracker.java" + line="147" + column="54"/> + </issue> + + <issue + id="NewApi" + message="Call requires API level 23 (current min is 21): `android.content.Context#getSystemService`" + errorLine1=" context.getSystemService(WifiManager.class)," + errorLine2=" ~~~~~~~~~~~~~~~~"> + <location + file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/wifi/WifiTracker.java" + line="208" + column="25"/> + </issue> + + <issue + id="NewApi" + message="Call requires API level 23 (current min is 21): `android.content.Context#getSystemService`" + errorLine1=" context.getSystemService(ConnectivityManager.class)," + errorLine2=" ~~~~~~~~~~~~~~~~"> + <location + file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/wifi/WifiTracker.java" + line="209" + column="25"/> + </issue> + + <issue + id="NewApi" + message="Call requires API level 23 (current min is 21): `android.content.Context#getSystemService`" + errorLine1=" context.getSystemService(NetworkScoreManager.class)," + errorLine2=" ~~~~~~~~~~~~~~~~"> + <location + file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/wifi/WifiTracker.java" + line="210" + column="25"/> + </issue> + + <issue + id="NewApi" + message="Call requires API level 23 (current min is 21): `android.content.Context#getSystemService`" + errorLine1=" context.getSystemService(WifiManager.class)," + errorLine2=" ~~~~~~~~~~~~~~~~"> + <location + file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/wifi/WifiTracker.java" + line="219" + column="25"/> + </issue> + + <issue + id="NewApi" + message="Call requires API level 23 (current min is 21): `android.content.Context#getSystemService`" + errorLine1=" context.getSystemService(ConnectivityManager.class)," + errorLine2=" ~~~~~~~~~~~~~~~~"> + <location + file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/wifi/WifiTracker.java" + line="220" + column="25"/> + </issue> + + <issue + id="NewApi" + message="Call requires API level 23 (current min is 21): `android.content.Context#getSystemService`" + errorLine1=" context.getSystemService(NetworkScoreManager.class)," + errorLine2=" ~~~~~~~~~~~~~~~~"> + <location + file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/wifi/WifiTracker.java" + line="221" + column="25"/> + </issue> + + <issue + id="NewApi" + message="Call requires API level R (current min is 21): `android.net.NetworkRequest.Builder#clearCapabilities`" + errorLine1=" .clearCapabilities()" + errorLine2=" ~~~~~~~~~~~~~~~~~"> + <location + file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/wifi/WifiTracker.java" + line="243" + column="18"/> + </issue> + + <issue + id="NewApi" + message="Call requires API level 26 (current min is 21): `android.net.ConnectivityManager#registerNetworkCallback`" + errorLine1=" mConnectivityManager.registerNetworkCallback(" + errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~"> + <location + file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/wifi/WifiTracker.java" + line="348" + column="34"/> + </issue> + + <issue + id="NewApi" + message="Call requires API level 23 (current min is 21): `new android.util.ArraySet`" + errorLine1=" Set<String> seenFQDNs = new ArraySet<>();" + errorLine2=" ~~~~~~~~~~~~~~"> + <location + file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/wifi/WifiTracker.java" + line="688" + column="33"/> + </issue> + + <issue + id="NewApi" + message="Cast from `ArraySet` to `Set` requires API level 23 (current min is 21)" + errorLine1=" Set<String> seenFQDNs = new ArraySet<>();" + errorLine2=" ~~~~~~~~~~~~~~~~"> + <location + file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/wifi/WifiTracker.java" + line="688" + column="33"/> + </issue> + + <issue + id="NewApi" + message="Call requires API level 29 (current min is 21): `android.net.wifi.WifiManager#isEnhancedOpenSupported`" + errorLine1=" final boolean isOweSupported = mWifiManager.isEnhancedOpenSupported();" + errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~"> + <location + file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/wifi/WifiTracker.java" + line="1116" + column="53"/> + </issue> + + <issue + id="NewApi" + message="Call requires API level 29 (current min is 21): `android.net.wifi.WifiManager#isWpa3SaeSupported`" + errorLine1=" final boolean isSaeSupported = mWifiManager.isWpa3SaeSupported();" + errorLine2=" ~~~~~~~~~~~~~~~~~~"> + <location + file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/wifi/WifiTracker.java" + line="1117" + column="53"/> + </issue> + + <issue + id="NewApi" + message="Call requires API level 29 (current min is 21): `android.net.wifi.WifiManager#isWpa3SuiteBSupported`" + errorLine1=" final boolean isSuiteBSupported = mWifiManager.isWpa3SuiteBSupported();" + errorLine2=" ~~~~~~~~~~~~~~~~~~~~~"> + <location + file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/wifi/WifiTracker.java" + line="1118" + column="56"/> + </issue> + + <issue + id="NewApi" + message="Call requires API level R (current min is 21): `android.net.wifi.WifiInfo#getWifiStandard`" + errorLine1=" visibility.append(" standard = ").append(info.getWifiStandard());" + errorLine2=" ~~~~~~~~~~~~~~~"> + <location + file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/wifi/WifiUtils.java" + line="103" + column="59"/> + </issue> + + <issue + id="NewApi" + message="Field requires API level 24 (current min is 21): `android.service.notification.Condition#line1`" + errorLine1=" radioContentText = condition.line1;" + errorLine2=" ~~~~~~~~~~~~~~~"> + <location + file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/notification/ZenDurationDialog.java" + line="285" + column="36"/> + </issue> + + <issue + id="NewApi" + message="Call requires API level 22 (current min is 21): `android.view.View#setAccessibilityTraversalAfter`" + errorLine1=" radio.setAccessibilityTraversalAfter(lastView.getId());" + errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"> + <location + file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/notification/ZenRadioLayout.java" + line="54" + column="23"/> + </issue> + + <issue + id="NewApi" + message="Call requires API level 22 (current min is 21): `android.view.View#setAccessibilityTraversalAfter`" + errorLine1=" if (contentClick != null) contentClick.setAccessibilityTraversalAfter(radio.getId());" + errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"> + <location + file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/notification/ZenRadioLayout.java" + line="57" + column="52"/> + </issue> + + <issue + id="NewApi" + message="Call requires API level 24 (current min is 21): `android.icu.text.TimeZoneFormat#getInstance`" + errorLine1=" TimeZoneFormat tzFormatter = TimeZoneFormat.getInstance(locale);" + errorLine2=" ~~~~~~~~~~~"> + <location + file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/datetime/ZoneGetter.java" + line="99" + column="53"/> + </issue> + + <issue + id="NewApi" + message="Call requires API level 24 (current min is 21): `android.icu.text.TimeZoneNames#getInstance`" + errorLine1=" TimeZoneNames timeZoneNames = TimeZoneNames.getInstance(locale);" + errorLine2=" ~~~~~~~~~~~"> + <location + file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/datetime/ZoneGetter.java" + line="101" + column="53"/> + </issue> + + <issue + id="NewApi" + message="Call requires API level 24 (current min is 21): `android.icu.text.TimeZoneNames#getInstance`" + errorLine1=" final TimeZoneNames timeZoneNames = TimeZoneNames.getInstance(locale);" + errorLine2=" ~~~~~~~~~~~"> + <location + file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/datetime/ZoneGetter.java" + line="114" + column="59"/> + </issue> + + <issue + id="NewApi" + message="Call requires API level 24 (current min is 21): `android.icu.util.TimeZone#getCanonicalID`" + errorLine1=" String canonicalZoneId = android.icu.util.TimeZone.getCanonicalID(tz.getID());" + errorLine2=" ~~~~~~~~~~~~~~"> + <location + file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/datetime/ZoneGetter.java" + line="222" + column="64"/> + </issue> + + <issue + id="NewApi" + message="Call requires API level 24 (current min is 21): `android.icu.text.TimeZoneNames#getExemplarLocationName`" + errorLine1=" displayName = timeZoneNames.getExemplarLocationName(canonicalZoneId);" + errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~"> + <location + file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/datetime/ZoneGetter.java" + line="226" + column="41"/> + </issue> + + <issue + id="NewApi" + message="Field requires API level 24 (current min is 21): `android.icu.text.TimeZoneNames.NameType#LONG_DAYLIGHT`" + errorLine1=" tz.inDaylightTime(now) ? TimeZoneNames.NameType.LONG_DAYLIGHT" + errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"> + <location + file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/datetime/ZoneGetter.java" + line="242" + column="42"/> + </issue> + + <issue + id="NewApi" + message="Field requires API level 24 (current min is 21): `android.icu.text.TimeZoneNames.NameType#LONG_STANDARD`" + errorLine1=" : TimeZoneNames.NameType.LONG_STANDARD;" + errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"> + <location + file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/datetime/ZoneGetter.java" + line="243" + column="27"/> + </issue> + + <issue + id="NewApi" + message="Call requires API level 24 (current min is 21): `android.icu.text.TimeZoneNames#getDisplayName`" + errorLine1=" return names.getDisplayName(getCanonicalZoneId(tz), nameType, now.getTime());" + errorLine2=" ~~~~~~~~~~~~~~"> + <location + file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/datetime/ZoneGetter.java" + line="244" + column="22"/> + </issue> + + <issue + id="NewApi" + message="Call requires API level 24 (current min is 21): `android.icu.util.TimeZone#getCanonicalID`" + errorLine1=" final String canonicalId = android.icu.util.TimeZone.getCanonicalID(id);" + errorLine2=" ~~~~~~~~~~~~~~"> + <location + file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/datetime/ZoneGetter.java" + line="249" + column="62"/> + </issue> + + <issue + id="NewApi" + message="Call requires API level 24 (current min is 21): `android.icu.text.TimeZoneFormat#getGMTPattern`" + errorLine1=" final String gmtPattern = tzFormatter.getGMTPattern();" + errorLine2=" ~~~~~~~~~~~~~"> + <location + file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/datetime/ZoneGetter.java" + line="290" + column="47"/> + </issue> + + <issue + id="NewApi" + message="Field requires API level 24 (current min is 21): `android.icu.text.TimeZoneFormat.GMTOffsetPatternType#NEGATIVE_HM`" + errorLine1=" patternType = TimeZoneFormat.GMTOffsetPatternType.NEGATIVE_HM;" + errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"> + <location + file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/datetime/ZoneGetter.java" + line="312" + column="27"/> + </issue> + + <issue + id="NewApi" + message="Field requires API level 24 (current min is 21): `android.icu.text.TimeZoneFormat.GMTOffsetPatternType#POSITIVE_HM`" + errorLine1=" patternType = TimeZoneFormat.GMTOffsetPatternType.POSITIVE_HM;" + errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"> + <location + file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/datetime/ZoneGetter.java" + line="314" + column="27"/> + </issue> + + <issue + id="NewApi" + message="Call requires API level 24 (current min is 21): `android.icu.text.TimeZoneFormat#getGMTOffsetPattern`" + errorLine1=" final String gmtOffsetPattern = tzFormatter.getGMTOffsetPattern(patternType);" + errorLine2=" ~~~~~~~~~~~~~~~~~~~"> + <location + file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/datetime/ZoneGetter.java" + line="316" + column="53"/> + </issue> + + <issue + id="NewApi" + message="Call requires API level 24 (current min is 21): `android.icu.text.TimeZoneFormat#getGMTOffsetDigits`" + errorLine1=" final String localizedDigits = tzFormatter.getGMTOffsetDigits();" + errorLine2=" ~~~~~~~~~~~~~~~~~~"> + <location + file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/datetime/ZoneGetter.java" + line="317" + column="52"/> + </issue> + + <issue + id="NewApi" + message="Call requires API level 24 (current min is 21): `android.icu.text.TimeZoneFormat#getInstance`" + errorLine1=" final TimeZoneFormat tzFormatter = TimeZoneFormat.getInstance(locale);" + errorLine2=" ~~~~~~~~~~~"> + <location + file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/datetime/ZoneGetter.java" + line="377" + column="63"/> + </issue> + + <issue + id="NewApi" + message="`?android:attr/colorError` requires API level 26 (current min is 21)" + errorLine1=" <item android:color="?android:attr/colorError" />" + errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"> + <location + file="frameworks/base/packages/SettingsLib/res/color/batterymeter_plus_color.xml" + line="17" + column="11"/> + </issue> + + <issue + id="NewApi" + message="`@android:id/switch_widget` requires API level 24 (current min is 21)" + errorLine1=" android:id="@android:id/switch_widget"" + errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"> + <location + file="frameworks/base/packages/SettingsLib/res/layout/restricted_switch_widget.xml" + line="26" + column="9"/> + </issue> + + <issue + id="NewApi" + message="`?android:attr/dialogPreferredPadding` requires API level 22 (current min is 21)" + errorLine1=" android:paddingStart="?android:attr/dialogPreferredPadding"" + errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"> + <location + file="frameworks/base/packages/SettingsLib/res/layout/settings_dialog_title.xml" + line="30" + column="9"/> + </issue> + + <issue + id="NewApi" + message="`?android:attr/dialogPreferredPadding` requires API level 22 (current min is 21)" + errorLine1=" android:paddingEnd="?android:attr/dialogPreferredPadding"" + errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"> + <location + file="frameworks/base/packages/SettingsLib/res/layout/settings_dialog_title.xml" + line="31" + column="9"/> + </issue> + + <issue + id="NewApi" + message="`?android:attr/colorError` requires API level 26 (current min is 21)" + errorLine1=" android:textColor="?android:attr/colorError"/>" + errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"> + <location + file="frameworks/base/packages/SettingsLib/res/layout/zen_mode_turn_on_dialog_container.xml" + line="58" + column="13"/> + </issue> + +</issues> diff --git a/packages/SettingsProvider/src/android/provider/settings/validators/SystemSettingsValidators.java b/packages/SettingsProvider/src/android/provider/settings/validators/SystemSettingsValidators.java index cb610fc61142..bcde58494838 100644 --- a/packages/SettingsProvider/src/android/provider/settings/validators/SystemSettingsValidators.java +++ b/packages/SettingsProvider/src/android/provider/settings/validators/SystemSettingsValidators.java @@ -89,7 +89,7 @@ public class SystemSettingsValidators { return value == null || value.length() < MAX_LENGTH; } }); - VALIDATORS.put(System.FONT_SCALE, new InclusiveFloatRangeValidator(0.85f, 1.3f)); + VALIDATORS.put(System.FONT_SCALE, new InclusiveFloatRangeValidator(0.25f, 5.0f)); VALIDATORS.put(System.DIM_SCREEN, BOOLEAN_VALIDATOR); VALIDATORS.put( System.DISPLAY_COLOR_MODE, diff --git a/packages/Shell/AndroidManifest.xml b/packages/Shell/AndroidManifest.xml index 904148f0415b..9a3b76fbd653 100644 --- a/packages/Shell/AndroidManifest.xml +++ b/packages/Shell/AndroidManifest.xml @@ -39,6 +39,75 @@ <uses-permission android:name="android.permission.WRITE_USER_DICTIONARY" /> <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" /> <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" /> + <uses-permission android:name="android.permission.RECEIVE_SMS" /> + <uses-permission android:name="android.permission.RECEIVE_WAP_PUSH" /> + <uses-permission android:name="android.permission.RECEIVE_MMS" /> + <uses-permission android:name="android.permission.READ_CELL_BROADCASTS" /> + <uses-permission android:name="android.permission.ACCESS_MEDIA_LOCATION" /> + <uses-permission android:name="android.permission.PROCESS_OUTGOING_CALLS" /> + <uses-permission android:name="android.permission.READ_PHONE_NUMBERS" /> + <uses-permission android:name="android.permission.USE_SIP" /> + <uses-permission android:name="android.permission.ANSWER_PHONE_CALLS" /> + <uses-permission android:name="android.permission.ACCEPT_HANDOVER" /> + <uses-permission android:name="android.permission.ACTIVITY_RECOGNITION" /> + <uses-permission android:name="android.permission.BODY_SENSORS" /> + <uses-permission android:name="com.android.voicemail.permission.ADD_VOICEMAIL" /> + <uses-permission android:name="android.permission.WRITE_EMBEDDED_SUBSCRIPTIONS" /> + <uses-permission android:name="android.permission.GET_PROCESS_STATE_AND_OOM_SCORE" /> + <uses-permission android:name="android.permission.READ_LOGS" /> + <uses-permission android:name="android.permission.BRIGHTNESS_SLIDER_USAGE" /> + <uses-permission android:name="android.permission.ACCESS_AMBIENT_LIGHT_STATS" /> + <uses-permission android:name="android.permission.CONFIGURE_DISPLAY_BRIGHTNESS" /> + <uses-permission android:name="android.permission.SET_VOLUME_KEY_LONG_PRESS_LISTENER" /> + <uses-permission android:name="android.permission.SET_MEDIA_KEY_LISTENER" /> + <uses-permission android:name="android.permission.INSTANT_APP_FOREGROUND_SERVICE" /> + <uses-permission android:name="android.permission.MANAGE_OWN_CALLS" /> + <uses-permission android:name="android.permission.CALL_COMPANION_APP" /> + <uses-permission android:name="android.permission.USE_FINGERPRINT" /> + <uses-permission android:name="android.permission.READ_PROFILE" /> + <uses-permission android:name="android.permission.WRITE_PROFILE" /> + <uses-permission android:name="android.permission.READ_SOCIAL_STREAM" /> + <uses-permission android:name="android.permission.WRITE_SOCIAL_STREAM" /> + <uses-permission android:name="android.permission.WRITE_SMS" /> + <uses-permission android:name="android.permission.AUTHENTICATE_ACCOUNTS" /> + <uses-permission android:name="android.permission.MANAGE_ACCOUNTS" /> + <uses-permission android:name="android.permission.USE_CREDENTIALS" /> + <uses-permission android:name="android.permission.SUBSCRIBED_FEEDS_READ" /> + <uses-permission android:name="android.permission.SUBSCRIBED_FEEDS_WRITE" /> + <uses-permission android:name="android.permission.FLASHLIGHT" /> + <uses-permission android:name="android.permission.INTERNET" /> + <uses-permission android:name="android.permission.NFC" /> + <uses-permission android:name="android.permission.NFC_TRANSACTION_EVENT" /> + <uses-permission android:name="android.permission.NFC_PREFERRED_PAYMENT_INFO" /> + <uses-permission android:name="android.permission.CHANGE_WIFI_MULTICAST_STATE" /> + <uses-permission android:name="android.permission.TRANSMIT_IR" /> + <uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" /> + <uses-permission android:name="android.permission.REQUEST_PASSWORD_COMPLEXITY" /> + <uses-permission android:name="android.permission.GET_TASKS" /> + <uses-permission android:name="android.permission.RESTART_PACKAGES" /> + <uses-permission android:name="android.permission.REQUEST_COMPANION_RUN_IN_BACKGROUND" /> + <uses-permission android:name="android.permission.REQUEST_COMPANION_USE_DATA_IN_BACKGROUND" /> + <uses-permission android:name="android.permission.REQUEST_COMPANION_PROFILE_WATCH" /> + <uses-permission android:name="android.permission.HIDE_OVERLAY_WINDOWS" /> + <uses-permission android:name="android.permission.SET_WALLPAPER_HINTS" /> + <uses-permission android:name="android.permission.READ_SYNC_SETTINGS" /> + <uses-permission android:name="android.permission.WRITE_SYNC_SETTINGS" /> + <uses-permission android:name="android.permission.READ_SYNC_STATS" /> + <uses-permission android:name="com.android.browser.permission.READ_HISTORY_BOOKMARKS" /> + <uses-permission android:name="com.android.browser.permission.WRITE_HISTORY_BOOKMARKS" /> + <uses-permission android:name="com.android.alarm.permission.SET_ALARM" /> + <uses-permission android:name="com.android.launcher.permission.INSTALL_SHORTCUT" /> + <uses-permission android:name="com.android.launcher.permission.UNINSTALL_SHORTCUT" /> + <uses-permission android:name="android.permission.PERSISTENT_ACTIVITY" /> + <uses-permission android:name="android.permission.GET_PACKAGE_SIZE" /> + <uses-permission android:name="android.permission.CHANGE_NETWORK_STATE" /> + <uses-permission android:name="android.permission.SCHEDULE_EXACT_ALARM" /> + <uses-permission android:name="android.permission.REQUEST_DELETE_PACKAGES" /> + <uses-permission android:name="android.permission.REQUEST_OBSERVE_COMPANION_DEVICE_PRESENCE" /> + <uses-permission android:name="android.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS" /> + <uses-permission android:name="android.permission.ACCESS_NOTIFICATION_POLICY" /> + <uses-permission android:name="android.permission.READ_INSTALL_SESSIONS" /> + <uses-permission android:name="android.permission.USE_FULL_SCREEN_INTENT" /> <!-- ACCESS_BACKGROUND_LOCATION is needed for testing purposes only. --> <uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION" /> <uses-permission android:name="android.permission.ACCESS_LOCATION_EXTRA_COMMANDS" /> @@ -251,10 +320,11 @@ <!-- permissions required for CTS test - PhoneStateListenerTest --> <uses-permission android:name="android.permission.LISTEN_ALWAYS_REPORTED_SIGNAL_STRENGTH" /> - <!-- Permissions required for ganting and logging --> + <!-- Permissions required for granting and logging --> <uses-permission android:name="android.permission.LOG_COMPAT_CHANGE"/> <uses-permission android:name="android.permission.READ_COMPAT_CHANGE_CONFIG"/> <uses-permission android:name="android.permission.OVERRIDE_COMPAT_CHANGE_CONFIG"/> + <uses-permission android:name="android.permission.OVERRIDE_COMPAT_CHANGE_CONFIG_ON_RELEASE_BUILD"/> <!-- Permission required for CTS test - BatterySaverTest --> <uses-permission android:name="android.permission.MODIFY_DAY_NIGHT_MODE"/> @@ -359,6 +429,9 @@ <!-- Permission needed for CTS test - CtsHdmiCecHostTestCases --> <uses-permission android:name="android.permission.HDMI_CEC" /> + <!-- Permission needed for CTS test - MediaPlayerTest --> + <uses-permission android:name="android.permission.BIND_IMS_SERVICE" /> + <!-- Permission needed for CTS test - WifiManagerTest --> <uses-permission android:name="android.permission.WIFI_ACCESS_COEX_UNSAFE_CHANNELS" /> <uses-permission android:name="android.permission.WIFI_UPDATE_COEX_UNSAFE_CHANNELS" /> @@ -383,6 +456,9 @@ <!-- Permission required for CTS test - CtsAlarmManagerTestCases --> <uses-permission android:name="android.permission.SCHEDULE_PRIORITIZED_ALARM" /> + <!-- Permission required for CTS test - CtsUwbTestCases --> + <uses-permission android:name="android.permission.UWB_PRIVILEGED" /> + <application android:label="@string/app_label" android:theme="@android:style/Theme.DeviceDefault.DayNight" android:defaultToDeviceProtectedStorage="true" diff --git a/packages/Shell/TEST_MAPPING b/packages/Shell/TEST_MAPPING index a149b5cda3ea..9bb1b4b99207 100644 --- a/packages/Shell/TEST_MAPPING +++ b/packages/Shell/TEST_MAPPING @@ -18,6 +18,20 @@ "exclude-annotation": "androidx.test.filters.FlakyTest" } ] + }, + { + "name": "CtsUiAutomationTestCases", + "options": [ + { + "include-filter": "android.app.uiautomation.cts.UiAutomationTest#testAdoptAllShellPermissions" + }, + { + "include-filter": "android.app.uiautomation.cts.UiAutomationTest#testAdoptSomeShellPermissions" + }, + { + "exclude-annotation": "androidx.test.filters.FlakyTest" + } + ] } ], "postsubmit": [ diff --git a/packages/SystemUI/shared/lint-baseline.xml b/packages/SystemUI/shared/lint-baseline.xml new file mode 100644 index 000000000000..8021fbfbb813 --- /dev/null +++ b/packages/SystemUI/shared/lint-baseline.xml @@ -0,0 +1,367 @@ +<?xml version="1.0" encoding="UTF-8"?> +<issues format="5" by="lint 4.1.0" client="cli" variant="all" version="4.1.0"> + + <issue + id="NewApi" + message="Call requires API level R (current min is 26): `android.os.RemoteException#rethrowFromSystemServer`" + errorLine1=" throw e.rethrowFromSystemServer();" + errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~"> + <location + file="frameworks/base/packages/SystemUI/shared/src/com/android/systemui/shared/system/ActivityManagerWrapper.java" + line="109" + column="21"/> + </issue> + + <issue + id="NewApi" + message="Call requires API level 29 (current min is 26): `android.graphics.Bitmap#wrapHardwareBuffer`" + errorLine1=" return Bitmap.wrapHardwareBuffer(Objects.requireNonNull(buffer), colorSpace);" + errorLine2=" ~~~~~~~~~~~~~~~~~~"> + <location + file="frameworks/base/packages/SystemUI/shared/src/com/android/systemui/shared/recents/utilities/BitmapUtil.java" + line="84" + column="23"/> + </issue> + + <issue + id="NewApi" + message="Call requires API level 29 (current min is 26): `new android.util.ArraySet`" + errorLine1=" mPluginActions = new ArraySet<>(mSharedPrefs.getStringSet(PLUGIN_ACTIONS, null));" + errorLine2=" ~~~~~~~~~~~~~~"> + <location + file="frameworks/base/packages/SystemUI/shared/src/com/android/systemui/shared/plugins/PluginPrefs.java" + line="41" + column="26"/> + </issue> + + <issue + id="NewApi" + message="Call requires API level 29 (current min is 26): `new android.util.ArraySet`" + errorLine1=" return new ArraySet<>(mPluginActions);" + errorLine2=" ~~~~~~~~~~~~~~"> + <location + file="frameworks/base/packages/SystemUI/shared/src/com/android/systemui/shared/plugins/PluginPrefs.java" + line="45" + column="16"/> + </issue> + + <issue + id="NewApi" + message="Call requires API level 28 (current min is 26): `android.graphics.Bitmap#createBitmap`" + errorLine1=" return Bitmap.createBitmap(picture);" + errorLine2=" ~~~~~~~~~~~~"> + <location + file="frameworks/base/packages/SystemUI/shared/src/com/android/systemui/shared/recents/view/RecentsTransition.java" + line="113" + column="23"/> + </issue> + + <issue + id="NewApi" + message="Call requires API level 29 (current min is 26): `android.view.SurfaceControl#release`" + errorLine1=" leash.mSurfaceControl.release();" + errorLine2=" ~~~~~~~"> + <location + file="frameworks/base/packages/SystemUI/shared/src/com/android/systemui/shared/system/RemoteAnimationTargetCompat.java" + line="86" + column="31"/> + </issue> + + <issue + id="NewApi" + message="Call requires API level 29 (current min is 26): `android.view.SurfaceControl#release`" + errorLine1=" mStartLeash.release();" + errorLine2=" ~~~~~~~"> + <location + file="frameworks/base/packages/SystemUI/shared/src/com/android/systemui/shared/system/RemoteAnimationTargetCompat.java" + line="88" + column="25"/> + </issue> + + <issue + id="NewApi" + message="Call requires API level 29 (current min is 26): `android.view.SurfaceControl#isValid`" + errorLine1=" return mSurfaceControl != null && mSurfaceControl.isValid();" + errorLine2=" ~~~~~~~"> + <location + file="frameworks/base/packages/SystemUI/shared/src/com/android/systemui/shared/system/SurfaceControlCompat.java" + line="41" + column="59"/> + </issue> + + <issue + id="NewApi" + message="Call requires API level R (current min is 26): `android.view.SurfaceControlViewHost#release`" + errorLine1=" mSurfaceControlViewHost.release();" + errorLine2=" ~~~~~~~"> + <location + file="frameworks/base/packages/SystemUI/shared/src/com/android/systemui/shared/system/SurfaceViewRequestReceiver.java" + line="61" + column="37"/> + </issue> + + <issue + id="NewApi" + message="Call requires API level R (current min is 26): `android.view.SurfaceView#getHostToken`" + errorLine1=" bundle.putBinder(KEY_HOST_TOKEN, surfaceView.getHostToken());" + errorLine2=" ~~~~~~~~~~~~"> + <location + file="frameworks/base/packages/SystemUI/shared/src/com/android/systemui/shared/system/SurfaceViewRequestUtils.java" + line="34" + column="54"/> + </issue> + + <issue + id="NewApi" + message="Call requires API level 29 (current min is 26): `android.view.SurfaceView#getSurfaceControl`" + errorLine1=" bundle.putParcelable(KEY_SURFACE_CONTROL, surfaceView.getSurfaceControl());" + errorLine2=" ~~~~~~~~~~~~~~~~~"> + <location + file="frameworks/base/packages/SystemUI/shared/src/com/android/systemui/shared/system/SurfaceViewRequestUtils.java" + line="35" + column="63"/> + </issue> + + <issue + id="NewApi" + message="Cast from `SurfaceControl` to `Parcelable` requires API level 29 (current min is 26)" + errorLine1=" bundle.putParcelable(KEY_SURFACE_CONTROL, surfaceView.getSurfaceControl());" + errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"> + <location + file="frameworks/base/packages/SystemUI/shared/src/com/android/systemui/shared/system/SurfaceViewRequestUtils.java" + line="35" + column="51"/> + </issue> + + <issue + id="NewApi" + message="Call requires API level 29 (current min is 26): `android.view.SurfaceControl#isValid`" + errorLine1=" if (mBarrierSurfaceControl == null || !mBarrierSurfaceControl.isValid()) {" + errorLine2=" ~~~~~~~"> + <location + file="frameworks/base/packages/SystemUI/shared/src/com/android/systemui/shared/system/SyncRtSurfaceTransactionApplierCompat.java" + line="106" + column="79"/> + </issue> + + <issue + id="NewApi" + message="Call requires API level 29 (current min is 26): `new android.view.SurfaceControl.Transaction`" + errorLine1=" Transaction t = new Transaction();" + errorLine2=" ~~~~~~~~~~~~~~~"> + <location + file="frameworks/base/packages/SystemUI/shared/src/com/android/systemui/shared/system/SyncRtSurfaceTransactionApplierCompat.java" + line="112" + column="33"/> + </issue> + + <issue + id="NewApi" + message="Call requires API level 29 (current min is 26): `android.view.SurfaceControl.Transaction#apply`" + errorLine1=" t.apply();" + errorLine2=" ~~~~~"> + <location + file="frameworks/base/packages/SystemUI/shared/src/com/android/systemui/shared/system/SyncRtSurfaceTransactionApplierCompat.java" + line="119" + column="19"/> + </issue> + + <issue + id="NewApi" + message="Call requires API level 29 (current min is 26): `android.view.SurfaceControl.Transaction#setAlpha`" + errorLine1=" t.setAlpha(surface, alpha);" + errorLine2=" ~~~~~~~~"> + <location + file="frameworks/base/packages/SystemUI/shared/src/com/android/systemui/shared/system/SyncRtSurfaceTransactionApplierCompat.java" + line="361" + column="19"/> + </issue> + + <issue + id="NewApi" + message="Call requires API level 29 (current min is 26): `android.view.SurfaceControl.Transaction#setLayer`" + errorLine1=" t.setLayer(surface, layer);" + errorLine2=" ~~~~~~~~"> + <location + file="frameworks/base/packages/SystemUI/shared/src/com/android/systemui/shared/system/SyncRtSurfaceTransactionApplierCompat.java" + line="364" + column="19"/> + </issue> + + <issue + id="NewApi" + message="Field requires API level 29 (current min is 26): `android.app.TaskInfo#origActivity`" + errorLine1=" ComponentName sourceComponent = t.origActivity != null" + errorLine2=" ~~~~~~~~~~~~~~"> + <location + file="frameworks/base/packages/SystemUI/shared/src/com/android/systemui/shared/recents/model/Task.java" + line="84" + column="45"/> + </issue> + + <issue + id="NewApi" + message="Field requires API level 29 (current min is 26): `android.app.TaskInfo#origActivity`" + errorLine1=" ? t.origActivity" + errorLine2=" ~~~~~~~~~~~~~~"> + <location + file="frameworks/base/packages/SystemUI/shared/src/com/android/systemui/shared/recents/model/Task.java" + line="86" + column="23"/> + </issue> + + <issue + id="NewApi" + message="Field requires API level 29 (current min is 26): `android.app.TaskInfo#taskId`" + errorLine1=" this.id = t.taskId;" + errorLine2=" ~~~~~~~~"> + <location + file="frameworks/base/packages/SystemUI/shared/src/com/android/systemui/shared/recents/model/Task.java" + line="89" + column="23"/> + </issue> + + <issue + id="NewApi" + message="Field requires API level 29 (current min is 26): `android.app.TaskInfo#baseIntent`" + errorLine1=" this.baseIntent = t.baseIntent;" + errorLine2=" ~~~~~~~~~~~~"> + <location + file="frameworks/base/packages/SystemUI/shared/src/com/android/systemui/shared/recents/model/Task.java" + line="91" + column="31"/> + </issue> + + <issue + id="NewApi" + message="Field requires API level 29 (current min is 26): `android.app.TaskInfo#taskDescription`" + errorLine1=" ActivityManager.TaskDescription td = taskInfo.taskDescription;" + errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~"> + <location + file="frameworks/base/packages/SystemUI/shared/src/com/android/systemui/shared/recents/model/Task.java" + line="280" + column="46"/> + </issue> + + <issue + id="NewApi" + message="Field requires API level 29 (current min is 26): `android.app.TaskInfo#topActivity`" + errorLine1=" taskInfo.supportsSplitScreenMultiWindow, isLocked, td, taskInfo.topActivity);" + errorLine2=" ~~~~~~~~~~~~~~~~~~~~"> + <location + file="frameworks/base/packages/SystemUI/shared/src/com/android/systemui/shared/recents/model/Task.java" + line="284" + column="72"/> + </issue> + + <issue + id="NewApi" + message="Field requires API level 29 (current min is 26): `android.app.TaskInfo#topActivity`" + errorLine1=" return info.topActivity;" + errorLine2=" ~~~~~~~~~~~~~~~~"> + <location + file="frameworks/base/packages/SystemUI/shared/src/com/android/systemui/shared/system/TaskInfoCompat.java" + line="42" + column="16"/> + </issue> + + <issue + id="NewApi" + message="Field requires API level 29 (current min is 26): `android.app.TaskInfo#taskDescription`" + errorLine1=" return info.taskDescription;" + errorLine2=" ~~~~~~~~~~~~~~~~~~~~"> + <location + file="frameworks/base/packages/SystemUI/shared/src/com/android/systemui/shared/system/TaskInfoCompat.java" + line="46" + column="16"/> + </issue> + + <issue + id="NewApi" + message="Field requires API level 29 (current min is 26): `android.app.ActivityManager.RunningTaskInfo#taskId`" + errorLine1=" onTaskMovedToFront(taskInfo.taskId);" + errorLine2=" ~~~~~~~~~~~~~~~"> + <location + file="frameworks/base/packages/SystemUI/shared/src/com/android/systemui/shared/system/TaskStackChangeListener.java" + line="86" + column="28"/> + </issue> + + <issue + id="NewApi" + message="Call requires API level 29 (current min is 26): `new android.view.SurfaceControl.Transaction`" + errorLine1=" mTransaction = new Transaction();" + errorLine2=" ~~~~~~~~~~~~~~~"> + <location + file="frameworks/base/packages/SystemUI/shared/src/com/android/systemui/shared/system/TransactionCompat.java" + line="31" + column="24"/> + </issue> + + <issue + id="NewApi" + message="Call requires API level 29 (current min is 26): `android.view.SurfaceControl.Transaction#apply`" + errorLine1=" mTransaction.apply();" + errorLine2=" ~~~~~"> + <location + file="frameworks/base/packages/SystemUI/shared/src/com/android/systemui/shared/system/TransactionCompat.java" + line="35" + column="22"/> + </issue> + + <issue + id="NewApi" + message="Call requires API level 29 (current min is 26): `android.view.SurfaceControl.Transaction#setBufferSize`" + errorLine1=" mTransaction.setBufferSize(surfaceControl.mSurfaceControl, w, h);" + errorLine2=" ~~~~~~~~~~~~~"> + <location + file="frameworks/base/packages/SystemUI/shared/src/com/android/systemui/shared/system/TransactionCompat.java" + line="54" + column="22"/> + </issue> + + <issue + id="NewApi" + message="Call requires API level 29 (current min is 26): `android.view.SurfaceControl.Transaction#setLayer`" + errorLine1=" mTransaction.setLayer(surfaceControl.mSurfaceControl, z);" + errorLine2=" ~~~~~~~~"> + <location + file="frameworks/base/packages/SystemUI/shared/src/com/android/systemui/shared/system/TransactionCompat.java" + line="59" + column="22"/> + </issue> + + <issue + id="NewApi" + message="Call requires API level 29 (current min is 26): `android.view.SurfaceControl.Transaction#setAlpha`" + errorLine1=" mTransaction.setAlpha(surfaceControl.mSurfaceControl, alpha);" + errorLine2=" ~~~~~~~~"> + <location + file="frameworks/base/packages/SystemUI/shared/src/com/android/systemui/shared/system/TransactionCompat.java" + line="64" + column="22"/> + </issue> + + <issue + id="NewApi" + message="Call requires API level 29 (current min is 26): `android.content.res.Resources#getFloat`" + errorLine1=" .getFloat(Resources.getSystem().getIdentifier(" + errorLine2=" ~~~~~~~~"> + <location + file="frameworks/base/packages/SystemUI/shared/src/com/android/systemui/shared/system/WallpaperManagerCompat.java" + line="46" + column="18"/> + </issue> + + <issue + id="NewApi" + message="Cast from `RecordingCanvas` to `Canvas` requires API level 29 (current min is 26)" + errorLine1=" WindowCallbacksCompat.this.onPostDraw(canvas);" + errorLine2=" ~~~~~~"> + <location + file="frameworks/base/packages/SystemUI/shared/src/com/android/systemui/shared/system/WindowCallbacksCompat.java" + line="59" + column="51"/> + </issue> + +</issues> diff --git a/services/Android.bp b/services/Android.bp index 872b1187a2de..0a01c955a612 100644 --- a/services/Android.bp +++ b/services/Android.bp @@ -107,6 +107,7 @@ java_library { libs: [ "android.hidl.manager-V1.0-java", "framework-tethering.stubs.module_lib", + "service-art.stubs.system_server", ], // Uncomment to enable output of certain warnings (deprecated, unchecked) @@ -146,7 +147,7 @@ stubs_defaults { " --hide DeprecationMismatch" + " --hide HiddenTypedefConstant", visibility: ["//visibility:private"], - filter_packages: ["com.android."] + filter_packages: ["com.android."], } droidstubs { @@ -161,7 +162,7 @@ droidstubs { last_released: { api_file: ":android.api.system-server.latest", removed_api_file: ":removed.api.system-server.latest", - baseline_file: ":android-incompatibilities.api.system-server.latest" + baseline_file: ":android-incompatibilities.api.system-server.latest", }, api_lint: { enabled: true, @@ -171,18 +172,24 @@ droidstubs { }, dists: [ { - targets: ["sdk", "win_sdk"], + targets: [ + "sdk", + "win_sdk", + ], dir: "apistubs/android/system-server/api", dest: "android.txt", - tag: ".api.txt" + tag: ".api.txt", }, { - targets: ["sdk", "win_sdk"], + targets: [ + "sdk", + "win_sdk", + ], dir: "apistubs/android/system-server/api", dest: "removed.txt", tag: ".removed-api.txt", }, - ] + ], } java_library { @@ -216,16 +223,22 @@ droidstubs { }, dists: [ { - targets: ["sdk", "win_sdk"], + targets: [ + "sdk", + "win_sdk", + ], dir: "apistubs/android/system-server/api", dest: "android-non-updatable.txt", - tag: ".api.txt" + tag: ".api.txt", }, { - targets: ["sdk", "win_sdk"], + targets: [ + "sdk", + "win_sdk", + ], dir: "apistubs/android/system-server/api", dest: "android-non-updatable-removed.tx", tag: ".removed-api.txt", }, - ] -}
\ No newline at end of file + ], +} diff --git a/services/autofill/java/com/android/server/autofill/Session.java b/services/autofill/java/com/android/server/autofill/Session.java index 1970b5774bbb..f5497f921315 100644 --- a/services/autofill/java/com/android/server/autofill/Session.java +++ b/services/autofill/java/com/android/server/autofill/Session.java @@ -1204,7 +1204,9 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState @Override public void onServiceDied(@NonNull RemoteFillService service) { Slog.w(TAG, "removing session because service died"); - forceRemoveSelfLocked(); + synchronized (mLock) { + forceRemoveSelfLocked(); + } } // AutoFillUiCallback diff --git a/services/backup/OWNERS b/services/backup/OWNERS index cc36b47029a2..852c689ae020 100644 --- a/services/backup/OWNERS +++ b/services/backup/OWNERS @@ -1,6 +1,5 @@ # Bug component: 656484 -aabhinav@google.com bryanmawhinney@google.com jstemmer@google.com millmore@google.com diff --git a/services/core/java/com/android/server/ConnectivityService.java b/services/core/java/com/android/server/ConnectivityService.java index 629006aa557e..2216e8980525 100644 --- a/services/core/java/com/android/server/ConnectivityService.java +++ b/services/core/java/com/android/server/ConnectivityService.java @@ -616,7 +616,9 @@ public class ConnectivityService extends IConnectivityManager.Stub } private static IDnsResolver getDnsResolver(Context context) { - return IDnsResolver.Stub.asInterface(DnsResolverServiceManager.getService(context)); + final DnsResolverServiceManager dsm = context.getSystemService( + DnsResolverServiceManager.class); + return IDnsResolver.Stub.asInterface(dsm.getService()); } /** Handler thread used for all of the handlers below. */ @@ -2260,7 +2262,9 @@ public class ConnectivityService extends IConnectivityManager.Stub netId = nai.network.getNetId(); } boolean ok = addLegacyRouteToHost(lp, addr, netId, uid); - if (DBG) log("requestRouteToHostAddress ok=" + ok); + if (DBG) { + log("requestRouteToHostAddress " + addr + nai.toShortString() + " ok=" + ok); + } return ok; } finally { Binder.restoreCallingIdentity(token); @@ -2787,6 +2791,8 @@ public class ConnectivityService extends IConnectivityManager.Stub @Override protected void dump(@NonNull FileDescriptor fd, @NonNull PrintWriter writer, @Nullable String[] args) { + if (!checkDumpPermission(mContext, TAG, writer)) return; + mPriorityDumper.dump(fd, writer, args); } @@ -2804,7 +2810,6 @@ public class ConnectivityService extends IConnectivityManager.Stub private void doDump(FileDescriptor fd, PrintWriter writer, String[] args) { final IndentingPrintWriter pw = new IndentingPrintWriter(writer, " "); - if (!checkDumpPermission(mContext, TAG, pw)) return; if (CollectionUtils.contains(args, DIAG_ARG)) { dumpNetworkDiagnostics(pw); @@ -2884,13 +2889,13 @@ public class ConnectivityService extends IConnectivityManager.Stub pw.println(); pw.println("mNetworkRequestInfoLogs (most recent first):"); pw.increaseIndent(); - mNetworkRequestInfoLogs.reverseDump(fd, pw, args); + mNetworkRequestInfoLogs.reverseDump(pw); pw.decreaseIndent(); pw.println(); pw.println("mNetworkInfoBlockingLogs (most recent first):"); pw.increaseIndent(); - mNetworkInfoBlockingLogs.reverseDump(fd, pw, args); + mNetworkInfoBlockingLogs.reverseDump(pw); pw.decreaseIndent(); pw.println(); @@ -2904,7 +2909,7 @@ public class ConnectivityService extends IConnectivityManager.Stub long duration = SystemClock.elapsedRealtime() - mLastWakeLockAcquireTimestamp; pw.println("currently holding WakeLock for: " + (duration / 1000) + "s"); } - mWakelockLogs.reverseDump(fd, pw, args); + mWakelockLogs.reverseDump(pw); pw.println(); pw.println("bandwidth update requests (by uid):"); @@ -2916,7 +2921,12 @@ public class ConnectivityService extends IConnectivityManager.Stub } } pw.decreaseIndent(); + pw.decreaseIndent(); + pw.println(); + pw.println("mOemNetworkPreferencesLogs (most recent first):"); + pw.increaseIndent(); + mOemNetworkPreferencesLogs.reverseDump(pw); pw.decreaseIndent(); } @@ -3773,6 +3783,10 @@ public class ConnectivityService extends IConnectivityManager.Stub private void destroyNativeNetwork(@NonNull NetworkAgentInfo networkAgent) { try { mNetd.networkDestroy(networkAgent.network.getNetId()); + } catch (RemoteException | ServiceSpecificException e) { + loge("Exception destroying network(networkDestroy): " + e); + } + try { mDnsResolver.destroyNetworkCache(networkAgent.network.getNetId()); } catch (RemoteException | ServiceSpecificException e) { loge("Exception destroying network: " + e); @@ -5682,7 +5696,7 @@ public class ConnectivityService extends IConnectivityManager.Stub + mNetworkRequestForCallback.requestId + " " + mRequests + (mPendingIntent == null ? "" : " to trigger " + mPendingIntent) - + "callback flags: " + mCallbackFlags; + + " callback flags: " + mCallbackFlags; } } @@ -6131,6 +6145,7 @@ public class ConnectivityService extends IConnectivityManager.Stub @Override public int registerNetworkProvider(Messenger messenger, String name) { enforceNetworkFactoryOrSettingsPermission(); + Objects.requireNonNull(messenger, "messenger must be non-null"); NetworkProviderInfo npi = new NetworkProviderInfo(name, messenger, nextNetworkProviderId(), () -> unregisterNetworkProvider(messenger)); mHandler.sendMessage(mHandler.obtainMessage(EVENT_REGISTER_NETWORK_PROVIDER, npi)); @@ -6201,6 +6216,12 @@ public class ConnectivityService extends IConnectivityManager.Stub @NonNull private ProfileNetworkPreferences mProfileNetworkPreferences = new ProfileNetworkPreferences(); + // OemNetworkPreferences activity String log entries. + private static final int MAX_OEM_NETWORK_PREFERENCE_LOGS = 20; + @NonNull + private final LocalLog mOemNetworkPreferencesLogs = + new LocalLog(MAX_OEM_NETWORK_PREFERENCE_LOGS); + /** * Determine whether a given package has a mapping in the current OemNetworkPreferences. * @param packageName the package name to check existence of a mapping for. @@ -7673,7 +7694,7 @@ public class ConnectivityService extends IConnectivityManager.Stub } void addRequestReassignment(@NonNull final RequestReassignment reassignment) { - if (Build.IS_DEBUGGABLE) { + if (Build.isDebuggable()) { // The code is never supposed to add two reassignments of the same request. Make // sure this stays true, but without imposing this expensive check on all // reassignments on all user devices. @@ -9057,6 +9078,7 @@ public class ConnectivityService extends IConnectivityManager.Stub @Override public void unregisterConnectivityDiagnosticsCallback( @NonNull IConnectivityDiagnosticsCallback callback) { + Objects.requireNonNull(callback, "callback must be non-null"); mConnectivityDiagnosticsHandler.sendMessage( mConnectivityDiagnosticsHandler.obtainMessage( ConnectivityDiagnosticsHandler @@ -9427,6 +9449,7 @@ public class ConnectivityService extends IConnectivityManager.Stub */ @Override public void unregisterQosCallback(@NonNull final IQosCallback callback) { + Objects.requireNonNull(callback, "callback must be non-null"); mQosCallbackTracker.unregisterCallback(callback); } @@ -9633,6 +9656,7 @@ public class ConnectivityService extends IConnectivityManager.Stub return; } + mOemNetworkPreferencesLogs.log("UPDATE INITIATED: " + preference); final ArraySet<NetworkRequestInfo> nris = new OemNetworkRequestFactory().createNrisFromOemNetworkPreferences(preference); replaceDefaultNetworkRequestsForPreference(nris); @@ -9786,7 +9810,7 @@ public class ConnectivityService extends IConnectivityManager.Stub } for (final UserHandle ui : users) { // Add the rules for all users as this policy is device wide. - uids.get(pref).add(UserHandle.getUid(ui, uid)); + uids.get(pref).add(ui.getUid(uid)); } } catch (PackageManager.NameNotFoundException e) { // Although this may seem like an error scenario, it is ok that uninstalled diff --git a/services/core/java/com/android/server/DropBoxManagerService.java b/services/core/java/com/android/server/DropBoxManagerService.java index 6560824fe3b7..5f6d9bd077fe 100644 --- a/services/core/java/com/android/server/DropBoxManagerService.java +++ b/services/core/java/com/android/server/DropBoxManagerService.java @@ -82,7 +82,7 @@ public final class DropBoxManagerService extends SystemService { private static final int DEFAULT_AGE_SECONDS = 3 * 86400; private static final int DEFAULT_MAX_FILES = 1000; private static final int DEFAULT_MAX_FILES_LOWRAM = 300; - private static final int DEFAULT_QUOTA_KB = 5 * 1024; + private static final int DEFAULT_QUOTA_KB = 10 * 1024; private static final int DEFAULT_QUOTA_PERCENT = 10; private static final int DEFAULT_RESERVE_PERCENT = 10; private static final int QUOTA_RESCAN_MILLIS = 5000; diff --git a/services/core/java/com/android/server/OWNERS b/services/core/java/com/android/server/OWNERS index 3bcde1204079..9821cdc64f69 100644 --- a/services/core/java/com/android/server/OWNERS +++ b/services/core/java/com/android/server/OWNERS @@ -20,6 +20,7 @@ per-file ServiceWatcher.java = sooniln@google.com per-file *Alarm* = file:/apex/jobscheduler/OWNERS per-file *AppOp* = file:/core/java/android/permission/OWNERS per-file *Battery* = file:/BATTERY_STATS_OWNERS +per-file *Binder* = file:/core/java/com/android/internal/os/BINDER_OWNERS per-file *Bluetooth* = file:/core/java/android/bluetooth/OWNERS per-file *Gnss* = file:/services/core/java/com/android/server/location/OWNERS per-file *Location* = file:/services/core/java/com/android/server/location/OWNERS diff --git a/services/core/java/com/android/server/PersistentDataBlockService.java b/services/core/java/com/android/server/PersistentDataBlockService.java index 351e616b433b..c6fdb9df49e9 100644 --- a/services/core/java/com/android/server/PersistentDataBlockService.java +++ b/services/core/java/com/android/server/PersistentDataBlockService.java @@ -23,7 +23,6 @@ import android.app.ActivityManager; import android.content.Context; import android.content.pm.PackageManager; import android.os.Binder; -import android.os.FileUtils; import android.os.IBinder; import android.os.RemoteException; import android.os.SystemProperties; @@ -45,6 +44,7 @@ import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; +import java.io.RandomAccessFile; import java.nio.ByteBuffer; import java.nio.channels.FileChannel; import java.security.MessageDigest; @@ -131,13 +131,13 @@ public class PersistentDataBlockService extends SystemService { private static final String FLASH_LOCK_UNLOCKED = "0"; private final Context mContext; + private final String mDataBlockFile; private final boolean mIsRunningDSU; private final Object mLock = new Object(); private final CountDownLatch mInitDoneSignal = new CountDownLatch(1); private int mAllowedUid = -1; private long mBlockDeviceSize; - private String mDataBlockFile; @GuardedBy("mLock") private boolean mIsWritable = true; @@ -145,8 +145,12 @@ public class PersistentDataBlockService extends SystemService { public PersistentDataBlockService(Context context) { super(context); mContext = context; - mDataBlockFile = SystemProperties.get(PERSISTENT_DATA_BLOCK_PROP); mIsRunningDSU = SystemProperties.getBoolean(GSI_RUNNING_PROP, false); + if (mIsRunningDSU) { + mDataBlockFile = GSI_SANDBOX; + } else { + mDataBlockFile = SystemProperties.get(PERSISTENT_DATA_BLOCK_PROP); + } mBlockDeviceSize = -1; // Load lazily } @@ -260,7 +264,11 @@ public class PersistentDataBlockService extends SystemService { private long getBlockDeviceSize() { synchronized (mLock) { if (mBlockDeviceSize == -1) { - mBlockDeviceSize = nativeGetBlockDeviceSize(mDataBlockFile); + if (mIsRunningDSU) { + mBlockDeviceSize = MAX_DATA_BLOCK_SIZE; + } else { + mBlockDeviceSize = nativeGetBlockDeviceSize(mDataBlockFile); + } } } @@ -290,40 +298,30 @@ public class PersistentDataBlockService extends SystemService { return true; } - private FileOutputStream getBlockOutputStream() throws IOException { - if (!mIsRunningDSU) { - return new FileOutputStream(new File(mDataBlockFile)); - } else { - File sandbox = new File(GSI_SANDBOX); - File realpdb = new File(SystemProperties.get(PERSISTENT_DATA_BLOCK_PROP)); - if (!sandbox.exists()) { - FileUtils.copy(realpdb, sandbox); - mDataBlockFile = GSI_SANDBOX; - } - Slog.i(TAG, "PersistentDataBlock copy-on-write"); - return new FileOutputStream(sandbox); - } + private FileChannel getBlockOutputChannel() throws IOException { + return new RandomAccessFile(mDataBlockFile, "rw").getChannel(); } private boolean computeAndWriteDigestLocked() { byte[] digest = computeDigestLocked(null); if (digest != null) { - DataOutputStream outputStream; + FileChannel channel; try { - outputStream = new DataOutputStream(getBlockOutputStream()); + channel = getBlockOutputChannel(); } catch (IOException e) { Slog.e(TAG, "partition not available?", e); return false; } try { - outputStream.write(digest, 0, DIGEST_SIZE_BYTES); - outputStream.flush(); + ByteBuffer buf = ByteBuffer.allocate(DIGEST_SIZE_BYTES); + buf.put(digest); + buf.flip(); + channel.write(buf); + channel.force(true); } catch (IOException e) { Slog.e(TAG, "failed to write block checksum", e); return false; - } finally { - IoUtils.closeQuietly(outputStream); } return true; } else { @@ -374,25 +372,18 @@ public class PersistentDataBlockService extends SystemService { } private void formatPartitionLocked(boolean setOemUnlockEnabled) { - DataOutputStream outputStream; - try { - outputStream = new DataOutputStream(getBlockOutputStream()); - } catch (IOException e) { - Slog.e(TAG, "partition not available?", e); - return; - } - byte[] data = new byte[DIGEST_SIZE_BYTES]; try { - outputStream.write(data, 0, DIGEST_SIZE_BYTES); - outputStream.writeInt(PARTITION_TYPE_MARKER); - outputStream.writeInt(0); // data size - outputStream.flush(); + FileChannel channel = getBlockOutputChannel(); + ByteBuffer buf = ByteBuffer.allocate(DIGEST_SIZE_BYTES + HEADER_SIZE); + buf.put(new byte[DIGEST_SIZE_BYTES]); + buf.putInt(PARTITION_TYPE_MARKER); + buf.putInt(0); + channel.write(buf); + channel.force(true); } catch (IOException e) { Slog.e(TAG, "failed to format block", e); return; - } finally { - IoUtils.closeQuietly(outputStream); } doSetOemUnlockEnabledLocked(setOemUnlockEnabled); @@ -400,16 +391,9 @@ public class PersistentDataBlockService extends SystemService { } private void doSetOemUnlockEnabledLocked(boolean enabled) { - FileOutputStream outputStream; - try { - outputStream = getBlockOutputStream(); - } catch (IOException e) { - Slog.e(TAG, "partition not available", e); - return; - } try { - FileChannel channel = outputStream.getChannel(); + FileChannel channel = getBlockOutputChannel(); channel.position(getBlockDeviceSize() - 1); @@ -417,13 +401,12 @@ public class PersistentDataBlockService extends SystemService { data.put(enabled ? (byte) 1 : (byte) 0); data.flip(); channel.write(data); - outputStream.flush(); + channel.force(true); } catch (IOException e) { Slog.e(TAG, "unable to access persistent partition", e); return; } finally { SystemProperties.set(OEM_UNLOCK_PROP, enabled ? "1" : "0"); - IoUtils.closeQuietly(outputStream); } } @@ -477,35 +460,32 @@ public class PersistentDataBlockService extends SystemService { return (int) -maxBlockSize; } - DataOutputStream outputStream; + FileChannel channel; try { - outputStream = new DataOutputStream(getBlockOutputStream()); + channel = getBlockOutputChannel(); } catch (IOException e) { Slog.e(TAG, "partition not available?", e); - return -1; + return -1; } - ByteBuffer headerAndData = ByteBuffer.allocate(data.length + HEADER_SIZE); + ByteBuffer headerAndData = ByteBuffer.allocate( + data.length + HEADER_SIZE + DIGEST_SIZE_BYTES); + headerAndData.put(new byte[DIGEST_SIZE_BYTES]); headerAndData.putInt(PARTITION_TYPE_MARKER); headerAndData.putInt(data.length); headerAndData.put(data); - + headerAndData.flip(); synchronized (mLock) { if (!mIsWritable) { - IoUtils.closeQuietly(outputStream); return -1; } try { - byte[] checksum = new byte[DIGEST_SIZE_BYTES]; - outputStream.write(checksum, 0, DIGEST_SIZE_BYTES); - outputStream.write(headerAndData.array()); - outputStream.flush(); + channel.write(headerAndData); + channel.force(true); } catch (IOException e) { Slog.e(TAG, "failed writing to the persistent data block", e); return -1; - } finally { - IoUtils.closeQuietly(outputStream); } if (computeAndWriteDigestLocked()) { @@ -565,17 +545,6 @@ public class PersistentDataBlockService extends SystemService { public void wipe() { enforceOemUnlockWritePermission(); - if (mIsRunningDSU) { - File sandbox = new File(GSI_SANDBOX); - if (sandbox.exists()) { - if (sandbox.delete()) { - mDataBlockFile = SystemProperties.get(PERSISTENT_DATA_BLOCK_PROP); - } else { - Slog.e(TAG, "Failed to wipe sandbox persistent data block"); - } - } - return; - } synchronized (mLock) { int ret = nativeWipe(mDataBlockFile); @@ -733,28 +702,18 @@ public class PersistentDataBlockService extends SystemService { } private void writeDataBuffer(long offset, ByteBuffer dataBuffer) { - FileOutputStream outputStream; - try { - outputStream = getBlockOutputStream(); - } catch (IOException e) { - Slog.e(TAG, "partition not available", e); - return; - } synchronized (mLock) { if (!mIsWritable) { - IoUtils.closeQuietly(outputStream); return; } try { - FileChannel channel = outputStream.getChannel(); + FileChannel channel = getBlockOutputChannel(); channel.position(offset); channel.write(dataBuffer); - outputStream.flush(); + channel.force(true); } catch (IOException e) { Slog.e(TAG, "unable to access persistent partition", e); return; - } finally { - IoUtils.closeQuietly(outputStream); } computeAndWriteDigestLocked(); diff --git a/services/core/java/com/android/server/TelephonyRegistry.java b/services/core/java/com/android/server/TelephonyRegistry.java index 0affda4fd561..d9ecddae558a 100644 --- a/services/core/java/com/android/server/TelephonyRegistry.java +++ b/services/core/java/com/android/server/TelephonyRegistry.java @@ -313,7 +313,7 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub { private final LocalLog mListenLog = new LocalLog(200); - private List<PhysicalChannelConfig> mPhysicalChannelConfigs; + private List<List<PhysicalChannelConfig>> mPhysicalChannelConfigs; private boolean[] mIsDataEnabled; @@ -583,9 +583,9 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub { mPreciseDataConnectionStates.add(new ArrayMap<>()); mBarringInfo.add(i, new BarringInfo()); mTelephonyDisplayInfos[i] = null; - mPhysicalChannelConfigs.add(i, new PhysicalChannelConfig.Builder().build()); mIsDataEnabled[i] = false; mDataEnabledReason[i] = TelephonyManager.DATA_ENABLED_REASON_USER; + mPhysicalChannelConfigs.add(i, new ArrayList<>()); mAllowedNetworkTypeReason[i] = -1; mAllowedNetworkTypeValue[i] = -1; mLinkCapacityEstimateLists.add(i, new ArrayList<>()); @@ -683,9 +683,9 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub { mPreciseDataConnectionStates.add(new ArrayMap<>()); mBarringInfo.add(i, new BarringInfo()); mTelephonyDisplayInfos[i] = null; - mPhysicalChannelConfigs.add(i, new PhysicalChannelConfig.Builder().build()); mIsDataEnabled[i] = false; mDataEnabledReason[i] = TelephonyManager.DATA_ENABLED_REASON_USER; + mPhysicalChannelConfigs.add(i, new ArrayList<>()); mAllowedNetworkTypeReason[i] = -1; mAllowedNetworkTypeValue[i] = -1; mLinkCapacityEstimateLists.add(i, new ArrayList<>()); @@ -1176,8 +1176,9 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub { try { r.callback.onPhysicalChannelConfigChanged( shouldSanitizeLocationForPhysicalChannelConfig(r) - ? getLocationSanitizedConfigs(mPhysicalChannelConfigs) - : mPhysicalChannelConfigs); + ? getLocationSanitizedConfigs( + mPhysicalChannelConfigs.get(phoneId)) + : mPhysicalChannelConfigs.get(phoneId)); } catch (RemoteException ex) { remove(r.binder); } @@ -2369,11 +2370,12 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub { * Send a notification to registrants that the configs of physical channel has changed for * a particular subscription. * + * @param phoneId the phone id. * @param subId the subId * @param configs a list of {@link PhysicalChannelConfig}, the configs of physical channel. */ - public void notifyPhysicalChannelConfigForSubscriber( - int subId, List<PhysicalChannelConfig> configs) { + public void notifyPhysicalChannelConfigForSubscriber(int phoneId, int subId, + List<PhysicalChannelConfig> configs) { if (!checkNotifyPermission("notifyPhysicalChannelConfig()")) { return; } @@ -2385,9 +2387,8 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub { } synchronized (mRecords) { - int phoneId = SubscriptionManager.getPhoneId(subId); if (validatePhoneId(phoneId)) { - mPhysicalChannelConfigs.set(phoneId, configs.get(phoneId)); + mPhysicalChannelConfigs.set(phoneId, configs); for (Record r : mRecords) { if (r.matchTelephonyCallbackEvent( TelephonyCallback.EVENT_PHYSICAL_CHANNEL_CONFIG_CHANGED) @@ -2594,6 +2595,7 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub { pw.println("mDataEnabledReason=" + mDataEnabledReason); pw.println("mAllowedNetworkTypeReason=" + mAllowedNetworkTypeReason[i]); pw.println("mAllowedNetworkTypeValue=" + mAllowedNetworkTypeValue[i]); + pw.println("mPhysicalChannelConfigs=" + mPhysicalChannelConfigs.get(i)); pw.println("mLinkCapacityEstimateList=" + mLinkCapacityEstimateLists.get(i)); pw.decreaseIndent(); } @@ -2604,7 +2606,6 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub { pw.println("mEmergencyNumberList=" + mEmergencyNumberList); pw.println("mDefaultPhoneId=" + mDefaultPhoneId); pw.println("mDefaultSubId=" + mDefaultSubId); - pw.println("mPhysicalChannelConfigs=" + mPhysicalChannelConfigs); pw.decreaseIndent(); diff --git a/services/core/java/com/android/server/VcnManagementService.java b/services/core/java/com/android/server/VcnManagementService.java index f7ae58ca0eb4..9c10658e7c0e 100644 --- a/services/core/java/com/android/server/VcnManagementService.java +++ b/services/core/java/com/android/server/VcnManagementService.java @@ -16,6 +16,7 @@ package com.android.server; +import static android.Manifest.permission.DUMP; import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED; import static android.net.NetworkCapabilities.TRANSPORT_WIFI; import static android.net.vcn.VcnManager.VCN_STATUS_CODE_ACTIVE; @@ -69,6 +70,7 @@ import android.util.Slog; import com.android.internal.annotations.GuardedBy; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.annotations.VisibleForTesting.Visibility; +import com.android.internal.util.IndentingPrintWriter; import com.android.net.module.util.LocationPermissionChecker; import com.android.server.vcn.TelephonySubscriptionTracker; import com.android.server.vcn.Vcn; @@ -76,7 +78,9 @@ import com.android.server.vcn.VcnContext; import com.android.server.vcn.VcnNetworkProvider; import com.android.server.vcn.util.PersistableBundleUtils; +import java.io.FileDescriptor; import java.io.IOException; +import java.io.PrintWriter; import java.util.ArrayList; import java.util.Collections; import java.util.List; @@ -168,9 +172,6 @@ public class VcnManagementService extends IVcnManagementService.Stub { @NonNull private final TrackingNetworkCallback mTrackingNetworkCallback = new TrackingNetworkCallback(); - /** Can only be assigned when {@link #systemReady()} is called, since it uses AppOpsManager. */ - @Nullable private LocationPermissionChecker mLocationPermissionChecker; - @GuardedBy("mLock") @NonNull private final Map<ParcelUuid, VcnConfig> mConfigs = new ArrayMap<>(); @@ -369,7 +370,6 @@ public class VcnManagementService extends IVcnManagementService.Stub { new NetworkRequest.Builder().clearCapabilities().build(), mTrackingNetworkCallback); mTelephonySubscriptionTracker.register(); - mLocationPermissionChecker = mDeps.newLocationPermissionChecker(mVcnContext.getContext()); } private void enforcePrimaryUser() { @@ -836,13 +836,6 @@ public class VcnManagementService extends IVcnManagementService.Stub { return false; } - if (!mLocationPermissionChecker.checkLocationPermission( - cbInfo.mPkgName, - "VcnStatusCallback" /* featureId */, - cbInfo.mUid, - null /* message */)) { - return false; - } return true; } @@ -929,6 +922,33 @@ public class VcnManagementService extends IVcnManagementService.Stub { } } + /** + * Dumps the state of the VcnManagementService for logging and debugging purposes. + * + * <p>PII and credentials MUST NEVER be dumped here. + */ + @Override + protected void dump(FileDescriptor fd, PrintWriter writer, String[] args) { + mContext.enforceCallingOrSelfPermission(DUMP, TAG); + + final IndentingPrintWriter pw = new IndentingPrintWriter(writer, " "); + + pw.println("VcnManagementService dump:"); + pw.increaseIndent(); + + mNetworkProvider.dump(pw); + + synchronized (mLock) { + pw.println("mVcns:"); + for (Vcn vcn : mVcns.values()) { + vcn.dump(pw); + } + pw.println(); + } + + pw.decreaseIndent(); + } + // TODO(b/180452282): Make name more generic and implement directly with VcnManagementService /** Callback for Vcn signals sent up to VcnManagementService. */ public interface VcnCallback { diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java index cc5a25a57e38..2744f11f1c4e 100644 --- a/services/core/java/com/android/server/am/ActivityManagerService.java +++ b/services/core/java/com/android/server/am/ActivityManagerService.java @@ -236,6 +236,7 @@ import android.graphics.Rect; import android.hardware.display.DisplayManagerInternal; import android.location.LocationManager; import android.media.audiofx.AudioEffect; +import android.net.ConnectivityManager; import android.net.Proxy; import android.net.Uri; import android.os.AppZygote; @@ -16458,7 +16459,7 @@ public class ActivityManagerService extends IActivityManager.Stub stats.noteCurrentTimeChangedLocked(); } break; - case Intent.ACTION_CLEAR_DNS_CACHE: + case ConnectivityManager.ACTION_CLEAR_DNS_CACHE: mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG); break; case Proxy.PROXY_CHANGE_ACTION: diff --git a/services/core/java/com/android/server/am/ProcessList.java b/services/core/java/com/android/server/am/ProcessList.java index 1667901fcd4f..444418cd3d6e 100644 --- a/services/core/java/com/android/server/am/ProcessList.java +++ b/services/core/java/com/android/server/am/ProcessList.java @@ -1722,12 +1722,13 @@ public final class ProcessList { private boolean enableNativeHeapZeroInit(ProcessRecord app) { // Look at the process attribute first. - if (app.processInfo != null && app.processInfo.nativeHeapZeroInit != null) { - return app.processInfo.nativeHeapZeroInit; + if (app.processInfo != null + && app.processInfo.nativeHeapZeroInitialized != ApplicationInfo.ZEROINIT_DEFAULT) { + return app.processInfo.nativeHeapZeroInitialized == ApplicationInfo.ZEROINIT_ENABLED; } // Then at the application attribute. - if (app.info.isNativeHeapZeroInit() != null) { - return app.info.isNativeHeapZeroInit(); + if (app.info.getNativeHeapZeroInitialized() != ApplicationInfo.ZEROINIT_DEFAULT) { + return app.info.getNativeHeapZeroInitialized() == ApplicationInfo.ZEROINIT_ENABLED; } // Compat feature last. if (mPlatformCompat.isChangeEnabled(NATIVE_HEAP_ZERO_INIT, app.info)) { diff --git a/services/core/java/com/android/server/am/ProcessRecord.java b/services/core/java/com/android/server/am/ProcessRecord.java index 4775541c6781..5ebf603a109e 100644 --- a/services/core/java/com/android/server/am/ProcessRecord.java +++ b/services/core/java/com/android/server/am/ProcessRecord.java @@ -650,7 +650,7 @@ class ProcessRecord implements WindowProcessListener { if (procInfo != null && procInfo.deniedPermissions == null && procInfo.gwpAsanMode == ApplicationInfo.GWP_ASAN_DEFAULT && procInfo.memtagMode == ApplicationInfo.MEMTAG_DEFAULT - && procInfo.nativeHeapZeroInit == null) { + && procInfo.nativeHeapZeroInitialized == ApplicationInfo.ZEROINIT_DEFAULT) { // If this process hasn't asked for permissions to be denied, or for a // non-default GwpAsan mode, or any other non-default setting, then we don't // care about it. diff --git a/services/core/java/com/android/server/appop/AppOpsService.java b/services/core/java/com/android/server/appop/AppOpsService.java index f2236d71948c..db8dc715214a 100644 --- a/services/core/java/com/android/server/appop/AppOpsService.java +++ b/services/core/java/com/android/server/appop/AppOpsService.java @@ -3003,8 +3003,8 @@ public class AppOpsService extends IAppOpsService.Stub { // This is a workaround for R QPR, new API change is not allowed. We only allow the current // voice recognizer is also the voice interactor to noteproxy op. - final boolean isTrustVoiceServiceProxy = - AppOpsManager.isTrustedVoiceServiceProxy(mContext, proxyPackageName, code); + final boolean isTrustVoiceServiceProxy = AppOpsManager.isTrustedVoiceServiceProxy(mContext, + proxyPackageName, code, UserHandle.getUserId(proxyUid)); final boolean isSelfBlame = Binder.getCallingUid() == proxiedUid; final boolean isProxyTrusted = mContext.checkPermission( Manifest.permission.UPDATE_APP_OPS_STATS, -1, proxyUid) diff --git a/services/core/java/com/android/server/clipboard/ClipboardService.java b/services/core/java/com/android/server/clipboard/ClipboardService.java index 72160c203595..f4e06d377a83 100644 --- a/services/core/java/com/android/server/clipboard/ClipboardService.java +++ b/services/core/java/com/android/server/clipboard/ClipboardService.java @@ -52,10 +52,6 @@ import android.os.SystemProperties; import android.os.UserHandle; import android.os.UserManager; import android.provider.Settings; -import android.system.ErrnoException; -import android.system.Os; -import android.system.OsConstants; -import android.system.VmSocketAddress; import android.text.TextUtils; import android.util.Slog; import android.util.SparseArray; @@ -67,128 +63,9 @@ import com.android.server.contentcapture.ContentCaptureManagerInternal; import com.android.server.uri.UriGrantsManagerInternal; import com.android.server.wm.WindowManagerInternal; -import java.io.FileDescriptor; -import java.io.InterruptedIOException; -import java.net.SocketException; -import java.nio.ByteBuffer; -import java.nio.ByteOrder; -import java.util.Arrays; import java.util.HashSet; import java.util.List; - -// The following class is Android Emulator specific. It is used to read and -// write contents of the host system's clipboard. -class HostClipboardMonitor implements Runnable { - public interface HostClipboardCallback { - void onHostClipboardUpdated(String contents); - } - - private FileDescriptor mPipe = null; - private HostClipboardCallback mHostClipboardCallback; - private static final String PIPE_NAME = "pipe:clipboard"; - private static final int HOST_PORT = 5000; - - private static byte[] createOpenHandshake() { - // String.getBytes doesn't include the null terminator, - // but the QEMU pipe device requires the pipe service name - // to be null-terminated. - - final byte[] bits = Arrays.copyOf(PIPE_NAME.getBytes(), PIPE_NAME.length() + 1); - bits[PIPE_NAME.length()] = 0; - return bits; - } - - private boolean openPipe() { - try { - final FileDescriptor fd = Os.socket(OsConstants.AF_VSOCK, OsConstants.SOCK_STREAM, 0); - - try { - Os.connect(fd, new VmSocketAddress(HOST_PORT, OsConstants.VMADDR_CID_HOST)); - - final byte[] handshake = createOpenHandshake(); - Os.write(fd, handshake, 0, handshake.length); - mPipe = fd; - return true; - } catch (ErrnoException | SocketException | InterruptedIOException e) { - Os.close(fd); - } - } catch (ErrnoException e) { - } - - return false; - } - - private void closePipe() { - try { - final FileDescriptor fd = mPipe; - mPipe = null; - if (fd != null) { - Os.close(fd); - } - } catch (ErrnoException ignore) { - } - } - - private byte[] receiveMessage() throws ErrnoException, InterruptedIOException { - final byte[] lengthBits = new byte[4]; - Os.read(mPipe, lengthBits, 0, lengthBits.length); - - final ByteBuffer bb = ByteBuffer.wrap(lengthBits); - bb.order(ByteOrder.LITTLE_ENDIAN); - final int msgLen = bb.getInt(); - - final byte[] msg = new byte[msgLen]; - Os.read(mPipe, msg, 0, msg.length); - - return msg; - } - - private void sendMessage(byte[] msg) throws ErrnoException, InterruptedIOException { - final byte[] lengthBits = new byte[4]; - final ByteBuffer bb = ByteBuffer.wrap(lengthBits); - bb.order(ByteOrder.LITTLE_ENDIAN); - bb.putInt(msg.length); - - Os.write(mPipe, lengthBits, 0, lengthBits.length); - Os.write(mPipe, msg, 0, msg.length); - } - - public HostClipboardMonitor(HostClipboardCallback cb) { - mHostClipboardCallback = cb; - } - - @Override - public void run() { - while (!Thread.interrupted()) { - try { - // There's no guarantee that QEMU pipes will be ready at the moment - // this method is invoked. We simply try to get the pipe open and - // retry on failure indefinitely. - while ((mPipe == null) && !openPipe()) { - Thread.sleep(100); - } - - final byte[] receivedData = receiveMessage(); - mHostClipboardCallback.onHostClipboardUpdated( - new String(receivedData)); - } catch (ErrnoException | InterruptedIOException e) { - closePipe(); - } catch (InterruptedException e) { - } - } - } - - public void setHostClipboard(String content) { - try { - if (mPipe != null) { - sendMessage(content.getBytes()); - } - } catch (ErrnoException | InterruptedIOException e) { - Slog.e("HostClipboardMonitor", - "Failed to set host clipboard " + e.getMessage()); - } - } -} +import java.util.function.Consumer; /** * Implementation of the clipboard for copy and paste. @@ -214,8 +91,7 @@ public class ClipboardService extends SystemService { private final ContentCaptureManagerInternal mContentCaptureInternal; private final AutofillManagerInternal mAutofillInternal; private final IBinder mPermissionOwner; - private HostClipboardMonitor mHostClipboardMonitor = null; - private Thread mHostMonitorThread = null; + private final Consumer<ClipData> mEmulatorClipboardMonitor; private final SparseArray<PerUserClipboard> mClipboards = new SparseArray<>(); @@ -237,22 +113,13 @@ public class ClipboardService extends SystemService { final IBinder permOwner = mUgmInternal.newUriPermissionOwner("clipboard"); mPermissionOwner = permOwner; if (IS_EMULATOR) { - mHostClipboardMonitor = new HostClipboardMonitor( - new HostClipboardMonitor.HostClipboardCallback() { - @Override - public void onHostClipboardUpdated(String contents){ - ClipData clip = - new ClipData("host clipboard", - new String[]{"text/plain"}, - new ClipData.Item(contents)); - synchronized(mClipboards) { - setPrimaryClipInternal(getClipboard(0), clip, - android.os.Process.SYSTEM_UID); - } - } - }); - mHostMonitorThread = new Thread(mHostClipboardMonitor); - mHostMonitorThread.start(); + mEmulatorClipboardMonitor = new EmulatorClipboardMonitor((clip) -> { + synchronized (this) { + setPrimaryClipInternal(getClipboard(0), clip, android.os.Process.SYSTEM_UID); + } + }); + } else { + mEmulatorClipboardMonitor = (clip) -> {}; } } @@ -547,18 +414,7 @@ public class ClipboardService extends SystemService { } void setPrimaryClipInternal(@Nullable ClipData clip, int uid) { - // Push clipboard to host, if any - if (mHostClipboardMonitor != null) { - if (clip == null) { - // Someone really wants the clipboard cleared, so push empty - mHostClipboardMonitor.setHostClipboard(""); - } else if (clip.getItemCount() > 0) { - final CharSequence text = clip.getItemAt(0).getText(); - if (text != null) { - mHostClipboardMonitor.setHostClipboard(text.toString()); - } - } - } + mEmulatorClipboardMonitor.accept(clip); // Update this user final int userId = UserHandle.getUserId(uid); diff --git a/services/core/java/com/android/server/clipboard/EmulatorClipboardMonitor.java b/services/core/java/com/android/server/clipboard/EmulatorClipboardMonitor.java new file mode 100644 index 000000000000..62b701aff398 --- /dev/null +++ b/services/core/java/com/android/server/clipboard/EmulatorClipboardMonitor.java @@ -0,0 +1,168 @@ +/* + * Copyright (C) 2021 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES 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.clipboard; + +import android.annotation.Nullable; +import android.content.ClipData; +import android.system.ErrnoException; +import android.system.Os; +import android.system.OsConstants; +import android.system.VmSocketAddress; +import android.util.Slog; + +import java.io.FileDescriptor; +import java.io.InterruptedIOException; +import java.net.SocketException; +import java.nio.ByteBuffer; +import java.nio.ByteOrder; +import java.util.Arrays; +import java.util.function.Consumer; + +// The following class is Android Emulator specific. It is used to read and +// write contents of the host system's clipboard. +class EmulatorClipboardMonitor implements Consumer<ClipData> { + private static final String TAG = "EmulatorClipboardMonitor"; + private static final String PIPE_NAME = "pipe:clipboard"; + private static final int HOST_PORT = 5000; + private final Thread mHostMonitorThread; + private FileDescriptor mPipe = null; + + private static byte[] createOpenHandshake() { + // String.getBytes doesn't include the null terminator, + // but the QEMU pipe device requires the pipe service name + // to be null-terminated. + + final byte[] bits = Arrays.copyOf(PIPE_NAME.getBytes(), PIPE_NAME.length() + 1); + bits[PIPE_NAME.length()] = 0; + return bits; + } + + private boolean isPipeOpened() { + return mPipe != null; + } + + private synchronized boolean openPipe() { + if (mPipe != null) { + return true; + } + + try { + final FileDescriptor fd = Os.socket(OsConstants.AF_VSOCK, OsConstants.SOCK_STREAM, 0); + + try { + Os.connect(fd, new VmSocketAddress(HOST_PORT, OsConstants.VMADDR_CID_HOST)); + + final byte[] handshake = createOpenHandshake(); + Os.write(fd, handshake, 0, handshake.length); + mPipe = fd; + return true; + } catch (ErrnoException | SocketException | InterruptedIOException e) { + Os.close(fd); + } + } catch (ErrnoException e) { + } + + return false; + } + + private synchronized void closePipe() { + try { + final FileDescriptor fd = mPipe; + mPipe = null; + if (fd != null) { + Os.close(fd); + } + } catch (ErrnoException ignore) { + } + } + + private byte[] receiveMessage() throws ErrnoException, InterruptedIOException { + final byte[] lengthBits = new byte[4]; + Os.read(mPipe, lengthBits, 0, lengthBits.length); + + final ByteBuffer bb = ByteBuffer.wrap(lengthBits); + bb.order(ByteOrder.LITTLE_ENDIAN); + final int msgLen = bb.getInt(); + + final byte[] msg = new byte[msgLen]; + Os.read(mPipe, msg, 0, msg.length); + + return msg; + } + + private void sendMessage(final byte[] msg) throws ErrnoException, InterruptedIOException { + final byte[] lengthBits = new byte[4]; + final ByteBuffer bb = ByteBuffer.wrap(lengthBits); + bb.order(ByteOrder.LITTLE_ENDIAN); + bb.putInt(msg.length); + + Os.write(mPipe, lengthBits, 0, lengthBits.length); + Os.write(mPipe, msg, 0, msg.length); + } + + EmulatorClipboardMonitor(final Consumer<ClipData> setAndroidClipboard) { + this.mHostMonitorThread = new Thread(() -> { + while (!Thread.interrupted()) { + try { + // There's no guarantee that QEMU pipes will be ready at the moment + // this method is invoked. We simply try to get the pipe open and + // retry on failure indefinitely. + while (!openPipe()) { + Thread.sleep(100); + } + + final byte[] receivedData = receiveMessage(); + + final String str = new String(receivedData); + final ClipData clip = new ClipData("host clipboard", + new String[]{"text/plain"}, + new ClipData.Item(str)); + + setAndroidClipboard.accept(clip); + } catch (ErrnoException | InterruptedIOException e) { + closePipe(); + } catch (InterruptedException | IllegalArgumentException e) { + } + } + }); + + this.mHostMonitorThread.start(); + } + + @Override + public void accept(final @Nullable ClipData clip) { + if (clip == null) { + setHostClipboardImpl(""); + } else if (clip.getItemCount() > 0) { + final CharSequence text = clip.getItemAt(0).getText(); + if (text != null) { + setHostClipboardImpl(text.toString()); + } + } + } + + private void setHostClipboardImpl(final String value) { + try { + if (isPipeOpened()) { + sendMessage(value.getBytes()); + } + } catch (ErrnoException | InterruptedIOException e) { + Slog.e(TAG, "Failed to set host clipboard " + e.getMessage()); + } catch (IllegalArgumentException e) { + } + } +} diff --git a/services/core/java/com/android/server/clipboard/OWNERS b/services/core/java/com/android/server/clipboard/OWNERS new file mode 100644 index 000000000000..5449df908051 --- /dev/null +++ b/services/core/java/com/android/server/clipboard/OWNERS @@ -0,0 +1 @@ +per-file EmulatorClipboardMonitor.java = bohu@google.com,lfy@google.com,rkir@google.com diff --git a/services/core/java/com/android/server/connectivity/DnsManager.java b/services/core/java/com/android/server/connectivity/DnsManager.java index ffeb77d1d109..cf4fe1ef9f97 100644 --- a/services/core/java/com/android/server/connectivity/DnsManager.java +++ b/services/core/java/com/android/server/connectivity/DnsManager.java @@ -420,7 +420,7 @@ public class DnsManager { /* * Tell the VMs to toss their DNS caches */ - final Intent intent = new Intent(Intent.ACTION_CLEAR_DNS_CACHE); + final Intent intent = new Intent(ConnectivityManager.ACTION_CLEAR_DNS_CACHE); intent.addFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING); /* * Connectivity events can happen before boot has completed ... diff --git a/services/core/java/com/android/server/connectivity/PermissionMonitor.java b/services/core/java/com/android/server/connectivity/PermissionMonitor.java index 37116797d8d7..7837e6e812f8 100644 --- a/services/core/java/com/android/server/connectivity/PermissionMonitor.java +++ b/services/core/java/com/android/server/connectivity/PermissionMonitor.java @@ -286,7 +286,7 @@ public class PermissionMonitor { for (UserHandle user : users) { if (user == null) continue; - list.add(UserHandle.getUid(user, app.getKey())); + list.add(user.getUid(app.getKey())); } } try { @@ -555,7 +555,7 @@ public class PermissionMonitor { final UserHandle handle = UserHandle.of(userId); if (handle == null) continue; - final int uid = UserHandle.getUid(handle, appId); + final int uid = handle.getUid(appId); if (range.contains(uid)) { result.add(uid); } diff --git a/services/core/java/com/android/server/hdmi/ArcTerminationActionFromAvr.java b/services/core/java/com/android/server/hdmi/ArcTerminationActionFromAvr.java index dedf2e28a573..049a339957cb 100644 --- a/services/core/java/com/android/server/hdmi/ArcTerminationActionFromAvr.java +++ b/services/core/java/com/android/server/hdmi/ArcTerminationActionFromAvr.java @@ -49,10 +49,7 @@ public class ArcTerminationActionFromAvr extends HdmiCecFeatureAction { switch (cmd.getOpcode()) { case Constants.MESSAGE_REPORT_ARC_TERMINATED: mState = STATE_ARC_TERMINATED; - audioSystem().setArcStatus(false); - if (audioSystem().getLocalActivePort() == Constants.CEC_SWITCH_ARC) { - audioSystem().routeToInputFromPortId(audioSystem().getRoutingPort()); - } + audioSystem().processArcTermination(); finish(); return true; } diff --git a/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceAudioSystem.java b/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceAudioSystem.java index f876e1ad4b88..afaae8a5b776 100644 --- a/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceAudioSystem.java +++ b/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceAudioSystem.java @@ -353,7 +353,6 @@ public class HdmiCecLocalDeviceAudioSystem extends HdmiCecLocalDeviceSource { super.disableDevice(initiatedByCec, callback); assertRunOnServiceThread(); mService.unregisterTvInputCallback(mTvInputCallback); - // TODO(b/129088603): check disableDevice and onStandby behaviors per spec } @Override @@ -557,8 +556,12 @@ public class HdmiCecLocalDeviceAudioSystem extends HdmiCecLocalDeviceSource { @ServiceThreadOnly protected boolean handleReportArcInitiate(HdmiCecMessage message) { assertRunOnServiceThread(); - // TODO(amyjojo): implement report arc initiate handler - HdmiLogger.debug(TAG + "Stub handleReportArcInitiate"); + /* + * Ideally, we should have got this response before the {@link ArcInitiationActionFromAvr} + * has timed out. Even if the response is late, {@link ArcInitiationActionFromAvr + * #handleInitiateArcTimeout()} would not have disabled ARC. So nothing needs to be done + * here. + */ return true; } @@ -566,8 +569,7 @@ public class HdmiCecLocalDeviceAudioSystem extends HdmiCecLocalDeviceSource { @ServiceThreadOnly protected boolean handleReportArcTermination(HdmiCecMessage message) { assertRunOnServiceThread(); - // TODO(amyjojo): implement report arc terminate handler - HdmiLogger.debug(TAG + "Stub handleReportArcTermination"); + processArcTermination(); return true; } @@ -912,6 +914,14 @@ public class HdmiCecLocalDeviceAudioSystem extends HdmiCecLocalDeviceSource { mArcEstablished = enabled; } + void processArcTermination() { + setArcStatus(false); + // Switch away from ARC input when ARC is terminated. + if (getLocalActivePort() == Constants.CEC_SWITCH_ARC) { + routeToInputFromPortId(getRoutingPort()); + } + } + /** Switch hardware ARC circuit in the system. */ @ServiceThreadOnly private void enableAudioReturnChannel(boolean enabled) { @@ -1035,7 +1045,6 @@ public class HdmiCecLocalDeviceAudioSystem extends HdmiCecLocalDeviceSource { } protected void switchToAudioInput() { - // TODO(b/111396634): switch input according to PROPERTY_SYSTEM_AUDIO_MODE_AUDIO_PORT } protected boolean isDirectConnectToTv() { diff --git a/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceSource.java b/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceSource.java index 470a25bbae6c..3d1a49e4f20a 100644 --- a/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceSource.java +++ b/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceSource.java @@ -201,7 +201,6 @@ abstract class HdmiCecLocalDeviceSource extends HdmiCecLocalDevice { // Only source devices that react to routing control messages should implement // this method (e.g. a TV with built in switch). - // TODO(): decide which type will handle the routing when multi device type is supported protected void handleRoutingChangeAndInformation(int physicalAddress, HdmiCecMessage message) { // do nothing } diff --git a/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceTv.java b/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceTv.java index 58a702527e5f..8bb5204ee083 100644 --- a/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceTv.java +++ b/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceTv.java @@ -800,7 +800,9 @@ final class HdmiCecLocalDeviceTv extends HdmiCecLocalDevice { assertRunOnServiceThread(); if (!mService.isPowerStandbyOrTransient()) { addAndStartAction(new SystemAudioAutoInitiationAction(this, avr.getLogicalAddress())); - if (isConnected(avr.getPortId()) && isArcFeatureEnabled(avr.getPortId()) + if (!isDirectConnectAddress(avr.getPhysicalAddress())) { + startArcAction(false); + } else if (isConnected(avr.getPortId()) && isArcFeatureEnabled(avr.getPortId()) && !hasAction(SetArcTransmissionStateAction.class)) { startArcAction(true); } diff --git a/services/core/java/com/android/server/location/gnss/GnssLocationProvider.java b/services/core/java/com/android/server/location/gnss/GnssLocationProvider.java index 5bd3c5707fd2..8017a442d8e7 100644 --- a/services/core/java/com/android/server/location/gnss/GnssLocationProvider.java +++ b/services/core/java/com/android/server/location/gnss/GnssLocationProvider.java @@ -841,6 +841,9 @@ public class GnssLocationProvider extends AbstractLocationProvider implements } private void injectBestLocation(Location location) { + if (location.isFromMockProvider()) { + return; + } if (DEBUG) { Log.d(TAG, "injectBestLocation: " + location); } @@ -942,6 +945,9 @@ public class GnssLocationProvider extends AbstractLocationProvider implements } private void injectLocation(Location location) { + if (location.isFromMockProvider()) { + return; + } if (location.hasAccuracy()) { if (DEBUG) { Log.d(TAG, "injectLocation: " + location); diff --git a/services/core/java/com/android/server/locksettings/LockSettingsService.java b/services/core/java/com/android/server/locksettings/LockSettingsService.java index f96fa0969de9..ca5f7b3869b2 100644 --- a/services/core/java/com/android/server/locksettings/LockSettingsService.java +++ b/services/core/java/com/android/server/locksettings/LockSettingsService.java @@ -1259,7 +1259,8 @@ public class LockSettingsService extends ILockSettings.Stub { return getCredentialTypeInternal(userId) != CREDENTIAL_TYPE_NONE; } - private void setKeystorePassword(byte[] password, int userHandle) { + @VisibleForTesting /** Note: this method is overridden in unit tests */ + void setKeystorePassword(byte[] password, int userHandle) { AndroidKeyStoreMaintenance.onUserPasswordChanged(userHandle, password); } @@ -3488,7 +3489,7 @@ public class LockSettingsService extends ILockSettings.Stub { } @Override - public boolean armRebootEscrow() { + public @ArmRebootEscrowErrorCode int armRebootEscrow() { return mRebootEscrowManager.armRebootEscrowIfNeeded(); } diff --git a/services/core/java/com/android/server/locksettings/RebootEscrowManager.java b/services/core/java/com/android/server/locksettings/RebootEscrowManager.java index 76ecc1acc7ac..c01523a4bc40 100644 --- a/services/core/java/com/android/server/locksettings/RebootEscrowManager.java +++ b/services/core/java/com/android/server/locksettings/RebootEscrowManager.java @@ -18,6 +18,15 @@ package com.android.server.locksettings; import static android.os.UserHandle.USER_SYSTEM; +import static com.android.internal.widget.LockSettingsInternal.ARM_REBOOT_ERROR_ESCROW_NOT_READY; +import static com.android.internal.widget.LockSettingsInternal.ARM_REBOOT_ERROR_KEYSTORE_FAILURE; +import static com.android.internal.widget.LockSettingsInternal.ARM_REBOOT_ERROR_NONE; +import static com.android.internal.widget.LockSettingsInternal.ARM_REBOOT_ERROR_NO_ESCROW_KEY; +import static com.android.internal.widget.LockSettingsInternal.ARM_REBOOT_ERROR_NO_PROVIDER; +import static com.android.internal.widget.LockSettingsInternal.ARM_REBOOT_ERROR_PROVIDER_MISMATCH; +import static com.android.internal.widget.LockSettingsInternal.ARM_REBOOT_ERROR_STORE_ESCROW_KEY; +import static com.android.internal.widget.LockSettingsInternal.ArmRebootEscrowErrorCode; + import android.annotation.IntDef; import android.annotation.NonNull; import android.annotation.UserIdInt; @@ -577,16 +586,14 @@ class RebootEscrowManager { mRebootEscrowWanted = false; setRebootEscrowReady(false); - RebootEscrowProviderInterface rebootEscrowProvider = mInjector.getRebootEscrowProvider(); if (rebootEscrowProvider == null) { - Slog.w(TAG, - "Had reboot escrow data for users, but RebootEscrowProvider is unavailable"); - return; + Slog.w(TAG, "RebootEscrowProvider is unavailable for clear request"); + } else { + rebootEscrowProvider.clearRebootEscrowKey(); } clearMetricsStorage(); - rebootEscrowProvider.clearRebootEscrowKey(); List<UserInfo> users = mUserManager.getUsers(); for (UserInfo user : users) { @@ -596,20 +603,30 @@ class RebootEscrowManager { mEventLog.addEntry(RebootEscrowEvent.CLEARED_LSKF_REQUEST); } - boolean armRebootEscrowIfNeeded() { + @ArmRebootEscrowErrorCode int armRebootEscrowIfNeeded() { if (!mRebootEscrowReady) { - return false; + return ARM_REBOOT_ERROR_ESCROW_NOT_READY; } RebootEscrowProviderInterface rebootEscrowProvider = mInjector.getRebootEscrowProvider(); if (rebootEscrowProvider == null) { Slog.w(TAG, "Had reboot escrow data for users, but RebootEscrowProvider is unavailable"); - return false; + clearRebootEscrowIfNeeded(); + return ARM_REBOOT_ERROR_NO_PROVIDER; } + int expectedProviderType = mInjector.serverBasedResumeOnReboot() + ? RebootEscrowProviderInterface.TYPE_SERVER_BASED + : RebootEscrowProviderInterface.TYPE_HAL; int actualProviderType = rebootEscrowProvider.getType(); - // TODO(b/183140900) Fail the reboot if provider type mismatches. + if (expectedProviderType != actualProviderType) { + Slog.w(TAG, "Expect reboot escrow provider " + expectedProviderType + + ", but the RoR is prepared with " + actualProviderType + + ". Please prepare the RoR again."); + clearRebootEscrowIfNeeded(); + return ARM_REBOOT_ERROR_PROVIDER_MISMATCH; + } RebootEscrowKey escrowKey; synchronized (mKeyGenerationLock) { @@ -618,30 +635,38 @@ class RebootEscrowManager { if (escrowKey == null) { Slog.e(TAG, "Escrow key is null, but escrow was marked as ready"); - return false; + clearRebootEscrowIfNeeded(); + return ARM_REBOOT_ERROR_NO_ESCROW_KEY; } // We will use the same key from keystore to encrypt the escrow key and escrow data blob. SecretKey kk = mKeyStoreManager.getKeyStoreEncryptionKey(); if (kk == null) { Slog.e(TAG, "Failed to get encryption key from keystore."); - return false; + clearRebootEscrowIfNeeded(); + return ARM_REBOOT_ERROR_KEYSTORE_FAILURE; } + + // TODO(b/183140900) design detailed errors for store escrow key errors. + // We don't clear rebootEscrow here, because some errors may be recoverable, e.g. network + // unavailable for server based provider. boolean armedRebootEscrow = rebootEscrowProvider.storeRebootEscrowKey(escrowKey, kk); - if (armedRebootEscrow) { - mStorage.setInt(REBOOT_ESCROW_ARMED_KEY, mInjector.getBootCount(), USER_SYSTEM); - mStorage.setLong(REBOOT_ESCROW_KEY_ARMED_TIMESTAMP, mInjector.getCurrentTimeMillis(), - USER_SYSTEM); - // Store the vbmeta digest of both slots. - mStorage.setString(REBOOT_ESCROW_KEY_VBMETA_DIGEST, mInjector.getVbmetaDigest(false), - USER_SYSTEM); - mStorage.setString(REBOOT_ESCROW_KEY_OTHER_VBMETA_DIGEST, - mInjector.getVbmetaDigest(true), USER_SYSTEM); - mStorage.setInt(REBOOT_ESCROW_KEY_PROVIDER, actualProviderType, USER_SYSTEM); - mEventLog.addEntry(RebootEscrowEvent.SET_ARMED_STATUS); - } - - return armedRebootEscrow; + if (!armedRebootEscrow) { + return ARM_REBOOT_ERROR_STORE_ESCROW_KEY; + } + + mStorage.setInt(REBOOT_ESCROW_ARMED_KEY, mInjector.getBootCount(), USER_SYSTEM); + mStorage.setLong(REBOOT_ESCROW_KEY_ARMED_TIMESTAMP, mInjector.getCurrentTimeMillis(), + USER_SYSTEM); + // Store the vbmeta digest of both slots. + mStorage.setString(REBOOT_ESCROW_KEY_VBMETA_DIGEST, mInjector.getVbmetaDigest(false), + USER_SYSTEM); + mStorage.setString(REBOOT_ESCROW_KEY_OTHER_VBMETA_DIGEST, + mInjector.getVbmetaDigest(true), USER_SYSTEM); + mStorage.setInt(REBOOT_ESCROW_KEY_PROVIDER, actualProviderType, USER_SYSTEM); + mEventLog.addEntry(RebootEscrowEvent.SET_ARMED_STATUS); + + return ARM_REBOOT_ERROR_NONE; } private void setRebootEscrowReady(boolean ready) { @@ -663,10 +688,6 @@ class RebootEscrowManager { } boolean clearRebootEscrow() { - if (mInjector.getRebootEscrowProvider() == null) { - return false; - } - clearRebootEscrowIfNeeded(); return true; } diff --git a/services/core/java/com/android/server/net/NetworkPolicyManagerService.java b/services/core/java/com/android/server/net/NetworkPolicyManagerService.java index 290307b4ea1a..319800d8b0b6 100644 --- a/services/core/java/com/android/server/net/NetworkPolicyManagerService.java +++ b/services/core/java/com/android/server/net/NetworkPolicyManagerService.java @@ -5857,7 +5857,8 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { return (bundle != null) ? bundle.getBoolean(key, defaultValue) : defaultValue; } - private class UidBlockedState { + @VisibleForTesting + static final class UidBlockedState { public int blockedReasons; public int allowedReasons; public int effectiveBlockedReasons; @@ -5869,16 +5870,21 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { } void updateEffectiveBlockedReasons() { - effectiveBlockedReasons = blockedReasons; + effectiveBlockedReasons = getEffectiveBlockedReasons(blockedReasons, allowedReasons); + } + + @VisibleForTesting + static int getEffectiveBlockedReasons(int blockedReasons, int allowedReasons) { + int effectiveBlockedReasons = blockedReasons; // If the uid is not subject to any blocked reasons, then return early if (blockedReasons == BLOCKED_REASON_NONE) { - return; + return effectiveBlockedReasons; } if ((allowedReasons & ALLOWED_REASON_SYSTEM) != 0) { - effectiveBlockedReasons = (blockedReasons & ALLOWED_METERED_REASON_MASK); + effectiveBlockedReasons &= ALLOWED_METERED_REASON_MASK; } if ((allowedReasons & ALLOWED_METERED_REASON_SYSTEM) != 0) { - effectiveBlockedReasons = (blockedReasons & ~ALLOWED_METERED_REASON_MASK); + effectiveBlockedReasons &= ~ALLOWED_METERED_REASON_MASK; } if ((allowedReasons & ALLOWED_REASON_FOREGROUND) != 0) { effectiveBlockedReasons &= ~BLOCKED_REASON_BATTERY_SAVER; @@ -5904,6 +5910,7 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { if ((allowedReasons & ALLOWED_METERED_REASON_USER_EXEMPTED) != 0) { effectiveBlockedReasons &= ~BLOCKED_METERED_REASON_DATA_SAVER; } + return effectiveBlockedReasons; } } diff --git a/services/core/java/com/android/server/net/TEST_MAPPING b/services/core/java/com/android/server/net/TEST_MAPPING index 9f04260242d9..571957bfa6fd 100644 --- a/services/core/java/com/android/server/net/TEST_MAPPING +++ b/services/core/java/com/android/server/net/TEST_MAPPING @@ -1,5 +1,5 @@ { - "presubmit": [ + "presubmit-large": [ { "name": "CtsHostsideNetworkTests", "file_patterns": ["(/|^)NetworkPolicy[^/]*\\.java"], @@ -11,7 +11,9 @@ "exclude-annotation": "androidx.test.filters.FlakyTest" } ] - }, + } + ], + "presubmit": [ { "name": "FrameworksServicesTests", "file_patterns": ["(/|^)NetworkPolicy[^/]*\\.java"], diff --git a/services/core/java/com/android/server/pm/PackageDexOptimizer.java b/services/core/java/com/android/server/pm/PackageDexOptimizer.java index 0e4a2ee076c2..ca9c75f71504 100644 --- a/services/core/java/com/android/server/pm/PackageDexOptimizer.java +++ b/services/core/java/com/android/server/pm/PackageDexOptimizer.java @@ -267,7 +267,7 @@ public class PackageDexOptimizer { mArtStatsLogger, sessionId, compilerFilter, - sharedGid, + pkg.getUid(), packageStats.getCompileTime(path), dexMetadataPath, options.getCompilationReason(), diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java index 58ffba202b25..48fee0b392a0 100644 --- a/services/core/java/com/android/server/pm/PackageManagerService.java +++ b/services/core/java/com/android/server/pm/PackageManagerService.java @@ -33,6 +33,8 @@ import static android.content.Intent.EXTRA_PACKAGE_NAME; import static android.content.Intent.EXTRA_VERSION_CODE; import static android.content.pm.PackageManager.CERT_INPUT_RAW_X509; import static android.content.pm.PackageManager.CERT_INPUT_SHA256; +import static android.content.Intent.CATEGORY_BROWSABLE; +import static android.content.Intent.CATEGORY_DEFAULT; import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_DEFAULT; import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_DISABLED; import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_DISABLED_UNTIL_USED; diff --git a/services/core/java/com/android/server/pm/dex/ArtStatsLogUtils.java b/services/core/java/com/android/server/pm/dex/ArtStatsLogUtils.java index 13798ba1b723..d67796b4e5f5 100644 --- a/services/core/java/com/android/server/pm/dex/ArtStatsLogUtils.java +++ b/services/core/java/com/android/server/pm/dex/ArtStatsLogUtils.java @@ -128,18 +128,12 @@ public class ArtStatsLogUtils { private static final Map<String, Integer> ISA_MAP = new HashMap(); static { - COMPILE_FILTER_MAP.put("arm", ArtStatsLog. - ART_DATUM_REPORTED__ISA__ART_ISA_ARM); - COMPILE_FILTER_MAP.put("arm64", ArtStatsLog. - ART_DATUM_REPORTED__ISA__ART_ISA_ARM64); - COMPILE_FILTER_MAP.put("x86", ArtStatsLog. - ART_DATUM_REPORTED__ISA__ART_ISA_X86); - COMPILE_FILTER_MAP.put("x86_64", ArtStatsLog. - ART_DATUM_REPORTED__ISA__ART_ISA_X86_64); - COMPILE_FILTER_MAP.put("mips", ArtStatsLog. - ART_DATUM_REPORTED__ISA__ART_ISA_MIPS); - COMPILE_FILTER_MAP.put("mips64", ArtStatsLog. - ART_DATUM_REPORTED__ISA__ART_ISA_MIPS64); + ISA_MAP.put("arm", ArtStatsLog.ART_DATUM_REPORTED__ISA__ART_ISA_ARM); + ISA_MAP.put("arm64", ArtStatsLog.ART_DATUM_REPORTED__ISA__ART_ISA_ARM64); + ISA_MAP.put("x86", ArtStatsLog.ART_DATUM_REPORTED__ISA__ART_ISA_X86); + ISA_MAP.put("x86_64", ArtStatsLog.ART_DATUM_REPORTED__ISA__ART_ISA_X86_64); + ISA_MAP.put("mips", ArtStatsLog.ART_DATUM_REPORTED__ISA__ART_ISA_MIPS); + ISA_MAP.put("mips64", ArtStatsLog.ART_DATUM_REPORTED__ISA__ART_ISA_MIPS64); } public static void writeStatsLog( diff --git a/services/core/java/com/android/server/pm/parsing/PackageInfoUtils.java b/services/core/java/com/android/server/pm/parsing/PackageInfoUtils.java index 64fa70812528..1fd2a0565fb2 100644 --- a/services/core/java/com/android/server/pm/parsing/PackageInfoUtils.java +++ b/services/core/java/com/android/server/pm/parsing/PackageInfoUtils.java @@ -400,7 +400,7 @@ public class PackageInfoUtils { retProcs.put(proc.getName(), new ProcessInfo(proc.getName(), new ArraySet<>(proc.getDeniedPermissions()), proc.getGwpAsanMode(), proc.getMemtagMode(), - proc.getNativeHeapZeroInit())); + proc.getNativeHeapZeroInitialized())); } return retProcs; } diff --git a/services/core/java/com/android/server/recoverysystem/RecoverySystemService.java b/services/core/java/com/android/server/recoverysystem/RecoverySystemService.java index fe21201f5cb7..81a51e290664 100644 --- a/services/core/java/com/android/server/recoverysystem/RecoverySystemService.java +++ b/services/core/java/com/android/server/recoverysystem/RecoverySystemService.java @@ -16,8 +16,17 @@ package com.android.server.recoverysystem; +import static android.os.RecoverySystem.RESUME_ON_REBOOT_REBOOT_ERROR_INVALID_PACKAGE_NAME; +import static android.os.RecoverySystem.RESUME_ON_REBOOT_REBOOT_ERROR_LSKF_NOT_CAPTURED; +import static android.os.RecoverySystem.RESUME_ON_REBOOT_REBOOT_ERROR_NONE; +import static android.os.RecoverySystem.RESUME_ON_REBOOT_REBOOT_ERROR_PROVIDER_PREPARATION_FAILURE; +import static android.os.RecoverySystem.RESUME_ON_REBOOT_REBOOT_ERROR_SLOT_MISMATCH; +import static android.os.RecoverySystem.RESUME_ON_REBOOT_REBOOT_ERROR_UNSPECIFIED; +import static android.os.RecoverySystem.ResumeOnRebootRebootErrorCode; import static android.os.UserHandle.USER_SYSTEM; +import static com.android.internal.widget.LockSettingsInternal.ARM_REBOOT_ERROR_NONE; + import android.annotation.IntDef; import android.content.Context; import android.content.IntentSender; @@ -40,6 +49,7 @@ import android.os.SystemProperties; import android.provider.DeviceConfig; import android.util.ArrayMap; import android.util.ArraySet; +import android.util.FastImmutableArraySet; import android.util.Slog; import com.android.internal.annotations.GuardedBy; @@ -136,7 +146,7 @@ public class RecoverySystemService extends IRecoverySystem.Stub implements Reboo */ @IntDef({ ROR_NEED_PREPARATION, ROR_SKIP_PREPARATION_AND_NOTIFY, - ROR_SKIP_PREPARATION_NOT_NOTIFY}) + ROR_SKIP_PREPARATION_NOT_NOTIFY }) private @interface ResumeOnRebootActionsOnRequest {} /** @@ -144,26 +154,41 @@ public class RecoverySystemService extends IRecoverySystem.Stub implements Reboo */ @IntDef({ ROR_NOT_REQUESTED, ROR_REQUESTED_NEED_CLEAR, - ROR_REQUESTED_SKIP_CLEAR}) + ROR_REQUESTED_SKIP_CLEAR }) private @interface ResumeOnRebootActionsOnClear {} /** - * The error codes for reboots initiated by resume on reboot clients. + * Fatal arm escrow errors from lock settings that means the RoR is in a bad state. So clients + * need to prepare RoR again. */ - private static final int REBOOT_ERROR_NONE = 0; - private static final int REBOOT_ERROR_UNKNOWN = 1; - private static final int REBOOT_ERROR_INVALID_PACKAGE_NAME = 2; - private static final int REBOOT_ERROR_LSKF_NOT_CAPTURED = 3; - private static final int REBOOT_ERROR_SLOT_MISMATCH = 4; - private static final int REBOOT_ERROR_ARM_REBOOT_ESCROW_FAILURE = 5; - - @IntDef({ REBOOT_ERROR_NONE, - REBOOT_ERROR_UNKNOWN, - REBOOT_ERROR_INVALID_PACKAGE_NAME, - REBOOT_ERROR_LSKF_NOT_CAPTURED, - REBOOT_ERROR_SLOT_MISMATCH, - REBOOT_ERROR_ARM_REBOOT_ESCROW_FAILURE}) - private @interface ResumeOnRebootRebootErrorCode {} + static final FastImmutableArraySet<Integer> FATAL_ARM_ESCROW_ERRORS = + new FastImmutableArraySet<>(new Integer[]{ + LockSettingsInternal.ARM_REBOOT_ERROR_ESCROW_NOT_READY, + LockSettingsInternal.ARM_REBOOT_ERROR_NO_PROVIDER, + LockSettingsInternal.ARM_REBOOT_ERROR_PROVIDER_MISMATCH, + LockSettingsInternal.ARM_REBOOT_ERROR_NO_ESCROW_KEY, + LockSettingsInternal.ARM_REBOOT_ERROR_KEYSTORE_FAILURE, + }); + + /** + * The error details for ArmRebootEscrow. It contains error codes from RecoverySystemService + * and LockSettingsService. + */ + static class RebootPreparationError { + final @ResumeOnRebootRebootErrorCode int mRebootErrorCode; + final int mProviderErrorCode; // The supplemental error code from lock settings + + RebootPreparationError(int rebootErrorCode, int providerErrorCode) { + mRebootErrorCode = rebootErrorCode; + mProviderErrorCode = providerErrorCode; + } + + int getErrorCodeForMetrics() { + // The ResumeOnRebootRebootErrorCode are aligned with 1000; so it's safe to add them + // for metrics purpose. + return mRebootErrorCode + mProviderErrorCode; + } + } /** * Manages shared preference, i.e. the storage used for metrics reporting. @@ -720,34 +745,40 @@ public class RecoverySystemService extends IRecoverySystem.Stub implements Reboo return true; } - private @ResumeOnRebootRebootErrorCode int armRebootEscrow(String packageName, + private RebootPreparationError armRebootEscrow(String packageName, boolean slotSwitch) { if (packageName == null) { Slog.w(TAG, "Missing packageName when rebooting with lskf."); - return REBOOT_ERROR_INVALID_PACKAGE_NAME; + return new RebootPreparationError( + RESUME_ON_REBOOT_REBOOT_ERROR_INVALID_PACKAGE_NAME, ARM_REBOOT_ERROR_NONE); } if (!isLskfCaptured(packageName)) { - return REBOOT_ERROR_LSKF_NOT_CAPTURED; + return new RebootPreparationError(RESUME_ON_REBOOT_REBOOT_ERROR_LSKF_NOT_CAPTURED, + ARM_REBOOT_ERROR_NONE); } if (!verifySlotForNextBoot(slotSwitch)) { - return REBOOT_ERROR_SLOT_MISMATCH; + return new RebootPreparationError(RESUME_ON_REBOOT_REBOOT_ERROR_SLOT_MISMATCH, + ARM_REBOOT_ERROR_NONE); } final long origId = Binder.clearCallingIdentity(); - boolean result; + int providerErrorCode; try { - result = mInjector.getLockSettingsService().armRebootEscrow(); + providerErrorCode = mInjector.getLockSettingsService().armRebootEscrow(); } finally { Binder.restoreCallingIdentity(origId); } - if (!result) { - Slog.w(TAG, "Failure to escrow key for reboot"); - return REBOOT_ERROR_ARM_REBOOT_ESCROW_FAILURE; + if (providerErrorCode != ARM_REBOOT_ERROR_NONE) { + Slog.w(TAG, "Failure to escrow key for reboot, providerErrorCode: " + + providerErrorCode); + return new RebootPreparationError( + RESUME_ON_REBOOT_REBOOT_ERROR_PROVIDER_PREPARATION_FAILURE, providerErrorCode); } - return REBOOT_ERROR_NONE; + return new RebootPreparationError(RESUME_ON_REBOOT_REBOOT_ERROR_NONE, + ARM_REBOOT_ERROR_NONE); } private boolean useServerBasedRoR() { @@ -761,7 +792,7 @@ public class RecoverySystemService extends IRecoverySystem.Stub implements Reboo } private void reportMetricsOnRebootWithLskf(String packageName, boolean slotSwitch, - @ResumeOnRebootRebootErrorCode int errorCode) { + RebootPreparationError escrowError) { int uid = mInjector.getUidFromPackageName(packageName); boolean serverBased = useServerBasedRoR(); int preparedClientCount; @@ -784,16 +815,33 @@ public class RecoverySystemService extends IRecoverySystem.Stub implements Reboo + " request count %d, lskf captured count %d, duration since lskf captured" + " %d seconds.", packageName, preparedClientCount, requestCount, lskfCapturedCount, durationSeconds)); - mInjector.reportRebootEscrowRebootMetrics(errorCode, uid, preparedClientCount, - requestCount, slotSwitch, serverBased, durationSeconds, lskfCapturedCount); + mInjector.reportRebootEscrowRebootMetrics(escrowError.getErrorCodeForMetrics(), uid, + preparedClientCount, requestCount, slotSwitch, serverBased, durationSeconds, + lskfCapturedCount); + } + + private void clearRoRPreparationStateOnRebootFailure(RebootPreparationError escrowError) { + if (!FATAL_ARM_ESCROW_ERRORS.contains(escrowError.mProviderErrorCode)) { + return; + } + + Slog.w(TAG, "Clearing resume on reboot states for all clients on arm escrow error: " + + escrowError.mProviderErrorCode); + synchronized (this) { + mCallerPendingRequest.clear(); + mCallerPreparedForReboot.clear(); + } } - private boolean rebootWithLskfImpl(String packageName, String reason, boolean slotSwitch) { - @ResumeOnRebootRebootErrorCode int errorCode = armRebootEscrow(packageName, slotSwitch); - reportMetricsOnRebootWithLskf(packageName, slotSwitch, errorCode); + private @ResumeOnRebootRebootErrorCode int rebootWithLskfImpl(String packageName, String reason, + boolean slotSwitch) { + RebootPreparationError escrowError = armRebootEscrow(packageName, slotSwitch); + reportMetricsOnRebootWithLskf(packageName, slotSwitch, escrowError); + clearRoRPreparationStateOnRebootFailure(escrowError); - if (errorCode != REBOOT_ERROR_NONE) { - return false; + @ResumeOnRebootRebootErrorCode int errorCode = escrowError.mRebootErrorCode; + if (errorCode != RESUME_ON_REBOOT_REBOOT_ERROR_NONE) { + return errorCode; } // Clear the metrics prefs after a successful RoR reboot. @@ -801,17 +849,19 @@ public class RecoverySystemService extends IRecoverySystem.Stub implements Reboo PowerManager pm = mInjector.getPowerManager(); pm.reboot(reason); - return true; + return RESUME_ON_REBOOT_REBOOT_ERROR_UNSPECIFIED; } @Override // Binder call for the legacy rebootWithLskf - public boolean rebootWithLskfAssumeSlotSwitch(String packageName, String reason) { + public @ResumeOnRebootRebootErrorCode int rebootWithLskfAssumeSlotSwitch(String packageName, + String reason) { mContext.enforceCallingOrSelfPermission(android.Manifest.permission.RECOVERY, null); return rebootWithLskfImpl(packageName, reason, true); } @Override // Binder call - public boolean rebootWithLskf(String packageName, String reason, boolean slotSwitch) { + public @ResumeOnRebootRebootErrorCode int rebootWithLskf(String packageName, String reason, + boolean slotSwitch) { enforcePermissionForResumeOnReboot(); return rebootWithLskfImpl(packageName, reason, slotSwitch); } diff --git a/services/core/java/com/android/server/recoverysystem/RecoverySystemShellCommand.java b/services/core/java/com/android/server/recoverysystem/RecoverySystemShellCommand.java index ae71c1a1e444..3d78828888da 100644 --- a/services/core/java/com/android/server/recoverysystem/RecoverySystemShellCommand.java +++ b/services/core/java/com/android/server/recoverysystem/RecoverySystemShellCommand.java @@ -17,6 +17,7 @@ package com.android.server.recoverysystem; import android.os.IRecoverySystem; +import android.os.RecoverySystem; import android.os.RemoteException; import android.os.ShellCommand; @@ -76,7 +77,8 @@ public class RecoverySystemShellCommand extends ShellCommand { private int rebootAndApply() throws RemoteException { String packageName = getNextArgRequired(); String rebootReason = getNextArgRequired(); - boolean success = mService.rebootWithLskf(packageName, rebootReason, false); + boolean success = (mService.rebootWithLskf(packageName, rebootReason, false) + == RecoverySystem.RESUME_ON_REBOOT_REBOOT_ERROR_NONE); PrintWriter pw = getOutPrintWriter(); // Keep the old message for cts test. pw.printf("%s Reboot and apply status: %s\n", packageName, diff --git a/services/core/java/com/android/server/trust/OWNERS b/services/core/java/com/android/server/trust/OWNERS index b039c4b45447..e2c6ce15b51e 100644 --- a/services/core/java/com/android/server/trust/OWNERS +++ b/services/core/java/com/android/server/trust/OWNERS @@ -1 +1 @@ -include /core/java/android/app/trust/OWNERS +include /core/java/android/service/trust/OWNERS diff --git a/services/core/java/com/android/server/vcn/UnderlyingNetworkTracker.java b/services/core/java/com/android/server/vcn/UnderlyingNetworkTracker.java index ab9de77005b3..ab214e8329ef 100644 --- a/services/core/java/com/android/server/vcn/UnderlyingNetworkTracker.java +++ b/services/core/java/com/android/server/vcn/UnderlyingNetworkTracker.java @@ -118,18 +118,18 @@ public class UnderlyingNetworkTracker { if (!mIsQuitting) { mRouteSelectionCallback = new RouteSelectionCallback(); mConnectivityManager.requestBackgroundNetwork( - getRouteSelectionRequest(), mHandler, mRouteSelectionCallback); + getRouteSelectionRequest(), mRouteSelectionCallback, mHandler); mWifiBringupCallback = new NetworkBringupCallback(); mConnectivityManager.requestBackgroundNetwork( - getWifiNetworkRequest(), mHandler, mWifiBringupCallback); + getWifiNetworkRequest(), mWifiBringupCallback, mHandler); for (final int subId : mLastSnapshot.getAllSubIdsInGroup(mSubscriptionGroup)) { final NetworkBringupCallback cb = new NetworkBringupCallback(); mCellBringupCallbacks.add(cb); mConnectivityManager.requestBackgroundNetwork( - getCellNetworkRequestForSubId(subId), mHandler, cb); + getCellNetworkRequestForSubId(subId), cb, mHandler); } } else { mRouteSelectionCallback = null; diff --git a/services/core/java/com/android/server/vcn/Vcn.java b/services/core/java/com/android/server/vcn/Vcn.java index ae806aa500a6..7bc6056f91f3 100644 --- a/services/core/java/com/android/server/vcn/Vcn.java +++ b/services/core/java/com/android/server/vcn/Vcn.java @@ -38,6 +38,7 @@ import android.util.Slog; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.annotations.VisibleForTesting.Visibility; +import com.android.internal.util.IndentingPrintWriter; import com.android.server.VcnManagementService.VcnCallback; import com.android.server.vcn.TelephonySubscriptionTracker.TelephonySubscriptionSnapshot; @@ -328,6 +329,8 @@ public class Vcn extends Handler { private void handleNetworkRequested( @NonNull NetworkRequest request, int score, int providerId) { + Slog.v(getLogTag(), "Received request " + request); + if (score > getNetworkScore()) { if (VDBG) { Slog.v( @@ -409,6 +412,26 @@ public class Vcn extends Handler { return TAG + " [" + mSubscriptionGroup.hashCode() + "]"; } + /** + * Dumps the state of this Vcn for logging and debugging purposes. + * + * <p>PII and credentials MUST NEVER be dumped here. + */ + public void dump(IndentingPrintWriter pw) { + pw.println("Vcn (" + mSubscriptionGroup + "):"); + pw.increaseIndent(); + + pw.println("mCurrentStatus: " + mCurrentStatus); + + pw.println("mVcnGatewayConnections:"); + for (VcnGatewayConnection gw : mVcnGatewayConnections.values()) { + gw.dump(pw); + } + pw.println(); + + pw.decreaseIndent(); + } + /** Retrieves the network score for a VCN Network */ // Package visibility for use in VcnGatewayConnection static int getNetworkScore() { diff --git a/services/core/java/com/android/server/vcn/VcnGatewayConnection.java b/services/core/java/com/android/server/vcn/VcnGatewayConnection.java index 20c08eb2ce92..df31221b5d60 100644 --- a/services/core/java/com/android/server/vcn/VcnGatewayConnection.java +++ b/services/core/java/com/android/server/vcn/VcnGatewayConnection.java @@ -23,6 +23,7 @@ import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_SUSPENDED; import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_VCN_MANAGED; import static android.net.NetworkCapabilities.TRANSPORT_CELLULAR; import static android.net.NetworkCapabilities.TRANSPORT_WIFI; +import static android.net.ipsec.ike.exceptions.IkeProtocolException.ERROR_TYPE_AUTHENTICATION_FAILED; import static android.net.vcn.VcnManager.VCN_ERROR_CODE_CONFIG_ERROR; import static android.net.vcn.VcnManager.VCN_ERROR_CODE_INTERNAL_ERROR; import static android.net.vcn.VcnManager.VCN_ERROR_CODE_NETWORK_ERROR; @@ -57,7 +58,6 @@ import android.net.ipsec.ike.IkeSession; import android.net.ipsec.ike.IkeSessionCallback; import android.net.ipsec.ike.IkeSessionConfiguration; import android.net.ipsec.ike.IkeSessionParams; -import android.net.ipsec.ike.exceptions.AuthenticationFailedException; import android.net.ipsec.ike.exceptions.IkeException; import android.net.ipsec.ike.exceptions.IkeInternalException; import android.net.ipsec.ike.exceptions.IkeProtocolException; @@ -77,6 +77,7 @@ import android.util.Slog; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.annotations.VisibleForTesting.Visibility; +import com.android.internal.util.IndentingPrintWriter; import com.android.internal.util.State; import com.android.internal.util.StateMachine; import com.android.internal.util.WakeupMessage; @@ -84,6 +85,7 @@ import com.android.server.vcn.TelephonySubscriptionTracker.TelephonySubscription import com.android.server.vcn.UnderlyingNetworkTracker.UnderlyingNetworkRecord; import com.android.server.vcn.UnderlyingNetworkTracker.UnderlyingNetworkTrackerCallback; import com.android.server.vcn.Vcn.VcnGatewayStatusCallback; +import com.android.server.vcn.util.MtuUtils; import java.io.IOException; import java.net.Inet4Address; @@ -448,6 +450,44 @@ public class VcnGatewayConnection extends StateMachine { */ private static final int EVENT_SAFE_MODE_TIMEOUT_EXCEEDED = 10; + /** + * Sent when an IKE has completed migration, and created updated transforms for application. + * + * <p>Only relevant in the Connected state. + * + * @param arg1 The session token for the IKE Session that completed migration, used to prevent + * out-of-date signals from propagating. + * @param obj @NonNull An EventMigrationCompletedInfo instance with relevant data. + */ + private static final int EVENT_MIGRATION_COMPLETED = 11; + + private static class EventMigrationCompletedInfo implements EventInfo { + @NonNull public final IpSecTransform inTransform; + @NonNull public final IpSecTransform outTransform; + + EventMigrationCompletedInfo( + @NonNull IpSecTransform inTransform, @NonNull IpSecTransform outTransform) { + this.inTransform = Objects.requireNonNull(inTransform); + this.outTransform = Objects.requireNonNull(outTransform); + } + + @Override + public int hashCode() { + return Objects.hash(inTransform, outTransform); + } + + @Override + public boolean equals(@Nullable Object other) { + if (!(other instanceof EventMigrationCompletedInfo)) { + return false; + } + + final EventMigrationCompletedInfo rhs = (EventMigrationCompletedInfo) other; + return Objects.equals(inTransform, rhs.inTransform) + && Objects.equals(outTransform, rhs.outTransform); + } + } + @VisibleForTesting(visibility = Visibility.PRIVATE) @NonNull final DisconnectedState mDisconnectedState = new DisconnectedState(); @@ -574,7 +614,7 @@ public class VcnGatewayConnection extends StateMachine { * <p>Set in Connected state, always @NonNull in Connected, Migrating states, @Nullable * otherwise. */ - private NetworkAgent mNetworkAgent; + private VcnNetworkAgent mNetworkAgent; @Nullable private WakeupMessage mTeardownTimeoutAlarm; @Nullable private WakeupMessage mDisconnectRequestAlarm; @@ -1011,12 +1051,21 @@ public class VcnGatewayConnection extends StateMachine { sessionLostWithoutCallback(token, exception); } + private static boolean isIkeAuthFailure(@NonNull Exception exception) { + if (!(exception instanceof IkeProtocolException)) { + return false; + } + + return ((IkeProtocolException) exception).getErrorType() + == ERROR_TYPE_AUTHENTICATION_FAILED; + } + private void notifyStatusCallbackForSessionClosed(@NonNull Exception exception) { final int errorCode; final String exceptionClass; final String exceptionMessage; - if (exception instanceof AuthenticationFailedException) { + if (isIkeAuthFailure(exception)) { errorCode = VCN_ERROR_CODE_CONFIG_ERROR; exceptionClass = exception.getClass().getName(); exceptionMessage = exception.getMessage(); @@ -1053,6 +1102,14 @@ public class VcnGatewayConnection extends StateMachine { sendMessageAndAcquireWakeLock(EVENT_SESSION_CLOSED, token); } + private void migrationCompleted( + int token, @NonNull IpSecTransform inTransform, @NonNull IpSecTransform outTransform) { + sendMessageAndAcquireWakeLock( + EVENT_MIGRATION_COMPLETED, + token, + new EventMigrationCompletedInfo(inTransform, outTransform)); + } + private void childTransformCreated( int token, @NonNull IpSecTransform transform, int direction) { sendMessageAndAcquireWakeLock( @@ -1148,7 +1205,9 @@ public class VcnGatewayConnection extends StateMachine { case EVENT_SETUP_COMPLETED: // Fallthrough case EVENT_DISCONNECT_REQUESTED: // Fallthrough case EVENT_TEARDOWN_TIMEOUT_EXPIRED: // Fallthrough - case EVENT_SUBSCRIPTIONS_CHANGED: + case EVENT_SUBSCRIPTIONS_CHANGED: // Fallthrough + case EVENT_SAFE_MODE_TIMEOUT_EXCEEDED: // Fallthrough + case EVENT_MIGRATION_COMPLETED: logUnexpectedEvent(msg.what); break; default: @@ -1440,30 +1499,32 @@ public class VcnGatewayConnection extends StateMachine { private abstract class ConnectedStateBase extends ActiveBaseState { protected void updateNetworkAgent( @NonNull IpSecTunnelInterface tunnelIface, - @NonNull NetworkAgent agent, + @NonNull VcnNetworkAgent agent, @NonNull VcnChildSessionConfiguration childConfig) { final NetworkCapabilities caps = buildNetworkCapabilities(mConnectionConfig, mUnderlying); final LinkProperties lp = - buildConnectedLinkProperties(mConnectionConfig, tunnelIface, childConfig); + buildConnectedLinkProperties( + mConnectionConfig, tunnelIface, childConfig, mUnderlying); agent.sendNetworkCapabilities(caps); agent.sendLinkProperties(lp); } - protected NetworkAgent buildNetworkAgent( + protected VcnNetworkAgent buildNetworkAgent( @NonNull IpSecTunnelInterface tunnelIface, @NonNull VcnChildSessionConfiguration childConfig) { final NetworkCapabilities caps = buildNetworkCapabilities(mConnectionConfig, mUnderlying); final LinkProperties lp = - buildConnectedLinkProperties(mConnectionConfig, tunnelIface, childConfig); + buildConnectedLinkProperties( + mConnectionConfig, tunnelIface, childConfig, mUnderlying); final NetworkAgentConfig nac = new NetworkAgentConfig.Builder() .setLegacyType(ConnectivityManager.TYPE_MOBILE) .build(); - final NetworkAgent agent = + final VcnNetworkAgent agent = mDeps.newNetworkAgent( mVcnContext, TAG, @@ -1472,15 +1533,21 @@ public class VcnGatewayConnection extends StateMachine { Vcn.getNetworkScore(), nac, mVcnContext.getVcnNetworkProvider(), - () -> { - Slog.d(TAG, "NetworkAgent was unwanted"); - // If network agent has already been torn down, skip sending the - // disconnect. Unwanted() is always called, even when networkAgents - // are unregistered in teardownNetwork(), so prevent duplicate - // notifications. - if (mNetworkAgent != null) { - teardownAsynchronously(); + (agentRef) -> { + // Only trigger teardown if the NetworkAgent hasn't been replaced or + // changed. This guards against two cases - the first where + // unwanted() may be called as a result of the + // NetworkAgent.unregister() call, which might trigger a teardown + // instead of just a Network disconnect, as well as the case where a + // new NetworkAgent replaces an old one before the unwanted() call + // is processed. + if (mNetworkAgent != agentRef) { + Slog.d(TAG, "unwanted() called on stale NetworkAgent"); + return; } + + Slog.d(TAG, "NetworkAgent was unwanted"); + teardownAsynchronously(); } /* networkUnwantedCallback */, (status) -> { if (status == NetworkAgent.VALIDATION_STATUS_VALID) { @@ -1620,12 +1687,36 @@ public class VcnGatewayConnection extends StateMachine { case EVENT_SAFE_MODE_TIMEOUT_EXCEEDED: handleSafeModeTimeoutExceeded(); break; + case EVENT_MIGRATION_COMPLETED: + final EventMigrationCompletedInfo migrationCompletedInfo = + (EventMigrationCompletedInfo) msg.obj; + + handleMigrationCompleted(migrationCompletedInfo); + break; default: logUnhandledMessage(msg); break; } } + private void handleMigrationCompleted(EventMigrationCompletedInfo migrationCompletedInfo) { + applyTransform( + mCurrentToken, + mTunnelIface, + mUnderlying.network, + migrationCompletedInfo.inTransform, + IpSecManager.DIRECTION_IN); + + applyTransform( + mCurrentToken, + mTunnelIface, + mUnderlying.network, + migrationCompletedInfo.outTransform, + IpSecManager.DIRECTION_OUT); + + updateNetworkAgent(mTunnelIface, mNetworkAgent, mChildConfig); + } + private void handleUnderlyingNetworkChanged(@NonNull Message msg) { final UnderlyingNetworkRecord oldUnderlying = mUnderlying; mUnderlying = ((EventUnderlyingNetworkChangedInfo) msg.obj).newUnderlying; @@ -1815,7 +1906,10 @@ public class VcnGatewayConnection extends StateMachine { private static LinkProperties buildConnectedLinkProperties( @NonNull VcnGatewayConnectionConfig gatewayConnectionConfig, @NonNull IpSecTunnelInterface tunnelIface, - @NonNull VcnChildSessionConfiguration childConfig) { + @NonNull VcnChildSessionConfiguration childConfig, + @Nullable UnderlyingNetworkRecord underlying) { + final VcnControlPlaneIkeConfig controlPlaneConfig = + (VcnControlPlaneIkeConfig) gatewayConnectionConfig.getControlPlaneConfig(); final LinkProperties lp = new LinkProperties(); lp.setInterfaceName(tunnelIface.getInterfaceName()); @@ -1831,7 +1925,12 @@ public class VcnGatewayConnection extends StateMachine { lp.addRoute(new RouteInfo(new IpPrefix(Inet6Address.ANY, 0), null /*gateway*/, null /*iface*/, RouteInfo.RTN_UNICAST)); - lp.setMtu(gatewayConnectionConfig.getMaxMtu()); + final int underlyingMtu = (underlying == null) ? 0 : underlying.linkProperties.getMtu(); + lp.setMtu( + MtuUtils.getMtu( + controlPlaneConfig.getChildSessionParams().getSaProposals(), + gatewayConnectionConfig.getMaxMtu(), + underlyingMtu)); return lp; } @@ -1912,8 +2011,7 @@ public class VcnGatewayConnection extends StateMachine { @NonNull IpSecTransform inIpSecTransform, @NonNull IpSecTransform outIpSecTransform) { Slog.v(TAG, "ChildTransformsMigrated; token " + mToken); - onIpSecTransformCreated(inIpSecTransform, IpSecManager.DIRECTION_IN); - onIpSecTransformCreated(outIpSecTransform, IpSecManager.DIRECTION_OUT); + migrationCompleted(mToken, inIpSecTransform, outIpSecTransform); } @Override @@ -1924,6 +2022,27 @@ public class VcnGatewayConnection extends StateMachine { } } + /** + * Dumps the state of this VcnGatewayConnection for logging and debugging purposes. + * + * <p>PII and credentials MUST NEVER be dumped here. + */ + public void dump(IndentingPrintWriter pw) { + pw.println("VcnGatewayConnection (" + mConnectionConfig.getGatewayConnectionName() + "):"); + pw.increaseIndent(); + + pw.println("Current state: " + getCurrentState().getClass().getSimpleName()); + pw.println("mIsQuitting: " + mIsQuitting); + pw.println("mIsInSafeMode: " + mIsInSafeMode); + pw.println("mCurrentToken: " + mCurrentToken); + pw.println("mFailedAttempts: " + mFailedAttempts); + pw.println( + "mNetworkAgent.getNetwork(): " + + (mNetworkAgent == null ? null : mNetworkAgent.getNetwork())); + + pw.decreaseIndent(); + } + @VisibleForTesting(visibility = Visibility.PRIVATE) void setTunnelInterface(IpSecTunnelInterface tunnelIface) { mTunnelIface = tunnelIface; @@ -1965,12 +2084,12 @@ public class VcnGatewayConnection extends StateMachine { } @VisibleForTesting(visibility = Visibility.PRIVATE) - NetworkAgent getNetworkAgent() { + VcnNetworkAgent getNetworkAgent() { return mNetworkAgent; } @VisibleForTesting(visibility = Visibility.PRIVATE) - void setNetworkAgent(@Nullable NetworkAgent networkAgent) { + void setNetworkAgent(@Nullable VcnNetworkAgent networkAgent) { mNetworkAgent = networkAgent; } @@ -1987,7 +2106,7 @@ public class VcnGatewayConnection extends StateMachine { (VcnControlPlaneIkeConfig) mConnectionConfig.getControlPlaneConfig(); final IkeSessionParams.Builder builder = new IkeSessionParams.Builder(controlPlaneConfig.getIkeSessionParams()); - builder.setConfiguredNetwork(network); + builder.setNetwork(network); return builder.build(); } @@ -2058,8 +2177,8 @@ public class VcnGatewayConnection extends StateMachine { return new WakeupMessage(vcnContext.getContext(), handler, tag, runnable); } - /** Builds a new NetworkAgent. */ - public NetworkAgent newNetworkAgent( + /** Builds a new VcnNetworkAgent. */ + public VcnNetworkAgent newNetworkAgent( @NonNull VcnContext vcnContext, @NonNull String tag, @NonNull NetworkCapabilities caps, @@ -2067,27 +2186,18 @@ public class VcnGatewayConnection extends StateMachine { @NonNull int score, @NonNull NetworkAgentConfig nac, @NonNull NetworkProvider provider, - @NonNull Runnable networkUnwantedCallback, + @NonNull Consumer<VcnNetworkAgent> networkUnwantedCallback, @NonNull Consumer<Integer> validationStatusCallback) { - return new NetworkAgent( - vcnContext.getContext(), - vcnContext.getLooper(), + return new VcnNetworkAgent( + vcnContext, tag, caps, lp, score, nac, - provider) { - @Override - public void onNetworkUnwanted() { - networkUnwantedCallback.run(); - } - - @Override - public void onValidationStatus(int status, @Nullable Uri redirectUri) { - validationStatusCallback.accept(status); - } - }; + provider, + networkUnwantedCallback, + validationStatusCallback); } /** Gets the elapsed real time since boot, in millis. */ @@ -2203,4 +2313,73 @@ public class VcnGatewayConnection extends StateMachine { mImpl.release(); } } + + /** Proxy Implementation of NetworkAgent, used for testing. */ + @VisibleForTesting(visibility = Visibility.PRIVATE) + public static class VcnNetworkAgent { + private final NetworkAgent mImpl; + + public VcnNetworkAgent( + @NonNull VcnContext vcnContext, + @NonNull String tag, + @NonNull NetworkCapabilities caps, + @NonNull LinkProperties lp, + @NonNull int score, + @NonNull NetworkAgentConfig nac, + @NonNull NetworkProvider provider, + @NonNull Consumer<VcnNetworkAgent> networkUnwantedCallback, + @NonNull Consumer<Integer> validationStatusCallback) { + mImpl = + new NetworkAgent( + vcnContext.getContext(), + vcnContext.getLooper(), + tag, + caps, + lp, + score, + nac, + provider) { + @Override + public void onNetworkUnwanted() { + networkUnwantedCallback.accept(VcnNetworkAgent.this); + } + + @Override + public void onValidationStatus(int status, @Nullable Uri redirectUri) { + validationStatusCallback.accept(status); + } + }; + } + + /** Registers the underlying NetworkAgent */ + public void register() { + mImpl.register(); + } + + /** Marks the underlying NetworkAgent as connected */ + public void markConnected() { + mImpl.markConnected(); + } + + /** Unregisters the underlying NetworkAgent */ + public void unregister() { + mImpl.unregister(); + } + + /** Sends new NetworkCapabilities for the underlying NetworkAgent */ + public void sendNetworkCapabilities(@NonNull NetworkCapabilities caps) { + mImpl.sendNetworkCapabilities(caps); + } + + /** Sends new LinkProperties for the underlying NetworkAgent */ + public void sendLinkProperties(@NonNull LinkProperties lp) { + mImpl.sendLinkProperties(lp); + } + + /** Retrieves the Network for the underlying NetworkAgent */ + @Nullable + public Network getNetwork() { + return mImpl.getNetwork(); + } + } } diff --git a/services/core/java/com/android/server/vcn/VcnNetworkProvider.java b/services/core/java/com/android/server/vcn/VcnNetworkProvider.java index a90969599159..be0deb57ee76 100644 --- a/services/core/java/com/android/server/vcn/VcnNetworkProvider.java +++ b/services/core/java/com/android/server/vcn/VcnNetworkProvider.java @@ -29,6 +29,7 @@ import android.util.Slog; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.annotations.VisibleForTesting.Visibility; +import com.android.internal.util.IndentingPrintWriter; import java.util.Objects; import java.util.Set; @@ -129,10 +130,50 @@ public class VcnNetworkProvider extends NetworkProvider { mScore = score; mProviderId = providerId; } + + /** + * Dumps the state of this NetworkRequestEntry for logging and debugging purposes. + * + * <p>PII and credentials MUST NEVER be dumped here. + */ + public void dump(IndentingPrintWriter pw) { + pw.println("NetworkRequestEntry:"); + pw.increaseIndent(); + + pw.println("mRequest: " + mRequest); + pw.println("mScore: " + mScore); + pw.println("mProviderId: " + mProviderId); + + pw.decreaseIndent(); + } } // package-private interface NetworkRequestListener { void onNetworkRequested(@NonNull NetworkRequest request, int score, int providerId); } + + /** + * Dumps the state of this VcnNetworkProvider for logging and debugging purposes. + * + * <p>PII and credentials MUST NEVER be dumped here. + */ + public void dump(IndentingPrintWriter pw) { + pw.println("VcnNetworkProvider:"); + pw.increaseIndent(); + + pw.println("mListeners:"); + for (NetworkRequestListener listener : mListeners) { + pw.println(listener); + } + pw.println(); + + pw.println("mRequests.values:"); + for (NetworkRequestEntry entry : mRequests.values()) { + entry.dump(pw); + } + pw.println(); + + pw.decreaseIndent(); + } } diff --git a/services/core/java/com/android/server/vcn/util/MtuUtils.java b/services/core/java/com/android/server/vcn/util/MtuUtils.java new file mode 100644 index 000000000000..5d40cca3e19d --- /dev/null +++ b/services/core/java/com/android/server/vcn/util/MtuUtils.java @@ -0,0 +1,154 @@ +/* + * Copyright (C) 2021 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES 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.vcn.util; + +import static android.net.ipsec.ike.SaProposal.ENCRYPTION_ALGORITHM_3DES; +import static android.net.ipsec.ike.SaProposal.ENCRYPTION_ALGORITHM_AES_CBC; +import static android.net.ipsec.ike.SaProposal.ENCRYPTION_ALGORITHM_AES_CTR; +import static android.net.ipsec.ike.SaProposal.ENCRYPTION_ALGORITHM_AES_GCM_12; +import static android.net.ipsec.ike.SaProposal.ENCRYPTION_ALGORITHM_AES_GCM_16; +import static android.net.ipsec.ike.SaProposal.ENCRYPTION_ALGORITHM_AES_GCM_8; +import static android.net.ipsec.ike.SaProposal.ENCRYPTION_ALGORITHM_CHACHA20_POLY1305; +import static android.net.ipsec.ike.SaProposal.INTEGRITY_ALGORITHM_AES_CMAC_96; +import static android.net.ipsec.ike.SaProposal.INTEGRITY_ALGORITHM_AES_XCBC_96; +import static android.net.ipsec.ike.SaProposal.INTEGRITY_ALGORITHM_HMAC_SHA1_96; +import static android.net.ipsec.ike.SaProposal.INTEGRITY_ALGORITHM_HMAC_SHA2_256_128; +import static android.net.ipsec.ike.SaProposal.INTEGRITY_ALGORITHM_HMAC_SHA2_384_192; +import static android.net.ipsec.ike.SaProposal.INTEGRITY_ALGORITHM_HMAC_SHA2_512_256; +import static android.net.ipsec.ike.SaProposal.INTEGRITY_ALGORITHM_NONE; + +import static com.android.net.module.util.NetworkStackConstants.IPV6_MIN_MTU; + +import static java.lang.Math.max; +import static java.util.Collections.unmodifiableMap; + +import android.annotation.NonNull; +import android.net.ipsec.ike.ChildSaProposal; +import android.util.ArrayMap; +import android.util.Pair; +import android.util.Slog; + +import java.util.List; +import java.util.Map; + +/** @hide */ +public class MtuUtils { + private static final String TAG = MtuUtils.class.getSimpleName(); + /** + * Max ESP overhead possible + * + * <p>60 (Outer IPv4 + options) + 8 (UDP encap) + 4 (SPI) + 4 (Seq) + 2 (Pad + NextHeader) + */ + private static final int GENERIC_ESP_OVERHEAD_MAX = 78; + + /** Maximum overheads of authentication algorithms, keyed on IANA-defined constants */ + private static final Map<Integer, Integer> AUTH_ALGORITHM_OVERHEAD; + + static { + final Map<Integer, Integer> map = new ArrayMap<>(); + map.put(INTEGRITY_ALGORITHM_NONE, 0); + map.put(INTEGRITY_ALGORITHM_HMAC_SHA1_96, 12); + map.put(INTEGRITY_ALGORITHM_AES_XCBC_96, 12); + map.put(INTEGRITY_ALGORITHM_HMAC_SHA2_256_128, 32); + map.put(INTEGRITY_ALGORITHM_HMAC_SHA2_384_192, 48); + map.put(INTEGRITY_ALGORITHM_HMAC_SHA2_512_256, 64); + map.put(INTEGRITY_ALGORITHM_AES_CMAC_96, 12); + + AUTH_ALGORITHM_OVERHEAD = unmodifiableMap(map); + } + + /** Maximum overheads of encryption algorithms, keyed on IANA-defined constants */ + private static final Map<Integer, Integer> CRYPT_ALGORITHM_OVERHEAD; + + static { + final Map<Integer, Integer> map = new ArrayMap<>(); + map.put(ENCRYPTION_ALGORITHM_3DES, 15); // 8 (IV) + 7 (Max pad) + map.put(ENCRYPTION_ALGORITHM_AES_CBC, 31); // 16 (IV) + 15 (Max pad) + map.put(ENCRYPTION_ALGORITHM_AES_CTR, 11); // 8 (IV) + 3 (Max pad) + + CRYPT_ALGORITHM_OVERHEAD = unmodifiableMap(map); + } + + /** Maximum overheads of combined mode algorithms, keyed on IANA-defined constants */ + private static final Map<Integer, Integer> AUTHCRYPT_ALGORITHM_OVERHEAD; + + static { + final Map<Integer, Integer> map = new ArrayMap<>(); + map.put(ENCRYPTION_ALGORITHM_AES_GCM_8, 19); // 8 (IV) + 3 (Max pad) + 8 (ICV) + map.put(ENCRYPTION_ALGORITHM_AES_GCM_12, 23); // 8 (IV) + 3 (Max pad) + 12 (ICV) + map.put(ENCRYPTION_ALGORITHM_AES_GCM_16, 27); // 8 (IV) + 3 (Max pad) + 16 (ICV) + map.put(ENCRYPTION_ALGORITHM_CHACHA20_POLY1305, 27); // 8 (IV) + 3 (Max pad) + 16 (ICV) + + AUTHCRYPT_ALGORITHM_OVERHEAD = unmodifiableMap(map); + } + + /** + * Calculates the MTU of the inner interface based on the parameters provided + * + * <p>The MTU of the inner interface will be the minimum of the following: + * + * <ul> + * <li>The MTU of the outer interface, minus the greatest ESP overhead (based on proposed + * algorithms). + * <li>The maximum MTU as provided in the arguments. + * </ul> + */ + public static int getMtu( + @NonNull List<ChildSaProposal> childProposals, int maxMtu, int underlyingMtu) { + if (underlyingMtu <= 0) { + return IPV6_MIN_MTU; + } + + int maxAuthOverhead = 0; + int maxCryptOverhead = 0; + int maxAuthCryptOverhead = 0; + + for (ChildSaProposal proposal : childProposals) { + for (Pair<Integer, Integer> encryptionAlgoPair : proposal.getEncryptionAlgorithms()) { + final int algo = encryptionAlgoPair.first; + + if (AUTHCRYPT_ALGORITHM_OVERHEAD.containsKey(algo)) { + maxAuthCryptOverhead = + max(maxAuthCryptOverhead, AUTHCRYPT_ALGORITHM_OVERHEAD.get(algo)); + continue; + } else if (CRYPT_ALGORITHM_OVERHEAD.containsKey(algo)) { + maxCryptOverhead = max(maxCryptOverhead, CRYPT_ALGORITHM_OVERHEAD.get(algo)); + continue; + } + + Slog.wtf(TAG, "Unknown encryption algorithm requested: " + algo); + return IPV6_MIN_MTU; + } + + for (int algo : proposal.getIntegrityAlgorithms()) { + if (AUTH_ALGORITHM_OVERHEAD.containsKey(algo)) { + maxAuthOverhead = max(maxAuthOverhead, AUTH_ALGORITHM_OVERHEAD.get(algo)); + continue; + } + + Slog.wtf(TAG, "Unknown integrity algorithm requested: " + algo); + return IPV6_MIN_MTU; + } + } + + // Return minimum of maxMtu, and the adjusted MTUs based on algorithms. + final int combinedModeMtu = underlyingMtu - maxAuthCryptOverhead - GENERIC_ESP_OVERHEAD_MAX; + final int normalModeMtu = + underlyingMtu - maxCryptOverhead - maxAuthOverhead - GENERIC_ESP_OVERHEAD_MAX; + return Math.min(Math.min(maxMtu, combinedModeMtu), normalModeMtu); + } +} diff --git a/services/core/jni/Android.bp b/services/core/jni/Android.bp index 24bb1b12305e..d0bd8b3e1ae2 100644 --- a/services/core/jni/Android.bp +++ b/services/core/jni/Android.bp @@ -102,6 +102,7 @@ cc_defaults { "libaudioclient", "libbase", "libappfuse", + "libbinder_ndk", "libbinder", "libcutils", "libcrypto", @@ -110,6 +111,7 @@ cc_defaults { "libhardware", "libhardware_legacy", "libhidlbase", + "libmemtrackproxy", "libmtp", "libnativehelper", "libprocessgroup", @@ -154,6 +156,7 @@ cc_defaults { "android.hardware.input.classifier@1.0", "android.hardware.ir@1.0", "android.hardware.light@2.0", + "android.hardware.memtrack-V1-ndk_platform", "android.hardware.power@1.0", "android.hardware.power@1.1", "android.hardware.power-V1-cpp", diff --git a/services/core/jni/com_android_server_SystemServer.cpp b/services/core/jni/com_android_server_SystemServer.cpp index d18043f6b3e9..b93b8ab034f8 100644 --- a/services/core/jni/com_android_server_SystemServer.cpp +++ b/services/core/jni/com_android_server_SystemServer.cpp @@ -23,11 +23,14 @@ #include <jni.h> #include <nativehelper/JNIHelp.h> +#include <android/binder_manager.h> +#include <android/binder_stability.h> #include <android/hidl/manager/1.2/IServiceManager.h> #include <binder/IServiceManager.h> #include <hidl/HidlTransportSupport.h> #include <incremental_service.h> +#include <memtrackproxy/MemtrackProxy.h> #include <schedulerservice/SchedulingPolicyService.h> #include <sensorservice/SensorService.h> #include <sensorservicehidl/SensorManager.h> @@ -57,6 +60,21 @@ static void android_server_SystemServer_startSensorService(JNIEnv* /* env */, jo } +static void android_server_SystemServer_startMemtrackProxyService(JNIEnv* env, + jobject /* clazz */) { + using aidl::android::hardware::memtrack::MemtrackProxy; + + const char* memtrackProxyService = "memtrack.proxy"; + + std::shared_ptr<MemtrackProxy> memtrack_proxy = ndk::SharedRefBase::make<MemtrackProxy>(); + auto binder = memtrack_proxy->asBinder(); + + AIBinder_forceDowngradeToLocalStability(binder.get()); + + const binder_exception_t err = AServiceManager_addService(binder.get(), memtrackProxyService); + LOG_ALWAYS_FATAL_IF(err != EX_NONE, "Cannot register %s: %d", memtrackProxyService, err); +} + static void android_server_SystemServer_startHidlServices(JNIEnv* env, jobject /* clazz */) { using ::android::frameworks::schedulerservice::V1_0::ISchedulingPolicyService; using ::android::frameworks::schedulerservice::V1_0::implementation::SchedulingPolicyService; @@ -121,6 +139,8 @@ static void android_server_SystemServer_setIncrementalServiceSystemReady(JNIEnv* static const JNINativeMethod gMethods[] = { /* name, signature, funcPtr */ {"startSensorService", "()V", (void*)android_server_SystemServer_startSensorService}, + {"startMemtrackProxyService", "()V", + (void*)android_server_SystemServer_startMemtrackProxyService}, {"startHidlServices", "()V", (void*)android_server_SystemServer_startHidlServices}, {"initZygoteChildHeapProfiling", "()V", (void*)android_server_SystemServer_initZygoteChildHeapProfiling}, diff --git a/services/core/jni/com_android_server_power_PowerManagerService.cpp b/services/core/jni/com_android_server_power_PowerManagerService.cpp index 5fde550dc19d..7a6d310c2520 100644 --- a/services/core/jni/com_android_server_power_PowerManagerService.cpp +++ b/services/core/jni/com_android_server_power_PowerManagerService.cpp @@ -191,19 +191,18 @@ static void setPowerBoostWithHandle(sp<IPowerAidl> handle, Boost boost, int32_t static std::array<std::atomic<HalSupport>, static_cast<int32_t>(Boost::DISPLAY_UPDATE_IMMINENT) + 1> boostSupportedArray = {HalSupport::UNKNOWN}; + size_t idx = static_cast<size_t>(boost); // Quick return if boost is not supported by HAL - if (boost > Boost::DISPLAY_UPDATE_IMMINENT || - boostSupportedArray[static_cast<int32_t>(boost)] == HalSupport::OFF) { + if (idx >= boostSupportedArray.size() || boostSupportedArray[idx] == HalSupport::OFF) { ALOGV("Skipped setPowerBoost %s because HAL doesn't support it", toString(boost).c_str()); return; } - if (boostSupportedArray[static_cast<int32_t>(boost)] == HalSupport::UNKNOWN) { + if (boostSupportedArray[idx] == HalSupport::UNKNOWN) { bool isSupported = false; handle->isBoostSupported(boost, &isSupported); - boostSupportedArray[static_cast<int32_t>(boost)] = - isSupported ? HalSupport::ON : HalSupport::OFF; + boostSupportedArray[idx] = isSupported ? HalSupport::ON : HalSupport::OFF; if (!isSupported) { ALOGV("Skipped setPowerBoost %s because HAL doesn't support it", toString(boost).c_str()); @@ -231,19 +230,18 @@ static bool setPowerModeWithHandle(sp<IPowerAidl> handle, Mode mode, bool enable // Need to increase the array if more mode supported. static std::array<std::atomic<HalSupport>, static_cast<int32_t>(Mode::DISPLAY_INACTIVE) + 1> modeSupportedArray = {HalSupport::UNKNOWN}; + size_t idx = static_cast<size_t>(mode); // Quick return if mode is not supported by HAL - if (mode > Mode::DISPLAY_INACTIVE || - modeSupportedArray[static_cast<int32_t>(mode)] == HalSupport::OFF) { + if (idx >= modeSupportedArray.size() || modeSupportedArray[idx] == HalSupport::OFF) { ALOGV("Skipped setPowerMode %s because HAL doesn't support it", toString(mode).c_str()); return false; } - if (modeSupportedArray[static_cast<int32_t>(mode)] == HalSupport::UNKNOWN) { + if (modeSupportedArray[idx] == HalSupport::UNKNOWN) { bool isSupported = false; handle->isModeSupported(mode, &isSupported); - modeSupportedArray[static_cast<int32_t>(mode)] = - isSupported ? HalSupport::ON : HalSupport::OFF; + modeSupportedArray[idx] = isSupported ? HalSupport::ON : HalSupport::OFF; if (!isSupported) { ALOGV("Skipped setPowerMode %s because HAL doesn't support it", toString(mode).c_str()); return false; diff --git a/services/incremental/Android.bp b/services/incremental/Android.bp index 7e1e99fe0a23..1a960484fb52 100644 --- a/services/incremental/Android.bp +++ b/services/incremental/Android.bp @@ -76,6 +76,7 @@ cc_defaults { "libcutils", "libincfs", "liblog", + "libpermission", "libz", "libziparchive", ], diff --git a/services/java/com/android/server/SystemServer.java b/services/java/com/android/server/SystemServer.java index 46ec65d7567c..81ec8f42e71a 100644 --- a/services/java/com/android/server/SystemServer.java +++ b/services/java/com/android/server/SystemServer.java @@ -96,6 +96,7 @@ import com.android.internal.util.FrameworkStatsLog; import com.android.internal.widget.ILockSettings; import com.android.server.am.ActivityManagerService; import com.android.server.appbinding.AppBindingService; +import com.android.server.art.ArtManagerLocal; import com.android.server.attention.AttentionManagerService; import com.android.server.audio.AudioService; import com.android.server.biometrics.AuthService; @@ -392,6 +393,11 @@ public final class SystemServer { private static native void startSensorService(); /** + * Start the memtrack proxy service. + */ + private static native void startMemtrackProxyService(); + + /** * Start all HIDL services that are run inside the system server. This may take some time. */ private static native void startHidlServices(); @@ -829,6 +835,12 @@ public final class SystemServer { mSystemServiceManager.startService(UriGrantsManagerService.Lifecycle.class); t.traceEnd(); + // Start MemtrackProxyService before ActivityManager, so that early calls + // to Memtrack::getMemory() don't fail. + t.traceBegin("MemtrackProxyService"); + startMemtrackProxyService(); + t.traceEnd(); + // Activity manager runs the show. t.traceBegin("StartActivityManager"); // TODO: Might need to move after migration to WM. @@ -2330,6 +2342,10 @@ public final class SystemServer { } t.traceEnd(); + t.traceBegin("ArtManagerLocal"); + LocalManagerRegistry.addManager(ArtManagerLocal.class, new ArtManagerLocal()); + t.traceEnd(); + t.traceBegin("StartBootPhaseDeviceSpecificServicesReady"); mSystemServiceManager.startBootPhase(t, SystemService.PHASE_DEVICE_SPECIFIC_SERVICES_READY); t.traceEnd(); diff --git a/services/net/java/android/net/util/KeepalivePacketDataUtil.java b/services/net/java/android/net/util/KeepalivePacketDataUtil.java index 6e539bbaf9fe..566698576026 100644 --- a/services/net/java/android/net/util/KeepalivePacketDataUtil.java +++ b/services/net/java/android/net/util/KeepalivePacketDataUtil.java @@ -80,12 +80,12 @@ public final class KeepalivePacketDataUtil { parcel.srcPort = pkt.getSrcPort(); parcel.dstAddress = dstAddress.getAddress(); parcel.dstPort = pkt.getDstPort(); - parcel.seq = pkt.tcpSeq; - parcel.ack = pkt.tcpAck; - parcel.rcvWnd = pkt.tcpWindow; - parcel.rcvWndScale = pkt.tcpWindowScale; - parcel.tos = pkt.ipTos; - parcel.ttl = pkt.ipTtl; + parcel.seq = pkt.getTcpSeq(); + parcel.ack = pkt.getTcpAck(); + parcel.rcvWnd = pkt.getTcpWindow(); + parcel.rcvWndScale = pkt.getTcpWindowScale(); + parcel.tos = pkt.getIpTos(); + parcel.ttl = pkt.getIpTtl(); return parcel; } diff --git a/services/tests/servicestests/src/com/android/server/locksettings/LockSettingsServiceTestable.java b/services/tests/servicestests/src/com/android/server/locksettings/LockSettingsServiceTestable.java index 1db5fcc70420..41562bb52a8d 100644 --- a/services/tests/servicestests/src/com/android/server/locksettings/LockSettingsServiceTestable.java +++ b/services/tests/servicestests/src/com/android/server/locksettings/LockSettingsServiceTestable.java @@ -208,4 +208,9 @@ public class LockSettingsServiceTestable extends LockSettingsService { parcel.recycle(); } } -} + + @Override + void setKeystorePassword(byte[] password, int userHandle) { + + } +}
\ No newline at end of file diff --git a/services/tests/servicestests/src/com/android/server/locksettings/LockSettingsStorageTestable.java b/services/tests/servicestests/src/com/android/server/locksettings/LockSettingsStorageTestable.java index 691d174f55f8..f2bb1d662ed9 100644 --- a/services/tests/servicestests/src/com/android/server/locksettings/LockSettingsStorageTestable.java +++ b/services/tests/servicestests/src/com/android/server/locksettings/LockSettingsStorageTestable.java @@ -87,6 +87,11 @@ public class LockSettingsStorageTestable extends LockSettingsStorage { } @Override + String getRebootEscrowFile(int userId) { + return makeDirs(mStorageDir, super.getRebootEscrowFile(userId)).getAbsolutePath(); + } + + @Override protected File getSyntheticPasswordDirectoryForUser(int userId) { return makeDirs(mStorageDir, super.getSyntheticPasswordDirectoryForUser( userId).getAbsolutePath()); diff --git a/services/tests/servicestests/src/com/android/server/locksettings/MockLockSettingsContext.java b/services/tests/servicestests/src/com/android/server/locksettings/MockLockSettingsContext.java index 2b9a05c3ef63..efa1b044f8f9 100644 --- a/services/tests/servicestests/src/com/android/server/locksettings/MockLockSettingsContext.java +++ b/services/tests/servicestests/src/com/android/server/locksettings/MockLockSettingsContext.java @@ -20,11 +20,16 @@ import android.app.KeyguardManager; import android.app.NotificationManager; import android.app.admin.DevicePolicyManager; import android.app.trust.TrustManager; +import android.content.BroadcastReceiver; import android.content.Context; import android.content.ContextWrapper; +import android.content.Intent; +import android.content.IntentFilter; import android.content.pm.PackageManager; import android.hardware.face.FaceManager; import android.hardware.fingerprint.FingerprintManager; +import android.os.Handler; +import android.os.UserHandle; import android.os.UserManager; import android.os.storage.StorageManager; @@ -94,4 +99,11 @@ public class MockLockSettingsContext extends ContextWrapper { public int checkCallingOrSelfPermission(String permission) { return PackageManager.PERMISSION_GRANTED; } + + @Override + public Intent registerReceiverAsUser(BroadcastReceiver receiver, + UserHandle user, IntentFilter filter, String broadcastPermission, + Handler scheduler) { + return null; + } } diff --git a/services/tests/servicestests/src/com/android/server/locksettings/RebootEscrowManagerTests.java b/services/tests/servicestests/src/com/android/server/locksettings/RebootEscrowManagerTests.java index 8c08226201a8..49a54ec1354b 100644 --- a/services/tests/servicestests/src/com/android/server/locksettings/RebootEscrowManagerTests.java +++ b/services/tests/servicestests/src/com/android/server/locksettings/RebootEscrowManagerTests.java @@ -21,6 +21,11 @@ import static android.content.pm.UserInfo.FLAG_PRIMARY; import static android.content.pm.UserInfo.FLAG_PROFILE; import static android.os.UserHandle.USER_SYSTEM; +import static com.android.internal.widget.LockSettingsInternal.ARM_REBOOT_ERROR_ESCROW_NOT_READY; +import static com.android.internal.widget.LockSettingsInternal.ARM_REBOOT_ERROR_NONE; +import static com.android.internal.widget.LockSettingsInternal.ARM_REBOOT_ERROR_PROVIDER_MISMATCH; +import static com.android.internal.widget.LockSettingsInternal.ARM_REBOOT_ERROR_STORE_ESCROW_KEY; + import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotNull; @@ -327,7 +332,7 @@ public class RebootEscrowManagerTests { assertNull( mStorage.getString(RebootEscrowManager.REBOOT_ESCROW_ARMED_KEY, null, USER_SYSTEM)); - assertTrue(mService.armRebootEscrowIfNeeded()); + assertEquals(ARM_REBOOT_ERROR_NONE, mService.armRebootEscrowIfNeeded()); assertNotNull( mStorage.getString(RebootEscrowManager.REBOOT_ESCROW_ARMED_KEY, null, USER_SYSTEM)); verify(mRebootEscrow).storeKey(any()); @@ -351,7 +356,7 @@ public class RebootEscrowManagerTests { when(mServiceConnection.wrapBlob(any(), anyLong(), anyLong())) .thenAnswer(invocation -> invocation.getArgument(0)); - assertTrue(mService.armRebootEscrowIfNeeded()); + assertEquals(ARM_REBOOT_ERROR_NONE, mService.armRebootEscrowIfNeeded()); verify(mServiceConnection).wrapBlob(any(), anyLong(), anyLong()); assertTrue(mStorage.hasRebootEscrow(PRIMARY_USER_ID)); @@ -373,7 +378,7 @@ public class RebootEscrowManagerTests { assertNull( mStorage.getString(RebootEscrowManager.REBOOT_ESCROW_ARMED_KEY, null, USER_SYSTEM)); doThrow(ServiceSpecificException.class).when(mRebootEscrow).storeKey(any()); - assertFalse(mService.armRebootEscrowIfNeeded()); + assertEquals(ARM_REBOOT_ERROR_STORE_ESCROW_KEY, mService.armRebootEscrowIfNeeded()); verify(mRebootEscrow).storeKey(any()); } @@ -396,7 +401,7 @@ public class RebootEscrowManagerTests { assertNull( mStorage.getString(RebootEscrowManager.REBOOT_ESCROW_ARMED_KEY, null, USER_SYSTEM)); - assertTrue(mService.armRebootEscrowIfNeeded()); + assertEquals(ARM_REBOOT_ERROR_NONE, mService.armRebootEscrowIfNeeded()); assertNotNull( mStorage.getString(RebootEscrowManager.REBOOT_ESCROW_ARMED_KEY, null, USER_SYSTEM)); verify(mRebootEscrow, times(1)).storeKey(any()); @@ -408,15 +413,24 @@ public class RebootEscrowManagerTests { @Test public void armService_NoInitialization_Failure() throws Exception { - assertFalse(mService.armRebootEscrowIfNeeded()); + assertEquals(ARM_REBOOT_ERROR_ESCROW_NOT_READY, mService.armRebootEscrowIfNeeded()); verifyNoMoreInteractions(mRebootEscrow); } @Test public void armService_RebootEscrowServiceException_Failure() throws Exception { + RebootEscrowListener mockListener = mock(RebootEscrowListener.class); + mService.setRebootEscrowListener(mockListener); + mService.prepareRebootEscrow(); + + clearInvocations(mRebootEscrow); + mService.callToRebootEscrowIfNeeded(PRIMARY_USER_ID, FAKE_SP_VERSION, FAKE_AUTH_TOKEN); + verify(mockListener).onPreparedForReboot(eq(true)); + verify(mRebootEscrow, never()).storeKey(any()); + doThrow(RemoteException.class).when(mRebootEscrow).storeKey(any()); - assertFalse(mService.armRebootEscrowIfNeeded()); - verifyNoMoreInteractions(mRebootEscrow); + assertEquals(ARM_REBOOT_ERROR_STORE_ESCROW_KEY, mService.armRebootEscrowIfNeeded()); + verify(mRebootEscrow).storeKey(any()); } @Test @@ -439,7 +453,7 @@ public class RebootEscrowManagerTests { verify(mRebootEscrow, never()).storeKey(any()); ArgumentCaptor<byte[]> keyByteCaptor = ArgumentCaptor.forClass(byte[].class); - assertTrue(mService.armRebootEscrowIfNeeded()); + assertEquals(ARM_REBOOT_ERROR_NONE, mService.armRebootEscrowIfNeeded()); verify(mRebootEscrow).storeKey(keyByteCaptor.capture()); verify(mKeyStoreManager).getKeyStoreEncryptionKey(); @@ -483,7 +497,7 @@ public class RebootEscrowManagerTests { // Use x -> x for both wrap & unwrap functions. when(mServiceConnection.wrapBlob(any(), anyLong(), anyLong())) .thenAnswer(invocation -> invocation.getArgument(0)); - assertTrue(mService.armRebootEscrowIfNeeded()); + assertEquals(ARM_REBOOT_ERROR_NONE, mService.armRebootEscrowIfNeeded()); verify(mServiceConnection).wrapBlob(any(), anyLong(), anyLong()); assertTrue(mStorage.hasRebootEscrowServerBlob()); @@ -520,7 +534,7 @@ public class RebootEscrowManagerTests { // Use x -> x for both wrap & unwrap functions. when(mServiceConnection.wrapBlob(any(), anyLong(), anyLong())) .thenAnswer(invocation -> invocation.getArgument(0)); - assertTrue(mService.armRebootEscrowIfNeeded()); + assertEquals(ARM_REBOOT_ERROR_NONE, mService.armRebootEscrowIfNeeded()); verify(mServiceConnection).wrapBlob(any(), anyLong(), anyLong()); assertTrue(mStorage.hasRebootEscrowServerBlob()); @@ -557,7 +571,7 @@ public class RebootEscrowManagerTests { // Use x -> x for both wrap & unwrap functions. when(mServiceConnection.wrapBlob(any(), anyLong(), anyLong())) .thenAnswer(invocation -> invocation.getArgument(0)); - assertTrue(mService.armRebootEscrowIfNeeded()); + assertEquals(ARM_REBOOT_ERROR_NONE, mService.armRebootEscrowIfNeeded()); verify(mServiceConnection).wrapBlob(any(), anyLong(), anyLong()); assertTrue(mStorage.hasRebootEscrowServerBlob()); @@ -597,7 +611,7 @@ public class RebootEscrowManagerTests { // Use x -> x for both wrap & unwrap functions. when(mServiceConnection.wrapBlob(any(), anyLong(), anyLong())) .thenAnswer(invocation -> invocation.getArgument(0)); - assertTrue(mService.armRebootEscrowIfNeeded()); + assertEquals(ARM_REBOOT_ERROR_NONE, mService.armRebootEscrowIfNeeded()); verify(mServiceConnection).wrapBlob(any(), anyLong(), anyLong()); assertTrue(mStorage.hasRebootEscrowServerBlob()); @@ -635,7 +649,7 @@ public class RebootEscrowManagerTests { verify(mRebootEscrow, never()).storeKey(any()); - assertTrue(mService.armRebootEscrowIfNeeded()); + assertEquals(ARM_REBOOT_ERROR_NONE, mService.armRebootEscrowIfNeeded()); verify(mRebootEscrow).storeKey(any()); assertTrue(mStorage.hasRebootEscrow(PRIMARY_USER_ID)); @@ -695,7 +709,7 @@ public class RebootEscrowManagerTests { verify(mRebootEscrow, never()).storeKey(any()); ArgumentCaptor<byte[]> keyByteCaptor = ArgumentCaptor.forClass(byte[].class); - assertTrue(mService.armRebootEscrowIfNeeded()); + assertEquals(ARM_REBOOT_ERROR_NONE, mService.armRebootEscrowIfNeeded()); verify(mRebootEscrow).storeKey(keyByteCaptor.capture()); assertTrue(mStorage.hasRebootEscrow(PRIMARY_USER_ID)); @@ -732,8 +746,7 @@ public class RebootEscrowManagerTests { verify(mockListener).onPreparedForReboot(eq(true)); verify(mRebootEscrow, never()).storeKey(any()); - - assertTrue(mService.armRebootEscrowIfNeeded()); + assertEquals(ARM_REBOOT_ERROR_NONE, mService.armRebootEscrowIfNeeded()); verify(mRebootEscrow).storeKey(any()); assertTrue(mStorage.hasRebootEscrow(PRIMARY_USER_ID)); @@ -756,4 +769,28 @@ public class RebootEscrowManagerTests { assertEquals(Integer.valueOf(RebootEscrowManager.ERROR_LOAD_ESCROW_KEY), metricsErrorCodeCaptor.getValue()); } + + @Test + public void armServiceProviderMismatch_Failure() throws Exception { + RebootEscrowListener mockListener = mock(RebootEscrowListener.class); + mService.setRebootEscrowListener(mockListener); + mService.prepareRebootEscrow(); + + clearInvocations(mRebootEscrow); + mService.callToRebootEscrowIfNeeded(PRIMARY_USER_ID, FAKE_SP_VERSION, FAKE_AUTH_TOKEN); + verify(mockListener).onPreparedForReboot(eq(true)); + assertTrue(mStorage.hasRebootEscrow(PRIMARY_USER_ID)); + verify(mRebootEscrow, never()).storeKey(any()); + + assertNull( + mStorage.getString(RebootEscrowManager.REBOOT_ESCROW_ARMED_KEY, null, USER_SYSTEM)); + // Change the provider to server based, expect the reboot to fail + when(mInjected.forceServerBased()).thenReturn(true); + assertEquals(ARM_REBOOT_ERROR_PROVIDER_MISMATCH, mService.armRebootEscrowIfNeeded()); + assertNull( + mStorage.getString(RebootEscrowManager.REBOOT_ESCROW_ARMED_KEY, null, USER_SYSTEM)); + // Verify that the escrow key & data have been cleared. + verify(mRebootEscrow).storeKey(eq(new byte[32])); + assertFalse(mStorage.hasRebootEscrow(PRIMARY_USER_ID)); + } } 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 f5876faad6cb..e9e24866f35c 100644 --- a/services/tests/servicestests/src/com/android/server/net/NetworkPolicyManagerServiceTest.java +++ b/services/tests/servicestests/src/com/android/server/net/NetworkPolicyManagerServiceTest.java @@ -18,6 +18,12 @@ package com.android.server.net; import static android.Manifest.permission.CONNECTIVITY_USE_RESTRICTED_NETWORKS; import static android.Manifest.permission.NETWORK_STACK; +import static android.net.ConnectivityManager.BLOCKED_METERED_REASON_DATA_SAVER; +import static android.net.ConnectivityManager.BLOCKED_METERED_REASON_USER_RESTRICTED; +import static android.net.ConnectivityManager.BLOCKED_REASON_APP_STANDBY; +import static android.net.ConnectivityManager.BLOCKED_REASON_BATTERY_SAVER; +import static android.net.ConnectivityManager.BLOCKED_REASON_DOZE; +import static android.net.ConnectivityManager.BLOCKED_REASON_NONE; import static android.net.ConnectivityManager.CONNECTIVITY_ACTION; import static android.net.ConnectivityManager.TYPE_MOBILE; import static android.net.ConnectivityManager.TYPE_WIFI; @@ -29,10 +35,17 @@ import static android.net.NetworkCapabilities.TRANSPORT_WIFI; import static android.net.NetworkPolicy.LIMIT_DISABLED; import static android.net.NetworkPolicy.SNOOZE_NEVER; import static android.net.NetworkPolicy.WARNING_DISABLED; +import static android.net.NetworkPolicyManager.ALLOWED_METERED_REASON_FOREGROUND; +import static android.net.NetworkPolicyManager.ALLOWED_METERED_REASON_SYSTEM; +import static android.net.NetworkPolicyManager.ALLOWED_REASON_FOREGROUND; +import static android.net.NetworkPolicyManager.ALLOWED_REASON_NONE; +import static android.net.NetworkPolicyManager.ALLOWED_REASON_SYSTEM; import static android.net.NetworkPolicyManager.FIREWALL_RULE_DEFAULT; import static android.net.NetworkPolicyManager.POLICY_ALLOW_METERED_BACKGROUND; import static android.net.NetworkPolicyManager.POLICY_NONE; import static android.net.NetworkPolicyManager.POLICY_REJECT_METERED_BACKGROUND; +import static android.net.NetworkPolicyManager.allowedReasonsToString; +import static android.net.NetworkPolicyManager.blockedReasonsToString; import static android.net.NetworkPolicyManager.uidPoliciesToString; import static android.net.NetworkPolicyManager.uidRulesToString; import static android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK; @@ -59,6 +72,7 @@ import static com.android.server.net.NetworkPolicyManagerService.TYPE_LIMIT; import static com.android.server.net.NetworkPolicyManagerService.TYPE_LIMIT_SNOOZED; import static com.android.server.net.NetworkPolicyManagerService.TYPE_RAPID; import static com.android.server.net.NetworkPolicyManagerService.TYPE_WARNING; +import static com.android.server.net.NetworkPolicyManagerService.UidBlockedState.getEffectiveBlockedReasons; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; @@ -134,8 +148,10 @@ import android.text.TextUtils; import android.util.ArrayMap; import android.util.DataUnit; import android.util.Log; +import android.util.Pair; import android.util.Range; import android.util.RecurrenceRule; +import android.util.SparseArray; import androidx.test.InstrumentationRegistry; import androidx.test.filters.FlakyTest; @@ -1896,6 +1912,65 @@ public class NetworkPolicyManagerServiceTest { assertFalse(mService.isUidNetworkingBlocked(UID_E, false)); } + @Test + public void testUpdateEffectiveBlockedReasons() { + final SparseArray<Pair<Integer, Integer>> effectiveBlockedReasons = new SparseArray<>(); + effectiveBlockedReasons.put(BLOCKED_REASON_NONE, + Pair.create(BLOCKED_REASON_NONE, ALLOWED_REASON_NONE)); + + effectiveBlockedReasons.put(BLOCKED_REASON_NONE, + Pair.create(BLOCKED_REASON_BATTERY_SAVER, ALLOWED_REASON_SYSTEM)); + effectiveBlockedReasons.put(BLOCKED_REASON_NONE, + Pair.create(BLOCKED_REASON_BATTERY_SAVER | BLOCKED_REASON_DOZE, + ALLOWED_REASON_SYSTEM)); + effectiveBlockedReasons.put(BLOCKED_REASON_NONE, + Pair.create(BLOCKED_METERED_REASON_DATA_SAVER, + ALLOWED_METERED_REASON_SYSTEM)); + effectiveBlockedReasons.put(BLOCKED_REASON_NONE, + Pair.create(BLOCKED_METERED_REASON_DATA_SAVER + | BLOCKED_METERED_REASON_USER_RESTRICTED, + ALLOWED_METERED_REASON_SYSTEM)); + + effectiveBlockedReasons.put(BLOCKED_METERED_REASON_DATA_SAVER, + Pair.create(BLOCKED_REASON_BATTERY_SAVER | BLOCKED_METERED_REASON_DATA_SAVER, + ALLOWED_REASON_SYSTEM)); + effectiveBlockedReasons.put(BLOCKED_REASON_APP_STANDBY, + Pair.create(BLOCKED_REASON_APP_STANDBY | BLOCKED_METERED_REASON_USER_RESTRICTED, + ALLOWED_METERED_REASON_SYSTEM)); + + effectiveBlockedReasons.put(BLOCKED_REASON_NONE, + Pair.create(BLOCKED_REASON_BATTERY_SAVER, ALLOWED_REASON_FOREGROUND)); + effectiveBlockedReasons.put(BLOCKED_REASON_NONE, + Pair.create(BLOCKED_REASON_BATTERY_SAVER | BLOCKED_REASON_DOZE, + ALLOWED_REASON_FOREGROUND)); + effectiveBlockedReasons.put(BLOCKED_REASON_NONE, + Pair.create(BLOCKED_METERED_REASON_DATA_SAVER, ALLOWED_METERED_REASON_FOREGROUND)); + effectiveBlockedReasons.put(BLOCKED_REASON_NONE, + Pair.create(BLOCKED_METERED_REASON_DATA_SAVER + | BLOCKED_METERED_REASON_USER_RESTRICTED, + ALLOWED_METERED_REASON_FOREGROUND)); + effectiveBlockedReasons.put(BLOCKED_METERED_REASON_DATA_SAVER, + Pair.create(BLOCKED_REASON_BATTERY_SAVER | BLOCKED_METERED_REASON_DATA_SAVER, + ALLOWED_REASON_FOREGROUND)); + effectiveBlockedReasons.put(BLOCKED_REASON_BATTERY_SAVER, + Pair.create(BLOCKED_REASON_BATTERY_SAVER + | BLOCKED_METERED_REASON_USER_RESTRICTED, + ALLOWED_METERED_REASON_FOREGROUND)); + // TODO: test more combinations of blocked reasons. + + for (int i = 0; i < effectiveBlockedReasons.size(); ++i) { + final int expectedEffectiveBlockedReasons = effectiveBlockedReasons.keyAt(i); + final int blockedReasons = effectiveBlockedReasons.valueAt(i).first; + final int allowedReasons = effectiveBlockedReasons.valueAt(i).second; + final String errorMsg = "Expected=" + + blockedReasonsToString(expectedEffectiveBlockedReasons) + + "; blockedReasons=" + blockedReasonsToString(blockedReasons) + + ", allowedReasons=" + allowedReasonsToString(allowedReasons); + assertEquals(errorMsg, expectedEffectiveBlockedReasons, + getEffectiveBlockedReasons(blockedReasons, allowedReasons)); + } + } + private String formatBlockedStateError(int uid, int rule, boolean metered, boolean backgroundRestricted) { return String.format( diff --git a/services/tests/servicestests/src/com/android/server/recoverysystem/RecoverySystemServiceTest.java b/services/tests/servicestests/src/com/android/server/recoverysystem/RecoverySystemServiceTest.java index 7903a90979fb..b64810b66542 100644 --- a/services/tests/servicestests/src/com/android/server/recoverysystem/RecoverySystemServiceTest.java +++ b/services/tests/servicestests/src/com/android/server/recoverysystem/RecoverySystemServiceTest.java @@ -16,8 +16,16 @@ package com.android.server.recoverysystem; +import static android.os.RecoverySystem.RESUME_ON_REBOOT_REBOOT_ERROR_INVALID_PACKAGE_NAME; +import static android.os.RecoverySystem.RESUME_ON_REBOOT_REBOOT_ERROR_LSKF_NOT_CAPTURED; +import static android.os.RecoverySystem.RESUME_ON_REBOOT_REBOOT_ERROR_PROVIDER_PREPARATION_FAILURE; +import static android.os.RecoverySystem.RESUME_ON_REBOOT_REBOOT_ERROR_SLOT_MISMATCH; + import static org.hamcrest.CoreMatchers.is; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertThat; +import static org.junit.Assert.assertTrue; import static org.mockito.AdditionalMatchers.not; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyBoolean; @@ -26,6 +34,7 @@ import static org.mockito.ArgumentMatchers.anyLong; import static org.mockito.ArgumentMatchers.anyString; import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.doNothing; +import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.doThrow; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.never; @@ -86,7 +95,8 @@ public class RecoverySystemServiceTest { mUncryptUpdateFileWriter = mock(FileWriter.class); mLockSettingsInternal = mock(LockSettingsInternal.class); - when(mLockSettingsInternal.armRebootEscrow()).thenReturn(true); + doReturn(LockSettingsInternal.ARM_REBOOT_ERROR_NONE).when(mLockSettingsInternal) + .armRebootEscrow(); Looper looper = InstrumentationRegistry.getContext().getMainLooper(); mIPowerManager = mock(IPowerManager.class); @@ -274,8 +284,7 @@ public class RecoverySystemServiceTest { verify(intentSender).sendIntent(any(), anyInt(), any(), any(), any()); assertThat(mRecoverySystemService.requestLskf(FAKE_OTA_PACKAGE_NAME, null), is(true)); - assertThat(mRecoverySystemService.rebootWithLskf(FAKE_OTA_PACKAGE_NAME, "foobar", true), - is(true)); + mRecoverySystemService.rebootWithLskf(FAKE_OTA_PACKAGE_NAME, "foobar", true); verify(mIPowerManager).reboot(anyBoolean(), eq("foobar"), anyBoolean()); } @@ -373,8 +382,7 @@ public class RecoverySystemServiceTest { anyInt())).thenReturn(3); when(mSharedPreferences.getLong(eq(RecoverySystemService.LSKF_CAPTURED_TIMESTAMP_PREF), anyLong())).thenReturn(40_000L); - assertThat(mRecoverySystemService.rebootWithLskf(FAKE_OTA_PACKAGE_NAME, "ab-update", true), - is(true)); + mRecoverySystemService.rebootWithLskf(FAKE_OTA_PACKAGE_NAME, "ab-update", true); verify(mIPowerManager).reboot(anyBoolean(), eq("ab-update"), anyBoolean()); verify(mMetricsReporter).reportRebootEscrowRebootMetrics(eq(0), eq(1000), eq(1) /* client count */, eq(2) /* request count */, eq(true) /* slot switch */, @@ -386,19 +394,20 @@ public class RecoverySystemServiceTest { public void rebootWithLskf_slotMismatch_Failure() throws Exception { assertThat(mRecoverySystemService.requestLskf(FAKE_OTA_PACKAGE_NAME, null), is(true)); mRecoverySystemService.onPreparedForReboot(true); - assertThat(mRecoverySystemService.rebootWithLskf(FAKE_OTA_PACKAGE_NAME, "ab-update", false), - is(false)); + assertEquals(RESUME_ON_REBOOT_REBOOT_ERROR_SLOT_MISMATCH, + mRecoverySystemService.rebootWithLskf(FAKE_OTA_PACKAGE_NAME, "ab-update", false)); } @Test public void rebootWithLskf_withoutPrepare_Failure() throws Exception { - assertThat(mRecoverySystemService.rebootWithLskf(FAKE_OTA_PACKAGE_NAME, null, true), - is(false)); + assertEquals(RESUME_ON_REBOOT_REBOOT_ERROR_LSKF_NOT_CAPTURED, + mRecoverySystemService.rebootWithLskf(FAKE_OTA_PACKAGE_NAME, null, true)); } @Test public void rebootWithLskf_withNullCallerId_Failure() throws Exception { - assertThat(mRecoverySystemService.rebootWithLskf(null, null, true), is(false)); + assertEquals(RESUME_ON_REBOOT_REBOOT_ERROR_INVALID_PACKAGE_NAME, + mRecoverySystemService.rebootWithLskf(null, null, true)); verifyNoMoreInteractions(mIPowerManager); } @@ -410,8 +419,7 @@ public class RecoverySystemServiceTest { // Client B's clear won't affect client A's preparation. assertThat(mRecoverySystemService.clearLskf(FAKE_OTHER_PACKAGE_NAME), is(true)); - assertThat(mRecoverySystemService.rebootWithLskf(FAKE_OTA_PACKAGE_NAME, "ab-update", true), - is(true)); + mRecoverySystemService.rebootWithLskf(FAKE_OTA_PACKAGE_NAME, "ab-update", true); verify(mIPowerManager).reboot(anyBoolean(), eq("ab-update"), anyBoolean()); } @@ -428,8 +436,7 @@ public class RecoverySystemServiceTest { when(mSharedPreferences.getLong(eq(RecoverySystemService.LSKF_CAPTURED_TIMESTAMP_PREF), anyLong())).thenReturn(60_000L); - assertThat(mRecoverySystemService.rebootWithLskf(FAKE_OTA_PACKAGE_NAME, "ab-update", true), - is(true)); + mRecoverySystemService.rebootWithLskf(FAKE_OTA_PACKAGE_NAME, "ab-update", true); verify(mIPowerManager).reboot(anyBoolean(), eq("ab-update"), anyBoolean()); verify(mMetricsReporter).reportRebootEscrowRebootMetrics(eq(0), eq(1000), eq(2) /* client count */, eq(2) /* request count */, eq(true) /* slot switch */, @@ -450,17 +457,15 @@ public class RecoverySystemServiceTest { anyLong())).thenReturn(60_000L); assertThat(mRecoverySystemService.clearLskf(FAKE_OTA_PACKAGE_NAME), is(true)); - assertThat(mRecoverySystemService.rebootWithLskf(FAKE_OTA_PACKAGE_NAME, null, true), - is(false)); + assertEquals(RESUME_ON_REBOOT_REBOOT_ERROR_LSKF_NOT_CAPTURED, + mRecoverySystemService.rebootWithLskf(FAKE_OTA_PACKAGE_NAME, null, true)); verifyNoMoreInteractions(mIPowerManager); verify(mMetricsReporter).reportRebootEscrowRebootMetrics(not(eq(0)), eq(1000), eq(1) /* client count */, anyInt() /* request count */, eq(true) /* slot switch */, anyBoolean(), eq(40), eq(1)/* lskf capture count */); assertThat(mRecoverySystemService.requestLskf(FAKE_OTHER_PACKAGE_NAME, null), is(true)); - assertThat( - mRecoverySystemService.rebootWithLskf(FAKE_OTHER_PACKAGE_NAME, "ab-update", true), - is(true)); + mRecoverySystemService.rebootWithLskf(FAKE_OTHER_PACKAGE_NAME, "ab-update", true); verify(mIPowerManager).reboot(anyBoolean(), eq("ab-update"), anyBoolean()); verify(mMetricsReporter).reportRebootEscrowRebootMetrics((eq(0)), eq(2000), @@ -476,18 +481,40 @@ public class RecoverySystemServiceTest { // Client A clears assertThat(mRecoverySystemService.clearLskf(FAKE_OTA_PACKAGE_NAME), is(true)); - assertThat(mRecoverySystemService.rebootWithLskf(FAKE_OTA_PACKAGE_NAME, null, true), - is(false)); + assertEquals(RESUME_ON_REBOOT_REBOOT_ERROR_LSKF_NOT_CAPTURED, + mRecoverySystemService.rebootWithLskf(FAKE_OTA_PACKAGE_NAME, null, true)); verifyNoMoreInteractions(mIPowerManager); // Client B clears assertThat(mRecoverySystemService.clearLskf(FAKE_OTHER_PACKAGE_NAME), is(true)); verify(mLockSettingsInternal).clearRebootEscrow(); - assertThat( - mRecoverySystemService.rebootWithLskf(FAKE_OTHER_PACKAGE_NAME, "ab-update", true), - is(false)); + assertEquals(RESUME_ON_REBOOT_REBOOT_ERROR_LSKF_NOT_CAPTURED, + mRecoverySystemService.rebootWithLskf(FAKE_OTHER_PACKAGE_NAME, "ab-update", true)); verifyNoMoreInteractions(mIPowerManager); } // TODO(xunchang) add more multi client tests + + @Test + public void rebootWithLskf_armEscrowDataFatalError_Failure() throws Exception { + doReturn(LockSettingsInternal.ARM_REBOOT_ERROR_PROVIDER_MISMATCH) + .when(mLockSettingsInternal).armRebootEscrow(); + + assertTrue(mRecoverySystemService.requestLskf(FAKE_OTA_PACKAGE_NAME, null)); + mRecoverySystemService.onPreparedForReboot(true); + assertTrue(mRecoverySystemService.isLskfCaptured(FAKE_OTA_PACKAGE_NAME)); + + when(mSharedPreferences.getInt(eq(FAKE_OTA_PACKAGE_NAME + + RecoverySystemService.REQUEST_LSKF_COUNT_PREF_SUFFIX), anyInt())).thenReturn(1); + when(mSharedPreferences.getInt(eq(RecoverySystemService.LSKF_CAPTURED_COUNT_PREF), + anyInt())).thenReturn(1); + assertEquals(RESUME_ON_REBOOT_REBOOT_ERROR_PROVIDER_PREPARATION_FAILURE, + mRecoverySystemService.rebootWithLskf(FAKE_OTA_PACKAGE_NAME, "ab-update", true)); + // Verify that the RoR preparation state has been cleared. + assertFalse(mRecoverySystemService.isLskfCaptured(FAKE_OTA_PACKAGE_NAME)); + verify(mMetricsReporter).reportRebootEscrowRebootMetrics(eq(5004 /* provider mismatch */), + eq(1000), eq(1) /* client count */, eq(1) /* request count */, + eq(true) /* slot switch */, anyBoolean(), anyInt(), + eq(1) /* lskf capture count */); + } } diff --git a/services/tests/servicestests/src/com/android/server/uwb/OWNERS b/services/tests/servicestests/src/com/android/server/uwb/OWNERS new file mode 100644 index 000000000000..c31a2f1ed3bc --- /dev/null +++ b/services/tests/servicestests/src/com/android/server/uwb/OWNERS @@ -0,0 +1 @@ +include platform/frameworks/base:/core/java/android/uwb/OWNERS diff --git a/services/uwb/OWNERS b/services/uwb/OWNERS new file mode 100644 index 000000000000..c31a2f1ed3bc --- /dev/null +++ b/services/uwb/OWNERS @@ -0,0 +1 @@ +include platform/frameworks/base:/core/java/android/uwb/OWNERS diff --git a/telephony/common/com/android/internal/telephony/TelephonyPermissions.java b/telephony/common/com/android/internal/telephony/TelephonyPermissions.java index 38fa9077f188..3c3df51aa4e8 100644 --- a/telephony/common/com/android/internal/telephony/TelephonyPermissions.java +++ b/telephony/common/com/android/internal/telephony/TelephonyPermissions.java @@ -525,7 +525,7 @@ public final class TelephonyPermissions { * * @throws SecurityException if the caller does not have the required permission/privileges */ - public static void enforeceCallingOrSelfReadPhoneStatePermissionOrCarrierPrivilege( + public static void enforceCallingOrSelfReadPhoneStatePermissionOrCarrierPrivilege( Context context, int subId, String message) { if (context.checkCallingOrSelfPermission(android.Manifest.permission.READ_PHONE_STATE) == PERMISSION_GRANTED) { @@ -545,7 +545,7 @@ public final class TelephonyPermissions { * * @throws SecurityException if the caller does not have the required permission/privileges */ - public static void enforeceCallingOrSelfReadPrivilegedPhoneStatePermissionOrCarrierPrivilege( + public static void enforceCallingOrSelfReadPrivilegedPhoneStatePermissionOrCarrierPrivilege( Context context, int subId, String message) { if (context.checkCallingOrSelfPermission(Manifest.permission.READ_PRIVILEGED_PHONE_STATE) == PERMISSION_GRANTED) { @@ -567,7 +567,7 @@ public final class TelephonyPermissions { * * @throws SecurityException if the caller does not have the required permission/privileges */ - public static void enforeceCallingOrSelfReadPrecisePhoneStatePermissionOrCarrierPrivilege( + public static void enforceCallingOrSelfReadPrecisePhoneStatePermissionOrCarrierPrivilege( Context context, int subId, String message) { if (context.checkCallingOrSelfPermission(Manifest.permission.READ_PRIVILEGED_PHONE_STATE) == PERMISSION_GRANTED) { diff --git a/telephony/java/android/telephony/AccessNetworkConstants.java b/telephony/java/android/telephony/AccessNetworkConstants.java index f6d18fcd9ab3..96e715ee0495 100644 --- a/telephony/java/android/telephony/AccessNetworkConstants.java +++ b/telephony/java/android/telephony/AccessNetworkConstants.java @@ -637,18 +637,18 @@ public final class AccessNetworkConstants { this.band = band; this.downlinkLowKhz = downlinkLowKhz; this.downlinkOffset = downlinkOffset; + this.downlinkRange = downlinkRange; this.uplinkLowKhz = uplinkLowKhz; this.uplinkOffset = uplinkOffset; - this.downlinkRange = downlinkRange; this.uplinkRange = uplinkRange; } int band; int downlinkLowKhz; int downlinkOffset; + int downlinkRange; int uplinkLowKhz; int uplinkOffset; - int downlinkRange; int uplinkRange; } diff --git a/telephony/java/android/telephony/AccessNetworkUtils.java b/telephony/java/android/telephony/AccessNetworkUtils.java index f29f3bd352be..6b820459be98 100644 --- a/telephony/java/android/telephony/AccessNetworkUtils.java +++ b/telephony/java/android/telephony/AccessNetworkUtils.java @@ -598,7 +598,8 @@ public class AccessNetworkUtils { : earfcnFrequency.downlinkOffset; break; } else { - Log.e(TAG, "Band and the range of EARFCN are not consistent."); + Rlog.w(TAG,"Band and the range of EARFCN are not consistent: band = " + band + + " ,earfcn = " + earfcn + " ,isUplink = " + isUplink); return INVALID_FREQUENCY; } } @@ -617,7 +618,7 @@ public class AccessNetworkUtils { } private static boolean isInEarfcnRange(int earfcn, EutranBandArfcnFrequency earfcnFrequency, - boolean isUplink) { + boolean isUplink) { if (isUplink) { return earfcn >= earfcnFrequency.uplinkOffset && earfcn <= earfcnFrequency.uplinkRange; } else { @@ -640,7 +641,8 @@ public class AccessNetworkUtils { : uarfcnFrequency.downlinkOffset; break; } else { - Log.e(TAG, "Band and the range of UARFCN are not consistent."); + Rlog.w(TAG,"Band and the range of UARFCN are not consistent: band = " + band + + " ,uarfcn = " + uarfcn + " ,isUplink = " + isUplink); return INVALID_FREQUENCY; } } @@ -716,7 +718,8 @@ public class AccessNetworkUtils { arfcnOffset); break; } else { - Log.e(TAG, "Band and the range of ARFCN are not consistent."); + Rlog.w(TAG,"Band and the range of ARFCN are not consistent: band = " + band + + " ,arfcn = " + arfcn + " ,isUplink = " + isUplink); return INVALID_FREQUENCY; } } @@ -733,7 +736,7 @@ public class AccessNetworkUtils { * Downlink actual frequency(kHz) = Uplink actual frequency + 10 */ private static int convertArfcnToFrequency(int arfcn, int uplinkFrequencyFirstKhz, - int arfcnOffset) { + int arfcnOffset) { return uplinkFrequencyFirstKhz + 200 * (arfcn - arfcnOffset); } diff --git a/telephony/java/android/telephony/CarrierConfigManager.java b/telephony/java/android/telephony/CarrierConfigManager.java index f027cd15e399..073f1e3c8b75 100644 --- a/telephony/java/android/telephony/CarrierConfigManager.java +++ b/telephony/java/android/telephony/CarrierConfigManager.java @@ -3222,6 +3222,14 @@ public class CarrierConfigManager { public static final String KEY_USE_CALLER_ID_USSD_BOOL = "use_caller_id_ussd_bool"; /** + * Call waiting uses USSD command without SS command. + * When {@code true}, the call waiting query/set by ussd command. + * When {@code false}, doesn't use USSD to query/set call waiting. + * @hide + */ + public static final String KEY_USE_CALL_WAITING_USSD_BOOL = "use_call_waiting_ussd_bool"; + + /** * Specifies the service class for call waiting service. * Default value is * {@link com.android.internal.telephony.CommandsInterface#SERVICE_CLASS_VOICE}. @@ -4820,6 +4828,7 @@ public class CarrierConfigManager { sDefaults.putBoolean(KEY_SUPPORT_EMERGENCY_DIALER_SHORTCUT_BOOL, true); sDefaults.putBoolean(KEY_USE_CALL_FORWARDING_USSD_BOOL, false); sDefaults.putBoolean(KEY_USE_CALLER_ID_USSD_BOOL, false); + sDefaults.putBoolean(KEY_USE_CALL_WAITING_USSD_BOOL, false); sDefaults.putInt(KEY_CALL_WAITING_SERVICE_CLASS_INT, 1 /* SERVICE_CLASS_VOICE */); sDefaults.putString(KEY_5G_ICON_CONFIGURATION_STRING, "connected_mmwave:5G,connected:5G,not_restricted_rrc_idle:5G," diff --git a/telephony/java/android/telephony/ims/DelegateRegistrationState.java b/telephony/java/android/telephony/ims/DelegateRegistrationState.java index fd206c1e803f..c00c741a0d60 100644 --- a/telephony/java/android/telephony/ims/DelegateRegistrationState.java +++ b/telephony/java/android/telephony/ims/DelegateRegistrationState.java @@ -63,7 +63,7 @@ public final class DelegateRegistrationState implements Parcelable { * This feature tag is being deregistered because the PDN that the IMS registration is on is *changing. * All open SIP dialogs need to be closed before the PDN change can proceed using - * {@link SipDelegateConnection#closeDialog(String)}. + * {@link SipDelegateConnection#cleanupSession(String)}. */ public static final int DEREGISTERING_REASON_PDN_CHANGE = 3; @@ -74,7 +74,7 @@ public final class DelegateRegistrationState implements Parcelable { * a user triggered hange, such as data being enabled/disabled. * <p> * All open SIP dialogs associated with the new deprovisioned feature tag need to be closed - * using {@link SipDelegateConnection#closeDialog(String)} before the IMS registration + * using {@link SipDelegateConnection#cleanupSession(String)} before the IMS registration * modification can proceed. */ public static final int DEREGISTERING_REASON_PROVISIONING_CHANGE = 4; @@ -84,7 +84,7 @@ public final class DelegateRegistrationState implements Parcelable { * needs to change its supported feature set. * <p> * All open SIP Dialogs associated with this feature tag must be closed - * using {@link SipDelegateConnection#closeDialog(String)} before this operation can proceed. + * using {@link SipDelegateConnection#cleanupSession(String)} before this operation can proceed. */ public static final int DEREGISTERING_REASON_FEATURE_TAGS_CHANGING = 5; @@ -93,7 +93,7 @@ public final class DelegateRegistrationState implements Parcelable { * destroyed. * <p> * All open SIP Dialogs associated with this feature tag must be closed - * using {@link SipDelegateConnection#closeDialog(String)} before this operation can proceed. + * using {@link SipDelegateConnection#cleanupSession(String)} before this operation can proceed. */ public static final int DEREGISTERING_REASON_DESTROY_PENDING = 6; diff --git a/telephony/java/android/telephony/ims/RcsConfig.java b/telephony/java/android/telephony/ims/RcsConfig.java index 07e95cc99290..8a3121118fde 100644 --- a/telephony/java/android/telephony/ims/RcsConfig.java +++ b/telephony/java/android/telephony/ims/RcsConfig.java @@ -48,6 +48,9 @@ public final class RcsConfig implements Parcelable { private static final String LOG_TAG = "RcsConfig"; private static final boolean DBG = Build.IS_ENG; + // Tag for Rcs Volte single registration defined in RCC.07 A.1.6.2 + private static final String TAG_SINGLE_REGISTRATION = "rcsVolteSingleRegistration"; + private final HashMap<String, String> mValues = new HashMap<>(); private RcsConfig(HashMap<String, String> values) { @@ -145,6 +148,14 @@ public final class RcsConfig implements Parcelable { return mValues.containsKey(tag); } + /** + * Check whether Rcs Volte single registration is supported by the config. + */ + public boolean isRcsVolteSingleRegistrationSupported() { + return getBoolean(TAG_SINGLE_REGISTRATION, false) + || getInteger(TAG_SINGLE_REGISTRATION, 0) != 0; + } + @Override public String toString() { final StringBuilder sb = new StringBuilder(); diff --git a/telephony/java/android/telephony/ims/RcsContactUceCapability.java b/telephony/java/android/telephony/ims/RcsContactUceCapability.java index a133eadb3517..acfa13380948 100644 --- a/telephony/java/android/telephony/ims/RcsContactUceCapability.java +++ b/telephony/java/android/telephony/ims/RcsContactUceCapability.java @@ -282,20 +282,6 @@ public final class RcsContactUceCapability implements Parcelable { * <p> * Note: this is only populated if {@link #getCapabilityMechanism} is * {@link RcsContactUceCapability#CAPABILITY_MECHANISM_OPTIONS} - * @hide - */ - public @NonNull List<String> getOptionsFeatureTags() { - if (mCapabilityMechanism != CAPABILITY_MECHANISM_OPTIONS) { - return Collections.emptyList(); - } - return Collections.unmodifiableList(new ArrayList<>(mFeatureTags)); - } - - /** - * @return The feature tags present in the OPTIONS response from the network. - * <p> - * Note: this is only populated if {@link #getCapabilityMechanism} is - * {@link RcsContactUceCapability#CAPABILITY_MECHANISM_OPTIONS} */ public @NonNull Set<String> getFeatureTags() { if (mCapabilityMechanism != CAPABILITY_MECHANISM_OPTIONS) { diff --git a/telephony/java/android/telephony/ims/SipDelegateConnection.java b/telephony/java/android/telephony/ims/SipDelegateConnection.java index 04a772cd873d..d7a19bc0cb62 100644 --- a/telephony/java/android/telephony/ims/SipDelegateConnection.java +++ b/telephony/java/android/telephony/ims/SipDelegateConnection.java @@ -74,8 +74,30 @@ public interface SipDelegateConnection { * closed. * @param callId The call-ID header value associated with the ongoing SIP Dialog that is * closing. + * @deprecated closeDialog does not capture INVITE forking. Use {@link #cleanupSession} instead. */ - void closeDialog(@NonNull String callId); + @Deprecated + default void closeDialog(@NonNull String callId) { + cleanupSession(callId); + } + + /** + * The SIP session associated with the provided Call-ID is being closed and routing resources + * associated with the session are free to be released. Each SIP session may contain multiple + * dialogs due to SIP INVITE forking, so this method must be called after all SIP dialogs + * associated with the session has closed. + * <p> + * Calling this method is also mandatory for situations where the framework IMS stack is waiting + * for pending SIP sessions to be closed before it can perform a handover or apply a + * provisioning change. See {@link DelegateRegistrationState} for more information about + * the scenarios where this can occur. + * <p> + * This method will need to be called for each SIP session managed by this application when it + * is closed. + * @param callId The call-ID header value associated with the ongoing SIP Dialog that is + * closing. + */ + default void cleanupSession(@NonNull String callId) { } /** * Notify the SIP delegate that the SIP message has been received from diff --git a/telephony/java/android/telephony/ims/SipMessage.java b/telephony/java/android/telephony/ims/SipMessage.java index b5295637d4dd..391372ac8ac1 100644 --- a/telephony/java/android/telephony/ims/SipMessage.java +++ b/telephony/java/android/telephony/ims/SipMessage.java @@ -203,9 +203,16 @@ public final class SipMessage implements Parcelable { } /** - * @return the UTF-8 encoded SIP message. + * According RFC-3261 section 7, SIP is a text protocol and uses the UTF-8 charset. Its format + * consists of a start-line, one or more header fields, an empty line indicating the end of the + * header fields, and an optional message-body. + * + * <p> + * Returns a byte array with UTF-8 format representation of the encoded SipMessage. + * + * @return byte array with UTF-8 format representation of the encoded SipMessage. */ - public @NonNull byte[] getEncodedMessage() { + public @NonNull byte[] toEncodedMessage() { byte[] header = new StringBuilder() .append(mStartLine) .append(mHeaderSection) diff --git a/telephony/java/android/telephony/ims/aidl/ISipDelegate.aidl b/telephony/java/android/telephony/ims/aidl/ISipDelegate.aidl index ad75be439da8..ff1a8f03350e 100644 --- a/telephony/java/android/telephony/ims/aidl/ISipDelegate.aidl +++ b/telephony/java/android/telephony/ims/aidl/ISipDelegate.aidl @@ -26,5 +26,5 @@ oneway interface ISipDelegate { void sendMessage(in SipMessage sipMessage, long configVersion); void notifyMessageReceived(in String viaTransactionId); void notifyMessageReceiveError(in String viaTransactionId, int reason); - void closeDialog(in String callId); + void cleanupSession(in String callId); } diff --git a/telephony/java/android/telephony/ims/aidl/SipDelegateAidlWrapper.java b/telephony/java/android/telephony/ims/aidl/SipDelegateAidlWrapper.java index 5c9ec53d713b..6a98d80d6b9b 100644 --- a/telephony/java/android/telephony/ims/aidl/SipDelegateAidlWrapper.java +++ b/telephony/java/android/telephony/ims/aidl/SipDelegateAidlWrapper.java @@ -79,11 +79,11 @@ public class SipDelegateAidlWrapper implements DelegateStateCallback, DelegateMe } @Override - public void closeDialog(String callId) { + public void cleanupSession(String callId) { SipDelegate d = mDelegate; final long token = Binder.clearCallingIdentity(); try { - mExecutor.execute(() -> d.closeDialog(callId)); + mExecutor.execute(() -> d.cleanupSession(callId)); } finally { Binder.restoreCallingIdentity(token); } diff --git a/telephony/java/android/telephony/ims/aidl/SipDelegateConnectionAidlWrapper.java b/telephony/java/android/telephony/ims/aidl/SipDelegateConnectionAidlWrapper.java index ad02fe55902f..0abb49574a73 100644 --- a/telephony/java/android/telephony/ims/aidl/SipDelegateConnectionAidlWrapper.java +++ b/telephony/java/android/telephony/ims/aidl/SipDelegateConnectionAidlWrapper.java @@ -200,13 +200,13 @@ public class SipDelegateConnectionAidlWrapper implements SipDelegateConnection, } @Override - public void closeDialog(String callId) { + public void cleanupSession(String callId) { try { ISipDelegate conn = getSipDelegateBinder(); if (conn == null) { return; } - conn.closeDialog(callId); + conn.cleanupSession(callId); } catch (RemoteException e) { // Nothing to do here, app will eventually get remote death callback. } diff --git a/telephony/java/android/telephony/ims/stub/RcsCapabilityExchangeImplBase.java b/telephony/java/android/telephony/ims/stub/RcsCapabilityExchangeImplBase.java index a117adcfb99a..57616d35f8fa 100644 --- a/telephony/java/android/telephony/ims/stub/RcsCapabilityExchangeImplBase.java +++ b/telephony/java/android/telephony/ims/stub/RcsCapabilityExchangeImplBase.java @@ -441,30 +441,6 @@ public class RcsCapabilityExchangeImplBase { * @param contactUri The URI of the remote user that we wish to get the capabilities of. * @param myCapabilities The capabilities of this device to send to the remote user. * @param callback The callback of this request which is sent from the remote user. - * @hide - */ - // executor used is defined in the constructor. - @SuppressLint("ExecutorRegistration") - public void sendOptionsCapabilityRequest(@NonNull Uri contactUri, - @NonNull List<String> myCapabilities, @NonNull OptionsResponseCallback callback) { - // Stub - to be implemented by service - Log.w(LOG_TAG, "sendOptionsCapabilityRequest called with no implementation."); - try { - callback.onCommandError(COMMAND_CODE_NOT_SUPPORTED); - } catch (ImsException e) { - // Do not do anything, this is a stub implementation. - } - } - - /** - * Push one's own capabilities to a remote user via the SIP OPTIONS presence exchange mechanism - * in order to receive the capabilities of the remote user in response. - * <p> - * The implementer must use {@link OptionsResponseCallback} to send the response of - * this query from the network back to the framework. - * @param contactUri The URI of the remote user that we wish to get the capabilities of. - * @param myCapabilities The capabilities of this device to send to the remote user. - * @param callback The callback of this request which is sent from the remote user. */ // executor used is defined in the constructor. @SuppressLint("ExecutorRegistration") diff --git a/telephony/java/android/telephony/ims/stub/SipDelegate.java b/telephony/java/android/telephony/ims/stub/SipDelegate.java index b036b5e71125..d5198a0aa25c 100644 --- a/telephony/java/android/telephony/ims/stub/SipDelegate.java +++ b/telephony/java/android/telephony/ims/stub/SipDelegate.java @@ -76,8 +76,30 @@ public interface SipDelegate { * * @param callId The call-ID header value associated with the ongoing SIP Dialog that the * framework is requesting be closed. + * @deprecated This method does not take into account INVITE forking. Use + * {@link #cleanupSession(String)} instead. */ - void closeDialog(@NonNull String callId); + @Deprecated + default void closeDialog(@NonNull String callId) { } + + /** + * The remote IMS application has closed a SIP session and the routing resources associated + * with the SIP session using the provided Call-ID may now be cleaned up. + * <p> + * Typically, a SIP session will be considered closed when all associated dialogs receive a + * BYE request. After the session has been closed, the IMS application will call + * {@link SipDelegateConnection#cleanupSession(String)} to signal to the framework that + * resources can be released. In some cases, the framework will request that the ImsService + * close the session due to the open SIP session holding up an event such as applying a + * provisioning change or handing over to another transport type. See + * {@link DelegateRegistrationState}. + * + * @param callId The call-ID header value associated with the ongoing SIP Session that the + * framework is requesting be cleaned up. + */ + default void cleanupSession(@NonNull String callId) { + closeDialog(callId); + } /** * The remote application has received the SIP message and is processing it. diff --git a/tests/net/common/java/ParseExceptionTest.kt b/tests/net/common/java/ParseExceptionTest.kt new file mode 100644 index 000000000000..f17715a099a3 --- /dev/null +++ b/tests/net/common/java/ParseExceptionTest.kt @@ -0,0 +1,46 @@ +/* + * Copyright (C) 2021 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import android.net.ParseException +import androidx.test.ext.junit.runners.AndroidJUnit4 +import androidx.test.filters.SmallTest +import junit.framework.Assert.assertEquals +import junit.framework.Assert.assertNull +import org.junit.Test +import org.junit.runner.RunWith + +@SmallTest +@RunWith(AndroidJUnit4::class) +class ParseExceptionTest { + @Test + fun testConstructor_WithCause() { + val testMessage = "Test message" + val base = Exception("Test") + val exception = ParseException(testMessage, base) + + assertEquals(testMessage, exception.response) + assertEquals(base, exception.cause) + } + + @Test + fun testConstructor_NoCause() { + val testMessage = "Test message" + val exception = ParseException(testMessage) + + assertEquals(testMessage, exception.response) + assertNull(exception.cause) + } +}
\ No newline at end of file diff --git a/tests/net/common/java/android/net/NetworkAgentConfigTest.kt b/tests/net/common/java/android/net/NetworkAgentConfigTest.kt index 1e54093bf111..2b45b3d69ce9 100644 --- a/tests/net/common/java/android/net/NetworkAgentConfigTest.kt +++ b/tests/net/common/java/android/net/NetworkAgentConfigTest.kt @@ -44,6 +44,9 @@ class NetworkAgentConfigTest { setSubscriberId("MySubId") setPartialConnectivityAcceptable(false) setUnvalidatedConnectivityAcceptable(true) + if (isAtLeastS()) { + setBypassableVpn(true) + } }.build() if (isAtLeastS()) { // From S, the config will have 12 items @@ -63,8 +66,11 @@ class NetworkAgentConfigTest { setPartialConnectivityAcceptable(false) setUnvalidatedConnectivityAcceptable(true) setLegacyTypeName("TEST_NETWORK") - disableNat64Detection() - disableProvisioningNotification() + if (isAtLeastS()) { + setNat64DetectionEnabled(false) + setProvisioningNotificationEnabled(false) + setBypassableVpn(true) + } }.build() assertTrue(config.isExplicitlySelected()) @@ -73,7 +79,13 @@ class NetworkAgentConfigTest { assertFalse(config.isPartialConnectivityAcceptable()) assertTrue(config.isUnvalidatedConnectivityAcceptable()) assertEquals("TEST_NETWORK", config.getLegacyTypeName()) - assertFalse(config.isNat64DetectionEnabled()) - assertFalse(config.isProvisioningNotificationEnabled()) + if (isAtLeastS()) { + assertFalse(config.isNat64DetectionEnabled()) + assertFalse(config.isProvisioningNotificationEnabled()) + assertTrue(config.isBypassableVpn()) + } else { + assertTrue(config.isNat64DetectionEnabled()) + assertTrue(config.isProvisioningNotificationEnabled()) + } } } diff --git a/tests/net/common/java/android/net/TcpKeepalivePacketDataTest.kt b/tests/net/common/java/android/net/TcpKeepalivePacketDataTest.kt index 677006692f84..7a18bb08faa8 100644 --- a/tests/net/common/java/android/net/TcpKeepalivePacketDataTest.kt +++ b/tests/net/common/java/android/net/TcpKeepalivePacketDataTest.kt @@ -92,12 +92,12 @@ class TcpKeepalivePacketDataTest { assertTrue(str.contains(data.dstAddress.hostAddress)) assertTrue(str.contains(data.dstPort.toString())) // .packet not included in toString() - assertTrue(str.contains(data.tcpSeq.toString())) - assertTrue(str.contains(data.tcpAck.toString())) - assertTrue(str.contains(data.tcpWindow.toString())) - assertTrue(str.contains(data.tcpWindowScale.toString())) - assertTrue(str.contains(data.ipTos.toString())) - assertTrue(str.contains(data.ipTtl.toString())) + assertTrue(str.contains(data.getTcpSeq().toString())) + assertTrue(str.contains(data.getTcpAck().toString())) + assertTrue(str.contains(data.getTcpWindow().toString())) + assertTrue(str.contains(data.getTcpWindowScale().toString())) + assertTrue(str.contains(data.getIpTos().toString())) + assertTrue(str.contains(data.getIpTtl().toString())) // Update above assertions if field is added assertFieldCountEquals(5, KeepalivePacketData::class.java) diff --git a/tests/net/java/android/net/ConnectivityManagerTest.java b/tests/net/java/android/net/ConnectivityManagerTest.java index 6cbdd258c00a..19f884346e6f 100644 --- a/tests/net/java/android/net/ConnectivityManagerTest.java +++ b/tests/net/java/android/net/ConnectivityManagerTest.java @@ -384,7 +384,7 @@ public class ConnectivityManagerTest { eq(TRACK_DEFAULT.ordinal()), any(), anyInt(), any(), eq(TYPE_NONE), anyInt(), eq(testPkgName), eq(testAttributionTag)); - manager.requestBackgroundNetwork(request, handler, callback); + manager.requestBackgroundNetwork(request, callback, handler); verify(mService).requestNetwork(eq(Process.INVALID_UID), eq(request.networkCapabilities), eq(BACKGROUND_REQUEST.ordinal()), any(), anyInt(), any(), eq(TYPE_NONE), anyInt(), eq(testPkgName), eq(testAttributionTag)); diff --git a/tests/net/java/com/android/server/ConnectivityServiceTest.java b/tests/net/java/com/android/server/ConnectivityServiceTest.java index 270941fdab53..91811f66eac2 100644 --- a/tests/net/java/com/android/server/ConnectivityServiceTest.java +++ b/tests/net/java/com/android/server/ConnectivityServiceTest.java @@ -18,6 +18,7 @@ package com.android.server; import static android.Manifest.permission.CHANGE_NETWORK_STATE; import static android.Manifest.permission.CONNECTIVITY_USE_RESTRICTED_NETWORKS; +import static android.Manifest.permission.DUMP; import static android.Manifest.permission.NETWORK_FACTORY; import static android.Manifest.permission.NETWORK_SETTINGS; import static android.app.PendingIntent.FLAG_IMMUTABLE; @@ -63,6 +64,7 @@ import static android.net.INetworkMonitor.NETWORK_VALIDATION_PROBE_HTTPS; import static android.net.INetworkMonitor.NETWORK_VALIDATION_PROBE_PRIVDNS; import static android.net.INetworkMonitor.NETWORK_VALIDATION_RESULT_PARTIAL; import static android.net.INetworkMonitor.NETWORK_VALIDATION_RESULT_VALID; +import static android.net.NetworkCapabilities.NET_CAPABILITY_BIP; import static android.net.NetworkCapabilities.NET_CAPABILITY_CAPTIVE_PORTAL; import static android.net.NetworkCapabilities.NET_CAPABILITY_CBS; import static android.net.NetworkCapabilities.NET_CAPABILITY_DUN; @@ -89,6 +91,7 @@ import static android.net.NetworkCapabilities.NET_CAPABILITY_SUPL; import static android.net.NetworkCapabilities.NET_CAPABILITY_TEMPORARILY_NOT_METERED; import static android.net.NetworkCapabilities.NET_CAPABILITY_TRUSTED; import static android.net.NetworkCapabilities.NET_CAPABILITY_VALIDATED; +import static android.net.NetworkCapabilities.NET_CAPABILITY_VSIM; import static android.net.NetworkCapabilities.NET_CAPABILITY_WIFI_P2P; import static android.net.NetworkCapabilities.NET_CAPABILITY_XCAP; import static android.net.NetworkCapabilities.REDACT_FOR_ACCESS_FINE_LOCATION; @@ -354,6 +357,8 @@ import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicReference; import java.util.function.Predicate; import java.util.function.Supplier; +import java.util.regex.Matcher; +import java.util.regex.Pattern; import java.util.stream.Collectors; import kotlin.reflect.KClass; @@ -3042,10 +3047,11 @@ public class ConnectivityServiceTest { // Verify NOT_RESTRICTED is set appropriately final NetworkCapabilities nc = new NetworkRequest.Builder().addCapability(capability) .build().networkCapabilities; - if (capability == NET_CAPABILITY_CBS || capability == NET_CAPABILITY_DUN || - capability == NET_CAPABILITY_EIMS || capability == NET_CAPABILITY_FOTA || - capability == NET_CAPABILITY_IA || capability == NET_CAPABILITY_IMS || - capability == NET_CAPABILITY_RCS || capability == NET_CAPABILITY_XCAP + if (capability == NET_CAPABILITY_CBS || capability == NET_CAPABILITY_DUN + || capability == NET_CAPABILITY_EIMS || capability == NET_CAPABILITY_FOTA + || capability == NET_CAPABILITY_IA || capability == NET_CAPABILITY_IMS + || capability == NET_CAPABILITY_RCS || capability == NET_CAPABILITY_XCAP + || capability == NET_CAPABILITY_VSIM || capability == NET_CAPABILITY_BIP || capability == NET_CAPABILITY_ENTERPRISE) { assertFalse(nc.hasCapability(NET_CAPABILITY_NOT_RESTRICTED)); } else { @@ -3155,6 +3161,8 @@ public class ConnectivityServiceTest { tryNetworkFactoryRequests(NET_CAPABILITY_INTERNET); tryNetworkFactoryRequests(NET_CAPABILITY_TRUSTED); tryNetworkFactoryRequests(NET_CAPABILITY_NOT_VPN); + tryNetworkFactoryRequests(NET_CAPABILITY_VSIM); + tryNetworkFactoryRequests(NET_CAPABILITY_BIP); // Skipping VALIDATED and CAPTIVE_PORTAL as they're disallowed. } @@ -4254,7 +4262,7 @@ public class ConnectivityServiceTest { final TestNetworkCallback cellBgCallback = new TestNetworkCallback(); mCm.requestBackgroundNetwork(new NetworkRequest.Builder() .addTransportType(TRANSPORT_CELLULAR).build(), - mCsHandlerThread.getThreadHandler(), cellBgCallback); + cellBgCallback, mCsHandlerThread.getThreadHandler()); // Make callbacks for monitoring. final NetworkRequest request = new NetworkRequest.Builder().build(); @@ -9152,7 +9160,7 @@ public class ConnectivityServiceTest { final int expectedOwnerUidWithoutIncludeFlag = shouldInclLocationSensitiveOwnerUidWithoutIncludeFlag - ? Process.myUid() : INVALID_UID; + ? myUid : INVALID_UID; assertEquals(expectedOwnerUidWithoutIncludeFlag, getOwnerUidNetCapsPermission( myUid, myUid, false /* includeLocationSensitiveInfo */)); @@ -9171,40 +9179,35 @@ public class ConnectivityServiceTest { } - @Test - public void testCreateWithLocationInfoSanitizedWithFineLocationAfterQ() - throws Exception { - setupLocationPermissions(Build.VERSION_CODES.Q, true, AppOpsManager.OPSTR_FINE_LOCATION, - Manifest.permission.ACCESS_FINE_LOCATION); - + private void verifyOwnerUidAndTransportInfoNetCapsPermissionPreS() { verifyOwnerUidAndTransportInfoNetCapsPermission( - // Ensure that we include owner uid even if the request asks to remove it since the - // app has necessary permissions and targetSdk < S. + // Ensure that owner uid is included even if the request asks to remove it (which is + // the default) since the app has necessary permissions and targetSdk < S. true, /* shouldInclLocationSensitiveOwnerUidWithoutIncludeFlag */ true, /* shouldInclLocationSensitiveOwnerUidWithIncludeFlag */ - false, /* shouldInclLocationSensitiveTransportInfoWithoutIncludeFlag */ - // Ensure that we remove location info if the request asks to remove it even if the + // Ensure that location info is removed if the request asks to remove it even if the // app has necessary permissions. + false, /* shouldInclLocationSensitiveTransportInfoWithoutIncludeFlag */ true /* shouldInclLocationSensitiveTransportInfoWithIncludeFlag */ ); } @Test + public void testCreateWithLocationInfoSanitizedWithFineLocationAfterQPreS() + throws Exception { + setupLocationPermissions(Build.VERSION_CODES.Q, true, AppOpsManager.OPSTR_FINE_LOCATION, + Manifest.permission.ACCESS_FINE_LOCATION); + + verifyOwnerUidAndTransportInfoNetCapsPermissionPreS(); + } + + @Test public void testCreateWithLocationInfoSanitizedWithFineLocationPreSWithAndWithoutCallbackFlag() throws Exception { setupLocationPermissions(Build.VERSION_CODES.R, true, AppOpsManager.OPSTR_FINE_LOCATION, Manifest.permission.ACCESS_FINE_LOCATION); - verifyOwnerUidAndTransportInfoNetCapsPermission( - // Ensure that we include owner uid even if the request asks to remove it since the - // app has necessary permissions and targetSdk < S. - true, /* shouldInclLocationSensitiveOwnerUidWithoutIncludeFlag */ - true, /* shouldInclLocationSensitiveOwnerUidWithIncludeFlag */ - false, /* shouldInclLocationSensitiveTransportInfoWithoutIncludeFlag */ - // Ensure that we remove location info if the request asks to remove it even if the - // app has necessary permissions. - true /* shouldInclLocationSensitiveTransportInfoWithIncludeFlag */ - ); + verifyOwnerUidAndTransportInfoNetCapsPermissionPreS(); } @Test @@ -9215,13 +9218,13 @@ public class ConnectivityServiceTest { Manifest.permission.ACCESS_FINE_LOCATION); verifyOwnerUidAndTransportInfoNetCapsPermission( - // Ensure that we owner UID if the request asks us to remove it even if the app - // has necessary permissions since targetSdk >= S. + // Ensure that the owner UID is removed if the request asks us to remove it even + // if the app has necessary permissions since targetSdk >= S. false, /* shouldInclLocationSensitiveOwnerUidWithoutIncludeFlag */ true, /* shouldInclLocationSensitiveOwnerUidWithIncludeFlag */ - false, /* shouldInclLocationSensitiveTransportInfoWithoutIncludeFlag */ - // Ensure that we remove location info if the request asks to remove it even if the + // Ensure that location info is removed if the request asks to remove it even if the // app has necessary permissions. + false, /* shouldInclLocationSensitiveTransportInfoWithoutIncludeFlag */ true /* shouldInclLocationSensitiveTransportInfoWithIncludeFlag */ ); } @@ -9232,15 +9235,15 @@ public class ConnectivityServiceTest { setupLocationPermissions(Build.VERSION_CODES.P, true, AppOpsManager.OPSTR_COARSE_LOCATION, Manifest.permission.ACCESS_COARSE_LOCATION); + verifyOwnerUidAndTransportInfoNetCapsPermissionPreS(); + } + + private void verifyOwnerUidAndTransportInfoNetCapsNotIncluded() { verifyOwnerUidAndTransportInfoNetCapsPermission( - // Ensure that we owner UID if the request asks us to remove it even if the app - // has necessary permissions since targetSdk >= S. - true, /* shouldInclLocationSensitiveOwnerUidWithoutIncludeFlag */ - true, /* shouldInclLocationSensitiveOwnerUidWithIncludeFlag */ + false, /* shouldInclLocationSensitiveOwnerUidWithoutIncludeFlag */ + false, /* shouldInclLocationSensitiveOwnerUidWithIncludeFlag */ false, /* shouldInclLocationSensitiveTransportInfoWithoutIncludeFlag */ - // Ensure that we remove location info if the request asks to remove it even if the - // app has necessary permissions. - true /* shouldInclLocationSensitiveTransportInfoWithIncludeFlag */ + false /* shouldInclLocationSensitiveTransportInfoWithIncludeFlag */ ); } @@ -9250,12 +9253,7 @@ public class ConnectivityServiceTest { setupLocationPermissions(Build.VERSION_CODES.Q, false, AppOpsManager.OPSTR_FINE_LOCATION, Manifest.permission.ACCESS_FINE_LOCATION); - verifyOwnerUidAndTransportInfoNetCapsPermission( - false, /* shouldInclLocationSensitiveOwnerUidWithoutIncludeFlag */ - false, /* shouldInclLocationSensitiveOwnerUidWithIncludeFlag */ - false, /* shouldInclLocationSensitiveTransportInfoWithoutIncludeFlag */ - false /* shouldInclLocationSensitiveTransportInfoWithIncludeFlag */ - ); + verifyOwnerUidAndTransportInfoNetCapsNotIncluded(); } @Test @@ -9277,26 +9275,17 @@ public class ConnectivityServiceTest { setupLocationPermissions(Build.VERSION_CODES.Q, true, AppOpsManager.OPSTR_COARSE_LOCATION, Manifest.permission.ACCESS_COARSE_LOCATION); - verifyOwnerUidAndTransportInfoNetCapsPermission( - false, /* shouldInclLocationSensitiveOwnerUidWithoutIncludeFlag */ - false, /* shouldInclLocationSensitiveOwnerUidWithIncludeFlag */ - false, /* shouldInclLocationSensitiveTransportInfoWithoutIncludeFlag */ - false /* shouldInclLocationSensitiveTransportInfoWithIncludeFlag */ - ); + verifyOwnerUidAndTransportInfoNetCapsNotIncluded(); } @Test - public void testCreateWithLocationInfoSanitizedWithoutLocationPermission() + public void testCreateWithLocationInfoSanitizedWithCoarseLocationAfterS() throws Exception { // Test that not having fine location permission leads to sanitization. - setupLocationPermissions(Build.VERSION_CODES.Q, true, null /* op */, null /* perm */); + setupLocationPermissions(Build.VERSION_CODES.S, true, AppOpsManager.OPSTR_COARSE_LOCATION, + Manifest.permission.ACCESS_COARSE_LOCATION); - verifyOwnerUidAndTransportInfoNetCapsPermission( - false, /* shouldInclLocationSensitiveOwnerUidWithoutIncludeFlag */ - false, /* shouldInclLocationSensitiveOwnerUidWithIncludeFlag */ - false, /* shouldInclLocationSensitiveTransportInfoWithoutIncludeFlag */ - false /* shouldInclLocationSensitiveTransportInfoWithIncludeFlag */ - ); + verifyOwnerUidAndTransportInfoNetCapsNotIncluded(); } @Test @@ -9964,6 +9953,7 @@ public class ConnectivityServiceTest { @Test public void testDumpDoesNotCrash() { + mServiceContext.setPermission(DUMP, PERMISSION_GRANTED); // Filing a couple requests prior to testing the dump. final TestNetworkCallback genericNetworkCallback = new TestNetworkCallback(); final TestNetworkCallback wifiNetworkCallback = new TestNetworkCallback(); @@ -11720,6 +11710,33 @@ public class ConnectivityServiceTest { } @Test + public void testSetOemNetworkPreferenceLogsRequest() throws Exception { + mServiceContext.setPermission(DUMP, PERMISSION_GRANTED); + @OemNetworkPreferences.OemNetworkPreference final int networkPref = + OEM_NETWORK_PREFERENCE_OEM_PAID; + final StringWriter stringWriter = new StringWriter(); + final String logIdentifier = "UPDATE INITIATED: OemNetworkPreferences"; + final Pattern pattern = Pattern.compile(logIdentifier); + + final int expectedNumLogs = 2; + final UidRangeParcel[] uidRanges = + toUidRangeStableParcels(uidRangesForUids(TEST_PACKAGE_UID)); + + // Call twice to generate two logs. + setupSetOemNetworkPreferenceForPreferenceTest(networkPref, uidRanges, TEST_PACKAGE_NAME); + setupSetOemNetworkPreferenceForPreferenceTest(networkPref, uidRanges, TEST_PACKAGE_NAME); + mService.dump(new FileDescriptor(), new PrintWriter(stringWriter), new String[0]); + + final String dumpOutput = stringWriter.toString(); + final Matcher matcher = pattern.matcher(dumpOutput); + int count = 0; + while (matcher.find()) { + count++; + } + assertEquals(expectedNumLogs, count); + } + + @Test public void testGetAllNetworkStateSnapshot() throws Exception { verifyNoNetwork(); diff --git a/tests/net/java/com/android/server/connectivity/PermissionMonitorTest.java b/tests/net/java/com/android/server/connectivity/PermissionMonitorTest.java index fec5ef39374a..d7535a958117 100644 --- a/tests/net/java/com/android/server/connectivity/PermissionMonitorTest.java +++ b/tests/net/java/com/android/server/connectivity/PermissionMonitorTest.java @@ -197,7 +197,7 @@ public class PermissionMonitorTest { } else { pkgInfo = packageInfoWithPermissions(REQUESTED_PERMISSION_GRANTED, new String[] {}, ""); } - pkgInfo.applicationInfo.uid = UserHandle.getUid(user, UserHandle.getAppId(uid)); + pkgInfo.applicationInfo.uid = user.getUid(UserHandle.getAppId(uid)); return pkgInfo; } @@ -390,7 +390,7 @@ public class PermissionMonitorTest { public void expectPermission(Boolean permission, UserHandle[] users, int[] apps) { for (final UserHandle user : users) { for (final int app : apps) { - final int uid = UserHandle.getUid(user, app); + final int uid = user.getUid(app); if (!mApps.containsKey(uid)) { fail("uid " + uid + " does not exist."); } @@ -404,7 +404,7 @@ public class PermissionMonitorTest { public void expectNoPermission(UserHandle[] users, int[] apps) { for (final UserHandle user : users) { for (final int app : apps) { - final int uid = UserHandle.getUid(user, app); + final int uid = user.getUid(app); if (mApps.containsKey(uid)) { fail("uid " + uid + " has listed permissions, expected none."); } @@ -502,9 +502,9 @@ public class PermissionMonitorTest { // When MOCK_UID1 package is uninstalled and reinstalled, expect Netd to be updated mPermissionMonitor.onPackageRemoved( - MOCK_PACKAGE1, UserHandle.getUid(MOCK_USER1, MOCK_UID1)); + MOCK_PACKAGE1, MOCK_USER1.getUid(MOCK_UID1)); verify(mNetdService).firewallRemoveUidInterfaceRules(aryEq(new int[] {MOCK_UID1})); - mPermissionMonitor.onPackageAdded(MOCK_PACKAGE1, UserHandle.getUid(MOCK_USER1, MOCK_UID1)); + mPermissionMonitor.onPackageAdded(MOCK_PACKAGE1, MOCK_USER1.getUid(MOCK_UID1)); verify(mNetdService).firewallAddUidInterfaceRules(eq("tun0"), aryEq(new int[] {MOCK_UID1})); @@ -541,13 +541,13 @@ public class PermissionMonitorTest { mPermissionMonitor.onVpnUidRangesAdded("tun0", vpnRange, VPN_UID); // Newly-installed package should have uid rules added - mPermissionMonitor.onPackageAdded(MOCK_PACKAGE1, UserHandle.getUid(MOCK_USER1, MOCK_UID1)); + mPermissionMonitor.onPackageAdded(MOCK_PACKAGE1, MOCK_USER1.getUid(MOCK_UID1)); verify(mNetdService).firewallAddUidInterfaceRules(eq("tun0"), aryEq(new int[] {MOCK_UID1})); // Removed package should have its uid rules removed mPermissionMonitor.onPackageRemoved( - MOCK_PACKAGE1, UserHandle.getUid(MOCK_USER1, MOCK_UID1)); + MOCK_PACKAGE1, MOCK_USER1.getUid(MOCK_UID1)); verify(mNetdService).firewallRemoveUidInterfaceRules(aryEq(new int[] {MOCK_UID1})); } @@ -557,13 +557,13 @@ public class PermissionMonitorTest { // called multiple times with the uid corresponding to each user. private void addPackageForUsers(UserHandle[] users, String packageName, int uid) { for (final UserHandle user : users) { - mPermissionMonitor.onPackageAdded(packageName, UserHandle.getUid(user, uid)); + mPermissionMonitor.onPackageAdded(packageName, user.getUid(uid)); } } private void removePackageForUsers(UserHandle[] users, String packageName, int uid) { for (final UserHandle user : users) { - mPermissionMonitor.onPackageRemoved(packageName, UserHandle.getUid(user, uid)); + mPermissionMonitor.onPackageRemoved(packageName, user.getUid(uid)); } } diff --git a/tests/vcn/java/android/net/vcn/VcnControlPlaneIkeConfigTest.java b/tests/vcn/java/android/net/vcn/VcnControlPlaneIkeConfigTest.java index 2333718d0cab..43b80e4c1bbf 100644 --- a/tests/vcn/java/android/net/vcn/VcnControlPlaneIkeConfigTest.java +++ b/tests/vcn/java/android/net/vcn/VcnControlPlaneIkeConfigTest.java @@ -22,12 +22,7 @@ import static android.net.ipsec.ike.SaProposal.PSEUDORANDOM_FUNCTION_AES128_XCBC import static org.junit.Assert.assertEquals; import static org.junit.Assert.fail; -import static org.mockito.Mockito.doReturn; -import static org.mockito.Mockito.mock; -import android.content.Context; -import android.net.ConnectivityManager; -import android.net.Network; import android.net.ipsec.ike.ChildSaProposal; import android.net.ipsec.ike.IkeFqdnIdentification; import android.net.ipsec.ike.IkeSaProposal; @@ -56,20 +51,13 @@ public class VcnControlPlaneIkeConfigTest { .addPseudorandomFunction(PSEUDORANDOM_FUNCTION_AES128_XCBC) .build(); - Context mockContext = mock(Context.class); - ConnectivityManager mockConnectManager = mock(ConnectivityManager.class); - doReturn(mockConnectManager) - .when(mockContext) - .getSystemService(Context.CONNECTIVITY_SERVICE); - doReturn(mock(Network.class)).when(mockConnectManager).getActiveNetwork(); - final String serverHostname = "192.0.2.100"; final String testLocalId = "test.client.com"; final String testRemoteId = "test.server.com"; final byte[] psk = "psk".getBytes(); IKE_PARAMS = - new IkeSessionParams.Builder(mockContext) + new IkeSessionParams.Builder() .setServerHostname(serverHostname) .addSaProposal(ikeProposal) .setLocalIdentification(new IkeFqdnIdentification(testLocalId)) diff --git a/tests/vcn/java/com/android/server/VcnManagementServiceTest.java b/tests/vcn/java/com/android/server/VcnManagementServiceTest.java index 43e6676e1d4c..bbc9bb600f6d 100644 --- a/tests/vcn/java/com/android/server/VcnManagementServiceTest.java +++ b/tests/vcn/java/com/android/server/VcnManagementServiceTest.java @@ -81,7 +81,6 @@ import android.telephony.TelephonyManager; import androidx.test.filters.SmallTest; import androidx.test.runner.AndroidJUnit4; -import com.android.net.module.util.LocationPermissionChecker; import com.android.server.VcnManagementService.VcnCallback; import com.android.server.VcnManagementService.VcnStatusCallbackInfo; import com.android.server.vcn.TelephonySubscriptionTracker; @@ -162,8 +161,6 @@ public class VcnManagementServiceTest { mock(PersistableBundleUtils.LockingReadWriteHelper.class); private final TelephonySubscriptionTracker mSubscriptionTracker = mock(TelephonySubscriptionTracker.class); - private final LocationPermissionChecker mLocationPermissionChecker = - mock(LocationPermissionChecker.class); private final ArgumentCaptor<VcnCallback> mVcnCallbackCaptor = ArgumentCaptor.forClass(VcnCallback.class); @@ -207,9 +204,6 @@ public class VcnManagementServiceTest { doReturn(mConfigReadWriteHelper) .when(mMockDeps) .newPersistableBundleLockingReadWriteHelper(any()); - doReturn(mLocationPermissionChecker) - .when(mMockDeps) - .newLocationPermissionChecker(eq(mMockContext)); // Setup VCN instance generation doAnswer((invocation) -> { @@ -521,10 +515,6 @@ public class VcnManagementServiceTest { @Test public void testSetVcnConfigNotifiesStatusCallback() throws Exception { - mVcnMgmtSvc.systemReady(); - doReturn(true) - .when(mLocationPermissionChecker) - .checkLocationPermission(eq(TEST_PACKAGE_NAME), any(), eq(TEST_UID), any()); triggerSubscriptionTrackerCbAndGetSnapshot(Collections.singleton(TEST_UUID_2)); mVcnMgmtSvc.registerVcnStatusCallback(TEST_UUID_2, mMockStatusCallback, TEST_PACKAGE_NAME); @@ -697,10 +687,6 @@ public class VcnManagementServiceTest { doReturn(isVcnActive ? VCN_STATUS_CODE_ACTIVE : VCN_STATUS_CODE_SAFE_MODE) .when(vcn) .getStatus(); - - doReturn(true) - .when(mLocationPermissionChecker) - .checkLocationPermission(eq(TEST_PACKAGE_NAME), any(), eq(TEST_UID), any()); } private NetworkCapabilities.Builder getNetworkCapabilitiesBuilderForTransport( @@ -933,8 +919,7 @@ public class VcnManagementServiceTest { @NonNull ParcelUuid subGroup, @NonNull String pkgName, int uid, - boolean hasPermissionsforSubGroup, - boolean hasLocationPermission) + boolean hasPermissionsforSubGroup) throws Exception { TelephonySubscriptionSnapshot snapshot = triggerSubscriptionTrackerCbAndGetSnapshot(Collections.singleton(subGroup)); @@ -946,10 +931,6 @@ public class VcnManagementServiceTest { .when(snapshot) .packageHasPermissionsForSubscriptionGroup(eq(subGroup), eq(pkgName)); - doReturn(hasLocationPermission) - .when(mLocationPermissionChecker) - .checkLocationPermission(eq(pkgName), any(), eq(uid), any()); - mVcnMgmtSvc.registerVcnStatusCallback(subGroup, mMockStatusCallback, pkgName); triggerVcnSafeMode(subGroup, snapshot, true /* enterSafeMode */); @@ -959,11 +940,7 @@ public class VcnManagementServiceTest { public void testVcnStatusCallbackOnSafeModeStatusChangedWithCarrierPrivileges() throws Exception { triggerVcnStatusCallbackOnSafeModeStatusChanged( - TEST_UUID_1, - TEST_PACKAGE_NAME, - TEST_UID, - true /* hasPermissionsforSubGroup */, - true /* hasLocationPermission */); + TEST_UUID_1, TEST_PACKAGE_NAME, TEST_UID, true /* hasPermissionsforSubGroup */); verify(mMockStatusCallback).onVcnStatusChanged(VcnManager.VCN_STATUS_CODE_SAFE_MODE); } @@ -972,25 +949,7 @@ public class VcnManagementServiceTest { public void testVcnStatusCallbackOnSafeModeStatusChangedWithoutCarrierPrivileges() throws Exception { triggerVcnStatusCallbackOnSafeModeStatusChanged( - TEST_UUID_1, - TEST_PACKAGE_NAME, - TEST_UID, - false /* hasPermissionsforSubGroup */, - true /* hasLocationPermission */); - - verify(mMockStatusCallback, never()) - .onVcnStatusChanged(VcnManager.VCN_STATUS_CODE_SAFE_MODE); - } - - @Test - public void testVcnStatusCallbackOnSafeModeStatusChangedWithoutLocationPermission() - throws Exception { - triggerVcnStatusCallbackOnSafeModeStatusChanged( - TEST_UUID_1, - TEST_PACKAGE_NAME, - TEST_UID, - true /* hasPermissionsforSubGroup */, - false /* hasLocationPermission */); + TEST_UUID_1, TEST_PACKAGE_NAME, TEST_UID, false /* hasPermissionsforSubGroup */); verify(mMockStatusCallback, never()) .onVcnStatusChanged(VcnManager.VCN_STATUS_CODE_SAFE_MODE); @@ -1052,9 +1011,6 @@ public class VcnManagementServiceTest { .when(snapshot) .packageHasPermissionsForSubscriptionGroup( eq(TEST_UUID_1), eq(TEST_CB_PACKAGE_NAME)); - doReturn(true) - .when(mLocationPermissionChecker) - .checkLocationPermission(eq(TEST_CB_PACKAGE_NAME), any(), eq(TEST_UID), any()); mVcnMgmtSvc.registerVcnStatusCallback( TEST_UUID_1, mMockStatusCallback, TEST_CB_PACKAGE_NAME); diff --git a/tests/vcn/java/com/android/server/vcn/UnderlyingNetworkTrackerTest.java b/tests/vcn/java/com/android/server/vcn/UnderlyingNetworkTrackerTest.java index b592000e38f9..0c7363e55cc6 100644 --- a/tests/vcn/java/com/android/server/vcn/UnderlyingNetworkTrackerTest.java +++ b/tests/vcn/java/com/android/server/vcn/UnderlyingNetworkTrackerTest.java @@ -153,21 +153,19 @@ public class UnderlyingNetworkTrackerTest { verify(mConnectivityManager) .requestBackgroundNetwork( eq(getWifiRequest(expectedSubIds)), - any(), - any(NetworkBringupCallback.class)); + any(NetworkBringupCallback.class), + any()); for (final int subId : expectedSubIds) { verify(mConnectivityManager) .requestBackgroundNetwork( eq(getCellRequestForSubId(subId)), - any(), - any(NetworkBringupCallback.class)); + any(NetworkBringupCallback.class), any()); } verify(mConnectivityManager) .requestBackgroundNetwork( eq(getRouteSelectionRequest(expectedSubIds)), - any(), - any(RouteSelectionCallback.class)); + any(RouteSelectionCallback.class), any()); } @Test @@ -267,8 +265,8 @@ public class UnderlyingNetworkTrackerTest { verify(mConnectivityManager) .requestBackgroundNetwork( eq(getRouteSelectionRequest(INITIAL_SUB_IDS)), - any(), - mRouteSelectionCallbackCaptor.capture()); + mRouteSelectionCallbackCaptor.capture(), + any()); RouteSelectionCallback cb = mRouteSelectionCallbackCaptor.getValue(); cb.onAvailable(mNetwork); diff --git a/tests/vcn/java/com/android/server/vcn/VcnGatewayConnectionConnectedStateTest.java b/tests/vcn/java/com/android/server/vcn/VcnGatewayConnectionConnectedStateTest.java index 34c00182f855..a2223e8c1e9a 100644 --- a/tests/vcn/java/com/android/server/vcn/VcnGatewayConnectionConnectedStateTest.java +++ b/tests/vcn/java/com/android/server/vcn/VcnGatewayConnectionConnectedStateTest.java @@ -20,12 +20,15 @@ import static android.net.IpSecManager.DIRECTION_IN; import static android.net.IpSecManager.DIRECTION_OUT; import static android.net.NetworkCapabilities.TRANSPORT_CELLULAR; import static android.net.NetworkCapabilities.TRANSPORT_WIFI; +import static android.net.ipsec.ike.exceptions.IkeProtocolException.ERROR_TYPE_AUTHENTICATION_FAILED; +import static android.net.ipsec.ike.exceptions.IkeProtocolException.ERROR_TYPE_TEMPORARY_FAILURE; import static android.net.vcn.VcnManager.VCN_ERROR_CODE_CONFIG_ERROR; import static android.net.vcn.VcnManager.VCN_ERROR_CODE_INTERNAL_ERROR; import static android.net.vcn.VcnManager.VCN_ERROR_CODE_NETWORK_ERROR; import static com.android.server.vcn.VcnGatewayConnection.VcnChildSessionConfiguration; import static com.android.server.vcn.VcnGatewayConnection.VcnIkeSession; +import static com.android.server.vcn.VcnGatewayConnection.VcnNetworkAgent; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; @@ -40,21 +43,25 @@ import static org.mockito.Mockito.never; 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.net.ConnectivityManager; import android.net.LinkAddress; import android.net.LinkProperties; import android.net.NetworkAgent; import android.net.NetworkCapabilities; -import android.net.ipsec.ike.exceptions.AuthenticationFailedException; +import android.net.ipsec.ike.ChildSaProposal; import android.net.ipsec.ike.exceptions.IkeException; import android.net.ipsec.ike.exceptions.IkeInternalException; -import android.net.ipsec.ike.exceptions.TemporaryFailureException; +import android.net.ipsec.ike.exceptions.IkeProtocolException; +import android.net.vcn.VcnControlPlaneIkeConfig; import android.net.vcn.VcnManager.VcnErrorCode; import androidx.test.filters.SmallTest; import androidx.test.runner.AndroidJUnit4; +import com.android.server.vcn.util.MtuUtils; + import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; @@ -73,13 +80,13 @@ import java.util.function.Consumer; @SmallTest public class VcnGatewayConnectionConnectedStateTest extends VcnGatewayConnectionTestBase { private VcnIkeSession mIkeSession; - private NetworkAgent mNetworkAgent; + private VcnNetworkAgent mNetworkAgent; @Before public void setUp() throws Exception { super.setUp(); - mNetworkAgent = mock(NetworkAgent.class); + mNetworkAgent = mock(VcnNetworkAgent.class); doReturn(mNetworkAgent) .when(mDeps) .newNetworkAgent(any(), any(), any(), any(), anyInt(), any(), any(), any(), any()); @@ -152,7 +159,9 @@ public class VcnGatewayConnectionConnectedStateTest extends VcnGatewayConnection } @Test - public void testMigratedTransformsAreApplied() throws Exception { + public void testMigration() throws Exception { + triggerChildOpened(); + getChildSessionCallback() .onIpSecTransformsMigrated(makeDummyIpSecTransform(), makeDummyIpSecTransform()); mTestLooper.dispatchAll(); @@ -170,6 +179,17 @@ public class VcnGatewayConnectionConnectedStateTest extends VcnGatewayConnection } assertEquals(mGatewayConnection.mConnectedState, mGatewayConnection.getCurrentState()); + + final List<ChildSaProposal> saProposals = + ((VcnControlPlaneIkeConfig) mConfig.getControlPlaneConfig()) + .getChildSessionParams() + .getSaProposals(); + final int expectedMtu = + MtuUtils.getMtu( + saProposals, + mConfig.getMaxMtu(), + TEST_UNDERLYING_NETWORK_RECORD_1.linkProperties.getMtu()); + verify(mNetworkAgent).sendLinkProperties(argThat(lp -> expectedMtu == lp.getMtu())); } private void triggerChildOpened() { @@ -299,8 +319,9 @@ public class VcnGatewayConnectionConnectedStateTest extends VcnGatewayConnection .removeAddressFromTunnelInterface( eq(TEST_IPSEC_TUNNEL_RESOURCE_ID), eq(TEST_INTERNAL_ADDR), any()); - // TODO(b/184579891): Also verify link properties updated and sent when sendLinkProperties - // is mockable + verify(mNetworkAgent).sendLinkProperties(argThat( + lp -> newInternalAddrs.equals(lp.getLinkAddresses()) + && Collections.singletonList(TEST_DNS_ADDR_2).equals(lp.getDnsServers()))); // Verify that IpSecTunnelInterface only created once verify(mIpSecSvc).createTunnelInterface(any(), any(), any(), any(), any()); @@ -323,6 +344,66 @@ public class VcnGatewayConnectionConnectedStateTest extends VcnGatewayConnection assertFalse(mGatewayConnection.isInSafeMode()); } + private Consumer<VcnNetworkAgent> setupNetworkAndGetUnwantedCallback() { + triggerChildOpened(); + mTestLooper.dispatchAll(); + + final ArgumentCaptor<Consumer<VcnNetworkAgent>> unwantedCallbackCaptor = + ArgumentCaptor.forClass(Consumer.class); + verify(mDeps) + .newNetworkAgent( + any(), + any(), + any(), + any(), + anyInt(), + any(), + any(), + unwantedCallbackCaptor.capture(), + any()); + + return unwantedCallbackCaptor.getValue(); + } + + @Test + public void testUnwantedNetworkAgentTriggersTeardown() throws Exception { + final Consumer<VcnNetworkAgent> unwantedCallback = setupNetworkAndGetUnwantedCallback(); + + unwantedCallback.accept(mNetworkAgent); + mTestLooper.dispatchAll(); + + assertTrue(mGatewayConnection.isQuitting()); + assertEquals(mGatewayConnection.mDisconnectingState, mGatewayConnection.getCurrentState()); + } + + @Test + public void testUnwantedNetworkAgentWithDisconnectedNetworkAgent() throws Exception { + final Consumer<VcnNetworkAgent> unwantedCallback = setupNetworkAndGetUnwantedCallback(); + + mGatewayConnection.setNetworkAgent(null); + unwantedCallback.accept(mNetworkAgent); + mTestLooper.dispatchAll(); + + // Verify that the call was ignored; the state machine is still running, and the state has + // not changed. + assertFalse(mGatewayConnection.isQuitting()); + assertEquals(mGatewayConnection.mConnectedState, mGatewayConnection.getCurrentState()); + } + + @Test + public void testUnwantedNetworkAgentWithNewNetworkAgent() throws Exception { + final Consumer<VcnNetworkAgent> unwantedCallback = setupNetworkAndGetUnwantedCallback(); + final VcnNetworkAgent testAgent = mock(VcnNetworkAgent.class); + + mGatewayConnection.setNetworkAgent(testAgent); + unwantedCallback.accept(mNetworkAgent); + mTestLooper.dispatchAll(); + + assertFalse(mGatewayConnection.isQuitting()); + assertEquals(mGatewayConnection.mConnectedState, mGatewayConnection.getCurrentState()); + assertEquals(testAgent, mGatewayConnection.getNetworkAgent()); + } + @Test public void testChildSessionClosedTriggersDisconnect() throws Exception { // Verify scheduled but not canceled when entering ConnectedState @@ -391,10 +472,17 @@ public class VcnGatewayConnectionConnectedStateTest extends VcnGatewayConnection any()); } + private static IkeProtocolException buildMockIkeProtocolException(int errorCode) { + final IkeProtocolException exception = mock(IkeProtocolException.class); + when(exception.getErrorType()).thenReturn(errorCode); + return exception; + } + @Test public void testIkeSessionClosedExceptionallyAuthenticationFailure() throws Exception { verifyIkeSessionClosedExceptionalltyNotifiesStatusCallback( - new AuthenticationFailedException("vcn test"), VCN_ERROR_CODE_CONFIG_ERROR); + buildMockIkeProtocolException(ERROR_TYPE_AUTHENTICATION_FAILED), + VCN_ERROR_CODE_CONFIG_ERROR); } @Test @@ -406,7 +494,8 @@ public class VcnGatewayConnectionConnectedStateTest extends VcnGatewayConnection @Test public void testIkeSessionClosedExceptionallyInternalFailure() throws Exception { verifyIkeSessionClosedExceptionalltyNotifiesStatusCallback( - new TemporaryFailureException("vcn test"), VCN_ERROR_CODE_INTERNAL_ERROR); + buildMockIkeProtocolException(ERROR_TYPE_TEMPORARY_FAILURE), + VCN_ERROR_CODE_INTERNAL_ERROR); } @Test diff --git a/tests/vcn/java/com/android/server/vcn/VcnGatewayConnectionConnectingStateTest.java b/tests/vcn/java/com/android/server/vcn/VcnGatewayConnectionConnectingStateTest.java index bfe8c73d6389..acc8bf98e95b 100644 --- a/tests/vcn/java/com/android/server/vcn/VcnGatewayConnectionConnectingStateTest.java +++ b/tests/vcn/java/com/android/server/vcn/VcnGatewayConnectionConnectingStateTest.java @@ -58,8 +58,7 @@ public class VcnGatewayConnectionConnectingStateTest extends VcnGatewayConnectio ArgumentCaptor.forClass(IkeSessionParams.class); verify(mDeps).newIkeSession(any(), paramsCaptor.capture(), any(), any(), any()); assertEquals( - TEST_UNDERLYING_NETWORK_RECORD_1.network, - paramsCaptor.getValue().getConfiguredNetwork()); + TEST_UNDERLYING_NETWORK_RECORD_1.network, paramsCaptor.getValue().getNetwork()); } @Test diff --git a/tests/vcn/java/com/android/server/vcn/VcnGatewayConnectionTestBase.java b/tests/vcn/java/com/android/server/vcn/VcnGatewayConnectionTestBase.java index c5ed8f6ddcc7..dc73be25ffa3 100644 --- a/tests/vcn/java/com/android/server/vcn/VcnGatewayConnectionTestBase.java +++ b/tests/vcn/java/com/android/server/vcn/VcnGatewayConnectionTestBase.java @@ -18,6 +18,7 @@ package com.android.server.vcn; import static com.android.server.vcn.UnderlyingNetworkTracker.UnderlyingNetworkRecord; import static com.android.server.vcn.VcnGatewayConnection.VcnIkeSession; +import static com.android.server.vcn.VcnGatewayConnection.VcnNetworkAgent; import static com.android.server.vcn.VcnTestUtils.setupIpSecManager; import static org.junit.Assert.assertEquals; @@ -44,7 +45,6 @@ import android.net.IpSecTunnelInterfaceResponse; import android.net.LinkAddress; import android.net.LinkProperties; import android.net.Network; -import android.net.NetworkAgent; import android.net.NetworkCapabilities; import android.net.ipsec.ike.ChildSessionCallback; import android.net.ipsec.ike.IkeSessionCallback; @@ -90,12 +90,18 @@ public class VcnGatewayConnectionTestBase { protected static final int TEST_SUB_ID = 5; protected static final long ELAPSED_REAL_TIME = 123456789L; protected static final String TEST_IPSEC_TUNNEL_IFACE = "IPSEC_IFACE"; + protected static final UnderlyingNetworkRecord TEST_UNDERLYING_NETWORK_RECORD_1 = new UnderlyingNetworkRecord( new Network(0), new NetworkCapabilities(), new LinkProperties(), false /* blocked */); + + static { + TEST_UNDERLYING_NETWORK_RECORD_1.linkProperties.setMtu(1500); + } + protected static final UnderlyingNetworkRecord TEST_UNDERLYING_NETWORK_RECORD_2 = new UnderlyingNetworkRecord( new Network(1), @@ -103,6 +109,10 @@ public class VcnGatewayConnectionTestBase { new LinkProperties(), false /* blocked */); + static { + TEST_UNDERLYING_NETWORK_RECORD_2.linkProperties.setMtu(1460); + } + protected static final TelephonySubscriptionSnapshot TEST_SUBSCRIPTION_SNAPSHOT = new TelephonySubscriptionSnapshot( Collections.singletonMap(TEST_SUB_ID, TEST_SUB_GRP), Collections.EMPTY_MAP); @@ -278,8 +288,8 @@ public class VcnGatewayConnectionTestBase { protected void verifySafeModeTimeoutNotifiesCallbackAndUnregistersNetworkAgent( @NonNull State expectedState) { - // Set a NetworkAgent, and expect it to be unregistered and cleared - final NetworkAgent mockNetworkAgent = mock(NetworkAgent.class); + // Set a VcnNetworkAgent, and expect it to be unregistered and cleared + final VcnNetworkAgent mockNetworkAgent = mock(VcnNetworkAgent.class); mGatewayConnection.setNetworkAgent(mockNetworkAgent); // SafeMode timer starts when VcnGatewayConnection exits DisconnectedState (the initial diff --git a/tests/vcn/java/com/android/server/vcn/util/MtuUtilsTest.java b/tests/vcn/java/com/android/server/vcn/util/MtuUtilsTest.java new file mode 100644 index 000000000000..29511f780bf6 --- /dev/null +++ b/tests/vcn/java/com/android/server/vcn/util/MtuUtilsTest.java @@ -0,0 +1,92 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES 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.vcn.util; + +import static android.net.ipsec.ike.SaProposal.ENCRYPTION_ALGORITHM_AES_CBC; +import static android.net.ipsec.ike.SaProposal.ENCRYPTION_ALGORITHM_AES_GCM_12; +import static android.net.ipsec.ike.SaProposal.ENCRYPTION_ALGORITHM_AES_GCM_16; +import static android.net.ipsec.ike.SaProposal.ENCRYPTION_ALGORITHM_AES_GCM_8; +import static android.net.ipsec.ike.SaProposal.INTEGRITY_ALGORITHM_HMAC_SHA2_256_128; +import static android.net.ipsec.ike.SaProposal.KEY_LEN_AES_256; + +import static com.android.net.module.util.NetworkStackConstants.ETHER_MTU; +import static com.android.net.module.util.NetworkStackConstants.IPV6_MIN_MTU; +import static com.android.server.vcn.util.MtuUtils.getMtu; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + +import static java.util.Collections.emptyList; + +import android.net.ipsec.ike.ChildSaProposal; + +import androidx.test.filters.SmallTest; +import androidx.test.runner.AndroidJUnit4; + +import org.junit.Test; +import org.junit.runner.RunWith; + +import java.util.Arrays; +import java.util.List; + +@RunWith(AndroidJUnit4.class) +@SmallTest +public class MtuUtilsTest { + @Test + public void testUnderlyingMtuZero() { + assertEquals( + IPV6_MIN_MTU, getMtu(emptyList(), ETHER_MTU /* maxMtu */, 0 /* underlyingMtu */)); + } + + @Test + public void testClampsToMaxMtu() { + assertEquals(0, getMtu(emptyList(), 0 /* maxMtu */, IPV6_MIN_MTU /* underlyingMtu */)); + } + + @Test + public void testNormalModeAlgorithmLessThanUnderlyingMtu() { + final List<ChildSaProposal> saProposals = + Arrays.asList( + new ChildSaProposal.Builder() + .addEncryptionAlgorithm( + ENCRYPTION_ALGORITHM_AES_CBC, KEY_LEN_AES_256) + .addIntegrityAlgorithm(INTEGRITY_ALGORITHM_HMAC_SHA2_256_128) + .build()); + + final int actualMtu = + getMtu(saProposals, ETHER_MTU /* maxMtu */, ETHER_MTU /* underlyingMtu */); + assertTrue(ETHER_MTU > actualMtu); + } + + @Test + public void testCombinedModeAlgorithmLessThanUnderlyingMtu() { + final List<ChildSaProposal> saProposals = + Arrays.asList( + new ChildSaProposal.Builder() + .addEncryptionAlgorithm( + ENCRYPTION_ALGORITHM_AES_GCM_16, KEY_LEN_AES_256) + .addEncryptionAlgorithm( + ENCRYPTION_ALGORITHM_AES_GCM_12, KEY_LEN_AES_256) + .addEncryptionAlgorithm( + ENCRYPTION_ALGORITHM_AES_GCM_8, KEY_LEN_AES_256) + .build()); + + final int actualMtu = + getMtu(saProposals, ETHER_MTU /* maxMtu */, ETHER_MTU /* underlyingMtu */); + assertTrue(ETHER_MTU > actualMtu); + } +} diff --git a/tools/fonts/Android.bp b/tools/fonts/Android.bp new file mode 100644 index 000000000000..bf506613c0a1 --- /dev/null +++ b/tools/fonts/Android.bp @@ -0,0 +1,39 @@ +// Copyright (C) 2021 The Android Open Source Project +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +python_defaults { + name: "fonts_python_defaults", + version: { + py2: { + enabled: false, + embedded_launcher: false, + }, + py3: { + enabled: true, + embedded_launcher: true, + }, + }, +} + +python_binary_host { + name: "fontchain_linter", + defaults: ["fonts_python_defaults"], + main: "fontchain_linter.py", + srcs: [ + "fontchain_linter.py", + ], + libs: [ + "fontTools", + ], +} diff --git a/tools/hiddenapi/OWNERS b/tools/hiddenapi/OWNERS new file mode 100644 index 000000000000..afbeef5a0b41 --- /dev/null +++ b/tools/hiddenapi/OWNERS @@ -0,0 +1,7 @@ +# compat-team@ for changes to hiddenapi files +andreionea@google.com +mathewi@google.com +satayev@google.com + +# soong-team@ as the files these tools protect are tightly coupled with Soong +file:platform/build/soong:/OWNERS diff --git a/tools/hiddenapi/checksorted_sha.sh b/tools/hiddenapi/checksorted_sha.sh deleted file mode 100755 index ceb705f4e42a..000000000000 --- a/tools/hiddenapi/checksorted_sha.sh +++ /dev/null @@ -1,10 +0,0 @@ -#!/bin/bash -set -e -LOCAL_DIR="$( dirname ${BASH_SOURCE} )" -git show --name-only --pretty=format: $1 | grep "config/hiddenapi-.*txt" | while read file; do - diff <(git show $1:$file) <(git show $1:$file | $LOCAL_DIR/sort_api.sh ) || { - echo -e "\e[1m\e[31m$file $1 is not sorted or contains duplicates. To sort it correctly:\e[0m" - echo -e "\e[33m${LOCAL_DIR}/sort_api.sh $2/frameworks/base/$file\e[0m" - exit 1 - } -done diff --git a/tools/hiddenapi/exclude.sh b/tools/hiddenapi/exclude.sh index 73eacc0641e5..8b18f9b1920e 100755 --- a/tools/hiddenapi/exclude.sh +++ b/tools/hiddenapi/exclude.sh @@ -7,12 +7,9 @@ LOCAL_DIR="$( dirname ${BASH_SOURCE} )" # the team email to use in the event of this detecting an entry in a <team> package. Also # add <team> to the TEAMS list. LIBCORE_PACKAGES="\ - android.icu \ android.system \ android.test \ com.android.bouncycastle \ - com.android.conscrypt \ - com.android.i18n.phonenumbers \ com.android.okhttp \ com.sun \ dalvik \ @@ -24,37 +21,54 @@ LIBCORE_PACKAGES="\ org.json \ org.w3c.dom \ org.xml.sax \ + org.xmlpull.v1 \ sun \ " LIBCORE_EMAIL=libcore-team@android.com +I18N_PACKAGES="\ + android.icu \ + " + +I18N_EMAIL=$LIBCORE_EMAIL + +CONSCRYPT_PACKAGES="\ + com.android.org.conscrypt \ + " + +CONSCRYPT_EMAIL=$LIBCORE_EMAIL + # List of teams. -TEAMS=LIBCORE +TEAMS="LIBCORE I18N CONSCRYPT" + +SHA=$1 # Generate the list of packages and convert to a regular expression. PACKAGES=$(for t in $TEAMS; do echo $(eval echo \${${t}_PACKAGES}); done) RE=$(echo ${PACKAGES} | sed "s/ /|/g") -git show --name-only --pretty=format: $1 | grep "config/hiddenapi-.*txt" | while read file; do - ENTRIES=$(grep -E "^L(${RE})/" || true <(git show $1:$file)) +EXIT_CODE=0 +for file in $(git show --name-only --pretty=format: $SHA | grep "boot/hiddenapi/hiddenapi-.*txt"); do + ENTRIES=$(grep -E "^\+L(${RE})/" <(git diff ${SHA}~1 ${SHA} $file) | sed "s|^\+||" || echo) if [[ -n "${ENTRIES}" ]]; then - echo -e "\e[1m\e[31m$file $1 contains the following entries\e[0m" + echo -e "\e[1m\e[31m$file $SHA contains the following entries\e[0m" echo -e "\e[1m\e[31mfor packages that are handled using UnsupportedAppUsage. Please remove\e[0m" echo -e "\e[1m\e[31mthese entries and add annotations instead.\e[0m" # Partition the entries by team and provide contact details to aid in fixing the issue. for t in ${TEAMS} do PACKAGES=$(eval echo \${${t}_PACKAGES}) - RE=$(echo ${PACKAGES} | sed "s/ /|/g") - TEAM_ENTRIES=$(grep -E "^L(${RE})/" <(echo "${ENTRIES}")) + TEAM_RE=$(echo ${PACKAGES} | sed "s/ /|/g") + TEAM_ENTRIES=$(grep -E "^L(${TEAM_RE})/" <(echo "${ENTRIES}") || echo) if [[ -n "${TEAM_ENTRIES}" ]]; then EMAIL=$(eval echo \${${t}_EMAIL}) - echo -e "\e[33mContact ${EMAIL} or compat- for help with the following:\e[0m" - for i in ${ENTRIES} + echo -e "\e[33mContact ${EMAIL} for help with the following:\e[0m" + for i in ${TEAM_ENTRIES} do echo -e "\e[33m ${i}\e[0m" done fi done - exit 1 + EXIT_CODE=1 fi done +exit $EXIT_CODE diff --git a/tools/hiddenapi/sort_api.sh b/tools/hiddenapi/sort_api.sh deleted file mode 100755 index 710da40585ac..000000000000 --- a/tools/hiddenapi/sort_api.sh +++ /dev/null @@ -1,26 +0,0 @@ -#!/bin/bash -set -e -if [ -z "$1" ]; then - source_list=/dev/stdin - dest_list=/dev/stdout -else - source_list="$1" - dest_list="$1" -fi -# Load the file -readarray A < "$source_list" -# Sort -IFS=$'\n' -# Stash away comments -C=( $(grep -E '^#' <<< "${A[*]}" || :) ) -A=( $(grep -v -E '^#' <<< "${A[*]}" || :) ) -# Sort entries -A=( $(LC_COLLATE=C sort -f <<< "${A[*]}") ) -A=( $(uniq <<< "${A[*]}") ) -# Concatenate comments and entries -A=( ${C[*]} ${A[*]} ) -unset IFS -# Dump array back into the file -if [ ${#A[@]} -ne 0 ]; then - printf '%s\n' "${A[@]}" > "$dest_list" -fi |