diff options
36 files changed, 646 insertions, 264 deletions
diff --git a/Android.bp b/Android.bp index 54fedaf9bb0f..9e65646154b8 100644 --- a/Android.bp +++ b/Android.bp @@ -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,6 +542,30 @@ 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", // There are a few classes from modules used by the core that @@ -553,14 +576,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..f7bd34ea2d66 100644 --- a/ApiDocs.bp +++ b/ApiDocs.bp @@ -57,7 +57,10 @@ framework_docs_only_libs = [ stubs_defaults { name: "android-non-updatable-doc-stubs-defaults", - defaults: ["android-non-updatable-stubs-defaults"], + defaults: [ + "android-non-updatable-stubs-defaults", + "module-classpath-stubs-defaults", + ], srcs: [ // No longer part of the stubs, but are included in the docs. ":android-test-base-sources", @@ -71,39 +74,21 @@ stubs_defaults { stubs_defaults { name: "framework-doc-stubs-default", + defaults: ["android-non-updatable-stubs-defaults"], 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. diff --git a/StubLibraries.bp b/StubLibraries.bp index 2ce37921715e..9e8b7071d0c7 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: { 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/module-lib-current.txt b/core/api/module-lib-current.txt index 674c09e6bd35..2b0b66447dc4 100644 --- a/core/api/module-lib-current.txt +++ b/core/api/module-lib-current.txt @@ -373,6 +373,7 @@ package android.net { } public class TrafficStats { + method public static void attachSocketTagger(); method public static void init(@NonNull android.content.Context); } diff --git a/core/api/system-current.txt b/core/api/system-current.txt index e49548729865..6d00909e4499 100644 --- a/core/api/system-current.txt +++ b/core/api/system-current.txt @@ -2027,9 +2027,11 @@ package android.bluetooth { 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 @RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT, android.Manifest.permission.BLUETOOTH_PRIVILEGED}) public static final String ACTION_SWITCH_BUFFER_SIZE = "android.bluetooth.device.action.SWITCH_BUFFER_SIZE"; 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 String EXTRA_LOW_LATENCY_BUFFER_SIZE = "android.bluetooth.device.extra.LOW_LATENCY_BUFFER_SIZE"; 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 @@ -2067,6 +2069,15 @@ package android.bluetooth { method @RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT, android.Manifest.permission.MODIFY_PHONE_STATE}) public boolean stopScoUsingVirtualVoiceCall(); } + public final class BluetoothHeadsetClient implements java.lang.AutoCloseable 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 getConnectionPolicy(@NonNull android.bluetooth.BluetoothDevice); + method @RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT, android.Manifest.permission.BLUETOOTH_PRIVILEGED}) public int getConnectionState(@NonNull android.bluetooth.BluetoothDevice); + method @NonNull @RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT, android.Manifest.permission.BLUETOOTH_PRIVILEGED}) public java.util.List<android.bluetooth.BluetoothDevice> getDevicesMatchingConnectionStates(@NonNull int[]); + method @RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT, android.Manifest.permission.BLUETOOTH_PRIVILEGED}) public boolean setConnectionPolicy(@NonNull android.bluetooth.BluetoothDevice, int); + field @RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT, android.Manifest.permission.BLUETOOTH_PRIVILEGED}) public static final String ACTION_CONNECTION_STATE_CHANGED = "android.bluetooth.headsetprofile.action.CONNECTION_STATE_CHANGED"; + } + 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); @@ -2098,8 +2109,14 @@ package android.bluetooth { 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 { + public final class BluetoothMapClient implements java.lang.AutoCloseable 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 getConnectionPolicy(@NonNull android.bluetooth.BluetoothDevice); + method @RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT, android.Manifest.permission.BLUETOOTH_PRIVILEGED}) public int getConnectionState(@NonNull android.bluetooth.BluetoothDevice); + method @NonNull @RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT, android.Manifest.permission.BLUETOOTH_PRIVILEGED}) public java.util.List<android.bluetooth.BluetoothDevice> getDevicesMatchingConnectionStates(@NonNull int[]); 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); + method @RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT, android.Manifest.permission.BLUETOOTH_PRIVILEGED}) public boolean setConnectionPolicy(@NonNull android.bluetooth.BluetoothDevice, int); + field @RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT, android.Manifest.permission.BLUETOOTH_PRIVILEGED}) public static final String ACTION_CONNECTION_STATE_CHANGED = "android.bluetooth.mapmce.profile.action.CONNECTION_STATE_CHANGED"; } public final class BluetoothPan implements android.bluetooth.BluetoothProfile { 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/com/android/internal/os/BatteryStatsImpl.java b/core/java/com/android/internal/os/BatteryStatsImpl.java index 7e4645c13a6b..58a0622ba53b 100644 --- a/core/java/com/android/internal/os/BatteryStatsImpl.java +++ b/core/java/com/android/internal/os/BatteryStatsImpl.java @@ -11599,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 @@ -11681,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/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 832c49801bdc..80e83ad9865c 100644 --- a/core/jni/OWNERS +++ b/core/jni/OWNERS @@ -72,6 +72,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/res/res/values/public.xml b/core/res/res/values/public.xml index 2403a605972e..5f89588bdc7d 100644 --- a/core/res/res/values/public.xml +++ b/core/res/res/values/public.xml @@ -3200,11 +3200,85 @@ <!-- @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"> + </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/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/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/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/TrafficStats.java b/packages/ConnectivityT/framework-t/src/android/net/TrafficStats.java index c803a723ba83..77b7f16671a0 100644 --- a/packages/ConnectivityT/framework-t/src/android/net/TrafficStats.java +++ b/packages/ConnectivityT/framework-t/src/android/net/TrafficStats.java @@ -16,6 +16,8 @@ package android.net; +import static android.annotation.SystemApi.Client.MODULE_LIBRARIES; + import android.annotation.NonNull; import android.annotation.SuppressLint; import android.annotation.SystemApi; @@ -214,6 +216,18 @@ public class TrafficStats { } /** + * 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/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/NetworkStatsService.java b/packages/ConnectivityT/service/src/com/android/server/net/NetworkStatsService.java index 1f87f7bf96a8..243d62164705 100644 --- a/packages/ConnectivityT/service/src/com/android/server/net/NetworkStatsService.java +++ b/packages/ConnectivityT/service/src/com/android/server/net/NetworkStatsService.java @@ -357,6 +357,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"); } @@ -419,7 +422,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()); @@ -454,6 +457,8 @@ public class NetworkStatsService extends INetworkStatsService.Stub { mContentObserver = mDeps.makeContentObserver(mHandler, mSettings, mNetworkStatsSubscriptionsMonitor); mLocationPermissionChecker = mDeps.makeLocationPermissionChecker(mContext); + mInterfaceMapUpdater = mDeps.makeBpfInterfaceMapUpdater(mContext, mHandler); + mInterfaceMapUpdater.start(); } /** @@ -508,6 +513,13 @@ 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); + } } /** @@ -988,8 +1000,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); 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..8551d887e80c 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; @@ -44,6 +44,7 @@ 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; @@ -1158,19 +1159,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 +1173,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); @@ -1464,9 +1458,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 +1533,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 +1552,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 +1625,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/stats/pull/StatsPullAtomService.java b/services/core/java/com/android/server/stats/pull/StatsPullAtomService.java index bbd4d058dfaf..d4e7573bf216 100644 --- a/services/core/java/com/android/server/stats/pull/StatsPullAtomService.java +++ b/services/core/java/com/android/server/stats/pull/StatsPullAtomService.java @@ -18,9 +18,6 @@ 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; @@ -73,6 +70,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 +84,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 +177,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 +225,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 +321,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 +767,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 +957,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 +1087,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 +1104,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; @@ -1223,23 +1195,19 @@ public class StatsPullAtomService extends SystemService { 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,13 +1215,12 @@ 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())); } } @@ -1268,12 +1235,11 @@ public class StatsPullAtomService extends SystemService { // 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,15 +1253,13 @@ 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())); } } } @@ -1357,22 +1321,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 quaryTaggedStats = + mNetworkStatsManager.queryTaggedSummary(template, + currentTimeInMillis - elapsedMillisSinceBoot - bucketDuration, + currentTimeInMillis); + final NetworkStats taggedStats = + NetworkStatsUtils.fromPublicNetworkStats(quaryTaggedStats); + return nonTaggedStats.add(taggedStats); } @NonNull private List<NetworkStatsExt> getDataUsageBytesTransferSnapshotForSub( @@ -1396,27 +1370,51 @@ public class StatsPullAtomService extends SystemService { return ret; } + @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 +1424,31 @@ 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); + @NonNull Function<NetworkStats.Entry, NetworkStats.Entry> slicer) { + NetworkStats ret = new NetworkStats(stats.getElapsedRealtime(), 1); + NetworkStats.Entry entry = new NetworkStats.Entry(); + for (NetworkStats.Entry e : stats) { if (slicer != null) { - slicer.accept(entry, recycle); + entry = slicer.apply(e); } - - 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); + ret = ret.addEntry(entry); } return ret; } diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java index df98390ddf05..a4162ba0e080 100644 --- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java +++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java @@ -109,6 +109,7 @@ 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.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; @@ -17541,7 +17542,12 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { ? 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(() -> 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..6c1d16402cab 100644 --- a/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java +++ b/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java @@ -40,6 +40,7 @@ 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.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; @@ -4109,6 +4110,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); |