diff options
121 files changed, 3555 insertions, 2836 deletions
diff --git a/Android.bp b/Android.bp index 54fedaf9bb0f..60ec7e2709a7 100644 --- a/Android.bp +++ b/Android.bp @@ -65,7 +65,6 @@ filegroup { // Java/AIDL sources under frameworks/base ":framework-annotations", ":framework-blobstore-sources", - ":framework-bluetooth-sources", // TODO(b/214988855) : Remove once framework-bluetooth jar is ready ":framework-connectivity-tiramisu-sources", ":framework-core-sources", ":framework-drm-sources", @@ -273,6 +272,7 @@ java_defaults { defaults: ["framework-aidl-export-defaults"], srcs: [ ":framework-non-updatable-sources", + ":framework-bluetooth-sources", // TODO(b/214988855) : Remove once framework-bluetooth jar is ready "core/java/**/*.logtags", ":apex-info-list", ], @@ -503,7 +503,9 @@ filegroup { visibility: ["//visibility:private"], } -// These defaults are used for both the jar stubs and the doc stubs. +// Defaults for all stubs that include the non-updatable framework. These defaults do not include +// module symbols, so will not compile correctly on their own. Users must add module APIs to the +// classpath (or sources) somehow. stubs_defaults { name: "android-non-updatable-stubs-defaults", srcs: [":android-non-updatable-stub-sources"], @@ -511,17 +513,14 @@ stubs_defaults { system_modules: "none", java_version: "1.8", arg_files: ["core/res/AndroidManifest.xml"], - // TODO(b/147699819): remove below aidl includes. aidl: { local_include_dirs: [ - "apex/media/aidl/stable", "media/aidl", "telephony/java", ], include_dirs: [ "frameworks/av/aidl", "frameworks/native/libs/permission/aidl", - "packages/modules/Connectivity/framework/aidl-export", ], }, // These are libs from framework-internal-utils that are required (i.e. being referenced) @@ -543,8 +542,33 @@ stubs_defaults { "android.hardware.usb.gadget-V1.0-java", "android.hardware.vibrator-V1.3-java", "framework-protos", + ], + filter_packages: packages_to_document, + high_mem: true, // Lots of sources => high memory use, see b/170701554 + installable: false, + annotations_enabled: true, + previous_api: ":android.api.public.latest", + merge_annotations_dirs: ["metalava-manual"], + defaults_visibility: ["//visibility:private"], + visibility: ["//frameworks/base/api"], +} + +// Defaults with module APIs in the classpath (mostly from prebuilts). +// Suitable for compiling android-non-updatable. +stubs_defaults { + name: "module-classpath-stubs-defaults", + aidl: { + local_include_dirs: [ + "apex/media/aidl/stable", + ], + include_dirs: [ + "packages/modules/Connectivity/framework/aidl-export", + ], + }, + libs: [ "art.module.public.api", "sdk_module-lib_current_framework-tethering", + "sdk_public_current_framework-bluetooth", // There are a few classes from modules used by the core that // need to be resolved by metalava. We use a prebuilt stub of the // full sdk to ensure we can resolve them. If a new class gets added, @@ -553,14 +577,7 @@ stubs_defaults { // NOTE: The below can be removed once the prebuilt stub contains IKE. "sdk_system_current_android.net.ipsec.ike", ], - filter_packages: packages_to_document, - high_mem: true, // Lots of sources => high memory use, see b/170701554 - installable: false, - annotations_enabled: true, - previous_api: ":android.api.public.latest", - merge_annotations_dirs: ["metalava-manual"], defaults_visibility: ["//visibility:private"], - visibility: ["//frameworks/base/api"], } build = [ diff --git a/ApiDocs.bp b/ApiDocs.bp index ec7b19482c82..5595e95631ad 100644 --- a/ApiDocs.bp +++ b/ApiDocs.bp @@ -55,6 +55,7 @@ framework_docs_only_libs = [ "android-support-multidex-instrumentation", ] +// These defaults enable doc-stub generation, api lint database generation and sdk value generation. stubs_defaults { name: "android-non-updatable-doc-stubs-defaults", defaults: ["android-non-updatable-stubs-defaults"], @@ -69,47 +70,10 @@ stubs_defaults { write_sdk_values: true, } -stubs_defaults { - name: "framework-doc-stubs-default", - srcs: [ - ":android-non-updatable-stub-sources", - - // No longer part of the stubs, but are included in the docs. - ":android-test-base-sources", - ":android-test-mock-sources", - ":android-test-runner-sources", - ], - arg_files: [ - "core/res/AndroidManifest.xml", - ], - libs: framework_docs_only_libs, - create_doc_stubs: true, - annotations_enabled: true, - filter_packages: packages_to_document, - api_levels_annotations_enabled: true, - api_levels_annotations_dirs: [ - "sdk-dir", - "api-versions-jars-dir", - ], - previous_api: ":android.api.public.latest", - merge_annotations_dirs: [ - "metalava-manual", - ], - write_sdk_values: true, - // TODO(b/169090544): remove below aidl includes. - aidl: { - local_include_dirs: ["media/aidl"], - include_dirs: [ - "frameworks/av/aidl", - "frameworks/native/libs/permission/aidl", - ], - }, -} - // Defaults module for doc-stubs targets that use module source code as input. stubs_defaults { name: "framework-doc-stubs-sources-default", - defaults: ["framework-doc-stubs-default"], + defaults: ["android-non-updatable-doc-stubs-defaults"], srcs: [ ":art.module.public.api{.public.stubs.source}", ":conscrypt.module.public.api{.public.stubs.source}", @@ -117,6 +81,7 @@ stubs_defaults { ":framework-appsearch-sources", ":framework-connectivity-sources", + ":framework-bluetooth-sources", ":framework-connectivity-tiramisu-updatable-sources", ":framework-graphics-srcs", ":framework-mediaprovider-sources", @@ -134,13 +99,19 @@ stubs_defaults { droidstubs { name: "android-non-updatable-doc-stubs", - defaults: ["android-non-updatable-doc-stubs-defaults"], + defaults: [ + "android-non-updatable-doc-stubs-defaults", + "module-classpath-stubs-defaults", + ], args: metalava_framework_docs_args, } droidstubs { name: "android-non-updatable-doc-stubs-system", - defaults: ["android-non-updatable-doc-stubs-defaults"], + defaults: [ + "android-non-updatable-doc-stubs-defaults", + "module-classpath-stubs-defaults", + ], args: metalava_framework_docs_args + " --show-annotation android.annotation.SystemApi\\(client=android.annotation.SystemApi.Client.PRIVILEGED_APPS\\) ", } @@ -150,14 +121,24 @@ droidstubs { defaults: ["framework-doc-stubs-sources-default"], args: metalava_framework_docs_args + " --show-annotation android.annotation.SystemApi\\(client=android.annotation.SystemApi.Client.PRIVILEGED_APPS\\) ", + api_levels_annotations_enabled: true, + api_levels_annotations_dirs: [ + "sdk-dir", + "api-versions-jars-dir", + ], api_levels_sdk_type: "system", } droidstubs { name: "framework-doc-stubs", - defaults: ["framework-doc-stubs-default"], + defaults: ["android-non-updatable-doc-stubs-defaults"], srcs: [":all-modules-public-stubs-source"], args: metalava_framework_docs_args, + api_levels_annotations_enabled: true, + api_levels_annotations_dirs: [ + "sdk-dir", + "api-versions-jars-dir", + ], aidl: { local_include_dirs: [ "apex/media/aidl/stable", diff --git a/StubLibraries.bp b/StubLibraries.bp index 2ce37921715e..5cb0a785bc2b 100644 --- a/StubLibraries.bp +++ b/StubLibraries.bp @@ -24,23 +24,15 @@ // with the latest frozen API signature. ///////////////////////////////////////////////////////////////////// -// Common metalava configs -///////////////////////////////////////////////////////////////////// - -stubs_defaults { - name: "metalava-non-updatable-api-stubs-default", - defaults: ["android-non-updatable-stubs-defaults"], - api_levels_annotations_enabled: false, - defaults_visibility: ["//visibility:private"], -} - -///////////////////////////////////////////////////////////////////// // These modules provide source files for the stub libraries ///////////////////////////////////////////////////////////////////// droidstubs { name: "api-stubs-docs-non-updatable", - defaults: ["metalava-non-updatable-api-stubs-default"], + defaults: [ + "android-non-updatable-stubs-defaults", + "module-classpath-stubs-defaults", + ], args: metalava_framework_docs_args, check_api: { current: { @@ -89,7 +81,10 @@ module_libs = " --show-annotation android.annotation.SystemApi\\(" + droidstubs { name: "system-api-stubs-docs-non-updatable", - defaults: ["metalava-non-updatable-api-stubs-default"], + defaults: [ + "android-non-updatable-stubs-defaults", + "module-classpath-stubs-defaults", + ], args: metalava_framework_docs_args + priv_apps, check_api: { current: { @@ -125,7 +120,10 @@ droidstubs { droidstubs { name: "test-api-stubs-docs-non-updatable", - defaults: ["metalava-non-updatable-api-stubs-default"], + defaults: [ + "android-non-updatable-stubs-defaults", + "module-classpath-stubs-defaults", + ], args: metalava_framework_docs_args + test + priv_apps_in_stubs, check_api: { current: { @@ -167,7 +165,10 @@ droidstubs { droidstubs { name: "module-lib-api-stubs-docs-non-updatable", - defaults: ["metalava-non-updatable-api-stubs-default"], + defaults: [ + "android-non-updatable-stubs-defaults", + "module-classpath-stubs-defaults", + ], args: metalava_framework_docs_args + priv_apps_in_stubs + module_libs, check_api: { current: { @@ -206,46 +207,6 @@ droidstubs { // from stub sources ///////////////////////////////////////////////////////////////////// -modules_public_stubs = [ - "android.net.ipsec.ike.stubs", - "art.module.public.api.stubs", - "conscrypt.module.public.api.stubs", - "framework-appsearch.stubs", - "framework-connectivity.stubs", - "framework-connectivity-tiramisu.stubs", - "framework-graphics.stubs", - "framework-media.stubs", - "framework-mediaprovider.stubs", - "framework-permission.stubs", - "framework-permission-s.stubs", - "framework-scheduling.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.system", - "conscrypt.module.public.api.stubs", // Only has public stubs - "framework-appsearch.stubs.system", - "framework-connectivity.stubs.system", - "framework-connectivity-tiramisu.stubs.system", - "framework-graphics.stubs.system", - "framework-media.stubs.system", - "framework-mediaprovider.stubs.system", - "framework-permission.stubs.system", - "framework-permission-s.stubs.system", - "framework-scheduling.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-non-updatable_defaults_stubs_current", libs: ["stub-annotations"], @@ -267,7 +228,7 @@ java_library { name: "android-non-updatable.stubs", defaults: ["android-non-updatable_defaults_stubs_current"], srcs: [":api-stubs-docs-non-updatable"], - libs: modules_public_stubs, + libs: ["all-modules-public-stubs"], dist: { dir: "apistubs/android/public", }, @@ -277,7 +238,7 @@ java_library { name: "android-non-updatable.stubs.system", defaults: ["android-non-updatable_defaults_stubs_current"], srcs: [":system-api-stubs-docs-non-updatable"], - libs: modules_system_stubs, + libs: ["all-modules-system-stubs"], dist: { dir: "apistubs/android/system", }, @@ -289,6 +250,8 @@ java_library { srcs: [":module-lib-api-stubs-docs-non-updatable"], libs: [ "sdk_module-lib_current_framework-tethering", + "sdk_public_current_framework-bluetooth", + // NOTE: The below can be removed once the prebuilt stub contains bluetooth. "sdk_system_current_android", // NOTE: The below can be removed once the prebuilt stub contains IKE. "sdk_system_current_android.net.ipsec.ike", @@ -302,7 +265,7 @@ java_library { name: "android-non-updatable.stubs.test", defaults: ["android-non-updatable_defaults_stubs_current"], srcs: [":test-api-stubs-docs-non-updatable"], - libs: modules_system_stubs, + libs: ["all-modules-system-stubs"], dist: { dir: "apistubs/android/test", }, @@ -320,7 +283,8 @@ java_defaults { java_library { name: "android_stubs_current", - static_libs: modules_public_stubs + [ + static_libs: [ + "all-modules-public-stubs", "android-non-updatable.stubs", "private-stub-annotations-jar", ], @@ -329,7 +293,8 @@ java_library { java_library { name: "android_system_stubs_current", - static_libs: modules_system_stubs + [ + static_libs: [ + "all-modules-system-stubs", "android-non-updatable.stubs.system", "private-stub-annotations-jar", ], @@ -354,7 +319,8 @@ java_library { name: "android_test_stubs_current", // 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 + [ + static_libs: [ + "all-modules-system-stubs", "android-non-updatable.stubs.test", "private-stub-annotations-jar", ], diff --git a/api/Android.bp b/api/Android.bp index 0c3a3e60bd9a..15356bdc0797 100644 --- a/api/Android.bp +++ b/api/Android.bp @@ -110,6 +110,7 @@ combined_apis { "art.module.public.api", "conscrypt.module.public.api", "framework-appsearch", + "framework-bluetooth", "framework-connectivity", "framework-connectivity-tiramisu", "framework-graphics", diff --git a/api/api.go b/api/api.go index 4b6ebc1947e9..aa9e399e7272 100644 --- a/api/api.go +++ b/api/api.go @@ -27,6 +27,7 @@ import ( const art = "art.module.public.api" const conscrypt = "conscrypt.module.public.api" const i18n = "i18n.module.public.api" +var modules_with_only_public_scope = []string{i18n, conscrypt} // The intention behind this soong plugin is to generate a number of "merged" // API-related modules that would otherwise require a large amount of very @@ -183,6 +184,27 @@ func createFilteredApiVersions(ctx android.LoadHookContext, modules []string) { ctx.CreateModule(genrule.GenRuleFactory, &props) } +func createMergedPublicStubs(ctx android.LoadHookContext, modules []string) { + props := libraryProps{} + props.Name = proptools.StringPtr("all-modules-public-stubs") + props.Static_libs = transformArray(modules, "", ".stubs") + props.Sdk_version = proptools.StringPtr("module_current") + props.Visibility = []string{"//frameworks/base"} + ctx.CreateModule(java.LibraryFactory, &props) +} + +func createMergedSystemStubs(ctx android.LoadHookContext, modules []string) { + props := libraryProps{} + modules_with_system_stubs := removeAll(modules, modules_with_only_public_scope) + props.Name = proptools.StringPtr("all-modules-system-stubs") + props.Static_libs = append( + transformArray(modules_with_only_public_scope, "", ".stubs"), + transformArray(modules_with_system_stubs, "", ".stubs.system")...) + props.Sdk_version = proptools.StringPtr("module_current") + props.Visibility = []string{"//frameworks/base"} + ctx.CreateModule(java.LibraryFactory, &props) +} + func createMergedModuleLibStubs(ctx android.LoadHookContext, modules []string) { // The user of this module compiles against the "core" SDK, so remove core libraries to avoid dupes. modules = removeAll(modules, []string{art, conscrypt, i18n}) @@ -205,7 +227,7 @@ func createPublicStubsSourceFilegroup(ctx android.LoadHookContext, modules []str func createMergedTxts(ctx android.LoadHookContext, bootclasspath, system_server_classpath []string) { var textFiles []MergedTxtDefinition // Two module libraries currently do not support @SystemApi so only have the public scope. - bcpWithSystemApi := removeAll(bootclasspath, []string{conscrypt, i18n}) + bcpWithSystemApi := removeAll(bootclasspath, modules_with_only_public_scope) tagSuffix := []string{".api.txt}", ".removed-api.txt}"} for i, f := range []string{"current.txt", "removed.txt"} { @@ -253,6 +275,8 @@ func (a *CombinedApis) createInternalModules(ctx android.LoadHookContext) { createMergedStubsSrcjar(ctx, bootclasspath) + createMergedPublicStubs(ctx, bootclasspath) + createMergedSystemStubs(ctx, bootclasspath) createMergedModuleLibStubs(ctx, bootclasspath) createMergedAnnotations(ctx, bootclasspath) diff --git a/cmds/app_process/Android.bp b/cmds/app_process/Android.bp index a1575173ded6..6a685a79cc33 100644 --- a/cmds/app_process/Android.bp +++ b/cmds/app_process/Android.bp @@ -64,6 +64,8 @@ cc_binary { "libwilhelm", ], + header_libs: ["bionic_libc_platform_headers"], + compile_multilib: "both", cflags: [ diff --git a/cmds/app_process/app_main.cpp b/cmds/app_process/app_main.cpp index 12083b6fe20b..815f9455471c 100644 --- a/cmds/app_process/app_main.cpp +++ b/cmds/app_process/app_main.cpp @@ -15,6 +15,7 @@ #include <android-base/macros.h> #include <binder/IPCThreadState.h> +#include <bionic/pac.h> #include <hwbinder/IPCThreadState.h> #include <utils/Log.h> #include <cutils/memory.h> @@ -182,6 +183,10 @@ int main(int argc, char* const argv[]) ALOGV("app_process main with argv: %s", argv_String.string()); } + // Because of applications that are using PAC instructions incorrectly, PAC + // is disabled in application processes for now. + ScopedDisablePAC x; + AppRuntime runtime(argv[0], computeArgBlockSize(argc, argv)); // Process command line arguments // ignore argv[0] diff --git a/core/api/current.txt b/core/api/current.txt index 3550d327340d..a32a3a9207aa 100644 --- a/core/api/current.txt +++ b/core/api/current.txt @@ -7185,6 +7185,7 @@ package android.app.admin { method @Nullable public java.util.List<java.lang.String> getPermittedCrossProfileNotificationListeners(@NonNull android.content.ComponentName); method @Nullable public java.util.List<java.lang.String> getPermittedInputMethods(@NonNull android.content.ComponentName); method public int getPersonalAppsSuspendedReasons(@NonNull android.content.ComponentName); + method @NonNull public android.app.admin.PreferentialNetworkServiceConfig getPreferentialNetworkServiceConfig(); method public int getRequiredPasswordComplexity(); method public long getRequiredStrongAuthTimeout(@Nullable android.content.ComponentName); method public boolean getScreenCaptureDisabled(@Nullable android.content.ComponentName); @@ -7327,6 +7328,7 @@ package android.app.admin { method public boolean setPermittedCrossProfileNotificationListeners(@NonNull android.content.ComponentName, @Nullable java.util.List<java.lang.String>); method public boolean setPermittedInputMethods(@NonNull android.content.ComponentName, java.util.List<java.lang.String>); method public void setPersonalAppsSuspended(@NonNull android.content.ComponentName, boolean); + method public void setPreferentialNetworkServiceConfig(@NonNull android.app.admin.PreferentialNetworkServiceConfig); method public void setPreferentialNetworkServiceEnabled(boolean); method public void setProfileEnabled(@NonNull android.content.ComponentName); method public void setProfileName(@NonNull android.content.ComponentName, String); @@ -7572,6 +7574,32 @@ package android.app.admin { field @NonNull public static final android.os.Parcelable.Creator<android.app.admin.NetworkEvent> CREATOR; } + public final class PreferentialNetworkServiceConfig implements android.os.Parcelable { + method public int describeContents(); + method @NonNull public int[] getExcludedUids(); + method @NonNull public int[] getIncludedUids(); + method public int getNetworkId(); + method public boolean isEnabled(); + method public boolean isFallbackToDefaultConnectionAllowed(); + method public void writeToParcel(@NonNull android.os.Parcel, int); + field @NonNull public static final android.os.Parcelable.Creator<android.app.admin.PreferentialNetworkServiceConfig> CREATOR; + field public static final int PREFERENTIAL_NETWORK_ID_1 = 1; // 0x1 + field public static final int PREFERENTIAL_NETWORK_ID_2 = 2; // 0x2 + field public static final int PREFERENTIAL_NETWORK_ID_3 = 3; // 0x3 + field public static final int PREFERENTIAL_NETWORK_ID_4 = 4; // 0x4 + field public static final int PREFERENTIAL_NETWORK_ID_5 = 5; // 0x5 + } + + public static final class PreferentialNetworkServiceConfig.Builder { + ctor public PreferentialNetworkServiceConfig.Builder(); + method @NonNull public android.app.admin.PreferentialNetworkServiceConfig build(); + method @NonNull public android.app.admin.PreferentialNetworkServiceConfig.Builder setEnabled(boolean); + method @NonNull public android.app.admin.PreferentialNetworkServiceConfig.Builder setExcludedUids(@NonNull int[]); + method @NonNull public android.app.admin.PreferentialNetworkServiceConfig.Builder setFallbackToDefaultConnectionAllowed(boolean); + method @NonNull public android.app.admin.PreferentialNetworkServiceConfig.Builder setIncludedUids(@NonNull int[]); + method @NonNull public android.app.admin.PreferentialNetworkServiceConfig.Builder setNetworkId(int); + } + public class SecurityLog { ctor public SecurityLog(); field public static final int LEVEL_ERROR = 3; // 0x3 @@ -8616,1318 +8644,6 @@ package android.appwidget { } -package android.bluetooth { - - public final class BluetoothA2dp implements android.bluetooth.BluetoothProfile { - method public void finalize(); - method @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public java.util.List<android.bluetooth.BluetoothDevice> getConnectedDevices(); - method @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public int getConnectionState(android.bluetooth.BluetoothDevice); - method @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public java.util.List<android.bluetooth.BluetoothDevice> getDevicesMatchingConnectionStates(int[]); - method @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public boolean isA2dpPlaying(android.bluetooth.BluetoothDevice); - field @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public static final String ACTION_CONNECTION_STATE_CHANGED = "android.bluetooth.a2dp.profile.action.CONNECTION_STATE_CHANGED"; - field @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public static final String ACTION_PLAYING_STATE_CHANGED = "android.bluetooth.a2dp.profile.action.PLAYING_STATE_CHANGED"; - field public static final int STATE_NOT_PLAYING = 11; // 0xb - field public static final int STATE_PLAYING = 10; // 0xa - } - - public final class BluetoothAdapter { - method @RequiresPermission(android.Manifest.permission.BLUETOOTH_SCAN) public boolean cancelDiscovery(); - method public static boolean checkBluetoothAddress(String); - method public void closeProfileProxy(int, android.bluetooth.BluetoothProfile); - method @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public boolean disable(); - method @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public boolean enable(); - method @RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT, "android.permission.LOCAL_MAC_ADDRESS"}) public String getAddress(); - method public android.bluetooth.le.BluetoothLeAdvertiser getBluetoothLeAdvertiser(); - method public android.bluetooth.le.BluetoothLeScanner getBluetoothLeScanner(); - method @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public java.util.Set<android.bluetooth.BluetoothDevice> getBondedDevices(); - method @Deprecated public static android.bluetooth.BluetoothAdapter getDefaultAdapter(); - method public int getLeMaximumAdvertisingDataLength(); - method @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public String getName(); - method @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public int getProfileConnectionState(int); - method public boolean getProfileProxy(android.content.Context, android.bluetooth.BluetoothProfile.ServiceListener, int); - method public android.bluetooth.BluetoothDevice getRemoteDevice(String); - method public android.bluetooth.BluetoothDevice getRemoteDevice(byte[]); - method @RequiresPermission(android.Manifest.permission.BLUETOOTH_SCAN) public int getScanMode(); - method public int getState(); - method @RequiresPermission(android.Manifest.permission.BLUETOOTH_SCAN) public boolean isDiscovering(); - method public boolean isEnabled(); - method public boolean isLe2MPhySupported(); - method public int isLeAudioSupported(); - method public boolean isLeCodedPhySupported(); - method public boolean isLeExtendedAdvertisingSupported(); - method public boolean isLePeriodicAdvertisingSupported(); - method public int isLePeriodicAdvertisingSyncTransferSenderSupported(); - method public boolean isMultipleAdvertisementSupported(); - method public boolean isOffloadedFilteringSupported(); - method public boolean isOffloadedScanBatchingSupported(); - method @NonNull @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public android.bluetooth.BluetoothServerSocket listenUsingInsecureL2capChannel() throws java.io.IOException; - method @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public android.bluetooth.BluetoothServerSocket listenUsingInsecureRfcommWithServiceRecord(String, java.util.UUID) throws java.io.IOException; - method @NonNull @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public android.bluetooth.BluetoothServerSocket listenUsingL2capChannel() throws java.io.IOException; - method @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public android.bluetooth.BluetoothServerSocket listenUsingRfcommWithServiceRecord(String, java.util.UUID) throws java.io.IOException; - method @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public boolean setName(String); - method @RequiresPermission(android.Manifest.permission.BLUETOOTH_SCAN) public boolean startDiscovery(); - method @Deprecated @RequiresPermission(android.Manifest.permission.BLUETOOTH_SCAN) public boolean startLeScan(android.bluetooth.BluetoothAdapter.LeScanCallback); - method @Deprecated @RequiresPermission(android.Manifest.permission.BLUETOOTH_SCAN) public boolean startLeScan(java.util.UUID[], android.bluetooth.BluetoothAdapter.LeScanCallback); - method @Deprecated @RequiresPermission(android.Manifest.permission.BLUETOOTH_SCAN) public void stopLeScan(android.bluetooth.BluetoothAdapter.LeScanCallback); - field @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public static final String ACTION_CONNECTION_STATE_CHANGED = "android.bluetooth.adapter.action.CONNECTION_STATE_CHANGED"; - field @RequiresPermission(android.Manifest.permission.BLUETOOTH_SCAN) public static final String ACTION_DISCOVERY_FINISHED = "android.bluetooth.adapter.action.DISCOVERY_FINISHED"; - field @RequiresPermission(android.Manifest.permission.BLUETOOTH_SCAN) public static final String ACTION_DISCOVERY_STARTED = "android.bluetooth.adapter.action.DISCOVERY_STARTED"; - field @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public static final String ACTION_LOCAL_NAME_CHANGED = "android.bluetooth.adapter.action.LOCAL_NAME_CHANGED"; - field @RequiresPermission(android.Manifest.permission.BLUETOOTH_ADVERTISE) public static final String ACTION_REQUEST_DISCOVERABLE = "android.bluetooth.adapter.action.REQUEST_DISCOVERABLE"; - field @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public static final String ACTION_REQUEST_ENABLE = "android.bluetooth.adapter.action.REQUEST_ENABLE"; - field @RequiresPermission(android.Manifest.permission.BLUETOOTH_SCAN) public static final String ACTION_SCAN_MODE_CHANGED = "android.bluetooth.adapter.action.SCAN_MODE_CHANGED"; - field public static final String ACTION_STATE_CHANGED = "android.bluetooth.adapter.action.STATE_CHANGED"; - field public static final int ERROR = -2147483648; // 0x80000000 - field public static final String EXTRA_CONNECTION_STATE = "android.bluetooth.adapter.extra.CONNECTION_STATE"; - field public static final String EXTRA_DISCOVERABLE_DURATION = "android.bluetooth.adapter.extra.DISCOVERABLE_DURATION"; - field public static final String EXTRA_LOCAL_NAME = "android.bluetooth.adapter.extra.LOCAL_NAME"; - field public static final String EXTRA_PREVIOUS_CONNECTION_STATE = "android.bluetooth.adapter.extra.PREVIOUS_CONNECTION_STATE"; - field public static final String EXTRA_PREVIOUS_SCAN_MODE = "android.bluetooth.adapter.extra.PREVIOUS_SCAN_MODE"; - field public static final String EXTRA_PREVIOUS_STATE = "android.bluetooth.adapter.extra.PREVIOUS_STATE"; - field public static final String EXTRA_SCAN_MODE = "android.bluetooth.adapter.extra.SCAN_MODE"; - field public static final String EXTRA_STATE = "android.bluetooth.adapter.extra.STATE"; - field public static final int SCAN_MODE_CONNECTABLE = 21; // 0x15 - field public static final int SCAN_MODE_CONNECTABLE_DISCOVERABLE = 23; // 0x17 - field public static final int SCAN_MODE_NONE = 20; // 0x14 - field public static final int STATE_CONNECTED = 2; // 0x2 - field public static final int STATE_CONNECTING = 1; // 0x1 - field public static final int STATE_DISCONNECTED = 0; // 0x0 - field public static final int STATE_DISCONNECTING = 3; // 0x3 - field public static final int STATE_OFF = 10; // 0xa - field public static final int STATE_ON = 12; // 0xc - field public static final int STATE_TURNING_OFF = 13; // 0xd - field public static final int STATE_TURNING_ON = 11; // 0xb - } - - public static interface BluetoothAdapter.LeScanCallback { - method public void onLeScan(android.bluetooth.BluetoothDevice, int, byte[]); - } - - public class BluetoothAssignedNumbers { - field public static final int AAMP_OF_AMERICA = 190; // 0xbe - field public static final int ACCEL_SEMICONDUCTOR = 74; // 0x4a - field public static final int ACE_SENSOR = 188; // 0xbc - field public static final int ADIDAS = 195; // 0xc3 - field public static final int ADVANCED_PANMOBIL_SYSTEMS = 145; // 0x91 - field public static final int AIROHA_TECHNOLOGY = 148; // 0x94 - field public static final int ALCATEL = 36; // 0x24 - field public static final int ALPWISE = 154; // 0x9a - field public static final int AMICCOM_ELECTRONICS = 192; // 0xc0 - field public static final int APLIX = 189; // 0xbd - field public static final int APPLE = 76; // 0x4c - field public static final int APT_LICENSING = 79; // 0x4f - field public static final int ARCHOS = 207; // 0xcf - field public static final int ARP_DEVICES = 168; // 0xa8 - field public static final int ATHEROS_COMMUNICATIONS = 69; // 0x45 - field public static final int ATMEL = 19; // 0x13 - field public static final int AUSTCO_COMMUNICATION_SYSTEMS = 213; // 0xd5 - field public static final int AUTONET_MOBILE = 127; // 0x7f - field public static final int AVAGO = 78; // 0x4e - field public static final int AVM_BERLIN = 31; // 0x1f - field public static final int A_AND_D_ENGINEERING = 105; // 0x69 - field public static final int A_AND_R_CAMBRIDGE = 124; // 0x7c - field public static final int BANDSPEED = 32; // 0x20 - field public static final int BAND_XI_INTERNATIONAL = 100; // 0x64 - field public static final int BDE_TECHNOLOGY = 180; // 0xb4 - field public static final int BEATS_ELECTRONICS = 204; // 0xcc - field public static final int BEAUTIFUL_ENTERPRISE = 108; // 0x6c - field public static final int BEKEY = 178; // 0xb2 - field public static final int BELKIN_INTERNATIONAL = 92; // 0x5c - field public static final int BINAURIC = 203; // 0xcb - field public static final int BIOSENTRONICS = 219; // 0xdb - field public static final int BLUEGIGA = 71; // 0x47 - field public static final int BLUERADIOS = 133; // 0x85 - field public static final int BLUETOOTH_SIG = 63; // 0x3f - field public static final int BLUETREK_TECHNOLOGIES = 151; // 0x97 - field public static final int BOSE = 158; // 0x9e - field public static final int BRIARTEK = 109; // 0x6d - field public static final int BROADCOM = 15; // 0xf - field public static final int CAEN_RFID = 170; // 0xaa - field public static final int CAMBRIDGE_SILICON_RADIO = 10; // 0xa - field public static final int CATC = 52; // 0x34 - field public static final int CINETIX = 175; // 0xaf - field public static final int CLARINOX_TECHNOLOGIES = 179; // 0xb3 - field public static final int COLORFY = 156; // 0x9c - field public static final int COMMIL = 51; // 0x33 - field public static final int CONEXANT_SYSTEMS = 28; // 0x1c - field public static final int CONNECTBLUE = 113; // 0x71 - field public static final int CONTINENTAL_AUTOMOTIVE = 75; // 0x4b - field public static final int CONWISE_TECHNOLOGY = 66; // 0x42 - field public static final int CREATIVE_TECHNOLOGY = 118; // 0x76 - field public static final int C_TECHNOLOGIES = 38; // 0x26 - field public static final int DANLERS = 225; // 0xe1 - field public static final int DELORME_PUBLISHING_COMPANY = 128; // 0x80 - field public static final int DEXCOM = 208; // 0xd0 - field public static final int DIALOG_SEMICONDUCTOR = 210; // 0xd2 - field public static final int DIGIANSWER = 12; // 0xc - field public static final int ECLIPSE = 53; // 0x35 - field public static final int ECOTEST = 136; // 0x88 - field public static final int ELGATO_SYSTEMS = 206; // 0xce - field public static final int EM_MICROELECTRONIC_MARIN = 90; // 0x5a - field public static final int EQUINOX_AG = 134; // 0x86 - field public static final int ERICSSON_TECHNOLOGY = 0; // 0x0 - field public static final int EVLUMA = 201; // 0xc9 - field public static final int FREE2MOVE = 83; // 0x53 - field public static final int FUNAI_ELECTRIC = 144; // 0x90 - field public static final int GARMIN_INTERNATIONAL = 135; // 0x87 - field public static final int GCT_SEMICONDUCTOR = 45; // 0x2d - field public static final int GELO = 200; // 0xc8 - field public static final int GENEQ = 194; // 0xc2 - field public static final int GENERAL_MOTORS = 104; // 0x68 - field public static final int GENNUM = 59; // 0x3b - field public static final int GEOFORCE = 157; // 0x9d - field public static final int GIBSON_GUITARS = 98; // 0x62 - field public static final int GN_NETCOM = 103; // 0x67 - field public static final int GN_RESOUND = 137; // 0x89 - field public static final int GOOGLE = 224; // 0xe0 - field public static final int GREEN_THROTTLE_GAMES = 172; // 0xac - field public static final int GROUP_SENSE = 115; // 0x73 - field public static final int HANLYNN_TECHNOLOGIES = 123; // 0x7b - field public static final int HARMAN_INTERNATIONAL = 87; // 0x57 - field public static final int HEWLETT_PACKARD = 101; // 0x65 - field public static final int HITACHI = 41; // 0x29 - field public static final int HOSIDEN = 221; // 0xdd - field public static final int IBM = 3; // 0x3 - field public static final int INFINEON_TECHNOLOGIES = 9; // 0x9 - field public static final int INGENIEUR_SYSTEMGRUPPE_ZAHN = 171; // 0xab - field public static final int INTEGRATED_SILICON_SOLUTION = 65; // 0x41 - field public static final int INTEGRATED_SYSTEM_SOLUTION = 57; // 0x39 - field public static final int INTEL = 2; // 0x2 - field public static final int INVENTEL = 30; // 0x1e - field public static final int IPEXTREME = 61; // 0x3d - field public static final int I_TECH_DYNAMIC_GLOBAL_DISTRIBUTION = 153; // 0x99 - field public static final int JAWBONE = 138; // 0x8a - field public static final int JIANGSU_TOPPOWER_AUTOMOTIVE_ELECTRONICS = 155; // 0x9b - field public static final int JOHNSON_CONTROLS = 185; // 0xb9 - field public static final int J_AND_M = 82; // 0x52 - field public static final int KAWANTECH = 212; // 0xd4 - field public static final int KC_TECHNOLOGY = 22; // 0x16 - field public static final int KENSINGTON_COMPUTER_PRODUCTS_GROUP = 160; // 0xa0 - field public static final int LAIRD_TECHNOLOGIES = 119; // 0x77 - field public static final int LESSWIRE = 121; // 0x79 - field public static final int LG_ELECTRONICS = 196; // 0xc4 - field public static final int LINAK = 164; // 0xa4 - field public static final int LUCENT = 7; // 0x7 - field public static final int LUDUS_HELSINKI = 132; // 0x84 - field public static final int MACRONIX = 44; // 0x2c - field public static final int MAGNETI_MARELLI = 169; // 0xa9 - field public static final int MANSELLA = 33; // 0x21 - field public static final int MARVELL = 72; // 0x48 - field public static final int MATSUSHITA_ELECTRIC = 58; // 0x3a - field public static final int MC10 = 202; // 0xca - field public static final int MEDIATEK = 70; // 0x46 - field public static final int MESO_INTERNATIONAL = 182; // 0xb6 - field public static final int META_WATCH = 163; // 0xa3 - field public static final int MEWTEL_TECHNOLOGY = 47; // 0x2f - field public static final int MICOMMAND = 99; // 0x63 - field public static final int MICROCHIP_TECHNOLOGY = 205; // 0xcd - field public static final int MICROSOFT = 6; // 0x6 - field public static final int MINDTREE = 106; // 0x6a - field public static final int MISFIT_WEARABLES = 223; // 0xdf - field public static final int MITEL_SEMICONDUCTOR = 16; // 0x10 - field public static final int MITSUBISHI_ELECTRIC = 20; // 0x14 - field public static final int MOBILIAN_CORPORATION = 55; // 0x37 - field public static final int MONSTER = 112; // 0x70 - field public static final int MOTOROLA = 8; // 0x8 - field public static final int MSTAR_SEMICONDUCTOR = 122; // 0x7a - field public static final int MUZIK = 222; // 0xde - field public static final int NEC = 34; // 0x22 - field public static final int NEC_LIGHTING = 149; // 0x95 - field public static final int NEWLOGIC = 23; // 0x17 - field public static final int NIKE = 120; // 0x78 - field public static final int NINE_SOLUTIONS = 102; // 0x66 - field public static final int NOKIA_MOBILE_PHONES = 1; // 0x1 - field public static final int NORDIC_SEMICONDUCTOR = 89; // 0x59 - field public static final int NORWOOD_SYSTEMS = 46; // 0x2e - field public static final int ODM_TECHNOLOGY = 150; // 0x96 - field public static final int OMEGAWAVE = 174; // 0xae - field public static final int ONSET_COMPUTER = 197; // 0xc5 - field public static final int OPEN_INTERFACE = 39; // 0x27 - field public static final int OTL_DYNAMICS = 165; // 0xa5 - field public static final int PANDA_OCEAN = 166; // 0xa6 - field public static final int PARROT = 67; // 0x43 - field public static final int PARTHUS_TECHNOLOGIES = 14; // 0xe - field public static final int PASSIF_SEMICONDUCTOR = 176; // 0xb0 - field public static final int PETER_SYSTEMTECHNIK = 173; // 0xad - field public static final int PHILIPS_SEMICONDUCTORS = 37; // 0x25 - field public static final int PLANTRONICS = 85; // 0x55 - field public static final int POLAR_ELECTRO = 107; // 0x6b - field public static final int POLAR_ELECTRO_EUROPE = 209; // 0xd1 - field public static final int PROCTER_AND_GAMBLE = 220; // 0xdc - field public static final int QUALCOMM = 29; // 0x1d - field public static final int QUALCOMM_CONNECTED_EXPERIENCES = 216; // 0xd8 - field public static final int QUALCOMM_INNOVATION_CENTER = 184; // 0xb8 - field public static final int QUALCOMM_LABS = 140; // 0x8c - field public static final int QUALCOMM_TECHNOLOGIES = 215; // 0xd7 - field public static final int QUINTIC = 142; // 0x8e - field public static final int QUUPPA = 199; // 0xc7 - field public static final int RALINK_TECHNOLOGY = 91; // 0x5b - field public static final int RDA_MICROELECTRONICS = 97; // 0x61 - field public static final int REALTEK_SEMICONDUCTOR = 93; // 0x5d - field public static final int RED_M = 50; // 0x32 - field public static final int RENESAS_TECHNOLOGY = 54; // 0x36 - field public static final int RESEARCH_IN_MOTION = 60; // 0x3c - field public static final int RF_MICRO_DEVICES = 40; // 0x28 - field public static final int RIVIERAWAVES = 96; // 0x60 - field public static final int ROHDE_AND_SCHWARZ = 25; // 0x19 - field public static final int RTX_TELECOM = 21; // 0x15 - field public static final int SAMSUNG_ELECTRONICS = 117; // 0x75 - field public static final int SARIS_CYCLING_GROUP = 177; // 0xb1 - field public static final int SEERS_TECHNOLOGY = 125; // 0x7d - field public static final int SEIKO_EPSON = 64; // 0x40 - field public static final int SELFLY = 198; // 0xc6 - field public static final int SEMILINK = 226; // 0xe2 - field public static final int SENNHEISER_COMMUNICATIONS = 130; // 0x82 - field public static final int SHANGHAI_SUPER_SMART_ELECTRONICS = 114; // 0x72 - field public static final int SHENZHEN_EXCELSECU_DATA_TECHNOLOGY = 193; // 0xc1 - field public static final int SIGNIA_TECHNOLOGIES = 27; // 0x1b - field public static final int SILICON_WAVE = 11; // 0xb - field public static final int SIRF_TECHNOLOGY = 80; // 0x50 - field public static final int SOCKET_MOBILE = 68; // 0x44 - field public static final int SONY_ERICSSON = 86; // 0x56 - field public static final int SOUND_ID = 111; // 0x6f - field public static final int SPORTS_TRACKING_TECHNOLOGIES = 126; // 0x7e - field public static final int SR_MEDIZINELEKTRONIK = 161; // 0xa1 - field public static final int STACCATO_COMMUNICATIONS = 77; // 0x4d - field public static final int STALMART_TECHNOLOGY = 191; // 0xbf - field public static final int STARKEY_LABORATORIES = 186; // 0xba - field public static final int STOLLMAN_E_PLUS_V = 143; // 0x8f - field public static final int STONESTREET_ONE = 94; // 0x5e - field public static final int ST_MICROELECTRONICS = 48; // 0x30 - field public static final int SUMMIT_DATA_COMMUNICATIONS = 110; // 0x6e - field public static final int SUUNTO = 159; // 0x9f - field public static final int SWIRL_NETWORKS = 181; // 0xb5 - field public static final int SYMBOL_TECHNOLOGIES = 42; // 0x2a - field public static final int SYNOPSYS = 49; // 0x31 - field public static final int SYSTEMS_AND_CHIPS = 62; // 0x3e - field public static final int S_POWER_ELECTRONICS = 187; // 0xbb - field public static final int TAIXINGBANG_TECHNOLOGY = 211; // 0xd3 - field public static final int TENOVIS = 43; // 0x2b - field public static final int TERAX = 56; // 0x38 - field public static final int TEXAS_INSTRUMENTS = 13; // 0xd - field public static final int THINKOPTICS = 146; // 0x92 - field public static final int THREECOM = 5; // 0x5 - field public static final int THREE_DIJOY = 84; // 0x54 - field public static final int THREE_DSP = 73; // 0x49 - field public static final int TIMEKEEPING_SYSTEMS = 131; // 0x83 - field public static final int TIMEX_GROUP_USA = 214; // 0xd6 - field public static final int TOPCORN_POSITIONING_SYSTEMS = 139; // 0x8b - field public static final int TOSHIBA = 4; // 0x4 - field public static final int TRANSILICA = 24; // 0x18 - field public static final int TRELAB = 183; // 0xb7 - field public static final int TTPCOM = 26; // 0x1a - field public static final int TXTR = 218; // 0xda - field public static final int TZERO_TECHNOLOGIES = 81; // 0x51 - field public static final int UNIVERSAL_ELECTRONICS = 147; // 0x93 - field public static final int VERTU = 162; // 0xa2 - field public static final int VISTEON = 167; // 0xa7 - field public static final int VIZIO = 88; // 0x58 - field public static final int VOYETRA_TURTLE_BEACH = 217; // 0xd9 - field public static final int WAVEPLUS_TECHNOLOGY = 35; // 0x23 - field public static final int WICENTRIC = 95; // 0x5f - field public static final int WIDCOMM = 17; // 0x11 - field public static final int WUXI_VIMICRO = 129; // 0x81 - field public static final int ZEEVO = 18; // 0x12 - field public static final int ZER01_TV = 152; // 0x98 - field public static final int ZOMM = 116; // 0x74 - field public static final int ZSCAN_SOFTWARE = 141; // 0x8d - } - - public final class BluetoothClass implements android.os.Parcelable { - method public int describeContents(); - method public int getDeviceClass(); - method public int getMajorDeviceClass(); - method public boolean hasService(int); - method public void writeToParcel(android.os.Parcel, int); - field @NonNull public static final android.os.Parcelable.Creator<android.bluetooth.BluetoothClass> CREATOR; - } - - public static class BluetoothClass.Device { - ctor public BluetoothClass.Device(); - field public static final int AUDIO_VIDEO_CAMCORDER = 1076; // 0x434 - field public static final int AUDIO_VIDEO_CAR_AUDIO = 1056; // 0x420 - field public static final int AUDIO_VIDEO_HANDSFREE = 1032; // 0x408 - field public static final int AUDIO_VIDEO_HEADPHONES = 1048; // 0x418 - field public static final int AUDIO_VIDEO_HIFI_AUDIO = 1064; // 0x428 - field public static final int AUDIO_VIDEO_LOUDSPEAKER = 1044; // 0x414 - field public static final int AUDIO_VIDEO_MICROPHONE = 1040; // 0x410 - field public static final int AUDIO_VIDEO_PORTABLE_AUDIO = 1052; // 0x41c - field public static final int AUDIO_VIDEO_SET_TOP_BOX = 1060; // 0x424 - field public static final int AUDIO_VIDEO_UNCATEGORIZED = 1024; // 0x400 - field public static final int AUDIO_VIDEO_VCR = 1068; // 0x42c - field public static final int AUDIO_VIDEO_VIDEO_CAMERA = 1072; // 0x430 - field public static final int AUDIO_VIDEO_VIDEO_CONFERENCING = 1088; // 0x440 - field public static final int AUDIO_VIDEO_VIDEO_DISPLAY_AND_LOUDSPEAKER = 1084; // 0x43c - field public static final int AUDIO_VIDEO_VIDEO_GAMING_TOY = 1096; // 0x448 - field public static final int AUDIO_VIDEO_VIDEO_MONITOR = 1080; // 0x438 - field public static final int AUDIO_VIDEO_WEARABLE_HEADSET = 1028; // 0x404 - field public static final int COMPUTER_DESKTOP = 260; // 0x104 - field public static final int COMPUTER_HANDHELD_PC_PDA = 272; // 0x110 - field public static final int COMPUTER_LAPTOP = 268; // 0x10c - field public static final int COMPUTER_PALM_SIZE_PC_PDA = 276; // 0x114 - field public static final int COMPUTER_SERVER = 264; // 0x108 - field public static final int COMPUTER_UNCATEGORIZED = 256; // 0x100 - field public static final int COMPUTER_WEARABLE = 280; // 0x118 - field public static final int HEALTH_BLOOD_PRESSURE = 2308; // 0x904 - field public static final int HEALTH_DATA_DISPLAY = 2332; // 0x91c - field public static final int HEALTH_GLUCOSE = 2320; // 0x910 - field public static final int HEALTH_PULSE_OXIMETER = 2324; // 0x914 - field public static final int HEALTH_PULSE_RATE = 2328; // 0x918 - field public static final int HEALTH_THERMOMETER = 2312; // 0x908 - field public static final int HEALTH_UNCATEGORIZED = 2304; // 0x900 - field public static final int HEALTH_WEIGHING = 2316; // 0x90c - field public static final int PHONE_CELLULAR = 516; // 0x204 - field public static final int PHONE_CORDLESS = 520; // 0x208 - field public static final int PHONE_ISDN = 532; // 0x214 - field public static final int PHONE_MODEM_OR_GATEWAY = 528; // 0x210 - field public static final int PHONE_SMART = 524; // 0x20c - field public static final int PHONE_UNCATEGORIZED = 512; // 0x200 - field public static final int TOY_CONTROLLER = 2064; // 0x810 - field public static final int TOY_DOLL_ACTION_FIGURE = 2060; // 0x80c - field public static final int TOY_GAME = 2068; // 0x814 - field public static final int TOY_ROBOT = 2052; // 0x804 - field public static final int TOY_UNCATEGORIZED = 2048; // 0x800 - field public static final int TOY_VEHICLE = 2056; // 0x808 - field public static final int WEARABLE_GLASSES = 1812; // 0x714 - field public static final int WEARABLE_HELMET = 1808; // 0x710 - field public static final int WEARABLE_JACKET = 1804; // 0x70c - field public static final int WEARABLE_PAGER = 1800; // 0x708 - field public static final int WEARABLE_UNCATEGORIZED = 1792; // 0x700 - field public static final int WEARABLE_WRIST_WATCH = 1796; // 0x704 - } - - public static class BluetoothClass.Device.Major { - ctor public BluetoothClass.Device.Major(); - field public static final int AUDIO_VIDEO = 1024; // 0x400 - field public static final int COMPUTER = 256; // 0x100 - field public static final int HEALTH = 2304; // 0x900 - field public static final int IMAGING = 1536; // 0x600 - field public static final int MISC = 0; // 0x0 - field public static final int NETWORKING = 768; // 0x300 - field public static final int PERIPHERAL = 1280; // 0x500 - field public static final int PHONE = 512; // 0x200 - field public static final int TOY = 2048; // 0x800 - field public static final int UNCATEGORIZED = 7936; // 0x1f00 - field public static final int WEARABLE = 1792; // 0x700 - } - - public static final class BluetoothClass.Service { - ctor public BluetoothClass.Service(); - field public static final int AUDIO = 2097152; // 0x200000 - field public static final int CAPTURE = 524288; // 0x80000 - field public static final int INFORMATION = 8388608; // 0x800000 - field public static final int LE_AUDIO = 16384; // 0x4000 - field public static final int LIMITED_DISCOVERABILITY = 8192; // 0x2000 - field public static final int NETWORKING = 131072; // 0x20000 - field public static final int OBJECT_TRANSFER = 1048576; // 0x100000 - field public static final int POSITIONING = 65536; // 0x10000 - field public static final int RENDER = 262144; // 0x40000 - field public static final int TELEPHONY = 4194304; // 0x400000 - } - - public final class BluetoothCodecConfig implements android.os.Parcelable { - ctor public BluetoothCodecConfig(int); - method public int describeContents(); - method public int getBitsPerSample(); - method public int getChannelMode(); - method public int getCodecPriority(); - method public long getCodecSpecific1(); - method public long getCodecSpecific2(); - method public long getCodecSpecific3(); - method public long getCodecSpecific4(); - method public int getCodecType(); - method public static int getMaxCodecType(); - method public int getSampleRate(); - method public void writeToParcel(android.os.Parcel, int); - field public static final int BITS_PER_SAMPLE_16 = 1; // 0x1 - field public static final int BITS_PER_SAMPLE_24 = 2; // 0x2 - field public static final int BITS_PER_SAMPLE_32 = 4; // 0x4 - field public static final int BITS_PER_SAMPLE_NONE = 0; // 0x0 - field public static final int CHANNEL_MODE_MONO = 1; // 0x1 - field public static final int CHANNEL_MODE_NONE = 0; // 0x0 - field public static final int CHANNEL_MODE_STEREO = 2; // 0x2 - field public static final int CODEC_PRIORITY_DEFAULT = 0; // 0x0 - field public static final int CODEC_PRIORITY_DISABLED = -1; // 0xffffffff - field public static final int CODEC_PRIORITY_HIGHEST = 1000000; // 0xf4240 - field @NonNull public static final android.os.Parcelable.Creator<android.bluetooth.BluetoothCodecConfig> CREATOR; - field public static final int SAMPLE_RATE_176400 = 16; // 0x10 - field public static final int SAMPLE_RATE_192000 = 32; // 0x20 - field public static final int SAMPLE_RATE_44100 = 1; // 0x1 - field public static final int SAMPLE_RATE_48000 = 2; // 0x2 - field public static final int SAMPLE_RATE_88200 = 4; // 0x4 - field public static final int SAMPLE_RATE_96000 = 8; // 0x8 - field public static final int SAMPLE_RATE_NONE = 0; // 0x0 - field public static final int SOURCE_CODEC_TYPE_AAC = 1; // 0x1 - field public static final int SOURCE_CODEC_TYPE_APTX = 2; // 0x2 - field public static final int SOURCE_CODEC_TYPE_APTX_HD = 3; // 0x3 - field public static final int SOURCE_CODEC_TYPE_INVALID = 1000000; // 0xf4240 - field public static final int SOURCE_CODEC_TYPE_LC3 = 5; // 0x5 - field public static final int SOURCE_CODEC_TYPE_LDAC = 4; // 0x4 - field public static final int SOURCE_CODEC_TYPE_SBC = 0; // 0x0 - } - - public static final class BluetoothCodecConfig.Builder { - ctor public BluetoothCodecConfig.Builder(); - method @NonNull public android.bluetooth.BluetoothCodecConfig build(); - method @NonNull public android.bluetooth.BluetoothCodecConfig.Builder setBitsPerSample(int); - method @NonNull public android.bluetooth.BluetoothCodecConfig.Builder setChannelMode(int); - method @NonNull public android.bluetooth.BluetoothCodecConfig.Builder setCodecPriority(int); - method @NonNull public android.bluetooth.BluetoothCodecConfig.Builder setCodecSpecific1(long); - method @NonNull public android.bluetooth.BluetoothCodecConfig.Builder setCodecSpecific2(long); - method @NonNull public android.bluetooth.BluetoothCodecConfig.Builder setCodecSpecific3(long); - method @NonNull public android.bluetooth.BluetoothCodecConfig.Builder setCodecSpecific4(long); - method @NonNull public android.bluetooth.BluetoothCodecConfig.Builder setCodecType(int); - method @NonNull public android.bluetooth.BluetoothCodecConfig.Builder setSampleRate(int); - } - - public final class BluetoothCodecStatus implements android.os.Parcelable { - ctor public BluetoothCodecStatus(@Nullable android.bluetooth.BluetoothCodecConfig, @Nullable java.util.List<android.bluetooth.BluetoothCodecConfig>, @Nullable java.util.List<android.bluetooth.BluetoothCodecConfig>); - method public int describeContents(); - method @Nullable public android.bluetooth.BluetoothCodecConfig getCodecConfig(); - method @NonNull public java.util.List<android.bluetooth.BluetoothCodecConfig> getCodecsLocalCapabilities(); - method @NonNull public java.util.List<android.bluetooth.BluetoothCodecConfig> getCodecsSelectableCapabilities(); - method public boolean isCodecConfigSelectable(@Nullable android.bluetooth.BluetoothCodecConfig); - method public void writeToParcel(@NonNull android.os.Parcel, int); - field @NonNull public static final android.os.Parcelable.Creator<android.bluetooth.BluetoothCodecStatus> CREATOR; - field public static final String EXTRA_CODEC_STATUS = "android.bluetooth.extra.CODEC_STATUS"; - } - - public final class BluetoothCsipSetCoordinator implements java.lang.AutoCloseable android.bluetooth.BluetoothProfile { - method public void close(); - method protected void finalize(); - method @NonNull public java.util.List<android.bluetooth.BluetoothDevice> getConnectedDevices(); - method public int getConnectionState(@Nullable android.bluetooth.BluetoothDevice); - method @NonNull public java.util.List<android.bluetooth.BluetoothDevice> getDevicesMatchingConnectionStates(@NonNull int[]); - field @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public static final String ACTION_CSIS_CONNECTION_STATE_CHANGED = "android.bluetooth.action.CSIS_CONNECTION_STATE_CHANGED"; - } - - public final class BluetoothDevice implements android.os.Parcelable { - method @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public android.bluetooth.BluetoothGatt connectGatt(android.content.Context, boolean, android.bluetooth.BluetoothGattCallback); - method @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public android.bluetooth.BluetoothGatt connectGatt(android.content.Context, boolean, android.bluetooth.BluetoothGattCallback, int); - method @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public android.bluetooth.BluetoothGatt connectGatt(android.content.Context, boolean, android.bluetooth.BluetoothGattCallback, int, int); - method @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public android.bluetooth.BluetoothGatt connectGatt(android.content.Context, boolean, android.bluetooth.BluetoothGattCallback, int, int, android.os.Handler); - method @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public boolean createBond(); - method @NonNull @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public android.bluetooth.BluetoothSocket createInsecureL2capChannel(int) throws java.io.IOException; - method @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public android.bluetooth.BluetoothSocket createInsecureRfcommSocketToServiceRecord(java.util.UUID) throws java.io.IOException; - method @NonNull @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public android.bluetooth.BluetoothSocket createL2capChannel(int) throws java.io.IOException; - method @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public android.bluetooth.BluetoothSocket createRfcommSocketToServiceRecord(java.util.UUID) throws java.io.IOException; - method public int describeContents(); - method @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public boolean fetchUuidsWithSdp(); - method public String getAddress(); - method @Nullable @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public String getAlias(); - method @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public android.bluetooth.BluetoothClass getBluetoothClass(); - method @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public int getBondState(); - method @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public String getName(); - method @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public int getType(); - method @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public android.os.ParcelUuid[] getUuids(); - method @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public int setAlias(@Nullable String); - method @RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT, android.Manifest.permission.BLUETOOTH_PRIVILEGED}) public boolean setPairingConfirmation(boolean); - method @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public boolean setPin(byte[]); - method public void writeToParcel(android.os.Parcel, int); - field @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public static final String ACTION_ACL_CONNECTED = "android.bluetooth.device.action.ACL_CONNECTED"; - field @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public static final String ACTION_ACL_DISCONNECTED = "android.bluetooth.device.action.ACL_DISCONNECTED"; - field @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public static final String ACTION_ACL_DISCONNECT_REQUESTED = "android.bluetooth.device.action.ACL_DISCONNECT_REQUESTED"; - field @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public static final String ACTION_ALIAS_CHANGED = "android.bluetooth.device.action.ALIAS_CHANGED"; - field @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public static final String ACTION_BOND_STATE_CHANGED = "android.bluetooth.device.action.BOND_STATE_CHANGED"; - field @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public static final String ACTION_CLASS_CHANGED = "android.bluetooth.device.action.CLASS_CHANGED"; - field @RequiresPermission(android.Manifest.permission.BLUETOOTH_SCAN) public static final String ACTION_FOUND = "android.bluetooth.device.action.FOUND"; - field @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public static final String ACTION_NAME_CHANGED = "android.bluetooth.device.action.NAME_CHANGED"; - field @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public static final String ACTION_PAIRING_REQUEST = "android.bluetooth.device.action.PAIRING_REQUEST"; - field @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public static final String ACTION_UUID = "android.bluetooth.device.action.UUID"; - field public static final int ADDRESS_TYPE_PUBLIC = 0; // 0x0 - field public static final int ADDRESS_TYPE_RANDOM = 1; // 0x1 - field public static final int BOND_BONDED = 12; // 0xc - field public static final int BOND_BONDING = 11; // 0xb - field public static final int BOND_NONE = 10; // 0xa - field @NonNull public static final android.os.Parcelable.Creator<android.bluetooth.BluetoothDevice> CREATOR; - field public static final int DEVICE_TYPE_CLASSIC = 1; // 0x1 - field public static final int DEVICE_TYPE_DUAL = 3; // 0x3 - field public static final int DEVICE_TYPE_LE = 2; // 0x2 - field public static final int DEVICE_TYPE_UNKNOWN = 0; // 0x0 - field public static final int ERROR = -2147483648; // 0x80000000 - field public static final String EXTRA_BOND_STATE = "android.bluetooth.device.extra.BOND_STATE"; - field public static final String EXTRA_CLASS = "android.bluetooth.device.extra.CLASS"; - field public static final String EXTRA_DEVICE = "android.bluetooth.device.extra.DEVICE"; - field public static final String EXTRA_IS_COORDINATED_SET_MEMBER = "android.bluetooth.extra.IS_COORDINATED_SET_MEMBER"; - field public static final String EXTRA_NAME = "android.bluetooth.device.extra.NAME"; - field public static final String EXTRA_PAIRING_KEY = "android.bluetooth.device.extra.PAIRING_KEY"; - field public static final String EXTRA_PAIRING_VARIANT = "android.bluetooth.device.extra.PAIRING_VARIANT"; - field public static final String EXTRA_PREVIOUS_BOND_STATE = "android.bluetooth.device.extra.PREVIOUS_BOND_STATE"; - field public static final String EXTRA_RSSI = "android.bluetooth.device.extra.RSSI"; - field public static final String EXTRA_UUID = "android.bluetooth.device.extra.UUID"; - field public static final int PAIRING_VARIANT_PASSKEY_CONFIRMATION = 2; // 0x2 - field public static final int PAIRING_VARIANT_PIN = 0; // 0x0 - field public static final int PHY_LE_1M = 1; // 0x1 - field public static final int PHY_LE_1M_MASK = 1; // 0x1 - field public static final int PHY_LE_2M = 2; // 0x2 - field public static final int PHY_LE_2M_MASK = 2; // 0x2 - field public static final int PHY_LE_CODED = 3; // 0x3 - field public static final int PHY_LE_CODED_MASK = 4; // 0x4 - field public static final int PHY_OPTION_NO_PREFERRED = 0; // 0x0 - field public static final int PHY_OPTION_S2 = 1; // 0x1 - field public static final int PHY_OPTION_S8 = 2; // 0x2 - field public static final int TRANSPORT_AUTO = 0; // 0x0 - field public static final int TRANSPORT_BREDR = 1; // 0x1 - field public static final int TRANSPORT_LE = 2; // 0x2 - } - - public final class BluetoothGatt implements android.bluetooth.BluetoothProfile { - method @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public void abortReliableWrite(); - method @Deprecated @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public void abortReliableWrite(android.bluetooth.BluetoothDevice); - method @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public boolean beginReliableWrite(); - method @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public void close(); - method @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public boolean connect(); - method @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public void disconnect(); - method @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public boolean discoverServices(); - method @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public boolean executeReliableWrite(); - method @Deprecated public java.util.List<android.bluetooth.BluetoothDevice> getConnectedDevices(); - method @Deprecated public int getConnectionState(android.bluetooth.BluetoothDevice); - method public android.bluetooth.BluetoothDevice getDevice(); - method @Deprecated public java.util.List<android.bluetooth.BluetoothDevice> getDevicesMatchingConnectionStates(int[]); - method public android.bluetooth.BluetoothGattService getService(java.util.UUID); - method public java.util.List<android.bluetooth.BluetoothGattService> getServices(); - method @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public boolean readCharacteristic(android.bluetooth.BluetoothGattCharacteristic); - method @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public boolean readDescriptor(android.bluetooth.BluetoothGattDescriptor); - method @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public void readPhy(); - method @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public boolean readRemoteRssi(); - method @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public boolean requestConnectionPriority(int); - method @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public boolean requestMtu(int); - method @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public boolean setCharacteristicNotification(android.bluetooth.BluetoothGattCharacteristic, boolean); - method @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public void setPreferredPhy(int, int, int); - method @Deprecated @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public boolean writeCharacteristic(android.bluetooth.BluetoothGattCharacteristic); - method @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public int writeCharacteristic(@NonNull android.bluetooth.BluetoothGattCharacteristic, @NonNull byte[], int); - method @Deprecated @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public boolean writeDescriptor(android.bluetooth.BluetoothGattDescriptor); - method @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public int writeDescriptor(@NonNull android.bluetooth.BluetoothGattDescriptor, @NonNull byte[]); - field public static final int CONNECTION_PRIORITY_BALANCED = 0; // 0x0 - field public static final int CONNECTION_PRIORITY_HIGH = 1; // 0x1 - field public static final int CONNECTION_PRIORITY_LOW_POWER = 2; // 0x2 - field public static final int GATT_CONNECTION_CONGESTED = 143; // 0x8f - field public static final int GATT_FAILURE = 257; // 0x101 - field public static final int GATT_INSUFFICIENT_AUTHENTICATION = 5; // 0x5 - field public static final int GATT_INSUFFICIENT_AUTHORIZATION = 8; // 0x8 - field public static final int GATT_INSUFFICIENT_ENCRYPTION = 15; // 0xf - field public static final int GATT_INVALID_ATTRIBUTE_LENGTH = 13; // 0xd - field public static final int GATT_INVALID_OFFSET = 7; // 0x7 - field public static final int GATT_READ_NOT_PERMITTED = 2; // 0x2 - field public static final int GATT_REQUEST_NOT_SUPPORTED = 6; // 0x6 - field public static final int GATT_SUCCESS = 0; // 0x0 - field public static final int GATT_WRITE_NOT_PERMITTED = 3; // 0x3 - } - - public abstract class BluetoothGattCallback { - ctor public BluetoothGattCallback(); - method @Deprecated public void onCharacteristicChanged(android.bluetooth.BluetoothGatt, android.bluetooth.BluetoothGattCharacteristic); - method public void onCharacteristicChanged(@NonNull android.bluetooth.BluetoothGatt, @NonNull android.bluetooth.BluetoothGattCharacteristic, @NonNull byte[]); - method @Deprecated public void onCharacteristicRead(android.bluetooth.BluetoothGatt, android.bluetooth.BluetoothGattCharacteristic, int); - method public void onCharacteristicRead(@NonNull android.bluetooth.BluetoothGatt, @NonNull android.bluetooth.BluetoothGattCharacteristic, @NonNull byte[], int); - method public void onCharacteristicWrite(android.bluetooth.BluetoothGatt, android.bluetooth.BluetoothGattCharacteristic, int); - method public void onConnectionStateChange(android.bluetooth.BluetoothGatt, int, int); - method @Deprecated public void onDescriptorRead(android.bluetooth.BluetoothGatt, android.bluetooth.BluetoothGattDescriptor, int); - method public void onDescriptorRead(@NonNull android.bluetooth.BluetoothGatt, @NonNull android.bluetooth.BluetoothGattDescriptor, int, @NonNull byte[]); - method public void onDescriptorWrite(android.bluetooth.BluetoothGatt, android.bluetooth.BluetoothGattDescriptor, int); - method public void onMtuChanged(android.bluetooth.BluetoothGatt, int, int); - method public void onPhyRead(android.bluetooth.BluetoothGatt, int, int, int); - method public void onPhyUpdate(android.bluetooth.BluetoothGatt, int, int, int); - method public void onReadRemoteRssi(android.bluetooth.BluetoothGatt, int, int); - method public void onReliableWriteCompleted(android.bluetooth.BluetoothGatt, int); - method public void onServiceChanged(@NonNull android.bluetooth.BluetoothGatt); - method public void onServicesDiscovered(android.bluetooth.BluetoothGatt, int); - } - - public class BluetoothGattCharacteristic implements android.os.Parcelable { - ctor public BluetoothGattCharacteristic(java.util.UUID, int, int); - method public boolean addDescriptor(android.bluetooth.BluetoothGattDescriptor); - method public int describeContents(); - method public android.bluetooth.BluetoothGattDescriptor getDescriptor(java.util.UUID); - method public java.util.List<android.bluetooth.BluetoothGattDescriptor> getDescriptors(); - method @Deprecated public Float getFloatValue(int, int); - method public int getInstanceId(); - method @Deprecated public Integer getIntValue(int, int); - method public int getPermissions(); - method public int getProperties(); - method public android.bluetooth.BluetoothGattService getService(); - method @Deprecated public String getStringValue(int); - method public java.util.UUID getUuid(); - method @Deprecated public byte[] getValue(); - method public int getWriteType(); - method @Deprecated public boolean setValue(byte[]); - method @Deprecated public boolean setValue(int, int, int); - method @Deprecated public boolean setValue(int, int, int, int); - method @Deprecated public boolean setValue(String); - method public void setWriteType(int); - method public void writeToParcel(android.os.Parcel, int); - field @NonNull public static final android.os.Parcelable.Creator<android.bluetooth.BluetoothGattCharacteristic> CREATOR; - field public static final int FORMAT_FLOAT = 52; // 0x34 - field public static final int FORMAT_SFLOAT = 50; // 0x32 - field public static final int FORMAT_SINT16 = 34; // 0x22 - field public static final int FORMAT_SINT32 = 36; // 0x24 - field public static final int FORMAT_SINT8 = 33; // 0x21 - field public static final int FORMAT_UINT16 = 18; // 0x12 - field public static final int FORMAT_UINT32 = 20; // 0x14 - field public static final int FORMAT_UINT8 = 17; // 0x11 - field public static final int PERMISSION_READ = 1; // 0x1 - field public static final int PERMISSION_READ_ENCRYPTED = 2; // 0x2 - field public static final int PERMISSION_READ_ENCRYPTED_MITM = 4; // 0x4 - field public static final int PERMISSION_WRITE = 16; // 0x10 - field public static final int PERMISSION_WRITE_ENCRYPTED = 32; // 0x20 - field public static final int PERMISSION_WRITE_ENCRYPTED_MITM = 64; // 0x40 - field public static final int PERMISSION_WRITE_SIGNED = 128; // 0x80 - field public static final int PERMISSION_WRITE_SIGNED_MITM = 256; // 0x100 - field public static final int PROPERTY_BROADCAST = 1; // 0x1 - field public static final int PROPERTY_EXTENDED_PROPS = 128; // 0x80 - field public static final int PROPERTY_INDICATE = 32; // 0x20 - field public static final int PROPERTY_NOTIFY = 16; // 0x10 - field public static final int PROPERTY_READ = 2; // 0x2 - field public static final int PROPERTY_SIGNED_WRITE = 64; // 0x40 - field public static final int PROPERTY_WRITE = 8; // 0x8 - field public static final int PROPERTY_WRITE_NO_RESPONSE = 4; // 0x4 - field public static final int WRITE_TYPE_DEFAULT = 2; // 0x2 - field public static final int WRITE_TYPE_NO_RESPONSE = 1; // 0x1 - field public static final int WRITE_TYPE_SIGNED = 4; // 0x4 - field protected java.util.List<android.bluetooth.BluetoothGattDescriptor> mDescriptors; - } - - public class BluetoothGattDescriptor implements android.os.Parcelable { - ctor public BluetoothGattDescriptor(java.util.UUID, int); - method public int describeContents(); - method public android.bluetooth.BluetoothGattCharacteristic getCharacteristic(); - method public int getPermissions(); - method public java.util.UUID getUuid(); - method @Deprecated public byte[] getValue(); - method @Deprecated public boolean setValue(byte[]); - method public void writeToParcel(android.os.Parcel, int); - field @NonNull public static final android.os.Parcelable.Creator<android.bluetooth.BluetoothGattDescriptor> CREATOR; - field public static final byte[] DISABLE_NOTIFICATION_VALUE; - field public static final byte[] ENABLE_INDICATION_VALUE; - field public static final byte[] ENABLE_NOTIFICATION_VALUE; - field public static final int PERMISSION_READ = 1; // 0x1 - field public static final int PERMISSION_READ_ENCRYPTED = 2; // 0x2 - field public static final int PERMISSION_READ_ENCRYPTED_MITM = 4; // 0x4 - field public static final int PERMISSION_WRITE = 16; // 0x10 - field public static final int PERMISSION_WRITE_ENCRYPTED = 32; // 0x20 - field public static final int PERMISSION_WRITE_ENCRYPTED_MITM = 64; // 0x40 - field public static final int PERMISSION_WRITE_SIGNED = 128; // 0x80 - field public static final int PERMISSION_WRITE_SIGNED_MITM = 256; // 0x100 - } - - public final class BluetoothGattServer implements android.bluetooth.BluetoothProfile { - method @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public boolean addService(android.bluetooth.BluetoothGattService); - method @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public void cancelConnection(android.bluetooth.BluetoothDevice); - method @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public void clearServices(); - method @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public void close(); - method @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public boolean connect(android.bluetooth.BluetoothDevice, boolean); - method public java.util.List<android.bluetooth.BluetoothDevice> getConnectedDevices(); - method public int getConnectionState(android.bluetooth.BluetoothDevice); - method public java.util.List<android.bluetooth.BluetoothDevice> getDevicesMatchingConnectionStates(int[]); - method public android.bluetooth.BluetoothGattService getService(java.util.UUID); - method public java.util.List<android.bluetooth.BluetoothGattService> getServices(); - method @Deprecated @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public boolean notifyCharacteristicChanged(android.bluetooth.BluetoothDevice, android.bluetooth.BluetoothGattCharacteristic, boolean); - method @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public int notifyCharacteristicChanged(@NonNull android.bluetooth.BluetoothDevice, @NonNull android.bluetooth.BluetoothGattCharacteristic, boolean, @NonNull byte[]); - method @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public void readPhy(android.bluetooth.BluetoothDevice); - method @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public boolean removeService(android.bluetooth.BluetoothGattService); - method @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public boolean sendResponse(android.bluetooth.BluetoothDevice, int, int, int, byte[]); - method @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public void setPreferredPhy(android.bluetooth.BluetoothDevice, int, int, int); - } - - public abstract class BluetoothGattServerCallback { - ctor public BluetoothGattServerCallback(); - method public void onCharacteristicReadRequest(android.bluetooth.BluetoothDevice, int, int, android.bluetooth.BluetoothGattCharacteristic); - method public void onCharacteristicWriteRequest(android.bluetooth.BluetoothDevice, int, android.bluetooth.BluetoothGattCharacteristic, boolean, boolean, int, byte[]); - method public void onConnectionStateChange(android.bluetooth.BluetoothDevice, int, int); - method public void onDescriptorReadRequest(android.bluetooth.BluetoothDevice, int, int, android.bluetooth.BluetoothGattDescriptor); - method public void onDescriptorWriteRequest(android.bluetooth.BluetoothDevice, int, android.bluetooth.BluetoothGattDescriptor, boolean, boolean, int, byte[]); - method public void onExecuteWrite(android.bluetooth.BluetoothDevice, int, boolean); - method public void onMtuChanged(android.bluetooth.BluetoothDevice, int); - method public void onNotificationSent(android.bluetooth.BluetoothDevice, int); - method public void onPhyRead(android.bluetooth.BluetoothDevice, int, int, int); - method public void onPhyUpdate(android.bluetooth.BluetoothDevice, int, int, int); - method public void onServiceAdded(int, android.bluetooth.BluetoothGattService); - } - - public class BluetoothGattService implements android.os.Parcelable { - ctor public BluetoothGattService(java.util.UUID, int); - method public boolean addCharacteristic(android.bluetooth.BluetoothGattCharacteristic); - method public boolean addService(android.bluetooth.BluetoothGattService); - method public int describeContents(); - method public android.bluetooth.BluetoothGattCharacteristic getCharacteristic(java.util.UUID); - method public java.util.List<android.bluetooth.BluetoothGattCharacteristic> getCharacteristics(); - method public java.util.List<android.bluetooth.BluetoothGattService> getIncludedServices(); - method public int getInstanceId(); - method public int getType(); - method public java.util.UUID getUuid(); - method public void writeToParcel(android.os.Parcel, int); - field @NonNull public static final android.os.Parcelable.Creator<android.bluetooth.BluetoothGattService> CREATOR; - field public static final int SERVICE_TYPE_PRIMARY = 0; // 0x0 - field public static final int SERVICE_TYPE_SECONDARY = 1; // 0x1 - field protected java.util.List<android.bluetooth.BluetoothGattCharacteristic> mCharacteristics; - field protected java.util.List<android.bluetooth.BluetoothGattService> mIncludedServices; - } - - public final class BluetoothHeadset implements android.bluetooth.BluetoothProfile { - method @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public java.util.List<android.bluetooth.BluetoothDevice> getConnectedDevices(); - method @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public int getConnectionState(android.bluetooth.BluetoothDevice); - method @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public java.util.List<android.bluetooth.BluetoothDevice> getDevicesMatchingConnectionStates(int[]); - method @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public boolean isAudioConnected(android.bluetooth.BluetoothDevice); - method @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public boolean isNoiseReductionSupported(@NonNull android.bluetooth.BluetoothDevice); - method @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public boolean isVoiceRecognitionSupported(@NonNull android.bluetooth.BluetoothDevice); - method @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public boolean sendVendorSpecificResultCode(android.bluetooth.BluetoothDevice, String, String); - method @RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT, android.Manifest.permission.MODIFY_PHONE_STATE}) public boolean startVoiceRecognition(android.bluetooth.BluetoothDevice); - method @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public boolean stopVoiceRecognition(android.bluetooth.BluetoothDevice); - field @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public static final String ACTION_AUDIO_STATE_CHANGED = "android.bluetooth.headset.profile.action.AUDIO_STATE_CHANGED"; - field @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public static final String ACTION_CONNECTION_STATE_CHANGED = "android.bluetooth.headset.profile.action.CONNECTION_STATE_CHANGED"; - field @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public static final String ACTION_VENDOR_SPECIFIC_HEADSET_EVENT = "android.bluetooth.headset.action.VENDOR_SPECIFIC_HEADSET_EVENT"; - field public static final int AT_CMD_TYPE_ACTION = 4; // 0x4 - field public static final int AT_CMD_TYPE_BASIC = 3; // 0x3 - field public static final int AT_CMD_TYPE_READ = 0; // 0x0 - field public static final int AT_CMD_TYPE_SET = 2; // 0x2 - field public static final int AT_CMD_TYPE_TEST = 1; // 0x1 - field public static final String EXTRA_VENDOR_SPECIFIC_HEADSET_EVENT_ARGS = "android.bluetooth.headset.extra.VENDOR_SPECIFIC_HEADSET_EVENT_ARGS"; - field public static final String EXTRA_VENDOR_SPECIFIC_HEADSET_EVENT_CMD = "android.bluetooth.headset.extra.VENDOR_SPECIFIC_HEADSET_EVENT_CMD"; - field public static final String EXTRA_VENDOR_SPECIFIC_HEADSET_EVENT_CMD_TYPE = "android.bluetooth.headset.extra.VENDOR_SPECIFIC_HEADSET_EVENT_CMD_TYPE"; - field public static final int STATE_AUDIO_CONNECTED = 12; // 0xc - field public static final int STATE_AUDIO_CONNECTING = 11; // 0xb - field public static final int STATE_AUDIO_DISCONNECTED = 10; // 0xa - field public static final String VENDOR_RESULT_CODE_COMMAND_ANDROID = "+ANDROID"; - field public static final String VENDOR_SPECIFIC_HEADSET_EVENT_COMPANY_ID_CATEGORY = "android.bluetooth.headset.intent.category.companyid"; - } - - @Deprecated public final class BluetoothHealth implements android.bluetooth.BluetoothProfile { - method @Deprecated @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public boolean connectChannelToSource(android.bluetooth.BluetoothDevice, android.bluetooth.BluetoothHealthAppConfiguration); - method @Deprecated @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public boolean disconnectChannel(android.bluetooth.BluetoothDevice, android.bluetooth.BluetoothHealthAppConfiguration, int); - method @Deprecated @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public java.util.List<android.bluetooth.BluetoothDevice> getConnectedDevices(); - method @Deprecated @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public int getConnectionState(android.bluetooth.BluetoothDevice); - method @Deprecated @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public java.util.List<android.bluetooth.BluetoothDevice> getDevicesMatchingConnectionStates(int[]); - method @Deprecated @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public android.os.ParcelFileDescriptor getMainChannelFd(android.bluetooth.BluetoothDevice, android.bluetooth.BluetoothHealthAppConfiguration); - method @Deprecated @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public boolean registerSinkAppConfiguration(String, int, android.bluetooth.BluetoothHealthCallback); - method @Deprecated @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public boolean unregisterAppConfiguration(android.bluetooth.BluetoothHealthAppConfiguration); - field @Deprecated public static final int APP_CONFIG_REGISTRATION_FAILURE = 1; // 0x1 - field @Deprecated public static final int APP_CONFIG_REGISTRATION_SUCCESS = 0; // 0x0 - field @Deprecated public static final int APP_CONFIG_UNREGISTRATION_FAILURE = 3; // 0x3 - field @Deprecated public static final int APP_CONFIG_UNREGISTRATION_SUCCESS = 2; // 0x2 - field @Deprecated public static final int CHANNEL_TYPE_RELIABLE = 10; // 0xa - field @Deprecated public static final int CHANNEL_TYPE_STREAMING = 11; // 0xb - field @Deprecated public static final int SINK_ROLE = 2; // 0x2 - field @Deprecated public static final int SOURCE_ROLE = 1; // 0x1 - field @Deprecated public static final int STATE_CHANNEL_CONNECTED = 2; // 0x2 - field @Deprecated public static final int STATE_CHANNEL_CONNECTING = 1; // 0x1 - field @Deprecated public static final int STATE_CHANNEL_DISCONNECTED = 0; // 0x0 - field @Deprecated public static final int STATE_CHANNEL_DISCONNECTING = 3; // 0x3 - } - - @Deprecated public final class BluetoothHealthAppConfiguration implements android.os.Parcelable { - method @Deprecated public int describeContents(); - method @Deprecated public int getDataType(); - method @Deprecated public String getName(); - method @Deprecated public int getRole(); - method @Deprecated public void writeToParcel(android.os.Parcel, int); - field @Deprecated @NonNull public static final android.os.Parcelable.Creator<android.bluetooth.BluetoothHealthAppConfiguration> CREATOR; - } - - @Deprecated public abstract class BluetoothHealthCallback { - ctor @Deprecated public BluetoothHealthCallback(); - method @Deprecated @BinderThread public void onHealthAppConfigurationStatusChange(android.bluetooth.BluetoothHealthAppConfiguration, int); - method @Deprecated @BinderThread public void onHealthChannelStateChange(android.bluetooth.BluetoothHealthAppConfiguration, android.bluetooth.BluetoothDevice, int, int, android.os.ParcelFileDescriptor, int); - } - - public final class BluetoothHearingAid implements android.bluetooth.BluetoothProfile { - method @NonNull @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public java.util.List<android.bluetooth.BluetoothDevice> getConnectedDevices(); - method @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public int getConnectionState(@NonNull android.bluetooth.BluetoothDevice); - method @NonNull @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public java.util.List<android.bluetooth.BluetoothDevice> getDevicesMatchingConnectionStates(@NonNull int[]); - field @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public static final String ACTION_CONNECTION_STATE_CHANGED = "android.bluetooth.hearingaid.profile.action.CONNECTION_STATE_CHANGED"; - } - - public final class BluetoothHidDevice implements android.bluetooth.BluetoothProfile { - method @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public boolean connect(android.bluetooth.BluetoothDevice); - method @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public boolean disconnect(android.bluetooth.BluetoothDevice); - method @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public java.util.List<android.bluetooth.BluetoothDevice> getConnectedDevices(); - method @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public int getConnectionState(android.bluetooth.BluetoothDevice); - method @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public java.util.List<android.bluetooth.BluetoothDevice> getDevicesMatchingConnectionStates(int[]); - method @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public boolean registerApp(android.bluetooth.BluetoothHidDeviceAppSdpSettings, android.bluetooth.BluetoothHidDeviceAppQosSettings, android.bluetooth.BluetoothHidDeviceAppQosSettings, java.util.concurrent.Executor, android.bluetooth.BluetoothHidDevice.Callback); - method @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public boolean replyReport(android.bluetooth.BluetoothDevice, byte, byte, byte[]); - method @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public boolean reportError(android.bluetooth.BluetoothDevice, byte); - method @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public boolean sendReport(android.bluetooth.BluetoothDevice, int, byte[]); - method @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public boolean unregisterApp(); - field @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public static final String ACTION_CONNECTION_STATE_CHANGED = "android.bluetooth.hiddevice.profile.action.CONNECTION_STATE_CHANGED"; - field public static final byte ERROR_RSP_INVALID_PARAM = 4; // 0x4 - field public static final byte ERROR_RSP_INVALID_RPT_ID = 2; // 0x2 - field public static final byte ERROR_RSP_NOT_READY = 1; // 0x1 - field public static final byte ERROR_RSP_SUCCESS = 0; // 0x0 - field public static final byte ERROR_RSP_UNKNOWN = 14; // 0xe - field public static final byte ERROR_RSP_UNSUPPORTED_REQ = 3; // 0x3 - field public static final byte PROTOCOL_BOOT_MODE = 0; // 0x0 - field public static final byte PROTOCOL_REPORT_MODE = 1; // 0x1 - field public static final byte REPORT_TYPE_FEATURE = 3; // 0x3 - field public static final byte REPORT_TYPE_INPUT = 1; // 0x1 - field public static final byte REPORT_TYPE_OUTPUT = 2; // 0x2 - field public static final byte SUBCLASS1_COMBO = -64; // 0xffffffc0 - field public static final byte SUBCLASS1_KEYBOARD = 64; // 0x40 - field public static final byte SUBCLASS1_MOUSE = -128; // 0xffffff80 - field public static final byte SUBCLASS1_NONE = 0; // 0x0 - field public static final byte SUBCLASS2_CARD_READER = 6; // 0x6 - field public static final byte SUBCLASS2_DIGITIZER_TABLET = 5; // 0x5 - field public static final byte SUBCLASS2_GAMEPAD = 2; // 0x2 - field public static final byte SUBCLASS2_JOYSTICK = 1; // 0x1 - field public static final byte SUBCLASS2_REMOTE_CONTROL = 3; // 0x3 - field public static final byte SUBCLASS2_SENSING_DEVICE = 4; // 0x4 - field public static final byte SUBCLASS2_UNCATEGORIZED = 0; // 0x0 - } - - public abstract static class BluetoothHidDevice.Callback { - ctor public BluetoothHidDevice.Callback(); - method public void onAppStatusChanged(android.bluetooth.BluetoothDevice, boolean); - method public void onConnectionStateChanged(android.bluetooth.BluetoothDevice, int); - method public void onGetReport(android.bluetooth.BluetoothDevice, byte, byte, int); - method public void onInterruptData(android.bluetooth.BluetoothDevice, byte, byte[]); - method public void onSetProtocol(android.bluetooth.BluetoothDevice, byte); - method public void onSetReport(android.bluetooth.BluetoothDevice, byte, byte, byte[]); - method public void onVirtualCableUnplug(android.bluetooth.BluetoothDevice); - } - - public final class BluetoothHidDeviceAppQosSettings implements android.os.Parcelable { - ctor public BluetoothHidDeviceAppQosSettings(int, int, int, int, int, int); - method public int describeContents(); - method public int getDelayVariation(); - method public int getLatency(); - method public int getPeakBandwidth(); - method public int getServiceType(); - method public int getTokenBucketSize(); - method public int getTokenRate(); - method public void writeToParcel(android.os.Parcel, int); - field @NonNull public static final android.os.Parcelable.Creator<android.bluetooth.BluetoothHidDeviceAppQosSettings> CREATOR; - field public static final int MAX = -1; // 0xffffffff - field public static final int SERVICE_BEST_EFFORT = 1; // 0x1 - field public static final int SERVICE_GUARANTEED = 2; // 0x2 - field public static final int SERVICE_NO_TRAFFIC = 0; // 0x0 - } - - public final class BluetoothHidDeviceAppSdpSettings implements android.os.Parcelable { - ctor public BluetoothHidDeviceAppSdpSettings(String, String, String, byte, byte[]); - method public int describeContents(); - method public String getDescription(); - method public byte[] getDescriptors(); - method public String getName(); - method public String getProvider(); - method public byte getSubclass(); - method public void writeToParcel(android.os.Parcel, int); - field @NonNull public static final android.os.Parcelable.Creator<android.bluetooth.BluetoothHidDeviceAppSdpSettings> CREATOR; - } - - public final class BluetoothLeAudio implements java.lang.AutoCloseable android.bluetooth.BluetoothProfile { - method public void close(); - method protected void finalize(); - method @NonNull @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public java.util.List<android.bluetooth.BluetoothDevice> getConnectedDevices(); - method @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public int getConnectionState(@NonNull android.bluetooth.BluetoothDevice); - method @NonNull @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public java.util.List<android.bluetooth.BluetoothDevice> getDevicesMatchingConnectionStates(@NonNull int[]); - method @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public int getGroupId(@NonNull android.bluetooth.BluetoothDevice); - field @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public static final String ACTION_LE_AUDIO_CONNECTION_STATE_CHANGED = "android.bluetooth.action.LE_AUDIO_CONNECTION_STATE_CHANGED"; - } - - public final class BluetoothLeAudioCodecConfig { - method @NonNull public String getCodecName(); - method public int getCodecType(); - method public static int getMaxCodecType(); - field public static final int SOURCE_CODEC_TYPE_INVALID = 1000000; // 0xf4240 - field public static final int SOURCE_CODEC_TYPE_LC3 = 0; // 0x0 - } - - public static final class BluetoothLeAudioCodecConfig.Builder { - ctor public BluetoothLeAudioCodecConfig.Builder(); - method @NonNull public android.bluetooth.BluetoothLeAudioCodecConfig build(); - method @NonNull public android.bluetooth.BluetoothLeAudioCodecConfig.Builder setCodecType(int); - } - - public final class BluetoothManager { - method public android.bluetooth.BluetoothAdapter getAdapter(); - method @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public java.util.List<android.bluetooth.BluetoothDevice> getConnectedDevices(int); - method @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public int getConnectionState(android.bluetooth.BluetoothDevice, int); - method @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public java.util.List<android.bluetooth.BluetoothDevice> getDevicesMatchingConnectionStates(int, int[]); - method @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public android.bluetooth.BluetoothGattServer openGattServer(android.content.Context, android.bluetooth.BluetoothGattServerCallback); - } - - public interface BluetoothProfile { - method public java.util.List<android.bluetooth.BluetoothDevice> getConnectedDevices(); - method public int getConnectionState(android.bluetooth.BluetoothDevice); - method public java.util.List<android.bluetooth.BluetoothDevice> getDevicesMatchingConnectionStates(int[]); - field public static final int A2DP = 2; // 0x2 - field public static final int CSIP_SET_COORDINATOR = 25; // 0x19 - field public static final String EXTRA_PREVIOUS_STATE = "android.bluetooth.profile.extra.PREVIOUS_STATE"; - field public static final String EXTRA_STATE = "android.bluetooth.profile.extra.STATE"; - field public static final int GATT = 7; // 0x7 - field public static final int GATT_SERVER = 8; // 0x8 - field public static final int HEADSET = 1; // 0x1 - field @Deprecated public static final int HEALTH = 3; // 0x3 - field public static final int HEARING_AID = 21; // 0x15 - field public static final int HID_DEVICE = 19; // 0x13 - field public static final int LE_AUDIO = 22; // 0x16 - field public static final int SAP = 10; // 0xa - field public static final int STATE_CONNECTED = 2; // 0x2 - field public static final int STATE_CONNECTING = 1; // 0x1 - field public static final int STATE_DISCONNECTED = 0; // 0x0 - field public static final int STATE_DISCONNECTING = 3; // 0x3 - } - - public static interface BluetoothProfile.ServiceListener { - method public void onServiceConnected(int, android.bluetooth.BluetoothProfile); - method public void onServiceDisconnected(int); - } - - public final class BluetoothServerSocket implements java.io.Closeable { - method public android.bluetooth.BluetoothSocket accept() throws java.io.IOException; - method public android.bluetooth.BluetoothSocket accept(int) throws java.io.IOException; - method public void close() throws java.io.IOException; - method public int getPsm(); - } - - public final class BluetoothSocket implements java.io.Closeable { - method public void close() throws java.io.IOException; - method @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public void connect() throws java.io.IOException; - method public int getConnectionType(); - method public java.io.InputStream getInputStream() throws java.io.IOException; - method public int getMaxReceivePacketSize(); - method public int getMaxTransmitPacketSize(); - method public java.io.OutputStream getOutputStream() throws java.io.IOException; - method public android.bluetooth.BluetoothDevice getRemoteDevice(); - method public boolean isConnected(); - field public static final int TYPE_L2CAP = 3; // 0x3 - field public static final int TYPE_RFCOMM = 1; // 0x1 - field public static final int TYPE_SCO = 2; // 0x2 - } - - public final class BluetoothStatusCodes { - field public static final int ERROR_BLUETOOTH_NOT_ALLOWED = 2; // 0x2 - field public static final int ERROR_BLUETOOTH_NOT_ENABLED = 1; // 0x1 - field public static final int ERROR_DEVICE_NOT_BONDED = 3; // 0x3 - field public static final int ERROR_FEATURE_NOT_SUPPORTED = 10; // 0xa - field public static final int ERROR_GATT_WRITE_NOT_ALLOWED = 101; // 0x65 - field public static final int ERROR_GATT_WRITE_REQUEST_BUSY = 102; // 0x66 - field public static final int ERROR_MISSING_BLUETOOTH_CONNECT_PERMISSION = 6; // 0x6 - field public static final int ERROR_MISSING_BLUETOOTH_PRIVILEGED_PERMISSION = 8; // 0x8 - field public static final int ERROR_PROFILE_SERVICE_NOT_BOUND = 9; // 0x9 - field public static final int ERROR_UNKNOWN = 2147483647; // 0x7fffffff - field public static final int SUCCESS = 0; // 0x0 - } - -} - -package android.bluetooth.le { - - public abstract class AdvertiseCallback { - ctor public AdvertiseCallback(); - method public void onStartFailure(int); - method public void onStartSuccess(android.bluetooth.le.AdvertiseSettings); - field public static final int ADVERTISE_FAILED_ALREADY_STARTED = 3; // 0x3 - field public static final int ADVERTISE_FAILED_DATA_TOO_LARGE = 1; // 0x1 - field public static final int ADVERTISE_FAILED_FEATURE_UNSUPPORTED = 5; // 0x5 - field public static final int ADVERTISE_FAILED_INTERNAL_ERROR = 4; // 0x4 - field public static final int ADVERTISE_FAILED_TOO_MANY_ADVERTISERS = 2; // 0x2 - } - - public final class AdvertiseData implements android.os.Parcelable { - method public int describeContents(); - method public boolean getIncludeDeviceName(); - method public boolean getIncludeTxPowerLevel(); - method public android.util.SparseArray<byte[]> getManufacturerSpecificData(); - method public java.util.Map<android.os.ParcelUuid,byte[]> getServiceData(); - method @NonNull public java.util.List<android.os.ParcelUuid> getServiceSolicitationUuids(); - method public java.util.List<android.os.ParcelUuid> getServiceUuids(); - method @NonNull public java.util.List<android.bluetooth.le.TransportDiscoveryData> getTransportDiscoveryData(); - method public void writeToParcel(android.os.Parcel, int); - field @NonNull public static final android.os.Parcelable.Creator<android.bluetooth.le.AdvertiseData> CREATOR; - } - - public static final class AdvertiseData.Builder { - ctor public AdvertiseData.Builder(); - method public android.bluetooth.le.AdvertiseData.Builder addManufacturerData(int, byte[]); - method public android.bluetooth.le.AdvertiseData.Builder addServiceData(android.os.ParcelUuid, byte[]); - method @NonNull public android.bluetooth.le.AdvertiseData.Builder addServiceSolicitationUuid(@NonNull android.os.ParcelUuid); - method public android.bluetooth.le.AdvertiseData.Builder addServiceUuid(android.os.ParcelUuid); - method @NonNull public android.bluetooth.le.AdvertiseData.Builder addTransportDiscoveryData(@NonNull android.bluetooth.le.TransportDiscoveryData); - method public android.bluetooth.le.AdvertiseData build(); - method public android.bluetooth.le.AdvertiseData.Builder setIncludeDeviceName(boolean); - method public android.bluetooth.le.AdvertiseData.Builder setIncludeTxPowerLevel(boolean); - } - - public final class AdvertiseSettings implements android.os.Parcelable { - method public int describeContents(); - method public int getMode(); - method public int getTimeout(); - method public int getTxPowerLevel(); - method public boolean isConnectable(); - method public void writeToParcel(android.os.Parcel, int); - field public static final int ADVERTISE_MODE_BALANCED = 1; // 0x1 - field public static final int ADVERTISE_MODE_LOW_LATENCY = 2; // 0x2 - field public static final int ADVERTISE_MODE_LOW_POWER = 0; // 0x0 - field public static final int ADVERTISE_TX_POWER_HIGH = 3; // 0x3 - field public static final int ADVERTISE_TX_POWER_LOW = 1; // 0x1 - field public static final int ADVERTISE_TX_POWER_MEDIUM = 2; // 0x2 - field public static final int ADVERTISE_TX_POWER_ULTRA_LOW = 0; // 0x0 - field @NonNull public static final android.os.Parcelable.Creator<android.bluetooth.le.AdvertiseSettings> CREATOR; - } - - public static final class AdvertiseSettings.Builder { - ctor public AdvertiseSettings.Builder(); - method public android.bluetooth.le.AdvertiseSettings build(); - method public android.bluetooth.le.AdvertiseSettings.Builder setAdvertiseMode(int); - method public android.bluetooth.le.AdvertiseSettings.Builder setConnectable(boolean); - method public android.bluetooth.le.AdvertiseSettings.Builder setTimeout(int); - method public android.bluetooth.le.AdvertiseSettings.Builder setTxPowerLevel(int); - } - - public final class AdvertisingSet { - method @RequiresPermission(android.Manifest.permission.BLUETOOTH_ADVERTISE) public void enableAdvertising(boolean, int, int); - method @RequiresPermission(android.Manifest.permission.BLUETOOTH_ADVERTISE) public void setAdvertisingData(android.bluetooth.le.AdvertiseData); - method @RequiresPermission(android.Manifest.permission.BLUETOOTH_ADVERTISE) public void setAdvertisingParameters(android.bluetooth.le.AdvertisingSetParameters); - method @RequiresPermission(android.Manifest.permission.BLUETOOTH_ADVERTISE) public void setPeriodicAdvertisingData(android.bluetooth.le.AdvertiseData); - method @RequiresPermission(android.Manifest.permission.BLUETOOTH_ADVERTISE) public void setPeriodicAdvertisingEnabled(boolean); - method @RequiresPermission(android.Manifest.permission.BLUETOOTH_ADVERTISE) public void setPeriodicAdvertisingParameters(android.bluetooth.le.PeriodicAdvertisingParameters); - method @RequiresPermission(android.Manifest.permission.BLUETOOTH_ADVERTISE) public void setScanResponseData(android.bluetooth.le.AdvertiseData); - } - - public abstract class AdvertisingSetCallback { - ctor public AdvertisingSetCallback(); - method public void onAdvertisingDataSet(android.bluetooth.le.AdvertisingSet, int); - method public void onAdvertisingEnabled(android.bluetooth.le.AdvertisingSet, boolean, int); - method public void onAdvertisingParametersUpdated(android.bluetooth.le.AdvertisingSet, int, int); - method public void onAdvertisingSetStarted(android.bluetooth.le.AdvertisingSet, int, int); - method public void onAdvertisingSetStopped(android.bluetooth.le.AdvertisingSet); - method public void onPeriodicAdvertisingDataSet(android.bluetooth.le.AdvertisingSet, int); - method public void onPeriodicAdvertisingEnabled(android.bluetooth.le.AdvertisingSet, boolean, int); - method public void onPeriodicAdvertisingParametersUpdated(android.bluetooth.le.AdvertisingSet, int); - method public void onScanResponseDataSet(android.bluetooth.le.AdvertisingSet, int); - field public static final int ADVERTISE_FAILED_ALREADY_STARTED = 3; // 0x3 - field public static final int ADVERTISE_FAILED_DATA_TOO_LARGE = 1; // 0x1 - field public static final int ADVERTISE_FAILED_FEATURE_UNSUPPORTED = 5; // 0x5 - field public static final int ADVERTISE_FAILED_INTERNAL_ERROR = 4; // 0x4 - field public static final int ADVERTISE_FAILED_TOO_MANY_ADVERTISERS = 2; // 0x2 - field public static final int ADVERTISE_SUCCESS = 0; // 0x0 - } - - public final class AdvertisingSetParameters implements android.os.Parcelable { - method public int describeContents(); - method public int getInterval(); - method public int getPrimaryPhy(); - method public int getSecondaryPhy(); - method public int getTxPowerLevel(); - method public boolean includeTxPower(); - method public boolean isAnonymous(); - method public boolean isConnectable(); - method public boolean isLegacy(); - method public boolean isScannable(); - method public void writeToParcel(android.os.Parcel, int); - field @NonNull public static final android.os.Parcelable.Creator<android.bluetooth.le.AdvertisingSetParameters> CREATOR; - field public static final int INTERVAL_HIGH = 1600; // 0x640 - field public static final int INTERVAL_LOW = 160; // 0xa0 - field public static final int INTERVAL_MAX = 16777215; // 0xffffff - field public static final int INTERVAL_MEDIUM = 400; // 0x190 - field public static final int INTERVAL_MIN = 160; // 0xa0 - field public static final int TX_POWER_HIGH = 1; // 0x1 - field public static final int TX_POWER_LOW = -15; // 0xfffffff1 - field public static final int TX_POWER_MAX = 1; // 0x1 - field public static final int TX_POWER_MEDIUM = -7; // 0xfffffff9 - field public static final int TX_POWER_MIN = -127; // 0xffffff81 - field public static final int TX_POWER_ULTRA_LOW = -21; // 0xffffffeb - } - - public static final class AdvertisingSetParameters.Builder { - ctor public AdvertisingSetParameters.Builder(); - method public android.bluetooth.le.AdvertisingSetParameters build(); - method public android.bluetooth.le.AdvertisingSetParameters.Builder setAnonymous(boolean); - method public android.bluetooth.le.AdvertisingSetParameters.Builder setConnectable(boolean); - method public android.bluetooth.le.AdvertisingSetParameters.Builder setIncludeTxPower(boolean); - method public android.bluetooth.le.AdvertisingSetParameters.Builder setInterval(int); - method public android.bluetooth.le.AdvertisingSetParameters.Builder setLegacyMode(boolean); - method public android.bluetooth.le.AdvertisingSetParameters.Builder setPrimaryPhy(int); - method public android.bluetooth.le.AdvertisingSetParameters.Builder setScannable(boolean); - method public android.bluetooth.le.AdvertisingSetParameters.Builder setSecondaryPhy(int); - method public android.bluetooth.le.AdvertisingSetParameters.Builder setTxPowerLevel(int); - } - - public final class BluetoothLeAdvertiser { - method @RequiresPermission(android.Manifest.permission.BLUETOOTH_ADVERTISE) public void startAdvertising(android.bluetooth.le.AdvertiseSettings, android.bluetooth.le.AdvertiseData, android.bluetooth.le.AdvertiseCallback); - method @RequiresPermission(android.Manifest.permission.BLUETOOTH_ADVERTISE) public void startAdvertising(android.bluetooth.le.AdvertiseSettings, android.bluetooth.le.AdvertiseData, android.bluetooth.le.AdvertiseData, android.bluetooth.le.AdvertiseCallback); - method @RequiresPermission(android.Manifest.permission.BLUETOOTH_ADVERTISE) public void startAdvertisingSet(android.bluetooth.le.AdvertisingSetParameters, android.bluetooth.le.AdvertiseData, android.bluetooth.le.AdvertiseData, android.bluetooth.le.PeriodicAdvertisingParameters, android.bluetooth.le.AdvertiseData, android.bluetooth.le.AdvertisingSetCallback); - method @RequiresPermission(android.Manifest.permission.BLUETOOTH_ADVERTISE) public void startAdvertisingSet(android.bluetooth.le.AdvertisingSetParameters, android.bluetooth.le.AdvertiseData, android.bluetooth.le.AdvertiseData, android.bluetooth.le.PeriodicAdvertisingParameters, android.bluetooth.le.AdvertiseData, android.bluetooth.le.AdvertisingSetCallback, android.os.Handler); - method @RequiresPermission(android.Manifest.permission.BLUETOOTH_ADVERTISE) public void startAdvertisingSet(android.bluetooth.le.AdvertisingSetParameters, android.bluetooth.le.AdvertiseData, android.bluetooth.le.AdvertiseData, android.bluetooth.le.PeriodicAdvertisingParameters, android.bluetooth.le.AdvertiseData, int, int, android.bluetooth.le.AdvertisingSetCallback); - method @RequiresPermission(android.Manifest.permission.BLUETOOTH_ADVERTISE) public void startAdvertisingSet(android.bluetooth.le.AdvertisingSetParameters, android.bluetooth.le.AdvertiseData, android.bluetooth.le.AdvertiseData, android.bluetooth.le.PeriodicAdvertisingParameters, android.bluetooth.le.AdvertiseData, int, int, android.bluetooth.le.AdvertisingSetCallback, android.os.Handler); - method @RequiresPermission(android.Manifest.permission.BLUETOOTH_ADVERTISE) public void stopAdvertising(android.bluetooth.le.AdvertiseCallback); - method @RequiresPermission(android.Manifest.permission.BLUETOOTH_ADVERTISE) public void stopAdvertisingSet(android.bluetooth.le.AdvertisingSetCallback); - } - - public final class BluetoothLeScanner { - method @RequiresPermission(android.Manifest.permission.BLUETOOTH_SCAN) public void flushPendingScanResults(android.bluetooth.le.ScanCallback); - method @RequiresPermission(android.Manifest.permission.BLUETOOTH_SCAN) public void startScan(android.bluetooth.le.ScanCallback); - method @RequiresPermission(android.Manifest.permission.BLUETOOTH_SCAN) public void startScan(java.util.List<android.bluetooth.le.ScanFilter>, android.bluetooth.le.ScanSettings, android.bluetooth.le.ScanCallback); - method @RequiresPermission(android.Manifest.permission.BLUETOOTH_SCAN) public int startScan(@Nullable java.util.List<android.bluetooth.le.ScanFilter>, @Nullable android.bluetooth.le.ScanSettings, @NonNull android.app.PendingIntent); - method @RequiresPermission(android.Manifest.permission.BLUETOOTH_SCAN) public void stopScan(android.bluetooth.le.ScanCallback); - method @RequiresPermission(android.Manifest.permission.BLUETOOTH_SCAN) public void stopScan(android.app.PendingIntent); - field public static final String EXTRA_CALLBACK_TYPE = "android.bluetooth.le.extra.CALLBACK_TYPE"; - field public static final String EXTRA_ERROR_CODE = "android.bluetooth.le.extra.ERROR_CODE"; - field public static final String EXTRA_LIST_SCAN_RESULT = "android.bluetooth.le.extra.LIST_SCAN_RESULT"; - } - - public final class PeriodicAdvertisingParameters implements android.os.Parcelable { - method public int describeContents(); - method public boolean getIncludeTxPower(); - method public int getInterval(); - method public void writeToParcel(android.os.Parcel, int); - field public static final android.os.Parcelable.Creator<android.bluetooth.le.PeriodicAdvertisingParameters> CREATOR; - } - - public static final class PeriodicAdvertisingParameters.Builder { - ctor public PeriodicAdvertisingParameters.Builder(); - method public android.bluetooth.le.PeriodicAdvertisingParameters build(); - method public android.bluetooth.le.PeriodicAdvertisingParameters.Builder setIncludeTxPower(boolean); - method public android.bluetooth.le.PeriodicAdvertisingParameters.Builder setInterval(int); - } - - public abstract class ScanCallback { - ctor public ScanCallback(); - method public void onBatchScanResults(java.util.List<android.bluetooth.le.ScanResult>); - method public void onScanFailed(int); - method public void onScanResult(int, android.bluetooth.le.ScanResult); - field public static final int SCAN_FAILED_ALREADY_STARTED = 1; // 0x1 - field public static final int SCAN_FAILED_APPLICATION_REGISTRATION_FAILED = 2; // 0x2 - field public static final int SCAN_FAILED_FEATURE_UNSUPPORTED = 4; // 0x4 - field public static final int SCAN_FAILED_INTERNAL_ERROR = 3; // 0x3 - } - - public final class ScanFilter implements android.os.Parcelable { - method public int describeContents(); - method @Nullable public String getDeviceAddress(); - method @Nullable public String getDeviceName(); - method @Nullable public byte[] getManufacturerData(); - method @Nullable public byte[] getManufacturerDataMask(); - method public int getManufacturerId(); - method @Nullable public byte[] getServiceData(); - method @Nullable public byte[] getServiceDataMask(); - method @Nullable public android.os.ParcelUuid getServiceDataUuid(); - method @Nullable public android.os.ParcelUuid getServiceSolicitationUuid(); - method @Nullable public android.os.ParcelUuid getServiceSolicitationUuidMask(); - method @Nullable public android.os.ParcelUuid getServiceUuid(); - method @Nullable public android.os.ParcelUuid getServiceUuidMask(); - method public boolean matches(android.bluetooth.le.ScanResult); - method public void writeToParcel(android.os.Parcel, int); - field @NonNull public static final android.os.Parcelable.Creator<android.bluetooth.le.ScanFilter> CREATOR; - } - - public static final class ScanFilter.Builder { - ctor public ScanFilter.Builder(); - method public android.bluetooth.le.ScanFilter build(); - method public android.bluetooth.le.ScanFilter.Builder setDeviceAddress(String); - method public android.bluetooth.le.ScanFilter.Builder setDeviceName(String); - method public android.bluetooth.le.ScanFilter.Builder setManufacturerData(int, byte[]); - method public android.bluetooth.le.ScanFilter.Builder setManufacturerData(int, byte[], byte[]); - method public android.bluetooth.le.ScanFilter.Builder setServiceData(android.os.ParcelUuid, byte[]); - method public android.bluetooth.le.ScanFilter.Builder setServiceData(android.os.ParcelUuid, byte[], byte[]); - method @NonNull public android.bluetooth.le.ScanFilter.Builder setServiceSolicitationUuid(@Nullable android.os.ParcelUuid); - method @NonNull public android.bluetooth.le.ScanFilter.Builder setServiceSolicitationUuid(@Nullable android.os.ParcelUuid, @Nullable android.os.ParcelUuid); - method public android.bluetooth.le.ScanFilter.Builder setServiceUuid(android.os.ParcelUuid); - method public android.bluetooth.le.ScanFilter.Builder setServiceUuid(android.os.ParcelUuid, android.os.ParcelUuid); - } - - public final class ScanRecord { - method public int getAdvertiseFlags(); - method public byte[] getBytes(); - method @Nullable public String getDeviceName(); - method public android.util.SparseArray<byte[]> getManufacturerSpecificData(); - method @Nullable public byte[] getManufacturerSpecificData(int); - method public java.util.Map<android.os.ParcelUuid,byte[]> getServiceData(); - method @Nullable public byte[] getServiceData(android.os.ParcelUuid); - method @NonNull public java.util.List<android.os.ParcelUuid> getServiceSolicitationUuids(); - method public java.util.List<android.os.ParcelUuid> getServiceUuids(); - method public int getTxPowerLevel(); - } - - public final class ScanResult implements android.os.Parcelable { - ctor @Deprecated public ScanResult(android.bluetooth.BluetoothDevice, android.bluetooth.le.ScanRecord, int, long); - ctor public ScanResult(android.bluetooth.BluetoothDevice, int, int, int, int, int, int, int, android.bluetooth.le.ScanRecord, long); - method public int describeContents(); - method public int getAdvertisingSid(); - method public int getDataStatus(); - method public android.bluetooth.BluetoothDevice getDevice(); - method public int getPeriodicAdvertisingInterval(); - method public int getPrimaryPhy(); - method public int getRssi(); - method @Nullable public android.bluetooth.le.ScanRecord getScanRecord(); - method public int getSecondaryPhy(); - method public long getTimestampNanos(); - method public int getTxPower(); - method public boolean isConnectable(); - method public boolean isLegacy(); - method public void writeToParcel(android.os.Parcel, int); - field @NonNull public static final android.os.Parcelable.Creator<android.bluetooth.le.ScanResult> CREATOR; - field public static final int DATA_COMPLETE = 0; // 0x0 - field public static final int DATA_TRUNCATED = 2; // 0x2 - field public static final int PERIODIC_INTERVAL_NOT_PRESENT = 0; // 0x0 - field public static final int PHY_UNUSED = 0; // 0x0 - field public static final int SID_NOT_PRESENT = 255; // 0xff - field public static final int TX_POWER_NOT_PRESENT = 127; // 0x7f - } - - public final class ScanSettings implements android.os.Parcelable { - method public int describeContents(); - method public int getCallbackType(); - method public boolean getLegacy(); - method public int getPhy(); - method public long getReportDelayMillis(); - method public int getScanMode(); - method public int getScanResultType(); - method public void writeToParcel(android.os.Parcel, int); - field public static final int CALLBACK_TYPE_ALL_MATCHES = 1; // 0x1 - field public static final int CALLBACK_TYPE_FIRST_MATCH = 2; // 0x2 - field public static final int CALLBACK_TYPE_MATCH_LOST = 4; // 0x4 - field @NonNull public static final android.os.Parcelable.Creator<android.bluetooth.le.ScanSettings> CREATOR; - field public static final int MATCH_MODE_AGGRESSIVE = 1; // 0x1 - field public static final int MATCH_MODE_STICKY = 2; // 0x2 - field public static final int MATCH_NUM_FEW_ADVERTISEMENT = 2; // 0x2 - field public static final int MATCH_NUM_MAX_ADVERTISEMENT = 3; // 0x3 - field public static final int MATCH_NUM_ONE_ADVERTISEMENT = 1; // 0x1 - field public static final int PHY_LE_ALL_SUPPORTED = 255; // 0xff - field public static final int SCAN_MODE_BALANCED = 1; // 0x1 - field public static final int SCAN_MODE_LOW_LATENCY = 2; // 0x2 - field public static final int SCAN_MODE_LOW_POWER = 0; // 0x0 - field public static final int SCAN_MODE_OPPORTUNISTIC = -1; // 0xffffffff - } - - public static final class ScanSettings.Builder { - ctor public ScanSettings.Builder(); - method public android.bluetooth.le.ScanSettings build(); - method public android.bluetooth.le.ScanSettings.Builder setCallbackType(int); - method public android.bluetooth.le.ScanSettings.Builder setLegacy(boolean); - method public android.bluetooth.le.ScanSettings.Builder setMatchMode(int); - method public android.bluetooth.le.ScanSettings.Builder setNumOfMatches(int); - method public android.bluetooth.le.ScanSettings.Builder setPhy(int); - method public android.bluetooth.le.ScanSettings.Builder setReportDelay(long); - method public android.bluetooth.le.ScanSettings.Builder setScanMode(int); - } - - public final class TransportBlock implements android.os.Parcelable { - ctor public TransportBlock(int, int, int, @Nullable byte[]); - method public int describeContents(); - method public int getOrgId(); - method public int getTdsFlags(); - method @Nullable public byte[] getTransportData(); - method public int getTransportDataLength(); - method @Nullable public byte[] toByteArray(); - method public int totalBytes(); - method public void writeToParcel(@NonNull android.os.Parcel, int); - field @NonNull public static final android.os.Parcelable.Creator<android.bluetooth.le.TransportBlock> CREATOR; - } - - public final class TransportDiscoveryData implements android.os.Parcelable { - ctor public TransportDiscoveryData(int, @NonNull java.util.List<android.bluetooth.le.TransportBlock>); - ctor public TransportDiscoveryData(@NonNull byte[]); - method public int describeContents(); - method @NonNull public java.util.List<android.bluetooth.le.TransportBlock> getTransportBlocks(); - method public int getTransportDataType(); - method @Nullable public byte[] toByteArray(); - method public int totalBytes(); - method public void writeToParcel(@NonNull android.os.Parcel, int); - field @NonNull public static final android.os.Parcelable.Creator<android.bluetooth.le.TransportDiscoveryData> CREATOR; - } - -} - package android.companion { public final class AssociationRequest implements android.os.Parcelable { @@ -21882,9 +20598,11 @@ package android.media { field public static final int COLOR_Format24bitBGR888 = 12; // 0xc field @Deprecated public static final int COLOR_Format24bitRGB888 = 11; // 0xb field @Deprecated public static final int COLOR_Format25bitARGB1888 = 14; // 0xe + field public static final int COLOR_Format32bitABGR2101010 = 2130750114; // 0x7f00aaa2 field public static final int COLOR_Format32bitABGR8888 = 2130747392; // 0x7f00a000 field @Deprecated public static final int COLOR_Format32bitARGB8888 = 16; // 0x10 field @Deprecated public static final int COLOR_Format32bitBGRA8888 = 15; // 0xf + field public static final int COLOR_Format64bitABGRFloat = 2130710294; // 0x7f000f16 field @Deprecated public static final int COLOR_Format8bitRGB332 = 2; // 0x2 field @Deprecated public static final int COLOR_FormatCbYCrY = 27; // 0x1b field @Deprecated public static final int COLOR_FormatCrYCbY = 28; // 0x1c @@ -21917,10 +20635,12 @@ package android.media { field @Deprecated public static final int COLOR_FormatYUV422SemiPlanar = 24; // 0x18 field public static final int COLOR_FormatYUV444Flexible = 2135181448; // 0x7f444888 field @Deprecated public static final int COLOR_FormatYUV444Interleaved = 29; // 0x1d + field public static final int COLOR_FormatYUVP010 = 54; // 0x36 field @Deprecated public static final int COLOR_QCOM_FormatYUV420SemiPlanar = 2141391872; // 0x7fa30c00 field @Deprecated public static final int COLOR_TI_FormatYUV420PackedSemiPlanar = 2130706688; // 0x7f000100 field public static final String FEATURE_AdaptivePlayback = "adaptive-playback"; field public static final String FEATURE_DynamicTimestamp = "dynamic-timestamp"; + field public static final String FEATURE_EncodingStatistics = "encoding-statistics"; field public static final String FEATURE_FrameParsing = "frame-parsing"; field public static final String FEATURE_IntraRefresh = "intra-refresh"; field public static final String FEATURE_LowLatency = "low-latency"; @@ -22004,11 +20724,14 @@ package android.media { field public static final int AVCProfileHigh422 = 32; // 0x20 field public static final int AVCProfileHigh444 = 64; // 0x40 field public static final int AVCProfileMain = 2; // 0x2 + field public static final int DolbyVisionLevel8k30 = 1024; // 0x400 + field public static final int DolbyVisionLevel8k60 = 2048; // 0x800 field public static final int DolbyVisionLevelFhd24 = 4; // 0x4 field public static final int DolbyVisionLevelFhd30 = 8; // 0x8 field public static final int DolbyVisionLevelFhd60 = 16; // 0x10 field public static final int DolbyVisionLevelHd24 = 1; // 0x1 field public static final int DolbyVisionLevelHd30 = 2; // 0x2 + field public static final int DolbyVisionLevelUhd120 = 512; // 0x200 field public static final int DolbyVisionLevelUhd24 = 32; // 0x20 field public static final int DolbyVisionLevelUhd30 = 64; // 0x40 field public static final int DolbyVisionLevelUhd48 = 128; // 0x80 @@ -22694,6 +21417,7 @@ package android.media { field public static final String KEY_OPERATING_RATE = "operating-rate"; field public static final String KEY_OUTPUT_REORDER_DEPTH = "output-reorder-depth"; field public static final String KEY_PCM_ENCODING = "pcm-encoding"; + field public static final String KEY_PICTURE_TYPE = "picture-type"; field public static final String KEY_PIXEL_ASPECT_RATIO_HEIGHT = "sar-height"; field public static final String KEY_PIXEL_ASPECT_RATIO_WIDTH = "sar-width"; field public static final String KEY_PREPEND_HEADER_TO_SYNC_FRAMES = "prepend-sps-pps-to-idr-frames"; @@ -22711,6 +21435,8 @@ package android.media { field public static final String KEY_TILE_HEIGHT = "tile-height"; field public static final String KEY_TILE_WIDTH = "tile-width"; field public static final String KEY_TRACK_ID = "track-id"; + field public static final String KEY_VIDEO_ENCODING_STATISTICS_LEVEL = "video-encoding-statistics-level"; + field public static final String KEY_VIDEO_QP_AVERAGE = "video-qp-average"; field public static final String KEY_VIDEO_QP_B_MAX = "video-qp-b-max"; field public static final String KEY_VIDEO_QP_B_MIN = "video-qp-b-min"; field public static final String KEY_VIDEO_QP_I_MAX = "video-qp-i-max"; @@ -22755,12 +21481,18 @@ package android.media { field public static final String MIMETYPE_VIDEO_SCRAMBLED = "video/scrambled"; field public static final String MIMETYPE_VIDEO_VP8 = "video/x-vnd.on2.vp8"; field public static final String MIMETYPE_VIDEO_VP9 = "video/x-vnd.on2.vp9"; + field public static final int PICTURE_TYPE_B = 3; // 0x3 + field public static final int PICTURE_TYPE_I = 1; // 0x1 + field public static final int PICTURE_TYPE_P = 2; // 0x2 + field public static final int PICTURE_TYPE_UNKNOWN = 0; // 0x0 field public static final int TYPE_BYTE_BUFFER = 5; // 0x5 field public static final int TYPE_FLOAT = 3; // 0x3 field public static final int TYPE_INTEGER = 1; // 0x1 field public static final int TYPE_LONG = 2; // 0x2 field public static final int TYPE_NULL = 0; // 0x0 field public static final int TYPE_STRING = 4; // 0x4 + field public static final int VIDEO_ENCODING_STATISTICS_LEVEL_1 = 1; // 0x1 + field public static final int VIDEO_ENCODING_STATISTICS_LEVEL_NONE = 0; // 0x0 } public final class MediaMetadata implements android.os.Parcelable { @@ -26484,12 +25216,14 @@ package android.net { public static final class Ikev2VpnProfile.Builder { ctor public Ikev2VpnProfile.Builder(@NonNull String, @NonNull String); + ctor public Ikev2VpnProfile.Builder(@NonNull android.net.ipsec.ike.IkeTunnelConnectionParams); method @NonNull public android.net.Ikev2VpnProfile build(); method @NonNull public android.net.Ikev2VpnProfile.Builder setAllowedAlgorithms(@NonNull java.util.List<java.lang.String>); method @NonNull public android.net.Ikev2VpnProfile.Builder setAuthDigitalSignature(@NonNull java.security.cert.X509Certificate, @NonNull java.security.PrivateKey, @Nullable java.security.cert.X509Certificate); method @NonNull public android.net.Ikev2VpnProfile.Builder setAuthPsk(@NonNull byte[]); method @NonNull public android.net.Ikev2VpnProfile.Builder setAuthUsernamePassword(@NonNull String, @NonNull String, @Nullable java.security.cert.X509Certificate); method @NonNull public android.net.Ikev2VpnProfile.Builder setBypassable(boolean); + method @NonNull public android.net.Ikev2VpnProfile.Builder setExcludeLocalRoutes(boolean); method @NonNull public android.net.Ikev2VpnProfile.Builder setMaxMtu(int); method @NonNull public android.net.Ikev2VpnProfile.Builder setMetered(boolean); method @NonNull public android.net.Ikev2VpnProfile.Builder setProxy(@Nullable android.net.ProxyInfo); @@ -26635,6 +25369,7 @@ package android.net { } public abstract class PlatformVpnProfile { + method public final boolean getExcludeLocalRoutes(); method public final int getType(); method @NonNull public final String getTypeString(); field public static final int TYPE_IKEV2_IPSEC_PSK = 7; // 0x7 @@ -41291,6 +40026,7 @@ package android.telephony { field public static final String KEY_SUPPORTED_IKE_SESSION_ENCRYPTION_ALGORITHMS_INT_ARRAY = "iwlan.supported_ike_session_encryption_algorithms_int_array"; field public static final String KEY_SUPPORTED_INTEGRITY_ALGORITHMS_INT_ARRAY = "iwlan.supported_integrity_algorithms_int_array"; field public static final String KEY_SUPPORTED_PRF_ALGORITHMS_INT_ARRAY = "iwlan.supported_prf_algorithms_int_array"; + field public static final String KEY_SUPPORTS_EAP_AKA_FAST_REAUTH_BOOL = "iwlan.supports_eap_aka_fast_reauth_bool"; } public abstract class CellIdentity implements android.os.Parcelable { diff --git a/core/api/module-lib-current.txt b/core/api/module-lib-current.txt index 445512e00f96..32c711b555a5 100644 --- a/core/api/module-lib-current.txt +++ b/core/api/module-lib-current.txt @@ -55,24 +55,23 @@ package android.app.usage { public class NetworkStatsManager { method @RequiresPermission(anyOf={android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK, android.Manifest.permission.NETWORK_STACK}) public void forceUpdate(); + method public static int getCollapsedRatType(int); method @RequiresPermission(anyOf={android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK, android.Manifest.permission.NETWORK_STACK}) public void notifyNetworkStatus(@NonNull java.util.List<android.net.Network>, @NonNull java.util.List<android.net.NetworkStateSnapshot>, @Nullable String, @NonNull java.util.List<android.net.UnderlyingNetworkInfo>); method @NonNull @WorkerThread public android.app.usage.NetworkStats queryDetailsForDevice(@NonNull android.net.NetworkTemplate, long, long); method @NonNull @WorkerThread public android.app.usage.NetworkStats queryDetailsForUidTagState(@NonNull android.net.NetworkTemplate, long, long, int, int, int) throws java.lang.SecurityException; method @NonNull @WorkerThread public android.app.usage.NetworkStats querySummary(@NonNull android.net.NetworkTemplate, long, long) throws java.lang.SecurityException; method @NonNull @WorkerThread public android.app.usage.NetworkStats.Bucket querySummaryForDevice(@NonNull android.net.NetworkTemplate, long, long); method @NonNull @WorkerThread public android.app.usage.NetworkStats queryTaggedSummary(@NonNull android.net.NetworkTemplate, long, long) throws java.lang.SecurityException; + method public void registerUsageCallback(@NonNull android.net.NetworkTemplate, long, @NonNull java.util.concurrent.Executor, @NonNull android.app.usage.NetworkStatsManager.UsageCallback); method @RequiresPermission(anyOf={android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK, android.Manifest.permission.NETWORK_STACK}) public void setDefaultGlobalAlert(long); method @RequiresPermission(anyOf={android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK, android.Manifest.permission.NETWORK_STACK}) public void setPollOnOpen(boolean); method @RequiresPermission(anyOf={android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK, android.Manifest.permission.NETWORK_STACK}) public void setStatsProviderWarningAndLimitAsync(@NonNull String, long, long); method @RequiresPermission(anyOf={android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK, android.Manifest.permission.NETWORK_STACK}) public void setUidForeground(int, boolean); + field public static final int NETWORK_TYPE_5G_NSA = -2; // 0xfffffffe } -} - -package android.bluetooth { - - public final class BluetoothPan implements android.bluetooth.BluetoothProfile { - method @Nullable @RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT, android.Manifest.permission.BLUETOOTH_PRIVILEGED, android.Manifest.permission.TETHER_PRIVILEGED}) public android.net.TetheringManager.TetheredInterfaceRequest requestTetheredInterface(@NonNull java.util.concurrent.Executor, @NonNull android.net.TetheringManager.TetheredInterfaceCallback); + public abstract static class NetworkStatsManager.UsageCallback { + method public void onThresholdReached(@NonNull android.net.NetworkTemplate); } } @@ -235,6 +234,36 @@ package android.net { method public int getResourceId(); } + public class LocalSocket implements java.io.Closeable { + ctor public LocalSocket(@NonNull java.io.FileDescriptor); + } + + public class NetworkIdentity { + method public int getOemManaged(); + method public int getRatType(); + method @Nullable public String getSubscriberId(); + method public int getType(); + method @Nullable public String getWifiNetworkKey(); + method public boolean isDefaultNetwork(); + method public boolean isMetered(); + method public boolean isRoaming(); + } + + public static final class NetworkIdentity.Builder { + ctor public NetworkIdentity.Builder(); + method @NonNull public android.net.NetworkIdentity build(); + method @NonNull public android.net.NetworkIdentity.Builder clearRatType(); + method @NonNull public android.net.NetworkIdentity.Builder setDefaultNetwork(boolean); + method @NonNull public android.net.NetworkIdentity.Builder setMetered(boolean); + method @NonNull public android.net.NetworkIdentity.Builder setNetworkStateSnapshot(@NonNull android.net.NetworkStateSnapshot); + method @NonNull public android.net.NetworkIdentity.Builder setOemManaged(int); + method @NonNull public android.net.NetworkIdentity.Builder setRatType(int); + method @NonNull public android.net.NetworkIdentity.Builder setRoaming(boolean); + method @NonNull public android.net.NetworkIdentity.Builder setSubscriberId(@Nullable String); + method @NonNull public android.net.NetworkIdentity.Builder setType(int); + method @NonNull public android.net.NetworkIdentity.Builder setWifiNetworkKey(@Nullable String); + } + public class NetworkPolicyManager { method @RequiresPermission(android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK) public int getMultipathPreference(@NonNull android.net.Network); method @RequiresPermission(android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK) public int getRestrictBackgroundStatus(int); @@ -262,6 +291,44 @@ package android.net { field @NonNull public static final android.os.Parcelable.Creator<android.net.NetworkStateSnapshot> CREATOR; } + public class NetworkStatsCollection { + method @NonNull public java.util.Map<android.net.NetworkStatsCollection.Key,android.net.NetworkStatsHistory> getEntries(); + } + + public static final class NetworkStatsCollection.Builder { + ctor public NetworkStatsCollection.Builder(long); + method @NonNull public android.net.NetworkStatsCollection.Builder addEntry(@NonNull android.net.NetworkStatsCollection.Key, @NonNull android.net.NetworkStatsHistory); + method @NonNull public android.net.NetworkStatsCollection build(); + } + + public static class NetworkStatsCollection.Key { + ctor public NetworkStatsCollection.Key(@NonNull java.util.Set<android.net.NetworkIdentity>, int, int, int); + } + + public final class NetworkStatsHistory implements android.os.Parcelable { + method public int describeContents(); + method @NonNull public java.util.List<android.net.NetworkStatsHistory.Entry> getEntries(); + method public void writeToParcel(@NonNull android.os.Parcel, int); + field @NonNull public static final android.os.Parcelable.Creator<android.net.NetworkStatsHistory> CREATOR; + } + + public static final class NetworkStatsHistory.Builder { + ctor public NetworkStatsHistory.Builder(long, int); + method @NonNull public android.net.NetworkStatsHistory.Builder addEntry(@NonNull android.net.NetworkStatsHistory.Entry); + method @NonNull public android.net.NetworkStatsHistory build(); + } + + public static final class NetworkStatsHistory.Entry { + ctor public NetworkStatsHistory.Entry(long, long, long, long, long, long, long); + method public long getActiveTime(); + method public long getBucketStart(); + method public long getOperations(); + method public long getRxBytes(); + method public long getRxPackets(); + method public long getTxBytes(); + method public long getTxPackets(); + } + public final class NetworkTemplate implements android.os.Parcelable { method public int describeContents(); method public int getDefaultNetworkStatus(); @@ -272,6 +339,7 @@ package android.net { method public int getRoaming(); method @NonNull public java.util.Set<java.lang.String> getSubscriberIds(); method @NonNull public java.util.Set<java.lang.String> getWifiNetworkKeys(); + method public boolean matches(@NonNull android.net.NetworkIdentity); method public void writeToParcel(@NonNull android.os.Parcel, int); field @NonNull public static final android.os.Parcelable.Creator<android.net.NetworkTemplate> CREATOR; field public static final int MATCH_BLUETOOTH = 8; // 0x8 @@ -317,6 +385,11 @@ package android.net { method public static void setHttpProxyConfiguration(@Nullable android.net.ProxyInfo); } + public class TrafficStats { + method public static void attachSocketTagger(); + method public static void init(@NonNull android.content.Context); + } + public final class UnderlyingNetworkInfo implements android.os.Parcelable { ctor public UnderlyingNetworkInfo(int, @NonNull String, @NonNull java.util.List<java.lang.String>); method public int describeContents(); diff --git a/core/api/system-current.txt b/core/api/system-current.txt index 1fde724d99c7..61b4ada0c5dd 100644 --- a/core/api/system-current.txt +++ b/core/api/system-current.txt @@ -316,6 +316,7 @@ package android { public static final class R.array { field public static final int config_keySystemUuidMapping = 17235973; // 0x1070005 + field public static final int config_optionalIpSecAlgorithms; } public static final class R.attr { @@ -1915,423 +1916,6 @@ package android.apphibernation { } -package android.bluetooth { - - public final class BluetoothA2dp implements android.bluetooth.BluetoothProfile { - method @Nullable @RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT, android.Manifest.permission.BLUETOOTH_PRIVILEGED}) public android.bluetooth.BufferConstraints getBufferConstraints(); - method @RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT, android.Manifest.permission.BLUETOOTH_PRIVILEGED}) public int getConnectionPolicy(@NonNull android.bluetooth.BluetoothDevice); - method @RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT, android.Manifest.permission.BLUETOOTH_PRIVILEGED}) public int getDynamicBufferSupport(); - method @RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT, android.Manifest.permission.BLUETOOTH_PRIVILEGED}) public boolean setBufferLengthMillis(int, int); - method @RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT, android.Manifest.permission.BLUETOOTH_PRIVILEGED}) public boolean setConnectionPolicy(@NonNull android.bluetooth.BluetoothDevice, int); - field public static final int DYNAMIC_BUFFER_SUPPORT_A2DP_OFFLOAD = 1; // 0x1 - field public static final int DYNAMIC_BUFFER_SUPPORT_A2DP_SOFTWARE_ENCODING = 2; // 0x2 - field public static final int DYNAMIC_BUFFER_SUPPORT_NONE = 0; // 0x0 - field public static final int OPTIONAL_CODECS_NOT_SUPPORTED = 0; // 0x0 - field public static final int OPTIONAL_CODECS_PREF_DISABLED = 0; // 0x0 - field public static final int OPTIONAL_CODECS_PREF_ENABLED = 1; // 0x1 - field public static final int OPTIONAL_CODECS_PREF_UNKNOWN = -1; // 0xffffffff - field public static final int OPTIONAL_CODECS_SUPPORTED = 1; // 0x1 - field public static final int OPTIONAL_CODECS_SUPPORT_UNKNOWN = -1; // 0xffffffff - } - - public final class BluetoothA2dpSink implements android.bluetooth.BluetoothProfile { - method public void finalize(); - method @RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT, android.Manifest.permission.BLUETOOTH_PRIVILEGED}) public int getConnectionPolicy(@NonNull android.bluetooth.BluetoothDevice); - method @RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT, android.Manifest.permission.BLUETOOTH_PRIVILEGED}) public boolean isAudioPlaying(@NonNull android.bluetooth.BluetoothDevice); - method @RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT, android.Manifest.permission.BLUETOOTH_PRIVILEGED}) public boolean setConnectionPolicy(@NonNull android.bluetooth.BluetoothDevice, int); - field @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public static final String ACTION_CONNECTION_STATE_CHANGED = "android.bluetooth.a2dp-sink.profile.action.CONNECTION_STATE_CHANGED"; - } - - public final class BluetoothActivityEnergyInfo implements android.os.Parcelable { - method public int getBluetoothStackState(); - method public long getControllerEnergyUsed(); - method public long getControllerIdleTimeMillis(); - method public long getControllerRxTimeMillis(); - method public long getControllerTxTimeMillis(); - method public long getTimestampMillis(); - method @NonNull public java.util.List<android.bluetooth.UidTraffic> getUidTraffic(); - method public boolean isValid(); - field public static final int BT_STACK_STATE_INVALID = 0; // 0x0 - field public static final int BT_STACK_STATE_STATE_ACTIVE = 1; // 0x1 - field public static final int BT_STACK_STATE_STATE_IDLE = 3; // 0x3 - field public static final int BT_STACK_STATE_STATE_SCANNING = 2; // 0x2 - field @NonNull public static final android.os.Parcelable.Creator<android.bluetooth.BluetoothActivityEnergyInfo> CREATOR; - } - - public final class BluetoothAdapter { - method @RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT, android.Manifest.permission.BLUETOOTH_PRIVILEGED}) public boolean addOnMetadataChangedListener(@NonNull android.bluetooth.BluetoothDevice, @NonNull java.util.concurrent.Executor, @NonNull android.bluetooth.BluetoothAdapter.OnMetadataChangedListener); - method @RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT, android.Manifest.permission.BLUETOOTH_PRIVILEGED}) public boolean disable(boolean); - method @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public boolean disableBLE(); - method @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public boolean enableBLE(); - method @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public boolean enableNoAutoConnect(); - method @RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT, android.Manifest.permission.BLUETOOTH_PRIVILEGED}) public void generateLocalOobData(int, @NonNull java.util.concurrent.Executor, @NonNull android.bluetooth.BluetoothAdapter.OobDataCallback); - method @NonNull @RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT, android.Manifest.permission.BLUETOOTH_PRIVILEGED}) public java.util.List<android.bluetooth.BluetoothDevice> getActiveDevices(int); - method @RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT, android.Manifest.permission.BLUETOOTH_PRIVILEGED}) public long getDiscoveryEndMillis(); - method public boolean isBleScanAlwaysAvailable(); - method public boolean isLeEnabled(); - method @RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT, android.Manifest.permission.BLUETOOTH_PRIVILEGED, android.Manifest.permission.MODIFY_PHONE_STATE}) public boolean removeActiveDevice(int); - method @RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT, android.Manifest.permission.BLUETOOTH_PRIVILEGED}) public boolean removeOnMetadataChangedListener(@NonNull android.bluetooth.BluetoothDevice, @NonNull android.bluetooth.BluetoothAdapter.OnMetadataChangedListener); - method @RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT, android.Manifest.permission.BLUETOOTH_PRIVILEGED, android.Manifest.permission.MODIFY_PHONE_STATE}) public boolean setActiveDevice(@NonNull android.bluetooth.BluetoothDevice, int); - field public static final String ACTION_BLE_STATE_CHANGED = "android.bluetooth.adapter.action.BLE_STATE_CHANGED"; - field public static final String ACTION_REQUEST_BLE_SCAN_ALWAYS_AVAILABLE = "android.bluetooth.adapter.action.REQUEST_BLE_SCAN_ALWAYS_AVAILABLE"; - 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 - } - - 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, @NonNull android.bluetooth.OobData); - } - - public final class BluetoothCsipSetCoordinator implements java.lang.AutoCloseable android.bluetooth.BluetoothProfile { - method @NonNull @RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED) public java.util.List<java.lang.Integer> getAllGroupIds(@Nullable android.os.ParcelUuid); - method @RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED) public int getConnectionPolicy(@Nullable android.bluetooth.BluetoothDevice); - method @NonNull @RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED) public java.util.Map getGroupUuidMapByDevice(@Nullable android.bluetooth.BluetoothDevice); - method @Nullable @RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED) public java.util.UUID groupLock(int, @Nullable java.util.concurrent.Executor, @Nullable android.bluetooth.BluetoothCsipSetCoordinator.ClientLockCallback); - method @RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED) public boolean groupUnlock(@NonNull java.util.UUID); - method @RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED) public boolean setConnectionPolicy(@Nullable android.bluetooth.BluetoothDevice, int); - field @RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED) public static final String ACTION_CSIS_DEVICE_AVAILABLE = "android.bluetooth.action.CSIS_DEVICE_AVAILABLE"; - field @RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED) public static final String ACTION_CSIS_SET_MEMBER_AVAILABLE = "android.bluetooth.action.CSIS_SET_MEMBER_AVAILABLE"; - } - - public static interface BluetoothCsipSetCoordinator.ClientLockCallback { - method public void onGroupLockSet(int, int, boolean); - } - - public final class BluetoothDevice implements android.os.Parcelable { - method @RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT, android.Manifest.permission.BLUETOOTH_PRIVILEGED}) public boolean canBondWithoutDialog(); - method @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public boolean cancelBondProcess(); - method @RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT, android.Manifest.permission.BLUETOOTH_PRIVILEGED, android.Manifest.permission.MODIFY_PHONE_STATE}) public int connect(); - method @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public boolean createBond(int); - method @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public boolean createBondOutOfBand(int, @Nullable android.bluetooth.OobData, @Nullable android.bluetooth.OobData); - method @RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT, android.Manifest.permission.BLUETOOTH_PRIVILEGED}) public int disconnect(); - method @RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT, android.Manifest.permission.BLUETOOTH_PRIVILEGED}) public boolean fetchUuidsWithSdp(int); - method @Nullable @RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT, android.Manifest.permission.BLUETOOTH_PRIVILEGED}) public byte[] getMetadata(int); - method @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public int getSimAccessPermission(); - method @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public boolean isConnected(); - method @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public boolean isEncrypted(); - method @RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT, android.Manifest.permission.BLUETOOTH_PRIVILEGED}) public boolean isInSilenceMode(); - method @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public boolean removeBond(); - method @RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT, android.Manifest.permission.BLUETOOTH_PRIVILEGED}) public boolean setMessageAccessPermission(int); - method @RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT, android.Manifest.permission.BLUETOOTH_PRIVILEGED}) public boolean setMetadata(int, @NonNull byte[]); - method @RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT, android.Manifest.permission.BLUETOOTH_PRIVILEGED}) public boolean setPhonebookAccessPermission(int); - method @RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT, android.Manifest.permission.BLUETOOTH_PRIVILEGED}) public boolean setSilenceMode(boolean); - method @RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT, android.Manifest.permission.BLUETOOTH_PRIVILEGED}) public boolean setSimAccessPermission(int); - field public static final int ACCESS_ALLOWED = 1; // 0x1 - field public static final int ACCESS_REJECTED = 2; // 0x2 - field public static final int ACCESS_UNKNOWN = 0; // 0x0 - field @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public static final String ACTION_SILENCE_MODE_CHANGED = "android.bluetooth.device.action.SILENCE_MODE_CHANGED"; - field public static final String DEVICE_TYPE_DEFAULT = "Default"; - field public static final String DEVICE_TYPE_UNTETHERED_HEADSET = "Untethered Headset"; - field public static final String DEVICE_TYPE_WATCH = "Watch"; - field public static final int METADATA_COMPANION_APP = 4; // 0x4 - field public static final int METADATA_DEVICE_TYPE = 17; // 0x11 - field public static final int METADATA_ENHANCED_SETTINGS_UI_URI = 16; // 0x10 - field public static final int METADATA_HARDWARE_VERSION = 3; // 0x3 - field public static final int METADATA_IS_UNTETHERED_HEADSET = 6; // 0x6 - field public static final int METADATA_MAIN_BATTERY = 18; // 0x12 - field public static final int METADATA_MAIN_CHARGING = 19; // 0x13 - field public static final int METADATA_MAIN_ICON = 5; // 0x5 - field public static final int METADATA_MAIN_LOW_BATTERY_THRESHOLD = 20; // 0x14 - field public static final int METADATA_MANUFACTURER_NAME = 0; // 0x0 - field public static final int METADATA_MAX_LENGTH = 2048; // 0x800 - field public static final int METADATA_MODEL_NAME = 1; // 0x1 - field public static final int METADATA_SOFTWARE_VERSION = 2; // 0x2 - field public static final int METADATA_UNTETHERED_CASE_BATTERY = 12; // 0xc - field public static final int METADATA_UNTETHERED_CASE_CHARGING = 15; // 0xf - field public static final int METADATA_UNTETHERED_CASE_ICON = 9; // 0x9 - field public static final int METADATA_UNTETHERED_CASE_LOW_BATTERY_THRESHOLD = 23; // 0x17 - field public static final int METADATA_UNTETHERED_LEFT_BATTERY = 10; // 0xa - field public static final int METADATA_UNTETHERED_LEFT_CHARGING = 13; // 0xd - field public static final int METADATA_UNTETHERED_LEFT_ICON = 7; // 0x7 - field public static final int METADATA_UNTETHERED_LEFT_LOW_BATTERY_THRESHOLD = 21; // 0x15 - field public static final int METADATA_UNTETHERED_RIGHT_BATTERY = 11; // 0xb - field public static final int METADATA_UNTETHERED_RIGHT_CHARGING = 14; // 0xe - field public static final int METADATA_UNTETHERED_RIGHT_ICON = 8; // 0x8 - field public static final int METADATA_UNTETHERED_RIGHT_LOW_BATTERY_THRESHOLD = 22; // 0x16 - } - - public final class BluetoothHeadset implements android.bluetooth.BluetoothProfile { - method @RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT, android.Manifest.permission.MODIFY_PHONE_STATE}) public boolean connect(android.bluetooth.BluetoothDevice); - method @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public boolean disconnect(android.bluetooth.BluetoothDevice); - method @RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT, android.Manifest.permission.BLUETOOTH_PRIVILEGED}) public int getConnectionPolicy(@NonNull android.bluetooth.BluetoothDevice); - method @RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED) public boolean isInbandRingingEnabled(); - method @RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT, android.Manifest.permission.BLUETOOTH_PRIVILEGED, android.Manifest.permission.MODIFY_PHONE_STATE}) public boolean setConnectionPolicy(@NonNull android.bluetooth.BluetoothDevice, int); - method @RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT, android.Manifest.permission.MODIFY_PHONE_STATE}) public boolean startScoUsingVirtualVoiceCall(); - method @RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT, android.Manifest.permission.MODIFY_PHONE_STATE}) public boolean stopScoUsingVirtualVoiceCall(); - } - - public final class BluetoothHearingAid implements android.bluetooth.BluetoothProfile { - method @RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT, android.Manifest.permission.BLUETOOTH_PRIVILEGED}) public int getConnectionPolicy(@NonNull android.bluetooth.BluetoothDevice); - method @RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT, android.Manifest.permission.BLUETOOTH_PRIVILEGED}) public long getHiSyncId(@NonNull android.bluetooth.BluetoothDevice); - method @RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT, android.Manifest.permission.BLUETOOTH_PRIVILEGED}) public boolean setConnectionPolicy(@NonNull android.bluetooth.BluetoothDevice, int); - } - - public final class BluetoothHidDevice implements android.bluetooth.BluetoothProfile { - method @RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT, android.Manifest.permission.BLUETOOTH_PRIVILEGED}) public boolean setConnectionPolicy(@NonNull android.bluetooth.BluetoothDevice, int); - } - - public final class BluetoothHidHost implements android.bluetooth.BluetoothProfile { - method @NonNull @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public java.util.List<android.bluetooth.BluetoothDevice> getConnectedDevices(); - method @RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT, android.Manifest.permission.BLUETOOTH_PRIVILEGED}) public int getConnectionPolicy(@NonNull android.bluetooth.BluetoothDevice); - method @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public int getConnectionState(@NonNull android.bluetooth.BluetoothDevice); - method @RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT, android.Manifest.permission.BLUETOOTH_PRIVILEGED}) public boolean setConnectionPolicy(@NonNull android.bluetooth.BluetoothDevice, int); - field @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public static final String ACTION_CONNECTION_STATE_CHANGED = "android.bluetooth.input.profile.action.CONNECTION_STATE_CHANGED"; - } - - public final class BluetoothMap implements java.lang.AutoCloseable android.bluetooth.BluetoothProfile { - method public void close(); - method protected void finalize(); - method @NonNull @RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT, android.Manifest.permission.BLUETOOTH_PRIVILEGED}) public java.util.List<android.bluetooth.BluetoothDevice> getConnectedDevices(); - method @RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT, android.Manifest.permission.BLUETOOTH_PRIVILEGED}) public int getConnectionPolicy(@NonNull android.bluetooth.BluetoothDevice); - method @RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT, android.Manifest.permission.BLUETOOTH_PRIVILEGED}) public boolean setConnectionPolicy(@NonNull android.bluetooth.BluetoothDevice, int); - field @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public static final String ACTION_CONNECTION_STATE_CHANGED = "android.bluetooth.map.profile.action.CONNECTION_STATE_CHANGED"; - } - - public final class BluetoothMapClient implements android.bluetooth.BluetoothProfile { - method @RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT, android.Manifest.permission.SEND_SMS}) public boolean sendMessage(@NonNull android.bluetooth.BluetoothDevice, @NonNull java.util.Collection<android.net.Uri>, @NonNull String, @Nullable android.app.PendingIntent, @Nullable android.app.PendingIntent); - } - - public final class BluetoothPan implements android.bluetooth.BluetoothProfile { - method @NonNull @RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT, android.Manifest.permission.BLUETOOTH_PRIVILEGED}) public java.util.List<android.bluetooth.BluetoothDevice> getConnectedDevices(); - method @RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT, android.Manifest.permission.BLUETOOTH_PRIVILEGED}) public int getConnectionState(@NonNull android.bluetooth.BluetoothDevice); - method @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public boolean isTetheringOn(); - method @Deprecated @RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT, android.Manifest.permission.BLUETOOTH_PRIVILEGED, android.Manifest.permission.TETHER_PRIVILEGED}) public void setBluetoothTethering(boolean); - method @RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT, android.Manifest.permission.BLUETOOTH_PRIVILEGED}) public boolean setConnectionPolicy(@NonNull android.bluetooth.BluetoothDevice, int); - field @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public static final String ACTION_CONNECTION_STATE_CHANGED = "android.bluetooth.pan.profile.action.CONNECTION_STATE_CHANGED"; - field public static final String ACTION_TETHERING_STATE_CHANGED = "android.bluetooth.action.TETHERING_STATE_CHANGED"; - field public static final String EXTRA_LOCAL_ROLE = "android.bluetooth.pan.extra.LOCAL_ROLE"; - field public static final String EXTRA_TETHERING_STATE = "android.bluetooth.extra.TETHERING_STATE"; - field public static final int LOCAL_NAP_ROLE = 1; // 0x1 - field public static final int LOCAL_PANU_ROLE = 2; // 0x2 - field public static final int PAN_ROLE_NONE = 0; // 0x0 - field public static final int REMOTE_NAP_ROLE = 1; // 0x1 - field public static final int REMOTE_PANU_ROLE = 2; // 0x2 - field public static final int TETHERING_STATE_OFF = 1; // 0x1 - field public static final int TETHERING_STATE_ON = 2; // 0x2 - } - - public class BluetoothPbap implements android.bluetooth.BluetoothProfile { - method @RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT, android.Manifest.permission.BLUETOOTH_PRIVILEGED}) public int getConnectionState(@NonNull android.bluetooth.BluetoothDevice); - method @RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT, android.Manifest.permission.BLUETOOTH_PRIVILEGED}) public boolean setConnectionPolicy(@NonNull android.bluetooth.BluetoothDevice, int); - field @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public static final String ACTION_CONNECTION_STATE_CHANGED = "android.bluetooth.pbap.profile.action.CONNECTION_STATE_CHANGED"; - } - - public interface BluetoothProfile { - field public static final int A2DP_SINK = 11; // 0xb - field public static final int AVRCP_CONTROLLER = 12; // 0xc - field public static final int CONNECTION_POLICY_ALLOWED = 100; // 0x64 - field public static final int CONNECTION_POLICY_FORBIDDEN = 0; // 0x0 - field public static final int CONNECTION_POLICY_UNKNOWN = -1; // 0xffffffff - field public static final int HEADSET_CLIENT = 16; // 0x10 - field public static final int MAP_CLIENT = 18; // 0x12 - field public static final int PAN = 5; // 0x5 - field public static final int PBAP_CLIENT = 17; // 0x11 - field @Deprecated public static final int PRIORITY_OFF = 0; // 0x0 - field @Deprecated public static final int PRIORITY_ON = 100; // 0x64 - field public static final int VOLUME_CONTROL = 23; // 0x17 - } - - public final class BluetoothStatusCodes { - field public static final int ERROR_ANOTHER_ACTIVE_OOB_REQUEST = 1000; // 0x3e8 - } - - public final class BluetoothUuid { - method public static boolean containsAnyUuid(@Nullable android.os.ParcelUuid[], @Nullable android.os.ParcelUuid[]); - method @NonNull public static android.os.ParcelUuid parseUuidFrom(@Nullable byte[]); - field @NonNull public static final android.os.ParcelUuid A2DP_SINK; - field @NonNull public static final android.os.ParcelUuid A2DP_SOURCE; - field @NonNull public static final android.os.ParcelUuid ADV_AUDIO_DIST; - field @NonNull public static final android.os.ParcelUuid AVRCP_CONTROLLER; - field @NonNull public static final android.os.ParcelUuid AVRCP_TARGET; - field @NonNull public static final android.os.ParcelUuid BASE_UUID; - field @NonNull public static final android.os.ParcelUuid BNEP; - field @NonNull public static final android.os.ParcelUuid CAP; - field @NonNull public static final android.os.ParcelUuid COORDINATED_SET; - field @NonNull public static final android.os.ParcelUuid DIP; - field @NonNull public static final android.os.ParcelUuid GENERIC_MEDIA_CONTROL; - field @NonNull public static final android.os.ParcelUuid HEARING_AID; - field @NonNull public static final android.os.ParcelUuid HFP; - field @NonNull public static final android.os.ParcelUuid HFP_AG; - field @NonNull public static final android.os.ParcelUuid HID; - field @NonNull public static final android.os.ParcelUuid HOGP; - field @NonNull public static final android.os.ParcelUuid HSP; - field @NonNull public static final android.os.ParcelUuid HSP_AG; - field @NonNull public static final android.os.ParcelUuid LE_AUDIO; - field @NonNull public static final android.os.ParcelUuid MAP; - field @NonNull public static final android.os.ParcelUuid MAS; - field @NonNull public static final android.os.ParcelUuid MEDIA_CONTROL; - field @NonNull public static final android.os.ParcelUuid MNS; - field @NonNull public static final android.os.ParcelUuid NAP; - field @NonNull public static final android.os.ParcelUuid OBEX_OBJECT_PUSH; - field @NonNull public static final android.os.ParcelUuid PANU; - field @NonNull public static final android.os.ParcelUuid PBAP_PCE; - field @NonNull public static final android.os.ParcelUuid PBAP_PSE; - field @NonNull public static final android.os.ParcelUuid SAP; - field public static final int UUID_BYTES_128_BIT = 16; // 0x10 - field public static final int UUID_BYTES_16_BIT = 2; // 0x2 - field public static final int UUID_BYTES_32_BIT = 4; // 0x4 - field @NonNull public static final android.os.ParcelUuid VOLUME_CONTROL; - } - - public final class BluetoothVolumeControl implements java.lang.AutoCloseable android.bluetooth.BluetoothProfile { - method @RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED) public void close(); - method @RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED) protected void finalize(); - method @NonNull @RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT, android.Manifest.permission.BLUETOOTH_PRIVILEGED}) public java.util.List<android.bluetooth.BluetoothDevice> getConnectedDevices(); - method @RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT, android.Manifest.permission.BLUETOOTH_PRIVILEGED}) public int getConnectionPolicy(@NonNull android.bluetooth.BluetoothDevice); - method @RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT, android.Manifest.permission.BLUETOOTH_PRIVILEGED}) public boolean setConnectionPolicy(@NonNull android.bluetooth.BluetoothDevice, int); - method @RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT, android.Manifest.permission.BLUETOOTH_PRIVILEGED}) public void setVolume(@Nullable android.bluetooth.BluetoothDevice, @IntRange(from=0, to=255) int); - field @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public static final String ACTION_CONNECTION_STATE_CHANGED = "android.bluetooth.volume-control.profile.action.CONNECTION_STATE_CHANGED"; - } - - public final class BufferConstraint implements android.os.Parcelable { - ctor public BufferConstraint(int, int, int); - method public int describeContents(); - method public int getDefaultMillis(); - method public int getMaxMillis(); - method public int getMinMillis(); - method public void writeToParcel(@NonNull android.os.Parcel, int); - field @NonNull public static final android.os.Parcelable.Creator<android.bluetooth.BufferConstraint> CREATOR; - } - - public final class BufferConstraints implements android.os.Parcelable { - ctor public BufferConstraints(@NonNull java.util.List<android.bluetooth.BufferConstraint>); - method public int describeContents(); - method @Nullable public android.bluetooth.BufferConstraint forCodec(int); - method public void writeToParcel(@NonNull android.os.Parcel, int); - field public static final int BUFFER_CODEC_MAX_NUM = 32; // 0x20 - field @NonNull public static final android.os.Parcelable.Creator<android.bluetooth.BufferConstraints> CREATOR; - } - - public final class OobData implements android.os.Parcelable { - method @NonNull public byte[] getClassOfDevice(); - method @NonNull public byte[] getClassicLength(); - method @NonNull public byte[] getConfirmationHash(); - method @NonNull public byte[] getDeviceAddressWithType(); - method @Nullable public byte[] getDeviceName(); - method @Nullable public byte[] getLeAppearance(); - method @NonNull public int getLeDeviceRole(); - method @NonNull public int getLeFlags(); - method @Nullable public byte[] getLeTemporaryKey(); - method @NonNull public byte[] getRandomizerHash(); - field public static final int CLASS_OF_DEVICE_OCTETS = 3; // 0x3 - field public static final int CONFIRMATION_OCTETS = 16; // 0x10 - field @NonNull public static final android.os.Parcelable.Creator<android.bluetooth.OobData> CREATOR; - field public static final int DEVICE_ADDRESS_OCTETS = 7; // 0x7 - field public static final int LE_APPEARANCE_OCTETS = 2; // 0x2 - field public static final int LE_DEVICE_FLAG_OCTETS = 1; // 0x1 - field public static final int LE_DEVICE_ROLE_BOTH_PREFER_CENTRAL = 3; // 0x3 - field public static final int LE_DEVICE_ROLE_BOTH_PREFER_PERIPHERAL = 2; // 0x2 - field public static final int LE_DEVICE_ROLE_CENTRAL_ONLY = 1; // 0x1 - field public static final int LE_DEVICE_ROLE_OCTETS = 1; // 0x1 - field public static final int LE_DEVICE_ROLE_PERIPHERAL_ONLY = 0; // 0x0 - field public static final int LE_FLAG_BREDR_NOT_SUPPORTED = 2; // 0x2 - field public static final int LE_FLAG_GENERAL_DISCOVERY_MODE = 1; // 0x1 - field public static final int LE_FLAG_LIMITED_DISCOVERY_MODE = 0; // 0x0 - field public static final int LE_FLAG_SIMULTANEOUS_CONTROLLER = 3; // 0x3 - field public static final int LE_FLAG_SIMULTANEOUS_HOST = 4; // 0x4 - field public static final int LE_TK_OCTETS = 16; // 0x10 - field public static final int OOB_LENGTH_OCTETS = 2; // 0x2 - field public static final int RANDOMIZER_OCTETS = 16; // 0x10 - } - - public static final class OobData.ClassicBuilder { - ctor public OobData.ClassicBuilder(@NonNull byte[], @NonNull byte[], @NonNull byte[]); - method @NonNull public android.bluetooth.OobData build(); - method @NonNull public android.bluetooth.OobData.ClassicBuilder setClassOfDevice(@NonNull byte[]); - method @NonNull public android.bluetooth.OobData.ClassicBuilder setDeviceName(@NonNull byte[]); - method @NonNull public android.bluetooth.OobData.ClassicBuilder setRandomizerHash(@NonNull byte[]); - } - - public static final class OobData.LeBuilder { - ctor public OobData.LeBuilder(@NonNull byte[], @NonNull byte[], int); - method @NonNull public android.bluetooth.OobData build(); - method @NonNull public android.bluetooth.OobData.LeBuilder setDeviceName(@NonNull byte[]); - method @NonNull public android.bluetooth.OobData.LeBuilder setLeFlags(int); - method @NonNull public android.bluetooth.OobData.LeBuilder setLeTemporaryKey(@NonNull byte[]); - method @NonNull public android.bluetooth.OobData.LeBuilder setRandomizerHash(@NonNull byte[]); - } - - public final class UidTraffic implements java.lang.Cloneable android.os.Parcelable { - method public long getRxBytes(); - method public long getTxBytes(); - method public int getUid(); - field @NonNull public static final android.os.Parcelable.Creator<android.bluetooth.UidTraffic> CREATOR; - } - -} - -package android.bluetooth.le { - - public final class AdvertiseSettings implements android.os.Parcelable { - method public int getOwnAddressType(); - } - - public static final class AdvertiseSettings.Builder { - method @NonNull public android.bluetooth.le.AdvertiseSettings.Builder setOwnAddressType(int); - } - - public final class AdvertisingSetParameters implements android.os.Parcelable { - method public int getOwnAddressType(); - field public static final int ADDRESS_TYPE_DEFAULT = -1; // 0xffffffff - field public static final int ADDRESS_TYPE_PUBLIC = 0; // 0x0 - field public static final int ADDRESS_TYPE_RANDOM = 1; // 0x1 - } - - public static final class AdvertisingSetParameters.Builder { - method @NonNull public android.bluetooth.le.AdvertisingSetParameters.Builder setOwnAddressType(int); - } - - public final class BluetoothLeScanner { - method @RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_SCAN, android.Manifest.permission.UPDATE_DEVICE_STATS}) public void startScanFromSource(android.os.WorkSource, android.bluetooth.le.ScanCallback); - method @RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_SCAN, android.Manifest.permission.UPDATE_DEVICE_STATS}) public void startScanFromSource(java.util.List<android.bluetooth.le.ScanFilter>, android.bluetooth.le.ScanSettings, android.os.WorkSource, android.bluetooth.le.ScanCallback); - method @Deprecated @RequiresPermission(android.Manifest.permission.BLUETOOTH_SCAN) public void startTruncatedScan(java.util.List<android.bluetooth.le.TruncatedFilter>, android.bluetooth.le.ScanSettings, android.bluetooth.le.ScanCallback); - } - - @Deprecated public final class ResultStorageDescriptor implements android.os.Parcelable { - ctor @Deprecated public ResultStorageDescriptor(int, int, int); - method @Deprecated public int describeContents(); - method @Deprecated public int getLength(); - method @Deprecated public int getOffset(); - method @Deprecated public int getType(); - method @Deprecated public void writeToParcel(android.os.Parcel, int); - field @Deprecated @NonNull public static final android.os.Parcelable.Creator<android.bluetooth.le.ResultStorageDescriptor> CREATOR; - } - - public final class ScanFilter implements android.os.Parcelable { - method public int getAddressType(); - method @Nullable public byte[] getIrk(); - } - - public static final class ScanFilter.Builder { - method @NonNull public android.bluetooth.le.ScanFilter.Builder setDeviceAddress(@NonNull String, int); - method @NonNull public android.bluetooth.le.ScanFilter.Builder setDeviceAddress(@NonNull String, int, @NonNull byte[]); - field public static final int LEN_IRK_OCTETS = 16; // 0x10 - } - - public final class ScanSettings implements android.os.Parcelable { - field public static final int SCAN_MODE_AMBIENT_DISCOVERY = 3; // 0x3 - field public static final int SCAN_RESULT_TYPE_ABBREVIATED = 1; // 0x1 - field public static final int SCAN_RESULT_TYPE_FULL = 0; // 0x0 - } - - public static final class ScanSettings.Builder { - method public android.bluetooth.le.ScanSettings.Builder setScanResultType(int); - } - - @Deprecated public final class TruncatedFilter { - ctor @Deprecated public TruncatedFilter(android.bluetooth.le.ScanFilter, java.util.List<android.bluetooth.le.ResultStorageDescriptor>); - method @Deprecated public android.bluetooth.le.ScanFilter getFilter(); - method @Deprecated public java.util.List<android.bluetooth.le.ResultStorageDescriptor> getStorageDescriptors(); - } - -} - package android.companion { public final class CompanionDeviceManager { @@ -12328,6 +11912,7 @@ package android.telephony { } public static class TelephonyManager.ModemActivityInfoException extends java.lang.Exception { + ctor public TelephonyManager.ModemActivityInfoException(int); method public int getErrorCode(); field public static final int ERROR_INVALID_INFO_RECEIVED = 2; // 0x2 field public static final int ERROR_MODEM_RESPONSE_ERROR = 3; // 0x3 @@ -13694,6 +13279,7 @@ package android.telephony.ims { field public static final int CAPABILITY_UPDATE_TRIGGER_MOVE_TO_3G = 6; // 0x6 field public static final int CAPABILITY_UPDATE_TRIGGER_MOVE_TO_EHRPD = 4; // 0x4 field public static final int CAPABILITY_UPDATE_TRIGGER_MOVE_TO_HSPAPLUS = 5; // 0x5 + field public static final int CAPABILITY_UPDATE_TRIGGER_MOVE_TO_INTERNET_PDN = 12; // 0xc field public static final int CAPABILITY_UPDATE_TRIGGER_MOVE_TO_IWLAN = 9; // 0x9 field public static final int CAPABILITY_UPDATE_TRIGGER_MOVE_TO_LTE_VOPS_DISABLED = 2; // 0x2 field public static final int CAPABILITY_UPDATE_TRIGGER_MOVE_TO_LTE_VOPS_ENABLED = 3; // 0x3 diff --git a/core/api/system-removed.txt b/core/api/system-removed.txt index 9a8a49397322..327bfef429ad 100644 --- a/core/api/system-removed.txt +++ b/core/api/system-removed.txt @@ -68,14 +68,6 @@ package android.app.search { } -package android.bluetooth { - - public final class BluetoothHeadset implements android.bluetooth.BluetoothProfile { - method @Deprecated @RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT, android.Manifest.permission.MODIFY_PHONE_STATE}) public boolean setPriority(android.bluetooth.BluetoothDevice, int); - } - -} - package android.content { public class Intent implements java.lang.Cloneable android.os.Parcelable { diff --git a/core/api/test-current.txt b/core/api/test-current.txt index d0e659bf36e9..18ceb2598766 100644 --- a/core/api/test-current.txt +++ b/core/api/test-current.txt @@ -675,14 +675,6 @@ package android.appwidget { } -package android.bluetooth { - - public final class BluetoothClass implements android.os.Parcelable { - method public int getClassOfDevice(); - } - -} - package android.content { public final class AttributionSource implements android.os.Parcelable { diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java index 3b0a5f3e9bdd..6d7835f84dc7 100644 --- a/core/java/android/app/ActivityThread.java +++ b/core/java/android/app/ActivityThread.java @@ -97,6 +97,7 @@ import android.media.MediaFrameworkPlatformInitializer; import android.media.MediaServiceManager; import android.net.ConnectivityManager; import android.net.Proxy; +import android.net.TrafficStats; import android.net.Uri; import android.os.AsyncTask; import android.os.Binder; @@ -6663,6 +6664,13 @@ public final class ActivityThread extends ClientTransactionHandler NetworkSecurityConfigProvider.install(appContext); Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER); + // For backward compatibility, TrafficStats needs static access to the application context. + // But for isolated apps which cannot access network related services, service discovery + // is restricted. Hence, calling this would result in NPE. + if (!Process.isIsolated()) { + TrafficStats.init(appContext); + } + // Continue loading instrumentation. if (ii != null) { initInstrumentation(ii, data, appContext); diff --git a/core/java/android/app/ActivityTransitionState.java b/core/java/android/app/ActivityTransitionState.java index 62619509184a..877e7d3b3bf7 100644 --- a/core/java/android/app/ActivityTransitionState.java +++ b/core/java/android/app/ActivityTransitionState.java @@ -119,7 +119,7 @@ class ActivityTransitionState { for (int i = mExitTransitionCoordinators.size() - 1; i >= 0; i--) { WeakReference<ExitTransitionCoordinator> oldRef = mExitTransitionCoordinators.valueAt(i); - if (oldRef.get() == null) { + if (oldRef.refersTo(null)) { mExitTransitionCoordinators.removeAt(i); } } diff --git a/core/java/android/app/ResourcesManager.java b/core/java/android/app/ResourcesManager.java index 198c33e83707..ab823983235c 100644 --- a/core/java/android/app/ResourcesManager.java +++ b/core/java/android/app/ResourcesManager.java @@ -678,8 +678,7 @@ public class ResourcesManager { int refCount = mResourceImpls.size(); for (int i = 0; i < refCount; i++) { WeakReference<ResourcesImpl> weakImplRef = mResourceImpls.valueAt(i); - ResourcesImpl impl = weakImplRef != null ? weakImplRef.get() : null; - if (resourceImpl == impl) { + if (weakImplRef != null && weakImplRef.refersTo(resourceImpl)) { return mResourceImpls.keyAt(i); } } @@ -1671,7 +1670,7 @@ public class ResourcesManager { for (int i = mResourceImpls.size() - 1; i >= 0; i--) { final ResourcesKey key = mResourceImpls.keyAt(i); final WeakReference<ResourcesImpl> impl = mResourceImpls.valueAt(i); - if (impl == null || impl.get() == null + if (impl == null || impl.refersTo(null) || !ArrayUtils.contains(key.mLoaders, loader)) { continue; } diff --git a/core/java/android/app/admin/DevicePolicyManager.java b/core/java/android/app/admin/DevicePolicyManager.java index 0fe80c45ad2a..3840f760eda8 100644 --- a/core/java/android/app/admin/DevicePolicyManager.java +++ b/core/java/android/app/admin/DevicePolicyManager.java @@ -10177,6 +10177,9 @@ public class DevicePolicyManager { * On fully-managed devices this method is unsupported because all traffic is considered * work traffic. * + * <p> This method enables preferential network service with a default configuration. + * To fine-tune the configuration, use {@link #setPreferentialNetworkServiceConfig) instead. + * * <p>This method can only be called by the profile owner of a managed profile. * @param enabled whether preferential network service should be enabled. * @throws SecurityException if the caller is not the profile owner. @@ -10215,6 +10218,56 @@ public class DevicePolicyManager { } /** + * Sets preferential network configuration on the work profile. + * {@see PreferentialNetworkServiceConfig} + * + * An example of a supported preferential network service is the Enterprise + * slice on 5G networks. + * + * By default, preferential network service is disabled on the work profile on supported + * carriers and devices. Admins can explicitly enable it with this API. + * On fully-managed devices this method is unsupported because all traffic is considered + * work traffic. + * + * <p>This method can only be called by the profile owner of a managed profile. + * @param preferentialNetworkServiceConfig preferential network configuration. + * @throws SecurityException if the caller is not the profile owner. + **/ + public void setPreferentialNetworkServiceConfig( + @NonNull PreferentialNetworkServiceConfig preferentialNetworkServiceConfig) { + throwIfParentInstance("setPreferentialNetworkServiceConfig"); + if (mService == null) { + return; + } + try { + mService.setPreferentialNetworkServiceConfig(preferentialNetworkServiceConfig); + } catch (RemoteException e) { + throw e.rethrowFromSystemServer(); + } + } + + /** + * Get preferential network configuration + * {@see PreferentialNetworkServiceConfig} + * + * <p>This method can be called by the profile owner of a managed profile. + * + * @return preferential network configuration. + * @throws SecurityException if the caller is not the profile owner. + */ + public @NonNull PreferentialNetworkServiceConfig getPreferentialNetworkServiceConfig() { + throwIfParentInstance("getPreferentialNetworkServiceConfig"); + if (mService == null) { + return PreferentialNetworkServiceConfig.DEFAULT; + } + try { + return mService.getPreferentialNetworkServiceConfig(); + } catch (RemoteException e) { + throw e.rethrowFromSystemServer(); + } + } + + /** * This method is mostly deprecated. * Most of the settings that still have an effect have dedicated setter methods or user * restrictions. See individual settings for details. diff --git a/core/java/android/app/admin/IDevicePolicyManager.aidl b/core/java/android/app/admin/IDevicePolicyManager.aidl index d287437b143b..c78a5a00f645 100644 --- a/core/java/android/app/admin/IDevicePolicyManager.aidl +++ b/core/java/android/app/admin/IDevicePolicyManager.aidl @@ -21,6 +21,7 @@ import android.app.admin.NetworkEvent; import android.app.IApplicationThread; import android.app.IServiceConnection; import android.app.admin.ParcelableGranteeMap; +import android.app.admin.PreferentialNetworkServiceConfig; import android.app.admin.StartInstallingUpdateCallback; import android.app.admin.SystemUpdateInfo; import android.app.admin.SystemUpdatePolicy; @@ -278,6 +279,10 @@ interface IDevicePolicyManager { void setPreferentialNetworkServiceEnabled(in boolean enabled); boolean isPreferentialNetworkServiceEnabled(int userHandle); + void setPreferentialNetworkServiceConfig( + in PreferentialNetworkServiceConfig preferentialNetworkServiceConfig); + PreferentialNetworkServiceConfig getPreferentialNetworkServiceConfig(); + void setLockTaskPackages(in ComponentName who, in String[] packages); String[] getLockTaskPackages(in ComponentName who); boolean isLockTaskPermitted(in String pkg); diff --git a/core/java/android/app/admin/PreferentialNetworkServiceConfig.aidl b/core/java/android/app/admin/PreferentialNetworkServiceConfig.aidl new file mode 100644 index 000000000000..6b6ee7d8d538 --- /dev/null +++ b/core/java/android/app/admin/PreferentialNetworkServiceConfig.aidl @@ -0,0 +1,20 @@ +/* +** +** Copyright 2022, The Android Open Source Project +** +** Licensed under the Apache License, Version 2.0 (the "License"); +** you may not use this file except in compliance with the License. +** You may obtain a copy of the License at +** +** http://www.apache.org/licenses/LICENSE-2.0 +** +** Unless required by applicable law or agreed to in writing, software +** distributed under the License is distributed on an "AS IS" BASIS, +** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +** See the License for the specific language governing permissions and +** limitations under the License. +*/ + +package android.app.admin; + +parcelable PreferentialNetworkServiceConfig;
\ No newline at end of file diff --git a/core/java/android/app/admin/PreferentialNetworkServiceConfig.java b/core/java/android/app/admin/PreferentialNetworkServiceConfig.java new file mode 100644 index 000000000000..2849139c606b --- /dev/null +++ b/core/java/android/app/admin/PreferentialNetworkServiceConfig.java @@ -0,0 +1,335 @@ +/* + * Copyright (C) 2022 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.app.admin; + +import android.annotation.IntDef; +import android.annotation.NonNull; +import android.annotation.SuppressLint; +import android.os.Parcel; +import android.os.Parcelable; + +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.util.Objects; + +/** + * Network configuration to be set for the user profile + * {@see DevicePolicyManager#setPreferentialNetworkServiceConfig}. + */ +public final class PreferentialNetworkServiceConfig implements Parcelable { + final boolean mIsEnabled; + final int mNetworkId; + final boolean mAllowFallbackToDefaultConnection; + final int[] mIncludedUids; + final int[] mExcludedUids; + + /** @hide */ + public static final PreferentialNetworkServiceConfig DEFAULT = + (new PreferentialNetworkServiceConfig.Builder()).build(); + + /** + * Preferential network identifier 1. + */ + public static final int PREFERENTIAL_NETWORK_ID_1 = 1; + + /** + * Preferential network identifier 2. + */ + public static final int PREFERENTIAL_NETWORK_ID_2 = 2; + + /** + * Preferential network identifier 3. + */ + public static final int PREFERENTIAL_NETWORK_ID_3 = 3; + + /** + * Preferential network identifier 4. + */ + public static final int PREFERENTIAL_NETWORK_ID_4 = 4; + + /** + * Preferential network identifier 5. + */ + public static final int PREFERENTIAL_NETWORK_ID_5 = 5; + + /** @hide */ + @Retention(RetentionPolicy.SOURCE) + @IntDef(prefix = { "PREFERENTIAL_NETWORK_ID_" }, value = { + PREFERENTIAL_NETWORK_ID_1, + PREFERENTIAL_NETWORK_ID_2, + PREFERENTIAL_NETWORK_ID_3, + PREFERENTIAL_NETWORK_ID_4, + PREFERENTIAL_NETWORK_ID_5, + }) + + public @interface PreferentialNetworkPreferenceId { + } + + private PreferentialNetworkServiceConfig(boolean isEnabled, + boolean allowFallbackToDefaultConnection, int[] includedUids, + int[] excludedUids, @PreferentialNetworkPreferenceId int networkId) { + mIsEnabled = isEnabled; + mAllowFallbackToDefaultConnection = allowFallbackToDefaultConnection; + mIncludedUids = includedUids; + mExcludedUids = excludedUids; + mNetworkId = networkId; + } + + private PreferentialNetworkServiceConfig(Parcel in) { + mIsEnabled = in.readBoolean(); + mAllowFallbackToDefaultConnection = in.readBoolean(); + mNetworkId = in.readInt(); + mIncludedUids = in.createIntArray(); + mExcludedUids = in.createIntArray(); + } + + /** + * Is the preferential network enabled. + * @return true if enabled else false + */ + public boolean isEnabled() { + return mIsEnabled; + } + + /** + * is fallback to default network allowed. This boolean configures whether default connection + * (default internet or wifi) should be used or not if a preferential network service + * connection is not available. + * @return true if fallback is allowed, else false. + */ + public boolean isFallbackToDefaultConnectionAllowed() { + return mAllowFallbackToDefaultConnection; + } + + /** + * Get the array of uids that are applicable for the profile preference. + * + * {@see #getExcludedUids()} + * Included UIDs and Excluded UIDs can't both be non-empty. + * if both are empty, it means this request applies to all uids in the user profile. + * if included is not empty, then only included UIDs are applied. + * if excluded is not empty, then it is all uids in the user profile except these UIDs. + * @return Array of uids applicable for the profile preference. + * Empty array would mean that this request applies to all uids in the profile. + */ + public @NonNull int[] getIncludedUids() { + return mIncludedUids; + } + + /** + * Get the array of uids that are excluded for the profile preference. + * + * {@see #getIncludedUids()} + * Included UIDs and Excluded UIDs can't both be non-empty. + * if both are empty, it means this request applies to all uids in the user profile. + * if included is not empty, then only included UIDs are applied. + * if excluded is not empty, then it is all uids in the user profile except these UIDs. + * @return Array of uids that are excluded for the profile preference. + * Empty array would mean that this request applies to all uids in the profile. + */ + public @NonNull int[] getExcludedUids() { + return mExcludedUids; + } + + /** + * @return preference enterprise identifier. + * valid values starts from + * {@link #PREFERENTIAL_NETWORK_ID_1} to {@link #PREFERENTIAL_NETWORK_ID_5}. + * preference identifier is applicable only if preference network service is enabled + * + */ + public @PreferentialNetworkPreferenceId int getNetworkId() { + return mNetworkId; + } + + @Override + public String toString() { + return "PreferentialNetworkServiceConfig{" + + "mIsEnabled=" + isEnabled() + + "mAllowFallbackToDefaultConnection=" + isFallbackToDefaultConnectionAllowed() + + "mIncludedUids=" + mIncludedUids.toString() + + "mExcludedUids=" + mExcludedUids.toString() + + "mNetworkId=" + mNetworkId + + '}'; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + final PreferentialNetworkServiceConfig that = (PreferentialNetworkServiceConfig) o; + return mIsEnabled == that.mIsEnabled + && mAllowFallbackToDefaultConnection == that.mAllowFallbackToDefaultConnection + && mNetworkId == that.mNetworkId + && Objects.equals(mIncludedUids, that.mIncludedUids) + && Objects.equals(mExcludedUids, that.mExcludedUids); + } + + @Override + public int hashCode() { + return ((Objects.hashCode(mIsEnabled) * 17) + + (Objects.hashCode(mAllowFallbackToDefaultConnection) * 19) + + (Objects.hashCode(mIncludedUids) * 23) + + (Objects.hashCode(mExcludedUids) * 29) + + mNetworkId * 31); + } + + /** + * Builder used to create {@link PreferentialNetworkServiceConfig} objects. + * Specify the preferred Network preference + */ + public static final class Builder { + boolean mIsEnabled = false; + int mNetworkId = 0; + boolean mAllowFallbackToDefaultConnection = true; + int[] mIncludedUids = new int[0]; + int[] mExcludedUids = new int[0]; + + /** + * Constructs an empty Builder with preferential network disabled by default. + */ + public Builder() {} + + /** + * Set the preferential network service enabled state. + * Default value is false. + * @param isEnabled the desired network preference to use, true to enable else false + * @return The builder to facilitate chaining. + */ + @NonNull + public PreferentialNetworkServiceConfig.Builder setEnabled(boolean isEnabled) { + mIsEnabled = isEnabled; + return this; + } + + /** + * Set whether the default connection should be used as fallback. + * This boolean configures whether the default connection (default internet or wifi) + * should be used if a preferential network service connection is not available. + * Default value is true + * @param allowFallbackToDefaultConnection true if fallback is allowed else false + * @return The builder to facilitate chaining. + */ + @NonNull + @SuppressLint("MissingGetterMatchingBuilder") + public PreferentialNetworkServiceConfig.Builder setFallbackToDefaultConnectionAllowed( + boolean allowFallbackToDefaultConnection) { + mAllowFallbackToDefaultConnection = allowFallbackToDefaultConnection; + return this; + } + + /** + * Set the array of uids whose network access will go through this preferential + * network service. + * {@see #setExcludedUids(int[])} + * Included UIDs and Excluded UIDs can't both be non-empty. + * if both are empty, it means this request applies to all uids in the user profile. + * if included is not empty, then only included UIDs are applied. + * if excluded is not empty, then it is all uids in the user profile except these UIDs. + * @param uids array of included uids + * @return The builder to facilitate chaining. + */ + @NonNull + public PreferentialNetworkServiceConfig.Builder setIncludedUids( + @NonNull int[] uids) { + Objects.requireNonNull(uids); + mIncludedUids = uids; + return this; + } + + /** + * Set the array of uids who are not allowed through this preferential + * network service. + * {@see #setIncludedUids(int[])} + * Included UIDs and Excluded UIDs can't both be non-empty. + * if both are empty, it means this request applies to all uids in the user profile. + * if included is not empty, then only included UIDs are applied. + * if excluded is not empty, then it is all uids in the user profile except these UIDs. + * @param uids array of excluded uids + * @return The builder to facilitate chaining. + */ + @NonNull + public PreferentialNetworkServiceConfig.Builder setExcludedUids( + @NonNull int[] uids) { + Objects.requireNonNull(uids); + mExcludedUids = uids; + return this; + } + + /** + * Returns an instance of {@link PreferentialNetworkServiceConfig} created from the + * fields set on this builder. + */ + @NonNull + public PreferentialNetworkServiceConfig build() { + if (mIncludedUids.length > 0 && mExcludedUids.length > 0) { + throw new IllegalStateException("Both includedUids and excludedUids " + + "cannot be nonempty"); + } + return new PreferentialNetworkServiceConfig(mIsEnabled, + mAllowFallbackToDefaultConnection, mIncludedUids, mExcludedUids, mNetworkId); + } + + /** + * Set the preferential network identifier. + * Valid values starts from {@link #PREFERENTIAL_NETWORK_ID_1} to + * {@link #PREFERENTIAL_NETWORK_ID_5}. + * preference identifier is applicable only if preferential network service is enabled. + * @param preferenceId preference Id + * @return The builder to facilitate chaining. + */ + @NonNull + public PreferentialNetworkServiceConfig.Builder setNetworkId( + @PreferentialNetworkPreferenceId int preferenceId) { + if ((preferenceId < PREFERENTIAL_NETWORK_ID_1) + || (preferenceId > PREFERENTIAL_NETWORK_ID_5)) { + throw new IllegalArgumentException("Invalid preference identifier"); + } + mNetworkId = preferenceId; + return this; + } + } + + @Override + public void writeToParcel(@NonNull android.os.Parcel dest, int flags) { + dest.writeBoolean(mIsEnabled); + dest.writeBoolean(mAllowFallbackToDefaultConnection); + dest.writeInt(mNetworkId); + dest.writeIntArray(mIncludedUids); + dest.writeIntArray(mExcludedUids); + } + + @Override + public int describeContents() { + return 0; + } + + @NonNull + public static final Creator<PreferentialNetworkServiceConfig> CREATOR = + new Creator<PreferentialNetworkServiceConfig>() { + @Override + public PreferentialNetworkServiceConfig[] newArray(int size) { + return new PreferentialNetworkServiceConfig[size]; + } + + @Override + public PreferentialNetworkServiceConfig createFromParcel( + @NonNull android.os.Parcel in) { + return new PreferentialNetworkServiceConfig(in); + } + }; +} diff --git a/core/java/android/app/wallpapereffectsgeneration/OWNERS b/core/java/android/app/wallpapereffectsgeneration/OWNERS new file mode 100644 index 000000000000..2bc01541a939 --- /dev/null +++ b/core/java/android/app/wallpapereffectsgeneration/OWNERS @@ -0,0 +1,5 @@ +susharon@google.com +shanh@google.com +huiwu@google.com +srazdan@google.com + diff --git a/core/java/android/content/res/ColorStateList.java b/core/java/android/content/res/ColorStateList.java index 5b727cc47d47..5031faa81afa 100644 --- a/core/java/android/content/res/ColorStateList.java +++ b/core/java/android/content/res/ColorStateList.java @@ -198,7 +198,7 @@ public class ColorStateList extends ComplexColor implements Parcelable { // Prune the cache before adding new items. final int N = sCache.size(); for (int i = N - 1; i >= 0; i--) { - if (sCache.valueAt(i).get() == null) { + if (sCache.valueAt(i).refersTo(null)) { sCache.removeAt(i); } } diff --git a/core/java/android/content/res/Resources.java b/core/java/android/content/res/Resources.java index 12e41e299e16..932cc8e402e1 100644 --- a/core/java/android/content/res/Resources.java +++ b/core/java/android/content/res/Resources.java @@ -2011,7 +2011,7 @@ public class Resources { // Clean up references to garbage collected themes if (mThemeRefs.size() > mThemeRefsNextFlushSize) { - mThemeRefs.removeIf(ref -> ref.get() == null); + mThemeRefs.removeIf(ref -> ref.refersTo(null)); mThemeRefsNextFlushSize = Math.max(MIN_THEME_REFS_FLUSH_SIZE, 2 * mThemeRefs.size()); } diff --git a/core/java/android/content/res/loader/ResourcesLoader.java b/core/java/android/content/res/loader/ResourcesLoader.java index c3084003c304..cf6e166b82ed 100644 --- a/core/java/android/content/res/loader/ResourcesLoader.java +++ b/core/java/android/content/res/loader/ResourcesLoader.java @@ -257,7 +257,7 @@ public class ResourcesLoader { for (int i = mChangeCallbacks.size() - 1; i >= 0; i--) { final WeakReference<Object> key = mChangeCallbacks.keyAt(i); - if (key.get() == null) { + if (key.refersTo(null)) { mChangeCallbacks.removeAt(i); } else { uniqueCallbacks.add(mChangeCallbacks.valueAt(i)); diff --git a/core/java/android/net/Ikev2VpnProfile.java b/core/java/android/net/Ikev2VpnProfile.java index 55541377a0bf..036607be2b5d 100644 --- a/core/java/android/net/Ikev2VpnProfile.java +++ b/core/java/android/net/Ikev2VpnProfile.java @@ -25,6 +25,12 @@ import static android.net.IpSecAlgorithm.AUTH_HMAC_SHA384; import static android.net.IpSecAlgorithm.AUTH_HMAC_SHA512; import static android.net.IpSecAlgorithm.CRYPT_AES_CBC; import static android.net.IpSecAlgorithm.CRYPT_AES_CTR; +import static android.net.eap.EapSessionConfig.EapMsChapV2Config; +import static android.net.ipsec.ike.IkeSessionParams.IkeAuthConfig; +import static android.net.ipsec.ike.IkeSessionParams.IkeAuthDigitalSignLocalConfig; +import static android.net.ipsec.ike.IkeSessionParams.IkeAuthDigitalSignRemoteConfig; +import static android.net.ipsec.ike.IkeSessionParams.IkeAuthEapConfig; +import static android.net.ipsec.ike.IkeSessionParams.IkeAuthPskConfig; import static com.android.internal.annotations.VisibleForTesting.Visibility; import static com.android.internal.util.Preconditions.checkStringNotEmpty; @@ -34,6 +40,14 @@ import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.RequiresFeature; import android.content.pm.PackageManager; +import android.net.ipsec.ike.IkeFqdnIdentification; +import android.net.ipsec.ike.IkeIdentification; +import android.net.ipsec.ike.IkeIpv4AddrIdentification; +import android.net.ipsec.ike.IkeIpv6AddrIdentification; +import android.net.ipsec.ike.IkeKeyIdIdentification; +import android.net.ipsec.ike.IkeRfc822AddrIdentification; +import android.net.ipsec.ike.IkeSessionParams; +import android.net.ipsec.ike.IkeTunnelConnectionParams; import android.security.Credentials; import android.util.Log; @@ -644,6 +658,102 @@ public final class Ikev2VpnProfile extends PlatformVpnProfile { return Objects.requireNonNull(reference, String.format(messageTemplate, messageArgs)); } + private static void checkBuilderSetter(boolean constructedFromIkeTunConParams, + @NonNull String message) { + if (constructedFromIkeTunConParams) { + throw new IllegalArgumentException("Constructed using IkeTunnelConnectionParams " + + "should not set " + message); + } + } + + private static int getTypeFromIkeSession(@NonNull IkeSessionParams params) { + final IkeAuthConfig config = params.getLocalAuthConfig(); + if (config instanceof IkeAuthDigitalSignLocalConfig) { + return TYPE_IKEV2_IPSEC_RSA; + } else if (config instanceof IkeAuthEapConfig) { + return TYPE_IKEV2_IPSEC_USER_PASS; + } else if (config instanceof IkeAuthPskConfig) { + return TYPE_IKEV2_IPSEC_PSK; + } else { + throw new IllegalStateException("Invalid local IkeAuthConfig"); + } + } + + @Nullable + private static String getPasswordFromIkeSession(@NonNull IkeSessionParams params) { + if (!(params.getLocalAuthConfig() instanceof IkeAuthEapConfig)) return null; + + final IkeAuthEapConfig ikeAuthEapConfig = (IkeAuthEapConfig) params.getLocalAuthConfig(); + final EapMsChapV2Config eapMsChapV2Config = + ikeAuthEapConfig.getEapConfig().getEapMsChapV2Config(); + return (eapMsChapV2Config != null) ? eapMsChapV2Config.getPassword() : null; + } + + @Nullable + private static String getUsernameFromIkeSession(@NonNull IkeSessionParams params) { + if (!(params.getLocalAuthConfig() instanceof IkeAuthEapConfig)) return null; + + final IkeAuthEapConfig ikeAuthEapConfig = (IkeAuthEapConfig) params.getLocalAuthConfig(); + final EapMsChapV2Config eapMsChapV2Config = + ikeAuthEapConfig.getEapConfig().getEapMsChapV2Config(); + return (eapMsChapV2Config != null) ? eapMsChapV2Config.getUsername() : null; + } + + @Nullable + private static X509Certificate getUserCertFromIkeSession(@NonNull IkeSessionParams params) { + if (!(params.getLocalAuthConfig() instanceof IkeAuthDigitalSignLocalConfig)) return null; + + final IkeAuthDigitalSignLocalConfig config = + (IkeAuthDigitalSignLocalConfig) params.getLocalAuthConfig(); + return config.getClientEndCertificate(); + } + + @Nullable + private static X509Certificate getServerRootCaCertFromIkeSession( + @NonNull IkeSessionParams params) { + if (!(params.getRemoteAuthConfig() instanceof IkeAuthDigitalSignRemoteConfig)) return null; + + final IkeAuthDigitalSignRemoteConfig config = + (IkeAuthDigitalSignRemoteConfig) params.getRemoteAuthConfig(); + return config.getRemoteCaCert(); + } + + @Nullable + private static PrivateKey getRsaPrivateKeyFromIkeSession(@NonNull IkeSessionParams params) { + if (!(params.getLocalAuthConfig() instanceof IkeAuthDigitalSignLocalConfig)) return null; + + final IkeAuthDigitalSignLocalConfig config = + (IkeAuthDigitalSignLocalConfig) params.getLocalAuthConfig(); + return config.getPrivateKey(); + } + + @Nullable + private static byte[] getPresharedKeyFromIkeSession(@NonNull IkeSessionParams params) { + if (!(params.getLocalAuthConfig() instanceof IkeAuthPskConfig)) return null; + + final IkeAuthPskConfig config = (IkeAuthPskConfig) params.getLocalAuthConfig(); + return config.getPsk(); + } + + @NonNull + private static String getUserIdentityFromIkeSession(@NonNull IkeSessionParams params) { + final IkeIdentification ident = params.getLocalIdentification(); + // Refer to VpnIkev2Utils.parseIkeIdentification(). + if (ident instanceof IkeKeyIdIdentification) { + return "@#" + new String(((IkeKeyIdIdentification) ident).keyId); + } else if (ident instanceof IkeRfc822AddrIdentification) { + return "@@" + ((IkeRfc822AddrIdentification) ident).rfc822Name; + } else if (ident instanceof IkeFqdnIdentification) { + return "@" + ((IkeFqdnIdentification) ident).fqdn; + } else if (ident instanceof IkeIpv4AddrIdentification) { + return ((IkeIpv4AddrIdentification) ident).ipv4Address.getHostAddress(); + } else if (ident instanceof IkeIpv6AddrIdentification) { + return ((IkeIpv6AddrIdentification) ident).ipv6Address.getHostAddress(); + } else { + throw new IllegalArgumentException("Unknown IkeIdentification to get user identity"); + } + } + /** A incremental builder for IKEv2 VPN profiles */ public static final class Builder { private int mType = -1; @@ -671,6 +781,7 @@ public final class Ikev2VpnProfile extends PlatformVpnProfile { private int mMaxMtu = PlatformVpnProfile.MAX_MTU_DEFAULT; private boolean mIsRestrictedToTestNetworks = false; private boolean mExcludeLocalRoutes = false; + @Nullable private IkeTunnelConnectionParams mIkeTunConnParams; /** * Creates a new builder with the basic parameters of an IKEv2/IPsec VPN. @@ -687,6 +798,32 @@ public final class Ikev2VpnProfile extends PlatformVpnProfile { mUserIdentity = identity; } + /** + * Creates a new builder from a {@link IkeTunnelConnectionParams} + * + * @param ikeTunConnParams the {@link IkeTunnelConnectionParams} contains IKEv2 + * configurations + */ + @RequiresFeature(PackageManager.FEATURE_IPSEC_TUNNELS) + public Builder(@NonNull IkeTunnelConnectionParams ikeTunConnParams) { + checkNotNull(ikeTunConnParams, MISSING_PARAM_MSG_TMPL, "ikeTunConnParams"); + + mIkeTunConnParams = ikeTunConnParams; + + final IkeSessionParams ikeSessionParams = mIkeTunConnParams.getIkeSessionParams(); + mServerAddr = ikeSessionParams.getServerHostname(); + + mType = getTypeFromIkeSession(ikeSessionParams); + mUserCert = getUserCertFromIkeSession(ikeSessionParams); + mServerRootCaCert = getServerRootCaCertFromIkeSession(ikeSessionParams); + mRsaPrivateKey = getRsaPrivateKeyFromIkeSession(ikeSessionParams); + mServerRootCaCert = getServerRootCaCertFromIkeSession(ikeSessionParams); + mUsername = getUsernameFromIkeSession(ikeSessionParams); + mPassword = getPasswordFromIkeSession(ikeSessionParams); + mPresharedKey = getPresharedKeyFromIkeSession(ikeSessionParams); + mUserIdentity = getUserIdentityFromIkeSession(ikeSessionParams); + } + private void resetAuthParams() { mPresharedKey = null; mServerRootCaCert = null; @@ -719,6 +856,7 @@ public final class Ikev2VpnProfile extends PlatformVpnProfile { @Nullable X509Certificate serverRootCa) { checkNotNull(user, MISSING_PARAM_MSG_TMPL, "user"); checkNotNull(pass, MISSING_PARAM_MSG_TMPL, "pass"); + checkBuilderSetter(mIkeTunConnParams != null, "authUsernamePassword"); // Test to make sure all auth params can be encoded safely. if (serverRootCa != null) checkCert(serverRootCa); @@ -755,6 +893,7 @@ public final class Ikev2VpnProfile extends PlatformVpnProfile { @Nullable X509Certificate serverRootCa) { checkNotNull(userCert, MISSING_PARAM_MSG_TMPL, "userCert"); checkNotNull(key, MISSING_PARAM_MSG_TMPL, "key"); + checkBuilderSetter(mIkeTunConnParams != null, "authDigitalSignature"); // Test to make sure all auth params can be encoded safely. checkCert(userCert); @@ -782,6 +921,7 @@ public final class Ikev2VpnProfile extends PlatformVpnProfile { @RequiresFeature(PackageManager.FEATURE_IPSEC_TUNNELS) public Builder setAuthPsk(@NonNull byte[] psk) { checkNotNull(psk, MISSING_PARAM_MSG_TMPL, "psk"); + checkBuilderSetter(mIkeTunConnParams != null, "authPsk"); resetAuthParams(); mPresharedKey = psk; @@ -931,8 +1071,6 @@ public final class Ikev2VpnProfile extends PlatformVpnProfile { * * Note that because the local traffic will always bypass the VPN, * it is not possible to set this flag on a non-bypassable VPN. - * - * @hide TODO(184750836): unhide once the implementation is completed */ @NonNull @RequiresFeature(PackageManager.FEATURE_IPSEC_TUNNELS) diff --git a/core/java/android/net/LocalServerSocket.java b/core/java/android/net/LocalServerSocket.java index d1f49d2082f5..506cbcb0623d 100644 --- a/core/java/android/net/LocalServerSocket.java +++ b/core/java/android/net/LocalServerSocket.java @@ -55,7 +55,9 @@ public class LocalServerSocket implements Closeable { * Create a LocalServerSocket from a file descriptor that's already * been created and bound. listen() will be called immediately on it. * Used for cases where file descriptors are passed in via environment - * variables + * variables. The passed-in FileDescriptor is not managed by this class + * and must be closed by the caller. Calling {@link #close()} on a socket + * created by this method has no effect. * * @param fd bound file descriptor * @throws IOException diff --git a/core/java/android/net/LocalSocket.java b/core/java/android/net/LocalSocket.java index 5b38f78782a8..b69410cf7d73 100644 --- a/core/java/android/net/LocalSocket.java +++ b/core/java/android/net/LocalSocket.java @@ -16,7 +16,14 @@ package android.net; +import static android.annotation.SystemApi.Client.MODULE_LIBRARIES; + +import android.annotation.NonNull; +import android.annotation.SuppressLint; +import android.annotation.SystemApi; import android.compat.annotation.UnsupportedAppUsage; +import android.system.ErrnoException; +import android.system.Os; import java.io.Closeable; import java.io.FileDescriptor; @@ -74,32 +81,39 @@ public class LocalSocket implements Closeable { this.isBound = false; } + private void checkConnected() { + try { + Os.getpeername(impl.getFileDescriptor()); + } catch (ErrnoException e) { + throw new IllegalArgumentException("Not a connected socket", e); + } + isConnected = true; + isBound = true; + implCreated = true; + } + /** - * Creates a LocalSocket instances using the FileDescriptor for an already-connected - * AF_LOCAL/UNIX domain stream socket. Note: the FileDescriptor must be closed by the caller: - * closing the LocalSocket will not close it. + * Creates a LocalSocket instance using the {@link FileDescriptor} for an already-connected + * AF_LOCAL/UNIX domain stream socket. The passed-in FileDescriptor is not managed by this class + * and must be closed by the caller. Calling {@link #close()} on a socket created by this + * method has no effect. + * + * @param fd the filedescriptor to adopt * - * @hide - used by BluetoothSocket. + * @hide */ - public static LocalSocket createConnectedLocalSocket(FileDescriptor fd) { - return createConnectedLocalSocket(new LocalSocketImpl(fd), SOCKET_UNKNOWN); + @SystemApi(client = MODULE_LIBRARIES) + public LocalSocket(@NonNull @SuppressLint("UseParcelFileDescriptor") FileDescriptor fd) { + this(new LocalSocketImpl(fd), SOCKET_UNKNOWN); + checkConnected(); } /** * for use with LocalServerSocket.accept() */ static LocalSocket createLocalSocketForAccept(LocalSocketImpl impl) { - return createConnectedLocalSocket(impl, SOCKET_UNKNOWN); - } - - /** - * Creates a LocalSocket from an existing LocalSocketImpl that is already connected. - */ - private static LocalSocket createConnectedLocalSocket(LocalSocketImpl impl, int sockType) { - LocalSocket socket = new LocalSocket(impl, sockType); - socket.isConnected = true; - socket.isBound = true; - socket.implCreated = true; + LocalSocket socket = new LocalSocket(impl, SOCKET_UNKNOWN); + socket.checkConnected(); return socket; } diff --git a/core/java/android/net/PlatformVpnProfile.java b/core/java/android/net/PlatformVpnProfile.java index 777a90c8985c..3c45799e10f2 100644 --- a/core/java/android/net/PlatformVpnProfile.java +++ b/core/java/android/net/PlatformVpnProfile.java @@ -83,8 +83,6 @@ public abstract class PlatformVpnProfile { /** * Returns if the local traffic is exempted from the VPN. - * - * @hide TODO(184750836): unhide once the implementation is completed */ public final boolean getExcludeLocalRoutes() { return mExcludeLocalRoutes; diff --git a/core/java/android/net/netstats/NetworkStatsDataMigrationUtils.java b/core/java/android/net/netstats/NetworkStatsDataMigrationUtils.java new file mode 100644 index 000000000000..24c22a99b78d --- /dev/null +++ b/core/java/android/net/netstats/NetworkStatsDataMigrationUtils.java @@ -0,0 +1,520 @@ +/* + * Copyright (C) 2022 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.net.netstats; + +import static android.app.usage.NetworkStatsManager.PREFIX_UID; +import static android.app.usage.NetworkStatsManager.PREFIX_UID_TAG; +import static android.app.usage.NetworkStatsManager.PREFIX_XT; +import static android.net.ConnectivityManager.TYPE_MOBILE; +import static android.net.ConnectivityManager.TYPE_MOBILE_DUN; +import static android.net.ConnectivityManager.TYPE_MOBILE_HIPRI; +import static android.net.ConnectivityManager.TYPE_MOBILE_MMS; +import static android.net.ConnectivityManager.TYPE_MOBILE_SUPL; +import static android.net.NetworkStats.SET_DEFAULT; +import static android.net.NetworkStats.TAG_NONE; + +import android.annotation.NonNull; +import android.net.NetworkIdentity; +import android.net.NetworkStatsCollection; +import android.net.NetworkStatsHistory; +import android.net.NetworkTemplate; +import android.os.Environment; +import android.util.AtomicFile; + +import com.android.internal.annotations.VisibleForTesting; +import com.android.internal.util.FastDataInput; + +import libcore.io.IoUtils; + +import java.io.BufferedInputStream; +import java.io.DataInput; +import java.io.DataInputStream; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.net.ProtocolException; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Set; + +/** + * Helper class to read old version of persistent network statistics, the implementation is + * intended to be modified by OEM partners to accommodate their custom changes. + * @hide + */ +// @SystemApi(client = MODULE_LIBRARIES) +public class NetworkStatsDataMigrationUtils { + + private static final HashMap<String, String> sPrefixLegacyFileNameMap = + new HashMap<String, String>() {{ + put(PREFIX_XT, "netstats_xt.bin"); + put(PREFIX_UID, "netstats_uid.bin"); + put(PREFIX_UID_TAG, "netstats_uid.bin"); + }}; + + // These version constants are copied from NetworkStatsCollection/History, which is okay for + // OEMs to modify to adapt their own logic. + private static class CollectionVersion { + static final int VERSION_NETWORK_INIT = 1; + + static final int VERSION_UID_INIT = 1; + static final int VERSION_UID_WITH_IDENT = 2; + static final int VERSION_UID_WITH_TAG = 3; + static final int VERSION_UID_WITH_SET = 4; + + static final int VERSION_UNIFIED_INIT = 16; + } + + private static class HistoryVersion { + static final int VERSION_INIT = 1; + static final int VERSION_ADD_PACKETS = 2; + static final int VERSION_ADD_ACTIVE = 3; + } + + private static class IdentitySetVersion { + static final int VERSION_INIT = 1; + static final int VERSION_ADD_ROAMING = 2; + static final int VERSION_ADD_NETWORK_ID = 3; + static final int VERSION_ADD_METERED = 4; + static final int VERSION_ADD_DEFAULT_NETWORK = 5; + static final int VERSION_ADD_OEM_MANAGED_NETWORK = 6; + } + + /** + * File header magic number: "ANET". The definition is copied from NetworkStatsCollection, + * but it is fine for OEM to re-define to their own value to adapt the legacy file reading + * logic. + */ + private static final int FILE_MAGIC = 0x414E4554; + /** Default buffer size from BufferedInputStream */ + private static final int BUFFER_SIZE = 8192; + + // Constructing this object is not allowed. + private NetworkStatsDataMigrationUtils() { + } + + // Used to read files at /data/system/netstats_*.bin. + @NonNull + private static File getPlatformSystemDir() { + return new File(Environment.getDataDirectory(), "system"); + } + + // Used to read files at /data/system/netstats/<tag>.<start>-<end>. + @NonNull + private static File getPlatformBaseDir() { + File baseDir = new File(getPlatformSystemDir(), "netstats"); + baseDir.mkdirs(); + return baseDir; + } + + // Get /data/system/netstats_*.bin legacy files. Does not check for existence. + @NonNull + private static File getLegacyBinFileForPrefix(@NonNull String prefix) { + return new File(getPlatformSystemDir(), sPrefixLegacyFileNameMap.get(prefix)); + } + + // List /data/system/netstats/[xt|uid|uid_tag].<start>-<end> legacy files. + @NonNull + private static ArrayList<File> getPlatformFileListForPrefix(@NonNull String prefix) { + final ArrayList<File> list = new ArrayList<>(); + final File platformFiles = new File(getPlatformBaseDir(), "netstats"); + if (platformFiles.exists()) { + for (String name : platformFiles.list()) { + // Skip when prefix doesn't match. + if (!name.startsWith(prefix + ".")) continue; + + list.add(new File(platformFiles, name)); + } + } + return list; + } + + /** + * Read legacy persisted network stats from disk. This function provides a default + * implementation to read persisted network stats from two different locations. + * And this is intended to be modified by OEM to read from custom file format or + * locations if necessary. + * + * @param prefix Type of data which is being read by the service. + * @param bucketDuration Duration of the buckets of the object, in milliseconds. + * @return {@link NetworkStatsCollection} instance. + */ + @NonNull + public static NetworkStatsCollection readPlatformCollectionLocked( + @NonNull String prefix, long bucketDuration) throws IOException { + final NetworkStatsCollection.Builder builder = + new NetworkStatsCollection.Builder(bucketDuration); + + // Import /data/system/netstats_uid.bin legacy files if exists. + switch (prefix) { + case PREFIX_UID: + case PREFIX_UID_TAG: + final File uidFile = getLegacyBinFileForPrefix(prefix); + if (uidFile.exists()) { + readLegacyUid(builder, uidFile, PREFIX_UID_TAG.equals(prefix) ? true : false); + } + break; + default: + // Ignore other types. + } + + // Import /data/system/netstats/[xt|uid|uid_tag].<start>-<end> legacy files if exists. + final ArrayList<File> platformFiles = getPlatformFileListForPrefix(prefix); + for (final File platformFile : platformFiles) { + if (platformFile.exists()) { + readPlatformCollection(builder, platformFile); + } + } + + return builder.build(); + } + + private static void readPlatformCollection(@NonNull NetworkStatsCollection.Builder builder, + @NonNull File file) throws IOException { + final FileInputStream is = new FileInputStream(file); + final FastDataInput dataIn = new FastDataInput(is, BUFFER_SIZE); + try { + readPlatformCollection(builder, dataIn); + } finally { + IoUtils.closeQuietly(dataIn); + } + } + + /** + * Helper function to read old version of NetworkStatsCollections that resided in the platform. + * + * @hide + */ + @VisibleForTesting + public static void readPlatformCollection(@NonNull NetworkStatsCollection.Builder builder, + @NonNull DataInput in) throws IOException { + // verify file magic header intact + final int magic = in.readInt(); + if (magic != FILE_MAGIC) { + throw new ProtocolException("unexpected magic: " + magic); + } + + final int version = in.readInt(); + switch (version) { + case CollectionVersion.VERSION_UNIFIED_INIT: { + // uid := size *(NetworkIdentitySet size *(uid set tag NetworkStatsHistory)) + final int identSize = in.readInt(); + for (int i = 0; i < identSize; i++) { + final Set<NetworkIdentity> ident = readPlatformNetworkIdentitySet(in); + + final int size = in.readInt(); + for (int j = 0; j < size; j++) { + final int uid = in.readInt(); + final int set = in.readInt(); + final int tag = in.readInt(); + + final NetworkStatsCollection.Key key = new NetworkStatsCollection.Key( + ident, uid, set, tag); + final NetworkStatsHistory history = readPlatformHistory(in); + builder.addEntry(key, history); + } + } + break; + } + default: { + throw new ProtocolException("unexpected version: " + version); + } + } + } + + // Copied from NetworkStatsHistory#DataStreamUtils. + private static long[] readFullLongArray(DataInput in) throws IOException { + final int size = in.readInt(); + if (size < 0) throw new ProtocolException("negative array size"); + final long[] values = new long[size]; + for (int i = 0; i < values.length; i++) { + values[i] = in.readLong(); + } + return values; + } + + // Copied from NetworkStatsHistory#DataStreamUtils. + private static long[] readVarLongArray(@NonNull DataInput in) throws IOException { + final int size = in.readInt(); + if (size == -1) return null; + if (size < 0) throw new ProtocolException("negative array size"); + final long[] values = new long[size]; + for (int i = 0; i < values.length; i++) { + values[i] = readVarLong(in); + } + return values; + } + + /** + * Read variable-length {@link Long} using protobuf-style approach. + */ + // Copied from NetworkStatsHistory#DataStreamUtils. + private static long readVarLong(DataInput in) throws IOException { + int shift = 0; + long result = 0; + while (shift < 64) { + byte b = in.readByte(); + result |= (long) (b & 0x7F) << shift; + if ((b & 0x80) == 0) { + return result; + } + shift += 7; + } + throw new ProtocolException("malformed var long"); + } + + // Copied from NetworkIdentitySet. + private static String readOptionalString(DataInput in) throws IOException { + if (in.readByte() != 0) { + return in.readUTF(); + } else { + return null; + } + } + + /** + * This is copied from NetworkStatsHistory#NetworkStatsHistory(DataInput in). But it is fine + * for OEM to re-write the logic to adapt the legacy file reading. + */ + @NonNull + private static NetworkStatsHistory readPlatformHistory(@NonNull DataInput in) + throws IOException { + final long bucketDuration; + final long[] bucketStart; + final long[] rxBytes; + final long[] rxPackets; + final long[] txBytes; + final long[] txPackets; + final long[] operations; + final int bucketCount; + long[] activeTime = new long[0]; + + final int version = in.readInt(); + switch (version) { + case HistoryVersion.VERSION_INIT: { + bucketDuration = in.readLong(); + bucketStart = readFullLongArray(in); + rxBytes = readFullLongArray(in); + rxPackets = new long[bucketStart.length]; + txBytes = readFullLongArray(in); + txPackets = new long[bucketStart.length]; + operations = new long[bucketStart.length]; + bucketCount = bucketStart.length; + break; + } + case HistoryVersion.VERSION_ADD_PACKETS: + case HistoryVersion.VERSION_ADD_ACTIVE: { + bucketDuration = in.readLong(); + bucketStart = readVarLongArray(in); + activeTime = (version >= HistoryVersion.VERSION_ADD_ACTIVE) + ? readVarLongArray(in) + : new long[bucketStart.length]; + rxBytes = readVarLongArray(in); + rxPackets = readVarLongArray(in); + txBytes = readVarLongArray(in); + txPackets = readVarLongArray(in); + operations = readVarLongArray(in); + bucketCount = bucketStart.length; + break; + } + default: { + throw new ProtocolException("unexpected version: " + version); + } + } + + final NetworkStatsHistory.Builder historyBuilder = + new NetworkStatsHistory.Builder(bucketDuration, bucketCount); + for (int i = 0; i < bucketCount; i++) { + final NetworkStatsHistory.Entry entry = new NetworkStatsHistory.Entry( + bucketStart[i], activeTime[i], + rxBytes[i], rxPackets[i], txBytes[i], txPackets[i], operations[i]); + historyBuilder.addEntry(entry); + } + + return historyBuilder.build(); + } + + @NonNull + private static Set<NetworkIdentity> readPlatformNetworkIdentitySet(@NonNull DataInput in) + throws IOException { + final int version = in.readInt(); + final int size = in.readInt(); + final Set<NetworkIdentity> set = new HashSet<>(); + for (int i = 0; i < size; i++) { + if (version <= IdentitySetVersion.VERSION_INIT) { + final int ignored = in.readInt(); + } + final int type = in.readInt(); + final int ratType = in.readInt(); + final String subscriberId = readOptionalString(in); + final String networkId; + if (version >= IdentitySetVersion.VERSION_ADD_NETWORK_ID) { + networkId = readOptionalString(in); + } else { + networkId = null; + } + final boolean roaming; + if (version >= IdentitySetVersion.VERSION_ADD_ROAMING) { + roaming = in.readBoolean(); + } else { + roaming = false; + } + + final boolean metered; + if (version >= IdentitySetVersion.VERSION_ADD_METERED) { + metered = in.readBoolean(); + } else { + // If this is the old data and the type is mobile, treat it as metered. (Note that + // if this is a mobile network, TYPE_MOBILE is the only possible type that could be + // used.) + metered = (type == TYPE_MOBILE); + } + + final boolean defaultNetwork; + if (version >= IdentitySetVersion.VERSION_ADD_DEFAULT_NETWORK) { + defaultNetwork = in.readBoolean(); + } else { + defaultNetwork = true; + } + + final int oemNetCapabilities; + if (version >= IdentitySetVersion.VERSION_ADD_OEM_MANAGED_NETWORK) { + oemNetCapabilities = in.readInt(); + } else { + oemNetCapabilities = NetworkIdentity.OEM_NONE; + } + + // Legacy files might contain TYPE_MOBILE_* types which were deprecated in later + // releases. For backward compatibility, record them as TYPE_MOBILE instead. + final int collapsedLegacyType = getCollapsedLegacyType(type); + final NetworkIdentity.Builder builder = new NetworkIdentity.Builder() + .setType(collapsedLegacyType) + .setSubscriberId(subscriberId) + .setWifiNetworkKey(networkId) + .setRoaming(roaming).setMetered(metered) + .setDefaultNetwork(defaultNetwork) + .setOemManaged(oemNetCapabilities); + if (type == TYPE_MOBILE && ratType != NetworkTemplate.NETWORK_TYPE_ALL) { + builder.setRatType(ratType); + } + set.add(builder.build()); + } + return set; + } + + private static int getCollapsedLegacyType(int networkType) { + // The constants are referenced from ConnectivityManager#TYPE_MOBILE_*. + switch (networkType) { + case TYPE_MOBILE: + case TYPE_MOBILE_SUPL: + case TYPE_MOBILE_MMS: + case TYPE_MOBILE_DUN: + case TYPE_MOBILE_HIPRI: + case 10 /* TYPE_MOBILE_FOTA */: + case 11 /* TYPE_MOBILE_IMS */: + case 12 /* TYPE_MOBILE_CBS */: + case 14 /* TYPE_MOBILE_IA */: + case 15 /* TYPE_MOBILE_EMERGENCY */: + return TYPE_MOBILE; + } + return networkType; + } + + private static void readLegacyUid(@NonNull NetworkStatsCollection.Builder builder, + @NonNull File uidFile, boolean onlyTaggedData) throws IOException { + final AtomicFile inputFile = new AtomicFile(uidFile); + DataInputStream in = new DataInputStream(new BufferedInputStream(inputFile.openRead())); + try { + readLegacyUid(builder, in, onlyTaggedData); + } finally { + IoUtils.closeQuietly(in); + } + } + + /** + * Read legacy Uid statistics file format into the collection. + * + * This is copied from {@code NetworkStatsCollection#readLegacyUid}. + * See {@code NetworkStatsService#maybeUpgradeLegacyStatsLocked}. + * + * @param taggedData whether to read tagged data. For legacy uid files, the tagged + * data was stored in the same binary file with non-tagged data. + * But in later releases, these data should be kept in different + * recorders. + * @hide + */ + @VisibleForTesting + public static void readLegacyUid(@NonNull NetworkStatsCollection.Builder builder, + @NonNull DataInput in, boolean taggedData) throws IOException { + try { + // verify file magic header intact + final int magic = in.readInt(); + if (magic != FILE_MAGIC) { + throw new ProtocolException("unexpected magic: " + magic); + } + + final int version = in.readInt(); + switch (version) { + case CollectionVersion.VERSION_UID_INIT: { + // uid := size *(UID NetworkStatsHistory) + // drop this data version, since we don't have a good + // mapping into NetworkIdentitySet. + break; + } + case CollectionVersion.VERSION_UID_WITH_IDENT: { + // uid := size *(NetworkIdentitySet size *(UID NetworkStatsHistory)) + // drop this data version, since this version only existed + // for a short time. + break; + } + case CollectionVersion.VERSION_UID_WITH_TAG: + case CollectionVersion.VERSION_UID_WITH_SET: { + // uid := size *(NetworkIdentitySet size *(uid set tag NetworkStatsHistory)) + final int identSize = in.readInt(); + for (int i = 0; i < identSize; i++) { + final Set<NetworkIdentity> ident = readPlatformNetworkIdentitySet(in); + + final int size = in.readInt(); + for (int j = 0; j < size; j++) { + final int uid = in.readInt(); + final int set = (version >= CollectionVersion.VERSION_UID_WITH_SET) + ? in.readInt() + : SET_DEFAULT; + final int tag = in.readInt(); + + final NetworkStatsCollection.Key key = new NetworkStatsCollection.Key( + ident, uid, set, tag); + final NetworkStatsHistory history = readPlatformHistory(in); + + if ((tag == TAG_NONE) != taggedData) { + builder.addEntry(key, history); + } + } + } + break; + } + default: { + throw new ProtocolException("unknown version: " + version); + } + } + } catch (FileNotFoundException | ProtocolException e) { + // missing stats is okay, probably first boot + } + } +} diff --git a/core/java/android/net/vcn/VcnGatewayConnectionConfig.java b/core/java/android/net/vcn/VcnGatewayConnectionConfig.java index a6830b708c31..2339656979b5 100644 --- a/core/java/android/net/vcn/VcnGatewayConnectionConfig.java +++ b/core/java/android/net/vcn/VcnGatewayConnectionConfig.java @@ -549,8 +549,8 @@ public final class VcnGatewayConnectionConfig { * networks, a network will be chosen arbitrarily amongst the networks matching the highest * priority rule. * - * <p>If all networks fail to match the rules provided, an underlying network will still be - * selected (at random if necessary). + * <p>If all networks fail to match the rules provided, a carrier-owned underlying network + * will still be selected (if available, at random if necessary). * * @param underlyingNetworkTemplates a list of unique VcnUnderlyingNetworkTemplates that are * ordered from most to least preferred, or an empty list to use the default diff --git a/core/java/android/os/BatteryUsageStats.java b/core/java/android/os/BatteryUsageStats.java index 0f94cbef3886..86e6db1dc625 100644 --- a/core/java/android/os/BatteryUsageStats.java +++ b/core/java/android/os/BatteryUsageStats.java @@ -127,6 +127,7 @@ public final class BatteryUsageStats implements Parcelable { private final AggregateBatteryConsumer[] mAggregateBatteryConsumers; private final Parcel mHistoryBuffer; private final List<BatteryStats.HistoryTag> mHistoryTagPool; + private final BatteryStatsHistory mBatteryStatsHistory; private BatteryUsageStats(@NonNull Builder builder) { mStatsStartTimestampMs = builder.mStatsStartTimestampMs; @@ -138,6 +139,7 @@ public final class BatteryUsageStats implements Parcelable { mDischargedPowerUpperBound = builder.mDischargedPowerUpperBoundMah; mHistoryBuffer = builder.mHistoryBuffer; mHistoryTagPool = builder.mHistoryTagPool; + mBatteryStatsHistory = builder.mBatteryStatsHistory; mBatteryTimeRemainingMs = builder.mBatteryTimeRemainingMs; mChargeTimeRemainingMs = builder.mChargeTimeRemainingMs; mCustomPowerComponentNames = builder.mCustomPowerComponentNames; @@ -289,8 +291,8 @@ public final class BatteryUsageStats implements Parcelable { throw new IllegalStateException( "Battery history was not requested in the BatteryUsageStatsQuery"); } - return new BatteryStatsHistoryIterator(new BatteryStatsHistory(mHistoryBuffer), - mHistoryTagPool); + + return new BatteryStatsHistoryIterator(mBatteryStatsHistory, mHistoryTagPool); } @Override @@ -356,7 +358,10 @@ public final class BatteryUsageStats implements Parcelable { tag.poolIdx = source.readInt(); mHistoryTagPool.add(tag); } + mBatteryStatsHistory = new BatteryStatsHistory(mHistoryBuffer); + mBatteryStatsHistory.readFromBatteryUsageStatsParcel(source); } else { + mBatteryStatsHistory = null; mHistoryBuffer = null; mHistoryTagPool = null; } @@ -404,6 +409,7 @@ public final class BatteryUsageStats implements Parcelable { dest.writeInt(tag.uid); dest.writeInt(tag.poolIdx); } + mBatteryStatsHistory.writeToBatteryUsageStatsParcel(dest); } else { dest.writeBoolean(false); } @@ -757,6 +763,7 @@ public final class BatteryUsageStats implements Parcelable { new SparseArray<>(); private Parcel mHistoryBuffer; private List<BatteryStats.HistoryTag> mHistoryTagPool; + private BatteryStatsHistory mBatteryStatsHistory; public Builder(@NonNull String[] customPowerComponentNames) { this(customPowerComponentNames, false); @@ -865,10 +872,12 @@ public final class BatteryUsageStats implements Parcelable { * Sets the parceled recent history. */ @NonNull - public Builder setBatteryHistory(Parcel historyBuffer, - List<BatteryStats.HistoryTag> historyTagPool) { + public Builder setBatteryHistory(@NonNull Parcel historyBuffer, + @NonNull List<BatteryStats.HistoryTag> historyTagPool, + @NonNull BatteryStatsHistory batteryStatsHistory) { mHistoryBuffer = historyBuffer; mHistoryTagPool = historyTagPool; + mBatteryStatsHistory = batteryStatsHistory; return this; } diff --git a/core/java/android/os/BinderProxy.java b/core/java/android/os/BinderProxy.java index c6466235e5d1..2a2cbb996751 100644 --- a/core/java/android/os/BinderProxy.java +++ b/core/java/android/os/BinderProxy.java @@ -116,7 +116,7 @@ public final class BinderProxy implements IBinder { for (ArrayList<WeakReference<BinderProxy>> a : mMainIndexValues) { if (a != null) { for (WeakReference<BinderProxy> ref : a) { - if (ref.get() != null) { + if (!ref.refersTo(null)) { ++size; } } @@ -187,7 +187,7 @@ public final class BinderProxy implements IBinder { // This ensures that ArrayList size is bounded by the maximum occupancy of // that bucket. for (int i = 0; i < size; ++i) { - if (valueArray.get(i).get() == null) { + if (valueArray.get(i).refersTo(null)) { valueArray.set(i, newWr); Long[] keyArray = mMainIndexKeys[myHash]; keyArray[i] = key; @@ -195,7 +195,7 @@ public final class BinderProxy implements IBinder { // "Randomly" check one of the remaining entries in [i+1, size), so that // needlessly long buckets are eventually pruned. int rnd = Math.floorMod(++mRandom, size - (i + 1)); - if (valueArray.get(i + 1 + rnd).get() == null) { + if (valueArray.get(i + 1 + rnd).refersTo(null)) { remove(myHash, i + 1 + rnd); } } diff --git a/core/java/android/service/wallpapereffectsgeneration/OWNERS b/core/java/android/service/wallpapereffectsgeneration/OWNERS new file mode 100644 index 000000000000..d2d3e2c0a7b6 --- /dev/null +++ b/core/java/android/service/wallpapereffectsgeneration/OWNERS @@ -0,0 +1,4 @@ +susharon@google.com +shanh@google.com +huiwu@google.com +srazdan@google.com diff --git a/core/java/android/text/method/TextKeyListener.java b/core/java/android/text/method/TextKeyListener.java index 9cbda9c07591..2eb917b6fd57 100644 --- a/core/java/android/text/method/TextKeyListener.java +++ b/core/java/android/text/method/TextKeyListener.java @@ -306,7 +306,7 @@ public class TextKeyListener extends BaseKeyListener implements SpanWatcher { /* package */ int getPrefs(Context context) { synchronized (this) { - if (!mPrefsInited || mResolver.get() == null) { + if (!mPrefsInited || mResolver.refersTo(null)) { initPrefs(context); } } diff --git a/core/java/com/android/internal/os/BatteryStatsHistory.java b/core/java/com/android/internal/os/BatteryStatsHistory.java index 879e0a8cfe10..8ebb11dd752b 100644 --- a/core/java/com/android/internal/os/BatteryStatsHistory.java +++ b/core/java/com/android/internal/os/BatteryStatsHistory.java @@ -160,6 +160,11 @@ public class BatteryStatsHistory { mHistoryDir = null; mHistoryBuffer = historyBuffer; } + + public File getHistoryDirectory() { + return mHistoryDir; + } + /** * Set the active file that mHistoryBuffer is backed up into. * @@ -375,12 +380,24 @@ public class BatteryStatsHistory { } /** + * Read all history files and serialize into a big Parcel. + * Checkin file calls this method. + * @param out the output parcel + */ + public void writeToParcel(Parcel out) { + writeToParcel(out, false /* useBlobs */); + } + + /** * Read all history files and serialize into a big Parcel. This is to send history files to * Settings app since Settings app can not access /data/system directory. - * Checkin file also call this method. * @param out the output parcel */ - public void writeToParcel(Parcel out) { + public void writeToBatteryUsageStatsParcel(Parcel out) { + writeToParcel(out, true /* useBlobs */); + } + + private void writeToParcel(Parcel out, boolean useBlobs) { final long start = SystemClock.uptimeMillis(); out.writeInt(mFileNumbers.size() - 1); for(int i = 0; i < mFileNumbers.size() - 1; i++) { @@ -391,7 +408,12 @@ public class BatteryStatsHistory { } catch(Exception e) { Slog.e(TAG, "Error reading file "+ file.getBaseFile().getPath(), e); } - out.writeByteArray(raw); + if (useBlobs) { + out.writeBlob(raw); + } else { + // Avoiding blobs in the check-in file for compatibility + out.writeByteArray(raw); + } } if (DEBUG) { Slog.d(TAG, "writeToParcel duration ms:" + (SystemClock.uptimeMillis() - start)); @@ -399,18 +421,29 @@ public class BatteryStatsHistory { } /** - * This is for Settings app, when Settings app receives big history parcel, it call - * this method to parse it into list of parcels. - * Checkin file also call this method. + * This is for the check-in file, which has all history files embedded. * @param in the input parcel. */ public void readFromParcel(Parcel in) { + readFromParcel(in, false /* useBlobs */); + } + + /** + * This is for Settings app, when Settings app receives big history parcel, it calls + * this method to parse it into list of parcels. + * @param in the input parcel. + */ + public void readFromBatteryUsageStatsParcel(Parcel in) { + readFromParcel(in, true /* useBlobs */); + } + + private void readFromParcel(Parcel in, boolean useBlobs) { final long start = SystemClock.uptimeMillis(); mHistoryParcels = new ArrayList<>(); final int count = in.readInt(); for(int i = 0; i < count; i++) { - byte[] temp = in.createByteArray(); - if (temp.length == 0) { + byte[] temp = useBlobs ? in.readBlob() : in.createByteArray(); + if (temp == null || temp.length == 0) { continue; } Parcel p = Parcel.obtain(); diff --git a/core/java/com/android/internal/os/BatteryStatsImpl.java b/core/java/com/android/internal/os/BatteryStatsImpl.java index 8faffacecd9e..58a0622ba53b 100644 --- a/core/java/com/android/internal/os/BatteryStatsImpl.java +++ b/core/java/com/android/internal/os/BatteryStatsImpl.java @@ -1200,12 +1200,21 @@ public class BatteryStatsImpl extends BatteryStats { } public BatteryStatsImpl(Clocks clocks) { + this(clocks, (File) null); + } + + public BatteryStatsImpl(Clocks clocks, File historyDirectory) { init(clocks); mStartClockTimeMs = clocks.currentTimeMillis(); - mStatsFile = null; mCheckinFile = null; mDailyFile = null; - mBatteryStatsHistory = new BatteryStatsHistory(mHistoryBuffer); + if (historyDirectory == null) { + mStatsFile = null; + mBatteryStatsHistory = new BatteryStatsHistory(mHistoryBuffer); + } else { + mStatsFile = new AtomicFile(new File(historyDirectory, "batterystats.bin")); + mBatteryStatsHistory = new BatteryStatsHistory(this, historyDirectory, mHistoryBuffer); + } mHandler = null; mPlatformIdleStateCallback = null; mMeasuredEnergyRetriever = null; @@ -11590,61 +11599,60 @@ public class BatteryStatsImpl extends BatteryStats { long totalTxPackets = 0; long totalRxPackets = 0; if (delta != null) { - NetworkStats.Entry entry = new NetworkStats.Entry(); - final int size = delta.size(); - for (int i = 0; i < size; i++) { - entry = delta.getValues(i, entry); - + for (NetworkStats.Entry entry : delta) { if (DEBUG_ENERGY) { - Slog.d(TAG, "Wifi uid " + entry.uid + ": delta rx=" + entry.rxBytes - + " tx=" + entry.txBytes + " rxPackets=" + entry.rxPackets - + " txPackets=" + entry.txPackets); + Slog.d(TAG, "Wifi uid " + entry.getUid() + + ": delta rx=" + entry.getRxBytes() + + " tx=" + entry.getTxBytes() + + " rxPackets=" + entry.getRxPackets() + + " txPackets=" + entry.getTxPackets()); } - if (entry.rxBytes == 0 && entry.txBytes == 0) { + if (entry.getRxBytes() == 0 && entry.getTxBytes() == 0) { // Skip the lookup below since there is no work to do. continue; } - final Uid u = getUidStatsLocked(mapUid(entry.uid), elapsedRealtimeMs, uptimeMs); - if (entry.rxBytes != 0) { - u.noteNetworkActivityLocked(NETWORK_WIFI_RX_DATA, entry.rxBytes, - entry.rxPackets); - if (entry.set == NetworkStats.SET_DEFAULT) { // Background transfers - u.noteNetworkActivityLocked(NETWORK_WIFI_BG_RX_DATA, entry.rxBytes, - entry.rxPackets); + final Uid u = getUidStatsLocked(mapUid(entry.getUid()), + elapsedRealtimeMs, uptimeMs); + if (entry.getRxBytes() != 0) { + u.noteNetworkActivityLocked(NETWORK_WIFI_RX_DATA, entry.getRxBytes(), + entry.getRxPackets()); + if (entry.getSet() == NetworkStats.SET_DEFAULT) { // Background transfers + u.noteNetworkActivityLocked(NETWORK_WIFI_BG_RX_DATA, entry.getRxBytes(), + entry.getRxPackets()); } mNetworkByteActivityCounters[NETWORK_WIFI_RX_DATA].addCountLocked( - entry.rxBytes); + entry.getRxBytes()); mNetworkPacketActivityCounters[NETWORK_WIFI_RX_DATA].addCountLocked( - entry.rxPackets); + entry.getRxPackets()); // TODO(b/182845426): What if u was a mapped isolated uid? Shouldn't we sum? - rxPackets.put(u.getUid(), entry.rxPackets); + rxPackets.put(u.getUid(), entry.getRxPackets()); // Sum the total number of packets so that the Rx Power can // be evenly distributed amongst the apps. - totalRxPackets += entry.rxPackets; + totalRxPackets += entry.getRxPackets(); } - if (entry.txBytes != 0) { - u.noteNetworkActivityLocked(NETWORK_WIFI_TX_DATA, entry.txBytes, - entry.txPackets); - if (entry.set == NetworkStats.SET_DEFAULT) { // Background transfers - u.noteNetworkActivityLocked(NETWORK_WIFI_BG_TX_DATA, entry.txBytes, - entry.txPackets); + if (entry.getTxBytes() != 0) { + u.noteNetworkActivityLocked(NETWORK_WIFI_TX_DATA, entry.getTxBytes(), + entry.getTxPackets()); + if (entry.getSet() == NetworkStats.SET_DEFAULT) { // Background transfers + u.noteNetworkActivityLocked(NETWORK_WIFI_BG_TX_DATA, entry.getTxBytes(), + entry.getTxPackets()); } mNetworkByteActivityCounters[NETWORK_WIFI_TX_DATA].addCountLocked( - entry.txBytes); + entry.getTxBytes()); mNetworkPacketActivityCounters[NETWORK_WIFI_TX_DATA].addCountLocked( - entry.txPackets); + entry.getTxPackets()); // TODO(b/182845426): What if u was a mapped isolated uid? Shouldn't we sum? - txPackets.put(u.getUid(), entry.txPackets); + txPackets.put(u.getUid(), entry.getTxPackets()); // Sum the total number of packets so that the Tx Power can // be evenly distributed amongst the apps. - totalTxPackets += entry.txPackets; + totalTxPackets += entry.getTxPackets(); } // Calculate consumed energy for this uid. Only do so if WifiReporting isn't @@ -11672,7 +11680,7 @@ public class BatteryStatsImpl extends BatteryStats { uidEstimatedConsumptionMah.add(u.getUid(), mWifiPowerCalculator.calcPowerWithoutControllerDataMah( - entry.rxPackets, entry.txPackets, + entry.getRxPackets(), entry.getTxPackets(), uidRunningMs, uidScanMs, uidBatchScanMs)); } } diff --git a/core/java/com/android/internal/os/BatteryUsageStatsProvider.java b/core/java/com/android/internal/os/BatteryUsageStatsProvider.java index 980aec196079..79832867d01f 100644 --- a/core/java/com/android/internal/os/BatteryUsageStatsProvider.java +++ b/core/java/com/android/internal/os/BatteryUsageStatsProvider.java @@ -21,6 +21,7 @@ import android.hardware.SensorManager; import android.os.BatteryStats; import android.os.BatteryUsageStats; import android.os.BatteryUsageStatsQuery; +import android.os.Parcel; import android.os.SystemClock; import android.os.UidBatteryConsumer; import android.util.Log; @@ -28,6 +29,7 @@ import android.util.SparseArray; import com.android.internal.annotations.VisibleForTesting; +import java.io.File; import java.util.ArrayList; import java.util.Arrays; import java.util.List; @@ -186,16 +188,28 @@ public class BatteryUsageStatsProvider { } BatteryStatsImpl batteryStatsImpl = (BatteryStatsImpl) mStats; + + // Make a copy of battery history to avoid concurrent modification. + Parcel historyBuffer = Parcel.obtain(); + historyBuffer.appendFrom(batteryStatsImpl.mHistoryBuffer, 0, + batteryStatsImpl.mHistoryBuffer.dataSize()); + ArrayList<BatteryStats.HistoryTag> tags = new ArrayList<>( batteryStatsImpl.mHistoryTagPool.size()); for (Map.Entry<BatteryStats.HistoryTag, Integer> entry : batteryStatsImpl.mHistoryTagPool.entrySet()) { - final BatteryStats.HistoryTag tag = entry.getKey(); + final BatteryStats.HistoryTag tag = new BatteryStats.HistoryTag(); + tag.setTo(entry.getKey()); tag.poolIdx = entry.getValue(); tags.add(tag); } - batteryUsageStatsBuilder.setBatteryHistory(batteryStatsImpl.mHistoryBuffer, tags); + final File systemDir = + batteryStatsImpl.mBatteryStatsHistory.getHistoryDirectory().getParentFile(); + final BatteryStatsHistory batteryStatsHistory = + new BatteryStatsHistory(batteryStatsImpl, systemDir, historyBuffer); + + batteryUsageStatsBuilder.setBatteryHistory(historyBuffer, tags, batteryStatsHistory); } return batteryUsageStatsBuilder.build(); diff --git a/core/java/com/android/internal/os/BinderLatencyObserver.java b/core/java/com/android/internal/os/BinderLatencyObserver.java index 20cf102953e4..e9d55db3a5b4 100644 --- a/core/java/com/android/internal/os/BinderLatencyObserver.java +++ b/core/java/com/android/internal/os/BinderLatencyObserver.java @@ -19,7 +19,6 @@ package com.android.internal.os; import android.annotation.Nullable; import android.os.Binder; import android.os.Handler; -import android.os.Looper; import android.os.SystemClock; import android.util.ArrayMap; import android.util.Slog; @@ -181,7 +180,7 @@ public class BinderLatencyObserver { } public Handler getHandler() { - return new Handler(Looper.getMainLooper()); + return BackgroundThread.getHandler(); } } diff --git a/core/java/com/android/internal/os/RuntimeInit.java b/core/java/com/android/internal/os/RuntimeInit.java index 8d1f16b4b259..44c7f5406713 100644 --- a/core/java/com/android/internal/os/RuntimeInit.java +++ b/core/java/com/android/internal/os/RuntimeInit.java @@ -22,6 +22,7 @@ import android.app.ApplicationErrorReport; import android.app.IActivityManager; import android.compat.annotation.UnsupportedAppUsage; import android.content.type.DefaultMimeMapFactory; +import android.net.TrafficStats; import android.os.Build; import android.os.DeadObjectException; import android.os.IBinder; @@ -32,7 +33,6 @@ import android.util.Log; import android.util.Slog; import com.android.internal.logging.AndroidConfig; -import com.android.server.NetworkManagementSocketTagger; import dalvik.system.RuntimeHooks; import dalvik.system.VMRuntime; @@ -254,7 +254,7 @@ public class RuntimeInit { /* * Wire socket tagging to traffic stats. */ - NetworkManagementSocketTagger.install(); + TrafficStats.attachSocketTagger(); initialized = true; } diff --git a/core/jni/Android.bp b/core/jni/Android.bp index 07b16ed42624..adcbb425d1cf 100644 --- a/core/jni/Android.bp +++ b/core/jni/Android.bp @@ -245,7 +245,6 @@ cc_library_shared { "libandroid_net", "libandroidicu", "libbpf_android", - "libnetdbpf", "libnetdutils", "libmemtrack", "libandroidfw", diff --git a/core/jni/OWNERS b/core/jni/OWNERS index 81ddf8629579..a17d807f946b 100644 --- a/core/jni/OWNERS +++ b/core/jni/OWNERS @@ -73,6 +73,9 @@ per-file AndroidRuntime.cpp = file:/graphics/java/android/graphics/OWNERS per-file AndroidRuntime.cpp = calin@google.com, ngeoffray@google.com, oth@google.com # Although marked "view" this is mostly graphics stuff per-file android_view_* = file:/graphics/java/android/graphics/OWNERS +# File used for Android Studio layoutlib +per-file LayoutlibLoader.cpp = file:/graphics/java/android/graphics/OWNERS +per-file LayoutlibLoader.cpp = diegoperez@google.com, jgaillard@google.com # Verity per-file com_android_internal_security_Verity* = ebiggers@google.com, victorhsieh@google.com diff --git a/core/jni/android_hardware_UsbDeviceConnection.cpp b/core/jni/android_hardware_UsbDeviceConnection.cpp index 845d65c67719..a0228428e90e 100644 --- a/core/jni/android_hardware_UsbDeviceConnection.cpp +++ b/core/jni/android_hardware_UsbDeviceConnection.cpp @@ -16,20 +16,19 @@ #define LOG_TAG "UsbDeviceConnectionJNI" -#include "utils/Log.h" - -#include "jni.h" +#include <fcntl.h> #include <nativehelper/JNIPlatformHelp.h> -#include "core_jni_helpers.h" - +#include <stdio.h> +#include <sys/stat.h> +#include <sys/types.h> #include <usbhost/usbhost.h> +#include <usbhost/usbhost_jni.h> #include <chrono> -#include <stdio.h> -#include <sys/types.h> -#include <sys/stat.h> -#include <fcntl.h> +#include "core_jni_helpers.h" +#include "jni.h" +#include "utils/Log.h" using namespace android; using namespace std::chrono; @@ -91,22 +90,8 @@ android_hardware_UsbDeviceConnection_get_fd(JNIEnv *env, jobject thiz) static jbyteArray android_hardware_UsbDeviceConnection_get_desc(JNIEnv *env, jobject thiz) { - char buffer[16384]; int fd = android_hardware_UsbDeviceConnection_get_fd(env, thiz); - if (fd < 0) return NULL; - lseek(fd, 0, SEEK_SET); - int length = read(fd, buffer, sizeof(buffer)); - if (length < 0) return NULL; - - jbyteArray ret = env->NewByteArray(length); - if (ret) { - jbyte* bytes = (jbyte*)env->GetPrimitiveArrayCritical(ret, 0); - if (bytes) { - memcpy(bytes, buffer, length); - env->ReleasePrimitiveArrayCritical(ret, bytes, 0); - } - } - return ret; + return usb_jni_read_descriptors(env, fd); } static jboolean diff --git a/core/proto/android/os/incident.proto b/core/proto/android/os/incident.proto index 998ec96f6f23..51e150e28437 100644 --- a/core/proto/android/os/incident.proto +++ b/core/proto/android/os/incident.proto @@ -249,7 +249,8 @@ message IncidentProto { optional android.service.NetworkStatsServiceDumpProto netstats = 3001 [ (section).type = SECTION_DUMPSYS, - (section).args = "netstats --proto" + (section).args = "netstats --proto", + (section).userdebug_and_eng_only = true ]; optional android.providers.settings.SettingsServiceDumpProto settings = 3002 [ diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml index 2f334989b53a..ba647d7daa28 100644 --- a/core/res/res/values/config.xml +++ b/core/res/res/values/config.xml @@ -134,9 +134,6 @@ be sent during a change to the audio output device. --> <bool name="config_sendAudioBecomingNoisy">true</bool> - <!-- Whether Hearing Aid profile is supported --> - <bool name="config_hearing_aid_profile_supported">false</bool> - <!-- Flag to disable all transition animations --> <bool name="config_disableTransitionAnimation">false</bool> @@ -404,10 +401,6 @@ <string-array translatable="false" name="config_tether_bluetooth_regexs"> </string-array> - <!-- Max number of Bluetooth tethering connections allowed. If this is - updated config_tether_dhcp_range has to be updated appropriately. --> - <integer translatable="false" name="config_max_pan_devices">5</integer> - <!-- This setting is deprecated, please use com.android.networkstack.tethering.R.array.config_dhcp_range instead. --> <string-array translatable="false" name="config_tether_dhcp_range"> @@ -1820,53 +1813,38 @@ <!-- Integer to set a max latency the accelerometer will batch sensor requests with. --> <integer name="config_flipToScreenOffMaxLatencyMicros">2000000</integer> - <!-- Boolean indicating if current platform supports bluetooth SCO for off call - use cases --> + <!-- Note: This config is deprecated + Boolean indicating if current platform supports bluetooth SCO for off call + use cases + --> <bool name="config_bluetooth_sco_off_call">true</bool> - <!-- Boolean indicating if current platform supports bluetooth wide band - speech --> - <bool name="config_bluetooth_wide_band_speech">true</bool> - - <!-- Boolean indicating if current platform need do one-time bluetooth address - re-validation --> + <!-- Note: This config is deprecated + Boolean indicating if current platform need do one-time bluetooth address + re-validation + --> <bool name="config_bluetooth_address_validation">false</bool> - <!-- Boolean indicating if current platform supports BLE peripheral mode --> - <bool name="config_bluetooth_le_peripheral_mode_supported">false</bool> - - <!-- Boolean indicating if current platform supports HFP inband ringing --> - <bool name="config_bluetooth_hfp_inband_ringing_support">false</bool> - - <!-- Max number of scan filters supported by blutooth controller. 0 if the - device does not support hardware scan filters--> - <integer translatable="false" name="config_bluetooth_max_scan_filters">0</integer> - - <!-- Max number of advertisers supported by bluetooth controller. 0 if the - device does not support multiple advertisement--> - <integer translatable="false" name="config_bluetooth_max_advertisers">0</integer> - - <!-- Idle current for bluetooth controller. 0 by default--> + <!-- Note: This config is deprecated, use BluetoothProperties instead. + Idle current for bluetooth controller. 0 by default + --> <integer translatable="false" name="config_bluetooth_idle_cur_ma">0</integer> - <!-- Rx current for bluetooth controller. 0 by default--> + <!-- Note: This config is deprecated, use BluetoothProperties instead. + Rx current for bluetooth controller. 0 by default + --> <integer translatable="false" name="config_bluetooth_rx_cur_ma">0</integer> - <!-- Tx current for bluetooth controller. 0 by default--> + <!-- Note: This config is deprecated, use BluetoothProperties instead. + Tx current for bluetooth controller. 0 by default + --> <integer translatable="false" name="config_bluetooth_tx_cur_ma">0</integer> - <!-- Operating volatage for bluetooth controller. 0 by default--> + <!-- Note: This config is deprecated, use BluetoothProperties instead. + Operating volatage for bluetooth controller. 0 by default + --> <integer translatable="false" name="config_bluetooth_operating_voltage_mv">0</integer> - <!-- Max number of connected audio devices supported by Bluetooth stack --> - <integer name="config_bluetooth_max_connected_audio_devices">5</integer> - - <!-- Whether supported profiles should be reloaded upon enabling bluetooth --> - <bool name="config_bluetooth_reload_supported_profiles_when_enabled">false</bool> - - <!-- Enabling autoconnect over pan --> - <bool name="config_bluetooth_pan_enable_autoconnect">false</bool> - <!-- The default data-use polling period. --> <integer name="config_datause_polling_period_sec">600</integer> @@ -2007,10 +1985,6 @@ <!-- The name of the package that will be allowed to change its components' label/icon. --> <string name="config_overrideComponentUiPackage" translatable="false">com.android.stk</string> - <!-- Enable/disable default bluetooth profiles: - HSP_AG, ObexObjectPush, Audio, NAP --> - <bool name="config_bluetooth_default_profiles">true</bool> - <!-- IP address of the dns server to use if nobody else suggests one --> <string name="config_default_dns_server" translatable="false">8.8.8.8</string> @@ -4141,8 +4115,6 @@ <!-- Component name that should be granted Notification Assistant access --> <string name="config_defaultAssistantAccessComponent" translatable="false">android.ext.services/android.ext.services.notification.Assistant</string> - <bool name="config_supportBluetoothPersistedState">true</bool> - <bool name="config_keepRestrictedProfilesInBackground">true</bool> <!-- Cellular network service package name to bind to by default. --> diff --git a/core/res/res/values/public.xml b/core/res/res/values/public.xml index 2403a605972e..6ef5bd46dce7 100644 --- a/core/res/res/values/public.xml +++ b/core/res/res/values/public.xml @@ -3200,11 +3200,87 @@ <!-- @hide For use by platform and tools only. Developers should not specify this value. --> <public type="string" name="config_defaultRingtoneVibrationSound" id="0x0104003b" /> + <!-- =============================================================== + Resources added in version T of the platform + + NOTE: add <public> elements within a <staging-public-group> like so: + + <staging-public-group type="attr" first-id="0x01ff0000"> + <public name="exampleAttr1" /> + <public name="exampleAttr2" /> + </staging-public-group> + + To add a new <staging-public-group> block, find the id value for the + last <staging-public-group> block defined for thie API level, and + subtract 0x00010000 from it to get to the id of the new block. + + For example, if the block closest to the end of this file has an id + of 0x01ee0000, the id of the new block should be 0x01ed0000 + (0x01ee0000 - 0x00010000 = 0x01ed0000). + =============================================================== --> + <eat-comment /> + + <staging-public-group type="attr" first-id="0x01df0000"> + </staging-public-group> + + <staging-public-group type="id" first-id="0x01de0000"> + </staging-public-group> + + <staging-public-group type="style" first-id="0x0dfd0000"> + </staging-public-group> + + <staging-public-group type="string" first-id="0x0dfc0000"> + </staging-public-group> + + <staging-public-group type="dimen" first-id="0x01db0000"> + </staging-public-group> + + <staging-public-group type="color" first-id="0x01da0000"> + </staging-public-group> + + <staging-public-group type="array" first-id="0x01d90000"> + <!-- @hide @SystemApi --> + <public name="config_optionalIpSecAlgorithms" /> + </staging-public-group> + + <staging-public-group type="drawable" first-id="0x01d80000"> + </staging-public-group> + + <staging-public-group type="layout" first-id="0x01d70000"> + </staging-public-group> + + <staging-public-group type="anim" first-id="0x01d60000"> + </staging-public-group> + + <staging-public-group type="animator" first-id="0x01d50000"> + </staging-public-group> + + <staging-public-group type="interpolator" first-id="0x01d40000"> + </staging-public-group> + + <staging-public-group type="mipmap" first-id="0x01d30000"> + </staging-public-group> + + <staging-public-group type="integer" first-id="0x01d20000"> + </staging-public-group> + + <staging-public-group type="transition" first-id="0x01d10000"> + </staging-public-group> + + <staging-public-group type="raw" first-id="0x01d00000"> + </staging-public-group> + + <staging-public-group type="bool" first-id="0x01cf0000"> + </staging-public-group> + + <staging-public-group type="fraction" first-id="0x01ce0000"> + </staging-public-group> + <!-- =============================================================== DO NOT ADD UN-GROUPED ITEMS HERE Any new items (attrs, styles, ids, etc.) *must* be added in a - public-group block, as the preceding comment explains. + staging-public-group block, as the preceding comment explains. Items added outside of a group may have their value recalculated every time something new is added to this file. =============================================================== --> diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml index 4db6499569b3..590fcf46f373 100644 --- a/core/res/res/values/symbols.xml +++ b/core/res/res/values/symbols.xml @@ -278,8 +278,6 @@ <java-symbol type="bool" name="config_flipToScreenOffEnabled" /> <java-symbol type="integer" name="config_flipToScreenOffMaxLatencyMicros" /> <java-symbol type="bool" name="config_bluetooth_sco_off_call" /> - <java-symbol type="bool" name="config_bluetooth_le_peripheral_mode_supported" /> - <java-symbol type="bool" name="config_bluetooth_hfp_inband_ringing_support" /> <java-symbol type="bool" name="config_cellBroadcastAppLinks" /> <java-symbol type="bool" name="config_duplicate_port_omadm_wappush" /> <java-symbol type="bool" name="config_disableTransitionAnimation" /> @@ -343,7 +341,6 @@ <java-symbol type="integer" name="config_timeZoneRulesCheckRetryCount" /> <java-symbol type="bool" name="config_sendAudioBecomingNoisy" /> <java-symbol type="bool" name="config_enableScreenshotChord" /> - <java-symbol type="bool" name="config_bluetooth_default_profiles" /> <java-symbol type="bool" name="config_enableWifiDisplay" /> <java-symbol type="bool" name="config_allowAnimationsInLowPowerMode" /> <java-symbol type="bool" name="config_useDevInputEventForAudioJack" /> @@ -417,9 +414,6 @@ <java-symbol type="dimen" name="config_pictureInPictureMaxAspectRatio" /> <java-symbol type="integer" name="config_pictureInPictureMaxNumberOfActions" /> <java-symbol type="dimen" name="config_closeToSquareDisplayMaxAspectRatio" /> - <java-symbol type="integer" name="config_bluetooth_max_advertisers" /> - <java-symbol type="integer" name="config_bluetooth_max_scan_filters" /> - <java-symbol type="integer" name="config_bluetooth_max_connected_audio_devices" /> <java-symbol type="integer" name="config_burnInProtectionMinHorizontalOffset" /> <java-symbol type="integer" name="config_burnInProtectionMaxHorizontalOffset" /> <java-symbol type="integer" name="config_burnInProtectionMinVerticalOffset" /> @@ -429,9 +423,6 @@ <java-symbol type="integer" name="config_bluetooth_rx_cur_ma" /> <java-symbol type="integer" name="config_bluetooth_tx_cur_ma" /> <java-symbol type="integer" name="config_bluetooth_operating_voltage_mv" /> - <java-symbol type="bool" name="config_bluetooth_pan_enable_autoconnect" /> - <java-symbol type="bool" name="config_bluetooth_reload_supported_profiles_when_enabled" /> - <java-symbol type="bool" name="config_hearing_aid_profile_supported" /> <java-symbol type="integer" name="config_cursorWindowSize" /> <java-symbol type="integer" name="config_drawLockTimeoutMillis" /> <java-symbol type="integer" name="config_doublePressOnPowerBehavior" /> @@ -450,7 +441,6 @@ <java-symbol type="integer" name="config_wakeUpToLastStateTimeoutMillis" /> <java-symbol type="integer" name="config_lowMemoryKillerMinFreeKbytesAdjust" /> <java-symbol type="integer" name="config_lowMemoryKillerMinFreeKbytesAbsolute" /> - <java-symbol type="integer" name="config_max_pan_devices" /> <java-symbol type="integer" name="config_ntpPollingInterval" /> <java-symbol type="integer" name="config_ntpPollingIntervalShorter" /> <java-symbol type="integer" name="config_ntpRetry" /> @@ -3782,8 +3772,6 @@ <java-symbol type="string" name="config_defaultAssistantAccessComponent" /> - <java-symbol type="bool" name="config_supportBluetoothPersistedState" /> - <java-symbol type="string" name="slices_permission_request" /> <java-symbol type="string" name="screenshot_edit" /> diff --git a/core/res/res/xml/sms_short_codes.xml b/core/res/res/xml/sms_short_codes.xml index 4c20ae1b099c..d1d86a782016 100644 --- a/core/res/res/xml/sms_short_codes.xml +++ b/core/res/res/xml/sms_short_codes.xml @@ -154,9 +154,9 @@ <!-- Israel: 4 digits, known premium codes listed --> <shortcode country="il" pattern="\\d{4}" premium="4422|4545" /> - <!-- Italy: 5 digits (premium=4xxxx), plus EU: - http://clients.txtnation.com/attachments/token/di5kfblvubttvlw/?name=Italy_CASP_EN.pdf --> - <shortcode country="it" pattern="\\d{5}" premium="4\\d{4}" free="116\\d{3}|4112503" standard="43\\d{3}" /> + <!-- Italy: 5 digits (premium=41xxx,42xxx), plus EU: + https://www.itu.int/dms_pub/itu-t/oth/02/02/T020200006B0001PDFE.pdf --> + <shortcode country="it" pattern="\\d{5}" premium="4\\d{4}" free="116\\d{3}|4112503|40\\d{0,12}" standard="430\\d{2}|431\\d{2}|434\\d{4}|435\\d{4}|439\\d{7}" /> <!-- Japan: 8083 used by SOFTBANK_DCB_2 --> <shortcode country="jp" pattern="\\d{1,5}" free="8083" /> diff --git a/core/tests/coretests/src/android/view/OWNERS b/core/tests/coretests/src/android/view/OWNERS index 74cdd2146937..10f6f1fd22f1 100644 --- a/core/tests/coretests/src/android/view/OWNERS +++ b/core/tests/coretests/src/android/view/OWNERS @@ -16,3 +16,6 @@ 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 + +# Stylus +per-file stylus/* = file:/core/java/android/text/OWNERS
\ No newline at end of file diff --git a/core/tests/coretests/src/com/android/internal/os/BatteryUsageStatsProviderTest.java b/core/tests/coretests/src/com/android/internal/os/BatteryUsageStatsProviderTest.java index 74b6dbe76a16..93910b9c816e 100644 --- a/core/tests/coretests/src/com/android/internal/os/BatteryUsageStatsProviderTest.java +++ b/core/tests/coretests/src/com/android/internal/os/BatteryUsageStatsProviderTest.java @@ -39,6 +39,8 @@ import androidx.test.InstrumentationRegistry; import androidx.test.filters.SmallTest; import androidx.test.runner.AndroidJUnit4; +import libcore.testing.io.TestIoUtils; + import org.junit.Rule; import org.junit.Test; import org.junit.runner.RunWith; @@ -52,8 +54,11 @@ public class BatteryUsageStatsProviderTest { private static final int APP_UID = Process.FIRST_APPLICATION_UID + 42; private static final long MINUTE_IN_MS = 60 * 1000; + private final File mHistoryDir = + TestIoUtils.createTemporaryDirectory(getClass().getSimpleName()); + @Rule - public final BatteryUsageStatsRule mStatsRule = new BatteryUsageStatsRule(12345) + public final BatteryUsageStatsRule mStatsRule = new BatteryUsageStatsRule(12345, mHistoryDir) .setAveragePower(PowerProfile.POWER_FLASHLIGHT, 360.0); @Test diff --git a/core/tests/coretests/src/com/android/internal/os/BatteryUsageStatsRule.java b/core/tests/coretests/src/com/android/internal/os/BatteryUsageStatsRule.java index 083090c54619..2c6f5fa1ae82 100644 --- a/core/tests/coretests/src/com/android/internal/os/BatteryUsageStatsRule.java +++ b/core/tests/coretests/src/com/android/internal/os/BatteryUsageStatsRule.java @@ -40,6 +40,7 @@ import org.junit.runner.Description; import org.junit.runners.model.Statement; import org.mockito.stubbing.Answer; +import java.io.File; import java.util.Arrays; public class BatteryUsageStatsRule implements TestRule { @@ -57,14 +58,18 @@ public class BatteryUsageStatsRule implements TestRule { private boolean mScreenOn; public BatteryUsageStatsRule() { - this(0); + this(0, null); } public BatteryUsageStatsRule(long currentTime) { + this(currentTime, null); + } + + public BatteryUsageStatsRule(long currentTime, File historyDir) { Context context = InstrumentationRegistry.getContext(); mPowerProfile = spy(new PowerProfile(context, true /* forTest */)); mMockClocks.currentTime = currentTime; - mBatteryStats = new MockBatteryStatsImpl(mMockClocks); + mBatteryStats = new MockBatteryStatsImpl(mMockClocks, historyDir); mBatteryStats.setPowerProfile(mPowerProfile); mBatteryStats.onSystemReady(); } diff --git a/core/tests/coretests/src/com/android/internal/os/MockBatteryStatsImpl.java b/core/tests/coretests/src/com/android/internal/os/MockBatteryStatsImpl.java index 8b14c62dd1d7..11d20f2ebeb0 100644 --- a/core/tests/coretests/src/com/android/internal/os/MockBatteryStatsImpl.java +++ b/core/tests/coretests/src/com/android/internal/os/MockBatteryStatsImpl.java @@ -29,6 +29,7 @@ import com.android.internal.os.KernelCpuUidTimeReader.KernelCpuUidFreqTimeReader import com.android.internal.os.KernelCpuUidTimeReader.KernelCpuUidUserSysTimeReader; import com.android.internal.power.MeasuredEnergyStats; +import java.io.File; import java.util.ArrayList; import java.util.Arrays; import java.util.Queue; @@ -44,7 +45,12 @@ public class MockBatteryStatsImpl extends BatteryStatsImpl { private NetworkStats mNetworkStats; MockBatteryStatsImpl(Clocks clocks) { - super(clocks); + this(clocks, null); + } + + MockBatteryStatsImpl(Clocks clocks, File historyDirectory) { + super(clocks, historyDirectory); + this.clocks = mClocks; initTimersAndCounters(); diff --git a/data/etc/privapp-permissions-platform.xml b/data/etc/privapp-permissions-platform.xml index be85fcc15ffa..fa6b086b9259 100644 --- a/data/etc/privapp-permissions-platform.xml +++ b/data/etc/privapp-permissions-platform.xml @@ -461,6 +461,7 @@ applications that come with the platform <!-- Permission needed for CTS test - WifiManagerTest --> <permission name="android.permission.WIFI_ACCESS_COEX_UNSAFE_CHANNELS" /> <permission name="android.permission.WIFI_UPDATE_COEX_UNSAFE_CHANNELS" /> + <permission name="android.permission.OVERRIDE_WIFI_CONFIG" /> <!-- Permission required for CTS test CarrierMessagingServiceWrapperTest --> <permission name="android.permission.BIND_CARRIER_SERVICES"/> <!-- Permission required for CTS test - MusicRecognitionManagerTest --> diff --git a/libs/hwui/Readback.cpp b/libs/hwui/Readback.cpp index f8d6c07b980d..a743d30939d0 100644 --- a/libs/hwui/Readback.cpp +++ b/libs/hwui/Readback.cpp @@ -32,8 +32,6 @@ using namespace android::uirenderer::renderthread; -static constexpr bool sEnableExtraCropInset = true; - namespace android { namespace uirenderer { @@ -66,20 +64,6 @@ CopyResult Readback::copySurfaceInto(ANativeWindow* window, const Rect& inSrcRec ALOGW("Surface doesn't have any previously queued frames, nothing to readback from"); return CopyResult::SourceEmpty; } - - if (sEnableExtraCropInset && - (cropRect.right - cropRect.left != bitmap->width() || - cropRect.bottom - cropRect.top != bitmap->height())) { - /* - * When we need use filtering, we should also make border shrink here like gui. - * But we could not check format for YUV or RGB here... Just use 1 pix. - */ - cropRect.left += 0.5f; - cropRect.top += 0.5f; - cropRect.right -= 0.5f; - cropRect.bottom -= 0.5f; - } - UniqueAHardwareBuffer sourceBuffer{rawSourceBuffer}; AHardwareBuffer_Desc description; AHardwareBuffer_describe(sourceBuffer.get(), &description); diff --git a/media/java/android/media/BtProfileConnectionInfo.java b/media/java/android/media/BtProfileConnectionInfo.java index d1bb41e70b54..88b9777e911d 100644 --- a/media/java/android/media/BtProfileConnectionInfo.java +++ b/media/java/android/media/BtProfileConnectionInfo.java @@ -15,39 +15,25 @@ */ package android.media; -import android.annotation.IntDef; import android.annotation.NonNull; import android.annotation.SystemApi; import android.bluetooth.BluetoothProfile; import android.os.Parcel; import android.os.Parcelable; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; - /** * Contains information about Bluetooth profile connection state changed * {@hide} */ @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES) public final class BtProfileConnectionInfo implements Parcelable { - /** @hide */ - @IntDef({ - BluetoothProfile.A2DP, - BluetoothProfile.A2DP_SINK, - BluetoothProfile.HEADSET, // Can only be set by BtHelper - BluetoothProfile.HEARING_AID, - BluetoothProfile.LE_AUDIO, - }) - @Retention(RetentionPolicy.SOURCE) - public @interface BtProfile {} - - private final @BtProfile int mProfile; + + private final int mProfile; private final boolean mSupprNoisy; private final int mVolume; private final boolean mIsLeOutput; - private BtProfileConnectionInfo(@BtProfile int profile, boolean suppressNoisyIntent, int volume, + private BtProfileConnectionInfo(int profile, boolean suppressNoisyIntent, int volume, boolean isLeOutput) { mProfile = profile; mSupprNoisy = suppressNoisyIntent; @@ -59,7 +45,7 @@ public final class BtProfileConnectionInfo implements Parcelable { * Constructor used by BtHelper when a profile is connected * {@hide} */ - public BtProfileConnectionInfo(@BtProfile int profile) { + public BtProfileConnectionInfo(int profile) { this(profile, false, -1, false); } @@ -142,7 +128,7 @@ public final class BtProfileConnectionInfo implements Parcelable { /** * @return The profile connection */ - public @BtProfile int getProfile() { + public int getProfile() { return mProfile; } diff --git a/media/java/android/media/MediaCodecInfo.java b/media/java/android/media/MediaCodecInfo.java index 3c152fb68c0a..77709d7d3823 100644 --- a/media/java/android/media/MediaCodecInfo.java +++ b/media/java/android/media/MediaCodecInfo.java @@ -426,10 +426,30 @@ public final class MediaCodecInfo { /** @deprecated Use {@link #COLOR_Format32bitABGR8888}. */ public static final int COLOR_Format24BitABGR6666 = 43; - /** @hide - * P010 is a 4:2:0 YCbCr semiplanar format comprised of a WxH Y plane - * followed by a Wx(H/2) CbCr plane. Each sample is represented by a 16-bit - * little-endian value, with the lower 6 bits set to zero. */ + /** + * P010 is 10-bit-per component 4:2:0 YCbCr semiplanar format. + * <p> + * This format uses 24 allocated bits per pixel with 15 bits of + * data per pixel. Chroma planes are subsampled by 2 both + * horizontally and vertically. Each chroma and luma component + * has 16 allocated bits in little-endian configuration with 10 + * MSB of actual data. + * + * <pre> + * byte byte + * <--------- i --------> | <------ i + 1 ------> + * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ + * | UNUSED | Y/Cb/Cr | + * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ + * 0 5 6 7 0 7 + * bit + * </pre> + * + * Use this format with {@link Image}. This format corresponds + * to {@link android.graphics.ImageFormat#YCBCR_P010}. + * <p> + */ + @SuppressLint("AllUpper") public static final int COLOR_FormatYUVP010 = 54; /** @deprecated Use {@link #COLOR_FormatYUV420Flexible}. */ @@ -439,6 +459,25 @@ public final class MediaCodecInfo { public static final int COLOR_FormatSurface = 0x7F000789; /** + * 64 bits per pixel RGBA color format, with 16-bit signed + * floating point red, green, blue, and alpha components. + * <p> + * + * <pre> + * byte byte byte byte + * <-- i -->|<- i+1 ->|<- i+2 ->|<- i+3 ->|<- i+4 ->|<- i+5 ->|<- i+6 ->|<- i+7 -> + * +---------+---------+-------------------+---------+---------+---------+---------+ + * | RED | GREEN | BLUE | ALPHA | + * +---------+---------+-------------------+---------+---------+---------+---------+ + * 0 7 0 7 0 7 0 7 0 7 0 7 0 7 0 7 + * </pre> + * + * This corresponds to {@link android.graphics.PixelFormat#RGBA_F16}. + */ + @SuppressLint("AllUpper") + public static final int COLOR_Format64bitABGRFloat = 0x7F000F16; + + /** * 32 bits per pixel RGBA color format, with 8-bit red, green, blue, and alpha components. * <p> * Using 32-bit little-endian representation, colors stored as Red 7:0, Green 15:8, @@ -456,6 +495,26 @@ public final class MediaCodecInfo { public static final int COLOR_Format32bitABGR8888 = 0x7F00A000; /** + * 32 bits per pixel RGBA color format, with 10-bit red, green, + * blue, and 2-bit alpha components. + * <p> + * Using 32-bit little-endian representation, colors stored as + * Red 9:0, Green 19:10, Blue 29:20, and Alpha 31:30. + * <pre> + * byte byte byte byte + * <------ i -----> | <---- i+1 ----> | <---- i+2 ----> | <---- i+3 -----> + * +-----------------+---+-------------+-------+---------+-----------+-----+ + * | RED | GREEN | BLUE |ALPHA| + * +-----------------+---+-------------+-------+---------+-----------+-----+ + * 0 7 0 1 2 7 0 3 4 7 0 5 6 7 + * </pre> + * + * This corresponds to {@link android.graphics.PixelFormat#RGBA_1010102}. + */ + @SuppressLint("AllUpper") + public static final int COLOR_Format32bitABGR2101010 = 0x7F00AAA2; + + /** * Flexible 12 bits per pixel, subsampled YUV color format with 8-bit chroma and luma * components. * <p> @@ -603,6 +662,18 @@ public final class MediaCodecInfo { public static final String FEATURE_QpBounds = "qp-bounds"; /** + * <b>video encoder only</b>: codec supports exporting encoding statistics. + * Encoders with this feature can provide the App clients with the encoding statistics + * information about the frame. + * The scope of encoding statistics is controlled by + * {@link MediaFormat#KEY_VIDEO_ENCODING_STATISTICS_LEVEL}. + * + * @see MediaFormat#KEY_VIDEO_ENCODING_STATISTICS_LEVEL + */ + @SuppressLint("AllUpper") // for consistency with other FEATURE_* constants + public static final String FEATURE_EncodingStatistics = "encoding-statistics"; + + /** * Query codec feature capabilities. * <p> * These features are supported to be used by the codec. These @@ -641,6 +712,7 @@ public final class MediaCodecInfo { new Feature(FEATURE_MultipleFrames, (1 << 1), false), new Feature(FEATURE_DynamicTimestamp, (1 << 2), false), new Feature(FEATURE_QpBounds, (1 << 3), false), + new Feature(FEATURE_EncodingStatistics, (1 << 4), false), // feature to exclude codec from REGULAR codec list new Feature(FEATURE_SpecialCodec, (1 << 30), false, true), }; @@ -3953,6 +4025,12 @@ public final class MediaCodecInfo { public static final int DolbyVisionLevelUhd30 = 0x40; public static final int DolbyVisionLevelUhd48 = 0x80; public static final int DolbyVisionLevelUhd60 = 0x100; + @SuppressLint("AllUpper") + public static final int DolbyVisionLevelUhd120 = 0x200; + @SuppressLint("AllUpper") + public static final int DolbyVisionLevel8k30 = 0x400; + @SuppressLint("AllUpper") + public static final int DolbyVisionLevel8k60 = 0x800; // Profiles and levels for AV1 Codec, corresponding to the definitions in // "AV1 Bitstream & Decoding Process Specification", Annex A diff --git a/media/java/android/media/MediaFormat.java b/media/java/android/media/MediaFormat.java index 9bf0db52f66d..aa5c404800e8 100644 --- a/media/java/android/media/MediaFormat.java +++ b/media/java/android/media/MediaFormat.java @@ -1102,6 +1102,76 @@ public final class MediaFormat { public static final String KEY_VIDEO_QP_B_MIN = "video-qp-b-min"; /** + * A key describing the level of encoding statistics information emitted from video encoder. + * + * The associated value is an integer. + */ + public static final String KEY_VIDEO_ENCODING_STATISTICS_LEVEL = + "video-encoding-statistics-level"; + + /** + * Encoding Statistics Level None. + * Encoder generates no information about Encoding statistics. + */ + public static final int VIDEO_ENCODING_STATISTICS_LEVEL_NONE = 0; + + /** + * Encoding Statistics Level 1. + * Encoder generates {@link MediaFormat#KEY_PICTURE_TYPE} and + * {@link MediaFormat#KEY_VIDEO_QP_AVERAGE} for each frame. + */ + public static final int VIDEO_ENCODING_STATISTICS_LEVEL_1 = 1; + + /** @hide */ + @IntDef({ + VIDEO_ENCODING_STATISTICS_LEVEL_NONE, + VIDEO_ENCODING_STATISTICS_LEVEL_1, + }) + @Retention(RetentionPolicy.SOURCE) + public @interface VideoEncodingStatisticsLevel {} + + /** + * A key describing the per-frame average block QP (Quantization Parameter). + * This is a part of a video 'Encoding Statistics' export feature. + * This value is emitted from video encoder for a video frame. + * The average value is rounded down (using floor()) to integer value. + * + * The associated value is an integer. + */ + public static final String KEY_VIDEO_QP_AVERAGE = "video-qp-average"; + + /** + * A key describing the picture type of the encoded frame. + * This is a part of a video 'Encoding Statistics' export feature. + * This value is emitted from video encoder for a video frame. + * + * The associated value is an integer. + */ + public static final String KEY_PICTURE_TYPE = "picture-type"; + + /** Picture Type is unknown. */ + public static final int PICTURE_TYPE_UNKNOWN = 0; + + /** Picture Type is I Frame. */ + public static final int PICTURE_TYPE_I = 1; + + /** Picture Type is P Frame. */ + public static final int PICTURE_TYPE_P = 2; + + /** Picture Type is B Frame. */ + public static final int PICTURE_TYPE_B = 3; + + /** @hide */ + @IntDef({ + PICTURE_TYPE_UNKNOWN, + PICTURE_TYPE_I, + PICTURE_TYPE_P, + PICTURE_TYPE_B, + }) + @Retention(RetentionPolicy.SOURCE) + public @interface PictureType {} + + /** * A key describing the audio session ID of the AudioTrack associated * to a tunneled video codec. * The associated value is an integer. diff --git a/packages/ConnectivityT/framework-t/Android.bp b/packages/ConnectivityT/framework-t/Android.bp index d3d8bba16c7c..223bdcdd9c95 100644 --- a/packages/ConnectivityT/framework-t/Android.bp +++ b/packages/ConnectivityT/framework-t/Android.bp @@ -129,6 +129,11 @@ filegroup { "src/android/net/EthernetNetworkSpecifier.java", "src/android/net/IEthernetManager.aidl", "src/android/net/IEthernetServiceListener.aidl", + "src/android/net/IInternalNetworkManagementListener.aidl", + "src/android/net/InternalNetworkUpdateRequest.java", + "src/android/net/InternalNetworkUpdateRequest.aidl", + "src/android/net/InternalNetworkManagementException.java", + "src/android/net/InternalNetworkManagementException.aidl", "src/android/net/ITetheredInterfaceCallback.aidl", ], path: "src", diff --git a/packages/ConnectivityT/framework-t/src/android/app/usage/NetworkStatsManager.java b/packages/ConnectivityT/framework-t/src/android/app/usage/NetworkStatsManager.java index 683678ad4671..84adef53e488 100644 --- a/packages/ConnectivityT/framework-t/src/android/app/usage/NetworkStatsManager.java +++ b/packages/ConnectivityT/framework-t/src/android/app/usage/NetworkStatsManager.java @@ -21,6 +21,7 @@ import static android.net.NetworkCapabilities.TRANSPORT_CELLULAR; import static android.net.NetworkCapabilities.TRANSPORT_WIFI; import android.Manifest; +import android.annotation.CallbackExecutor; import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.RequiresPermission; @@ -39,14 +40,11 @@ import android.net.NetworkStack; import android.net.NetworkStateSnapshot; import android.net.NetworkTemplate; import android.net.UnderlyingNetworkInfo; +import android.net.netstats.IUsageCallback; import android.net.netstats.provider.INetworkStatsProviderCallback; import android.net.netstats.provider.NetworkStatsProvider; -import android.os.Binder; import android.os.Build; import android.os.Handler; -import android.os.Looper; -import android.os.Message; -import android.os.Messenger; import android.os.RemoteException; import android.telephony.TelephonyManager; import android.text.TextUtils; @@ -57,6 +55,7 @@ import com.android.net.module.util.NetworkIdentityUtils; import java.util.List; import java.util.Objects; +import java.util.concurrent.Executor; /** * Provides access to network usage history and statistics. Usage data is collected in @@ -146,6 +145,18 @@ public class NetworkStatsManager { /** @hide */ public static final int FLAG_AUGMENT_WITH_SUBSCRIPTION_PLAN = 1 << 2; + /** + * Virtual RAT type to represent 5G NSA (Non Stand Alone) mode, where the primary cell is + * still LTE and network allocates a secondary 5G cell so telephony reports RAT = LTE along + * with NR state as connected. This is a concept added by NetworkStats on top of the telephony + * constants for backward compatibility of metrics so this should not be overlapped with any of + * the {@code TelephonyManager.NETWORK_TYPE_*} constants. + * + * @hide + */ + @SystemApi(client = MODULE_LIBRARIES) + public static final int NETWORK_TYPE_5G_NSA = -2; + private int mFlags; /** @hide */ @@ -157,6 +168,11 @@ public class NetworkStatsManager { setAugmentWithSubscriptionPlan(true); } + /** @hide */ + public INetworkStatsService getBinder() { + return mService; + } + /** * Set poll on open flag to indicate the poll is needed before service gets statistics * result. This is default enabled. However, for any non-privileged caller, the poll might @@ -718,26 +734,36 @@ public class NetworkStatsManager { } } - /** @hide */ - public void registerUsageCallback(NetworkTemplate template, int networkType, - long thresholdBytes, UsageCallback callback, @Nullable Handler handler) { + /** + * Registers to receive notifications about data usage on specified networks. + * + * <p>The callbacks will continue to be called as long as the process is alive or + * {@link #unregisterUsageCallback} is called. + * + * @param template Template used to match networks. See {@link NetworkTemplate}. + * @param thresholdBytes Threshold in bytes to be notified on. The provided value that lower + * than 2MiB will be clamped for non-privileged callers. + * @param executor The executor on which callback will be invoked. The provided {@link Executor} + * must run callback sequentially, otherwise the order of callbacks cannot be + * guaranteed. + * @param callback The {@link UsageCallback} that the system will call when data usage + * has exceeded the specified threshold. + * @hide + */ + @SystemApi(client = MODULE_LIBRARIES) + public void registerUsageCallback(@NonNull NetworkTemplate template, long thresholdBytes, + @NonNull @CallbackExecutor Executor executor, @NonNull UsageCallback callback) { + Objects.requireNonNull(template, "NetworkTemplate cannot be null"); Objects.requireNonNull(callback, "UsageCallback cannot be null"); + Objects.requireNonNull(executor, "Executor cannot be null"); - final Looper looper; - if (handler == null) { - looper = Looper.myLooper(); - } else { - looper = handler.getLooper(); - } - - DataUsageRequest request = new DataUsageRequest(DataUsageRequest.REQUEST_ID_UNSET, + final DataUsageRequest request = new DataUsageRequest(DataUsageRequest.REQUEST_ID_UNSET, template, thresholdBytes); try { - CallbackHandler callbackHandler = new CallbackHandler(looper, networkType, - template.getSubscriberId(), callback); + final UsageCallbackWrapper callbackWrapper = + new UsageCallbackWrapper(executor, callback); callback.request = mService.registerUsageCallback( - mContext.getOpPackageName(), request, new Messenger(callbackHandler), - new Binder()); + mContext.getOpPackageName(), request, callbackWrapper); if (DBG) Log.d(TAG, "registerUsageCallback returned " + callback.request); if (callback.request == null) { @@ -790,12 +816,15 @@ public class NetworkStatsManager { NetworkTemplate template = createTemplate(networkType, subscriberId); if (DBG) { Log.d(TAG, "registerUsageCallback called with: {" - + " networkType=" + networkType - + " subscriberId=" + subscriberId - + " thresholdBytes=" + thresholdBytes - + " }"); + + " networkType=" + networkType + + " subscriberId=" + subscriberId + + " thresholdBytes=" + thresholdBytes + + " }"); } - registerUsageCallback(template, networkType, thresholdBytes, callback, handler); + + final Executor executor = handler == null ? r -> r.run() : r -> handler.post(r); + + registerUsageCallback(template, thresholdBytes, executor, callback); } /** @@ -820,6 +849,26 @@ public class NetworkStatsManager { * Base class for usage callbacks. Should be extended by applications wanting notifications. */ public static abstract class UsageCallback { + /** + * Called when data usage has reached the given threshold. + * + * Called by {@code NetworkStatsService} when the registered threshold is reached. + * If a caller implements {@link #onThresholdReached(NetworkTemplate)}, the system + * will not call {@link #onThresholdReached(int, String)}. + * + * @param template The {@link NetworkTemplate} that associated with this callback. + * @hide + */ + @SystemApi(client = MODULE_LIBRARIES) + public void onThresholdReached(@NonNull NetworkTemplate template) { + // Backward compatibility for those who didn't override this function. + final int networkType = networkTypeForTemplate(template); + if (networkType != ConnectivityManager.TYPE_NONE) { + final String subscriberId = template.getSubscriberIds().isEmpty() ? null + : template.getSubscriberIds().iterator().next(); + onThresholdReached(networkType, subscriberId); + } + } /** * Called when data usage has reached the given threshold. @@ -830,6 +879,25 @@ public class NetworkStatsManager { * @hide used for internal bookkeeping */ private DataUsageRequest request; + + /** + * Get network type from a template if feasible. + * + * @param template the target {@link NetworkTemplate}. + * @return legacy network type, only supports for the types which is already supported in + * {@link #registerUsageCallback(int, String, long, UsageCallback, Handler)}. + * {@link ConnectivityManager#TYPE_NONE} for other types. + */ + private static int networkTypeForTemplate(@NonNull NetworkTemplate template) { + switch (template.getMatchRule()) { + case NetworkTemplate.MATCH_MOBILE: + return ConnectivityManager.TYPE_MOBILE; + case NetworkTemplate.MATCH_WIFI: + return ConnectivityManager.TYPE_WIFI; + default: + return ConnectivityManager.TYPE_NONE; + } + } } /** @@ -948,43 +1016,32 @@ public class NetworkStatsManager { } } - private static class CallbackHandler extends Handler { - private final int mNetworkType; - private final String mSubscriberId; - private UsageCallback mCallback; + private static class UsageCallbackWrapper extends IUsageCallback.Stub { + // Null if unregistered. + private volatile UsageCallback mCallback; + + private final Executor mExecutor; - CallbackHandler(Looper looper, int networkType, String subscriberId, - UsageCallback callback) { - super(looper); - mNetworkType = networkType; - mSubscriberId = subscriberId; + UsageCallbackWrapper(@NonNull Executor executor, @NonNull UsageCallback callback) { mCallback = callback; + mExecutor = executor; } @Override - public void handleMessage(Message message) { - DataUsageRequest request = - (DataUsageRequest) getObject(message, DataUsageRequest.PARCELABLE_KEY); - - switch (message.what) { - case CALLBACK_LIMIT_REACHED: { - if (mCallback != null) { - mCallback.onThresholdReached(mNetworkType, mSubscriberId); - } else { - Log.e(TAG, "limit reached with released callback for " + request); - } - break; - } - case CALLBACK_RELEASED: { - if (DBG) Log.d(TAG, "callback released for " + request); - mCallback = null; - break; - } + public void onThresholdReached(DataUsageRequest request) { + // Copy it to a local variable in case mCallback changed inside the if condition. + final UsageCallback callback = mCallback; + if (callback != null) { + mExecutor.execute(() -> callback.onThresholdReached(request.template)); + } else { + Log.e(TAG, "onThresholdReached with released callback for " + request); } } - private static Object getObject(Message msg, String key) { - return msg.getData().getParcelable(key); + @Override + public void onCallbackReleased(DataUsageRequest request) { + if (DBG) Log.d(TAG, "callback released for " + request); + mCallback = null; } } @@ -1066,4 +1123,52 @@ public class NetworkStatsManager { throw e.rethrowFromSystemServer(); } } + + /** + * Get a RAT type representative of a group of RAT types for network statistics. + * + * Collapse the given Radio Access Technology (RAT) type into a bucket that + * is representative of the original RAT type for network statistics. The + * mapping mostly corresponds to {@code TelephonyManager#NETWORK_CLASS_BIT_MASK_*} + * but with adaptations specific to the virtual types introduced by + * networks stats. + * + * @param ratType An integer defined in {@code TelephonyManager#NETWORK_TYPE_*}. + * + * @hide + */ + @SystemApi(client = MODULE_LIBRARIES) + public static int getCollapsedRatType(int ratType) { + switch (ratType) { + case TelephonyManager.NETWORK_TYPE_GPRS: + case TelephonyManager.NETWORK_TYPE_GSM: + case TelephonyManager.NETWORK_TYPE_EDGE: + case TelephonyManager.NETWORK_TYPE_IDEN: + case TelephonyManager.NETWORK_TYPE_CDMA: + case TelephonyManager.NETWORK_TYPE_1xRTT: + return TelephonyManager.NETWORK_TYPE_GSM; + case TelephonyManager.NETWORK_TYPE_EVDO_0: + case TelephonyManager.NETWORK_TYPE_EVDO_A: + case TelephonyManager.NETWORK_TYPE_EVDO_B: + case TelephonyManager.NETWORK_TYPE_EHRPD: + case TelephonyManager.NETWORK_TYPE_UMTS: + case TelephonyManager.NETWORK_TYPE_HSDPA: + case TelephonyManager.NETWORK_TYPE_HSUPA: + case TelephonyManager.NETWORK_TYPE_HSPA: + case TelephonyManager.NETWORK_TYPE_HSPAP: + case TelephonyManager.NETWORK_TYPE_TD_SCDMA: + return TelephonyManager.NETWORK_TYPE_UMTS; + case TelephonyManager.NETWORK_TYPE_LTE: + case TelephonyManager.NETWORK_TYPE_IWLAN: + return TelephonyManager.NETWORK_TYPE_LTE; + case TelephonyManager.NETWORK_TYPE_NR: + return TelephonyManager.NETWORK_TYPE_NR; + // Virtual RAT type for 5G NSA mode, see + // {@link NetworkStatsManager#NETWORK_TYPE_5G_NSA}. + case NetworkStatsManager.NETWORK_TYPE_5G_NSA: + return NetworkStatsManager.NETWORK_TYPE_5G_NSA; + default: + return TelephonyManager.NETWORK_TYPE_UNKNOWN; + } + } } diff --git a/core/java/android/net/IInternalNetworkManagementListener.aidl b/packages/ConnectivityT/framework-t/src/android/net/IInternalNetworkManagementListener.aidl index 69cde3bd14e8..69cde3bd14e8 100644 --- a/core/java/android/net/IInternalNetworkManagementListener.aidl +++ b/packages/ConnectivityT/framework-t/src/android/net/IInternalNetworkManagementListener.aidl diff --git a/packages/ConnectivityT/framework-t/src/android/net/INetworkStatsService.aidl b/packages/ConnectivityT/framework-t/src/android/net/INetworkStatsService.aidl index da0aa99b9370..efe626d3c939 100644 --- a/packages/ConnectivityT/framework-t/src/android/net/INetworkStatsService.aidl +++ b/packages/ConnectivityT/framework-t/src/android/net/INetworkStatsService.aidl @@ -24,6 +24,7 @@ import android.net.NetworkStats; import android.net.NetworkStatsHistory; import android.net.NetworkTemplate; import android.net.UnderlyingNetworkInfo; +import android.net.netstats.IUsageCallback; import android.net.netstats.provider.INetworkStatsProvider; import android.net.netstats.provider.INetworkStatsProviderCallback; import android.os.IBinder; @@ -71,7 +72,7 @@ interface INetworkStatsService { /** Registers a callback on data usage. */ DataUsageRequest registerUsageCallback(String callingPackage, - in DataUsageRequest request, in Messenger messenger, in IBinder binder); + in DataUsageRequest request, in IUsageCallback callback); /** Unregisters a callback on data usage. */ void unregisterUsageRequest(in DataUsageRequest request); diff --git a/core/java/android/net/InternalNetworkManagementException.aidl b/packages/ConnectivityT/framework-t/src/android/net/InternalNetworkManagementException.aidl index dcce706989f6..dcce706989f6 100644 --- a/core/java/android/net/InternalNetworkManagementException.aidl +++ b/packages/ConnectivityT/framework-t/src/android/net/InternalNetworkManagementException.aidl diff --git a/core/java/android/net/InternalNetworkManagementException.java b/packages/ConnectivityT/framework-t/src/android/net/InternalNetworkManagementException.java index 7f4e403f2259..7f4e403f2259 100644 --- a/core/java/android/net/InternalNetworkManagementException.java +++ b/packages/ConnectivityT/framework-t/src/android/net/InternalNetworkManagementException.java diff --git a/core/java/android/net/InternalNetworkUpdateRequest.aidl b/packages/ConnectivityT/framework-t/src/android/net/InternalNetworkUpdateRequest.aidl index da00cb97afb4..da00cb97afb4 100644 --- a/core/java/android/net/InternalNetworkUpdateRequest.aidl +++ b/packages/ConnectivityT/framework-t/src/android/net/InternalNetworkUpdateRequest.aidl diff --git a/core/java/android/net/InternalNetworkUpdateRequest.java b/packages/ConnectivityT/framework-t/src/android/net/InternalNetworkUpdateRequest.java index f42c4b7c420d..f42c4b7c420d 100644 --- a/core/java/android/net/InternalNetworkUpdateRequest.java +++ b/packages/ConnectivityT/framework-t/src/android/net/InternalNetworkUpdateRequest.java diff --git a/packages/ConnectivityT/framework-t/src/android/net/IpSecAlgorithm.java b/packages/ConnectivityT/framework-t/src/android/net/IpSecAlgorithm.java index a84e7a9c6344..10a22ac360b1 100644 --- a/packages/ConnectivityT/framework-t/src/android/net/IpSecAlgorithm.java +++ b/packages/ConnectivityT/framework-t/src/android/net/IpSecAlgorithm.java @@ -343,7 +343,7 @@ public final class IpSecAlgorithm implements Parcelable { // Load and validate the optional algorithm resource. Undefined or duplicate algorithms in // the resource are not allowed. final String[] resourceAlgos = systemResources.getStringArray( - com.android.internal.R.array.config_optionalIpSecAlgorithms); + android.R.array.config_optionalIpSecAlgorithms); for (String str : resourceAlgos) { if (!ALGO_TO_REQUIRED_FIRST_SDK.containsKey(str) || !enabledAlgos.add(str)) { // This error should be caught by CTS and never be thrown to API callers diff --git a/packages/ConnectivityT/framework-t/src/android/net/NetworkIdentity.java b/packages/ConnectivityT/framework-t/src/android/net/NetworkIdentity.java index 9b9d38a36066..56faa52e82df 100644 --- a/packages/ConnectivityT/framework-t/src/android/net/NetworkIdentity.java +++ b/packages/ConnectivityT/framework-t/src/android/net/NetworkIdentity.java @@ -16,6 +16,8 @@ package android.net; +import static android.annotation.SystemApi.Client.MODULE_LIBRARIES; +import static android.net.ConnectivityManager.TYPE_MOBILE; import static android.net.ConnectivityManager.TYPE_WIFI; import static android.net.NetworkTemplate.NETWORK_TYPE_ALL; @@ -23,13 +25,15 @@ import android.annotation.IntDef; import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.SuppressLint; +import android.annotation.SystemApi; +import android.app.usage.NetworkStatsManager; import android.content.Context; import android.net.wifi.WifiInfo; import android.service.NetworkIdentityProto; -import android.telephony.Annotation; import android.telephony.TelephonyManager; import android.util.proto.ProtoOutputStream; +import com.android.net.module.util.CollectionUtils; import com.android.net.module.util.NetworkCapabilitiesUtils; import com.android.net.module.util.NetworkIdentityUtils; @@ -44,8 +48,8 @@ import java.util.Objects; * * @hide */ -// @SystemApi(client = MODULE_LIBRARIES) -public class NetworkIdentity implements Comparable<NetworkIdentity> { +@SystemApi(client = MODULE_LIBRARIES) +public class NetworkIdentity { private static final String TAG = "NetworkIdentity"; /** @hide */ @@ -55,7 +59,7 @@ public class NetworkIdentity implements Comparable<NetworkIdentity> { /** @hide */ @Retention(RetentionPolicy.SOURCE) - @IntDef(prefix = { "OEM_MANAGED_" }, value = { + @IntDef(prefix = { "OEM_MANAGED_" }, flag = true, value = { NetworkTemplate.OEM_MANAGED_NO, NetworkTemplate.OEM_MANAGED_PAID, NetworkTemplate.OEM_MANAGED_PRIVATE @@ -71,12 +75,14 @@ public class NetworkIdentity implements Comparable<NetworkIdentity> { * Network has {@link NetworkCapabilities#NET_CAPABILITY_OEM_PAID}. * @hide */ - public static final int OEM_PAID = 0x1; + public static final int OEM_PAID = 1 << 0; /** * Network has {@link NetworkCapabilities#NET_CAPABILITY_OEM_PRIVATE}. * @hide */ - public static final int OEM_PRIVATE = 0x2; + public static final int OEM_PRIVATE = 1 << 1; + + private static final long SUPPORTED_OEM_MANAGED_TYPES = OEM_PAID | OEM_PRIVATE; final int mType; final int mRatType; @@ -206,7 +212,7 @@ public class NetworkIdentity implements Comparable<NetworkIdentity> { return mSubscriberId; } - /** Get the Wifi Network Key of this instance. See {@link WifiInfo#getCurrentNetworkKey()}. */ + /** Get the Wifi Network Key of this instance. See {@link WifiInfo#getNetworkKey()}. */ @Nullable public String getWifiNetworkKey() { return mWifiNetworkKey; @@ -218,7 +224,7 @@ public class NetworkIdentity implements Comparable<NetworkIdentity> { return mRoaming; } - /** Return the roaming status of this instance. */ + /** Return whether this network is roaming. */ public boolean isRoaming() { return mRoaming; } @@ -229,7 +235,7 @@ public class NetworkIdentity implements Comparable<NetworkIdentity> { return mMetered; } - /** Return the meteredness of this instance. */ + /** Return whether this network is metered. */ public boolean isMetered() { return mMetered; } @@ -240,7 +246,7 @@ public class NetworkIdentity implements Comparable<NetworkIdentity> { return mDefaultNetwork; } - /** Return the default network status of this instance. */ + /** Return whether this network is the default network. */ public boolean isDefaultNetwork() { return mDefaultNetwork; } @@ -262,16 +268,19 @@ public class NetworkIdentity implements Comparable<NetworkIdentity> { * {@link TelephonyManager#NETWORK_TYPE_UNKNOWN} if not applicable. * See {@code TelephonyManager.NETWORK_TYPE_*}. * @hide - * @deprecated See {@link NetworkIdentity#Builder}. + * @deprecated See {@link NetworkIdentity.Builder}. */ // TODO: Remove this after all callers are migrated to use new Api. @Deprecated @NonNull public static NetworkIdentity buildNetworkIdentity(Context context, - @NonNull NetworkStateSnapshot snapshot, - boolean defaultNetwork, @Annotation.NetworkType int ratType) { - return new NetworkIdentity.Builder().setNetworkStateSnapshot(snapshot) - .setDefaultNetwork(defaultNetwork).setRatType(ratType).build(); + @NonNull NetworkStateSnapshot snapshot, boolean defaultNetwork, int ratType) { + final NetworkIdentity.Builder builder = new NetworkIdentity.Builder() + .setNetworkStateSnapshot(snapshot).setDefaultNetwork(defaultNetwork); + if (snapshot.getLegacyType() == TYPE_MOBILE && ratType != NETWORK_TYPE_ALL) { + builder.setRatType(ratType); + } + return builder.build(); } /** @@ -291,30 +300,30 @@ public class NetworkIdentity implements Comparable<NetworkIdentity> { return oemManaged; } - @Override - public int compareTo(@NonNull NetworkIdentity another) { - Objects.requireNonNull(another); - int res = Integer.compare(mType, another.mType); + /** @hide */ + public static int compare(@NonNull NetworkIdentity left, @NonNull NetworkIdentity right) { + Objects.requireNonNull(right); + int res = Integer.compare(left.mType, right.mType); if (res == 0) { - res = Integer.compare(mRatType, another.mRatType); + res = Integer.compare(left.mRatType, right.mRatType); } - if (res == 0 && mSubscriberId != null && another.mSubscriberId != null) { - res = mSubscriberId.compareTo(another.mSubscriberId); + if (res == 0 && left.mSubscriberId != null && right.mSubscriberId != null) { + res = left.mSubscriberId.compareTo(right.mSubscriberId); } - if (res == 0 && mWifiNetworkKey != null && another.mWifiNetworkKey != null) { - res = mWifiNetworkKey.compareTo(another.mWifiNetworkKey); + if (res == 0 && left.mWifiNetworkKey != null && right.mWifiNetworkKey != null) { + res = left.mWifiNetworkKey.compareTo(right.mWifiNetworkKey); } if (res == 0) { - res = Boolean.compare(mRoaming, another.mRoaming); + res = Boolean.compare(left.mRoaming, right.mRoaming); } if (res == 0) { - res = Boolean.compare(mMetered, another.mMetered); + res = Boolean.compare(left.mMetered, right.mMetered); } if (res == 0) { - res = Boolean.compare(mDefaultNetwork, another.mDefaultNetwork); + res = Boolean.compare(left.mDefaultNetwork, right.mDefaultNetwork); } if (res == 0) { - res = Integer.compare(mOemManaged, another.mOemManaged); + res = Integer.compare(left.mOemManaged, right.mOemManaged); } return res; } @@ -323,6 +332,11 @@ public class NetworkIdentity implements Comparable<NetworkIdentity> { * Builder class for {@link NetworkIdentity}. */ public static final class Builder { + // Need to be synchronized with ConnectivityManager. + // TODO: Use {@link ConnectivityManager#MAX_NETWORK_TYPE} when this file is in the module. + private static final int MAX_NETWORK_TYPE = 18; // TYPE_TEST + private static final int MIN_NETWORK_TYPE = TYPE_MOBILE; + private int mType; private int mRatType; private String mSubscriberId; @@ -349,7 +363,14 @@ public class NetworkIdentity implements Comparable<NetworkIdentity> { /** * Add an {@link NetworkStateSnapshot} into the {@link NetworkIdentity} instance. - * This is to read roaming, metered, wifikey... from the snapshot for convenience. + * This is a useful shorthand that will read from the snapshot and set the + * following fields, if they are set in the snapshot : + * - type + * - subscriberId + * - roaming + * - metered + * - oemManaged + * - wifiNetworkKey * * @param snapshot The target {@link NetworkStateSnapshot} object. * @return The builder object. @@ -374,9 +395,7 @@ public class NetworkIdentity implements Comparable<NetworkIdentity> { .getTransportInfo(); if (transportInfo instanceof WifiInfo) { final WifiInfo info = (WifiInfo) transportInfo; - if (info != null) { - setWifiNetworkKey(info.getCurrentNetworkKey()); - } + setWifiNetworkKey(info.getNetworkKey()); } } return this; @@ -391,6 +410,12 @@ public class NetworkIdentity implements Comparable<NetworkIdentity> { */ @NonNull public Builder setType(int type) { + // Include TYPE_NONE for compatibility, type field might not be filled by some + // networks such as test networks. + if ((type < MIN_NETWORK_TYPE || MAX_NETWORK_TYPE < type) + && type != ConnectivityManager.TYPE_NONE) { + throw new IllegalArgumentException("Invalid network type: " + type); + } mType = type; return this; } @@ -398,13 +423,20 @@ public class NetworkIdentity implements Comparable<NetworkIdentity> { /** * Set the Radio Access Technology(RAT) type of the network. * + * No RAT type is specified by default. Call clearRatType to reset. + * * @param ratType the Radio Access Technology(RAT) type if applicable. See * {@code TelephonyManager.NETWORK_TYPE_*}. * * @return this builder. */ @NonNull - public Builder setRatType(@Annotation.NetworkType int ratType) { + public Builder setRatType(int ratType) { + if (!CollectionUtils.contains(TelephonyManager.getAllNetworkTypes(), ratType) + && ratType != TelephonyManager.NETWORK_TYPE_UNKNOWN + && ratType != NetworkStatsManager.NETWORK_TYPE_5G_NSA) { + throw new IllegalArgumentException("Invalid ratType " + ratType); + } mRatType = ratType; return this; } @@ -436,7 +468,7 @@ public class NetworkIdentity implements Comparable<NetworkIdentity> { * Set the Wifi Network Key. * * @param wifiNetworkKey Wifi Network Key of the network, - * see {@link WifiInfo#getCurrentNetworkKey()}. + * see {@link WifiInfo#getNetworkKey()}. * Or null if not applicable. * @return this builder. */ @@ -447,7 +479,9 @@ public class NetworkIdentity implements Comparable<NetworkIdentity> { } /** - * Set the roaming. + * Set whether this network is roaming. + * + * This field is false by default. Call with false to reset. * * @param roaming the roaming status of the network. * @return this builder. @@ -459,7 +493,9 @@ public class NetworkIdentity implements Comparable<NetworkIdentity> { } /** - * Set the meteredness. + * Set whether this network is metered. + * + * This field is false by default. Call with false to reset. * * @param metered the meteredness of the network. * @return this builder. @@ -471,7 +507,9 @@ public class NetworkIdentity implements Comparable<NetworkIdentity> { } /** - * Set the default network status. + * Set whether this network is the default network. + * + * This field is false by default. Call with false to reset. * * @param defaultNetwork the default network status of the network. * @return this builder. @@ -491,10 +529,27 @@ public class NetworkIdentity implements Comparable<NetworkIdentity> { */ @NonNull public Builder setOemManaged(@OemManaged int oemManaged) { + // Assert input does not contain illegal oemManage bits. + if ((~SUPPORTED_OEM_MANAGED_TYPES & oemManaged) != 0) { + throw new IllegalArgumentException("Invalid value for OemManaged : " + oemManaged); + } mOemManaged = oemManaged; return this; } + private void ensureValidParameters() { + // Assert non-mobile network cannot have a ratType. + if (mType != TYPE_MOBILE && mRatType != NetworkTemplate.NETWORK_TYPE_ALL) { + throw new IllegalArgumentException( + "Invalid ratType " + mRatType + " for type " + mType); + } + + // Assert non-wifi network cannot have a wifi network key. + if (mType != TYPE_WIFI && mWifiNetworkKey != null) { + throw new IllegalArgumentException("Invalid wifi network key for type " + mType); + } + } + /** * Builds the instance of the {@link NetworkIdentity}. * @@ -502,6 +557,7 @@ public class NetworkIdentity implements Comparable<NetworkIdentity> { */ @NonNull public NetworkIdentity build() { + ensureValidParameters(); return new NetworkIdentity(mType, mRatType, mSubscriberId, mWifiNetworkKey, mRoaming, mMetered, mDefaultNetwork, mOemManaged); } diff --git a/packages/ConnectivityT/framework-t/src/android/net/NetworkIdentitySet.java b/packages/ConnectivityT/framework-t/src/android/net/NetworkIdentitySet.java index 041f070512b0..dfa347f6f12b 100644 --- a/packages/ConnectivityT/framework-t/src/android/net/NetworkIdentitySet.java +++ b/packages/ConnectivityT/framework-t/src/android/net/NetworkIdentitySet.java @@ -27,6 +27,7 @@ import java.io.DataOutput; import java.io.IOException; import java.util.HashSet; import java.util.Objects; +import java.util.Set; /** * Identity of a {@code iface}, defined by the set of {@link NetworkIdentity} @@ -34,9 +35,7 @@ import java.util.Objects; * * @hide */ -// @SystemApi(client = MODULE_LIBRARIES) -public class NetworkIdentitySet extends HashSet<NetworkIdentity> implements - Comparable<NetworkIdentitySet> { +public class NetworkIdentitySet extends HashSet<NetworkIdentity> { private static final int VERSION_INIT = 1; private static final int VERSION_ADD_ROAMING = 2; private static final int VERSION_ADD_NETWORK_ID = 3; @@ -52,6 +51,11 @@ public class NetworkIdentitySet extends HashSet<NetworkIdentity> implements } /** @hide */ + public NetworkIdentitySet(@NonNull Set<NetworkIdentity> ident) { + super(ident); + } + + /** @hide */ public NetworkIdentitySet(DataInput in) throws IOException { final int version = in.readInt(); final int size = in.readInt(); @@ -189,15 +193,15 @@ public class NetworkIdentitySet extends HashSet<NetworkIdentity> implements } } - @Override - public int compareTo(@NonNull NetworkIdentitySet another) { - Objects.requireNonNull(another); - if (isEmpty()) return -1; - if (another.isEmpty()) return 1; + public static int compare(@NonNull NetworkIdentitySet left, @NonNull NetworkIdentitySet right) { + Objects.requireNonNull(left); + Objects.requireNonNull(right); + if (left.isEmpty()) return -1; + if (right.isEmpty()) return 1; - final NetworkIdentity ident = iterator().next(); - final NetworkIdentity anotherIdent = another.iterator().next(); - return ident.compareTo(anotherIdent); + final NetworkIdentity leftIdent = left.iterator().next(); + final NetworkIdentity rightIdent = right.iterator().next(); + return NetworkIdentity.compare(leftIdent, rightIdent); } /** diff --git a/packages/ConnectivityT/framework-t/src/android/net/NetworkStatsCollection.java b/packages/ConnectivityT/framework-t/src/android/net/NetworkStatsCollection.java index f169fed6b9b3..735c44d5c87e 100644 --- a/packages/ConnectivityT/framework-t/src/android/net/NetworkStatsCollection.java +++ b/packages/ConnectivityT/framework-t/src/android/net/NetworkStatsCollection.java @@ -16,6 +16,7 @@ package android.net; +import static android.annotation.SystemApi.Client.MODULE_LIBRARIES; import static android.net.NetworkStats.DEFAULT_NETWORK_NO; import static android.net.NetworkStats.DEFAULT_NETWORK_YES; import static android.net.NetworkStats.IFACE_ALL; @@ -34,6 +35,8 @@ import static com.android.net.module.util.NetworkStatsUtils.multiplySafeByRation import android.annotation.NonNull; import android.annotation.Nullable; +import android.annotation.SystemApi; +import android.net.NetworkStatsHistory.Entry; import android.os.Binder; import android.service.NetworkStatsCollectionKeyProto; import android.service.NetworkStatsCollectionProto; @@ -71,7 +74,10 @@ import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; import java.util.Iterator; +import java.util.List; +import java.util.Map; import java.util.Objects; +import java.util.Set; /** * Collection of {@link NetworkStatsHistory}, stored based on combined key of @@ -79,7 +85,7 @@ import java.util.Objects; * * @hide */ -// @SystemApi(client = MODULE_LIBRARIES) +@SystemApi(client = MODULE_LIBRARIES) public class NetworkStatsCollection implements FileRotator.Reader, FileRotator.Writer { private static final String TAG = NetworkStatsCollection.class.getSimpleName(); /** File header magic number: "ANET" */ @@ -702,7 +708,7 @@ public class NetworkStatsCollection implements FileRotator.Reader, FileRotator.W private ArrayList<Key> getSortedKeys() { final ArrayList<Key> keys = new ArrayList<>(); keys.addAll(mStats.keySet()); - Collections.sort(keys); + Collections.sort(keys, (left, right) -> Key.compare(left, right)); return keys; } @@ -809,10 +815,75 @@ public class NetworkStatsCollection implements FileRotator.Reader, FileRotator.W } /** + * Get the all historical stats of the collection {@link NetworkStatsCollection}. + * + * @return All {@link NetworkStatsHistory} in this collection. + */ + @NonNull + public Map<Key, NetworkStatsHistory> getEntries() { + return new ArrayMap(mStats); + } + + /** + * Builder class for {@link NetworkStatsCollection}. + */ + public static final class Builder { + private final long mBucketDuration; + private final ArrayMap<Key, NetworkStatsHistory> mEntries = new ArrayMap<>(); + + /** + * Creates a new Builder with given bucket duration. + * + * @param bucketDuration Duration of the buckets of the object, in milliseconds. + */ + public Builder(long bucketDuration) { + mBucketDuration = bucketDuration; + } + + /** + * Add association of the history with the specified key in this map. + * + * @param key The object used to identify a network, see {@link Key}. + * @param history {@link NetworkStatsHistory} instance associated to the given {@link Key}. + * @return The builder object. + */ + @NonNull + public NetworkStatsCollection.Builder addEntry(@NonNull Key key, + @NonNull NetworkStatsHistory history) { + Objects.requireNonNull(key); + Objects.requireNonNull(history); + final List<Entry> historyEntries = history.getEntries(); + + final NetworkStatsHistory.Builder historyBuilder = + new NetworkStatsHistory.Builder(mBucketDuration, historyEntries.size()); + for (Entry entry : historyEntries) { + historyBuilder.addEntry(entry); + } + + mEntries.put(key, historyBuilder.build()); + return this; + } + + /** + * Builds the instance of the {@link NetworkStatsCollection}. + * + * @return the built instance of {@link NetworkStatsCollection}. + */ + @NonNull + public NetworkStatsCollection build() { + final NetworkStatsCollection collection = new NetworkStatsCollection(mBucketDuration); + for (int i = 0; i < mEntries.size(); i++) { + collection.recordHistory(mEntries.keyAt(i), mEntries.valueAt(i)); + } + return collection; + } + } + + /** * the identifier that associate with the {@link NetworkStatsHistory} object to identify * a certain record in the {@link NetworkStatsCollection} object. */ - public static class Key implements Comparable<Key> { + public static class Key { /** @hide */ public final NetworkIdentitySet ident; /** @hide */ @@ -832,6 +903,11 @@ public class NetworkStatsCollection implements FileRotator.Reader, FileRotator.W * @param set Set of the record, see {@code NetworkStats#SET_*}. * @param tag Tag of the record, see {@link TrafficStats#setThreadStatsTag(int)}. */ + public Key(@NonNull Set<NetworkIdentity> ident, int uid, int set, int tag) { + this(new NetworkIdentitySet(Objects.requireNonNull(ident)), uid, set, tag); + } + + /** @hide */ public Key(@NonNull NetworkIdentitySet ident, int uid, int set, int tag) { this.ident = Objects.requireNonNull(ident); this.uid = uid; @@ -855,21 +931,22 @@ public class NetworkStatsCollection implements FileRotator.Reader, FileRotator.W return false; } - @Override - public int compareTo(@NonNull Key another) { - Objects.requireNonNull(another); + /** @hide */ + public static int compare(@NonNull Key left, @NonNull Key right) { + Objects.requireNonNull(left); + Objects.requireNonNull(right); int res = 0; - if (ident != null && another.ident != null) { - res = ident.compareTo(another.ident); + if (left.ident != null && right.ident != null) { + res = NetworkIdentitySet.compare(left.ident, right.ident); } if (res == 0) { - res = Integer.compare(uid, another.uid); + res = Integer.compare(left.uid, right.uid); } if (res == 0) { - res = Integer.compare(set, another.set); + res = Integer.compare(left.set, right.set); } if (res == 0) { - res = Integer.compare(tag, another.tag); + res = Integer.compare(left.tag, right.tag); } return res; } diff --git a/packages/ConnectivityT/framework-t/src/android/net/NetworkStatsHistory.java b/packages/ConnectivityT/framework-t/src/android/net/NetworkStatsHistory.java index 90054c683de5..78c137073aaa 100644 --- a/packages/ConnectivityT/framework-t/src/android/net/NetworkStatsHistory.java +++ b/packages/ConnectivityT/framework-t/src/android/net/NetworkStatsHistory.java @@ -16,6 +16,7 @@ package android.net; +import static android.annotation.SystemApi.Client.MODULE_LIBRARIES; import static android.net.NetworkStats.IFACE_ALL; import static android.net.NetworkStats.SET_DEFAULT; import static android.net.NetworkStats.TAG_NONE; @@ -31,6 +32,7 @@ import static android.text.format.DateUtils.SECOND_IN_MILLIS; import static com.android.net.module.util.NetworkStatsUtils.multiplySafeByRational; import android.annotation.NonNull; +import android.annotation.SystemApi; import android.compat.annotation.UnsupportedAppUsage; import android.os.Build; import android.os.Parcel; @@ -51,7 +53,9 @@ import java.io.DataOutput; import java.io.IOException; import java.io.PrintWriter; import java.net.ProtocolException; +import java.util.ArrayList; import java.util.Arrays; +import java.util.List; import java.util.Random; /** @@ -65,7 +69,7 @@ import java.util.Random; * * @hide */ -// @SystemApi(client = MODULE_LIBRARIES) +@SystemApi(client = MODULE_LIBRARIES) public final class NetworkStatsHistory implements Parcelable { private static final int VERSION_INIT = 1; private static final int VERSION_ADD_PACKETS = 2; @@ -97,23 +101,157 @@ public final class NetworkStatsHistory implements Parcelable { private long[] operations; private long totalBytes; - public static class Entry { + /** @hide */ + public NetworkStatsHistory(long bucketDuration, long[] bucketStart, long[] activeTime, + long[] rxBytes, long[] rxPackets, long[] txBytes, long[] txPackets, + long[] operations, int bucketCount, long totalBytes) { + this.bucketDuration = bucketDuration; + this.bucketStart = bucketStart; + this.activeTime = activeTime; + this.rxBytes = rxBytes; + this.rxPackets = rxPackets; + this.txBytes = txBytes; + this.txPackets = txPackets; + this.operations = operations; + this.bucketCount = bucketCount; + this.totalBytes = totalBytes; + } + + /** + * An instance to represent a single record in a {@link NetworkStatsHistory} object. + */ + public static final class Entry { + /** @hide */ public static final long UNKNOWN = -1; + /** @hide */ + // TODO: Migrate all callers to get duration from the history object and remove this field. @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public long bucketDuration; + /** @hide */ @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public long bucketStart; + /** @hide */ public long activeTime; + /** @hide */ @UnsupportedAppUsage public long rxBytes; + /** @hide */ @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public long rxPackets; + /** @hide */ @UnsupportedAppUsage public long txBytes; + /** @hide */ @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public long txPackets; + /** @hide */ public long operations; + /** @hide */ + Entry() {} + + /** + * Construct a {@link Entry} instance to represent a single record in a + * {@link NetworkStatsHistory} object. + * + * @param bucketStart Start of period for this {@link Entry}, in milliseconds since the + * Unix epoch, see {@link java.lang.System#currentTimeMillis}. + * @param activeTime Active time for this {@link Entry}, in milliseconds. + * @param rxBytes Number of bytes received for this {@link Entry}. Statistics should + * represent the contents of IP packets, including IP headers. + * @param rxPackets Number of packets received for this {@link Entry}. Statistics should + * represent the contents of IP packets, including IP headers. + * @param txBytes Number of bytes transmitted for this {@link Entry}. Statistics should + * represent the contents of IP packets, including IP headers. + * @param txPackets Number of bytes transmitted for this {@link Entry}. Statistics should + * represent the contents of IP packets, including IP headers. + * @param operations count of network operations performed for this {@link Entry}. This can + * be used to derive bytes-per-operation. + */ + public Entry(long bucketStart, long activeTime, long rxBytes, + long rxPackets, long txBytes, long txPackets, long operations) { + this.bucketStart = bucketStart; + this.activeTime = activeTime; + this.rxBytes = rxBytes; + this.rxPackets = rxPackets; + this.txBytes = txBytes; + this.txPackets = txPackets; + this.operations = operations; + } + + /** + * Get start timestamp of the bucket's time interval, in milliseconds since the Unix epoch. + */ + public long getBucketStart() { + return bucketStart; + } + + /** + * Get active time of the bucket's time interval, in milliseconds. + */ + public long getActiveTime() { + return activeTime; + } + + /** Get number of bytes received for this {@link Entry}. */ + public long getRxBytes() { + return rxBytes; + } + + /** Get number of packets received for this {@link Entry}. */ + public long getRxPackets() { + return rxPackets; + } + + /** Get number of bytes transmitted for this {@link Entry}. */ + public long getTxBytes() { + return txBytes; + } + + /** Get number of packets transmitted for this {@link Entry}. */ + public long getTxPackets() { + return txPackets; + } + + /** Get count of network operations performed for this {@link Entry}. */ + public long getOperations() { + return operations; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o.getClass() != getClass()) return false; + Entry entry = (Entry) o; + return bucketStart == entry.bucketStart + && activeTime == entry.activeTime && rxBytes == entry.rxBytes + && rxPackets == entry.rxPackets && txBytes == entry.txBytes + && txPackets == entry.txPackets && operations == entry.operations; + } + + @Override + public int hashCode() { + return (int) (bucketStart * 2 + + activeTime * 3 + + rxBytes * 5 + + rxPackets * 7 + + txBytes * 11 + + txPackets * 13 + + operations * 17); + } + + @Override + public String toString() { + return "Entry{" + + "bucketStart=" + bucketStart + + ", activeTime=" + activeTime + + ", rxBytes=" + rxBytes + + ", rxPackets=" + rxPackets + + ", txBytes=" + txBytes + + ", txPackets=" + txPackets + + ", operations=" + operations + + "}"; + } } /** @hide */ @@ -324,6 +462,22 @@ public final class NetworkStatsHistory implements Parcelable { return entry; } + /** + * Get List of {@link Entry} of the {@link NetworkStatsHistory} instance. + * + * @return + */ + @NonNull + public List<Entry> getEntries() { + // TODO: Return a wrapper that uses this list instead, to prevent the returned result + // from being changed. + final ArrayList<Entry> ret = new ArrayList<>(size()); + for (int i = 0; i < size(); i++) { + ret.add(getValues(i, null /* recycle */)); + } + return ret; + } + /** @hide */ public void setValues(int i, Entry entry) { // Unwind old values @@ -928,4 +1082,80 @@ public final class NetworkStatsHistory implements Parcelable { } } + /** + * Builder class for {@link NetworkStatsHistory}. + */ + public static final class Builder { + private final long mBucketDuration; + private final List<Long> mBucketStart; + private final List<Long> mActiveTime; + private final List<Long> mRxBytes; + private final List<Long> mRxPackets; + private final List<Long> mTxBytes; + private final List<Long> mTxPackets; + private final List<Long> mOperations; + + /** + * Creates a new Builder with given bucket duration and initial capacity to construct + * {@link NetworkStatsHistory} objects. + * + * @param bucketDuration Duration of the buckets of the object, in milliseconds. + * @param initialCapacity Estimated number of records. + */ + public Builder(long bucketDuration, int initialCapacity) { + mBucketDuration = bucketDuration; + mBucketStart = new ArrayList<>(initialCapacity); + mActiveTime = new ArrayList<>(initialCapacity); + mRxBytes = new ArrayList<>(initialCapacity); + mRxPackets = new ArrayList<>(initialCapacity); + mTxBytes = new ArrayList<>(initialCapacity); + mTxPackets = new ArrayList<>(initialCapacity); + mOperations = new ArrayList<>(initialCapacity); + } + + /** + * Add an {@link Entry} into the {@link NetworkStatsHistory} instance. + * + * @param entry The target {@link Entry} object. + * @return The builder object. + */ + @NonNull + public Builder addEntry(@NonNull Entry entry) { + mBucketStart.add(entry.bucketStart); + mActiveTime.add(entry.activeTime); + mRxBytes.add(entry.rxBytes); + mRxPackets.add(entry.rxPackets); + mTxBytes.add(entry.txBytes); + mTxPackets.add(entry.txPackets); + mOperations.add(entry.operations); + return this; + } + + private static long sum(@NonNull List<Long> list) { + long sum = 0; + for (long entry : list) { + sum += entry; + } + return sum; + } + + /** + * Builds the instance of the {@link NetworkStatsHistory}. + * + * @return the built instance of {@link NetworkStatsHistory}. + */ + @NonNull + public NetworkStatsHistory build() { + return new NetworkStatsHistory(mBucketDuration, + CollectionUtils.toLongArray(mBucketStart), + CollectionUtils.toLongArray(mActiveTime), + CollectionUtils.toLongArray(mRxBytes), + CollectionUtils.toLongArray(mRxPackets), + CollectionUtils.toLongArray(mTxBytes), + CollectionUtils.toLongArray(mTxPackets), + CollectionUtils.toLongArray(mOperations), + mBucketStart.size(), + sum(mRxBytes) + sum(mTxBytes)); + } + } } diff --git a/packages/ConnectivityT/framework-t/src/android/net/NetworkTemplate.java b/packages/ConnectivityT/framework-t/src/android/net/NetworkTemplate.java index a7e48d43631b..9b58b016bbf3 100644 --- a/packages/ConnectivityT/framework-t/src/android/net/NetworkTemplate.java +++ b/packages/ConnectivityT/framework-t/src/android/net/NetworkTemplate.java @@ -41,13 +41,12 @@ import android.annotation.IntDef; import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.SystemApi; +import android.app.usage.NetworkStatsManager; import android.compat.annotation.UnsupportedAppUsage; import android.net.wifi.WifiInfo; import android.os.Build; import android.os.Parcel; import android.os.Parcelable; -import android.telephony.Annotation.NetworkType; -import android.telephony.TelephonyManager; import android.text.TextUtils; import android.util.ArraySet; @@ -58,9 +57,7 @@ import com.android.net.module.util.NetworkStatsUtils; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.util.Arrays; -import java.util.Collection; import java.util.Comparator; -import java.util.HashSet; import java.util.List; import java.util.Objects; import java.util.Set; @@ -136,15 +133,6 @@ public final class NetworkTemplate implements Parcelable { * {@code TelephonyManager.NETWORK_TYPE_*} constants, and thus needs to stay in sync. */ public static final int NETWORK_TYPE_ALL = -1; - /** - * Virtual RAT type to represent 5G NSA (Non Stand Alone) mode, where the primary cell is - * still LTE and network allocates a secondary 5G cell so telephony reports RAT = LTE along - * with NR state as connected. This should not be overlapped with any of the - * {@code TelephonyManager.NETWORK_TYPE_*} constants. - * - * @hide - */ - public static final int NETWORK_TYPE_5G_NSA = -2; /** @hide */ @Retention(RetentionPolicy.SOURCE) @@ -214,7 +202,7 @@ public final class NetworkTemplate implements Parcelable { * @hide */ public static NetworkTemplate buildTemplateMobileWithRatType(@Nullable String subscriberId, - @NetworkType int ratType, int metered) { + int ratType, int metered) { if (TextUtils.isEmpty(subscriberId)) { return new NetworkTemplate(MATCH_MOBILE_WILDCARD, null /* subscriberId */, null /* matchSubscriberIds */, @@ -263,7 +251,7 @@ public final class NetworkTemplate implements Parcelable { * Template to match {@link ConnectivityManager#TYPE_WIFI} networks with the * given key of the wifi network. * - * @param wifiNetworkKey key of the wifi network. see {@link WifiInfo#getCurrentNetworkKey()} + * @param wifiNetworkKey key of the wifi network. see {@link WifiInfo#getNetworkKey()} * to know details about the key. * @hide */ @@ -283,7 +271,7 @@ public final class NetworkTemplate implements Parcelable { * Call with {@link #WIFI_NETWORK_KEY_ALL} for {@code wifiNetworkKey} to get result regardless * of key of the wifi network. * - * @param wifiNetworkKey key of the wifi network. see {@link WifiInfo#getCurrentNetworkKey()} + * @param wifiNetworkKey key of the wifi network. see {@link WifiInfo#getNetworkKey()} * to know details about the key. * @param subscriberId the IMSI associated to this wifi network. * @@ -593,7 +581,7 @@ public final class NetworkTemplate implements Parcelable { /** * Get the set of Wifi Network Keys of the template. - * See {@link WifiInfo#getCurrentNetworkKey()}. + * See {@link WifiInfo#getNetworkKey()}. */ @NonNull public Set<String> getWifiNetworkKeys() { @@ -652,7 +640,9 @@ public final class NetworkTemplate implements Parcelable { * * @hide */ - public boolean matches(NetworkIdentity ident) { + @SystemApi(client = MODULE_LIBRARIES) + public boolean matches(@NonNull NetworkIdentity ident) { + Objects.requireNonNull(ident); if (!matchesMetered(ident)) return false; if (!matchesRoaming(ident)) return false; if (!matchesDefaultNetwork(ident)) return false; @@ -709,7 +699,8 @@ public final class NetworkTemplate implements Parcelable { private boolean matchesCollapsedRatType(NetworkIdentity ident) { return mRatType == NETWORK_TYPE_ALL - || getCollapsedRatType(mRatType) == getCollapsedRatType(ident.mRatType); + || NetworkStatsManager.getCollapsedRatType(mRatType) + == NetworkStatsManager.getCollapsedRatType(ident.mRatType); } /** @@ -729,7 +720,7 @@ public final class NetworkTemplate implements Parcelable { * Returns true when the key matches, or when {@code mMatchWifiNetworkKeys} is * empty. * - * @param wifiNetworkKey key of the wifi network. see {@link WifiInfo#getCurrentNetworkKey()} + * @param wifiNetworkKey key of the wifi network. see {@link WifiInfo#getNetworkKey()} * to know details about the key. */ private boolean matchesWifiNetworkKey(@NonNull String wifiNetworkKey) { @@ -753,84 +744,6 @@ public final class NetworkTemplate implements Parcelable { } /** - * Get a Radio Access Technology(RAT) type that is representative of a group of RAT types. - * The mapping is corresponding to {@code TelephonyManager#NETWORK_CLASS_BIT_MASK_*}. - * - * @param ratType An integer defined in {@code TelephonyManager#NETWORK_TYPE_*}. - * - * @hide - */ - // TODO: 1. Consider move this to TelephonyManager if used by other modules. - // 2. Consider make this configurable. - // 3. Use TelephonyManager APIs when available. - // TODO: @SystemApi when ready. - public static int getCollapsedRatType(int ratType) { - switch (ratType) { - case TelephonyManager.NETWORK_TYPE_GPRS: - case TelephonyManager.NETWORK_TYPE_GSM: - case TelephonyManager.NETWORK_TYPE_EDGE: - case TelephonyManager.NETWORK_TYPE_IDEN: - case TelephonyManager.NETWORK_TYPE_CDMA: - case TelephonyManager.NETWORK_TYPE_1xRTT: - return TelephonyManager.NETWORK_TYPE_GSM; - case TelephonyManager.NETWORK_TYPE_EVDO_0: - case TelephonyManager.NETWORK_TYPE_EVDO_A: - case TelephonyManager.NETWORK_TYPE_EVDO_B: - case TelephonyManager.NETWORK_TYPE_EHRPD: - case TelephonyManager.NETWORK_TYPE_UMTS: - case TelephonyManager.NETWORK_TYPE_HSDPA: - case TelephonyManager.NETWORK_TYPE_HSUPA: - case TelephonyManager.NETWORK_TYPE_HSPA: - case TelephonyManager.NETWORK_TYPE_HSPAP: - case TelephonyManager.NETWORK_TYPE_TD_SCDMA: - return TelephonyManager.NETWORK_TYPE_UMTS; - case TelephonyManager.NETWORK_TYPE_LTE: - case TelephonyManager.NETWORK_TYPE_IWLAN: - return TelephonyManager.NETWORK_TYPE_LTE; - case TelephonyManager.NETWORK_TYPE_NR: - return TelephonyManager.NETWORK_TYPE_NR; - // Virtual RAT type for 5G NSA mode, see {@link NetworkTemplate#NETWORK_TYPE_5G_NSA}. - case NetworkTemplate.NETWORK_TYPE_5G_NSA: - return NetworkTemplate.NETWORK_TYPE_5G_NSA; - default: - return TelephonyManager.NETWORK_TYPE_UNKNOWN; - } - } - - /** - * Return all supported collapsed RAT types that could be returned by - * {@link #getCollapsedRatType(int)}. - * - * @hide - */ - // TODO: @SystemApi when ready. - @NonNull - public static final int[] getAllCollapsedRatTypes() { - final int[] ratTypes = TelephonyManager.getAllNetworkTypes(); - final HashSet<Integer> collapsedRatTypes = new HashSet<>(); - for (final int ratType : ratTypes) { - collapsedRatTypes.add(NetworkTemplate.getCollapsedRatType(ratType)); - } - // Add NETWORK_TYPE_5G_NSA to the returned list since 5G NSA is a virtual RAT type and - // it is not in TelephonyManager#NETWORK_TYPE_* constants. - // See {@link NetworkTemplate#NETWORK_TYPE_5G_NSA}. - collapsedRatTypes.add(NetworkTemplate.getCollapsedRatType(NETWORK_TYPE_5G_NSA)); - // Ensure that unknown type is returned. - collapsedRatTypes.add(TelephonyManager.NETWORK_TYPE_UNKNOWN); - return toIntArray(collapsedRatTypes); - } - - @NonNull - private static int[] toIntArray(@NonNull Collection<Integer> list) { - final int[] array = new int[list.size()]; - int i = 0; - for (final Integer item : list) { - array[i++] = item; - } - return array; - } - - /** * Check if matches Wi-Fi network template. */ private boolean matchesWifi(NetworkIdentity ident) { @@ -1059,9 +972,9 @@ public final class NetworkTemplate implements Parcelable { * the intention of matching any Wifi Network Key. * * @param wifiNetworkKeys the list of Wifi Network Key, - * see {@link WifiInfo#getCurrentNetworkKey()}. + * see {@link WifiInfo#getNetworkKey()}. * Or an empty list to match all networks. - * Note that {@code getCurrentNetworkKey()} might get null key + * Note that {@code getNetworkKey()} might get null key * when wifi disconnects. However, the caller should never invoke * this function with a null Wifi Network Key since such statistics * never exists. @@ -1125,7 +1038,7 @@ public final class NetworkTemplate implements Parcelable { * @return this builder. */ @NonNull - public Builder setRatType(@NetworkType int ratType) { + public Builder setRatType(int ratType) { // Input will be validated with the match rule when building the template. mRatType = ratType; return this; diff --git a/packages/ConnectivityT/framework-t/src/android/net/TrafficStats.java b/packages/ConnectivityT/framework-t/src/android/net/TrafficStats.java index 1af32bf5524c..c2f0cdfb048c 100644 --- a/packages/ConnectivityT/framework-t/src/android/net/TrafficStats.java +++ b/packages/ConnectivityT/framework-t/src/android/net/TrafficStats.java @@ -16,8 +16,9 @@ package android.net; +import static android.annotation.SystemApi.Client.MODULE_LIBRARIES; + import android.annotation.NonNull; -import android.annotation.Nullable; import android.annotation.SuppressLint; import android.annotation.SystemApi; import android.annotation.TestApi; @@ -27,9 +28,10 @@ import android.app.usage.NetworkStatsManager; import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; import android.media.MediaPlayer; +import android.os.Binder; import android.os.Build; -import android.os.IBinder; import android.os.RemoteException; +import android.util.Log; import com.android.server.NetworkManagementSocketTagger; @@ -37,8 +39,6 @@ import dalvik.system.SocketTagger; import java.io.FileDescriptor; import java.io.IOException; -import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Method; import java.net.DatagramSocket; import java.net.Socket; import java.net.SocketException; @@ -177,25 +177,12 @@ public class TrafficStats { @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 130143562) private synchronized static INetworkStatsService getStatsService() { if (sStatsService == null) { - sStatsService = getStatsBinder(); + throw new IllegalStateException("TrafficStats not initialized, uid=" + + Binder.getCallingUid()); } return sStatsService; } - @Nullable - private static INetworkStatsService getStatsBinder() { - try { - final Method getServiceMethod = Class.forName("android.os.ServiceManager") - .getDeclaredMethod("getService", new Class[]{String.class}); - final IBinder binder = (IBinder) getServiceMethod.invoke( - null, Context.NETWORK_STATS_SERVICE); - return INetworkStatsService.Stub.asInterface(binder); - } catch (NoSuchMethodException | ClassNotFoundException | IllegalAccessException - | InvocationTargetException e) { - throw new NullPointerException("Cannot get INetworkStatsService: " + e); - } - } - /** * Snapshot of {@link NetworkStats} when the currently active profiling * session started, or {@code null} if no session active. @@ -210,6 +197,45 @@ public class TrafficStats { private static final String LOOPBACK_IFACE = "lo"; /** + * Initialization {@link TrafficStats} with the context, to + * allow {@link TrafficStats} to fetch the needed binder. + * + * @param context a long-lived context, such as the application context or system + * server context. + * @hide + */ + @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES) + @SuppressLint("VisiblySynchronized") + public static synchronized void init(@NonNull final Context context) { + if (sStatsService != null) { + throw new IllegalStateException("TrafficStats is already initialized, uid=" + + Binder.getCallingUid()); + } + final NetworkStatsManager statsManager = + context.getSystemService(NetworkStatsManager.class); + if (statsManager == null) { + // TODO: Currently Process.isSupplemental is not working yet, because it depends on + // process to run in a certain UID range, which is not true for now. Change this + // to Log.wtf once Process.isSupplemental is ready. + Log.e(TAG, "TrafficStats not initialized, uid=" + Binder.getCallingUid()); + return; + } + sStatsService = statsManager.getBinder(); + } + + /** + * Attach the socket tagger implementation to the current process, to + * get notified when a socket's {@link FileDescriptor} is assigned to + * a thread. See {@link SocketTagger#set(SocketTagger)}. + * + * @hide + */ + @SystemApi(client = MODULE_LIBRARIES) + public static void attachSocketTagger() { + NetworkManagementSocketTagger.install(); + } + + /** * Set active tag to use when accounting {@link Socket} traffic originating * from the current thread. Only one active tag per thread is supported. * <p> diff --git a/packages/ConnectivityT/framework-t/src/android/net/netstats/IUsageCallback.aidl b/packages/ConnectivityT/framework-t/src/android/net/netstats/IUsageCallback.aidl new file mode 100644 index 000000000000..4e8a5b23093a --- /dev/null +++ b/packages/ConnectivityT/framework-t/src/android/net/netstats/IUsageCallback.aidl @@ -0,0 +1,29 @@ +/* + * Copyright (C) 2022 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.net.netstats; + +import android.net.DataUsageRequest; + +/** + * Interface for NetworkStatsService to notify events to the callers of registerUsageCallback. + * + * @hide + */ +oneway interface IUsageCallback { + void onThresholdReached(in DataUsageRequest request); + void onCallbackReleased(in DataUsageRequest request); +} diff --git a/packages/ConnectivityT/service/Android.bp b/packages/ConnectivityT/service/Android.bp index b261e165a112..24bc91d91ef7 100644 --- a/packages/ConnectivityT/service/Android.bp +++ b/packages/ConnectivityT/service/Android.bp @@ -26,6 +26,8 @@ filegroup { srcs: [ "src/com/android/server/net/NetworkIdentity*.java", "src/com/android/server/net/NetworkStats*.java", + "src/com/android/server/net/BpfInterfaceMapUpdater.java", + "src/com/android/server/net/InterfaceMapValue.java", ], path: "src", visibility: [ @@ -66,6 +68,7 @@ filegroup { filegroup { name: "services.connectivity-ethernet-sources", srcs: [ + "src/com/android/server/net/DelayedDiskWrite.java", "src/com/android/server/net/IpConfigStore.java", ], path: "src", @@ -97,3 +100,28 @@ filegroup { "//packages/modules/Connectivity:__subpackages__", ], } + +cc_library_shared { + name: "libcom_android_net_module_util_jni", + min_sdk_version: "30", + cflags: [ + "-Wall", + "-Werror", + "-Wno-unused-parameter", + "-Wthread-safety", + ], + srcs: [ + "jni/onload.cpp", + ], + stl: "libc++_static", + static_libs: [ + "libnet_utils_device_common_bpfjni", + ], + shared_libs: [ + "liblog", + "libnativehelper", + ], + apex_available: [ + "//apex_available:platform", + ], +} diff --git a/packages/ConnectivityT/service/jni/onload.cpp b/packages/ConnectivityT/service/jni/onload.cpp new file mode 100644 index 000000000000..bca469756095 --- /dev/null +++ b/packages/ConnectivityT/service/jni/onload.cpp @@ -0,0 +1,38 @@ +/* + * Copyright (C) 2022 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT 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 <nativehelper/JNIHelp.h> +#include <log/log.h> + +namespace android { + +int register_com_android_net_module_util_BpfMap(JNIEnv* env, char const* class_name); + +extern "C" jint JNI_OnLoad(JavaVM* vm, void*) { + JNIEnv *env; + if (vm->GetEnv(reinterpret_cast<void**>(&env), JNI_VERSION_1_6) != JNI_OK) { + ALOGE("GetEnv failed"); + return JNI_ERR; + } + + if (register_com_android_net_module_util_BpfMap(env, + "com/android/net/module/util/BpfMap") < 0) return JNI_ERR; + + return JNI_VERSION_1_6; +} + +}; + diff --git a/packages/ConnectivityT/service/src/com/android/server/net/BpfInterfaceMapUpdater.java b/packages/ConnectivityT/service/src/com/android/server/net/BpfInterfaceMapUpdater.java new file mode 100644 index 000000000000..25c88eb6bdb2 --- /dev/null +++ b/packages/ConnectivityT/service/src/com/android/server/net/BpfInterfaceMapUpdater.java @@ -0,0 +1,139 @@ +/* + * Copyright (C) 2022 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES 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.net; + +import android.content.Context; +import android.net.INetd; +import android.os.Handler; +import android.os.IBinder; +import android.os.RemoteException; +import android.os.ServiceSpecificException; +import android.system.ErrnoException; +import android.util.Log; + +import com.android.internal.annotations.VisibleForTesting; +import com.android.net.module.util.BaseNetdUnsolicitedEventListener; +import com.android.net.module.util.BpfMap; +import com.android.net.module.util.IBpfMap; +import com.android.net.module.util.InterfaceParams; +import com.android.net.module.util.Struct.U32; + +/** + * Monitor interface added (without removed) and right interface name and its index to bpf map. + */ +public class BpfInterfaceMapUpdater { + private static final String TAG = BpfInterfaceMapUpdater.class.getSimpleName(); + // This is current path but may be changed soon. + private static final String IFACE_INDEX_NAME_MAP_PATH = + "/sys/fs/bpf/map_netd_iface_index_name_map"; + private final IBpfMap<U32, InterfaceMapValue> mBpfMap; + private final INetd mNetd; + private final Handler mHandler; + private final Dependencies mDeps; + + public BpfInterfaceMapUpdater(Context ctx, Handler handler) { + this(ctx, handler, new Dependencies()); + } + + @VisibleForTesting + public BpfInterfaceMapUpdater(Context ctx, Handler handler, Dependencies deps) { + mDeps = deps; + mBpfMap = deps.getInterfaceMap(); + mNetd = deps.getINetd(ctx); + mHandler = handler; + } + + /** + * Dependencies of BpfInerfaceMapUpdater, for injection in tests. + */ + @VisibleForTesting + public static class Dependencies { + /** Create BpfMap for updating interface and index mapping. */ + public IBpfMap<U32, InterfaceMapValue> getInterfaceMap() { + try { + return new BpfMap<>(IFACE_INDEX_NAME_MAP_PATH, BpfMap.BPF_F_RDWR, + U32.class, InterfaceMapValue.class); + } catch (ErrnoException e) { + Log.e(TAG, "Cannot create interface map: " + e); + return null; + } + } + + /** Get InterfaceParams for giving interface name. */ + public InterfaceParams getInterfaceParams(String ifaceName) { + return InterfaceParams.getByName(ifaceName); + } + + /** Get INetd binder object. */ + public INetd getINetd(Context ctx) { + return INetd.Stub.asInterface((IBinder) ctx.getSystemService(Context.NETD_SERVICE)); + } + } + + /** + * Start listening interface update event. + * Query current interface names before listening. + */ + public void start() { + mHandler.post(() -> { + if (mBpfMap == null) { + Log.wtf(TAG, "Fail to start: Null bpf map"); + return; + } + + try { + // TODO: use a NetlinkMonitor and listen for RTM_NEWLINK messages instead. + mNetd.registerUnsolicitedEventListener(new InterfaceChangeObserver()); + } catch (RemoteException e) { + Log.wtf(TAG, "Unable to register netd UnsolicitedEventListener, " + e); + } + + final String[] ifaces; + try { + // TODO: use a netlink dump to get the current interface list. + ifaces = mNetd.interfaceGetList(); + } catch (RemoteException | ServiceSpecificException e) { + Log.wtf(TAG, "Unable to query interface names by netd, " + e); + return; + } + + for (String ifaceName : ifaces) { + addInterface(ifaceName); + } + }); + } + + private void addInterface(String ifaceName) { + final InterfaceParams iface = mDeps.getInterfaceParams(ifaceName); + if (iface == null) { + Log.e(TAG, "Unable to get InterfaceParams for " + ifaceName); + return; + } + + try { + mBpfMap.updateEntry(new U32(iface.index), new InterfaceMapValue(ifaceName)); + } catch (ErrnoException e) { + Log.e(TAG, "Unable to update entry for " + ifaceName + ", " + e); + } + } + + private class InterfaceChangeObserver extends BaseNetdUnsolicitedEventListener { + @Override + public void onInterfaceAdded(String ifName) { + mHandler.post(() -> addInterface(ifName)); + } + } +} diff --git a/services/core/java/com/android/server/net/DelayedDiskWrite.java b/packages/ConnectivityT/service/src/com/android/server/net/DelayedDiskWrite.java index 8f09eb7c19ab..35dc4557252c 100644 --- a/services/core/java/com/android/server/net/DelayedDiskWrite.java +++ b/packages/ConnectivityT/service/src/com/android/server/net/DelayedDiskWrite.java @@ -26,21 +26,37 @@ import java.io.DataOutputStream; import java.io.FileOutputStream; import java.io.IOException; +/** + * This class provides APIs to do a delayed data write to a given {@link OutputStream}. + */ public class DelayedDiskWrite { + private static final String TAG = "DelayedDiskWrite"; + private HandlerThread mDiskWriteHandlerThread; private Handler mDiskWriteHandler; /* Tracks multiple writes on the same thread */ private int mWriteSequence = 0; - private final String TAG = "DelayedDiskWrite"; + /** + * Used to do a delayed data write to a given {@link OutputStream}. + */ public interface Writer { - public void onWriteCalled(DataOutputStream out) throws IOException; + /** + * write data to a given {@link OutputStream}. + */ + void onWriteCalled(DataOutputStream out) throws IOException; } + /** + * Do a delayed data write to a given output stream opened from filePath. + */ public void write(final String filePath, final Writer w) { write(filePath, w, true); } + /** + * Do a delayed data write to a given output stream opened from filePath. + */ public void write(final String filePath, final Writer w, final boolean open) { if (TextUtils.isEmpty(filePath)) { throw new IllegalArgumentException("empty file path"); @@ -77,7 +93,7 @@ public class DelayedDiskWrite { if (out != null) { try { out.close(); - } catch (Exception e) {} + } catch (Exception e) { } } // Quit if no more writes sent diff --git a/packages/ConnectivityT/service/src/com/android/server/net/InterfaceMapValue.java b/packages/ConnectivityT/service/src/com/android/server/net/InterfaceMapValue.java new file mode 100644 index 000000000000..061f323447b0 --- /dev/null +++ b/packages/ConnectivityT/service/src/com/android/server/net/InterfaceMapValue.java @@ -0,0 +1,35 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.android.server.net; + +import com.android.net.module.util.Struct; +import com.android.net.module.util.Struct.Field; +import com.android.net.module.util.Struct.Type; + +/** + * The value of bpf interface index map which is used for NetworkStatsService. + */ +public class InterfaceMapValue extends Struct { + @Field(order = 0, type = Type.ByteArray, arraysize = 16) + public final byte[] interfaceName; + + public InterfaceMapValue(String iface) { + final byte[] ifaceArray = iface.getBytes(); + interfaceName = new byte[16]; + // All array bytes after the interface name, if any, must be 0. + System.arraycopy(ifaceArray, 0, interfaceName, 0, ifaceArray.length); + } +} diff --git a/packages/ConnectivityT/service/src/com/android/server/net/NetworkStatsFactory.java b/packages/ConnectivityT/service/src/com/android/server/net/NetworkStatsFactory.java index bb123a38ebc0..17f3455d20a2 100644 --- a/packages/ConnectivityT/service/src/com/android/server/net/NetworkStatsFactory.java +++ b/packages/ConnectivityT/service/src/com/android/server/net/NetworkStatsFactory.java @@ -26,10 +26,10 @@ import static com.android.server.NetworkManagementSocketTagger.kernelToTag; import android.annotation.NonNull; import android.annotation.Nullable; -import android.net.INetd; +import android.content.Context; +import android.net.ConnectivityManager; import android.net.NetworkStats; import android.net.UnderlyingNetworkInfo; -import android.os.RemoteException; import android.os.StrictMode; import android.os.SystemClock; @@ -70,7 +70,7 @@ public class NetworkStatsFactory { private final boolean mUseBpfStats; - private final INetd mNetd; + private final Context mContext; /** * Guards persistent data access in this class @@ -158,12 +158,12 @@ public class NetworkStatsFactory { NetworkStats.apply464xlatAdjustments(baseTraffic, stackedTraffic, mStackedIfaces); } - public NetworkStatsFactory(@NonNull INetd netd) { - this(new File("/proc/"), true, netd); + public NetworkStatsFactory(@NonNull Context ctx) { + this(ctx, new File("/proc/"), true); } @VisibleForTesting - public NetworkStatsFactory(File procRoot, boolean useBpfStats, @NonNull INetd netd) { + public NetworkStatsFactory(@NonNull Context ctx, File procRoot, boolean useBpfStats) { mStatsXtIfaceAll = new File(procRoot, "net/xt_qtaguid/iface_stat_all"); mStatsXtIfaceFmt = new File(procRoot, "net/xt_qtaguid/iface_stat_fmt"); mStatsXtUid = new File(procRoot, "net/xt_qtaguid/stats"); @@ -172,7 +172,7 @@ public class NetworkStatsFactory { mPersistSnapshot = new NetworkStats(SystemClock.elapsedRealtime(), -1); mTunAnd464xlatAdjustedStats = new NetworkStats(SystemClock.elapsedRealtime(), -1); } - mNetd = netd; + mContext = ctx; } public NetworkStats readBpfNetworkStatsDev() throws IOException { @@ -295,11 +295,12 @@ public class NetworkStatsFactory { } @GuardedBy("mPersistentDataLock") - private void requestSwapActiveStatsMapLocked() throws RemoteException { - // Ask netd to do a active map stats swap. When the binder call successfully returns, + private void requestSwapActiveStatsMapLocked() { + // Do a active map stats swap. When the binder call successfully returns, // the system server should be able to safely read and clean the inactive map // without race problem. - mNetd.trafficSwapActiveStatsMap(); + final ConnectivityManager cm = mContext.getSystemService(ConnectivityManager.class); + cm.swapActiveStatsMap(); } /** @@ -327,7 +328,7 @@ public class NetworkStatsFactory { if (mUseBpfStats) { try { requestSwapActiveStatsMapLocked(); - } catch (RemoteException e) { + } catch (RuntimeException e) { throw new IOException(e); } // Stats are always read from the inactive map, so they must be read after the diff --git a/packages/ConnectivityT/service/src/com/android/server/net/NetworkStatsObservers.java b/packages/ConnectivityT/service/src/com/android/server/net/NetworkStatsObservers.java index b57a4f920b60..19536247b23b 100644 --- a/packages/ConnectivityT/service/src/com/android/server/net/NetworkStatsObservers.java +++ b/packages/ConnectivityT/service/src/com/android/server/net/NetworkStatsObservers.java @@ -26,13 +26,12 @@ import android.net.NetworkStatsAccess; import android.net.NetworkStatsCollection; import android.net.NetworkStatsHistory; import android.net.NetworkTemplate; -import android.os.Bundle; +import android.net.netstats.IUsageCallback; import android.os.Handler; import android.os.HandlerThread; import android.os.IBinder; import android.os.Looper; import android.os.Message; -import android.os.Messenger; import android.os.Process; import android.os.RemoteException; import android.util.ArrayMap; @@ -75,10 +74,10 @@ class NetworkStatsObservers { * * @return the normalized request wrapped within {@link RequestInfo}. */ - public DataUsageRequest register(DataUsageRequest inputRequest, Messenger messenger, - IBinder binder, int callingUid, @NetworkStatsAccess.Level int accessLevel) { - DataUsageRequest request = buildRequest(inputRequest); - RequestInfo requestInfo = buildRequestInfo(request, messenger, binder, callingUid, + public DataUsageRequest register(DataUsageRequest inputRequest, IUsageCallback callback, + int callingUid, @NetworkStatsAccess.Level int accessLevel) { + DataUsageRequest request = buildRequest(inputRequest, callingUid); + RequestInfo requestInfo = buildRequestInfo(request, callback, callingUid, accessLevel); if (LOGV) Log.v(TAG, "Registering observer for " + request); @@ -195,10 +194,12 @@ class NetworkStatsObservers { } } - private DataUsageRequest buildRequest(DataUsageRequest request) { - // Cap the minimum threshold to a safe default to avoid too many callbacks - long thresholdInBytes = Math.max(MIN_THRESHOLD_BYTES, request.thresholdInBytes); - if (thresholdInBytes < request.thresholdInBytes) { + private DataUsageRequest buildRequest(DataUsageRequest request, int callingUid) { + // For non-system uid, cap the minimum threshold to a safe default to avoid too + // many callbacks. + long thresholdInBytes = (callingUid == Process.SYSTEM_UID ? request.thresholdInBytes + : Math.max(MIN_THRESHOLD_BYTES, request.thresholdInBytes)); + if (thresholdInBytes > request.thresholdInBytes) { Log.w(TAG, "Threshold was too low for " + request + ". Overriding to a safer default of " + thresholdInBytes + " bytes"); } @@ -206,11 +207,10 @@ class NetworkStatsObservers { request.template, thresholdInBytes); } - private RequestInfo buildRequestInfo(DataUsageRequest request, - Messenger messenger, IBinder binder, int callingUid, - @NetworkStatsAccess.Level int accessLevel) { + private RequestInfo buildRequestInfo(DataUsageRequest request, IUsageCallback callback, + int callingUid, @NetworkStatsAccess.Level int accessLevel) { if (accessLevel <= NetworkStatsAccess.Level.USER) { - return new UserUsageRequestInfo(this, request, messenger, binder, callingUid, + return new UserUsageRequestInfo(this, request, callback, callingUid, accessLevel); } else { // Safety check in case a new access level is added and we forgot to update this @@ -218,7 +218,7 @@ class NetworkStatsObservers { throw new IllegalArgumentException( "accessLevel " + accessLevel + " is less than DEVICESUMMARY."); } - return new NetworkUsageRequestInfo(this, request, messenger, binder, callingUid, + return new NetworkUsageRequestInfo(this, request, callback, callingUid, accessLevel); } } @@ -230,25 +230,23 @@ class NetworkStatsObservers { private abstract static class RequestInfo implements IBinder.DeathRecipient { private final NetworkStatsObservers mStatsObserver; protected final DataUsageRequest mRequest; - private final Messenger mMessenger; - private final IBinder mBinder; + private final IUsageCallback mCallback; protected final int mCallingUid; protected final @NetworkStatsAccess.Level int mAccessLevel; protected NetworkStatsRecorder mRecorder; protected NetworkStatsCollection mCollection; RequestInfo(NetworkStatsObservers statsObserver, DataUsageRequest request, - Messenger messenger, IBinder binder, int callingUid, + IUsageCallback callback, int callingUid, @NetworkStatsAccess.Level int accessLevel) { mStatsObserver = statsObserver; mRequest = request; - mMessenger = messenger; - mBinder = binder; + mCallback = callback; mCallingUid = callingUid; mAccessLevel = accessLevel; try { - mBinder.linkToDeath(this, 0); + mCallback.asBinder().linkToDeath(this, 0); } catch (RemoteException e) { binderDied(); } @@ -257,7 +255,7 @@ class NetworkStatsObservers { @Override public void binderDied() { if (LOGV) { - Log.v(TAG, "RequestInfo binderDied(" + mRequest + ", " + mBinder + ")"); + Log.v(TAG, "RequestInfo binderDied(" + mRequest + ", " + mCallback + ")"); } mStatsObserver.unregister(mRequest, Process.SYSTEM_UID); callCallback(NetworkStatsManager.CALLBACK_RELEASED); @@ -270,9 +268,7 @@ class NetworkStatsObservers { } private void unlinkDeathRecipient() { - if (mBinder != null) { - mBinder.unlinkToDeath(this, 0); - } + mCallback.asBinder().unlinkToDeath(this, 0); } /** @@ -294,17 +290,19 @@ class NetworkStatsObservers { } private void callCallback(int callbackType) { - Bundle bundle = new Bundle(); - bundle.putParcelable(DataUsageRequest.PARCELABLE_KEY, mRequest); - Message msg = Message.obtain(); - msg.what = callbackType; - msg.setData(bundle); try { if (LOGV) { Log.v(TAG, "sending notification " + callbackTypeToName(callbackType) + " for " + mRequest); } - mMessenger.send(msg); + switch (callbackType) { + case NetworkStatsManager.CALLBACK_LIMIT_REACHED: + mCallback.onThresholdReached(mRequest); + break; + case NetworkStatsManager.CALLBACK_RELEASED: + mCallback.onCallbackReleased(mRequest); + break; + } } catch (RemoteException e) { // May occur naturally in the race of binder death. Log.w(TAG, "RemoteException caught trying to send a callback msg for " + mRequest); @@ -334,9 +332,9 @@ class NetworkStatsObservers { private static class NetworkUsageRequestInfo extends RequestInfo { NetworkUsageRequestInfo(NetworkStatsObservers statsObserver, DataUsageRequest request, - Messenger messenger, IBinder binder, int callingUid, + IUsageCallback callback, int callingUid, @NetworkStatsAccess.Level int accessLevel) { - super(statsObserver, request, messenger, binder, callingUid, accessLevel); + super(statsObserver, request, callback, callingUid, accessLevel); } @Override @@ -376,9 +374,9 @@ class NetworkStatsObservers { private static class UserUsageRequestInfo extends RequestInfo { UserUsageRequestInfo(NetworkStatsObservers statsObserver, DataUsageRequest request, - Messenger messenger, IBinder binder, int callingUid, + IUsageCallback callback, int callingUid, @NetworkStatsAccess.Level int accessLevel) { - super(statsObserver, request, messenger, binder, callingUid, accessLevel); + super(statsObserver, request, callback, callingUid, accessLevel); } @Override diff --git a/packages/ConnectivityT/service/src/com/android/server/net/NetworkStatsService.java b/packages/ConnectivityT/service/src/com/android/server/net/NetworkStatsService.java index 9b90f3b54542..8e584d084fb9 100644 --- a/packages/ConnectivityT/service/src/com/android/server/net/NetworkStatsService.java +++ b/packages/ConnectivityT/service/src/com/android/server/net/NetworkStatsService.java @@ -60,7 +60,6 @@ import static android.text.format.DateUtils.SECOND_IN_MILLIS; import static com.android.net.module.util.NetworkCapabilitiesUtils.getDisplayTransport; import static com.android.net.module.util.NetworkStatsUtils.LIMIT_GLOBAL_ALERT; import static com.android.server.NetworkManagementSocketTagger.resetKernelUidStats; -import static com.android.server.NetworkManagementSocketTagger.setKernelCounterSet; import android.annotation.NonNull; import android.annotation.Nullable; @@ -99,6 +98,7 @@ import android.net.TetheringManager; import android.net.TrafficStats; import android.net.UnderlyingNetworkInfo; import android.net.Uri; +import android.net.netstats.IUsageCallback; import android.net.netstats.provider.INetworkStatsProvider; import android.net.netstats.provider.INetworkStatsProviderCallback; import android.net.netstats.provider.NetworkStatsProvider; @@ -106,12 +106,10 @@ import android.os.Binder; import android.os.DropBoxManager; import android.os.Environment; import android.os.Handler; -import android.os.HandlerExecutor; import android.os.HandlerThread; import android.os.IBinder; import android.os.Looper; import android.os.Message; -import android.os.Messenger; import android.os.PowerManager; import android.os.RemoteException; import android.os.ServiceSpecificException; @@ -122,6 +120,7 @@ import android.provider.Settings; import android.provider.Settings.Global; import android.service.NetworkInterfaceProto; import android.service.NetworkStatsServiceDumpProto; +import android.system.ErrnoException; import android.telephony.PhoneStateListener; import android.telephony.SubscriptionPlan; import android.text.TextUtils; @@ -140,10 +139,14 @@ import com.android.internal.util.FileRotator; import com.android.net.module.util.BaseNetdUnsolicitedEventListener; import com.android.net.module.util.BestClock; import com.android.net.module.util.BinderUtils; +import com.android.net.module.util.BpfMap; import com.android.net.module.util.CollectionUtils; +import com.android.net.module.util.IBpfMap; import com.android.net.module.util.LocationPermissionChecker; import com.android.net.module.util.NetworkStatsUtils; import com.android.net.module.util.PermissionUtils; +import com.android.net.module.util.Struct.U32; +import com.android.net.module.util.Struct.U8; import java.io.File; import java.io.FileDescriptor; @@ -208,6 +211,10 @@ public class NetworkStatsService extends INetworkStatsService.Stub { private static final String NETSTATS_COMBINE_SUBTYPE_ENABLED = "netstats_combine_subtype_enabled"; + // This is current path but may be changed soon. + private static final String UID_COUNTERSET_MAP_PATH = + "/sys/fs/bpf/map_netd_uid_counterset_map"; + private final Context mContext; private final NetworkStatsFactory mStatsFactory; private final AlarmManager mAlarmManager; @@ -245,7 +252,7 @@ public class NetworkStatsService extends INetworkStatsService.Stub { /** * When enabled, all mobile data is reported under {@link NetworkTemplate#NETWORK_TYPE_ALL}. * When disabled, mobile data is broken down by a granular ratType representative of the - * actual ratType. {@see NetworkTemplate#getCollapsedRatType}. + * actual ratType. {@see android.app.usage.NetworkStatsManager#getCollapsedRatType}. * Enabling this decreases the level of detail but saves performance, disk space and * amount of data logged. */ @@ -326,8 +333,14 @@ public class NetworkStatsService extends INetworkStatsService.Stub { @GuardedBy("mStatsLock") private NetworkStatsCollection mXtStatsCached; - /** Current counter sets for each UID. */ + /** + * Current counter sets for each UID. + * TODO: maybe remove mActiveUidCounterSet and read UidCouneterSet value from mUidCounterSetMap + * directly ? But if mActiveUidCounterSet would be accessed very frequently, maybe keep + * mActiveUidCounterSet to avoid accessing kernel too frequently. + */ private SparseIntArray mActiveUidCounterSet = new SparseIntArray(); + private final IBpfMap<U32, U8> mUidCounterSetMap; /** Data layer operation counters for splicing into other structures. */ private NetworkStats mUidOperations = new NetworkStats(0L, 10); @@ -358,6 +371,9 @@ public class NetworkStatsService extends INetworkStatsService.Stub { @NonNull private final LocationPermissionChecker mLocationPermissionChecker; + @NonNull + private final BpfInterfaceMapUpdater mInterfaceMapUpdater; + private static @NonNull File getDefaultSystemDir() { return new File(Environment.getDataDirectory(), "system"); } @@ -420,7 +436,7 @@ public class NetworkStatsService extends INetworkStatsService.Stub { final NetworkStatsService service = new NetworkStatsService(context, INetd.Stub.asInterface((IBinder) context.getSystemService(Context.NETD_SERVICE)), alarmManager, wakeLock, getDefaultClock(), - new DefaultNetworkStatsSettings(), new NetworkStatsFactory(netd), + new DefaultNetworkStatsSettings(), new NetworkStatsFactory(context), new NetworkStatsObservers(), getDefaultSystemDir(), getDefaultBaseDir(), new Dependencies()); @@ -450,11 +466,14 @@ public class NetworkStatsService extends INetworkStatsService.Stub { handlerThread.start(); mHandler = new NetworkStatsHandler(handlerThread.getLooper()); mNetworkStatsSubscriptionsMonitor = deps.makeSubscriptionsMonitor(mContext, - new HandlerExecutor(mHandler), this); + (command) -> mHandler.post(command) , this); mContentResolver = mContext.getContentResolver(); mContentObserver = mDeps.makeContentObserver(mHandler, mSettings, mNetworkStatsSubscriptionsMonitor); mLocationPermissionChecker = mDeps.makeLocationPermissionChecker(mContext); + mInterfaceMapUpdater = mDeps.makeBpfInterfaceMapUpdater(mContext, mHandler); + mInterfaceMapUpdater.start(); + mUidCounterSetMap = mDeps.getUidCounterSetMap(); } /** @@ -509,6 +528,24 @@ public class NetworkStatsService extends INetworkStatsService.Stub { public LocationPermissionChecker makeLocationPermissionChecker(final Context context) { return new LocationPermissionChecker(context); } + + /** Create BpfInterfaceMapUpdater to update bpf interface map. */ + @NonNull + public BpfInterfaceMapUpdater makeBpfInterfaceMapUpdater( + @NonNull Context ctx, @NonNull Handler handler) { + return new BpfInterfaceMapUpdater(ctx, handler); + } + + /** Get counter sets map for each UID. */ + public IBpfMap<U32, U8> getUidCounterSetMap() { + try { + return new BpfMap<U32, U8>(UID_COUNTERSET_MAP_PATH, BpfMap.BPF_F_RDWR, + U32.class, U8.class); + } catch (ErrnoException e) { + Log.wtf(TAG, "Cannot create uid counter set map: " + e); + return null; + } + } } /** @@ -557,7 +594,7 @@ public class NetworkStatsService extends INetworkStatsService.Stub { // watch for tethering changes final TetheringManager tetheringManager = mContext.getSystemService(TetheringManager.class); tetheringManager.registerTetheringEventCallback( - new HandlerExecutor(mHandler), mTetherListener); + (command) -> mHandler.post(command), mTetherListener); // listen for periodic polling events final IntentFilter pollFilter = new IntentFilter(ACTION_NETWORK_STATS_POLL); @@ -989,8 +1026,17 @@ public class NetworkStatsService extends INetworkStatsService.Stub { } // TODO: switch to data layer stats once kernel exports - // for now, read network layer stats and flatten across all ifaces - final NetworkStats networkLayer = readNetworkStatsUidDetail(uid, INTERFACES_ALL, TAG_ALL); + // for now, read network layer stats and flatten across all ifaces. + // This function is used to query NeworkStats for calle's uid. The only caller method + // TrafficStats#getDataLayerSnapshotForUid alrady claim no special permission to query + // its own NetworkStats. + final long ident = Binder.clearCallingIdentity(); + final NetworkStats networkLayer; + try { + networkLayer = readNetworkStatsUidDetail(uid, INTERFACES_ALL, TAG_ALL); + } finally { + Binder.restoreCallingIdentity(ident); + } // splice in operation counts networkLayer.spliceOperationsFrom(mUidOperations); @@ -1057,6 +1103,29 @@ public class NetworkStatsService extends INetworkStatsService.Stub { } } + private void setKernelCounterSet(int uid, int set) { + if (mUidCounterSetMap == null) { + Log.wtf(TAG, "Fail to set UidCounterSet: Null bpf map"); + return; + } + + if (set == SET_DEFAULT) { + try { + mUidCounterSetMap.deleteEntry(new U32(uid)); + } catch (ErrnoException e) { + Log.w(TAG, "UidCounterSetMap.deleteEntry(" + uid + ") failed with errno: " + e); + } + return; + } + + try { + mUidCounterSetMap.updateEntry(new U32(uid), new U8((short) set)); + } catch (ErrnoException e) { + Log.w(TAG, "UidCounterSetMap.updateEntry(" + uid + ", " + set + + ") failed with errno: " + e); + } + } + @VisibleForTesting public void setUidForeground(int uid, boolean uidForeground) { PermissionUtils.enforceNetworkStackPermission(mContext); @@ -1137,21 +1206,20 @@ public class NetworkStatsService extends INetworkStatsService.Stub { } @Override - public DataUsageRequest registerUsageCallback(String callingPackage, - DataUsageRequest request, Messenger messenger, IBinder binder) { + public DataUsageRequest registerUsageCallback(@NonNull String callingPackage, + @NonNull DataUsageRequest request, @NonNull IUsageCallback callback) { Objects.requireNonNull(callingPackage, "calling package is null"); Objects.requireNonNull(request, "DataUsageRequest is null"); Objects.requireNonNull(request.template, "NetworkTemplate is null"); - Objects.requireNonNull(messenger, "messenger is null"); - Objects.requireNonNull(binder, "binder is null"); + Objects.requireNonNull(callback, "callback is null"); int callingUid = Binder.getCallingUid(); @NetworkStatsAccess.Level int accessLevel = checkAccessLevel(callingPackage); DataUsageRequest normalizedRequest; final long token = Binder.clearCallingIdentity(); try { - normalizedRequest = mStatsObservers.register(request, messenger, binder, - callingUid, accessLevel); + normalizedRequest = mStatsObservers.register( + request, callback, callingUid, accessLevel); } finally { Binder.restoreCallingIdentity(token); } diff --git a/packages/ConnectivityT/service/src/com/android/server/net/NetworkStatsSubscriptionsMonitor.java b/packages/ConnectivityT/service/src/com/android/server/net/NetworkStatsSubscriptionsMonitor.java index 4875f1cf5aaa..5bba0b17aa42 100644 --- a/packages/ConnectivityT/service/src/com/android/server/net/NetworkStatsSubscriptionsMonitor.java +++ b/packages/ConnectivityT/service/src/com/android/server/net/NetworkStatsSubscriptionsMonitor.java @@ -16,15 +16,14 @@ package com.android.server.net; -import static android.net.NetworkTemplate.NETWORK_TYPE_5G_NSA; -import static android.net.NetworkTemplate.getCollapsedRatType; +import static android.app.usage.NetworkStatsManager.NETWORK_TYPE_5G_NSA; +import static android.app.usage.NetworkStatsManager.getCollapsedRatType; import static android.telephony.TelephonyDisplayInfo.OVERRIDE_NETWORK_TYPE_NR_ADVANCED; import static android.telephony.TelephonyDisplayInfo.OVERRIDE_NETWORK_TYPE_NR_NSA; import static android.telephony.TelephonyManager.NETWORK_TYPE_LTE; import android.annotation.NonNull; import android.content.Context; -import android.telephony.Annotation; import android.telephony.SubscriptionManager; import android.telephony.TelephonyCallback; import android.telephony.TelephonyDisplayInfo; @@ -57,10 +56,9 @@ public class NetworkStatsSubscriptionsMonitor extends * * @param subscriberId IMSI of the subscription. * @param collapsedRatType collapsed RAT type. - * @see android.net.NetworkTemplate#getCollapsedRatType(int). + * @see android.app.usage.NetworkStatsManager#getCollapsedRatType(int). */ - void onCollapsedRatTypeChanged(@NonNull String subscriberId, - @Annotation.NetworkType int collapsedRatType); + void onCollapsedRatTypeChanged(@NonNull String subscriberId, int collapsedRatType); } private final Delegate mDelegate; diff --git a/packages/SettingsLib/src/com/android/settingslib/NetworkPolicyEditor.java b/packages/SettingsLib/src/com/android/settingslib/NetworkPolicyEditor.java index f5aa652f3194..b4e84dd54654 100644 --- a/packages/SettingsLib/src/com/android/settingslib/NetworkPolicyEditor.java +++ b/packages/SettingsLib/src/com/android/settingslib/NetworkPolicyEditor.java @@ -27,9 +27,7 @@ import static com.android.internal.util.Preconditions.checkNotNull; import android.net.NetworkPolicy; import android.net.NetworkPolicyManager; import android.net.NetworkTemplate; -import android.net.wifi.WifiInfo; import android.os.AsyncTask; -import android.text.TextUtils; import android.util.RecurrenceRule; import com.google.android.collect.Lists; @@ -124,7 +122,7 @@ public class NetworkPolicyEditor { if (policy != null) { return policy; } else { - return getPolicy(buildUnquotedNetworkTemplate(template)); + return getPolicy(template); } } @@ -207,21 +205,4 @@ public class NetworkPolicyEditor { policy.clearSnooze(); writeAsync(); } - - /** - * Build a revised {@link NetworkTemplate} that matches the same rule, but - * with an unquoted {@link NetworkTemplate#getNetworkId()}. Used to work - * around legacy bugs. - */ - private static NetworkTemplate buildUnquotedNetworkTemplate(NetworkTemplate template) { - if (template == null) return null; - final String networkId = template.getNetworkId(); - final String strippedNetworkId = WifiInfo.sanitizeSsid(networkId); - if (!TextUtils.equals(strippedNetworkId, networkId)) { - return new NetworkTemplate( - template.getMatchRule(), template.getSubscriberId(), strippedNetworkId); - } else { - return null; - } - } } diff --git a/packages/SettingsLib/src/com/android/settingslib/mobile/OWNERS b/packages/SettingsLib/src/com/android/settingslib/mobile/OWNERS new file mode 100644 index 000000000000..ab9b5dc3ff7a --- /dev/null +++ b/packages/SettingsLib/src/com/android/settingslib/mobile/OWNERS @@ -0,0 +1,4 @@ +# Default reviewers for this and subdirectories. +bonianchen@google.com + +# Emergency approvers in case the above are not available diff --git a/packages/SettingsLib/src/com/android/settingslib/net/ChartData.java b/packages/SettingsLib/src/com/android/settingslib/net/ChartData.java index e30aac575c67..a69c59c6da6d 100644 --- a/packages/SettingsLib/src/com/android/settingslib/net/ChartData.java +++ b/packages/SettingsLib/src/com/android/settingslib/net/ChartData.java @@ -16,12 +16,18 @@ package com.android.settingslib.net; -import android.net.NetworkStatsHistory; +import android.app.usage.NetworkStats; + +import java.util.List; public class ChartData { - public NetworkStatsHistory network; + // Collect the data usage history of the network from the given {@link NetworkTemplate}. + public List<NetworkStats.Bucket> network; - public NetworkStatsHistory detail; - public NetworkStatsHistory detailDefault; - public NetworkStatsHistory detailForeground; + // Collect the detail datausage history (foreground + Background). + public List<NetworkStats.Bucket> detail; + // Collect background datausage history. + public List<NetworkStats.Bucket> detailDefault; + // Collect foreground datausage history. + public List<NetworkStats.Bucket> detailForeground; } diff --git a/packages/SettingsLib/src/com/android/settingslib/net/ChartDataLoader.java b/packages/SettingsLib/src/com/android/settingslib/net/ChartDataLoader.java index 60d22a0d5803..573922f9013c 100644 --- a/packages/SettingsLib/src/com/android/settingslib/net/ChartDataLoader.java +++ b/packages/SettingsLib/src/com/android/settingslib/net/ChartDataLoader.java @@ -19,20 +19,21 @@ package com.android.settingslib.net; import static android.net.NetworkStats.SET_DEFAULT; import static android.net.NetworkStats.SET_FOREGROUND; import static android.net.NetworkStats.TAG_NONE; -import static android.net.NetworkStatsHistory.FIELD_RX_BYTES; -import static android.net.NetworkStatsHistory.FIELD_TX_BYTES; -import static android.text.format.DateUtils.HOUR_IN_MILLIS; +import android.annotation.NonNull; +import android.app.usage.NetworkStats; +import android.app.usage.NetworkStatsManager; import android.content.AsyncTaskLoader; import android.content.Context; -import android.net.INetworkStatsSession; -import android.net.NetworkStatsHistory; import android.net.NetworkTemplate; import android.os.Bundle; import android.os.RemoteException; import com.android.settingslib.AppItem; +import java.util.ArrayList; +import java.util.List; + /** * Framework loader is deprecated, use the compat version instead. * @@ -42,26 +43,20 @@ import com.android.settingslib.AppItem; public class ChartDataLoader extends AsyncTaskLoader<ChartData> { private static final String KEY_TEMPLATE = "template"; private static final String KEY_APP = "app"; - private static final String KEY_FIELDS = "fields"; - private final INetworkStatsSession mSession; + private final NetworkStatsManager mNetworkStatsManager; private final Bundle mArgs; public static Bundle buildArgs(NetworkTemplate template, AppItem app) { - return buildArgs(template, app, FIELD_RX_BYTES | FIELD_TX_BYTES); - } - - public static Bundle buildArgs(NetworkTemplate template, AppItem app, int fields) { final Bundle args = new Bundle(); args.putParcelable(KEY_TEMPLATE, template); args.putParcelable(KEY_APP, app); - args.putInt(KEY_FIELDS, fields); return args; } - public ChartDataLoader(Context context, INetworkStatsSession session, Bundle args) { + public ChartDataLoader(Context context, NetworkStatsManager statsManager, Bundle args) { super(context); - mSession = session; + mNetworkStatsManager = statsManager; mArgs = args; } @@ -75,10 +70,9 @@ public class ChartDataLoader extends AsyncTaskLoader<ChartData> { public ChartData loadInBackground() { final NetworkTemplate template = mArgs.getParcelable(KEY_TEMPLATE); final AppItem app = mArgs.getParcelable(KEY_APP); - final int fields = mArgs.getInt(KEY_FIELDS); try { - return loadInBackground(template, app, fields); + return loadInBackground(template, app); } catch (RemoteException e) { // since we can't do much without history, and we don't want to // leave with half-baked UI, we bail hard. @@ -86,10 +80,22 @@ public class ChartDataLoader extends AsyncTaskLoader<ChartData> { } } - private ChartData loadInBackground(NetworkTemplate template, AppItem app, int fields) + @NonNull + private List<NetworkStats.Bucket> convertToBuckets(@NonNull NetworkStats stats) { + final List<NetworkStats.Bucket> ret = new ArrayList<>(); + while (stats.hasNextBucket()) { + final NetworkStats.Bucket bucket = new NetworkStats.Bucket(); + stats.getNextBucket(bucket); + ret.add(bucket); + } + return ret; + } + + private ChartData loadInBackground(NetworkTemplate template, AppItem app) throws RemoteException { final ChartData data = new ChartData(); - data.network = mSession.getHistoryForNetwork(template, fields); + data.network = convertToBuckets(mNetworkStatsManager.queryDetailsForDevice( + template, Long.MIN_VALUE, Long.MAX_VALUE)); if (app != null) { // load stats for current uid and template @@ -103,13 +109,13 @@ public class ChartDataLoader extends AsyncTaskLoader<ChartData> { } if (size > 0) { - data.detail = new NetworkStatsHistory(data.detailForeground.getBucketDuration()); - data.detail.recordEntireHistory(data.detailDefault); - data.detail.recordEntireHistory(data.detailForeground); + data.detail = new ArrayList<>(); + data.detail.addAll(data.detailDefault); + data.detail.addAll(data.detailForeground); } else { - data.detailDefault = new NetworkStatsHistory(HOUR_IN_MILLIS); - data.detailForeground = new NetworkStatsHistory(HOUR_IN_MILLIS); - data.detail = new NetworkStatsHistory(HOUR_IN_MILLIS); + data.detailDefault = new ArrayList<>(); + data.detailForeground = new ArrayList<>(); + data.detail = new ArrayList<>(); } } @@ -129,17 +135,17 @@ public class ChartDataLoader extends AsyncTaskLoader<ChartData> { } /** - * Collect {@link NetworkStatsHistory} for the requested UID, combining with - * an existing {@link NetworkStatsHistory} if provided. + * Collect {@link List<NetworkStats.Bucket>} for the requested UID, combining with + * an existing {@link List<NetworkStats.Bucket>} if provided. */ - private NetworkStatsHistory collectHistoryForUid( - NetworkTemplate template, int uid, int set, NetworkStatsHistory existing) - throws RemoteException { - final NetworkStatsHistory history = mSession.getHistoryForUid( - template, uid, set, TAG_NONE, FIELD_RX_BYTES | FIELD_TX_BYTES); + private List<NetworkStats.Bucket> collectHistoryForUid( + NetworkTemplate template, int uid, int set, List<NetworkStats.Bucket> existing) { + final List<NetworkStats.Bucket> history = convertToBuckets( + mNetworkStatsManager.queryDetailsForUidTagState(template, + Long.MIN_VALUE, Long.MAX_VALUE, uid, TAG_NONE, set)); if (existing != null) { - existing.recordEntireHistory(history); + existing.addAll(history); return existing; } else { return history; diff --git a/packages/SettingsLib/src/com/android/settingslib/net/DataUsageController.java b/packages/SettingsLib/src/com/android/settingslib/net/DataUsageController.java index cff45c6be0e0..30c6645193c0 100644 --- a/packages/SettingsLib/src/com/android/settingslib/net/DataUsageController.java +++ b/packages/SettingsLib/src/com/android/settingslib/net/DataUsageController.java @@ -16,7 +16,6 @@ package com.android.settingslib.net; -import static android.net.TrafficStats.MB_IN_BYTES; import static android.telephony.TelephonyManager.SIM_STATE_READY; import static android.text.format.DateUtils.FORMAT_ABBREV_MONTH; import static android.text.format.DateUtils.FORMAT_SHOW_DATE; @@ -49,6 +48,7 @@ public class DataUsageController { private static final StringBuilder PERIOD_BUILDER = new StringBuilder(50); private static final java.util.Formatter PERIOD_FORMATTER = new java.util.Formatter( PERIOD_BUILDER, Locale.getDefault()); + private static final long MB_IN_BYTES = 1024 * 1024; private final Context mContext; private final NetworkPolicyManager mPolicyManager; @@ -237,10 +237,8 @@ public class DataUsageController { final int matchRule = networkTemplate.getMatchRule(); switch (matchRule) { case NetworkTemplate.MATCH_MOBILE: - case NetworkTemplate.MATCH_MOBILE_WILDCARD: return ConnectivityManager.TYPE_MOBILE; case NetworkTemplate.MATCH_WIFI: - case NetworkTemplate.MATCH_WIFI_WILDCARD: return ConnectivityManager.TYPE_WIFI; case NetworkTemplate.MATCH_ETHERNET: return ConnectivityManager.TYPE_ETHERNET; diff --git a/packages/SettingsLib/src/com/android/settingslib/net/DataUsageUtils.java b/packages/SettingsLib/src/com/android/settingslib/net/DataUsageUtils.java index afd44d5bbc90..386a47ae29b0 100644 --- a/packages/SettingsLib/src/com/android/settingslib/net/DataUsageUtils.java +++ b/packages/SettingsLib/src/com/android/settingslib/net/DataUsageUtils.java @@ -63,14 +63,32 @@ public class DataUsageUtils { private static NetworkTemplate getNormalizedMobileTemplate( TelephonyManager telephonyManager, int subId) { final NetworkTemplate mobileTemplate = getMobileTemplateForSubId(telephonyManager, subId); - final String[] mergedSubscriberIds = telephonyManager - .createForSubscriptionId(subId).getMergedImsisFromGroup(); + final Set<String> mergedSubscriberIds = Set.of(telephonyManager + .createForSubscriptionId(subId).getMergedImsisFromGroup()); if (ArrayUtils.isEmpty(mergedSubscriberIds)) { Log.i(TAG, "mergedSubscriberIds is null."); return mobileTemplate; } - return NetworkTemplate.normalize(mobileTemplate, mergedSubscriberIds); + return normalizeMobileTemplate(mobileTemplate, mergedSubscriberIds); + } + + private static NetworkTemplate normalizeMobileTemplate( + NetworkTemplate template, Set<String> mergedSet) { + if (template.getSubscriberIds().isEmpty()) return template; + // The input template should have at most 1 subscriberId. + final String subscriberId = template.getSubscriberIds().iterator().next(); + + if (mergedSet.contains(subscriberId)) { + // Requested template subscriber is part of the merge group; return + // a template that matches all merged subscribers. + return new NetworkTemplate.Builder(template.getMatchRule()) + .setSubscriberIds(mergedSet) + .setWifiNetworkKeys(template.getWifiNetworkKeys()) + .setMeteredness(NetworkStats.METERED_YES).build(); + } + + return template; } private static NetworkTemplate getMobileTemplateForSubId( diff --git a/packages/SettingsLib/src/com/android/settingslib/net/NetworkCycleDataForUidLoader.java b/packages/SettingsLib/src/com/android/settingslib/net/NetworkCycleDataForUidLoader.java index 43c05b8b64d6..504390cd0b63 100644 --- a/packages/SettingsLib/src/com/android/settingslib/net/NetworkCycleDataForUidLoader.java +++ b/packages/SettingsLib/src/com/android/settingslib/net/NetworkCycleDataForUidLoader.java @@ -53,8 +53,9 @@ public class NetworkCycleDataForUidLoader extends long totalUsage = 0L; long totalForeground = 0L; for (int uid : mUids) { - final NetworkStats stats = mNetworkStatsManager.queryDetailsForUid( - mNetworkTemplate, start, end, uid); + final NetworkStats stats = mNetworkStatsManager.queryDetailsForUidTagState( + mNetworkTemplate, start, end, uid, NetworkStats.Bucket.TAG_NONE, + NetworkStats.Bucket.STATE_ALL); final long usage = getTotalUsage(stats); if (usage > 0L) { totalUsage += usage; diff --git a/packages/SettingsLib/src/com/android/settingslib/net/OWNERS b/packages/SettingsLib/src/com/android/settingslib/net/OWNERS new file mode 100644 index 000000000000..ab9b5dc3ff7a --- /dev/null +++ b/packages/SettingsLib/src/com/android/settingslib/net/OWNERS @@ -0,0 +1,4 @@ +# Default reviewers for this and subdirectories. +bonianchen@google.com + +# Emergency approvers in case the above are not available diff --git a/packages/SettingsLib/src/com/android/settingslib/net/SummaryForAllUidLoader.java b/packages/SettingsLib/src/com/android/settingslib/net/SummaryForAllUidLoader.java index 649aeffd0d5f..8da6032a6649 100644 --- a/packages/SettingsLib/src/com/android/settingslib/net/SummaryForAllUidLoader.java +++ b/packages/SettingsLib/src/com/android/settingslib/net/SummaryForAllUidLoader.java @@ -16,13 +16,12 @@ package com.android.settingslib.net; +import android.app.usage.NetworkStats; +import android.app.usage.NetworkStatsManager; import android.content.AsyncTaskLoader; import android.content.Context; -import android.net.INetworkStatsSession; -import android.net.NetworkStats; import android.net.NetworkTemplate; import android.os.Bundle; -import android.os.RemoteException; /** * Framework loader is deprecated, use the compat version instead. @@ -35,7 +34,7 @@ public class SummaryForAllUidLoader extends AsyncTaskLoader<NetworkStats> { private static final String KEY_START = "start"; private static final String KEY_END = "end"; - private final INetworkStatsSession mSession; + private final NetworkStatsManager mNetworkStatsManager; private final Bundle mArgs; public static Bundle buildArgs(NetworkTemplate template, long start, long end) { @@ -46,9 +45,9 @@ public class SummaryForAllUidLoader extends AsyncTaskLoader<NetworkStats> { return args; } - public SummaryForAllUidLoader(Context context, INetworkStatsSession session, Bundle args) { + public SummaryForAllUidLoader(Context context, Bundle args) { super(context); - mSession = session; + mNetworkStatsManager = context.getSystemService(NetworkStatsManager.class); mArgs = args; } @@ -63,12 +62,7 @@ public class SummaryForAllUidLoader extends AsyncTaskLoader<NetworkStats> { final NetworkTemplate template = mArgs.getParcelable(KEY_TEMPLATE); final long start = mArgs.getLong(KEY_START); final long end = mArgs.getLong(KEY_END); - - try { - return mSession.getSummaryForAllUid(template, start, end, false); - } catch (RemoteException e) { - return null; - } + return mNetworkStatsManager.querySummary(template, start, end); } @Override diff --git a/packages/SettingsLib/src/com/android/settingslib/net/UidDetailProvider.java b/packages/SettingsLib/src/com/android/settingslib/net/UidDetailProvider.java index 02326ea85ff6..623eb33f9c0d 100644 --- a/packages/SettingsLib/src/com/android/settingslib/net/UidDetailProvider.java +++ b/packages/SettingsLib/src/com/android/settingslib/net/UidDetailProvider.java @@ -17,6 +17,7 @@ package com.android.settingslib.net; import android.app.AppGlobals; +import android.app.usage.NetworkStats; import android.content.Context; import android.content.pm.ApplicationInfo; import android.content.pm.IPackageManager; @@ -116,13 +117,13 @@ public class UidDetailProvider { detail.label = res.getString(R.string.process_kernel_label); detail.icon = pm.getDefaultActivityIcon(); return detail; - case TrafficStats.UID_REMOVED: + case NetworkStats.Bucket.UID_REMOVED: detail.label = res.getString(UserManager.supportsMultipleUsers() ? R.string.data_usage_uninstalled_apps_users : R.string.data_usage_uninstalled_apps); detail.icon = pm.getDefaultActivityIcon(); return detail; - case TrafficStats.UID_TETHERING: + case NetworkStats.Bucket.UID_TETHERING: final TetheringManager tm = mContext.getSystemService(TetheringManager.class); detail.label = res.getString(Utils.getTetheringLabel(tm)); detail.icon = pm.getDefaultActivityIcon(); diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/net/NetworkCycleDataForUidLoaderTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/net/NetworkCycleDataForUidLoaderTest.java index 5b0f659e9c7a..2f3da831a08f 100644 --- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/net/NetworkCycleDataForUidLoaderTest.java +++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/net/NetworkCycleDataForUidLoaderTest.java @@ -16,6 +16,7 @@ package com.android.settingslib.net; +import static android.app.usage.NetworkStats.Bucket.STATE_ALL; import static android.app.usage.NetworkStats.Bucket.STATE_FOREGROUND; import static android.net.NetworkStats.TAG_NONE; @@ -83,7 +84,6 @@ public class NetworkCycleDataForUidLoaderTest { mLoader.recordUsage(start, end); - verify(mNetworkStatsManager).queryDetailsForUid(mNetworkTemplate, start, end, uid); verify(mNetworkStatsManager).queryDetailsForUidTagState( mNetworkTemplate, start, end, uid, TAG_NONE, STATE_FOREGROUND); } @@ -116,9 +116,12 @@ public class NetworkCycleDataForUidLoaderTest { mLoader.recordUsage(start, end); - verify(mNetworkStatsManager).queryDetailsForUid(mNetworkTemplate, start, end, 1); - verify(mNetworkStatsManager).queryDetailsForUid(mNetworkTemplate, start, end, 2); - verify(mNetworkStatsManager).queryDetailsForUid(mNetworkTemplate, start, end, 3); + verify(mNetworkStatsManager).queryDetailsForUidTagState(mNetworkTemplate, start, end, 1, + TAG_NONE, STATE_ALL); + verify(mNetworkStatsManager).queryDetailsForUidTagState(mNetworkTemplate, start, end, 2, + TAG_NONE, STATE_ALL); + verify(mNetworkStatsManager).queryDetailsForUidTagState(mNetworkTemplate, start, end, 3, + TAG_NONE, STATE_ALL); } } diff --git a/packages/Shell/AndroidManifest.xml b/packages/Shell/AndroidManifest.xml index 96310b8597d2..5b2e8ae3e7de 100644 --- a/packages/Shell/AndroidManifest.xml +++ b/packages/Shell/AndroidManifest.xml @@ -504,6 +504,7 @@ <!-- 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" /> + <uses-permission android:name="android.permission.OVERRIDE_WIFI_CONFIG" /> <!-- Permission required for CTS tests to enable/disable rate limiting toasts. --> <uses-permission android:name="android.permission.MANAGE_TOAST_RATE_LIMITING" /> diff --git a/packages/SystemUI/OWNERS b/packages/SystemUI/OWNERS index e1da74466b55..8323e326dea1 100644 --- a/packages/SystemUI/OWNERS +++ b/packages/SystemUI/OWNERS @@ -11,8 +11,10 @@ asc@google.com awickham@google.com beverlyt@google.com brockman@google.com +brzezinski@google.com brycelee@google.com ccassidy@google.com +chrisgollner@google.com cinek@google.com cwren@google.com dupin@google.com @@ -43,6 +45,8 @@ mpietal@google.com mrcasey@google.com mrenouf@google.com nesciosquid@google.com +nickchameyev@google.com +nicomazz@google.com ogunwale@google.com peanutbutter@google.com pinyaoting@google.com @@ -67,6 +71,7 @@ winsonc@google.com yurilin@google.com xuqiu@google.com zakcohen@google.com +jernej@google.com #Android Auto hseog@google.com diff --git a/services/Android.bp b/services/Android.bp index 8fb9ae86a15f..8947393849c1 100644 --- a/services/Android.bp +++ b/services/Android.bp @@ -176,6 +176,10 @@ cc_library_shared { name: "libandroid_servers", defaults: ["libservices.core-libs"], whole_static_libs: ["libservices.core"], + required: [ + // TODO: remove after NetworkStatsService is moved to the mainline module. + "libcom_android_net_module_util_jni", + ], } platform_compat_config { diff --git a/services/core/Android.bp b/services/core/Android.bp index 960f7ca63b1d..9d190087e300 100644 --- a/services/core/Android.bp +++ b/services/core/Android.bp @@ -166,6 +166,9 @@ java_library_static { "overlayable_policy_aidl-java", "SurfaceFlingerProperties", "com.android.sysprop.watchdog", + // This is used for services.connectivity-tiramisu-sources. + // TODO: delete when NetworkStatsService is moved to the mainline module. + "net-utils-device-common-bpf", ], javac_shard_size: 50, } diff --git a/services/core/java/android/app/usage/OWNERS b/services/core/java/android/app/usage/OWNERS new file mode 100644 index 000000000000..3a555143b11d --- /dev/null +++ b/services/core/java/android/app/usage/OWNERS @@ -0,0 +1 @@ +include platform/frameworks/base:/core/java/android/app/usage/OWNERS diff --git a/services/core/java/com/android/server/NetworkManagementService.java b/services/core/java/com/android/server/NetworkManagementService.java index 39516802e93b..39ac5effe6fa 100644 --- a/services/core/java/com/android/server/NetworkManagementService.java +++ b/services/core/java/com/android/server/NetworkManagementService.java @@ -20,12 +20,12 @@ import static android.Manifest.permission.CONNECTIVITY_INTERNAL; import static android.Manifest.permission.NETWORK_SETTINGS; import static android.Manifest.permission.OBSERVE_NETWORK_POLICY; import static android.Manifest.permission.SHUTDOWN; +import static android.net.ConnectivityManager.FIREWALL_CHAIN_DOZABLE; +import static android.net.ConnectivityManager.FIREWALL_CHAIN_POWERSAVE; +import static android.net.ConnectivityManager.FIREWALL_CHAIN_RESTRICTED; +import static android.net.ConnectivityManager.FIREWALL_CHAIN_STANDBY; import static android.net.INetd.FIREWALL_ALLOWLIST; -import static android.net.INetd.FIREWALL_CHAIN_DOZABLE; import static android.net.INetd.FIREWALL_CHAIN_NONE; -import static android.net.INetd.FIREWALL_CHAIN_POWERSAVE; -import static android.net.INetd.FIREWALL_CHAIN_RESTRICTED; -import static android.net.INetd.FIREWALL_CHAIN_STANDBY; import static android.net.INetd.FIREWALL_DENYLIST; import static android.net.INetd.FIREWALL_RULE_ALLOW; import static android.net.INetd.FIREWALL_RULE_DENY; @@ -34,16 +34,13 @@ import static android.net.NetworkPolicyManager.FIREWALL_CHAIN_NAME_POWERSAVE; import static android.net.NetworkPolicyManager.FIREWALL_CHAIN_NAME_RESTRICTED; import static android.net.NetworkPolicyManager.FIREWALL_CHAIN_NAME_STANDBY; import static android.net.NetworkPolicyManager.FIREWALL_RULE_DEFAULT; -import static android.net.NetworkStats.SET_DEFAULT; -import static android.net.NetworkStats.STATS_PER_UID; -import static android.net.NetworkStats.TAG_NONE; -import static android.net.TrafficStats.UID_TETHERING; import static com.android.net.module.util.NetworkStatsUtils.LIMIT_GLOBAL_ALERT; import android.annotation.NonNull; import android.app.ActivityManager; import android.content.Context; +import android.net.ConnectivityManager; import android.net.INetd; import android.net.INetdUnsolicitedEventListener; import android.net.INetworkManagementEventObserver; @@ -57,7 +54,6 @@ import android.net.NetworkPolicyManager; import android.net.NetworkStack; import android.net.NetworkStats; import android.net.RouteInfo; -import android.net.TetherStatsParcel; import android.net.UidRangeParcel; import android.net.util.NetdService; import android.os.BatteryStats; @@ -1158,19 +1154,12 @@ public class NetworkManagementService extends INetworkManagementService.Stub { } Trace.traceBegin(Trace.TRACE_TAG_NETWORK, "inetd bandwidth"); + final ConnectivityManager cm = mContext.getSystemService(ConnectivityManager.class); try { if (allowlist) { - if (enable) { - mNetdService.bandwidthAddNiceApp(uid); - } else { - mNetdService.bandwidthRemoveNiceApp(uid); - } + cm.updateMeteredNetworkAllowList(uid, enable); } else { - if (enable) { - mNetdService.bandwidthAddNaughtyApp(uid); - } else { - mNetdService.bandwidthRemoveNaughtyApp(uid); - } + cm.updateMeteredNetworkDenyList(uid, enable); } synchronized (mRulesLock) { if (enable) { @@ -1179,7 +1168,7 @@ public class NetworkManagementService extends INetworkManagementService.Stub { quotaList.delete(uid); } } - } catch (RemoteException | ServiceSpecificException e) { + } catch (RuntimeException e) { throw new IllegalStateException(e); } finally { Trace.traceEnd(Trace.TRACE_TAG_NETWORK); @@ -1292,40 +1281,9 @@ public class NetworkManagementService extends INetworkManagementService.Stub { private class NetdTetheringStatsProvider extends ITetheringStatsProvider.Stub { @Override public NetworkStats getTetherStats(int how) { - // We only need to return per-UID stats. Per-device stats are already counted by - // interface counters. - if (how != STATS_PER_UID) { - return new NetworkStats(SystemClock.elapsedRealtime(), 0); - } - - final TetherStatsParcel[] tetherStatsVec; - try { - tetherStatsVec = mNetdService.tetherGetStats(); - } catch (RemoteException | ServiceSpecificException e) { - throw new IllegalStateException("problem parsing tethering stats: ", e); - } - - final NetworkStats stats = new NetworkStats(SystemClock.elapsedRealtime(), - tetherStatsVec.length); - final NetworkStats.Entry entry = new NetworkStats.Entry(); - - for (TetherStatsParcel tetherStats : tetherStatsVec) { - try { - entry.iface = tetherStats.iface; - entry.uid = UID_TETHERING; - entry.set = SET_DEFAULT; - entry.tag = TAG_NONE; - entry.rxBytes = tetherStats.rxBytes; - entry.rxPackets = tetherStats.rxPackets; - entry.txBytes = tetherStats.txBytes; - entry.txPackets = tetherStats.txPackets; - stats.combineValues(entry); - } catch (ArrayIndexOutOfBoundsException e) { - throw new IllegalStateException("invalid tethering stats " + e); - } - } - - return stats; + // Remove the implementation of NetdTetheringStatsProvider#getTetherStats + // since all callers are migrated to use INetd#tetherGetStats directly. + throw new UnsupportedOperationException(); } @Override @@ -1336,20 +1294,9 @@ public class NetworkManagementService extends INetworkManagementService.Stub { @Override public NetworkStats getNetworkStatsTethering(int how) { - NetworkStack.checkNetworkStackPermission(mContext); - - final NetworkStats stats = new NetworkStats(SystemClock.elapsedRealtime(), 1); - synchronized (mTetheringStatsProviders) { - for (ITetheringStatsProvider provider: mTetheringStatsProviders.keySet()) { - try { - stats.combineAllValues(provider.getTetherStats(how)); - } catch (RemoteException e) { - Log.e(TAG, "Problem reading tethering stats from " + - mTetheringStatsProviders.get(provider) + ": " + e); - } - } - } - return stats; + // Remove the implementation of getNetworkStatsTethering since all callers are migrated + // to use INetd#tetherGetStats directly. + throw new UnsupportedOperationException(); } @Override @@ -1464,9 +1411,10 @@ public class NetworkManagementService extends INetworkManagementService.Stub { throw new IllegalArgumentException("Bad child chain: " + chainName); } + final ConnectivityManager cm = mContext.getSystemService(ConnectivityManager.class); try { - mNetdService.firewallEnableChildChain(chain, enable); - } catch (RemoteException | ServiceSpecificException e) { + cm.setFirewallChainEnabled(chain, enable); + } catch (RuntimeException e) { throw new IllegalStateException(e); } @@ -1538,25 +1486,10 @@ public class NetworkManagementService extends INetworkManagementService.Stub { updateFirewallUidRuleLocked(chain, uid, FIREWALL_RULE_DEFAULT); } } + final ConnectivityManager cm = mContext.getSystemService(ConnectivityManager.class); try { - switch (chain) { - case FIREWALL_CHAIN_DOZABLE: - mNetdService.firewallReplaceUidChain("fw_dozable", true, uids); - break; - case FIREWALL_CHAIN_STANDBY: - mNetdService.firewallReplaceUidChain("fw_standby", false, uids); - break; - case FIREWALL_CHAIN_POWERSAVE: - mNetdService.firewallReplaceUidChain("fw_powersave", true, uids); - break; - case FIREWALL_CHAIN_RESTRICTED: - mNetdService.firewallReplaceUidChain("fw_restricted", true, uids); - break; - case FIREWALL_CHAIN_NONE: - default: - Slog.d(TAG, "setFirewallUidRules() called on invalid chain: " + chain); - } - } catch (RemoteException e) { + cm.replaceFirewallChain(chain, uids); + } catch (RuntimeException e) { Slog.w(TAG, "Error flushing firewall chain " + chain, e); } } @@ -1572,10 +1505,10 @@ public class NetworkManagementService extends INetworkManagementService.Stub { private void setFirewallUidRuleLocked(int chain, int uid, int rule) { if (updateFirewallUidRuleLocked(chain, uid, rule)) { - final int ruleType = getFirewallRuleType(chain, rule); + final ConnectivityManager cm = mContext.getSystemService(ConnectivityManager.class); try { - mNetdService.firewallSetUidRule(chain, uid, ruleType); - } catch (RemoteException | ServiceSpecificException e) { + cm.updateFirewallRule(chain, uid, isFirewallRuleAllow(chain, rule)); + } catch (RuntimeException e) { throw new IllegalStateException(e); } } @@ -1645,12 +1578,12 @@ public class NetworkManagementService extends INetworkManagementService.Stub { } } - private int getFirewallRuleType(int chain, int rule) { + // There are only two type of firewall rule: FIREWALL_RULE_ALLOW or FIREWALL_RULE_DENY. + private boolean isFirewallRuleAllow(int chain, int rule) { if (rule == NetworkPolicyManager.FIREWALL_RULE_DEFAULT) { - return getFirewallType(chain) == FIREWALL_ALLOWLIST - ? INetd.FIREWALL_RULE_DENY : INetd.FIREWALL_RULE_ALLOW; + return getFirewallType(chain) == FIREWALL_DENYLIST; } - return rule; + return rule == INetd.FIREWALL_RULE_ALLOW; } private void enforceSystemUid() { diff --git a/services/core/java/com/android/server/StorageManagerService.java b/services/core/java/com/android/server/StorageManagerService.java index 53c8635c4e0a..9546496fd8e8 100644 --- a/services/core/java/com/android/server/StorageManagerService.java +++ b/services/core/java/com/android/server/StorageManagerService.java @@ -3620,8 +3620,12 @@ class StorageManagerService extends IStorageManager.Stub mInstaller.tryMountDataMirror(volumeUuid); } } - } catch (Exception e) { + } catch (RemoteException | Installer.InstallerException e) { Slog.wtf(TAG, e); + // Make sure to re-throw this exception; we must not ignore failure + // to prepare the user storage as it could indicate that encryption + // wasn't successfully set up. + throw new RuntimeException(e); } } diff --git a/services/core/java/com/android/server/clipboard/ClipboardService.java b/services/core/java/com/android/server/clipboard/ClipboardService.java index 3d5abfe83394..38df5f896000 100644 --- a/services/core/java/com/android/server/clipboard/ClipboardService.java +++ b/services/core/java/com/android/server/clipboard/ClipboardService.java @@ -571,7 +571,7 @@ public class ClipboardService extends SystemService { final boolean canCopyIntoProfile = !hasRestriction( UserManager.DISALLOW_SHARE_INTO_MANAGED_PROFILE, id); if (canCopyIntoProfile) { - setPrimaryClipInternalLocked( + setPrimaryClipInternalNoClassifyLocked( getClipboardLocked(id), clip, uid, sourcePackage); } } diff --git a/services/core/java/com/android/server/clipboard/OWNERS b/services/core/java/com/android/server/clipboard/OWNERS index 5449df908051..0d5dbf9acac3 100644 --- a/services/core/java/com/android/server/clipboard/OWNERS +++ b/services/core/java/com/android/server/clipboard/OWNERS @@ -1 +1,3 @@ per-file EmulatorClipboardMonitor.java = bohu@google.com,lfy@google.com,rkir@google.com + +olilan@google.com diff --git a/services/core/java/com/android/server/connectivity/MultipathPolicyTracker.java b/services/core/java/com/android/server/connectivity/MultipathPolicyTracker.java index fce673765020..603f20633cfb 100644 --- a/services/core/java/com/android/server/connectivity/MultipathPolicyTracker.java +++ b/services/core/java/com/android/server/connectivity/MultipathPolicyTracker.java @@ -18,14 +18,12 @@ package com.android.server.connectivity; import static android.net.ConnectivityManager.MULTIPATH_PREFERENCE_HANDOVER; import static android.net.ConnectivityManager.MULTIPATH_PREFERENCE_RELIABILITY; -import static android.net.ConnectivityManager.TYPE_MOBILE; import static android.net.NetworkCapabilities.NET_CAPABILITY_INTERNET; import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_METERED; import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_ROAMING; import static android.net.NetworkCapabilities.TRANSPORT_CELLULAR; import static android.net.NetworkPolicy.LIMIT_DISABLED; import static android.net.NetworkPolicy.WARNING_DISABLED; -import static android.net.NetworkTemplate.OEM_MANAGED_ALL; import static android.provider.Settings.Global.NETWORK_DEFAULT_DAILY_MULTIPATH_QUOTA_BYTES; import static android.telephony.SubscriptionManager.INVALID_SUBSCRIPTION_ID; @@ -95,6 +93,7 @@ public class MultipathPolicyTracker { private static String TAG = MultipathPolicyTracker.class.getSimpleName(); private static final boolean DBG = false; + private static final long MIN_THRESHOLD_BYTES = 2 * 1_048_576L; // 2MiB // This context is for the current user. private final Context mContext; @@ -279,15 +278,11 @@ public class MultipathPolicyTracker { } private NetworkIdentity getTemplateMatchingNetworkIdentity(NetworkCapabilities nc) { - return new NetworkIdentity( - ConnectivityManager.TYPE_MOBILE, - 0 /* subType, unused for template matching */, - subscriberId, - null /* networkId, unused for matching mobile networks */, - !nc.hasCapability(NET_CAPABILITY_NOT_ROAMING), - !nc.hasCapability(NET_CAPABILITY_NOT_METERED), - false /* defaultNetwork, templates should have DEFAULT_NETWORK_ALL */, - OEM_MANAGED_ALL); + return new NetworkIdentity.Builder().setType(ConnectivityManager.TYPE_MOBILE) + .setSubscriberId(subscriberId) + .setRoaming(!nc.hasCapability(NET_CAPABILITY_NOT_ROAMING)) + .setMetered(!nc.hasCapability(NET_CAPABILITY_NOT_METERED)) + .build(); } private long getRemainingDailyBudget(long limitBytes, @@ -376,7 +371,7 @@ public class MultipathPolicyTracker { // This will only be called if the total quota for the day changed, not if usage changed // since last time, so even if this is called very often the budget will not snap to 0 // as soon as there are less than 2MB left for today. - if (budget > NetworkStatsManager.MIN_THRESHOLD_BYTES) { + if (budget > MIN_THRESHOLD_BYTES) { if (DBG) { Log.d(TAG, "Setting callback for " + budget + " bytes on network " + network); } @@ -409,8 +404,8 @@ public class MultipathPolicyTracker { private void registerUsageCallback(long budget) { maybeUnregisterUsageCallback(); - mStatsManager.registerUsageCallback(mNetworkTemplate, TYPE_MOBILE, budget, - mUsageCallback, mHandler); + mStatsManager.registerUsageCallback(mNetworkTemplate, budget, + (command) -> mHandler.post(command), mUsageCallback); mMultipathBudget = budget; } diff --git a/services/core/java/com/android/server/net/NetworkPolicyManagerService.java b/services/core/java/com/android/server/net/NetworkPolicyManagerService.java index 8902d0d2cac4..c05138f8eae1 100644 --- a/services/core/java/com/android/server/net/NetworkPolicyManagerService.java +++ b/services/core/java/com/android/server/net/NetworkPolicyManagerService.java @@ -24,7 +24,6 @@ import static android.Manifest.permission.MANAGE_SUBSCRIPTION_PLANS; import static android.Manifest.permission.NETWORK_SETTINGS; import static android.Manifest.permission.NETWORK_STACK; import static android.Manifest.permission.OBSERVE_NETWORK_POLICY; -import static android.Manifest.permission.READ_NETWORK_USAGE_HISTORY; import static android.Manifest.permission.READ_PHONE_STATE; import static android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE; import static android.app.PendingIntent.FLAG_IMMUTABLE; @@ -63,7 +62,6 @@ import static android.net.INetd.FIREWALL_RULE_DENY; import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_METERED; import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_ROAMING; import static android.net.NetworkCapabilities.TRANSPORT_CELLULAR; -import static android.net.NetworkIdentity.OEM_NONE; import static android.net.NetworkPolicy.LIMIT_DISABLED; import static android.net.NetworkPolicy.SNOOZE_NEVER; import static android.net.NetworkPolicy.WARNING_DISABLED; @@ -102,7 +100,6 @@ import static android.net.NetworkTemplate.MATCH_MOBILE; import static android.net.NetworkTemplate.MATCH_WIFI; import static android.net.NetworkTemplate.buildTemplateCarrierMetered; import static android.net.NetworkTemplate.buildTemplateMobileAll; -import static android.net.TrafficStats.MB_IN_BYTES; import static android.net.netstats.provider.NetworkStatsProvider.QUOTA_UNLIMITED; import static android.os.Trace.TRACE_TAG_NETWORK; import static android.provider.Settings.Global.NETPOLICY_OVERRIDE_ENABLED; @@ -131,7 +128,6 @@ import static com.android.internal.util.XmlUtils.writeIntAttribute; import static com.android.internal.util.XmlUtils.writeLongAttribute; import static com.android.internal.util.XmlUtils.writeStringAttribute; import static com.android.net.module.util.NetworkStatsUtils.LIMIT_GLOBAL_ALERT; -import static com.android.server.net.NetworkStatsService.ACTION_NETWORK_STATS_UPDATED; import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT; import static org.xmlpull.v1.XmlPullParser.END_TAG; @@ -185,7 +181,6 @@ import android.net.NetworkStack; import android.net.NetworkStateSnapshot; import android.net.NetworkTemplate; import android.net.TelephonyNetworkSpecifier; -import android.net.TrafficStats; import android.net.wifi.WifiConfiguration; import android.net.wifi.WifiManager; import android.os.BestClock; @@ -1013,10 +1008,11 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { userFilter.addAction(ACTION_USER_REMOVED); mContext.registerReceiver(mUserReceiver, userFilter, null, mHandler); - // listen for stats update events - final IntentFilter statsFilter = new IntentFilter(ACTION_NETWORK_STATS_UPDATED); - mContext.registerReceiver( - mStatsReceiver, statsFilter, READ_NETWORK_USAGE_HISTORY, mHandler); + // listen for stats updated callbacks for interested network types. + mNetworkStats.registerUsageCallback(new NetworkTemplate.Builder(MATCH_MOBILE).build(), + 0 /* thresholdBytes */, new HandlerExecutor(mHandler), mStatsCallback); + mNetworkStats.registerUsageCallback(new NetworkTemplate.Builder(MATCH_WIFI).build(), + 0 /* thresholdBytes */, new HandlerExecutor(mHandler), mStatsCallback); // listen for restrict background changes from notifications final IntentFilter allowFilter = new IntentFilter(ACTION_ALLOW_BACKGROUND); @@ -1221,19 +1217,16 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { }; /** - * Receiver that watches for {@link NetworkStatsManager} updates, which we - * use to check against {@link NetworkPolicy#warningBytes}. + * Listener that watches for {@link NetworkStatsManager} updates, which + * NetworkPolicyManagerService uses to check against {@link NetworkPolicy#warningBytes}. */ - private final NetworkStatsBroadcastReceiver mStatsReceiver = - new NetworkStatsBroadcastReceiver(); - private class NetworkStatsBroadcastReceiver extends BroadcastReceiver { - private boolean mIsAnyIntentReceived = false; - @Override - public void onReceive(Context context, Intent intent) { - // on background handler thread, and verified - // READ_NETWORK_USAGE_HISTORY permission above. + private final StatsCallback mStatsCallback = new StatsCallback(); + private class StatsCallback extends NetworkStatsManager.UsageCallback { + private boolean mIsAnyCallbackReceived = false; - mIsAnyIntentReceived = true; + @Override + public void onThresholdReached(int networkType, String subscriberId) { + mIsAnyCallbackReceived = true; synchronized (mNetworkPoliciesSecondLock) { updateNetworkRulesNL(); @@ -1243,11 +1236,11 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { } /** - * Return whether any {@code ACTION_NETWORK_STATS_UPDATED} intent is received. + * Return whether any callback is received. * Used to determine if NetworkStatsService is ready. */ - public boolean isAnyIntentReceived() { - return mIsAnyIntentReceived; + public boolean isAnyCallbackReceived() { + return mIsAnyCallbackReceived; } }; @@ -1474,7 +1467,7 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { // Skip if not ready. NetworkStatsService will block public API calls until it is // ready. To prevent NPMS be blocked on that, skip and fail fast instead. - if (!mStatsReceiver.isAnyIntentReceived()) return null; + if (!mStatsCallback.isAnyCallbackReceived()) return null; final List<NetworkStats.Bucket> stats = mDeps.getNetworkUidBytes(template, start, end); for (final NetworkStats.Bucket entry : stats) { @@ -1518,13 +1511,11 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { for (int i = 0; i < mSubIdToSubscriberId.size(); i++) { final int subId = mSubIdToSubscriberId.keyAt(i); final String subscriberId = mSubIdToSubscriberId.valueAt(i); - final NetworkIdentity probeIdent = new NetworkIdentity(TYPE_MOBILE, - TelephonyManager.NETWORK_TYPE_UNKNOWN, subscriberId, null, false, true, - true, OEM_NONE); - /* While OEM_NONE indicates "any non OEM managed network", OEM_NONE is meant to be a - * placeholder value here. The probeIdent is matched against a NetworkTemplate which - * should have its OEM managed value set to OEM_MANAGED_ALL, which will cause the - * template to match probeIdent without regard to OEM managed status. */ + final NetworkIdentity probeIdent = new NetworkIdentity.Builder() + .setType(TYPE_MOBILE) + .setSubscriberId(subscriberId) + .setMetered(true) + .setDefaultNetwork(true).build(); if (template.matches(probeIdent)) { return subId; } @@ -1757,9 +1748,11 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { // find and update the carrier NetworkPolicy for this subscriber id boolean policyUpdated = false; - final NetworkIdentity probeIdent = new NetworkIdentity(TYPE_MOBILE, - TelephonyManager.NETWORK_TYPE_UNKNOWN, subscriberId, null, false, true, true, - OEM_NONE); + final NetworkIdentity probeIdent = new NetworkIdentity.Builder() + .setType(TYPE_MOBILE) + .setSubscriberId(subscriberId) + .setMetered(true) + .setDefaultNetwork(true).build(); for (int i = mNetworkPolicy.size() - 1; i >= 0; i--) { final NetworkTemplate template = mNetworkPolicy.keyAt(i); if (template.matches(probeIdent)) { @@ -1987,10 +1980,11 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { for (int i = 0; i < mSubIdToSubscriberId.size(); i++) { final int subId = mSubIdToSubscriberId.keyAt(i); final String subscriberId = mSubIdToSubscriberId.valueAt(i); - - final NetworkIdentity probeIdent = new NetworkIdentity(TYPE_MOBILE, - TelephonyManager.NETWORK_TYPE_UNKNOWN, subscriberId, null, false, true, - true, OEM_NONE); + final NetworkIdentity probeIdent = new NetworkIdentity.Builder() + .setType(TYPE_MOBILE) + .setSubscriberId(subscriberId) + .setMetered(true) + .setDefaultNetwork(true).build(); // Template is matched when subscriber id matches. if (template.matches(probeIdent)) { matchingSubIds.add(subId); @@ -2094,11 +2088,9 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { for (final NetworkStateSnapshot snapshot : snapshots) { mNetIdToSubId.put(snapshot.getNetwork().getNetId(), parseSubId(snapshot)); - // Policies matched by NPMS only match by subscriber ID or by network ID. Thus subtype - // in the object created here is never used and its value doesn't matter, so use - // NETWORK_TYPE_UNKNOWN. - final NetworkIdentity ident = NetworkIdentity.buildNetworkIdentity(mContext, snapshot, - true, TelephonyManager.NETWORK_TYPE_UNKNOWN /* subType */); + // Policies matched by NPMS only match by subscriber ID or by network ID. + final NetworkIdentity ident = new NetworkIdentity.Builder() + .setNetworkStateSnapshot(snapshot).setDefaultNetwork(true).build(); identified.put(snapshot, ident); } @@ -2295,9 +2287,11 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { @GuardedBy("mNetworkPoliciesSecondLock") private boolean ensureActiveCarrierPolicyAL(int subId, String subscriberId) { // Poke around to see if we already have a policy - final NetworkIdentity probeIdent = new NetworkIdentity(TYPE_MOBILE, - TelephonyManager.NETWORK_TYPE_UNKNOWN, subscriberId, null, false, true, true, - OEM_NONE); + final NetworkIdentity probeIdent = new NetworkIdentity.Builder() + .setType(TYPE_MOBILE) + .setSubscriberId(subscriberId) + .setMetered(true) + .setDefaultNetwork(true).build(); for (int i = mNetworkPolicy.size() - 1; i >= 0; i--) { final NetworkTemplate template = mNetworkPolicy.keyAt(i); if (template.matches(probeIdent)) { @@ -2323,7 +2317,7 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { if (dataWarningConfig == WARNING_DISABLED) { return WARNING_DISABLED; } else { - return dataWarningConfig * MB_IN_BYTES; + return DataUnit.MEBIBYTES.toBytes(dataWarningConfig); } } @@ -2707,7 +2701,7 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { final List<WifiConfiguration> configs = wm.getConfiguredNetworks(); for (int i = 0; i < configs.size(); ++i) { final WifiConfiguration config = configs.get(i); - for (String key : config.getAllPersistableNetworkKeys()) { + for (String key : config.getAllNetworkKeys()) { final Boolean metered = wifiNetworkKeys.get(key); if (metered != null) { Slog.d(TAG, "Found network " + key + "; upgrading metered hint"); @@ -3492,9 +3486,9 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { plans.add(SubscriptionPlan.Builder .createRecurringMonthly(ZonedDateTime.parse("2007-03-14T00:00:00.000Z")) .setTitle("G-Mobile") - .setDataLimit(5 * TrafficStats.GB_IN_BYTES, + .setDataLimit(DataUnit.GIBIBYTES.toBytes(5), SubscriptionPlan.LIMIT_BEHAVIOR_BILLED) - .setDataUsage(1 * TrafficStats.GB_IN_BYTES, + .setDataUsage(DataUnit.GIBIBYTES.toBytes(1), ZonedDateTime.now().minusHours(36).toInstant().toEpochMilli()) .build()); plans.add(SubscriptionPlan.Builder @@ -3502,15 +3496,15 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { .setTitle("G-Mobile Happy") .setDataLimit(SubscriptionPlan.BYTES_UNLIMITED, SubscriptionPlan.LIMIT_BEHAVIOR_BILLED) - .setDataUsage(5 * TrafficStats.GB_IN_BYTES, + .setDataUsage(DataUnit.GIBIBYTES.toBytes(5), ZonedDateTime.now().minusHours(36).toInstant().toEpochMilli()) .build()); plans.add(SubscriptionPlan.Builder .createRecurringMonthly(ZonedDateTime.parse("2017-03-14T00:00:00.000Z")) .setTitle("G-Mobile, Charged after limit") - .setDataLimit(5 * TrafficStats.GB_IN_BYTES, + .setDataLimit(DataUnit.GIBIBYTES.toBytes(5), SubscriptionPlan.LIMIT_BEHAVIOR_BILLED) - .setDataUsage(5 * TrafficStats.GB_IN_BYTES, + .setDataUsage(DataUnit.GIBIBYTES.toBytes(5), ZonedDateTime.now().minusHours(36).toInstant().toEpochMilli()) .build()); } else if ("month_soft".equals(fake)) { @@ -3519,25 +3513,25 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { .setTitle("G-Mobile is the carriers name who this plan belongs to") .setSummary("Crazy unlimited bandwidth plan with incredibly long title " + "that should be cut off to prevent UI from looking terrible") - .setDataLimit(5 * TrafficStats.GB_IN_BYTES, + .setDataLimit(DataUnit.GIBIBYTES.toBytes(5), SubscriptionPlan.LIMIT_BEHAVIOR_THROTTLED) - .setDataUsage(1 * TrafficStats.GB_IN_BYTES, + .setDataUsage(DataUnit.GIBIBYTES.toBytes(1), ZonedDateTime.now().minusHours(1).toInstant().toEpochMilli()) .build()); plans.add(SubscriptionPlan.Builder .createRecurringMonthly(ZonedDateTime.parse("2017-03-14T00:00:00.000Z")) .setTitle("G-Mobile, Throttled after limit") - .setDataLimit(5 * TrafficStats.GB_IN_BYTES, + .setDataLimit(DataUnit.GIBIBYTES.toBytes(5), SubscriptionPlan.LIMIT_BEHAVIOR_THROTTLED) - .setDataUsage(5 * TrafficStats.GB_IN_BYTES, + .setDataUsage(DataUnit.GIBIBYTES.toBytes(5), ZonedDateTime.now().minusHours(1).toInstant().toEpochMilli()) .build()); plans.add(SubscriptionPlan.Builder .createRecurringMonthly(ZonedDateTime.parse("2017-03-14T00:00:00.000Z")) .setTitle("G-Mobile, No data connection after limit") - .setDataLimit(5 * TrafficStats.GB_IN_BYTES, + .setDataLimit(DataUnit.GIBIBYTES.toBytes(5), SubscriptionPlan.LIMIT_BEHAVIOR_DISABLED) - .setDataUsage(5 * TrafficStats.GB_IN_BYTES, + .setDataUsage(DataUnit.GIBIBYTES.toBytes(5), ZonedDateTime.now().minusHours(1).toInstant().toEpochMilli()) .build()); @@ -3545,25 +3539,25 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { plans.add(SubscriptionPlan.Builder .createRecurringMonthly(ZonedDateTime.parse("2007-03-14T00:00:00.000Z")) .setTitle("G-Mobile is the carriers name who this plan belongs to") - .setDataLimit(5 * TrafficStats.GB_IN_BYTES, + .setDataLimit(DataUnit.GIBIBYTES.toBytes(5), SubscriptionPlan.LIMIT_BEHAVIOR_THROTTLED) - .setDataUsage(6 * TrafficStats.GB_IN_BYTES, + .setDataUsage(DataUnit.GIBIBYTES.toBytes(6), ZonedDateTime.now().minusHours(1).toInstant().toEpochMilli()) .build()); plans.add(SubscriptionPlan.Builder .createRecurringMonthly(ZonedDateTime.parse("2017-03-14T00:00:00.000Z")) .setTitle("G-Mobile, Throttled after limit") - .setDataLimit(5 * TrafficStats.GB_IN_BYTES, + .setDataLimit(DataUnit.GIBIBYTES.toBytes(5), SubscriptionPlan.LIMIT_BEHAVIOR_THROTTLED) - .setDataUsage(5 * TrafficStats.GB_IN_BYTES, + .setDataUsage(DataUnit.GIBIBYTES.toBytes(5), ZonedDateTime.now().minusHours(1).toInstant().toEpochMilli()) .build()); plans.add(SubscriptionPlan.Builder .createRecurringMonthly(ZonedDateTime.parse("2017-03-14T00:00:00.000Z")) .setTitle("G-Mobile, No data connection after limit") - .setDataLimit(5 * TrafficStats.GB_IN_BYTES, + .setDataLimit(DataUnit.GIBIBYTES.toBytes(5), SubscriptionPlan.LIMIT_BEHAVIOR_DISABLED) - .setDataUsage(5 * TrafficStats.GB_IN_BYTES, + .setDataUsage(DataUnit.GIBIBYTES.toBytes(5), ZonedDateTime.now().minusHours(1).toInstant().toEpochMilli()) .build()); @@ -3577,9 +3571,9 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { .createNonrecurring(ZonedDateTime.now().minusDays(20), ZonedDateTime.now().plusDays(10)) .setTitle("G-Mobile") - .setDataLimit(512 * TrafficStats.MB_IN_BYTES, + .setDataLimit(DataUnit.MEBIBYTES.toBytes(512), SubscriptionPlan.LIMIT_BEHAVIOR_DISABLED) - .setDataUsage(100 * TrafficStats.MB_IN_BYTES, + .setDataUsage(DataUnit.MEBIBYTES.toBytes(100), ZonedDateTime.now().minusHours(3).toInstant().toEpochMilli()) .build()); } else if ("prepaid_crazy".equals(fake)) { @@ -3587,9 +3581,9 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { .createNonrecurring(ZonedDateTime.now().minusDays(20), ZonedDateTime.now().plusDays(10)) .setTitle("G-Mobile Anytime") - .setDataLimit(512 * TrafficStats.MB_IN_BYTES, + .setDataLimit(DataUnit.MEBIBYTES.toBytes(512), SubscriptionPlan.LIMIT_BEHAVIOR_DISABLED) - .setDataUsage(100 * TrafficStats.MB_IN_BYTES, + .setDataUsage(DataUnit.MEBIBYTES.toBytes(100), ZonedDateTime.now().minusHours(3).toInstant().toEpochMilli()) .build()); plans.add(SubscriptionPlan.Builder @@ -3597,9 +3591,9 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { ZonedDateTime.now().plusDays(20)) .setTitle("G-Mobile Nickel Nights") .setSummary("5¢/GB between 1-5AM") - .setDataLimit(5 * TrafficStats.GB_IN_BYTES, + .setDataLimit(DataUnit.GIBIBYTES.toBytes(5), SubscriptionPlan.LIMIT_BEHAVIOR_THROTTLED) - .setDataUsage(15 * TrafficStats.MB_IN_BYTES, + .setDataUsage(DataUnit.MEBIBYTES.toBytes(15), ZonedDateTime.now().minusHours(30).toInstant().toEpochMilli()) .build()); plans.add(SubscriptionPlan.Builder @@ -3607,9 +3601,9 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { ZonedDateTime.now().plusDays(20)) .setTitle("G-Mobile Bonus 3G") .setSummary("Unlimited 3G data") - .setDataLimit(1 * TrafficStats.GB_IN_BYTES, + .setDataLimit(DataUnit.GIBIBYTES.toBytes(1), SubscriptionPlan.LIMIT_BEHAVIOR_THROTTLED) - .setDataUsage(300 * TrafficStats.MB_IN_BYTES, + .setDataUsage(DataUnit.MEBIBYTES.toBytes(300), ZonedDateTime.now().minusHours(1).toInstant().toEpochMilli()) .build()); } else if ("unlimited".equals(fake)) { @@ -3619,7 +3613,7 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { .setTitle("G-Mobile Awesome") .setDataLimit(SubscriptionPlan.BYTES_UNLIMITED, SubscriptionPlan.LIMIT_BEHAVIOR_THROTTLED) - .setDataUsage(50 * TrafficStats.MB_IN_BYTES, + .setDataUsage(DataUnit.MEBIBYTES.toBytes(50), ZonedDateTime.now().minusHours(3).toInstant().toEpochMilli()) .build()); } @@ -5470,7 +5464,7 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { private long getTotalBytes(NetworkTemplate template, long start, long end) { // Skip if not ready. NetworkStatsService will block public API calls until it is // ready. To prevent NPMS be blocked on that, skip and fail fast instead. - if (!mStatsReceiver.isAnyIntentReceived()) return 0; + if (!mStatsCallback.isAnyCallbackReceived()) return 0; return mDeps.getNetworkTotalBytes(template, start, end); } diff --git a/services/core/java/com/android/server/pm/UserDataPreparer.java b/services/core/java/com/android/server/pm/UserDataPreparer.java index 045a295da965..504769064808 100644 --- a/services/core/java/com/android/server/pm/UserDataPreparer.java +++ b/services/core/java/com/android/server/pm/UserDataPreparer.java @@ -22,6 +22,7 @@ import android.content.Context; import android.content.pm.UserInfo; import android.os.Environment; import android.os.FileUtils; +import android.os.RecoverySystem; import android.os.storage.StorageManager; import android.os.storage.VolumeInfo; import android.os.SystemProperties; @@ -115,6 +116,13 @@ class UserDataPreparer { // Try one last time; if we fail again we're really in trouble prepareUserDataLI(volumeUuid, userId, userSerial, flags | StorageManager.FLAG_STORAGE_DE, false); + } else { + try { + Log.e(TAG, "prepareUserData failed", e); + RecoverySystem.rebootPromptAndWipeUserData(mContext, "prepareUserData failed"); + } catch (IOException e2) { + throw new RuntimeException("error rebooting into recovery", e2); + } } } } diff --git a/services/core/java/com/android/server/stats/pull/StatsPullAtomService.java b/services/core/java/com/android/server/stats/pull/StatsPullAtomService.java index bbd4d058dfaf..1fa948cef216 100644 --- a/services/core/java/com/android/server/stats/pull/StatsPullAtomService.java +++ b/services/core/java/com/android/server/stats/pull/StatsPullAtomService.java @@ -18,21 +18,17 @@ package com.android.server.stats.pull; import static android.app.AppOpsManager.OP_FLAG_SELF; import static android.app.AppOpsManager.OP_FLAG_TRUSTED_PROXIED; -import static android.app.usage.NetworkStatsManager.FLAG_AUGMENT_WITH_SUBSCRIPTION_PLAN; -import static android.app.usage.NetworkStatsManager.FLAG_POLL_FORCE; -import static android.app.usage.NetworkStatsManager.FLAG_POLL_ON_OPEN; import static android.content.pm.PackageInfo.REQUESTED_PERMISSION_GRANTED; import static android.content.pm.PermissionInfo.PROTECTION_DANGEROUS; import static android.net.NetworkCapabilities.TRANSPORT_CELLULAR; import static android.net.NetworkCapabilities.TRANSPORT_WIFI; -import static android.net.NetworkIdentity.OEM_PAID; -import static android.net.NetworkIdentity.OEM_PRIVATE; import static android.net.NetworkStats.METERED_YES; import static android.net.NetworkTemplate.MATCH_ETHERNET; import static android.net.NetworkTemplate.MATCH_MOBILE; import static android.net.NetworkTemplate.MATCH_WIFI; import static android.net.NetworkTemplate.OEM_MANAGED_ALL; -import static android.net.NetworkTemplate.getAllCollapsedRatTypes; +import static android.net.NetworkTemplate.OEM_MANAGED_PAID; +import static android.net.NetworkTemplate.OEM_MANAGED_PRIVATE; import static android.os.Debug.getIonHeapsSizeKb; import static android.os.Process.LAST_SHARED_APPLICATION_GID; import static android.os.Process.getUidForPid; @@ -73,6 +69,7 @@ import android.app.ProcessMemoryState; import android.app.RuntimeAppOpAccessMessage; import android.app.StatsManager; import android.app.StatsManager.PullAtomMetadata; +import android.app.usage.NetworkStatsManager; import android.bluetooth.BluetoothActivityEnergyInfo; import android.bluetooth.BluetoothAdapter; import android.bluetooth.UidTraffic; @@ -86,8 +83,6 @@ import android.hardware.biometrics.BiometricsProtoEnums; import android.hardware.face.FaceManager; import android.hardware.fingerprint.FingerprintManager; import android.net.ConnectivityManager; -import android.net.INetworkStatsService; -import android.net.INetworkStatsSession; import android.net.Network; import android.net.NetworkRequest; import android.net.NetworkStats; @@ -181,6 +176,7 @@ import com.android.internal.os.StoragedUidIoStatsReader; import com.android.internal.os.SystemServerCpuThreadReader.SystemServiceCpuThreadTimes; import com.android.internal.util.CollectionUtils; import com.android.internal.util.FrameworkStatsLog; +import com.android.net.module.util.NetworkStatsUtils; import com.android.role.RoleManagerLocal; import com.android.server.BinderCallsStatsService; import com.android.server.LocalManagerRegistry; @@ -228,7 +224,7 @@ import java.util.concurrent.Executor; import java.util.concurrent.ThreadLocalRandom; import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeoutException; -import java.util.function.BiConsumer; +import java.util.function.Function; /** * SystemService containing PullAtomCallbacks that are registered with statsd. @@ -324,6 +320,7 @@ public class StatsPullAtomService extends SystemService { private WifiManager mWifiManager; private TelephonyManager mTelephony; private SubscriptionManager mSubscriptionManager; + private NetworkStatsManager mNetworkStatsManager; @GuardedBy("mKernelWakelockLock") private KernelWakelockReader mKernelWakelockReader; @@ -769,7 +766,7 @@ public class StatsPullAtomService extends SystemService { mContext.getSystemService(Context.TELEPHONY_SUBSCRIPTION_SERVICE); mStatsSubscriptionsListener = new StatsSubscriptionsListener(mSubscriptionManager); mStorageManager = (StorageManager) mContext.getSystemService(StorageManager.class); - + mNetworkStatsManager = mContext.getSystemService(NetworkStatsManager.class); // Initialize DiskIO mStoragedUidIoStatsReader = new StoragedUidIoStatsReader(); @@ -959,32 +956,6 @@ public class StatsPullAtomService extends SystemService { registerOemManagedBytesTransfer(); } - /** - * Return the {@code INetworkStatsSession} object that holds the necessary properties needed - * for the subsequent queries to {@link com.android.server.net.NetworkStatsService}. Or - * null if the service or binder cannot be obtained. Calling this method will trigger poll - * in NetworkStatsService with once per 15 seconds rate-limit, unless {@code bypassRateLimit} - * is set to true. This is needed in {@link #getUidNetworkStatsSnapshotForTemplate}, where - * bypassing the limit is necessary for perfd to supply realtime stats to developers looking at - * the network usage of their app. - */ - @Nullable - private INetworkStatsSession getNetworkStatsSession(boolean bypassRateLimit) { - final INetworkStatsService networkStatsService = - INetworkStatsService.Stub.asInterface( - ServiceManager.getService(Context.NETWORK_STATS_SERVICE)); - if (networkStatsService == null) return null; - - try { - return networkStatsService.openSessionForUsageStats( - FLAG_AUGMENT_WITH_SUBSCRIPTION_PLAN | (bypassRateLimit ? FLAG_POLL_FORCE - : FLAG_POLL_ON_OPEN), mContext.getOpPackageName()); - } catch (RemoteException e) { - Slog.e(TAG, "Cannot get NetworkStats session", e); - return null; - } - } - private IThermalService getIThermalService() { synchronized (mThermalLock) { if (mThermalService == null) { @@ -1115,8 +1086,8 @@ public class StatsPullAtomService extends SystemService { case FrameworkStatsLog.WIFI_BYTES_TRANSFER: { final NetworkStats stats = getUidNetworkStatsSnapshotForTransport(TRANSPORT_WIFI); if (stats != null) { - ret.add(new NetworkStatsExt(stats.groupedByUid(), new int[] {TRANSPORT_WIFI}, - /*slicedByFgbg=*/false)); + ret.add(new NetworkStatsExt(sliceNetworkStatsByUid(stats), + new int[] {TRANSPORT_WIFI}, /*slicedByFgbg=*/false)); } break; } @@ -1132,7 +1103,7 @@ public class StatsPullAtomService extends SystemService { final NetworkStats stats = getUidNetworkStatsSnapshotForTransport(TRANSPORT_CELLULAR); if (stats != null) { - ret.add(new NetworkStatsExt(stats.groupedByUid(), + ret.add(new NetworkStatsExt(sliceNetworkStatsByUid(stats), new int[] {TRANSPORT_CELLULAR}, /*slicedByFgbg=*/false)); } break; @@ -1196,13 +1167,14 @@ public class StatsPullAtomService extends SystemService { Slog.e(TAG, "baseline is null for " + atomTag + ", return."); return StatsManager.PULL_SKIP; } + final NetworkStatsExt diff = new NetworkStatsExt( - item.stats.subtract(baseline.stats).removeEmptyEntries(), item.transports, + removeEmptyEntries(item.stats.subtract(baseline.stats)), item.transports, item.slicedByFgbg, item.slicedByTag, item.slicedByMetered, item.ratType, item.subInfo, item.oemManaged); // If no diff, skip. - if (diff.stats.size() == 0) continue; + if (!diff.stats.iterator().hasNext()) continue; switch (atomTag) { case FrameworkStatsLog.BYTES_TRANSFER_BY_TAG_AND_METERED: @@ -1221,25 +1193,32 @@ public class StatsPullAtomService extends SystemService { return StatsManager.PULL_SUCCESS; } + @NonNull private static NetworkStats removeEmptyEntries(NetworkStats stats) { + NetworkStats ret = new NetworkStats(0, 1); + for (NetworkStats.Entry e : stats) { + if (e.getRxBytes() != 0 || e.getRxPackets() != 0 || e.getTxBytes() != 0 + || e.getTxPackets() != 0 || e.getOperations() != 0) { + ret = ret.addEntry(e); + } + } + return ret; + } + private void addNetworkStats(int atomTag, @NonNull List<StatsEvent> ret, @NonNull NetworkStatsExt statsExt) { - int size = statsExt.stats.size(); - final NetworkStats.Entry entry = new NetworkStats.Entry(); // For recycling - for (int j = 0; j < size; j++) { - statsExt.stats.getValues(j, entry); + for (NetworkStats.Entry entry : statsExt.stats) { StatsEvent statsEvent; - if (statsExt.slicedByFgbg) { // MobileBytesTransferByFgBg atom or WifiBytesTransferByFgBg atom. statsEvent = FrameworkStatsLog.buildStatsEvent( - atomTag, entry.uid, - (entry.set > 0), entry.rxBytes, entry.rxPackets, entry.txBytes, - entry.txPackets); + atomTag, entry.getUid(), + (entry.getSet() > 0), entry.getRxBytes(), entry.getRxPackets(), + entry.getTxBytes(), entry.getTxPackets()); } else { // MobileBytesTransfer atom or WifiBytesTransfer atom. statsEvent = FrameworkStatsLog.buildStatsEvent( - atomTag, entry.uid, entry.rxBytes, - entry.rxPackets, entry.txBytes, entry.txPackets); + atomTag, entry.getUid(), entry.getRxBytes(), + entry.getRxPackets(), entry.getTxBytes(), entry.getTxPackets()); } ret.add(statsEvent); } @@ -1247,33 +1226,31 @@ public class StatsPullAtomService extends SystemService { private void addBytesTransferByTagAndMeteredAtoms(@NonNull NetworkStatsExt statsExt, @NonNull List<StatsEvent> pulledData) { - final NetworkStats.Entry entry = new NetworkStats.Entry(); // for recycling - for (int i = 0; i < statsExt.stats.size(); i++) { - statsExt.stats.getValues(i, entry); + for (NetworkStats.Entry entry : statsExt.stats) { pulledData.add(FrameworkStatsLog.buildStatsEvent( - FrameworkStatsLog.BYTES_TRANSFER_BY_TAG_AND_METERED, entry.uid, - entry.metered == NetworkStats.METERED_YES, entry.tag, entry.rxBytes, - entry.rxPackets, entry.txBytes, entry.txPackets)); + FrameworkStatsLog.BYTES_TRANSFER_BY_TAG_AND_METERED, entry.getUid(), + entry.getMetered() == NetworkStats.METERED_YES, entry.getTag(), + entry.getRxBytes(), entry.getRxPackets(), entry.getTxBytes(), + entry.getTxPackets())); } } private void addDataUsageBytesTransferAtoms(@NonNull NetworkStatsExt statsExt, @NonNull List<StatsEvent> pulledData) { - // Workaround for 5G NSA mode, see {@link NetworkTemplate#NETWORK_TYPE_5G_NSA}. + // Workaround for 5G NSA mode, see {@link NetworkStatsManager#NETWORK_TYPE_5G_NSA}. // 5G NSA mode means the primary cell is LTE with a secondary connection to an // NR cell. To mitigate risk, NetworkStats is currently storing this state as // a fake RAT type rather than storing the boolean separately. - final boolean is5GNsa = statsExt.ratType == NetworkTemplate.NETWORK_TYPE_5G_NSA; + final boolean is5GNsa = statsExt.ratType == NetworkStatsManager.NETWORK_TYPE_5G_NSA; // Report NR connected in 5G non-standalone mode, or if the RAT type is NR to begin with. final boolean isNR = is5GNsa || statsExt.ratType == TelephonyManager.NETWORK_TYPE_NR; - final NetworkStats.Entry entry = new NetworkStats.Entry(); // for recycling - for (int i = 0; i < statsExt.stats.size(); i++) { - statsExt.stats.getValues(i, entry); + for (NetworkStats.Entry entry : statsExt.stats) { pulledData.add(FrameworkStatsLog.buildStatsEvent( - FrameworkStatsLog.DATA_USAGE_BYTES_TRANSFER, entry.set, entry.rxBytes, - entry.rxPackets, entry.txBytes, entry.txPackets, + FrameworkStatsLog.DATA_USAGE_BYTES_TRANSFER, + entry.getSet(), entry.getRxBytes(), entry.getRxPackets(), + entry.getTxBytes(), entry.getTxPackets(), is5GNsa ? TelephonyManager.NETWORK_TYPE_LTE : statsExt.ratType, // Fill information about subscription, these cannot be null since invalid data // would be filtered when adding into subInfo list. @@ -1287,22 +1264,21 @@ public class StatsPullAtomService extends SystemService { private void addOemDataUsageBytesTransferAtoms(@NonNull NetworkStatsExt statsExt, @NonNull List<StatsEvent> pulledData) { - final NetworkStats.Entry entry = new NetworkStats.Entry(); // for recycling final int oemManaged = statsExt.oemManaged; for (final int transport : statsExt.transports) { - for (int i = 0; i < statsExt.stats.size(); i++) { - statsExt.stats.getValues(i, entry); + for (NetworkStats.Entry entry : statsExt.stats) { pulledData.add(FrameworkStatsLog.buildStatsEvent( - FrameworkStatsLog.OEM_MANAGED_BYTES_TRANSFER, entry.uid, (entry.set > 0), - oemManaged, transport, entry.rxBytes, entry.rxPackets, entry.txBytes, - entry.txPackets)); + FrameworkStatsLog.OEM_MANAGED_BYTES_TRANSFER, entry.getUid(), + (entry.getSet() > 0), oemManaged, transport, entry.getRxBytes(), + entry.getRxPackets(), entry.getTxBytes(), entry.getTxPackets())); } } } @NonNull private List<NetworkStatsExt> getDataUsageBytesTransferSnapshotForOemManaged() { final int[] matchRules = new int[] {MATCH_ETHERNET, MATCH_MOBILE, MATCH_WIFI}; - final int[] oemManagedTypes = new int[] {OEM_PAID | OEM_PRIVATE, OEM_PAID, OEM_PRIVATE}; + final int[] oemManagedTypes = new int[] {OEM_MANAGED_PAID | OEM_MANAGED_PRIVATE, + OEM_MANAGED_PAID, OEM_MANAGED_PRIVATE}; final List<NetworkStatsExt> ret = new ArrayList<>(); @@ -1357,22 +1333,32 @@ public class StatsPullAtomService extends SystemService { final long currentTimeInMillis = MICROSECONDS.toMillis(SystemClock.currentTimeMicro()); final long bucketDuration = Settings.Global.getLong(mContext.getContentResolver(), NETSTATS_UID_BUCKET_DURATION, NETSTATS_UID_DEFAULT_BUCKET_DURATION_MS); - try { - // TODO (b/156313635): This is short-term hack to allow perfd gets updated networkStats - // history when query in every second in order to show realtime statistics. However, - // this is not a good long-term solution since NetworkStatsService will make frequent - // I/O and also block main thread when polling. - // Consider making perfd queries NetworkStatsService directly. - final NetworkStats stats = getNetworkStatsSession(template.getMatchRule() - == NetworkTemplate.MATCH_WIFI_WILDCARD).getSummaryForAllUid(template, - currentTimeInMillis - elapsedMillisSinceBoot - bucketDuration, - currentTimeInMillis, includeTags); - return stats; - } catch (RemoteException | NullPointerException e) { - Slog.e(TAG, "Pulling netstats for template=" + template + " and includeTags=" - + includeTags + " causes error", e); + + // TODO (b/156313635): This is short-term hack to allow perfd gets updated networkStats + // history when query in every second in order to show realtime statistics. However, + // this is not a good long-term solution since NetworkStatsService will make frequent + // I/O and also block main thread when polling. + // Consider making perfd queries NetworkStatsService directly. + if (template.getMatchRule() == MATCH_WIFI && template.getSubscriberIds().isEmpty()) { + mNetworkStatsManager.forceUpdate(); } - return null; + + final android.app.usage.NetworkStats queryNonTaggedStats = + mNetworkStatsManager.querySummary( + template, currentTimeInMillis - elapsedMillisSinceBoot - bucketDuration, + currentTimeInMillis); + + final NetworkStats nonTaggedStats = + NetworkStatsUtils.fromPublicNetworkStats(queryNonTaggedStats); + if (!includeTags) return nonTaggedStats; + + final android.app.usage.NetworkStats queryTaggedStats = + mNetworkStatsManager.queryTaggedSummary(template, + currentTimeInMillis - elapsedMillisSinceBoot - bucketDuration, + currentTimeInMillis); + final NetworkStats taggedStats = + NetworkStatsUtils.fromPublicNetworkStats(queryTaggedStats); + return nonTaggedStats.add(taggedStats); } @NonNull private List<NetworkStatsExt> getDataUsageBytesTransferSnapshotForSub( @@ -1396,27 +1382,72 @@ public class StatsPullAtomService extends SystemService { return ret; } + /** + * Return all supported collapsed RAT types that could be returned by + * {@link android.app.usage.NetworkStatsManager#getCollapsedRatType(int)}. + */ + @NonNull + private static int[] getAllCollapsedRatTypes() { + final int[] ratTypes = TelephonyManager.getAllNetworkTypes(); + final HashSet<Integer> collapsedRatTypes = new HashSet<>(); + for (final int ratType : ratTypes) { + collapsedRatTypes.add(NetworkStatsManager.getCollapsedRatType(ratType)); + } + // Add NETWORK_TYPE_5G_NSA to the returned list since 5G NSA is a virtual RAT type and + // it is not in TelephonyManager#NETWORK_TYPE_* constants. + // See {@link NetworkStatsManager#NETWORK_TYPE_5G_NSA}. + collapsedRatTypes.add( + NetworkStatsManager.getCollapsedRatType(NetworkStatsManager.NETWORK_TYPE_5G_NSA)); + // Ensure that unknown type is returned. + collapsedRatTypes.add(TelephonyManager.NETWORK_TYPE_UNKNOWN); + return com.android.net.module.util.CollectionUtils.toIntArray(collapsedRatTypes); + } + + @NonNull private NetworkStats sliceNetworkStatsByUid(@NonNull NetworkStats stats) { + return sliceNetworkStats(stats, + (entry) -> { + return new NetworkStats.Entry(null /* IFACE_ALL */, entry.getUid(), + NetworkStats.SET_ALL, NetworkStats.TAG_NONE, + NetworkStats.METERED_ALL, NetworkStats.ROAMING_ALL, + NetworkStats.DEFAULT_NETWORK_ALL, + entry.getRxBytes(), entry.getRxPackets(), + entry.getTxBytes(), entry.getTxPackets(), 0); + }); + } + @NonNull private NetworkStats sliceNetworkStatsByFgbg(@NonNull NetworkStats stats) { return sliceNetworkStats(stats, - (newEntry, oldEntry) -> { - newEntry.set = oldEntry.set; + (entry) -> { + return new NetworkStats.Entry(null /* IFACE_ALL */, NetworkStats.UID_ALL, + entry.getSet(), NetworkStats.TAG_NONE, + NetworkStats.METERED_ALL, NetworkStats.ROAMING_ALL, + NetworkStats.DEFAULT_NETWORK_ALL, + entry.getRxBytes(), entry.getRxPackets(), + entry.getTxBytes(), entry.getTxPackets(), 0); }); } @NonNull private NetworkStats sliceNetworkStatsByUidAndFgbg(@NonNull NetworkStats stats) { return sliceNetworkStats(stats, - (newEntry, oldEntry) -> { - newEntry.uid = oldEntry.uid; - newEntry.set = oldEntry.set; + (entry) -> { + return new NetworkStats.Entry(null /* IFACE_ALL */, entry.getUid(), + entry.getSet(), NetworkStats.TAG_NONE, + NetworkStats.METERED_ALL, NetworkStats.ROAMING_ALL, + NetworkStats.DEFAULT_NETWORK_ALL, + entry.getRxBytes(), entry.getRxPackets(), + entry.getTxBytes(), entry.getTxPackets(), 0); }); } @NonNull private NetworkStats sliceNetworkStatsByUidTagAndMetered(@NonNull NetworkStats stats) { return sliceNetworkStats(stats, - (newEntry, oldEntry) -> { - newEntry.uid = oldEntry.uid; - newEntry.tag = oldEntry.tag; - newEntry.metered = oldEntry.metered; + (entry) -> { + return new NetworkStats.Entry(null /* IFACE_ALL */, entry.getUid(), + NetworkStats.SET_ALL, entry.getTag(), + entry.getMetered(), NetworkStats.ROAMING_ALL, + NetworkStats.DEFAULT_NETWORK_ALL, + entry.getRxBytes(), entry.getRxPackets(), + entry.getTxBytes(), entry.getTxPackets(), 0); }); } @@ -1426,46 +1457,27 @@ public class StatsPullAtomService extends SystemService { * * This function iterates through each NetworkStats.Entry, sets its dimensions equal to the * default state (with the presumption that we don't want to slice on anything), and then - * applies the slicer lambda to allow users to control which dimensions to slice on. This is - * adapted from groupedByUid within NetworkStats.java + * applies the slicer lambda to allow users to control which dimensions to slice on. * - * @param slicer An operation taking into two parameters, new NetworkStats.Entry and old - * NetworkStats.Entry, that should be used to copy state from the old to the new. + * @param slicer An operation taking one parameter, NetworkStats.Entry, that should be used to + * get the state from entry to replace the default value. * This is useful for slicing by particular dimensions. For example, if we wished * to slice by uid and tag, we could write the following lambda: - * (new, old) -> { - * new.uid = old.uid; - * new.tag = old.tag; + * (entry) -> { + * return new NetworkStats.Entry(null, entry.getUid(), + * NetworkStats.SET_ALL, entry.getTag(), + * NetworkStats.METERED_ALL, NetworkStats.ROAMING_ALL, + * NetworkStats.DEFAULT_NETWORK_ALL, + * entry.getRxBytes(), entry.getRxPackets(), + * entry.getTxBytes(), entry.getTxPackets(), 0); * } - * If no slicer is provided, the data is not sliced by any dimensions. * @return new NeworkStats object appropriately sliced */ @NonNull private NetworkStats sliceNetworkStats(@NonNull NetworkStats stats, - @Nullable BiConsumer<NetworkStats.Entry, NetworkStats.Entry> slicer) { - final NetworkStats ret = new NetworkStats(stats.getElapsedRealtime(), 1); - - final NetworkStats.Entry entry = new NetworkStats.Entry(); - entry.uid = NetworkStats.UID_ALL; - entry.iface = NetworkStats.IFACE_ALL; - entry.set = NetworkStats.SET_ALL; - entry.tag = NetworkStats.TAG_NONE; - entry.metered = NetworkStats.METERED_ALL; - entry.roaming = NetworkStats.ROAMING_ALL; - entry.defaultNetwork = NetworkStats.DEFAULT_NETWORK_ALL; - - final NetworkStats.Entry recycle = new NetworkStats.Entry(); // used for retrieving values - for (int i = 0; i < stats.size(); i++) { - stats.getValues(i, recycle); - if (slicer != null) { - slicer.accept(entry, recycle); - } - - entry.rxBytes = recycle.rxBytes; - entry.rxPackets = recycle.rxPackets; - entry.txBytes = recycle.txBytes; - entry.txPackets = recycle.txPackets; - // Operations purposefully omitted since we don't use them for statsd. - ret.combineValues(entry); + @NonNull Function<NetworkStats.Entry, NetworkStats.Entry> slicer) { + NetworkStats ret = new NetworkStats(0, 1); + for (NetworkStats.Entry e : stats) { + ret = ret.addEntry(slicer.apply(e)); } return ret; } diff --git a/services/core/java/com/android/server/wm/SurfaceAnimator.java b/services/core/java/com/android/server/wm/SurfaceAnimator.java index c7bf8ecfe949..94f0e24f88c9 100644 --- a/services/core/java/com/android/server/wm/SurfaceAnimator.java +++ b/services/core/java/com/android/server/wm/SurfaceAnimator.java @@ -85,6 +85,8 @@ class SurfaceAnimator { private boolean mAnimationStartDelayed; + private boolean mAnimationFinished; + /** * @param animatable The object to animate. * @param staticAnimationFinishedCallback Callback to invoke when an animation has finished @@ -134,6 +136,7 @@ class SurfaceAnimator { || anim.shouldDeferAnimationFinish(resetAndInvokeFinish))) { resetAndInvokeFinish.run(); } + mAnimationFinished = true; } }; } @@ -289,6 +292,9 @@ class SurfaceAnimator { Slog.w(TAG, "Unable to transfer animation, surface or parent is null"); cancelAnimation(); return; + } else if (from.mAnimationFinished) { + Slog.w(TAG, "Unable to transfer animation, because " + from + " animation is finished"); + return; } endDelayingAnimationStart(); final Transaction t = mAnimatable.getPendingTransaction(); @@ -367,6 +373,7 @@ class SurfaceAnimator { SurfaceControl leash = mLeash; mLeash = null; final boolean scheduleAnim = removeLeash(t, mAnimatable, leash, destroyLeash); + mAnimationFinished = false; if (scheduleAnim) { mService.scheduleAnimationLocked(); } diff --git a/services/core/jni/Android.bp b/services/core/jni/Android.bp index e7005daf5626..e48b5e17739b 100644 --- a/services/core/jni/Android.bp +++ b/services/core/jni/Android.bp @@ -141,8 +141,8 @@ cc_defaults { "libutils", "libhwui", "libbpf_android", - "libnetdbpf", "libnetdutils", + "libnetworkstats", "libpsi", "libdataloader", "libincfs", diff --git a/services/core/jni/com_android_server_UsbAlsaJackDetector.cpp b/services/core/jni/com_android_server_UsbAlsaJackDetector.cpp index ccb4f5995330..cba54b39fe9a 100644 --- a/services/core/jni/com_android_server_UsbAlsaJackDetector.cpp +++ b/services/core/jni/com_android_server_UsbAlsaJackDetector.cpp @@ -25,7 +25,6 @@ #include <stdio.h> #include <string.h> -#include <asm/byteorder.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> diff --git a/services/core/jni/com_android_server_UsbDescriptorParser.cpp b/services/core/jni/com_android_server_UsbDescriptorParser.cpp index d29d3fcb51d5..9917bcb45c0a 100644 --- a/services/core/jni/com_android_server_UsbDescriptorParser.cpp +++ b/services/core/jni/com_android_server_UsbDescriptorParser.cpp @@ -15,16 +15,14 @@ */ #define LOG_TAG "UsbHostManagerJNI" -#include "utils/Log.h" - +#include <nativehelper/JNIHelp.h> #include <stdlib.h> +#include <usbhost/usbhost.h> +#include <usbhost/usbhost_jni.h> #include "jni.h" -#include <nativehelper/JNIHelp.h> - -#include <usbhost/usbhost.h> +#include "utils/Log.h" -#define MAX_DESCRIPTORS_LENGTH 4096 static const int USB_CONTROL_TRANSFER_TIMEOUT_MS = 200; // com.android.server.usb.descriptors @@ -41,26 +39,9 @@ jbyteArray JNICALL Java_com_android_server_usb_descriptors_UsbDescriptorParser_g } int fd = usb_device_get_fd(device); - if (fd < 0) { - usb_device_close(device); - return NULL; - } - - // from android_hardware_UsbDeviceConnection_get_desc() - jbyte buffer[MAX_DESCRIPTORS_LENGTH]; - lseek(fd, 0, SEEK_SET); - int numBytes = read(fd, buffer, sizeof(buffer)); - jbyteArray ret = NULL; + jbyteArray descriptors = usb_jni_read_descriptors(env, fd); usb_device_close(device); - - if (numBytes > 0) { - ret = env->NewByteArray(numBytes); - env->SetByteArrayRegion(ret, 0, numBytes, buffer); - } else { - ALOGE("error reading descriptors\n"); - } - - return ret; + return descriptors; } jstring JNICALL Java_com_android_server_usb_descriptors_UsbDescriptorParser_getDescriptorString_1native( diff --git a/services/core/jni/com_android_server_UsbDeviceManager.cpp b/services/core/jni/com_android_server_UsbDeviceManager.cpp index 3ab5920d8b59..0a9ce2fed7fc 100644 --- a/services/core/jni/com_android_server_UsbDeviceManager.cpp +++ b/services/core/jni/com_android_server_UsbDeviceManager.cpp @@ -25,7 +25,6 @@ #include "MtpDescriptors.h" #include <stdio.h> -#include <asm/byteorder.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> diff --git a/services/core/jni/com_android_server_UsbHostManager.cpp b/services/core/jni/com_android_server_UsbHostManager.cpp index a629b69c1c27..e29d2ca663f7 100644 --- a/services/core/jni/com_android_server_UsbHostManager.cpp +++ b/services/core/jni/com_android_server_UsbHostManager.cpp @@ -23,7 +23,6 @@ #include "android_runtime/Log.h" #include <stdio.h> -#include <asm/byteorder.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> @@ -31,8 +30,6 @@ #include <usbhost/usbhost.h> -#define MAX_DESCRIPTORS_LENGTH 4096 - namespace android { diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/ActiveAdmin.java b/services/devicepolicy/java/com/android/server/devicepolicy/ActiveAdmin.java index 37a84f3698c1..1c9d58458629 100644 --- a/services/devicepolicy/java/com/android/server/devicepolicy/ActiveAdmin.java +++ b/services/devicepolicy/java/com/android/server/devicepolicy/ActiveAdmin.java @@ -32,6 +32,7 @@ import android.app.admin.DeviceAdminInfo; import android.app.admin.DevicePolicyManager; import android.app.admin.FactoryResetProtectionPolicy; import android.app.admin.PasswordPolicy; +import android.app.admin.PreferentialNetworkServiceConfig; import android.graphics.Color; import android.os.Bundle; import android.os.PersistableBundle; @@ -294,6 +295,8 @@ class ActiveAdmin { public boolean mAdminCanGrantSensorsPermissions; public boolean mPreferentialNetworkServiceEnabled = DevicePolicyManager.PREFERENTIAL_NETWORK_SERVICE_ENABLED_DEFAULT; + public PreferentialNetworkServiceConfig mPreferentialNetworkServiceConfig = + PreferentialNetworkServiceConfig.DEFAULT; private static final boolean USB_DATA_SIGNALING_ENABLED_DEFAULT = true; boolean mUsbDataSignalingEnabled = USB_DATA_SIGNALING_ENABLED_DEFAULT; diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java index df98390ddf05..564b60825ab0 100644 --- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java +++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java @@ -109,6 +109,8 @@ import static android.content.pm.PackageManager.MATCH_DIRECT_BOOT_UNAWARE; import static android.content.pm.PackageManager.MATCH_UNINSTALLED_PACKAGES; import static android.net.ConnectivityManager.PROFILE_NETWORK_PREFERENCE_DEFAULT; import static android.net.ConnectivityManager.PROFILE_NETWORK_PREFERENCE_ENTERPRISE; +import static android.net.ConnectivityManager.PROFILE_NETWORK_PREFERENCE_ENTERPRISE_NO_FALLBACK; +import static android.net.NetworkCapabilities.NET_ENTERPRISE_ID_1; import static android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK; import static android.provider.Settings.Global.PRIVATE_DNS_SPECIFIER; import static android.provider.Settings.Secure.USER_SETUP_COMPLETE; @@ -179,6 +181,7 @@ import android.app.admin.NetworkEvent; import android.app.admin.ParcelableGranteeMap; import android.app.admin.PasswordMetrics; import android.app.admin.PasswordPolicy; +import android.app.admin.PreferentialNetworkServiceConfig; import android.app.admin.SecurityLog; import android.app.admin.SecurityLog.SecurityEvent; import android.app.admin.StartInstallingUpdateCallback; @@ -3277,14 +3280,14 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { updatePermissionPolicyCache(userId); updateAdminCanGrantSensorsPermissionCache(userId); - final boolean preferentialNetworkServiceEnabled; + final PreferentialNetworkServiceConfig preferentialNetworkServiceConfig; synchronized (getLockObject()) { ActiveAdmin owner = getDeviceOrProfileOwnerAdminLocked(userId); - preferentialNetworkServiceEnabled = owner != null - ? owner.mPreferentialNetworkServiceEnabled - : DevicePolicyManager.PREFERENTIAL_NETWORK_SERVICE_ENABLED_DEFAULT; + preferentialNetworkServiceConfig = owner != null + ? owner.mPreferentialNetworkServiceConfig + : PreferentialNetworkServiceConfig.DEFAULT; } - updateNetworkPreferenceForUser(userId, preferentialNetworkServiceEnabled); + updateNetworkPreferenceForUser(userId, preferentialNetworkServiceConfig); startOwnerService(userId, "start-user"); } @@ -3301,7 +3304,7 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { @Override void handleStopUser(int userId) { - updateNetworkPreferenceForUser(userId, false); + updateNetworkPreferenceForUser(userId, PreferentialNetworkServiceConfig.DEFAULT); stopOwnerService(userId, "stop-user"); } @@ -11845,7 +11848,7 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { final CallerIdentity caller = getCallerIdentity(); Preconditions.checkCallAuthorization(isProfileOwner(caller), "Caller is not profile owner;" - + " only profile owner may control the preferntial network service"); + + " only profile owner may control the preferential network service"); synchronized (getLockObject()) { final ActiveAdmin requiredAdmin = getProfileOwnerAdminLocked( caller.getUserId()); @@ -11882,6 +11885,47 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { } @Override + public void setPreferentialNetworkServiceConfig( + PreferentialNetworkServiceConfig preferentialNetworkServiceConfig) { + if (!mHasFeature) { + return; + } + final CallerIdentity caller = getCallerIdentity(); + Preconditions.checkCallAuthorization(isProfileOwner(caller), + "Caller is not profile owner;" + + " only profile owner may control the preferential network service"); + synchronized (getLockObject()) { + final ActiveAdmin requiredAdmin = getProfileOwnerAdminLocked( + caller.getUserId()); + if (!requiredAdmin.mPreferentialNetworkServiceConfig.equals( + preferentialNetworkServiceConfig)) { + requiredAdmin.mPreferentialNetworkServiceConfig = preferentialNetworkServiceConfig; + saveSettingsLocked(caller.getUserId()); + } + } + updateNetworkPreferenceForUser(caller.getUserId(), preferentialNetworkServiceConfig); + DevicePolicyEventLogger + .createEvent(DevicePolicyEnums.SET_PREFERENTIAL_NETWORK_SERVICE_ENABLED) + .setBoolean(preferentialNetworkServiceConfig.isEnabled()) + .write(); + } + + @Override + public PreferentialNetworkServiceConfig getPreferentialNetworkServiceConfig() { + if (!mHasFeature) { + return PreferentialNetworkServiceConfig.DEFAULT; + } + + final CallerIdentity caller = getCallerIdentity(); + Preconditions.checkCallAuthorization(isProfileOwner(caller), + "Caller is not profile owner"); + synchronized (getLockObject()) { + final ActiveAdmin requiredAdmin = getProfileOwnerAdminLocked(caller.getUserId()); + return requiredAdmin.mPreferentialNetworkServiceConfig; + } + } + + @Override public void setLockTaskPackages(ComponentName who, String[] packages) throws SecurityException { Objects.requireNonNull(who, "ComponentName is null"); @@ -17537,11 +17581,48 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { if (!isManagedProfile(userId)) { return; } - int networkPreference = preferentialNetworkServiceEnabled - ? PROFILE_NETWORK_PREFERENCE_ENTERPRISE : PROFILE_NETWORK_PREFERENCE_DEFAULT; ProfileNetworkPreference.Builder preferenceBuilder = new ProfileNetworkPreference.Builder(); - preferenceBuilder.setPreference(networkPreference); + if (preferentialNetworkServiceEnabled) { + preferenceBuilder.setPreference(PROFILE_NETWORK_PREFERENCE_ENTERPRISE); + preferenceBuilder.setPreferenceEnterpriseId(NET_ENTERPRISE_ID_1); + } else { + preferenceBuilder.setPreference(PROFILE_NETWORK_PREFERENCE_DEFAULT); + } + List<ProfileNetworkPreference> preferences = new ArrayList<>(); + preferences.add(preferenceBuilder.build()); + mInjector.binderWithCleanCallingIdentity(() -> + mInjector.getConnectivityManager().setProfileNetworkPreferences( + UserHandle.of(userId), preferences, + null /* executor */, null /* listener */)); + } + + private void updateNetworkPreferenceForUser(int userId, + PreferentialNetworkServiceConfig preferentialNetworkServiceConfig) { + if (!isManagedProfile(userId)) { + return; + } + ProfileNetworkPreference.Builder preferenceBuilder = + new ProfileNetworkPreference.Builder(); + if (preferentialNetworkServiceConfig.isEnabled()) { + if (preferentialNetworkServiceConfig.isFallbackToDefaultConnectionAllowed()) { + preferenceBuilder.setPreference(PROFILE_NETWORK_PREFERENCE_ENTERPRISE); + } else { + preferenceBuilder.setPreference(PROFILE_NETWORK_PREFERENCE_ENTERPRISE_NO_FALLBACK); + } + } else { + preferenceBuilder.setPreference(PROFILE_NETWORK_PREFERENCE_DEFAULT); + } + List<Integer> allowedUids = Arrays.stream( + preferentialNetworkServiceConfig.getIncludedUids()).boxed().collect( + Collectors.toList()); + List<Integer> excludedUids = Arrays.stream( + preferentialNetworkServiceConfig.getExcludedUids()).boxed().collect( + Collectors.toList()); + preferenceBuilder.setIncludedUids(allowedUids); + preferenceBuilder.setExcludedUids(excludedUids); + preferenceBuilder.setPreferenceEnterpriseId( + preferentialNetworkServiceConfig.getNetworkId()); List<ProfileNetworkPreference> preferences = new ArrayList<>(); preferences.add(preferenceBuilder.build()); mInjector.binderWithCleanCallingIdentity(() -> diff --git a/services/java/com/android/server/SystemServer.java b/services/java/com/android/server/SystemServer.java index 554a7b1bd574..710a9cf74112 100644 --- a/services/java/com/android/server/SystemServer.java +++ b/services/java/com/android/server/SystemServer.java @@ -54,6 +54,7 @@ import android.hardware.display.DisplayManagerInternal; import android.net.ConnectivityManager; import android.net.ConnectivityModuleConnector; import android.net.NetworkStackClient; +import android.net.TrafficStats; import android.os.BaseBundle; import android.os.Binder; import android.os.Build; @@ -1838,6 +1839,7 @@ public final class SystemServer implements Dumpable { try { networkStats = NetworkStatsService.create(context); ServiceManager.addService(Context.NETWORK_STATS_SERVICE, networkStats); + TrafficStats.init(context); } catch (Throwable e) { reportWtf("starting NetworkStats Service", e); } diff --git a/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java b/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java index a63aa6a918d7..3511fc1c36d5 100644 --- a/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java +++ b/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java @@ -39,7 +39,9 @@ import static android.app.admin.PasswordMetrics.computeForPasswordOrPin; import static android.content.pm.ApplicationInfo.PRIVATE_FLAG_DIRECT_BOOT_AWARE; import static android.net.ConnectivityManager.PROFILE_NETWORK_PREFERENCE_DEFAULT; import static android.net.ConnectivityManager.PROFILE_NETWORK_PREFERENCE_ENTERPRISE; +import static android.net.ConnectivityManager.PROFILE_NETWORK_PREFERENCE_ENTERPRISE_NO_FALLBACK; import static android.net.InetAddresses.parseNumericAddress; +import static android.net.NetworkCapabilities.NET_ENTERPRISE_ID_1; import static com.android.internal.widget.LockPatternUtils.CREDENTIAL_TYPE_NONE; import static com.android.internal.widget.LockPatternUtils.EscrowTokenStateChangeCallback; @@ -89,6 +91,7 @@ import android.app.admin.DevicePolicyManagerInternal; import android.app.admin.DevicePolicyManagerLiteInternal; import android.app.admin.FactoryResetProtectionPolicy; import android.app.admin.PasswordMetrics; +import android.app.admin.PreferentialNetworkServiceConfig; import android.app.admin.SystemUpdatePolicy; import android.content.BroadcastReceiver; import android.content.ComponentName; @@ -4109,6 +4112,7 @@ public class DevicePolicyManagerTest extends DpmTestBase { ProfileNetworkPreference preferenceDetails2 = new ProfileNetworkPreference.Builder() .setPreference(PROFILE_NETWORK_PREFERENCE_ENTERPRISE) + .setPreferenceEnterpriseId(NET_ENTERPRISE_ID_1) .build(); List<ProfileNetworkPreference> preferences2 = new ArrayList<>(); preferences2.add(preferenceDetails); @@ -4118,6 +4122,164 @@ public class DevicePolicyManagerTest extends DpmTestBase { } @Test + public void testSetPreferentialNetworkServiceConfig_noProfileOwner() throws Exception { + assertExpectException(SecurityException.class, null, + () -> dpm.setPreferentialNetworkServiceConfig( + PreferentialNetworkServiceConfig.DEFAULT)); + } + + @Test + public void testIsPreferentialNetworkServiceEnabled_noProfileOwner() throws Exception { + assertExpectException(SecurityException.class, null, + () -> dpm.isPreferentialNetworkServiceEnabled()); + } + + @Test + public void testSetPreferentialNetworkServiceConfig_invalidConfig() throws Exception { + final int managedProfileUserId = 15; + final int managedProfileAdminUid = UserHandle.getUid(managedProfileUserId, 19436); + addManagedProfile(admin1, managedProfileAdminUid, admin1); + mContext.binder.callingUid = managedProfileAdminUid; + + PreferentialNetworkServiceConfig.Builder preferentialNetworkServiceConfigBuilder = + new PreferentialNetworkServiceConfig.Builder(); + assertExpectException(NullPointerException.class, null, + () -> preferentialNetworkServiceConfigBuilder.setIncludedUids(null)); + assertExpectException(NullPointerException.class, null, + () -> preferentialNetworkServiceConfigBuilder.setExcludedUids(null)); + assertExpectException(IllegalArgumentException.class, null, + () -> preferentialNetworkServiceConfigBuilder.setNetworkId(6)); + int[] includedUids = new int[]{1, 2}; + int[] excludedUids = new int[]{3, 4}; + preferentialNetworkServiceConfigBuilder.setIncludedUids(includedUids); + preferentialNetworkServiceConfigBuilder.setExcludedUids(excludedUids); + + assertExpectException(IllegalStateException.class, null, + () -> preferentialNetworkServiceConfigBuilder.build()); + } + + @Test + public void testSetPreferentialNetworkServiceConfig_defaultPreference() throws Exception { + final int managedProfileUserId = 15; + final int managedProfileAdminUid = UserHandle.getUid(managedProfileUserId, 19436); + addManagedProfile(admin1, managedProfileAdminUid, admin1); + mContext.binder.callingUid = managedProfileAdminUid; + + dpm.setPreferentialNetworkServiceConfig(PreferentialNetworkServiceConfig.DEFAULT); + assertThat(dpm.isPreferentialNetworkServiceEnabled()).isFalse(); + assertThat(dpm.getPreferentialNetworkServiceConfig() + .isEnabled()).isFalse(); + + ProfileNetworkPreference preferenceDetails = + new ProfileNetworkPreference.Builder() + .setPreference(PROFILE_NETWORK_PREFERENCE_DEFAULT) + .build(); + List<ProfileNetworkPreference> preferences = new ArrayList<>(); + preferences.add(preferenceDetails); + verify(getServices().connectivityManager, times(1)) + .setProfileNetworkPreferences(UserHandle.of(managedProfileUserId), preferences, + null, null); + } + + @Test + public void testSetPreferentialNetworkServiceConfig_enterprisePreference() throws Exception { + PreferentialNetworkServiceConfig preferentialNetworkServiceConfigEnabled = + (new PreferentialNetworkServiceConfig.Builder()) + .setEnabled(true) + .setNetworkId(NET_ENTERPRISE_ID_1) + .build(); + + final int managedProfileUserId = 15; + final int managedProfileAdminUid = UserHandle.getUid(managedProfileUserId, 19436); + addManagedProfile(admin1, managedProfileAdminUid, admin1); + mContext.binder.callingUid = managedProfileAdminUid; + + dpm.setPreferentialNetworkServiceConfig(preferentialNetworkServiceConfigEnabled); + assertThat(dpm.getPreferentialNetworkServiceConfig() + .isEnabled()).isTrue(); + ProfileNetworkPreference preferenceDetails = + new ProfileNetworkPreference.Builder() + .setPreference(PROFILE_NETWORK_PREFERENCE_ENTERPRISE) + .setPreferenceEnterpriseId(NET_ENTERPRISE_ID_1) + .build(); + List<ProfileNetworkPreference> preferences = new ArrayList<>(); + preferences.add(preferenceDetails); + verify(getServices().connectivityManager, times(1)) + .setProfileNetworkPreferences(UserHandle.of(managedProfileUserId), preferences, + null, null); + } + + @Test + public void testSetPreferentialNetworkServiceConfig_enterprisePreferenceIncludedUids() + throws Exception { + final int managedProfileUserId = 15; + final int managedProfileAdminUid = UserHandle.getUid(managedProfileUserId, 19436); + addManagedProfile(admin1, managedProfileAdminUid, admin1); + mContext.binder.callingUid = managedProfileAdminUid; + + PreferentialNetworkServiceConfig preferentialNetworkServiceConfigEnabled = + (new PreferentialNetworkServiceConfig.Builder()) + .setEnabled(true) + .setNetworkId(NET_ENTERPRISE_ID_1) + .setFallbackToDefaultConnectionAllowed(false) + .setIncludedUids(new int[]{1, 2}) + .build(); + dpm.setPreferentialNetworkServiceConfig(preferentialNetworkServiceConfigEnabled); + assertThat(dpm.getPreferentialNetworkServiceConfig() + .isEnabled()).isTrue(); + List<Integer> includedList = new ArrayList<>(); + includedList.add(1); + includedList.add(2); + ProfileNetworkPreference preferenceDetails = + new ProfileNetworkPreference.Builder() + .setPreference(PROFILE_NETWORK_PREFERENCE_ENTERPRISE_NO_FALLBACK) + .setPreferenceEnterpriseId(NET_ENTERPRISE_ID_1) + .setIncludedUids(includedList) + .build(); + List<ProfileNetworkPreference> preferences = new ArrayList<>(); + preferences.add(preferenceDetails); + verify(getServices().connectivityManager, times(1)) + .setProfileNetworkPreferences(UserHandle.of(managedProfileUserId), preferences, + null, null); + } + + @Test + public void testSetPreferentialNetworkServiceConfig_enterprisePreferenceExcludedUids() + throws Exception { + final int managedProfileUserId = 15; + final int managedProfileAdminUid = UserHandle.getUid(managedProfileUserId, 19436); + addManagedProfile(admin1, managedProfileAdminUid, admin1); + mContext.binder.callingUid = managedProfileAdminUid; + + PreferentialNetworkServiceConfig preferentialNetworkServiceConfigEnabled = + (new PreferentialNetworkServiceConfig.Builder()) + .setEnabled(true) + .setNetworkId(NET_ENTERPRISE_ID_1) + .setFallbackToDefaultConnectionAllowed(false) + .setExcludedUids(new int[]{1, 2}) + .build(); + + dpm.setPreferentialNetworkServiceConfig(preferentialNetworkServiceConfigEnabled); + assertThat(dpm.getPreferentialNetworkServiceConfig() + .isEnabled()).isTrue(); + List<Integer> excludedUids = new ArrayList<>(); + excludedUids.add(1); + excludedUids.add(2); + ProfileNetworkPreference preferenceDetails = + new ProfileNetworkPreference.Builder() + .setPreference(PROFILE_NETWORK_PREFERENCE_ENTERPRISE_NO_FALLBACK) + .setPreferenceEnterpriseId(NET_ENTERPRISE_ID_1) + .setExcludedUids(excludedUids) + .build(); + List<ProfileNetworkPreference> preferences = new ArrayList<>(); + preferences.clear(); + preferences.add(preferenceDetails); + verify(getServices().connectivityManager, times(1)) + .setProfileNetworkPreferences(UserHandle.of(managedProfileUserId), preferences, + null, null); + } + + @Test public void testSetSystemSettingFailWithNonWhitelistedSettings() throws Exception { mContext.binder.callingUid = DpmMockContext.CALLER_SYSTEM_USER_UID; setupDeviceOwner(); 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 c544f5c2e245..e80721a10e90 100644 --- a/services/tests/servicestests/src/com/android/server/net/NetworkPolicyManagerServiceTest.java +++ b/services/tests/servicestests/src/com/android/server/net/NetworkPolicyManagerServiceTest.java @@ -51,6 +51,7 @@ import static android.net.NetworkPolicyManager.uidRulesToString; import static android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK; import static android.net.NetworkStats.METERED_NO; import static android.net.NetworkStats.METERED_YES; +import static android.net.NetworkTemplate.MATCH_MOBILE; import static android.net.NetworkTemplate.buildTemplateCarrierMetered; import static android.net.NetworkTemplate.buildTemplateWifi; import static android.net.TrafficStats.MB_IN_BYTES; @@ -71,7 +72,6 @@ import static com.android.server.net.NetworkPolicyManagerService.TYPE_LIMIT_SNOO 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 com.android.server.net.NetworkStatsService.ACTION_NETWORK_STATS_UPDATED; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; @@ -95,6 +95,7 @@ import static org.mockito.Mockito.doNothing; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.never; import static org.mockito.Mockito.reset; +import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; @@ -495,8 +496,14 @@ public class NetworkPolicyManagerServiceTest { verify(mNetworkManager).registerObserver(networkObserver.capture()); mNetworkObserver = networkObserver.getValue(); - // Simulate NetworkStatsService broadcast stats updated to signal its readiness. - mServiceContext.sendBroadcast(new Intent(ACTION_NETWORK_STATS_UPDATED)); + // Catch UsageCallback during systemReady(). Simulate NetworkStatsService triggered + // stats updated callback to signal its readiness. + final ArgumentCaptor<NetworkStatsManager.UsageCallback> usageObserver = + ArgumentCaptor.forClass(NetworkStatsManager.UsageCallback.class); + verify(mStatsManager, times(2)) + .registerUsageCallback(any(), anyLong(), any(), usageObserver.capture()); + usageObserver.getValue().onThresholdReached( + new NetworkTemplate.Builder(MATCH_MOBILE).build()); NetworkPolicy defaultPolicy = mService.buildDefaultCarrierPolicy(0, ""); mDefaultWarningBytes = defaultPolicy.warningBytes; @@ -2046,7 +2053,7 @@ public class NetworkPolicyManagerServiceTest { private static NetworkStateSnapshot buildWifi() { WifiInfo mockWifiInfo = mock(WifiInfo.class); when(mockWifiInfo.makeCopy(anyLong())).thenReturn(mockWifiInfo); - when(mockWifiInfo.getCurrentNetworkKey()).thenReturn(TEST_WIFI_NETWORK_KEY); + when(mockWifiInfo.getNetworkKey()).thenReturn(TEST_WIFI_NETWORK_KEY); final LinkProperties prop = new LinkProperties(); prop.setInterfaceName(TEST_IFACE); final NetworkCapabilities networkCapabilities = new NetworkCapabilities.Builder() diff --git a/services/wallpapereffectsgeneration/OWNERS b/services/wallpapereffectsgeneration/OWNERS new file mode 100644 index 000000000000..d2d3e2c0a7b6 --- /dev/null +++ b/services/wallpapereffectsgeneration/OWNERS @@ -0,0 +1,4 @@ +susharon@google.com +shanh@google.com +huiwu@google.com +srazdan@google.com diff --git a/telephony/java/android/telephony/CarrierConfigManager.java b/telephony/java/android/telephony/CarrierConfigManager.java index e59c2e41a6c0..9a764a0a0a3a 100644 --- a/telephony/java/android/telephony/CarrierConfigManager.java +++ b/telephony/java/android/telephony/CarrierConfigManager.java @@ -4883,6 +4883,10 @@ public class CarrierConfigManager { /** Specifies the PCO id for IPv4 Epdg server address */ public static final String KEY_EPDG_PCO_ID_IPV4_INT = KEY_PREFIX + "epdg_pco_id_ipv4_int"; + /** Controls if the IKE tunnel setup supports EAP-AKA fast reauth */ + public static final String KEY_SUPPORTS_EAP_AKA_FAST_REAUTH_BOOL = + KEY_PREFIX + "supports_eap_aka_fast_reauth_bool"; + /** @hide */ @IntDef({AUTHENTICATION_METHOD_EAP_ONLY, AUTHENTICATION_METHOD_CERT}) public @interface AuthenticationMethodType {} @@ -5029,6 +5033,7 @@ public class CarrierConfigManager { defaults.putBoolean(KEY_ADD_KE_TO_CHILD_SESSION_REKEY_BOOL, false); defaults.putInt(KEY_EPDG_PCO_ID_IPV6_INT, 0); defaults.putInt(KEY_EPDG_PCO_ID_IPV4_INT, 0); + defaults.putBoolean(KEY_SUPPORTS_EAP_AKA_FAST_REAUTH_BOOL, false); return defaults; } diff --git a/telephony/java/android/telephony/SubscriptionManager.java b/telephony/java/android/telephony/SubscriptionManager.java index f72832438204..4e32a55b2e6e 100644 --- a/telephony/java/android/telephony/SubscriptionManager.java +++ b/telephony/java/android/telephony/SubscriptionManager.java @@ -3820,6 +3820,11 @@ public class SubscriptionManager { * {@link #PHONE_NUMBER_SOURCE_UICC UICC} and decide if the previously set phone number * of source {@link #PHONE_NUMBER_SOURCE_CARRIER carrier} should be updated. * + * <p>The API provides no guarantees of what format the number is in: the format can vary + * depending on the {@code source} and the network etc. Programmatic parsing should be done + * cautiously, for example, after formatting the number to a consistent format with + * {@link android.telephony.PhoneNumberUtils#formatNumberToE164(String, String)}. + * * <p>Note the assumption is that one subscription (which usually means one SIM) has * only one phone number. The multiple sources backup each other so hopefully at least one * is availavle. For example, for a carrier that doesn't typically set phone numbers @@ -3878,6 +3883,11 @@ public class SubscriptionManager { * from available sources in the following order: {@link #PHONE_NUMBER_SOURCE_CARRIER} * > {@link #PHONE_NUMBER_SOURCE_UICC} > {@link #PHONE_NUMBER_SOURCE_IMS}. * + * <p>The API provides no guarantees of what format the number is in: the format can vary + * depending on the underlying source and the network etc. Programmatic parsing should be done + * cautiously, for example, after formatting the number to a consistent format with + * {@link android.telephony.PhoneNumberUtils#formatNumberToE164(String, String)}. + * * @param subscriptionId the subscription ID, or {@link #DEFAULT_SUBSCRIPTION_ID} * for the default one. * @return the phone number, or an empty string if not available. @@ -3916,6 +3926,9 @@ public class SubscriptionManager { * <p>The API is suitable for carrier apps to provide a phone number, for example when * it's not possible to update {@link #PHONE_NUMBER_SOURCE_UICC UICC} directly. * + * <p>It's recommended that the phone number is formatted to well-known formats, + * for example, by {@link PhoneNumberUtils} {@code formatNumber*} methods. + * * @param subscriptionId the subscription ID, or {@link #DEFAULT_SUBSCRIPTION_ID} * for the default one. * @param number the phone number, or an empty string to remove the previously set number. diff --git a/telephony/java/android/telephony/TelephonyManager.java b/telephony/java/android/telephony/TelephonyManager.java index 9ac9d66b3965..aab6daa20279 100644 --- a/telephony/java/android/telephony/TelephonyManager.java +++ b/telephony/java/android/telephony/TelephonyManager.java @@ -11487,7 +11487,11 @@ public class TelephonyManager { private final int mErrorCode; - /** @hide */ + /** + * An exception with ModemActivityInfo specific error codes. + * + * @param errorCode a ModemActivityInfoError code. + */ public ModemActivityInfoException(@ModemActivityInfoError int errorCode) { mErrorCode = errorCode; } diff --git a/telephony/java/android/telephony/ims/RcsUceAdapter.java b/telephony/java/android/telephony/ims/RcsUceAdapter.java index 61de3ac2b25e..154bb11db5e3 100644 --- a/telephony/java/android/telephony/ims/RcsUceAdapter.java +++ b/telephony/java/android/telephony/ims/RcsUceAdapter.java @@ -268,6 +268,13 @@ public class RcsUceAdapter { @SystemApi public static final int CAPABILITY_UPDATE_TRIGGER_MOVE_TO_NR5G_VOPS_ENABLED = 11; + /** + * A capability update has been requested due to IMS being registered over INTERNET PDN. + * @hide + */ + @SystemApi + public static final int CAPABILITY_UPDATE_TRIGGER_MOVE_TO_INTERNET_PDN = 12; + /**@hide*/ @Retention(RetentionPolicy.SOURCE) @IntDef(prefix = "ERROR_", value = { @@ -282,7 +289,8 @@ public class RcsUceAdapter { CAPABILITY_UPDATE_TRIGGER_MOVE_TO_WLAN, CAPABILITY_UPDATE_TRIGGER_MOVE_TO_IWLAN, CAPABILITY_UPDATE_TRIGGER_MOVE_TO_NR5G_VOPS_DISABLED, - CAPABILITY_UPDATE_TRIGGER_MOVE_TO_NR5G_VOPS_ENABLED + CAPABILITY_UPDATE_TRIGGER_MOVE_TO_NR5G_VOPS_ENABLED, + CAPABILITY_UPDATE_TRIGGER_MOVE_TO_INTERNET_PDN }) public @interface StackPublishTriggerType {} diff --git a/telephony/java/com/android/internal/telephony/DctConstants.java b/telephony/java/com/android/internal/telephony/DctConstants.java index 409c838cb3e3..24708873986c 100644 --- a/telephony/java/com/android/internal/telephony/DctConstants.java +++ b/telephony/java/com/android/internal/telephony/DctConstants.java @@ -114,6 +114,7 @@ public class DctConstants { public static final int EVENT_CARRIER_CONFIG_CHANGED = BASE + 54; public static final int EVENT_SIM_STATE_UPDATED = BASE + 55; public static final int EVENT_APN_UNTHROTTLED = BASE + 56; + public static final int EVENT_TRAFFIC_DESCRIPTORS_UPDATED = BASE + 57; /***** Constants *****/ |