summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--core/api/current.txt1
-rw-r--r--core/api/module-lib-current.txt23
-rw-r--r--core/api/system-current.txt51
-rw-r--r--core/java/android/bluetooth/BluetoothDevice.java50
-rw-r--r--core/java/android/bluetooth/OobData.java982
-rw-r--r--core/java/android/content/Context.java3
-rw-r--r--core/java/android/hardware/camera2/CameraManager.java4
-rw-r--r--core/java/android/net/INetworkPolicyListener.aidl1
-rw-r--r--core/java/android/net/NetworkPolicyManager.java294
-rw-r--r--core/java/android/provider/Telephony.java3
-rw-r--r--core/java/com/android/internal/app/OWNERS7
-rw-r--r--core/java/com/android/internal/os/ZygoteInit.java14
-rw-r--r--core/proto/android/net/networkcapabilities.proto118
-rw-r--r--core/proto/android/net/networkrequest.proto2
-rw-r--r--core/proto/android/os/incident.proto2
-rw-r--r--core/proto/android/service/enums.proto40
-rw-r--r--core/proto/android/service/usb.proto431
-rw-r--r--keystore/java/android/security/keystore2/AndroidKeyStoreCipherSpiBase.java15
-rw-r--r--keystore/java/android/security/keystore2/AndroidKeyStoreProvider.java8
-rw-r--r--media/jni/Android.bp1
-rw-r--r--packages/CarrierDefaultApp/src/com/android/carrierdefaultapp/CaptivePortalLoginActivity.java3
-rw-r--r--packages/CarrierDefaultApp/src/com/android/carrierdefaultapp/ProvisionObserver.java2
-rw-r--r--packages/Connectivity/framework/aidl-export/android/net/NetworkScore.aidl (renamed from core/java/android/net/NetworkScore.aidl)0
-rw-r--r--packages/Connectivity/framework/api/current.txt1
-rw-r--r--packages/Connectivity/framework/api/module-lib-current.txt1
-rw-r--r--packages/Connectivity/framework/api/system-current.txt4
-rw-r--r--packages/Connectivity/framework/src/android/net/CaptivePortalData.java14
-rw-r--r--packages/Connectivity/framework/src/android/net/ConnectivityManager.java14
-rw-r--r--packages/Connectivity/framework/src/android/net/IOnCompleteListener.aidl (renamed from core/java/android/net/IOnCompleteListener.aidl)0
-rw-r--r--packages/Connectivity/framework/src/android/net/InetAddressCompat.java88
-rw-r--r--packages/Connectivity/framework/src/android/net/Network.java4
-rw-r--r--packages/Connectivity/framework/src/android/net/NetworkAgentConfig.java3
-rw-r--r--packages/Connectivity/framework/src/android/net/NetworkCapabilities.java4
-rw-r--r--packages/Connectivity/framework/src/android/net/NetworkScore.java (renamed from core/java/android/net/NetworkScore.java)30
-rw-r--r--packages/SettingsLib/src/com/android/settingslib/deviceinfo/AbstractIpAddressPreferenceController.java8
-rw-r--r--services/core/java/com/android/server/ConnectivityService.java165
-rw-r--r--services/core/java/com/android/server/NetworkManagementService.java2
-rw-r--r--services/core/java/com/android/server/am/OWNERS4
-rw-r--r--services/core/java/com/android/server/connectivity/ConnectivityConstants.java10
-rw-r--r--services/core/java/com/android/server/connectivity/FullScore.java211
-rw-r--r--services/core/java/com/android/server/connectivity/NetworkAgentInfo.java52
-rw-r--r--services/core/java/com/android/server/connectivity/NetworkNotificationManager.java2
-rw-r--r--services/core/java/com/android/server/connectivity/ProxyTracker.java3
-rw-r--r--services/core/java/com/android/server/connectivity/Vpn.java24
-rw-r--r--services/core/java/com/android/server/connectivity/VpnIkev2Utils.java3
-rw-r--r--services/core/java/com/android/server/locksettings/LockSettingsService.java10
-rw-r--r--services/core/java/com/android/server/net/NetworkPolicyManagerService.java249
-rw-r--r--services/core/java/com/android/server/pm/dex/ArtStatsLogUtils.java36
-rw-r--r--services/core/java/com/android/server/policy/LegacyGlobalActions.java9
-rw-r--r--services/core/java/com/android/server/recoverysystem/RecoverySystemService.java120
-rw-r--r--services/core/java/com/android/server/vcn/VcnGatewayConnection.java14
-rw-r--r--services/tests/mockingservicestests/src/com/android/server/pm/dex/OWNERS3
-rw-r--r--services/tests/servicestests/src/com/android/server/pm/dex/ArtStatsLogUtilsTest.java8
-rw-r--r--services/tests/servicestests/src/com/android/server/recoverysystem/RecoverySystemServiceTest.java43
-rw-r--r--services/tests/servicestests/src/com/android/server/recoverysystem/RecoverySystemServiceTestable.java52
-rw-r--r--services/usb/java/com/android/server/usb/UsbPortManager.java12
-rw-r--r--telephony/java/android/telephony/CarrierConfigManager.java9
-rw-r--r--telephony/java/android/telephony/TelephonyManager.java19
-rw-r--r--tests/net/java/com/android/server/ConnectivityServiceTest.java78
-rw-r--r--tests/net/java/com/android/server/connectivity/FullScoreTest.kt134
-rw-r--r--tests/net/java/com/android/server/connectivity/LingerMonitorTest.java2
61 files changed, 3006 insertions, 494 deletions
diff --git a/core/api/current.txt b/core/api/current.txt
index 2b5075dfae95..8224a754ec69 100644
--- a/core/api/current.txt
+++ b/core/api/current.txt
@@ -39222,6 +39222,7 @@ package android.telephony {
field public static final String KEY_GSM_ROAMING_NETWORKS_STRING_ARRAY = "gsm_roaming_networks_string_array";
field public static final String KEY_HAS_IN_CALL_NOISE_SUPPRESSION_BOOL = "has_in_call_noise_suppression_bool";
field public static final String KEY_HIDE_CARRIER_NETWORK_SETTINGS_BOOL = "hide_carrier_network_settings_bool";
+ field public static final String KEY_HIDE_ENABLE_2G = "hide_enable_2g_bool";
field public static final String KEY_HIDE_ENHANCED_4G_LTE_BOOL = "hide_enhanced_4g_lte_bool";
field public static final String KEY_HIDE_IMS_APN_BOOL = "hide_ims_apn_bool";
field public static final String KEY_HIDE_LTE_PLUS_DATA_ICON_BOOL = "hide_lte_plus_data_icon_bool";
diff --git a/core/api/module-lib-current.txt b/core/api/module-lib-current.txt
index 4df72046340b..03aadbb05806 100644
--- a/core/api/module-lib-current.txt
+++ b/core/api/module-lib-current.txt
@@ -22,6 +22,10 @@ package android.app.usage {
package android.content {
+ public abstract class Context {
+ field public static final String TEST_NETWORK_SERVICE = "test_network";
+ }
+
public class Intent implements java.lang.Cloneable android.os.Parcelable {
field public static final String ACTION_CLEAR_DNS_CACHE = "android.intent.action.CLEAR_DNS_CACHE";
}
@@ -42,6 +46,25 @@ package android.net {
method public int getResourceId();
}
+ public class NetworkPolicyManager {
+ method @NonNull public static String blockedReasonsToString(int);
+ method public static boolean isUidBlocked(int, boolean);
+ method @RequiresPermission(android.Manifest.permission.OBSERVE_NETWORK_POLICY) public void registerNetworkPolicyCallback(@Nullable java.util.concurrent.Executor, @NonNull android.net.NetworkPolicyManager.NetworkPolicyCallback);
+ method @RequiresPermission(android.Manifest.permission.OBSERVE_NETWORK_POLICY) public void unregisterNetworkPolicyCallback(@NonNull android.net.NetworkPolicyManager.NetworkPolicyCallback);
+ field public static final int BLOCKED_METERED_REASON_ADMIN_DISABLED = 262144; // 0x40000
+ field public static final int BLOCKED_METERED_REASON_DATA_SAVER = 65536; // 0x10000
+ field public static final int BLOCKED_METERED_REASON_USER_RESTRICTED = 131072; // 0x20000
+ field public static final int BLOCKED_REASON_APP_STANDBY = 4; // 0x4
+ field public static final int BLOCKED_REASON_BATTERY_SAVER = 1; // 0x1
+ field public static final int BLOCKED_REASON_DOZE = 2; // 0x2
+ field public static final int BLOCKED_REASON_NONE = 0; // 0x0
+ field public static final int BLOCKED_REASON_RESTRICTED_MODE = 8; // 0x8
+ }
+
+ public static interface NetworkPolicyManager.NetworkPolicyCallback {
+ method public default void onUidBlockedReasonChanged(int, int);
+ }
+
public final class NetworkStateSnapshot implements android.os.Parcelable {
ctor public NetworkStateSnapshot(@NonNull android.net.Network, @NonNull android.net.NetworkCapabilities, @NonNull android.net.LinkProperties, @Nullable String, int);
method public int describeContents();
diff --git a/core/api/system-current.txt b/core/api/system-current.txt
index ad867880aec5..2b37fef55d56 100644
--- a/core/api/system-current.txt
+++ b/core/api/system-current.txt
@@ -1480,6 +1480,7 @@ package android.bluetooth {
public final class BluetoothDevice implements android.os.Parcelable {
method @RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED) public boolean cancelBondProcess();
+ method @RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED) public boolean createBondOutOfBand(int, @Nullable android.bluetooth.OobData, @Nullable android.bluetooth.OobData);
method @Nullable @RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED) public byte[] getMetadata(int);
method @RequiresPermission(android.Manifest.permission.BLUETOOTH) public int getSimAccessPermission();
method @RequiresPermission(android.Manifest.permission.BLUETOOTH) public boolean isConnected();
@@ -1656,6 +1657,55 @@ package android.bluetooth {
field @NonNull public static final android.os.Parcelable.Creator<android.bluetooth.BufferConstraints> CREATOR;
}
+ public final class OobData implements android.os.Parcelable {
+ method @NonNull public static android.bluetooth.OobData.ClassicBuilder createClassicBuilder(@NonNull byte[], @NonNull byte[], @NonNull byte[]);
+ method @NonNull public static android.bluetooth.OobData.LeBuilder createLeBuilder(@NonNull byte[], @NonNull byte[], int);
+ 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 {
+ 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 {
+ 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[]);
+ }
+
}
package android.bluetooth.le {
@@ -10234,6 +10284,7 @@ package android.telephony {
field public static final String ACTION_SIM_CARD_STATE_CHANGED = "android.telephony.action.SIM_CARD_STATE_CHANGED";
field public static final String ACTION_SIM_SLOT_STATUS_CHANGED = "android.telephony.action.SIM_SLOT_STATUS_CHANGED";
field public static final int ALLOWED_NETWORK_TYPES_REASON_CARRIER = 2; // 0x2
+ field public static final int ALLOWED_NETWORK_TYPES_REASON_ENABLE_2G = 3; // 0x3
field public static final int ALLOWED_NETWORK_TYPES_REASON_POWER = 1; // 0x1
field public static final int ALLOWED_NETWORK_TYPES_REASON_USER = 0; // 0x0
field public static final int CALL_WAITING_STATUS_DISABLED = 2; // 0x2
diff --git a/core/java/android/bluetooth/BluetoothDevice.java b/core/java/android/bluetooth/BluetoothDevice.java
index 89030bcf12e0..41bc77651db6 100644
--- a/core/java/android/bluetooth/BluetoothDevice.java
+++ b/core/java/android/bluetooth/BluetoothDevice.java
@@ -1279,7 +1279,6 @@ public final class BluetoothDevice implements Parcelable {
* the bonding process completes, and its result.
* <p>Android system services will handle the necessary user interactions
* to confirm and complete the bonding process.
- * <p>Requires {@link android.Manifest.permission#BLUETOOTH_ADMIN}.
*
* @param transport The transport to use for the pairing procedure.
* @return false on immediate error, true if bonding will begin
@@ -1287,8 +1286,9 @@ public final class BluetoothDevice implements Parcelable {
* @hide
*/
@UnsupportedAppUsage
+ @RequiresPermission(Manifest.permission.BLUETOOTH_ADMIN)
public boolean createBond(int transport) {
- return createBondOutOfBand(transport, null);
+ return createBondInternal(transport, null, null);
}
/**
@@ -1302,21 +1302,38 @@ public final class BluetoothDevice implements Parcelable {
* <p>Android system services will handle the necessary user interactions
* to confirm and complete the bonding process.
*
- * <p>Requires {@link android.Manifest.permission#BLUETOOTH_ADMIN}.
+ * <p>There are two possible versions of OOB Data. This data can come in as
+ * P192 or P256. This is a reference to the cryptography used to generate the key.
+ * The caller may pass one or both. If both types of data are passed, then the
+ * P256 data will be preferred, and thus used.
*
* @param transport - Transport to use
- * @param oobData - Out Of Band data
+ * @param remoteP192Data - Out Of Band data (P192) or null
+ * @param remoteP256Data - Out Of Band data (P256) or null
* @return false on immediate error, true if bonding will begin
* @hide
*/
- public boolean createBondOutOfBand(int transport, OobData oobData) {
+ @SystemApi
+ @RequiresPermission(Manifest.permission.BLUETOOTH_PRIVILEGED)
+ public boolean createBondOutOfBand(int transport, @Nullable OobData remoteP192Data,
+ @Nullable OobData remoteP256Data) {
+ if (remoteP192Data == null && remoteP256Data == null) {
+ throw new IllegalArgumentException(
+ "One or both arguments for the OOB data types are required to not be null."
+ + " Please use createBond() instead if you do not have OOB data to pass.");
+ }
+ return createBondInternal(transport, remoteP192Data, remoteP256Data);
+ }
+
+ private boolean createBondInternal(int transport, @Nullable OobData remoteP192Data,
+ @Nullable OobData remoteP256Data) {
final IBluetooth service = sService;
if (service == null) {
Log.w(TAG, "BT not enabled, createBondOutOfBand failed");
return false;
}
try {
- return service.createBond(this, transport, oobData);
+ return service.createBond(this, transport, remoteP192Data, remoteP256Data);
} catch (RemoteException e) {
Log.e(TAG, "", e);
}
@@ -1347,27 +1364,6 @@ public final class BluetoothDevice implements Parcelable {
}
/**
- * Set the Out Of Band data for a remote device to be used later
- * in the pairing mechanism. Users can obtain this data through other
- * trusted channels
- *
- * <p>Requires {@link android.Manifest.permission#BLUETOOTH_ADMIN}.
- *
- * @param hash Simple Secure pairing hash
- * @param randomizer The random key obtained using OOB
- * @return false on error; true otherwise
- * @hide
- */
- public boolean setDeviceOutOfBandData(byte[] hash, byte[] randomizer) {
- //TODO(BT)
- /*
- try {
- return sService.setDeviceOutOfBandData(this, hash, randomizer);
- } catch (RemoteException e) {Log.e(TAG, "", e);} */
- return false;
- }
-
- /**
* Cancel an in-progress bonding request started with {@link #createBond}.
*
* @return true on success, false on error
diff --git a/core/java/android/bluetooth/OobData.java b/core/java/android/bluetooth/OobData.java
index 0d0c6ab2efa9..08d694eb93e2 100644
--- a/core/java/android/bluetooth/OobData.java
+++ b/core/java/android/bluetooth/OobData.java
@@ -1,4 +1,4 @@
-/*
+/**
* Copyright (C) 2016 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
@@ -16,88 +16,949 @@
package android.bluetooth;
+import android.annotation.IntDef;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.annotation.SystemApi;
import android.os.Parcel;
import android.os.Parcelable;
+import com.android.internal.util.Preconditions;
+
+import java.lang.IllegalArgumentException;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
/**
* Out Of Band Data for Bluetooth device pairing.
*
* <p>This object represents optional data obtained from a remote device through
- * an out-of-band channel (eg. NFC).
+ * an out-of-band channel (eg. NFC, QR).
+ *
+ * <p>References:
+ * NFC AD Forum SSP 1.1 (AD)
+ * {@link https://members.nfc-forum.org//apps/group_public/download.php/24620/NFCForum-AD-BTSSP_1_1.pdf}
+ * Core Specification Supplement (CSS) V9
+ *
+ * <p>There are several BR/EDR Examples
+ *
+ * <p>Negotiated Handover:
+ * Bluetooth Carrier Configuration Record:
+ * - OOB Data Length
+ * - Device Address
+ * - Class of Device
+ * - Simple Pairing Hash C
+ * - Simple Pairing Randomizer R
+ * - Service Class UUID
+ * - Bluetooth Local Name
+ *
+ * <p>Static Handover:
+ * Bluetooth Carrier Configuration Record:
+ * - OOB Data Length
+ * - Device Address
+ * - Class of Device
+ * - Service Class UUID
+ * - Bluetooth Local Name
+ *
+ * <p>Simplified Tag Format for Single BT Carrier:
+ * Bluetooth OOB Data Record:
+ * - OOB Data Length
+ * - Device Address
+ * - Class of Device
+ * - Service Class UUID
+ * - Bluetooth Local Name
*
* @hide
*/
-public class OobData implements Parcelable {
- private byte[] mLeBluetoothDeviceAddress;
- private byte[] mSecurityManagerTk;
- private byte[] mLeSecureConnectionsConfirmation;
- private byte[] mLeSecureConnectionsRandom;
+@SystemApi
+public final class OobData implements Parcelable {
+
+ private static final String TAG = "OobData";
+ /** The {@link OobData#mClassicLength} may be. (AD 3.1.1) (CSS 1.6.2) @hide */
+ @SystemApi
+ public static final int OOB_LENGTH_OCTETS = 2;
+ /**
+ * The length for the {@link OobData#mDeviceAddressWithType}(6) and Address Type(1).
+ * (AD 3.1.2) (CSS 1.6.2)
+ * @hide
+ */
+ @SystemApi
+ public static final int DEVICE_ADDRESS_OCTETS = 7;
+ /** The Class of Device is 3 octets. (AD 3.1.3) (CSS 1.6.2) @hide */
+ @SystemApi
+ public static final int CLASS_OF_DEVICE_OCTETS = 3;
+ /** The Confirmation data must be 16 octets. (AD 3.2.2) (CSS 1.6.2) @hide */
+ @SystemApi
+ public static final int CONFIRMATION_OCTETS = 16;
+ /** The Randomizer data must be 16 octets. (AD 3.2.3) (CSS 1.6.2) @hide */
+ @SystemApi
+ public static final int RANDOMIZER_OCTETS = 16;
+ /** The LE Device Role length is 1 octet. (AD 3.3.2) (CSS 1.17) @hide */
+ @SystemApi
+ public static final int LE_DEVICE_ROLE_OCTETS = 1;
+ /** The {@link OobData#mLeTemporaryKey} length. (3.4.1) @hide */
+ @SystemApi
+ public static final int LE_TK_OCTETS = 16;
+ /** The {@link OobData#mLeAppearance} length. (3.4.1) @hide */
+ @SystemApi
+ public static final int LE_APPEARANCE_OCTETS = 2;
+ /** The {@link OobData#mLeFlags} length. (3.4.1) @hide */
+ @SystemApi
+ public static final int LE_DEVICE_FLAG_OCTETS = 1; // 1 octet to hold the 0-4 value.
+
+ // Le Roles
+ /** @hide */
+ @Retention(RetentionPolicy.SOURCE)
+ @IntDef(
+ prefix = { "LE_DEVICE_ROLE_" },
+ value = {
+ LE_DEVICE_ROLE_PERIPHERAL_ONLY,
+ LE_DEVICE_ROLE_CENTRAL_ONLY,
+ LE_DEVICE_ROLE_BOTH_PREFER_PERIPHERAL,
+ LE_DEVICE_ROLE_BOTH_PREFER_CENTRAL
+ }
+ )
+ public @interface LeRole {}
+
+ /** @hide */
+ @SystemApi
+ public static final int LE_DEVICE_ROLE_PERIPHERAL_ONLY = 0x00;
+ /** @hide */
+ @SystemApi
+ public static final int LE_DEVICE_ROLE_CENTRAL_ONLY = 0x01;
+ /** @hide */
+ @SystemApi
+ public static final int LE_DEVICE_ROLE_BOTH_PREFER_PERIPHERAL = 0x02;
+ /** @hide */
+ @SystemApi
+ public static final int LE_DEVICE_ROLE_BOTH_PREFER_CENTRAL = 0x03;
+
+ // Le Flags
+ /** @hide */
+ @Retention(RetentionPolicy.SOURCE)
+ @IntDef(
+ prefix = { "LE_FLAG_" },
+ value = {
+ LE_FLAG_LIMITED_DISCOVERY_MODE,
+ LE_FLAG_GENERAL_DISCOVERY_MODE,
+ LE_FLAG_BREDR_NOT_SUPPORTED,
+ LE_FLAG_SIMULTANEOUS_CONTROLLER,
+ LE_FLAG_SIMULTANEOUS_HOST
+ }
+ )
+ public @interface LeFlag {}
+
+ /** @hide */
+ @SystemApi
+ public static final int LE_FLAG_LIMITED_DISCOVERY_MODE = 0x00;
+ /** @hide */
+ @SystemApi
+ public static final int LE_FLAG_GENERAL_DISCOVERY_MODE = 0x01;
+ /** @hide */
+ @SystemApi
+ public static final int LE_FLAG_BREDR_NOT_SUPPORTED = 0x02;
+ /** @hide */
+ @SystemApi
+ public static final int LE_FLAG_SIMULTANEOUS_CONTROLLER = 0x03;
+ /** @hide */
+ @SystemApi
+ public static final int LE_FLAG_SIMULTANEOUS_HOST = 0x04;
+
+ /**
+ * Main creation method for creating a Classic version of {@link OobData}.
+ *
+ * <p>This object will allow the caller to call {@link ClassicBuilder#build()}
+ * to build the data object or add any option information to the builder.
+ *
+ * @param confirmationHash byte array consisting of {@link OobData#CONFIRMATION_OCTETS} octets
+ * of data. Data is derived from controller/host stack and is required for pairing OOB.
+ * @param classicLength byte array representing the length of data from 8-65535 across 2
+ * octets (0xXXXX).
+ * @param deviceAddressWithType byte array representing the Bluetooth Address of the device
+ * that owns the OOB data. (i.e. the originator) [6 octets]
+ *
+ * @return a Classic Builder instance with all the given data set or null.
+ *
+ * @throws IllegalArgumentException if any of the values fail to be set.
+ * @throws NullPointerException if any argument is null.
+ *
+ * @hide
+ */
+ @NonNull
+ @SystemApi
+ public static ClassicBuilder createClassicBuilder(@NonNull byte[] confirmationHash,
+ @NonNull byte[] classicLength, @NonNull byte[] deviceAddressWithType) {
+ return new ClassicBuilder(confirmationHash, classicLength, deviceAddressWithType);
+ }
+
+ /**
+ * Main creation method for creating a LE version of {@link OobData}.
+ *
+ * <p>This object will allow the caller to call {@link LeBuilder#build()}
+ * to build the data object or add any option information to the builder.
+ *
+ * @param deviceAddressWithType the LE device address plus the address type (7 octets);
+ * not null.
+ * @param leDeviceRole whether the device supports Peripheral, Central,
+ * Both including preference; not null. (1 octet)
+ * @param confirmationHash Array consisting of {@link OobData#CONFIRMATION_OCTETS} octets
+ * of data. Data is derived from controller/host stack and is
+ * required for pairing OOB.
+ *
+ * <p>Possible LE Device Role Values:
+ * 0x00 Only Peripheral supported
+ * 0x01 Only Central supported
+ * 0x02 Central & Peripheral supported; Peripheral Preferred
+ * 0x03 Only peripheral supported; Central Preferred
+ * 0x04 - 0xFF Reserved
+ *
+ * @return a LeBuilder instance with all the given data set or null.
+ *
+ * @throws IllegalArgumentException if any of the values fail to be set.
+ * @throws NullPointerException if any argument is null.
+ *
+ * @hide
+ */
+ @NonNull
+ @SystemApi
+ public static LeBuilder createLeBuilder(@NonNull byte[] confirmationHash,
+ @NonNull byte[] deviceAddressWithType, @LeRole int leDeviceRole) {
+ return new LeBuilder(confirmationHash, deviceAddressWithType, leDeviceRole);
+ }
+
+ /**
+ * Builds an {@link OobData} object and validates that the required combination
+ * of values are present to create the LE specific OobData type.
+ *
+ * @hide
+ */
+ @SystemApi
+ public static final class LeBuilder {
+
+ /**
+ * It is recommended that this Hash C is generated anew for each
+ * pairing.
+ *
+ * <p>It should be noted that on passive NFC this isn't possible as the data is static
+ * and immutable.
+ */
+ private byte[] mConfirmationHash = null;
+
+ /**
+ * Optional, but adds more validity to the pairing.
+ *
+ * <p>If not present a value of 0 is assumed.
+ */
+ private byte[] mRandomizerHash = new byte[] {
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ };
+
+ /**
+ * The Bluetooth Device user-friendly name presented over Bluetooth Technology.
+ *
+ * <p>This is the name that may be displayed to the device user as part of the UI.
+ */
+ private byte[] mDeviceName = null;
+
+ /**
+ * Sets the Bluetooth Device name to be used for UI purposes.
+ *
+ * <p>Optional attribute.
+ *
+ * @param deviceName byte array representing the name, may be 0 in length, not null.
+ *
+ * @return {@link OobData#ClassicBuilder}
+ *
+ * @throws NullPointerException if deviceName is null.
+ *
+ * @hide
+ */
+ @NonNull
+ @SystemApi
+ public LeBuilder setDeviceName(@NonNull byte[] deviceName) {
+ Preconditions.checkNotNull(deviceName);
+ this.mDeviceName = deviceName;
+ return this;
+ }
+
+ /**
+ * The Bluetooth Device Address is the address to which the OOB data belongs.
+ *
+ * <p>The length MUST be {@link OobData#DEVICE_ADDRESS_OCTETS} octets.
+ *
+ * <p> Address is encoded in Little Endian order.
+ *
+ * <p>e.g. 00:01:02:03:04:05 would be x05x04x03x02x01x00
+ */
+ private final byte[] mDeviceAddressWithType;
+
+ /**
+ * During an LE connection establishment, one must be in the Peripheral mode and the other
+ * in the Central role.
+ *
+ * <p>Possible Values:
+ * {@link LE_DEVICE_ROLE_PERIPHERAL_ONLY} Only Peripheral supported
+ * {@link LE_DEVICE_ROLE_CENTRAL_ONLY} Only Central supported
+ * {@link LE_DEVICE_ROLE_BOTH_PREFER_PERIPHERAL} Central & Peripheral supported;
+ * Peripheral Preferred
+ * {@link LE_DEVICE_ROLE_BOTH_PREFER_CENTRAL} Only peripheral supported; Central Preferred
+ * 0x04 - 0xFF Reserved
+ */
+ private final @LeRole int mLeDeviceRole;
+
+ /**
+ * Temporary key value from the Security Manager.
+ *
+ * <p> Must be {@link LE_TK_OCTETS} in size
+ */
+ private byte[] mLeTemporaryKey = null;
+
+ /**
+ * Defines the representation of the external appearance of the device.
+ *
+ * <p>For example, a mouse, remote control, or keyboard.
+ *
+ * <p>Used for visual on discovering device to represent icon/string/etc...
+ */
+ private byte[] mLeAppearance = null;
+
+ /**
+ * Contains which discoverable mode to use, BR/EDR support and capability.
+ *
+ * <p>Possible LE Flags:
+ * {@link LE_FLAG_LIMITED_DISCOVERY_MODE} LE Limited Discoverable Mode.
+ * {@link LE_FLAG_GENERAL_DISCOVERY_MODE} LE General Discoverable Mode.
+ * {@link LE_FLAG_BREDR_NOT_SUPPORTED} BR/EDR Not Supported. Bit 37 of
+ * LMP Feature Mask Definitions.
+ * {@link LE_FLAG_SIMULTANEOUS_CONTROLLER} Simultaneous LE and BR/EDR to
+ * Same Device Capable (Controller).
+ * Bit 49 of LMP Feature Mask Definitions.
+ * {@link LE_FLAG_SIMULTANEOUS_HOST} Simultaneous LE and BR/EDR to
+ * Same Device Capable (Host).
+ * Bit 55 of LMP Feature Mask Definitions.
+ * <b>0x05- 0x07 Reserved</b>
+ */
+ private @LeFlag int mLeFlags = LE_FLAG_GENERAL_DISCOVERY_MODE; // Invalid default
+
+ /**
+ * Constructing an OobData object for use with LE requires
+ * a LE Device Address and LE Device Role as well as the Confirmation
+ * and optionally, the Randomizer, however it is recommended to use.
+ *
+ * @param confirmationHash byte array consisting of {@link OobData#CONFIRMATION_OCTETS}
+ * octets of data. Data is derived from controller/host stack and is required for
+ * pairing OOB.
+ * @param deviceAddressWithType 7 bytes containing the 6 byte address with the 1 byte
+ * address type.
+ * @param leDeviceRole indicating device's role and preferences (Central or Peripheral)
+ *
+ * <p>Possible Values:
+ * {@link LE_DEVICE_ROLE_PERIPHERAL_ONLY} Only Peripheral supported
+ * {@link LE_DEVICE_ROLE_CENTRAL_ONLY} Only Central supported
+ * {@link LE_DEVICE_ROLE_BOTH_PREFER_PERIPHERAL} Central & Peripheral supported;
+ * Peripheral Preferred
+ * {@link LE_DEVICE_ROLE_BOTH_PREFER_CENTRAL} Only peripheral supported; Central Preferred
+ * 0x04 - 0xFF Reserved
+ *
+ * @throws IllegalArgumentException if deviceAddressWithType is not
+ * {@link LE_DEVICE_ADDRESS_OCTETS} octets
+ * @throws NullPointerException if any argument is null.
+ */
+ private LeBuilder(@NonNull byte[] confirmationHash, @NonNull byte[] deviceAddressWithType,
+ @LeRole int leDeviceRole) {
+ Preconditions.checkNotNull(confirmationHash);
+ Preconditions.checkNotNull(deviceAddressWithType);
+ if (confirmationHash.length != OobData.CONFIRMATION_OCTETS) {
+ throw new IllegalArgumentException("confirmationHash must be "
+ + OobData.CONFIRMATION_OCTETS + " octets in length.");
+ }
+ this.mConfirmationHash = confirmationHash;
+ if (deviceAddressWithType.length != OobData.DEVICE_ADDRESS_OCTETS) {
+ throw new IllegalArgumentException("confirmationHash must be "
+ + OobData.DEVICE_ADDRESS_OCTETS+ " octets in length.");
+ }
+ this.mDeviceAddressWithType = deviceAddressWithType;
+ if (leDeviceRole < LE_DEVICE_ROLE_PERIPHERAL_ONLY
+ || leDeviceRole > LE_DEVICE_ROLE_BOTH_PREFER_CENTRAL) {
+ throw new IllegalArgumentException("leDeviceRole must be a valid value.");
+ }
+ this.mLeDeviceRole = leDeviceRole;
+ }
+
+ /**
+ * Sets the Temporary Key value to be used by the LE Security Manager during
+ * LE pairing.
+ *
+ * @param leTemporaryKey byte array that shall be 16 bytes. Please see Bluetooth CSSv6,
+ * Part A 1.8 for a detailed description.
+ *
+ * @return {@link OobData#Builder}
+ *
+ * @throws IllegalArgumentException if the leTemporaryKey is an invalid format.
+ * @throws NullinterException if leTemporaryKey is null.
+ *
+ * @hide
+ */
+ @NonNull
+ @SystemApi
+ public LeBuilder setLeTemporaryKey(@NonNull byte[] leTemporaryKey) {
+ Preconditions.checkNotNull(leTemporaryKey);
+ if (leTemporaryKey.length != LE_TK_OCTETS) {
+ throw new IllegalArgumentException("leTemporaryKey must be "
+ + LE_TK_OCTETS + " octets in length.");
+ }
+ this.mLeTemporaryKey = leTemporaryKey;
+ return this;
+ }
+
+ /**
+ * @param randomizerHash byte array consisting of {@link OobData#RANDOMIZER_OCTETS} octets
+ * of data. Data is derived from controller/host stack and is required for pairing OOB.
+ * Also, randomizerHash may be all 0s or null in which case it becomes all 0s.
+ *
+ * @throws IllegalArgumentException if null or incorrect length randomizerHash was passed.
+ * @throws NullPointerException if randomizerHash is null.
+ *
+ * @hide
+ */
+ @NonNull
+ @SystemApi
+ public LeBuilder setRandomizerHash(@NonNull byte[] randomizerHash) {
+ Preconditions.checkNotNull(randomizerHash);
+ if (randomizerHash.length != OobData.RANDOMIZER_OCTETS) {
+ throw new IllegalArgumentException("randomizerHash must be "
+ + OobData.RANDOMIZER_OCTETS + " octets in length.");
+ }
+ this.mRandomizerHash = randomizerHash;
+ return this;
+ }
+
+ /**
+ * Sets the LE Flags necessary for the pairing scenario or discovery mode.
+ *
+ * @param leFlags enum value representing the 1 octet of data about discovery modes.
+ *
+ * <p>Possible LE Flags:
+ * {@link LE_FLAG_LIMITED_DISCOVERY_MODE} LE Limited Discoverable Mode.
+ * {@link LE_FLAG_GENERAL_DISCOVERY_MODE} LE General Discoverable Mode.
+ * {@link LE_FLAG_BREDR_NOT_SUPPORTED} BR/EDR Not Supported. Bit 37 of
+ * LMP Feature Mask Definitions.
+ * {@link LE_FLAG_SIMULTANEOUS_CONTROLLER} Simultaneous LE and BR/EDR to
+ * Same Device Capable (Controller) Bit 49 of LMP Feature Mask Definitions.
+ * {@link LE_FLAG_SIMULTANEOUS_HOST} Simultaneous LE and BR/EDR to
+ * Same Device Capable (Host).
+ * Bit 55 of LMP Feature Mask Definitions.
+ * 0x05- 0x07 Reserved
+ *
+ * @throws IllegalArgumentException for invalid flag
+ * @hide
+ */
+ @NonNull
+ @SystemApi
+ public LeBuilder setLeFlags(@LeFlag int leFlags) {
+ if (leFlags < LE_FLAG_LIMITED_DISCOVERY_MODE || leFlags > LE_FLAG_SIMULTANEOUS_HOST) {
+ throw new IllegalArgumentException("leFlags must be a valid value.");
+ }
+ this.mLeFlags = leFlags;
+ return this;
+ }
+
+ /**
+ * Validates and builds the {@link OobData} object for LE Security.
+ *
+ * @return {@link OobData} with given builder values
+ *
+ * @throws IllegalStateException if either of the 2 required fields were not set.
+ *
+ * @hide
+ */
+ @NonNull
+ @SystemApi
+ public OobData build() {
+ final OobData oob =
+ new OobData(this.mDeviceAddressWithType, this.mLeDeviceRole,
+ this.mConfirmationHash);
+
+ // If we have values, set them, otherwise use default
+ oob.mLeTemporaryKey =
+ (this.mLeTemporaryKey != null) ? this.mLeTemporaryKey : oob.mLeTemporaryKey;
+ oob.mLeAppearance = (this.mLeAppearance != null)
+ ? this.mLeAppearance : oob.mLeAppearance;
+ oob.mLeFlags = (this.mLeFlags != 0xF) ? this.mLeFlags : oob.mLeFlags;
+ oob.mDeviceName = (this.mDeviceName != null) ? this.mDeviceName : oob.mDeviceName;
+ oob.mRandomizerHash = this.mRandomizerHash;
+ return oob;
+ }
+ }
+
+ /**
+ * Builds an {@link OobData} object and validates that the required combination
+ * of values are present to create the Classic specific OobData type.
+ *
+ * @hide
+ */
+ @SystemApi
+ public static final class ClassicBuilder {
+ // Used by both Classic and LE
+ /**
+ * It is recommended that this Hash C is generated anew for each
+ * pairing.
+ *
+ * <p>It should be noted that on passive NFC this isn't possible as the data is static
+ * and immutable.
+ *
+ * @hide
+ */
+ private byte[] mConfirmationHash = null;
+
+ /**
+ * Optional, but adds more validity to the pairing.
+ *
+ * <p>If not present a value of 0 is assumed.
+ *
+ * @hide
+ */
+ private byte[] mRandomizerHash = new byte[] {
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ };
+
+ /**
+ * The Bluetooth Device user-friendly name presented over Bluetooth Technology.
+ *
+ * <p>This is the name that may be displayed to the device user as part of the UI.
+ *
+ * @hide
+ */
+ private byte[] mDeviceName = null;
+
+ /**
+ * This length value provides the absolute length of total OOB data block used for
+ * Bluetooth BR/EDR
+ *
+ * <p>OOB communication, which includes the length field itself and the Bluetooth
+ * Device Address.
+ *
+ * <p>The minimum length that may be represented in this field is 8.
+ *
+ * @hide
+ */
+ private final byte[] mClassicLength;
+
+ /**
+ * The Bluetooth Device Address is the address to which the OOB data belongs.
+ *
+ * <p>The length MUST be {@link OobData#DEVICE_ADDRESS_OCTETS} octets.
+ *
+ * <p> Address is encoded in Little Endian order.
+ *
+ * <p>e.g. 00:01:02:03:04:05 would be x05x04x03x02x01x00
+ *
+ * @hide
+ */
+ private final byte[] mDeviceAddressWithType;
+
+ /**
+ * Class of Device information is to be used to provide a graphical representation
+ * to the user as part of UI involving operations.
+ *
+ * <p>This is not to be used to determine a particular service can be used.
+ *
+ * <p>The length MUST be {@link OobData#CLASS_OF_DEVICE_OCTETS} octets.
+ *
+ * @hide
+ */
+ private byte[] mClassOfDevice = null;
+
+ /**
+ * @param confirmationHash byte array consisting of {@link OobData#CONFIRMATION_OCTETS}
+ * octets of data. Data is derived from controller/host stack and is required for pairing
+ * OOB.
+ * @param randomizerHash byte array consisting of {@link OobData#RANDOMIZER_OCTETS} octets
+ * of data. Data is derived from controller/host stack and is required
+ * for pairing OOB. Also, randomizerHash may be all 0s or null in which case
+ * it becomes all 0s.
+ * @param classicLength byte array representing the length of data from 8-65535 across 2
+ * octets (0xXXXX). Inclusive of this value in the length.
+ * @param deviceAddressWithType byte array representing the Bluetooth Address of the device
+ * that owns the OOB data. (i.e. the originator) [7 octets] this includes the Address Type
+ * as the last octet.
+ *
+ * @throws IllegalArgumentException if any value is not the correct length
+ * @throws NullPointerException if anything passed is null
+ *
+ * @hide
+ */
+ private ClassicBuilder(@NonNull byte[] confirmationHash, @NonNull byte[] classicLength,
+ @NonNull byte[] deviceAddressWithType) {
+ Preconditions.checkNotNull(confirmationHash);
+ Preconditions.checkNotNull(classicLength);
+ Preconditions.checkNotNull(deviceAddressWithType);
+ if (confirmationHash.length != OobData.CONFIRMATION_OCTETS) {
+ throw new IllegalArgumentException("confirmationHash must be "
+ + OobData.CONFIRMATION_OCTETS + " octets in length.");
+ }
+ this.mConfirmationHash = confirmationHash;
+ if (classicLength.length != OOB_LENGTH_OCTETS) {
+ throw new IllegalArgumentException("classicLength must be "
+ + OOB_LENGTH_OCTETS + " octets in length.");
+ }
+ this.mClassicLength = classicLength;
+ if (deviceAddressWithType.length != DEVICE_ADDRESS_OCTETS) {
+ throw new IllegalArgumentException("deviceAddressWithType must be "
+ + DEVICE_ADDRESS_OCTETS + " octets in length.");
+ }
+ this.mDeviceAddressWithType = deviceAddressWithType;
+ }
- public byte[] getLeBluetoothDeviceAddress() {
- return mLeBluetoothDeviceAddress;
+ /**
+ * @param randomizerHash byte array consisting of {@link OobData#RANDOMIZER_OCTETS} octets
+ * of data. Data is derived from controller/host stack and is required for pairing OOB.
+ * Also, randomizerHash may be all 0s or null in which case it becomes all 0s.
+ *
+ * @throws IllegalArgumentException if null or incorrect length randomizerHash was passed.
+ * @throws NullPointerException if randomizerHash is null.
+ *
+ * @hide
+ */
+ @NonNull
+ @SystemApi
+ public ClassicBuilder setRandomizerHash(@NonNull byte[] randomizerHash) {
+ Preconditions.checkNotNull(randomizerHash);
+ if (randomizerHash.length != OobData.RANDOMIZER_OCTETS) {
+ throw new IllegalArgumentException("randomizerHash must be "
+ + OobData.RANDOMIZER_OCTETS + " octets in length.");
+ }
+ this.mRandomizerHash = randomizerHash;
+ return this;
+ }
+
+ /**
+ * Sets the Bluetooth Device name to be used for UI purposes.
+ *
+ * <p>Optional attribute.
+ *
+ * @param deviceName byte array representing the name, may be 0 in length, not null.
+ *
+ * @return {@link OobData#ClassicBuilder}
+ *
+ * @throws NullPointerException if deviceName is null
+ *
+ * @hide
+ */
+ @NonNull
+ @SystemApi
+ public ClassicBuilder setDeviceName(@NonNull byte[] deviceName) {
+ Preconditions.checkNotNull(deviceName);
+ this.mDeviceName = deviceName;
+ return this;
+ }
+
+ /**
+ * Sets the Bluetooth Class of Device; used for UI purposes only.
+ *
+ * <p>Not an indicator of available services!
+ *
+ * <p>Optional attribute.
+ *
+ * @param classOfDevice byte array of {@link OobData#CLASS_OF_DEVICE_OCTETS} octets.
+ *
+ * @return {@link OobData#ClassicBuilder}
+ *
+ * @throws IllegalArgumentException if length is not equal to
+ * {@link OobData#CLASS_OF_DEVICE_OCTETS} octets.
+ * @throws NullPointerException if classOfDevice is null.
+ *
+ * @hide
+ */
+ @NonNull
+ @SystemApi
+ public ClassicBuilder setClassOfDevice(@NonNull byte[] classOfDevice) {
+ Preconditions.checkNotNull(classOfDevice);
+ if (classOfDevice.length != OobData.CLASS_OF_DEVICE_OCTETS) {
+ throw new IllegalArgumentException("classOfDevice must be "
+ + OobData.CLASS_OF_DEVICE_OCTETS + " octets in length.");
+ }
+ this.mClassOfDevice = classOfDevice;
+ return this;
+ }
+
+ /**
+ * Validates and builds the {@link OobDat object for Classic Security.
+ *
+ * @return {@link OobData} with previously given builder values.
+ *
+ * @hide
+ */
+ @NonNull
+ @SystemApi
+ public OobData build() {
+ final OobData oob =
+ new OobData(this.mClassicLength, this.mDeviceAddressWithType,
+ this.mConfirmationHash);
+ // If we have values, set them, otherwise use default
+ oob.mDeviceName = (this.mDeviceName != null) ? this.mDeviceName : oob.mDeviceName;
+ oob.mClassOfDevice = (this.mClassOfDevice != null)
+ ? this.mClassOfDevice : oob.mClassOfDevice;
+ oob.mRandomizerHash = this.mRandomizerHash;
+ return oob;
+ }
+ }
+
+ // Members (Defaults for Optionals must be set or Parceling fails on NPE)
+ // Both
+ private final byte[] mDeviceAddressWithType;
+ private final byte[] mConfirmationHash;
+ private byte[] mRandomizerHash = new byte[] {
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ };
+ // Default the name to "Bluetooth Device"
+ private byte[] mDeviceName = new byte[] {
+ // Bluetooth
+ 0x42, 0x6c, 0x75, 0x65, 0x74, 0x6f, 0x6f, 0x74, 0x68,
+ // <space>Device
+ 0x20, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65
+ };
+
+ // Classic
+ private final byte[] mClassicLength;
+ private byte[] mClassOfDevice = new byte[CLASS_OF_DEVICE_OCTETS];
+
+ // LE
+ private final @LeRole int mLeDeviceRole;
+ private byte[] mLeTemporaryKey = new byte[LE_TK_OCTETS];
+ private byte[] mLeAppearance = new byte[LE_APPEARANCE_OCTETS];
+ private @LeFlag int mLeFlags = LE_FLAG_LIMITED_DISCOVERY_MODE;
+
+ /**
+ * @return byte array representing the MAC address of a bluetooth device.
+ * The Address is 6 octets long with a 1 octet address type associated with the address.
+ *
+ * <p>For classic this will be 6 byte address plus the default of PUBLIC_ADDRESS Address Type.
+ * For LE there are more choices for Address Type.
+ *
+ * @hide
+ */
+ @NonNull
+ @SystemApi
+ public byte[] getDeviceAddressWithType() {
+ return mDeviceAddressWithType;
+ }
+
+ /**
+ * @return byte array representing the confirmationHash value
+ * which is used to confirm the identity to the controller.
+ *
+ * @hide
+ */
+ @NonNull
+ @SystemApi
+ public byte[] getConfirmationHash() {
+ return mConfirmationHash;
}
/**
- * Sets the LE Bluetooth Device Address value to be used during LE pairing.
- * The value shall be 7 bytes. Please see Bluetooth CSSv6, Part A 1.16 for
- * a detailed description.
+ * @return byte array representing the randomizerHash value
+ * which is used to verify the identity of the controller.
+ *
+ * @hide
*/
- public void setLeBluetoothDeviceAddress(byte[] leBluetoothDeviceAddress) {
- mLeBluetoothDeviceAddress = leBluetoothDeviceAddress;
+ @NonNull
+ @SystemApi
+ public byte[] getRandomizerHash() {
+ return mRandomizerHash;
}
- public byte[] getSecurityManagerTk() {
- return mSecurityManagerTk;
+ /**
+ * @return Device Name used for displaying name in UI.
+ *
+ * <p>Also, this will be populated with the LE Local Name if the data is for LE.
+ *
+ * @hide
+ */
+ @Nullable
+ @SystemApi
+ public byte[] getDeviceName() {
+ return mDeviceName;
+ }
+
+ /**
+ * @return byte array representing the oob data length which is the length
+ * of all of the data including these octets.
+ *
+ * @hide
+ */
+ @NonNull
+ @SystemApi
+ public byte[] getClassicLength() {
+ return mClassicLength;
+ }
+
+ /**
+ * @return byte array representing the class of device for UI display.
+ *
+ * <p>Does not indicate services available; for display only.
+ *
+ * @hide
+ */
+ @NonNull
+ @SystemApi
+ public byte[] getClassOfDevice() {
+ return mClassOfDevice;
}
/**
- * Sets the Temporary Key value to be used by the LE Security Manager during
- * LE pairing. The value shall be 16 bytes. Please see Bluetooth CSSv6,
- * Part A 1.8 for a detailed description.
+ * @return Temporary Key used for LE pairing.
+ *
+ * @hide
*/
- public void setSecurityManagerTk(byte[] securityManagerTk) {
- mSecurityManagerTk = securityManagerTk;
+ @Nullable
+ @SystemApi
+ public byte[] getLeTemporaryKey() {
+ return mLeTemporaryKey;
}
- public byte[] getLeSecureConnectionsConfirmation() {
- return mLeSecureConnectionsConfirmation;
+ /**
+ * @return Appearance used for LE pairing. For use in UI situations
+ * when determining what sort of icons or text to display regarding
+ * the device.
+ *
+ * @hide
+ */
+ @Nullable
+ @SystemApi
+ public byte[] getLeAppearance() {
+ return mLeTemporaryKey;
}
- public void setLeSecureConnectionsConfirmation(byte[] leSecureConnectionsConfirmation) {
- mLeSecureConnectionsConfirmation = leSecureConnectionsConfirmation;
+ /**
+ * @return Flags used to determing discoverable mode to use, BR/EDR Support, and Capability.
+ *
+ * <p>Possible LE Flags:
+ * {@link LE_FLAG_LIMITED_DISCOVERY_MODE} LE Limited Discoverable Mode.
+ * {@link LE_FLAG_GENERAL_DISCOVERY_MODE} LE General Discoverable Mode.
+ * {@link LE_FLAG_BREDR_NOT_SUPPORTED} BR/EDR Not Supported. Bit 37 of
+ * LMP Feature Mask Definitions.
+ * {@link LE_FLAG_SIMULTANEOUS_CONTROLLER} Simultaneous LE and BR/EDR to
+ * Same Device Capable (Controller).
+ * Bit 49 of LMP Feature Mask Definitions.
+ * {@link LE_FLAG_SIMULTANEOUS_HOST} Simultaneous LE and BR/EDR to
+ * Same Device Capable (Host).
+ * Bit 55 of LMP Feature Mask Definitions.
+ * <b>0x05- 0x07 Reserved</b>
+ *
+ * @hide
+ */
+ @NonNull
+ @SystemApi
+ @LeFlag
+ public int getLeFlags() {
+ return mLeFlags;
}
- public byte[] getLeSecureConnectionsRandom() {
- return mLeSecureConnectionsRandom;
+ /**
+ * @return the supported and preferred roles of the LE device.
+ *
+ * <p>Possible Values:
+ * {@link LE_DEVICE_ROLE_PERIPHERAL_ONLY} Only Peripheral supported
+ * {@link LE_DEVICE_ROLE_CENTRAL_ONLY} Only Central supported
+ * {@link LE_DEVICE_ROLE_BOTH_PREFER_PERIPHERAL} Central & Peripheral supported;
+ * Peripheral Preferred
+ * {@link LE_DEVICE_ROLE_BOTH_PREFER_CENTRAL} Only peripheral supported; Central Preferred
+ * 0x04 - 0xFF Reserved
+ *
+ * @hide
+ */
+ @NonNull
+ @SystemApi
+ @LeRole
+ public int getLeDeviceRole() {
+ return mLeDeviceRole;
}
- public void setLeSecureConnectionsRandom(byte[] leSecureConnectionsRandom) {
- mLeSecureConnectionsRandom = leSecureConnectionsRandom;
+ /**
+ * Classic Security Constructor
+ */
+ private OobData(@NonNull byte[] classicLength, @NonNull byte[] deviceAddressWithType,
+ @NonNull byte[] confirmationHash) {
+ mClassicLength = classicLength;
+ mDeviceAddressWithType = deviceAddressWithType;
+ mConfirmationHash = confirmationHash;
+ mLeDeviceRole = -1; // Satisfy final
}
- public OobData() {
+ /**
+ * LE Security Constructor
+ */
+ private OobData(@NonNull byte[] deviceAddressWithType, @LeRole int leDeviceRole,
+ @NonNull byte[] confirmationHash) {
+ mDeviceAddressWithType = deviceAddressWithType;
+ mLeDeviceRole = leDeviceRole;
+ mConfirmationHash = confirmationHash;
+ mClassicLength = new byte[OOB_LENGTH_OCTETS]; // Satisfy final
}
private OobData(Parcel in) {
- mLeBluetoothDeviceAddress = in.createByteArray();
- mSecurityManagerTk = in.createByteArray();
- mLeSecureConnectionsConfirmation = in.createByteArray();
- mLeSecureConnectionsRandom = in.createByteArray();
+ // Both
+ mDeviceAddressWithType = in.createByteArray();
+ mConfirmationHash = in.createByteArray();
+ mRandomizerHash = in.createByteArray();
+ mDeviceName = in.createByteArray();
+
+ // Classic
+ mClassicLength = in.createByteArray();
+ mClassOfDevice = in.createByteArray();
+
+ // LE
+ mLeDeviceRole = in.readInt();
+ mLeTemporaryKey = in.createByteArray();
+ mLeAppearance = in.createByteArray();
+ mLeFlags = in.readInt();
}
+ /**
+ * @hide
+ */
@Override
public int describeContents() {
return 0;
}
+ /**
+ * @hide
+ */
@Override
- public void writeToParcel(Parcel out, int flags) {
- out.writeByteArray(mLeBluetoothDeviceAddress);
- out.writeByteArray(mSecurityManagerTk);
- out.writeByteArray(mLeSecureConnectionsConfirmation);
- out.writeByteArray(mLeSecureConnectionsRandom);
+ public void writeToParcel(@NonNull Parcel out, int flags) {
+ // Both
+ // Required
+ out.writeByteArray(mDeviceAddressWithType);
+ // Required
+ out.writeByteArray(mConfirmationHash);
+ // Optional
+ out.writeByteArray(mRandomizerHash);
+ // Optional
+ out.writeByteArray(mDeviceName);
+
+ // Classic
+ // Required
+ out.writeByteArray(mClassicLength);
+ // Optional
+ out.writeByteArray(mClassOfDevice);
+
+ // LE
+ // Required
+ out.writeInt(mLeDeviceRole);
+ // Required
+ out.writeByteArray(mLeTemporaryKey);
+ // Optional
+ out.writeByteArray(mLeAppearance);
+ // Optional
+ out.writeInt(mLeFlags);
}
+ // For Parcelable
public static final @android.annotation.NonNull Parcelable.Creator<OobData> CREATOR =
new Parcelable.Creator<OobData>() {
public OobData createFromParcel(Parcel in) {
@@ -108,4 +969,47 @@ public class OobData implements Parcelable {
return new OobData[size];
}
};
+
+ /**
+ * @return a {@link String} representation of the OobData object.
+ *
+ * @hide
+ */
+ @Override
+ @NonNull
+ public String toString() {
+ return "OobData: \n\t"
+ // Both
+ + "Device Address With Type: " + toHexString(mDeviceAddressWithType) + "\n\t"
+ + "Confirmation: " + toHexString(mConfirmationHash) + "\n\t"
+ + "Randomizer: " + toHexString(mRandomizerHash) + "\n\t"
+ + "Device Name: " + toHexString(mDeviceName) + "\n\t"
+ // Classic
+ + "OobData Length: " + toHexString(mClassicLength) + "\n\t"
+ + "Class of Device: " + toHexString(mClassOfDevice) + "\n\t"
+ // LE
+ + "LE Device Role: " + toHexString(mLeDeviceRole) + "\n\t"
+ + "LE Temporary Key: " + toHexString(mLeTemporaryKey) + "\n\t"
+ + "LE Appearance: " + toHexString(mLeAppearance) + "\n\t"
+ + "LE Flags: " + toHexString(mLeFlags) + "\n\t";
+ }
+
+ @NonNull
+ private String toHexString(@NonNull int b) {
+ return toHexString(new byte[] {(byte) b});
+ }
+
+ @NonNull
+ private String toHexString(@NonNull byte b) {
+ return toHexString(new byte[] {b});
+ }
+
+ @NonNull
+ private String toHexString(@NonNull byte[] array) {
+ StringBuilder builder = new StringBuilder(array.length * 2);
+ for (byte b: array) {
+ builder.append(String.format("%02x", b));
+ }
+ return builder.toString();
+ }
}
diff --git a/core/java/android/content/Context.java b/core/java/android/content/Context.java
index aa6127904400..fe9ed27a516f 100644
--- a/core/java/android/content/Context.java
+++ b/core/java/android/content/Context.java
@@ -4099,7 +4099,8 @@ public abstract class Context {
* @see #getSystemService(String)
* @hide
*/
- @TestApi public static final String TEST_NETWORK_SERVICE = "test_network";
+ @TestApi @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
+ public static final String TEST_NETWORK_SERVICE = "test_network";
/**
* Use with {@link #getSystemService(String)} to retrieve a {@link
diff --git a/core/java/android/hardware/camera2/CameraManager.java b/core/java/android/hardware/camera2/CameraManager.java
index 7f834afd7b30..933dee3a6470 100644
--- a/core/java/android/hardware/camera2/CameraManager.java
+++ b/core/java/android/hardware/camera2/CameraManager.java
@@ -2024,7 +2024,9 @@ public final class CameraManager {
// Tell listeners that the cameras and torch modes are unavailable and schedule a
// reconnection to camera service. When camera service is reconnected, the camera
// and torch statuses will be updated.
- for (int i = 0; i < mDeviceStatus.size(); i++) {
+ // Iterate from the end to the beginning befcause onStatusChangedLocked removes
+ // entries from the ArrayMap.
+ for (int i = mDeviceStatus.size() - 1; i >= 0; i--) {
String cameraId = mDeviceStatus.keyAt(i);
onStatusChangedLocked(ICameraServiceListener.STATUS_NOT_PRESENT, cameraId);
}
diff --git a/core/java/android/net/INetworkPolicyListener.aidl b/core/java/android/net/INetworkPolicyListener.aidl
index dfb1e996c55a..00c691379187 100644
--- a/core/java/android/net/INetworkPolicyListener.aidl
+++ b/core/java/android/net/INetworkPolicyListener.aidl
@@ -25,4 +25,5 @@ oneway interface INetworkPolicyListener {
void onUidPoliciesChanged(int uid, int uidPolicies);
void onSubscriptionOverride(int subId, int overrideMask, int overrideValue, in int[] networkTypes);
void onSubscriptionPlansChanged(int subId, in SubscriptionPlan[] plans);
+ void onBlockedReasonChanged(int uid, int oldBlockedReason, int newBlockedReason);
}
diff --git a/core/java/android/net/NetworkPolicyManager.java b/core/java/android/net/NetworkPolicyManager.java
index 1c56954a1c36..c544c3275cf3 100644
--- a/core/java/android/net/NetworkPolicyManager.java
+++ b/core/java/android/net/NetworkPolicyManager.java
@@ -23,6 +23,7 @@ import android.annotation.IntDef;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.RequiresPermission;
+import android.annotation.SystemApi;
import android.annotation.SystemService;
import android.annotation.TestApi;
import android.app.ActivityManager;
@@ -44,6 +45,8 @@ import android.util.DebugUtils;
import android.util.Pair;
import android.util.Range;
+import com.android.internal.util.function.pooled.PooledLambda;
+
import com.google.android.collect.Sets;
import java.lang.annotation.Retention;
@@ -53,6 +56,7 @@ import java.util.HashSet;
import java.util.Iterator;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.Executor;
/**
* Manager for creating and modifying network policy rules.
@@ -60,6 +64,7 @@ import java.util.concurrent.ConcurrentHashMap;
* @hide
*/
@TestApi
+@SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
@SystemService(Context.NETWORK_POLICY_SERVICE)
public class NetworkPolicyManager {
@@ -198,12 +203,157 @@ public class NetworkPolicyManager {
})
public @interface SubscriptionOverrideMask {}
+ /**
+ * Flag to indicate that an app is not subject to any restrictions that could result in its
+ * network access blocked.
+ *
+ * @hide
+ */
+ @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
+ public static final int BLOCKED_REASON_NONE = 0;
+
+ /**
+ * Flag to indicate that an app is subject to Battery saver restrictions that would
+ * result in its network access being blocked.
+ *
+ * @hide
+ */
+ @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
+ public static final int BLOCKED_REASON_BATTERY_SAVER = 1 << 0;
+
+ /**
+ * Flag to indicate that an app is subject to Doze restrictions that would
+ * result in its network access being blocked.
+ *
+ * @hide
+ */
+ @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
+ public static final int BLOCKED_REASON_DOZE = 1 << 1;
+
+ /**
+ * Flag to indicate that an app is subject to App Standby restrictions that would
+ * result in its network access being blocked.
+ *
+ * @hide
+ */
+ @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
+ public static final int BLOCKED_REASON_APP_STANDBY = 1 << 2;
+
+ /**
+ * Flag to indicate that an app is subject to Restricted mode restrictions that would
+ * result in its network access being blocked.
+ *
+ * @hide
+ */
+ @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
+ public static final int BLOCKED_REASON_RESTRICTED_MODE = 1 << 3;
+
+ /**
+ * Flag to indicate that an app is subject to Data saver restrictions that would
+ * result in its metered network access being blocked.
+ *
+ * @hide
+ */
+ @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
+ public static final int BLOCKED_METERED_REASON_DATA_SAVER = 1 << 16;
+
+ /**
+ * Flag to indicate that an app is subject to user restrictions that would
+ * result in its metered network access being blocked.
+ *
+ * @hide
+ */
+ @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
+ public static final int BLOCKED_METERED_REASON_USER_RESTRICTED = 1 << 17;
+
+ /**
+ * Flag to indicate that an app is subject to Device admin restrictions that would
+ * result in its metered network access being blocked.
+ *
+ * @hide
+ */
+ @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
+ public static final int BLOCKED_METERED_REASON_ADMIN_DISABLED = 1 << 18;
+
+ /** @hide */
+ public static final int BLOCKED_METERED_REASON_MASK = 0xffff0000;
+
+ /**
+ * Flag to indicate that app is not exempt from any network restrictions.
+ *
+ * @hide
+ */
+ public static final int ALLOWED_REASON_NONE = 0;
+ /**
+ * Flag to indicate that app is exempt from certain network restrictions because of it being a
+ * system component.
+ *
+ * @hide
+ */
+ public static final int ALLOWED_REASON_SYSTEM = 1 << 0;
+ /**
+ * Flag to indicate that app is exempt from certain network restrictions because of it being
+ * in the foreground.
+ *
+ * @hide
+ */
+ public static final int ALLOWED_REASON_FOREGROUND = 1 << 1;
+ /**
+ * Flag to indicate that app is exempt from certain network restrictions because of it being
+ * in the {@code allow-in-power-save} list.
+ *
+ * @hide
+ */
+ public static final int ALLOWED_REASON_POWER_SAVE_ALLOWLIST = 1 << 2;
+ /**
+ * Flag to indicate that app is exempt from certain network restrictions because of it being
+ * in the {@code allow-in-power-save-except-idle} list.
+ *
+ * @hide
+ */
+ public static final int ALLOWED_REASON_POWER_SAVE_EXCEPT_IDLE_ALLOWLIST = 1 << 3;
+ /**
+ * Flag to indicate that app is exempt from certain network restrictions because of it holding
+ * certain privileged permissions.
+ *
+ * @hide
+ */
+ public static final int ALLOWED_REASON_RESTRICTED_MODE_PERMISSIONS = 1 << 4;
+ /**
+ * Flag to indicate that app is exempt from certain metered network restrictions because user
+ * explicitly exempted it.
+ *
+ * @hide
+ */
+ public static final int ALLOWED_METERED_REASON_USER_EXEMPTED = 1 << 16;
+
+ /** @hide */
+ public static final int ALLOWED_METERED_REASON_MASK = 0xffff0000;
+
+ /**
+ * @hide
+ */
+ @Retention(RetentionPolicy.SOURCE)
+ @IntDef(flag = true, prefix = {"BLOCKED_"}, value = {
+ BLOCKED_REASON_NONE,
+ BLOCKED_REASON_BATTERY_SAVER,
+ BLOCKED_REASON_DOZE,
+ BLOCKED_REASON_APP_STANDBY,
+ BLOCKED_REASON_RESTRICTED_MODE,
+ BLOCKED_METERED_REASON_DATA_SAVER,
+ BLOCKED_METERED_REASON_USER_RESTRICTED,
+ BLOCKED_METERED_REASON_ADMIN_DISABLED,
+ })
+ public @interface BlockedReason {}
+
private final Context mContext;
@UnsupportedAppUsage
private INetworkPolicyManager mService;
private final Map<SubscriptionCallback, SubscriptionCallbackProxy>
- mCallbackMap = new ConcurrentHashMap<>();
+ mSubscriptionCallbackMap = new ConcurrentHashMap<>();
+ private final Map<NetworkPolicyCallback, NetworkPolicyCallbackProxy>
+ mNetworkPolicyCallbackMap = new ConcurrentHashMap<>();
/** @hide */
public NetworkPolicyManager(Context context, INetworkPolicyManager service) {
@@ -318,7 +468,7 @@ public class NetworkPolicyManager {
}
final SubscriptionCallbackProxy callbackProxy = new SubscriptionCallbackProxy(callback);
- if (null != mCallbackMap.putIfAbsent(callback, callbackProxy)) {
+ if (null != mSubscriptionCallbackMap.putIfAbsent(callback, callbackProxy)) {
throw new IllegalArgumentException("Callback is already registered.");
}
registerListener(callbackProxy);
@@ -331,7 +481,7 @@ public class NetworkPolicyManager {
throw new NullPointerException("Callback cannot be null.");
}
- final SubscriptionCallbackProxy callbackProxy = mCallbackMap.remove(callback);
+ final SubscriptionCallbackProxy callbackProxy = mSubscriptionCallbackMap.remove(callback);
if (callbackProxy == null) return;
unregisterListener(callbackProxy);
@@ -689,6 +839,142 @@ public class NetworkPolicyManager {
return WifiInfo.sanitizeSsid(ssid);
}
+ /**
+ * Returns whether network access of an UID is blocked or not based on {@code blockedReasons}
+ * corresponding to it.
+ *
+ * {@code blockedReasons} would be a bitwise {@code OR} combination of the
+ * {@code BLOCKED_REASON_*} and/or {@code BLOCKED_METERED_REASON_*} constants.
+ *
+ * @param blockedReasons Value indicating the reasons for why the network access of an UID is
+ * blocked. If the value is equal to {@link #BLOCKED_REASON_NONE}, then
+ * it indicates that an app's network access is not blocked.
+ * @param meteredNetwork Value indicating whether the network is metered or not.
+ * @return Whether network access is blocked or not.
+ * @hide
+ */
+ @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
+ public static boolean isUidBlocked(@BlockedReason int blockedReasons, boolean meteredNetwork) {
+ if (blockedReasons == BLOCKED_REASON_NONE) {
+ return false;
+ }
+ final int blockedOnAllNetworksReason = (blockedReasons & ~BLOCKED_METERED_REASON_MASK);
+ if (blockedOnAllNetworksReason != BLOCKED_REASON_NONE) {
+ return true;
+ }
+ if (meteredNetwork) {
+ return blockedReasons != BLOCKED_REASON_NONE;
+ }
+ return false;
+ }
+
+ /**
+ * Returns the {@code string} representation of {@code blockedReasons} argument.
+ *
+ * @param blockedReasons Value indicating the reasons for why the network access of an UID is
+ * blocked.
+ * @hide
+ */
+ @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
+ @NonNull
+ public static String blockedReasonsToString(@BlockedReason int blockedReasons) {
+ return DebugUtils.flagsToString(NetworkPolicyManager.class, "BLOCKED_", blockedReasons);
+ }
+
+ /**
+ * Register a {@link NetworkPolicyCallback} to listen for changes to network blocked status
+ * of apps.
+ *
+ * Note that when a caller tries to register a new callback, it might replace a previously
+ * registered callback if it is considered equal to the new one, based on the
+ * {@link Object#equals(Object)} check.
+ *
+ * @param executor The {@link Executor} to run the callback on.
+ * @param callback The {@link NetworkPolicyCallback} to be registered.
+ * @hide
+ */
+ @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
+ @RequiresPermission(android.Manifest.permission.OBSERVE_NETWORK_POLICY)
+ public void registerNetworkPolicyCallback(@Nullable Executor executor,
+ @NonNull NetworkPolicyCallback callback) {
+ if (callback == null) {
+ throw new NullPointerException("Callback cannot be null.");
+ }
+
+ final NetworkPolicyCallbackProxy callbackProxy = new NetworkPolicyCallbackProxy(
+ executor, callback);
+ registerListener(callbackProxy);
+ mNetworkPolicyCallbackMap.put(callback, callbackProxy);
+ }
+
+ /**
+ * Unregister a previously registered {@link NetworkPolicyCallback}.
+ *
+ * @param callback The {@link NetworkPolicyCallback} to be unregistered.
+ * @hide
+ */
+ @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
+ @RequiresPermission(android.Manifest.permission.OBSERVE_NETWORK_POLICY)
+ public void unregisterNetworkPolicyCallback(@NonNull NetworkPolicyCallback callback) {
+ if (callback == null) {
+ throw new NullPointerException("Callback cannot be null.");
+ }
+
+ final NetworkPolicyCallbackProxy callbackProxy = mNetworkPolicyCallbackMap.remove(callback);
+ if (callbackProxy == null) return;
+ unregisterListener(callbackProxy);
+ }
+
+ /**
+ * Interface for the callback to listen for changes to network blocked status of apps.
+ *
+ * @hide
+ */
+ @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
+ public interface NetworkPolicyCallback {
+ /**
+ * Called when the reason for why the network access of an UID is blocked changes.
+ *
+ * @param uid The UID for which the blocked status changed.
+ * @param blockedReasons Value indicating the reasons for why the network access of an
+ * UID is blocked.
+ * @hide
+ */
+ @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
+ default void onUidBlockedReasonChanged(int uid, @BlockedReason int blockedReasons) {}
+ }
+
+ /** @hide */
+ public static class NetworkPolicyCallbackProxy extends Listener {
+ private final Executor mExecutor;
+ private final NetworkPolicyCallback mCallback;
+
+ NetworkPolicyCallbackProxy(@Nullable Executor executor,
+ @NonNull NetworkPolicyCallback callback) {
+ mExecutor = executor;
+ mCallback = callback;
+ }
+
+ @Override
+ public void onBlockedReasonChanged(int uid, @BlockedReason int oldBlockedReasons,
+ @BlockedReason int newBlockedReasons) {
+ if (oldBlockedReasons != newBlockedReasons) {
+ dispatchOnUidBlockedReasonChanged(mExecutor, mCallback, uid, newBlockedReasons);
+ }
+ }
+ }
+
+ private static void dispatchOnUidBlockedReasonChanged(@Nullable Executor executor,
+ @NonNull NetworkPolicyCallback callback, int uid, @BlockedReason int blockedReasons) {
+ if (executor == null) {
+ callback.onUidBlockedReasonChanged(uid, blockedReasons);
+ } else {
+ executor.execute(PooledLambda.obtainRunnable(
+ NetworkPolicyCallback::onUidBlockedReasonChanged,
+ callback, uid, blockedReasons).recycleOnUse());
+ }
+ }
+
/** @hide */
public static class SubscriptionCallback {
/**
@@ -743,5 +1029,7 @@ public class NetworkPolicyManager {
@Override public void onSubscriptionOverride(int subId, int overrideMask,
int overrideValue, int[] networkTypes) { }
@Override public void onSubscriptionPlansChanged(int subId, SubscriptionPlan[] plans) { }
+ @Override public void onBlockedReasonChanged(int uid,
+ int oldBlockedReasons, int newBlockedReasons) { }
}
}
diff --git a/core/java/android/provider/Telephony.java b/core/java/android/provider/Telephony.java
index 9cb76c1ffb5d..753abea2cfe2 100644
--- a/core/java/android/provider/Telephony.java
+++ b/core/java/android/provider/Telephony.java
@@ -5284,7 +5284,8 @@ public final class Telephony {
* which network types are allowed for
* {@link TelephonyManager#ALLOWED_NETWORK_TYPES_REASON_USER},
* {@link TelephonyManager#ALLOWED_NETWORK_TYPES_REASON_POWER},
- * {@link TelephonyManager#ALLOWED_NETWORK_TYPES_REASON_CARRIER}.
+ * {@link TelephonyManager#ALLOWED_NETWORK_TYPES_REASON_CARRIER},
+ * {@link TelephonyManager#ALLOWED_NETWORK_TYPES_REASON_ENABLE_2G}.
* <P>Type: TEXT </P>
*
* @hide
diff --git a/core/java/com/android/internal/app/OWNERS b/core/java/com/android/internal/app/OWNERS
index 7ade05cc6de1..e6c911e5b41d 100644
--- a/core/java/com/android/internal/app/OWNERS
+++ b/core/java/com/android/internal/app/OWNERS
@@ -3,6 +3,9 @@ per-file *Resolver* = file:/packages/SystemUI/OWNERS
per-file *Chooser* = file:/packages/SystemUI/OWNERS
per-file SimpleIconFactory.java = file:/packages/SystemUI/OWNERS
per-file NetInitiatedActivity.java = file:/location/java/android/location/OWNERS
-per-file IVoice* = file:/core/java/android/service/voice/OWNERS
-per-file *Hotword* = file:/core/java/android/service/voice/OWNERS
per-file *BatteryStats* = file:/BATTERY_STATS_OWNERS
+
+# Voice Interaction
+per-file *Assist* = file:/core/java/android/service/voice/OWNERS
+per-file *Hotword* = file:/core/java/android/service/voice/OWNERS
+per-file *Voice* = file:/core/java/android/service/voice/OWNERS
diff --git a/core/java/com/android/internal/os/ZygoteInit.java b/core/java/com/android/internal/os/ZygoteInit.java
index c220428df58b..5fea76a7228e 100644
--- a/core/java/com/android/internal/os/ZygoteInit.java
+++ b/core/java/com/android/internal/os/ZygoteInit.java
@@ -41,7 +41,6 @@ import android.os.UserHandle;
import android.os.ZygoteProcess;
import android.os.storage.StorageManager;
import android.provider.DeviceConfig;
-import android.security.keystore.AndroidKeyStoreProvider;
import android.system.ErrnoException;
import android.system.Os;
import android.system.OsConstants;
@@ -74,7 +73,6 @@ import java.io.InputStream;
import java.io.InputStreamReader;
import java.security.Provider;
import java.security.Security;
-import java.util.Optional;
/**
* Startup class for the zygote process.
@@ -227,17 +225,7 @@ public class ZygoteInit {
// AndroidKeyStoreProvider.install() manipulates the list of JCA providers to insert
// preferred providers. Note this is not done via security.properties as the JCA providers
// are not on the classpath in the case of, for example, raw dalvikvm runtimes.
- // TODO b/171305684 This code is used to conditionally enable the installation of the
- // Keystore 2.0 provider to enable teams adjusting to Keystore 2.0 at their own
- // pace. This code will be removed when all calling code was adjusted to
- // Keystore 2.0.
- Optional<Boolean> keystore2_enabled =
- android.sysprop.Keystore2Properties.keystore2_enabled();
- if (keystore2_enabled.isPresent() && keystore2_enabled.get()) {
- android.security.keystore2.AndroidKeyStoreProvider.install();
- } else {
- AndroidKeyStoreProvider.install();
- }
+ android.security.keystore2.AndroidKeyStoreProvider.install();
Log.i(TAG, "Installed AndroidKeyStoreProvider in "
+ (SystemClock.uptimeMillis() - startTime) + "ms.");
Trace.traceEnd(Trace.TRACE_TAG_DALVIK);
diff --git a/core/proto/android/net/networkcapabilities.proto b/core/proto/android/net/networkcapabilities.proto
new file mode 100644
index 000000000000..edb6c0400062
--- /dev/null
+++ b/core/proto/android/net/networkcapabilities.proto
@@ -0,0 +1,118 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+syntax = "proto2";
+
+package android.net;
+
+option java_multiple_files = true;
+
+import "frameworks/base/core/proto/android/privacy.proto";
+import "frameworks/proto_logging/stats/enums/net/enums.proto";
+
+/**
+ * An android.net.NetworkCapabilities object.
+ */
+message NetworkCapabilitiesProto {
+ option (.android.msg_privacy).dest = DEST_AUTOMATIC;
+
+ repeated Transport transports = 1;
+
+ enum NetCapability {
+ // Indicates this is a network that has the ability to reach the
+ // carrier's MMSC for sending and receiving MMS messages.
+ NET_CAPABILITY_MMS = 0;
+ // Indicates this is a network that has the ability to reach the
+ // carrier's SUPL server, used to retrieve GPS information.
+ NET_CAPABILITY_SUPL = 1;
+ // Indicates this is a network that has the ability to reach the
+ // carrier's DUN or tethering gateway.
+ NET_CAPABILITY_DUN = 2;
+ // Indicates this is a network that has the ability to reach the
+ // carrier's FOTA portal, used for over the air updates.
+ NET_CAPABILITY_FOTA = 3;
+ // Indicates this is a network that has the ability to reach the
+ // carrier's IMS servers, used for network registration and signaling.
+ NET_CAPABILITY_IMS = 4;
+ // Indicates this is a network that has the ability to reach the
+ // carrier's CBS servers, used for carrier specific services.
+ NET_CAPABILITY_CBS = 5;
+ // Indicates this is a network that has the ability to reach a Wi-Fi
+ // direct peer.
+ NET_CAPABILITY_WIFI_P2P = 6;
+ // Indicates this is a network that has the ability to reach a carrier's
+ // Initial Attach servers.
+ NET_CAPABILITY_IA = 7;
+ // Indicates this is a network that has the ability to reach a carrier's
+ // RCS servers, used for Rich Communication Services.
+ NET_CAPABILITY_RCS = 8;
+ // Indicates this is a network that has the ability to reach a carrier's
+ // XCAP servers, used for configuration and control.
+ NET_CAPABILITY_XCAP = 9;
+ // Indicates this is a network that has the ability to reach a carrier's
+ // Emergency IMS servers or other services, used for network signaling
+ // during emergency calls.
+ NET_CAPABILITY_EIMS = 10;
+ // Indicates that this network is unmetered.
+ NET_CAPABILITY_NOT_METERED = 11;
+ // Indicates that this network should be able to reach the internet.
+ NET_CAPABILITY_INTERNET = 12;
+ // Indicates that this network is available for general use. If this is
+ // not set applications should not attempt to communicate on this
+ // network. Note that this is simply informative and not enforcement -
+ // enforcement is handled via other means. Set by default.
+ NET_CAPABILITY_NOT_RESTRICTED = 13;
+ // Indicates that the user has indicated implicit trust of this network.
+ // This generally means it's a sim-selected carrier, a plugged in
+ // ethernet, a paired BT device or a wifi the user asked to connect to.
+ // Untrusted networks are probably limited to unknown wifi AP. Set by
+ // default.
+ NET_CAPABILITY_TRUSTED = 14;
+ // Indicates that this network is not a VPN. This capability is set by
+ // default and should be explicitly cleared for VPN networks.
+ NET_CAPABILITY_NOT_VPN = 15;
+ // Indicates that connectivity on this network was successfully
+ // validated. For example, for a network with NET_CAPABILITY_INTERNET,
+ // it means that Internet connectivity was successfully detected.
+ NET_CAPABILITY_VALIDATED = 16;
+ // Indicates that this network was found to have a captive portal in
+ // place last time it was probed.
+ NET_CAPABILITY_CAPTIVE_PORTAL = 17;
+ // Indicates that this network is not roaming.
+ NET_CAPABILITY_NOT_ROAMING = 18;
+ // Indicates that this network is available for use by apps, and not a
+ // network that is being kept up in the background to facilitate fast
+ // network switching.
+ NET_CAPABILITY_FOREGROUND = 19;
+ }
+ repeated NetCapability capabilities = 2;
+
+ // Passive link bandwidth. This is a rough guide of the expected peak
+ // bandwidth for the first hop on the given transport. It is not measured,
+ // but may take into account link parameters (Radio technology, allocated
+ // channels, etc).
+ optional int32 link_up_bandwidth_kbps = 3;
+ optional int32 link_down_bandwidth_kbps = 4;
+
+ optional string network_specifier = 5 [ (.android.privacy).dest = DEST_EXPLICIT ];
+
+ // True if this object specifies a signal strength.
+ optional bool can_report_signal_strength = 6;
+ // This is a signed integer, and higher values indicate better signal. The
+ // exact units are bearer-dependent. For example, Wi-Fi uses RSSI.
+ // Only valid if can_report_signal_strength is true.
+ optional sint32 signal_strength = 7;
+}
diff --git a/core/proto/android/net/networkrequest.proto b/core/proto/android/net/networkrequest.proto
index 0041f199b448..57b9f7162e67 100644
--- a/core/proto/android/net/networkrequest.proto
+++ b/core/proto/android/net/networkrequest.proto
@@ -20,8 +20,8 @@ package android.net;
option java_multiple_files = true;
+import "frameworks/base/core/proto/android/net/networkcapabilities.proto";
import "frameworks/base/core/proto/android/privacy.proto";
-import "frameworks/proto_logging/stats/enums/net/networkcapabilities.proto";
/**
* An android.net.NetworkRequest object.
diff --git a/core/proto/android/os/incident.proto b/core/proto/android/os/incident.proto
index e97b1a8770ed..64cf75d51c3d 100644
--- a/core/proto/android/os/incident.proto
+++ b/core/proto/android/os/incident.proto
@@ -55,13 +55,13 @@ import "frameworks/base/core/proto/android/service/print.proto";
import "frameworks/base/core/proto/android/service/procstats.proto";
import "frameworks/base/core/proto/android/service/restricted_image.proto";
import "frameworks/base/core/proto/android/service/sensor_service.proto";
+import "frameworks/base/core/proto/android/service/usb.proto";
import "frameworks/base/core/proto/android/util/event_log_tags.proto";
import "frameworks/base/core/proto/android/util/log.proto";
import "frameworks/base/core/proto/android/util/textdump.proto";
import "frameworks/base/core/proto/android/privacy.proto";
import "frameworks/base/core/proto/android/section.proto";
import "frameworks/base/proto/src/ipconnectivity.proto";
-import "frameworks/proto_logging/stats/enums/service/usb.proto";
package android.os;
diff --git a/core/proto/android/service/enums.proto b/core/proto/android/service/enums.proto
deleted file mode 100644
index b64e685104b7..000000000000
--- a/core/proto/android/service/enums.proto
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-syntax = "proto2";
-package android.service;
-
-option java_outer_classname = "ServiceProtoEnums";
-option java_multiple_files = true;
-
-enum UsbEndPointType {
- USB_ENDPOINT_TYPE_XFER_CONTROL = 0;
- USB_ENDPOINT_TYPE_XFER_ISOC = 1;
- USB_ENDPOINT_TYPE_XFER_BULK = 2;
- USB_ENDPOINT_TYPE_XFER_INT = 3;
-}
-
-enum UsbEndPointDirection {
- USB_ENDPOINT_DIR_OUT = 0;
- USB_ENDPOINT_DIR_IN = 0x80;
-}
-
-enum UsbConnectionRecordMode {
- USB_CONNECTION_RECORD_MODE_CONNECT = 0;
- USB_CONNECTION_RECORD_MODE_CONNECT_BADPARSE = 1;
- USB_CONNECTION_RECORD_MODE_CONNECT_BADDEVICE = 2;
- USB_CONNECTION_RECORD_MODE_DISCONNECT = -1;
-} \ No newline at end of file
diff --git a/core/proto/android/service/usb.proto b/core/proto/android/service/usb.proto
new file mode 100644
index 000000000000..dd313aa81726
--- /dev/null
+++ b/core/proto/android/service/usb.proto
@@ -0,0 +1,431 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+syntax = "proto2";
+package android.service.usb;
+
+option java_multiple_files = true;
+option java_outer_classname = "UsbServiceProto";
+
+import "frameworks/base/core/proto/android/content/component_name.proto";
+import "frameworks/base/core/proto/android/privacy.proto";
+import "frameworks/proto_logging/stats/enums/service/enums.proto";
+
+message UsbServiceDumpProto {
+ option (android.msg_privacy).dest = DEST_AUTOMATIC;
+
+ optional UsbDeviceManagerProto device_manager = 1;
+ optional UsbHostManagerProto host_manager = 2;
+ optional UsbPortManagerProto port_manager = 3;
+ optional UsbAlsaManagerProto alsa_manager = 4;
+ optional UsbSettingsManagerProto settings_manager = 5;
+ optional UsbPermissionsManagerProto permissions_manager = 6;
+}
+
+message UsbDeviceManagerProto {
+ option (android.msg_privacy).dest = DEST_AUTOMATIC;
+
+ optional UsbHandlerProto handler = 1;
+ optional UsbDebuggingManagerProto debugging_manager = 2;
+}
+
+message UsbHandlerProto {
+ option (android.msg_privacy).dest = DEST_AUTOMATIC;
+
+ /* Same as android.hardware.usb.gadget.V1_0.GadgetFunction.* */
+ enum Function {
+ FUNCTION_ADB = 1;
+ FUNCTION_ACCESSORY = 2;
+ FUNCTION_MTP = 4;
+ FUNCTION_MIDI = 8;
+ FUNCTION_PTP = 16;
+ FUNCTION_RNDIS = 32;
+ FUNCTION_AUDIO_SOURCE = 64;
+ }
+
+ repeated Function current_functions = 1;
+ optional bool current_functions_applied = 2;
+ repeated Function screen_unlocked_functions = 3;
+ optional bool screen_locked = 4;
+ optional bool connected = 5;
+ optional bool configured = 6;
+ optional UsbAccessoryProto current_accessory = 7;
+ optional bool host_connected = 8;
+ optional bool source_power = 9;
+ optional bool sink_power = 10;
+ optional bool usb_charging = 11;
+ optional bool hide_usb_notification = 12;
+ optional bool audio_accessory_connected = 13;
+ optional bool adb_enabled = 14;
+ optional string kernel_state = 15;
+ optional string kernel_function_list = 16;
+}
+
+message UsbAccessoryProto {
+ option (android.msg_privacy).dest = DEST_AUTOMATIC;
+
+ optional string manufacturer = 1;
+ optional string model = 2;
+ // For "classical" USB-accessories the manufacturer bakes this into the
+ // firmware of the device. If an Android phone is configured as accessory, the
+ // app that sets up the accessory side of the connection set this. Either way,
+ // these are part of the detection protocol, and so they cannot be user set or
+ // unique.
+ optional string description = 3;
+ optional string version = 4;
+ optional string uri = 5 [ (android.privacy).dest = DEST_EXPLICIT ];
+ // Non-resettable hardware ID.
+ optional string serial = 6 [ (android.privacy).dest = DEST_LOCAL ];
+}
+
+message UsbDebuggingManagerProto {
+ option (android.msg_privacy).dest = DEST_AUTOMATIC;
+
+ optional bool connected_to_adb = 1;
+ // A workstation that connects to the phone for debugging is identified by
+ // this key.
+ optional string last_key_received = 2 [ (android.privacy).dest = DEST_EXPLICIT ];
+ optional string user_keys = 3 [ (android.privacy).dest = DEST_LOCAL ];
+ optional string system_keys = 4 [ (android.privacy).dest = DEST_LOCAL ];
+}
+
+message UsbHostManagerProto {
+ option (android.msg_privacy).dest = DEST_AUTOMATIC;
+
+ optional android.content.ComponentNameProto default_usb_host_connection_handler = 1;
+ repeated UsbDeviceProto devices = 2;
+ optional int32 num_connects = 3;
+ repeated UsbConnectionRecordProto connections = 4;
+}
+
+message UsbDeviceProto {
+ option (android.msg_privacy).dest = DEST_AUTOMATIC;
+
+ // Generic USB name, not user-provided.
+ optional string name = 1;
+ // ID specific to the vendor, not the device.
+ optional int32 vendor_id = 2;
+ // ID of this product type: Each vendor gives each product a unique ID. E.g.
+ // all mice of the same model would have the same ID.
+ optional int32 product_id = 3;
+ optional int32 class = 4;
+ optional int32 subclass = 5;
+ optional int32 protocol = 6;
+ optional string manufacturer_name = 7;
+ optional string product_name = 8;
+ optional string version = 9;
+ // Non-resettable hardware ID.
+ optional string serial_number = 10 [ (android.privacy).dest = DEST_LOCAL ];
+ repeated UsbConfigurationProto configurations = 11;
+}
+
+message UsbConfigurationProto {
+ option (android.msg_privacy).dest = DEST_AUTOMATIC;
+
+ // A single USB device can have several configurations and the app accessing
+ // the USB device can switch between them. At any time only one can be active.
+ // Each configuration can present completely different interfaces end
+ // endpoints, i.e. a completely different behavior.
+ optional int32 id = 1;
+ // Hardware-defined name, not set by the user.
+ optional string name = 2;
+ optional uint32 attributes = 3;
+ optional int32 max_power = 4;
+ repeated UsbInterfaceProto interfaces = 5;
+}
+
+message UsbInterfaceProto {
+ option (android.msg_privacy).dest = DEST_AUTOMATIC;
+
+ // Hardware defined. This is the id used by the app to identify the interface.
+ optional int32 id = 1;
+ optional int32 alternate_settings = 2;
+ optional string name = 3;
+ optional int32 class = 4;
+ optional int32 subclass = 5;
+ optional int32 protocol = 6;
+ repeated UsbEndPointProto endpoints = 7;
+}
+
+message UsbEndPointProto {
+ option (android.msg_privacy).dest = DEST_AUTOMATIC;
+
+ optional int32 endpoint_number = 1;
+ optional android.service.UsbEndPointDirection direction = 2;
+ // The address of the endpoint. Needed to read and write to the endpoint.
+ optional int32 address = 3;
+ optional android.service.UsbEndPointType type = 4;
+ optional uint32 attributes = 5;
+ optional int32 max_packet_size = 6;
+ optional int32 interval = 7;
+}
+
+message UsbConnectionRecordProto {
+ option (android.msg_privacy).dest = DEST_AUTOMATIC;
+
+ // usb device's address, e.g. 001/002, nothing about the phone
+ optional string device_address = 1;
+ optional android.service.UsbConnectionRecordMode mode = 2;
+ optional int64 timestamp = 3;
+ optional int32 manufacturer = 4;
+ optional int32 product = 5;
+ optional UsbIsHeadsetProto is_headset = 6;
+}
+
+message UsbIsHeadsetProto {
+ option (android.msg_privacy).dest = DEST_AUTOMATIC;
+
+ optional bool in = 1;
+ optional bool out = 2;
+}
+
+message UsbPortManagerProto {
+ option (android.msg_privacy).dest = DEST_AUTOMATIC;
+
+ optional bool is_simulation_active = 1;
+ repeated UsbPortInfoProto usb_ports = 2;
+}
+
+message UsbPortInfoProto {
+ option (android.msg_privacy).dest = DEST_AUTOMATIC;
+
+ optional UsbPortProto port = 1;
+ optional UsbPortStatusProto status = 2;
+ optional bool can_change_mode = 3;
+ optional bool can_change_power_role = 4;
+ optional bool can_change_data_role = 5;
+ optional int64 connected_at_millis = 6;
+ optional int64 last_connect_duration_millis = 7;
+}
+
+message UsbPortProto {
+ option (android.msg_privacy).dest = DEST_AUTOMATIC;
+
+ /* Same as android.hardware.usb.V1_1.Constants.PortMode_1_1 */
+ enum Mode {
+ MODE_NONE = 0;
+ MODE_UFP = 1;
+ MODE_DFP = 2;
+ MODE_DRP = 3;
+ MODE_AUDIO_ACCESSORY = 4;
+ MODE_DEBUG_ACCESSORY = 8;
+ }
+
+ // ID of the port. A device (eg: Chromebooks) might have multiple ports.
+ optional string id = 1;
+ repeated Mode supported_modes = 2;
+}
+
+message UsbPortStatusProto {
+ option (android.msg_privacy).dest = DEST_AUTOMATIC;
+
+ /* Same as android.hardware.usb.V1_0.Constants.PortPowerRole */
+ enum PowerRole {
+ POWER_ROLE_NONE = 0;
+ POWER_ROLE_SOURCE = 1;
+ POWER_ROLE_SINK = 2;
+ }
+
+ /* Same as android.hardware.usb.V1_0.Constants.PortDataRole */
+ enum DataRole {
+ DATA_ROLE_NONE = 0;
+ DATA_ROLE_HOST = 1;
+ DATA_ROLE_DEVICE = 2;
+ }
+
+ optional bool connected = 1;
+ optional UsbPortProto.Mode current_mode = 2;
+ optional PowerRole power_role = 3;
+ optional DataRole data_role = 4;
+ repeated UsbPortStatusRoleCombinationProto role_combinations = 5;
+ optional android.service.ContaminantPresenceStatus contaminant_presence_status = 6;
+}
+
+message UsbPortStatusRoleCombinationProto {
+ option (android.msg_privacy).dest = DEST_AUTOMATIC;
+
+ optional UsbPortStatusProto.PowerRole power_role = 1;
+ optional UsbPortStatusProto.DataRole data_role = 2;
+}
+
+message UsbAlsaManagerProto {
+ option (android.msg_privacy).dest = DEST_AUTOMATIC;
+
+ optional int32 cards_parser = 1;
+ repeated UsbAlsaDeviceProto alsa_devices = 2;
+ repeated UsbMidiDeviceProto midi_devices = 3;
+}
+
+message UsbAlsaDeviceProto {
+ option (android.msg_privacy).dest = DEST_AUTOMATIC;
+
+ optional int32 card = 1;
+ optional int32 device = 2;
+ optional string name = 3;
+ optional bool has_playback = 4;
+ optional bool has_capture = 5;
+ // usb device's address, e.g. 001/002, nothing about the phone
+ optional string address = 6;
+}
+
+message UsbMidiDeviceProto {
+ option (android.msg_privacy).dest = DEST_AUTOMATIC;
+
+ optional int32 card = 1;
+ optional int32 device = 2;
+ // usb device's address, e.g. 001/002, nothing about the phone
+ optional string device_address = 3;
+}
+
+message UsbSettingsManagerProto {
+ option (android.msg_privacy).dest = DEST_AUTOMATIC;
+
+ repeated UsbUserSettingsManagerProto user_settings = 1;
+ repeated UsbProfileGroupSettingsManagerProto profile_group_settings = 2;
+}
+
+message UsbUserSettingsManagerProto {
+ option (android.msg_privacy).dest = DEST_AUTOMATIC;
+
+ optional int32 user_id = 1;
+ reserved 2; // previously device_permissions, now unused
+ reserved 3; // previously accessory_permissions, now unused
+ repeated UsbDeviceAttachedActivities device_attached_activities = 4;
+ repeated UsbAccessoryAttachedActivities accessory_attached_activities = 5;
+}
+
+message UsbProfileGroupSettingsManagerProto {
+ option (android.msg_privacy).dest = DEST_AUTOMATIC;
+
+ // The user id of the personal profile if the device has a work profile.
+ optional int32 parent_user_id = 1;
+ repeated UsbSettingsDevicePreferenceProto device_preferences = 2;
+ repeated UsbSettingsAccessoryPreferenceProto accessory_preferences = 3;
+}
+
+message UsbSettingsDevicePreferenceProto {
+ option (android.msg_privacy).dest = DEST_AUTOMATIC;
+
+ optional UsbDeviceFilterProto filter = 1;
+ optional UserPackageProto user_package = 2;
+}
+
+message UsbPermissionsManagerProto {
+ option (android.msg_privacy).dest = DEST_AUTOMATIC;
+
+ repeated UsbUserPermissionsManagerProto user_permissions = 1;
+}
+
+message UsbUserPermissionsManagerProto {
+ option (android.msg_privacy).dest = DEST_AUTOMATIC;
+
+ optional int32 user_id = 1;
+
+ repeated UsbDevicePermissionProto device_permissions = 2;
+ repeated UsbAccessoryPermissionProto accessory_permissions = 3;
+
+ repeated UsbDevicePersistentPermissionProto device_persistent_permissions = 4;
+ repeated UsbAccessoryPersistentPermissionProto accessory_persistent_permissions = 5;
+}
+
+message UsbDevicePermissionProto {
+ option (android.msg_privacy).dest = DEST_AUTOMATIC;
+
+ // Name of device set by manufacturer
+ // All devices of the same model have the same name
+ optional string device_name = 1;
+ repeated int32 uids = 2;
+}
+
+message UsbAccessoryPermissionProto {
+ option (android.msg_privacy).dest = DEST_AUTOMATIC;
+
+ // Description of accessory set by manufacturer
+ // All accessories of the same model have the same description
+ optional string accessory_description = 1;
+ repeated int32 uids = 2;
+}
+
+message UsbDevicePersistentPermissionProto {
+ option (android.msg_privacy).dest = DEST_AUTOMATIC;
+
+ optional UsbDeviceFilterProto device_filter = 1;
+ repeated UsbUidPermissionProto permission_values = 2;
+}
+
+message UsbAccessoryPersistentPermissionProto {
+ option (android.msg_privacy).dest = DEST_AUTOMATIC;
+
+ optional UsbAccessoryFilterProto accessory_filter = 1;
+ repeated UsbUidPermissionProto permission_values = 2;
+}
+
+message UsbUidPermissionProto {
+ option (android.msg_privacy).dest = DEST_AUTOMATIC;
+
+ optional int32 uid = 1;
+ optional bool is_granted = 2;
+}
+
+message UsbDeviceFilterProto {
+ option (android.msg_privacy).dest = DEST_AUTOMATIC;
+
+ // Mirrors the vendor_id of UsbDeviceProto.
+ optional int32 vendor_id = 1;
+ optional int32 product_id = 2;
+ optional int32 class = 3;
+ optional int32 subclass = 4;
+ optional int32 protocol = 5;
+ optional string manufacturer_name = 6;
+ optional string product_name = 7;
+ optional string serial_number = 8 [ (android.privacy).dest = DEST_EXPLICIT ];
+}
+
+message UserPackageProto {
+ option (android.msg_privacy).dest = DEST_AUTOMATIC;
+
+ optional int32 user_id = 1;
+ optional string package_name =2;
+}
+
+message UsbSettingsAccessoryPreferenceProto {
+ option (android.msg_privacy).dest = DEST_AUTOMATIC;
+
+ optional UsbAccessoryFilterProto filter = 1;
+ optional UserPackageProto user_package = 2;
+}
+
+message UsbAccessoryFilterProto {
+ option (android.msg_privacy).dest = DEST_AUTOMATIC;
+
+ optional string manufacturer = 1;
+ optional string model = 2;
+ optional string version = 3;
+}
+
+message UsbDeviceAttachedActivities {
+ option (android.msg_privacy).dest = DEST_AUTOMATIC;
+
+ optional android.content.ComponentNameProto activity = 1;
+ repeated UsbDeviceFilterProto filters = 2;
+}
+
+message UsbAccessoryAttachedActivities {
+ option (android.msg_privacy).dest = DEST_AUTOMATIC;
+
+ optional android.content.ComponentNameProto activity = 1;
+ repeated UsbAccessoryFilterProto filters = 2;
+}
diff --git a/keystore/java/android/security/keystore2/AndroidKeyStoreCipherSpiBase.java b/keystore/java/android/security/keystore2/AndroidKeyStoreCipherSpiBase.java
index 2ee952cbc5fb..9d8a5effc2d7 100644
--- a/keystore/java/android/security/keystore2/AndroidKeyStoreCipherSpiBase.java
+++ b/keystore/java/android/security/keystore2/AndroidKeyStoreCipherSpiBase.java
@@ -123,8 +123,9 @@ abstract class AndroidKeyStoreCipherSpiBase extends CipherSpi implements KeyStor
throws InvalidKeyException {
resetAll();
- if (!(key instanceof AndroidKeyStorePrivateKey
- || key instanceof AndroidKeyStoreSecretKey)) {
+ // Public key operations get diverted to the default provider.
+ if (!(key instanceof AndroidKeyStorePrivateKey)
+ && (key instanceof PrivateKey || key instanceof PublicKey)) {
try {
mCipher = Cipher.getInstance(getTransform());
String transform = getTransform();
@@ -184,8 +185,9 @@ abstract class AndroidKeyStoreCipherSpiBase extends CipherSpi implements KeyStor
SecureRandom random) throws InvalidKeyException, InvalidAlgorithmParameterException {
resetAll();
- if (!(key instanceof AndroidKeyStorePrivateKey
- || key instanceof AndroidKeyStoreSecretKey)) {
+ // Public key operations get diverted to the default provider.
+ if (!(key instanceof AndroidKeyStorePrivateKey)
+ && (key instanceof PrivateKey || key instanceof PublicKey)) {
try {
mCipher = Cipher.getInstance(getTransform());
mCipher.init(opmode, key, params, random);
@@ -213,8 +215,9 @@ abstract class AndroidKeyStoreCipherSpiBase extends CipherSpi implements KeyStor
SecureRandom random) throws InvalidKeyException, InvalidAlgorithmParameterException {
resetAll();
- if (!(key instanceof AndroidKeyStorePrivateKey
- || key instanceof AndroidKeyStoreSecretKey)) {
+ // Public key operations get diverted to the default provider.
+ if (!(key instanceof AndroidKeyStorePrivateKey)
+ && (key instanceof PrivateKey || key instanceof PublicKey)) {
try {
mCipher = Cipher.getInstance(getTransform());
mCipher.init(opmode, key, params, random);
diff --git a/keystore/java/android/security/keystore2/AndroidKeyStoreProvider.java b/keystore/java/android/security/keystore2/AndroidKeyStoreProvider.java
index fa852e33a1d8..ba6d22f681ce 100644
--- a/keystore/java/android/security/keystore2/AndroidKeyStoreProvider.java
+++ b/keystore/java/android/security/keystore2/AndroidKeyStoreProvider.java
@@ -145,23 +145,15 @@ public class AndroidKeyStoreProvider extends Provider {
sInstalled = true;
Security.addProvider(new AndroidKeyStoreProvider());
- Security.addProvider(
- new android.security.keystore.AndroidKeyStoreProvider(
- "AndroidKeyStoreLegacy"));
Provider workaroundProvider = new AndroidKeyStoreBCWorkaroundProvider();
- Provider legacyWorkaroundProvider =
- new android.security.keystore.AndroidKeyStoreBCWorkaroundProvider(
- "AndroidKeyStoreBCWorkaroundLegacy");
if (bcProviderIndex != -1) {
// Bouncy Castle provider found -- install the workaround provider above it.
// insertProviderAt uses 1-based positions.
- Security.insertProviderAt(legacyWorkaroundProvider, bcProviderIndex + 1);
Security.insertProviderAt(workaroundProvider, bcProviderIndex + 1);
} else {
// Bouncy Castle provider not found -- install the workaround provider at lowest
// priority.
Security.addProvider(workaroundProvider);
- Security.addProvider(legacyWorkaroundProvider);
}
}
diff --git a/media/jni/Android.bp b/media/jni/Android.bp
index f65dfddef008..517e192e00af 100644
--- a/media/jni/Android.bp
+++ b/media/jni/Android.bp
@@ -19,6 +19,7 @@ cc_library_shared {
name: "libmedia_jni",
defaults: ["libcodec2-internal-defaults"],
+ min_sdk_version: "",
srcs: [
"android_media_ImageWriter.cpp",
diff --git a/packages/CarrierDefaultApp/src/com/android/carrierdefaultapp/CaptivePortalLoginActivity.java b/packages/CarrierDefaultApp/src/com/android/carrierdefaultapp/CaptivePortalLoginActivity.java
index 6fab9e4641b6..550e324733d9 100644
--- a/packages/CarrierDefaultApp/src/com/android/carrierdefaultapp/CaptivePortalLoginActivity.java
+++ b/packages/CarrierDefaultApp/src/com/android/carrierdefaultapp/CaptivePortalLoginActivity.java
@@ -86,7 +86,7 @@ public class CaptivePortalLoginActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
- mCm = ConnectivityManager.from(this);
+ mCm = getSystemService(ConnectivityManager.class);
mUrl = getUrlForCaptivePortal();
if (mUrl == null) {
done(false);
@@ -161,7 +161,6 @@ public class CaptivePortalLoginActivity extends Activity {
if (network != null) {
network = network.getPrivateDnsBypassingCopy();
mCm.bindProcessToNetwork(network);
- mCm.setProcessDefaultNetworkForHostResolution(network);
}
mNetwork = network;
}
diff --git a/packages/CarrierDefaultApp/src/com/android/carrierdefaultapp/ProvisionObserver.java b/packages/CarrierDefaultApp/src/com/android/carrierdefaultapp/ProvisionObserver.java
index 78a02d71fc9f..43ca7393abfc 100644
--- a/packages/CarrierDefaultApp/src/com/android/carrierdefaultapp/ProvisionObserver.java
+++ b/packages/CarrierDefaultApp/src/com/android/carrierdefaultapp/ProvisionObserver.java
@@ -49,7 +49,7 @@ public class ProvisionObserver extends JobService {
case PROVISION_OBSERVER_REEVALUATION_JOB_ID:
if (isProvisioned(this)) {
Log.d(TAG, "device provisioned, force network re-evaluation");
- final ConnectivityManager connMgr = ConnectivityManager.from(this);
+ final ConnectivityManager connMgr = getSystemService(ConnectivityManager.class);
Network[] info = connMgr.getAllNetworks();
for (Network nw : info) {
final NetworkCapabilities nc = connMgr.getNetworkCapabilities(nw);
diff --git a/core/java/android/net/NetworkScore.aidl b/packages/Connectivity/framework/aidl-export/android/net/NetworkScore.aidl
index af12dcf7f17a..af12dcf7f17a 100644
--- a/core/java/android/net/NetworkScore.aidl
+++ b/packages/Connectivity/framework/aidl-export/android/net/NetworkScore.aidl
diff --git a/packages/Connectivity/framework/api/current.txt b/packages/Connectivity/framework/api/current.txt
index f22d4b7b779a..e415e01fea3a 100644
--- a/packages/Connectivity/framework/api/current.txt
+++ b/packages/Connectivity/framework/api/current.txt
@@ -291,6 +291,7 @@ package android.net {
ctor public NetworkCapabilities();
ctor public NetworkCapabilities(android.net.NetworkCapabilities);
method public int describeContents();
+ method @NonNull public int[] getCapabilities();
method public int getLinkDownstreamBandwidthKbps();
method public int getLinkUpstreamBandwidthKbps();
method @Nullable public android.net.NetworkSpecifier getNetworkSpecifier();
diff --git a/packages/Connectivity/framework/api/module-lib-current.txt b/packages/Connectivity/framework/api/module-lib-current.txt
index 7a91f6454b90..8629c1971b7b 100644
--- a/packages/Connectivity/framework/api/module-lib-current.txt
+++ b/packages/Connectivity/framework/api/module-lib-current.txt
@@ -19,6 +19,7 @@ package android.net {
method @RequiresPermission(android.Manifest.permission.NETWORK_STACK) public void setGlobalProxy(@Nullable android.net.ProxyInfo);
method @RequiresPermission(android.Manifest.permission.NETWORK_STACK) public void setProfileNetworkPreference(@NonNull android.os.UserHandle, int, @Nullable java.util.concurrent.Executor, @Nullable Runnable);
method @RequiresPermission(anyOf={android.Manifest.permission.MANAGE_TEST_NETWORKS, android.Manifest.permission.NETWORK_STACK}) public void simulateDataStall(int, long, @NonNull android.net.Network, @NonNull android.os.PersistableBundle);
+ method @RequiresPermission(anyOf={android.Manifest.permission.NETWORK_SETTINGS, android.Manifest.permission.NETWORK_STACK, android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK}) public void startCaptivePortalApp(@NonNull android.net.Network);
method public void systemReady();
field public static final String PRIVATE_DNS_MODE_OFF = "off";
field public static final String PRIVATE_DNS_MODE_OPPORTUNISTIC = "opportunistic";
diff --git a/packages/Connectivity/framework/api/system-current.txt b/packages/Connectivity/framework/api/system-current.txt
index 031bb916c4f2..884522582352 100644
--- a/packages/Connectivity/framework/api/system-current.txt
+++ b/packages/Connectivity/framework/api/system-current.txt
@@ -18,7 +18,7 @@ package android.net {
method public long getRefreshTimeMillis();
method @Nullable public android.net.Uri getUserPortalUrl();
method public int getUserPortalUrlSource();
- method @Nullable public String getVenueFriendlyName();
+ method @Nullable public CharSequence getVenueFriendlyName();
method @Nullable public android.net.Uri getVenueInfoUrl();
method public int getVenueInfoUrlSource();
method public boolean isCaptive();
@@ -40,7 +40,7 @@ package android.net {
method @NonNull public android.net.CaptivePortalData.Builder setSessionExtendable(boolean);
method @NonNull public android.net.CaptivePortalData.Builder setUserPortalUrl(@Nullable android.net.Uri);
method @NonNull public android.net.CaptivePortalData.Builder setUserPortalUrl(@Nullable android.net.Uri, int);
- method @NonNull public android.net.CaptivePortalData.Builder setVenueFriendlyName(@Nullable String);
+ method @NonNull public android.net.CaptivePortalData.Builder setVenueFriendlyName(@Nullable CharSequence);
method @NonNull public android.net.CaptivePortalData.Builder setVenueInfoUrl(@Nullable android.net.Uri);
method @NonNull public android.net.CaptivePortalData.Builder setVenueInfoUrl(@Nullable android.net.Uri, int);
}
diff --git a/packages/Connectivity/framework/src/android/net/CaptivePortalData.java b/packages/Connectivity/framework/src/android/net/CaptivePortalData.java
index eafda4d2d694..82dbd0fb1f87 100644
--- a/packages/Connectivity/framework/src/android/net/CaptivePortalData.java
+++ b/packages/Connectivity/framework/src/android/net/CaptivePortalData.java
@@ -42,7 +42,7 @@ public final class CaptivePortalData implements Parcelable {
private final long mByteLimit;
private final long mExpiryTimeMillis;
private final boolean mCaptive;
- private final String mVenueFriendlyName;
+ private final CharSequence mVenueFriendlyName;
private final int mVenueInfoUrlSource;
private final int mUserPortalUrlSource;
@@ -65,7 +65,7 @@ public final class CaptivePortalData implements Parcelable {
private CaptivePortalData(long refreshTimeMillis, Uri userPortalUrl, Uri venueInfoUrl,
boolean isSessionExtendable, long byteLimit, long expiryTimeMillis, boolean captive,
- String venueFriendlyName, int venueInfoUrlSource, int userPortalUrlSource) {
+ CharSequence venueFriendlyName, int venueInfoUrlSource, int userPortalUrlSource) {
mRefreshTimeMillis = refreshTimeMillis;
mUserPortalUrl = userPortalUrl;
mVenueInfoUrl = venueInfoUrl;
@@ -80,7 +80,7 @@ public final class CaptivePortalData implements Parcelable {
private CaptivePortalData(Parcel p) {
this(p.readLong(), p.readParcelable(null), p.readParcelable(null), p.readBoolean(),
- p.readLong(), p.readLong(), p.readBoolean(), p.readString(), p.readInt(),
+ p.readLong(), p.readLong(), p.readBoolean(), p.readCharSequence(), p.readInt(),
p.readInt());
}
@@ -98,7 +98,7 @@ public final class CaptivePortalData implements Parcelable {
dest.writeLong(mByteLimit);
dest.writeLong(mExpiryTimeMillis);
dest.writeBoolean(mCaptive);
- dest.writeString(mVenueFriendlyName);
+ dest.writeCharSequence(mVenueFriendlyName);
dest.writeInt(mVenueInfoUrlSource);
dest.writeInt(mUserPortalUrlSource);
}
@@ -114,7 +114,7 @@ public final class CaptivePortalData implements Parcelable {
private long mBytesRemaining = -1;
private long mExpiryTime = -1;
private boolean mCaptive;
- private String mVenueFriendlyName;
+ private CharSequence mVenueFriendlyName;
private @CaptivePortalDataSource int mVenueInfoUrlSource = CAPTIVE_PORTAL_DATA_SOURCE_OTHER;
private @CaptivePortalDataSource int mUserPortalUrlSource =
CAPTIVE_PORTAL_DATA_SOURCE_OTHER;
@@ -228,7 +228,7 @@ public final class CaptivePortalData implements Parcelable {
* Set the venue friendly name.
*/
@NonNull
- public Builder setVenueFriendlyName(@Nullable String venueFriendlyName) {
+ public Builder setVenueFriendlyName(@Nullable CharSequence venueFriendlyName) {
mVenueFriendlyName = venueFriendlyName;
return this;
}
@@ -321,7 +321,7 @@ public final class CaptivePortalData implements Parcelable {
* Get the venue friendly name
*/
@Nullable
- public String getVenueFriendlyName() {
+ public CharSequence getVenueFriendlyName() {
return mVenueFriendlyName;
}
diff --git a/packages/Connectivity/framework/src/android/net/ConnectivityManager.java b/packages/Connectivity/framework/src/android/net/ConnectivityManager.java
index 786ed240e39e..e32622391cda 100644
--- a/packages/Connectivity/framework/src/android/net/ConnectivityManager.java
+++ b/packages/Connectivity/framework/src/android/net/ConnectivityManager.java
@@ -4461,12 +4461,20 @@ public class ConnectivityManager {
/**
* Requests that the system open the captive portal app on the specified network.
*
+ * <p>This is to be used on networks where a captive portal was detected, as per
+ * {@link NetworkCapabilities#NET_CAPABILITY_CAPTIVE_PORTAL}.
+ *
* @param network The network to log into.
*
* @hide
*/
- @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS)
- public void startCaptivePortalApp(Network network) {
+ @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
+ @RequiresPermission(anyOf = {
+ android.Manifest.permission.NETWORK_SETTINGS,
+ android.Manifest.permission.NETWORK_STACK,
+ NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK
+ })
+ public void startCaptivePortalApp(@NonNull Network network) {
try {
mService.startCaptivePortalApp(network);
} catch (RemoteException e) {
@@ -4661,7 +4669,7 @@ public class ConnectivityManager {
Log.e(TAG, "Can't set proxy properties", e);
}
// Must flush DNS cache as new network may have different DNS resolutions.
- InetAddress.clearDnsCache();
+ InetAddressCompat.clearDnsCache();
// Must flush socket pool as idle sockets will be bound to previous network and may
// cause subsequent fetches to be performed on old network.
NetworkEventDispatcher.getInstance().onNetworkConfigurationChanged();
diff --git a/core/java/android/net/IOnCompleteListener.aidl b/packages/Connectivity/framework/src/android/net/IOnCompleteListener.aidl
index 4bb89f6c89e4..4bb89f6c89e4 100644
--- a/core/java/android/net/IOnCompleteListener.aidl
+++ b/packages/Connectivity/framework/src/android/net/IOnCompleteListener.aidl
diff --git a/packages/Connectivity/framework/src/android/net/InetAddressCompat.java b/packages/Connectivity/framework/src/android/net/InetAddressCompat.java
new file mode 100644
index 000000000000..6b7e75c75359
--- /dev/null
+++ b/packages/Connectivity/framework/src/android/net/InetAddressCompat.java
@@ -0,0 +1,88 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.net;
+
+import android.util.Log;
+
+import java.lang.reflect.InvocationTargetException;
+import java.net.InetAddress;
+import java.net.UnknownHostException;
+
+/**
+ * Compatibility utility for InetAddress core platform APIs.
+ *
+ * Connectivity has access to such APIs, but they are not part of the module_current stubs yet
+ * (only core_current). Most stable core platform APIs are included manually in the connectivity
+ * build rules, but because InetAddress is also part of the base java SDK that is earlier on the
+ * classpath, the extra core platform APIs are not seen.
+ *
+ * TODO (b/183097033): remove this utility as soon as core_current is part of module_current
+ * @hide
+ */
+public class InetAddressCompat {
+
+ /**
+ * @see InetAddress#clearDnsCache()
+ */
+ public static void clearDnsCache() {
+ try {
+ InetAddress.class.getMethod("clearDnsCache").invoke(null);
+ } catch (InvocationTargetException e) {
+ if (e.getCause() instanceof RuntimeException) {
+ throw (RuntimeException) e.getCause();
+ }
+ throw new IllegalStateException("Unknown InvocationTargetException", e.getCause());
+ } catch (IllegalAccessException | NoSuchMethodException e) {
+ Log.wtf(InetAddressCompat.class.getSimpleName(), "Error clearing DNS cache", e);
+ }
+ }
+
+ /**
+ * @see InetAddress#getAllByNameOnNet(String, int)
+ */
+ public static InetAddress[] getAllByNameOnNet(String host, int netId) throws
+ UnknownHostException {
+ return (InetAddress[]) callGetByNameMethod("getAllByNameOnNet", host, netId);
+ }
+
+ /**
+ * @see InetAddress#getByNameOnNet(String, int)
+ */
+ public static InetAddress getByNameOnNet(String host, int netId) throws
+ UnknownHostException {
+ return (InetAddress) callGetByNameMethod("getByNameOnNet", host, netId);
+ }
+
+ private static Object callGetByNameMethod(String method, String host, int netId)
+ throws UnknownHostException {
+ try {
+ return InetAddress.class.getMethod(method, String.class, int.class)
+ .invoke(null, host, netId);
+ } catch (InvocationTargetException e) {
+ if (e.getCause() instanceof UnknownHostException) {
+ throw (UnknownHostException) e.getCause();
+ }
+ if (e.getCause() instanceof RuntimeException) {
+ throw (RuntimeException) e.getCause();
+ }
+ throw new IllegalStateException("Unknown InvocationTargetException", e.getCause());
+ } catch (IllegalAccessException | NoSuchMethodException e) {
+ Log.wtf(InetAddressCompat.class.getSimpleName(), "Error calling " + method, e);
+ throw new IllegalStateException("Error querying via " + method, e);
+ }
+ }
+}
diff --git a/packages/Connectivity/framework/src/android/net/Network.java b/packages/Connectivity/framework/src/android/net/Network.java
index 7245db3b17db..0741414ab3aa 100644
--- a/packages/Connectivity/framework/src/android/net/Network.java
+++ b/packages/Connectivity/framework/src/android/net/Network.java
@@ -142,7 +142,7 @@ public class Network implements Parcelable {
* @throws UnknownHostException if the address lookup fails.
*/
public InetAddress[] getAllByName(String host) throws UnknownHostException {
- return InetAddress.getAllByNameOnNet(host, getNetIdForResolv());
+ return InetAddressCompat.getAllByNameOnNet(host, getNetIdForResolv());
}
/**
@@ -155,7 +155,7 @@ public class Network implements Parcelable {
* if the address lookup fails.
*/
public InetAddress getByName(String host) throws UnknownHostException {
- return InetAddress.getByNameOnNet(host, getNetIdForResolv());
+ return InetAddressCompat.getByNameOnNet(host, getNetIdForResolv());
}
/**
diff --git a/packages/Connectivity/framework/src/android/net/NetworkAgentConfig.java b/packages/Connectivity/framework/src/android/net/NetworkAgentConfig.java
index 664c2650ff0c..5e50a6404acb 100644
--- a/packages/Connectivity/framework/src/android/net/NetworkAgentConfig.java
+++ b/packages/Connectivity/framework/src/android/net/NetworkAgentConfig.java
@@ -50,7 +50,8 @@ public final class NetworkAgentConfig implements Parcelable {
* ap in the wifi settings to trigger a connection is explicit. A 3rd party app asking to
* connect to a particular access point is also explicit, though this may change in the future
* as we want apps to use the multinetwork apis.
- *
+ * TODO : this is a bad name, because it sounds like the user just tapped on the network.
+ * It's not necessarily the case ; auto-reconnection to WiFi has this true for example.
* @hide
*/
public boolean explicitlySelected;
diff --git a/packages/Connectivity/framework/src/android/net/NetworkCapabilities.java b/packages/Connectivity/framework/src/android/net/NetworkCapabilities.java
index 058f3c999dd7..5ec7aa1b23ac 100644
--- a/packages/Connectivity/framework/src/android/net/NetworkCapabilities.java
+++ b/packages/Connectivity/framework/src/android/net/NetworkCapabilities.java
@@ -609,10 +609,8 @@ public final class NetworkCapabilities implements Parcelable {
* Gets all the capabilities set on this {@code NetworkCapability} instance.
*
* @return an array of capability values for this instance.
- * @hide
*/
- @UnsupportedAppUsage
- public @NetCapability int[] getCapabilities() {
+ public @NonNull @NetCapability int[] getCapabilities() {
return NetworkCapabilitiesUtils.unpackBits(mNetworkCapabilities);
}
diff --git a/core/java/android/net/NetworkScore.java b/packages/Connectivity/framework/src/android/net/NetworkScore.java
index f47801002296..eadcb2d0a7f4 100644
--- a/core/java/android/net/NetworkScore.java
+++ b/packages/Connectivity/framework/src/android/net/NetworkScore.java
@@ -20,6 +20,8 @@ import android.annotation.NonNull;
import android.os.Parcel;
import android.os.Parcelable;
+import com.android.internal.annotations.VisibleForTesting;
+
/**
* Object representing the quality of a network as perceived by the user.
*
@@ -33,19 +35,39 @@ public final class NetworkScore implements Parcelable {
// a migration.
private final int mLegacyInt;
+ // Agent-managed policies
+ // TODO : add them here, starting from 1
+ /** @hide */
+ public static final int MIN_AGENT_MANAGED_POLICY = 0;
+ /** @hide */
+ public static final int MAX_AGENT_MANAGED_POLICY = -1;
+
+ // Bitmask of all the policies applied to this score.
+ private final long mPolicies;
+
/** @hide */
- NetworkScore(final int legacyInt) {
- this.mLegacyInt = legacyInt;
+ NetworkScore(final int legacyInt, final long policies) {
+ mLegacyInt = legacyInt;
+ mPolicies = policies;
}
private NetworkScore(@NonNull final Parcel in) {
mLegacyInt = in.readInt();
+ mPolicies = in.readLong();
}
public int getLegacyInt() {
return mLegacyInt;
}
+ /**
+ * @return whether this score has a particular policy.
+ */
+ @VisibleForTesting
+ public boolean hasPolicy(final int policy) {
+ return 0 != (mPolicies & (1L << policy));
+ }
+
@Override
public String toString() {
return "Score(" + mLegacyInt + ")";
@@ -54,6 +76,7 @@ public final class NetworkScore implements Parcelable {
@Override
public void writeToParcel(@NonNull final Parcel dest, final int flags) {
dest.writeInt(mLegacyInt);
+ dest.writeLong(mPolicies);
}
@Override
@@ -79,6 +102,7 @@ public final class NetworkScore implements Parcelable {
* A builder for NetworkScore.
*/
public static final class Builder {
+ private static final long POLICY_NONE = 0L;
private static final int INVALID_LEGACY_INT = Integer.MIN_VALUE;
private int mLegacyInt = INVALID_LEGACY_INT;
@@ -102,7 +126,7 @@ public final class NetworkScore implements Parcelable {
*/
@NonNull
public NetworkScore build() {
- return new NetworkScore(mLegacyInt);
+ return new NetworkScore(mLegacyInt, POLICY_NONE);
}
}
}
diff --git a/packages/SettingsLib/src/com/android/settingslib/deviceinfo/AbstractIpAddressPreferenceController.java b/packages/SettingsLib/src/com/android/settingslib/deviceinfo/AbstractIpAddressPreferenceController.java
index 3bb3a0c412a5..7f12cc8e6911 100644
--- a/packages/SettingsLib/src/com/android/settingslib/deviceinfo/AbstractIpAddressPreferenceController.java
+++ b/packages/SettingsLib/src/com/android/settingslib/deviceinfo/AbstractIpAddressPreferenceController.java
@@ -18,6 +18,7 @@ package com.android.settingslib.deviceinfo;
import android.content.Context;
import android.net.ConnectivityManager;
+import android.net.LinkAddress;
import android.net.LinkProperties;
import android.net.wifi.WifiManager;
@@ -28,7 +29,6 @@ import androidx.preference.PreferenceScreen;
import com.android.settingslib.R;
import com.android.settingslib.core.lifecycle.Lifecycle;
-import java.net.InetAddress;
import java.util.Iterator;
/**
@@ -93,19 +93,19 @@ public abstract class AbstractIpAddressPreferenceController
* @return the formatted and newline-separated IP addresses, or null if none.
*/
private static String getDefaultIpAddresses(ConnectivityManager cm) {
- LinkProperties prop = cm.getActiveLinkProperties();
+ LinkProperties prop = cm.getLinkProperties(cm.getActiveNetwork());
return formatIpAddresses(prop);
}
private static String formatIpAddresses(LinkProperties prop) {
if (prop == null) return null;
- Iterator<InetAddress> iter = prop.getAllAddresses().iterator();
+ Iterator<LinkAddress> iter = prop.getAllLinkAddresses().iterator();
// If there are no entries, return null
if (!iter.hasNext()) return null;
// Concatenate all available addresses, newline separated
StringBuilder addresses = new StringBuilder();
while (iter.hasNext()) {
- addresses.append(iter.next().getHostAddress());
+ addresses.append(iter.next().getAddress().getHostAddress());
if (iter.hasNext()) addresses.append("\n");
}
return addresses.toString();
diff --git a/services/core/java/com/android/server/ConnectivityService.java b/services/core/java/com/android/server/ConnectivityService.java
index 58a921f0e3be..f527da582959 100644
--- a/services/core/java/com/android/server/ConnectivityService.java
+++ b/services/core/java/com/android/server/ConnectivityService.java
@@ -72,8 +72,8 @@ import static android.net.NetworkCapabilities.NET_CAPABILITY_VALIDATED;
import static android.net.NetworkCapabilities.TRANSPORT_CELLULAR;
import static android.net.NetworkCapabilities.TRANSPORT_TEST;
import static android.net.NetworkCapabilities.TRANSPORT_VPN;
-import static android.net.NetworkPolicyManager.RULE_NONE;
-import static android.net.NetworkPolicyManager.uidRulesToString;
+import static android.net.NetworkPolicyManager.BLOCKED_REASON_NONE;
+import static android.net.NetworkPolicyManager.blockedReasonsToString;
import static android.net.NetworkRequest.Type.LISTEN_FOR_BEST;
import static android.net.shared.NetworkMonitorUtils.isPrivateDnsValidationRequired;
import static android.os.Process.INVALID_UID;
@@ -117,7 +117,6 @@ import android.net.INetd;
import android.net.INetworkActivityListener;
import android.net.INetworkMonitor;
import android.net.INetworkMonitorCallbacks;
-import android.net.INetworkPolicyListener;
import android.net.IOnCompleteListener;
import android.net.IQosCallback;
import android.net.ISocketKeepaliveCallback;
@@ -135,6 +134,7 @@ import android.net.NetworkInfo;
import android.net.NetworkInfo.DetailedState;
import android.net.NetworkMonitorManager;
import android.net.NetworkPolicyManager;
+import android.net.NetworkPolicyManager.NetworkPolicyCallback;
import android.net.NetworkProvider;
import android.net.NetworkRequest;
import android.net.NetworkScore;
@@ -331,12 +331,10 @@ public class ConnectivityService extends IConnectivityManager.Stub
private volatile boolean mLockdownEnabled;
/**
- * Stale copy of uid rules provided by NPMS. As long as they are accessed only in internal
- * handler thread, they don't need a lock.
+ * Stale copy of uid blocked reasons provided by NPMS. As long as they are accessed only in
+ * internal handler thread, they don't need a lock.
*/
- private SparseIntArray mUidRules = new SparseIntArray();
- /** Flag indicating if background data is restricted. */
- private boolean mRestrictBackground;
+ private SparseIntArray mUidBlockedReasons = new SparseIntArray();
private final Context mContext;
private final ConnectivityResources mResources;
@@ -510,16 +508,6 @@ public class ConnectivityService extends IConnectivityManager.Stub
// Handle private DNS validation status updates.
private static final int EVENT_PRIVATE_DNS_VALIDATION_UPDATE = 38;
- /**
- * Used to handle onUidRulesChanged event from NetworkPolicyManagerService.
- */
- private static final int EVENT_UID_RULES_CHANGED = 39;
-
- /**
- * Used to handle onRestrictBackgroundChanged event from NetworkPolicyManagerService.
- */
- private static final int EVENT_DATA_SAVER_CHANGED = 40;
-
/**
* Event for NetworkMonitor/NetworkAgentInfo to inform ConnectivityService that the network has
* been tested.
@@ -596,6 +584,13 @@ public class ConnectivityService extends IConnectivityManager.Stub
private static final int EVENT_SET_PROFILE_NETWORK_PREFERENCE = 50;
/**
+ * Event to specify that reasons for why an uid is blocked changed.
+ * arg1 = uid
+ * arg2 = blockedReasons
+ */
+ private static final int EVENT_UID_BLOCKED_REASON_CHANGED = 51;
+
+ /**
* Argument for {@link #EVENT_PROVISIONING_NOTIFICATION} to indicate that the notification
* should be shown.
*/
@@ -1253,10 +1248,10 @@ public class ConnectivityService extends IConnectivityManager.Stub
mAppOpsManager = (AppOpsManager) mContext.getSystemService(Context.APP_OPS_SERVICE);
mLocationPermissionChecker = new LocationPermissionChecker(mContext);
- // To ensure uid rules are synchronized with Network Policy, register for
+ // To ensure uid state is synchronized with Network Policy, register for
// NetworkPolicyManagerService events must happen prior to NetworkPolicyManagerService
// reading existing policy from disk.
- mPolicyManager.registerListener(mPolicyListener);
+ mPolicyManager.registerNetworkPolicyCallback(null, mPolicyCallback);
final PowerManager powerManager = (PowerManager) context.getSystemService(
Context.POWER_SERVICE);
@@ -1785,7 +1780,7 @@ public class ConnectivityService extends IConnectivityManager.Stub
}
// No need to check mLockdownEnabled. If it's true, getVpnUnderlyingNetworks returns null.
- final Network[] networks = getVpnUnderlyingNetworks(Binder.getCallingUid());
+ final Network[] networks = getVpnUnderlyingNetworks(mDeps.getCallingUid());
if (null != networks) {
for (final Network network : networks) {
final NetworkCapabilities nc = getNetworkCapabilitiesInternal(network);
@@ -2237,53 +2232,17 @@ public class ConnectivityService extends IConnectivityManager.Stub
}
}
- private final INetworkPolicyListener mPolicyListener = new NetworkPolicyManager.Listener() {
- @Override
- public void onUidRulesChanged(int uid, int uidRules) {
- mHandler.sendMessage(mHandler.obtainMessage(EVENT_UID_RULES_CHANGED, uid, uidRules));
- }
+ private final NetworkPolicyCallback mPolicyCallback = new NetworkPolicyCallback() {
@Override
- public void onRestrictBackgroundChanged(boolean restrictBackground) {
- // caller is NPMS, since we only register with them
- if (LOGD_BLOCKED_NETWORKINFO) {
- log("onRestrictBackgroundChanged(restrictBackground=" + restrictBackground + ")");
- }
- mHandler.sendMessage(mHandler.obtainMessage(
- EVENT_DATA_SAVER_CHANGED, restrictBackground ? 1 : 0, 0));
+ public void onUidBlockedReasonChanged(int uid, int blockedReasons) {
+ mHandler.sendMessage(mHandler.obtainMessage(EVENT_UID_BLOCKED_REASON_CHANGED,
+ uid, blockedReasons));
}
};
- void handleUidRulesChanged(int uid, int newRules) {
- // skip update when we've already applied rules
- final int oldRules = mUidRules.get(uid, RULE_NONE);
- if (oldRules == newRules) return;
-
- maybeNotifyNetworkBlockedForNewUidRules(uid, newRules);
-
- if (newRules == RULE_NONE) {
- mUidRules.delete(uid);
- } else {
- mUidRules.put(uid, newRules);
- }
- }
-
- void handleRestrictBackgroundChanged(boolean restrictBackground) {
- if (mRestrictBackground == restrictBackground) return;
-
- final List<UidRange> blockedRanges = mVpnBlockedUidRanges;
- for (final NetworkAgentInfo nai : mNetworkAgentInfos) {
- final boolean curMetered = nai.networkCapabilities.isMetered();
- maybeNotifyNetworkBlocked(nai, curMetered, curMetered, mRestrictBackground,
- restrictBackground, blockedRanges, blockedRanges);
- }
-
- mRestrictBackground = restrictBackground;
- }
-
- private boolean isUidBlockedByRules(int uid, int uidRules, boolean isNetworkMetered,
- boolean isBackgroundRestricted) {
- return mPolicyManager.checkUidNetworkingBlocked(uid, uidRules, isNetworkMetered,
- isBackgroundRestricted);
+ void handleUidBlockedReasonChanged(int uid, int blockedReasons) {
+ maybeNotifyNetworkBlockedForNewState(uid, blockedReasons);
+ mUidBlockedReasons.put(uid, blockedReasons);
}
private boolean checkAnyPermissionOf(String... permissions) {
@@ -2757,19 +2716,16 @@ public class ConnectivityService extends IConnectivityManager.Stub
pw.decreaseIndent();
pw.println();
- pw.print("Restrict background: ");
- pw.println(mRestrictBackground);
- pw.println();
-
pw.println("Status for known UIDs:");
pw.increaseIndent();
- final int size = mUidRules.size();
+ final int size = mUidBlockedReasons.size();
for (int i = 0; i < size; i++) {
// Don't crash if the array is modified while dumping in bugreports.
try {
- final int uid = mUidRules.keyAt(i);
- final int uidRules = mUidRules.get(uid, RULE_NONE);
- pw.println("UID=" + uid + " rules=" + uidRulesToString(uidRules));
+ final int uid = mUidBlockedReasons.keyAt(i);
+ final int blockedReasons = mUidBlockedReasons.valueAt(i);
+ pw.println("UID=" + uid + " blockedReasons="
+ + blockedReasonsToString(blockedReasons));
} catch (ArrayIndexOutOfBoundsException e) {
pw.println(" ArrayIndexOutOfBoundsException");
} catch (ConcurrentModificationException e) {
@@ -3005,6 +2961,9 @@ public class ConnectivityService extends IConnectivityManager.Stub
case NetworkAgent.EVENT_SET_EXPLICITLY_SELECTED: {
if (nai.everConnected) {
loge("ERROR: cannot call explicitlySelected on already-connected network");
+ // Note that if the NAI had been connected, this would affect the
+ // score, and therefore would require re-mixing the score and performing
+ // a rematch.
}
nai.networkAgentConfig.explicitlySelected = toBool(msg.arg1);
nai.networkAgentConfig.acceptUnvalidated = toBool(msg.arg1) && toBool(msg.arg2);
@@ -3691,7 +3650,7 @@ public class ConnectivityService extends IConnectivityManager.Stub
log("Replacing " + existingRequest.mRequests.get(0) + " with "
+ nri.mRequests.get(0) + " because their intents matched.");
}
- handleReleaseNetworkRequest(existingRequest.mRequests.get(0), getCallingUid(),
+ handleReleaseNetworkRequest(existingRequest.mRequests.get(0), mDeps.getCallingUid(),
/* callOnUnavailable */ false);
}
handleRegisterNetworkRequest(nri);
@@ -4089,6 +4048,7 @@ public class ConnectivityService extends IConnectivityManager.Stub
// network, we should respect the user's option and don't need to popup the
// PARTIAL_CONNECTIVITY notification to user again.
nai.networkAgentConfig.acceptPartialConnectivity = accept;
+ nai.updateScoreForNetworkAgentConfigUpdate();
rematchAllNetworksAndRequests();
sendUpdatedScoreToFactories(nai);
}
@@ -4351,7 +4311,7 @@ public class ConnectivityService extends IConnectivityManager.Stub
Intent intent = new Intent(action);
if (type != NotificationType.PRIVATE_DNS_BROKEN) {
- intent.setData(Uri.fromParts("netId", Integer.toString(nai.network.getNetId()), null));
+ intent.putExtra(ConnectivityManager.EXTRA_NETWORK, nai.network);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
// Some OEMs have their own Settings package. Thus, need to get the current using
// Settings package name instead of just use default name "com.android.settings".
@@ -4566,11 +4526,8 @@ public class ConnectivityService extends IConnectivityManager.Stub
handlePrivateDnsValidationUpdate(
(PrivateDnsValidationUpdate) msg.obj);
break;
- case EVENT_UID_RULES_CHANGED:
- handleUidRulesChanged(msg.arg1, msg.arg2);
- break;
- case EVENT_DATA_SAVER_CHANGED:
- handleRestrictBackgroundChanged(toBool(msg.arg1));
+ case EVENT_UID_BLOCKED_REASON_CHANGED:
+ handleUidBlockedReasonChanged(msg.arg1, msg.arg2);
break;
case EVENT_SET_REQUIRE_VPN_FOR_UIDS:
handleSetRequireVpnForUids(toBool(msg.arg1), (UidRange[]) msg.obj);
@@ -5043,8 +5000,8 @@ public class ConnectivityService extends IConnectivityManager.Stub
for (final NetworkAgentInfo nai : mNetworkAgentInfos) {
final boolean curMetered = nai.networkCapabilities.isMetered();
- maybeNotifyNetworkBlocked(nai, curMetered, curMetered, mRestrictBackground,
- mRestrictBackground, mVpnBlockedUidRanges, newVpnBlockedUidRanges);
+ maybeNotifyNetworkBlocked(nai, curMetered, curMetered,
+ mVpnBlockedUidRanges, newVpnBlockedUidRanges);
}
mVpnBlockedUidRanges = newVpnBlockedUidRanges;
@@ -5777,14 +5734,14 @@ public class ConnectivityService extends IConnectivityManager.Stub
private void releasePendingNetworkRequestWithDelay(PendingIntent operation) {
mHandler.sendMessageDelayed(
mHandler.obtainMessage(EVENT_RELEASE_NETWORK_REQUEST_WITH_INTENT,
- getCallingUid(), 0, operation), mReleasePendingIntentDelayMs);
+ mDeps.getCallingUid(), 0, operation), mReleasePendingIntentDelayMs);
}
@Override
public void releasePendingNetworkRequest(PendingIntent operation) {
Objects.requireNonNull(operation, "PendingIntent cannot be null.");
mHandler.sendMessage(mHandler.obtainMessage(EVENT_RELEASE_NETWORK_REQUEST_WITH_INTENT,
- getCallingUid(), 0, operation));
+ mDeps.getCallingUid(), 0, operation));
}
// In order to implement the compatibility measure for pre-M apps that call
@@ -5881,7 +5838,7 @@ public class ConnectivityService extends IConnectivityManager.Stub
public void releaseNetworkRequest(NetworkRequest networkRequest) {
ensureNetworkRequestHasType(networkRequest);
mHandler.sendMessage(mHandler.obtainMessage(
- EVENT_RELEASE_NETWORK_REQUEST, getCallingUid(), 0, networkRequest));
+ EVENT_RELEASE_NETWORK_REQUEST, mDeps.getCallingUid(), 0, networkRequest));
}
private void handleRegisterNetworkProvider(NetworkProviderInfo npi) {
@@ -6827,8 +6784,8 @@ public class ConnectivityService extends IConnectivityManager.Stub
final boolean meteredChanged = oldMetered != newMetered;
if (meteredChanged) {
- maybeNotifyNetworkBlocked(nai, oldMetered, newMetered, mRestrictBackground,
- mRestrictBackground, mVpnBlockedUidRanges, mVpnBlockedUidRanges);
+ maybeNotifyNetworkBlocked(nai, oldMetered, newMetered,
+ mVpnBlockedUidRanges, mVpnBlockedUidRanges);
}
final boolean roamingChanged = prevNc.hasCapability(NET_CAPABILITY_NOT_ROAMING)
@@ -7951,8 +7908,8 @@ public class ConnectivityService extends IConnectivityManager.Stub
final boolean metered = nai.networkCapabilities.isMetered();
boolean blocked;
blocked = isUidBlockedByVpn(nri.mUid, mVpnBlockedUidRanges);
- blocked |= isUidBlockedByRules(nri.mUid, mUidRules.get(nri.mUid),
- metered, mRestrictBackground);
+ blocked |= NetworkPolicyManager.isUidBlocked(
+ mUidBlockedReasons.get(nri.mUid, BLOCKED_REASON_NONE), metered);
callCallbackForRequest(nri, nai, ConnectivityManager.CALLBACK_AVAILABLE, blocked ? 1 : 0);
}
@@ -7970,16 +7927,14 @@ public class ConnectivityService extends IConnectivityManager.Stub
*
* @param nai The target NetworkAgentInfo.
* @param oldMetered True if the previous network capabilities is metered.
- * @param newRestrictBackground True if data saver is enabled.
*/
private void maybeNotifyNetworkBlocked(NetworkAgentInfo nai, boolean oldMetered,
- boolean newMetered, boolean oldRestrictBackground, boolean newRestrictBackground,
- List<UidRange> oldBlockedUidRanges, List<UidRange> newBlockedUidRanges) {
+ boolean newMetered, List<UidRange> oldBlockedUidRanges,
+ List<UidRange> newBlockedUidRanges) {
for (int i = 0; i < nai.numNetworkRequests(); i++) {
NetworkRequest nr = nai.requestAt(i);
NetworkRequestInfo nri = mNetworkRequests.get(nr);
- final int uidRules = mUidRules.get(nri.mUid);
final boolean oldBlocked, newBlocked, oldVpnBlocked, newVpnBlocked;
oldVpnBlocked = isUidBlockedByVpn(nri.mUid, oldBlockedUidRanges);
@@ -7987,10 +7942,11 @@ public class ConnectivityService extends IConnectivityManager.Stub
? isUidBlockedByVpn(nri.mUid, newBlockedUidRanges)
: oldVpnBlocked;
- oldBlocked = oldVpnBlocked || isUidBlockedByRules(nri.mUid, uidRules, oldMetered,
- oldRestrictBackground);
- newBlocked = newVpnBlocked || isUidBlockedByRules(nri.mUid, uidRules, newMetered,
- newRestrictBackground);
+ final int blockedReasons = mUidBlockedReasons.get(nri.mUid, BLOCKED_REASON_NONE);
+ oldBlocked = oldVpnBlocked || NetworkPolicyManager.isUidBlocked(
+ blockedReasons, oldMetered);
+ newBlocked = newVpnBlocked || NetworkPolicyManager.isUidBlocked(
+ blockedReasons, newMetered);
if (oldBlocked != newBlocked) {
callCallbackForRequest(nri, nai, ConnectivityManager.CALLBACK_BLK_CHANGED,
@@ -8000,19 +7956,20 @@ public class ConnectivityService extends IConnectivityManager.Stub
}
/**
- * Notify apps with a given UID of the new blocked state according to new uid rules.
+ * Notify apps with a given UID of the new blocked state according to new uid state.
* @param uid The uid for which the rules changed.
- * @param newRules The new rules to apply.
+ * @param blockedReasons The reasons for why an uid is blocked.
*/
- private void maybeNotifyNetworkBlockedForNewUidRules(int uid, int newRules) {
+ private void maybeNotifyNetworkBlockedForNewState(int uid, int blockedReasons) {
for (final NetworkAgentInfo nai : mNetworkAgentInfos) {
final boolean metered = nai.networkCapabilities.isMetered();
final boolean vpnBlocked = isUidBlockedByVpn(uid, mVpnBlockedUidRanges);
final boolean oldBlocked, newBlocked;
- oldBlocked = vpnBlocked || isUidBlockedByRules(
- uid, mUidRules.get(uid), metered, mRestrictBackground);
- newBlocked = vpnBlocked || isUidBlockedByRules(
- uid, newRules, metered, mRestrictBackground);
+
+ oldBlocked = vpnBlocked || NetworkPolicyManager.isUidBlocked(
+ mUidBlockedReasons.get(uid, BLOCKED_REASON_NONE), metered);
+ newBlocked = vpnBlocked || NetworkPolicyManager.isUidBlocked(
+ blockedReasons, metered);
if (oldBlocked == newBlocked) {
continue;
}
@@ -8359,7 +8316,7 @@ public class ConnectivityService extends IConnectivityManager.Stub
final NetworkAgentInfo vpn = getVpnForUid(uid);
if (vpn == null || getVpnType(vpn) != VpnManager.TYPE_VPN_SERVICE
- || vpn.networkCapabilities.getOwnerUid() != Binder.getCallingUid()) {
+ || vpn.networkCapabilities.getOwnerUid() != mDeps.getCallingUid()) {
return INVALID_UID;
}
diff --git a/services/core/java/com/android/server/NetworkManagementService.java b/services/core/java/com/android/server/NetworkManagementService.java
index 10d6570929ed..3ea0ce173745 100644
--- a/services/core/java/com/android/server/NetworkManagementService.java
+++ b/services/core/java/com/android/server/NetworkManagementService.java
@@ -643,7 +643,7 @@ public class NetworkManagementService extends INetworkManagementService.Stub {
String route, String gateway, String ifName) throws RemoteException {
final RouteInfo processRoute = new RouteInfo(new IpPrefix(route),
("".equals(gateway)) ? null : InetAddresses.parseNumericAddress(gateway),
- ifName);
+ ifName, RouteInfo.RTN_UNICAST);
mDaemonHandler.post(() -> notifyRouteChange(updated, processRoute));
}
diff --git a/services/core/java/com/android/server/am/OWNERS b/services/core/java/com/android/server/am/OWNERS
index 1c38c86d08c8..90d940939be8 100644
--- a/services/core/java/com/android/server/am/OWNERS
+++ b/services/core/java/com/android/server/am/OWNERS
@@ -30,6 +30,10 @@ per-file BatteryExternalStats* = file:/BATTERY_STATS_OWNERS
michaelwr@google.com
narayan@google.com
+# Voice Interaction
+per-file *Assist* = file:/core/java/android/service/voice/OWNERS
+per-file *Voice* = file:/core/java/android/service/voice/OWNERS
+
per-file SettingsToPropertiesMapper.java = omakoto@google.com, svetoslavganov@google.com, yamasani@google.com
per-file CarUserSwitchingDialog.java = keunyoung@google.com, felipeal@google.com, gurunagarajan@google.com
diff --git a/services/core/java/com/android/server/connectivity/ConnectivityConstants.java b/services/core/java/com/android/server/connectivity/ConnectivityConstants.java
index 0fb6fecd4fe2..325a2cd7bd69 100644
--- a/services/core/java/com/android/server/connectivity/ConnectivityConstants.java
+++ b/services/core/java/com/android/server/connectivity/ConnectivityConstants.java
@@ -18,18 +18,10 @@ package com.android.server.connectivity;
/**
* A class encapsulating various constants used by Connectivity.
+ * TODO : remove this class.
* @hide
*/
public class ConnectivityConstants {
-
- // Penalty applied to scores of Networks that have not been validated.
- public static final int UNVALIDATED_SCORE_PENALTY = 40;
-
- // Score for explicitly connected network.
- //
- // This ensures that a) the explicitly selected network is never trumped by anything else, and
- // b) the explicitly selected network is never torn down.
- public static final int EXPLICITLY_SELECTED_NETWORK_SCORE = 100;
// VPNs typically have priority over other networks. Give them a score that will
// let them win every single time.
public static final int VPN_DEFAULT_SCORE = 101;
diff --git a/services/core/java/com/android/server/connectivity/FullScore.java b/services/core/java/com/android/server/connectivity/FullScore.java
new file mode 100644
index 000000000000..028cfee36593
--- /dev/null
+++ b/services/core/java/com/android/server/connectivity/FullScore.java
@@ -0,0 +1,211 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.connectivity;
+
+import static android.net.NetworkCapabilities.NET_CAPABILITY_VALIDATED;
+import static android.net.NetworkCapabilities.TRANSPORT_VPN;
+
+import android.annotation.IntDef;
+import android.annotation.NonNull;
+import android.net.NetworkAgentConfig;
+import android.net.NetworkCapabilities;
+import android.net.NetworkScore;
+
+import com.android.internal.annotations.VisibleForTesting;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.util.StringJoiner;
+
+/**
+ * This class represents how desirable a network is.
+ *
+ * FullScore is very similar to NetworkScore, but it contains the bits that are managed
+ * by ConnectivityService. This provides static guarantee that all users must know whether
+ * they are handling a score that had the CS-managed bits set.
+ */
+public class FullScore {
+ // This will be removed soon. Do *NOT* depend on it for any new code that is not part of
+ // a migration.
+ private final int mLegacyInt;
+
+ /** @hide */
+ @Retention(RetentionPolicy.SOURCE)
+ @IntDef(prefix = {"POLICY_"}, value = {
+ POLICY_IS_VALIDATED,
+ POLICY_IS_VPN,
+ POLICY_EVER_USER_SELECTED,
+ POLICY_ACCEPT_UNVALIDATED
+ })
+ public @interface Policy {
+ }
+
+ // Agent-managed policies are in NetworkScore. They start from 1.
+ // CS-managed policies, counting from 63 downward
+ // This network is validated. CS-managed because the source of truth is in NetworkCapabilities.
+ /** @hide */
+ public static final int POLICY_IS_VALIDATED = 63;
+
+ // This is a VPN and behaves as one for scoring purposes.
+ /** @hide */
+ public static final int POLICY_IS_VPN = 62;
+
+ // This network has been selected by the user manually from settings or a 3rd party app
+ // at least once. {@see NetworkAgentConfig#explicitlySelected}.
+ /** @hide */
+ public static final int POLICY_EVER_USER_SELECTED = 61;
+
+ // The user has indicated in UI that this network should be used even if it doesn't
+ // validate. {@see NetworkAgentConfig#acceptUnvalidated}.
+ /** @hide */
+ public static final int POLICY_ACCEPT_UNVALIDATED = 60;
+
+ // To help iterate when printing
+ @VisibleForTesting
+ static final int MIN_CS_MANAGED_POLICY = POLICY_ACCEPT_UNVALIDATED;
+ @VisibleForTesting
+ static final int MAX_CS_MANAGED_POLICY = POLICY_IS_VALIDATED;
+
+ @VisibleForTesting
+ static @NonNull String policyNameOf(final int policy) {
+ switch (policy) {
+ case POLICY_IS_VALIDATED: return "IS_VALIDATED";
+ case POLICY_IS_VPN: return "IS_VPN";
+ case POLICY_EVER_USER_SELECTED: return "EVER_USER_SELECTED";
+ case POLICY_ACCEPT_UNVALIDATED: return "ACCEPT_UNVALIDATED";
+ }
+ throw new IllegalArgumentException("Unknown policy : " + policy);
+ }
+
+ // Bitmask of all the policies applied to this score.
+ private final long mPolicies;
+
+ FullScore(final int legacyInt, final long policies) {
+ mLegacyInt = legacyInt;
+ mPolicies = policies;
+ }
+
+ /**
+ * Given a score supplied by the NetworkAgent and CS-managed objects, produce a full score.
+ *
+ * @param score the score supplied by the agent
+ * @param caps the NetworkCapabilities of the network
+ * @param config the NetworkAgentConfig of the network
+ * @return an FullScore that is appropriate to use for ranking.
+ */
+ public static FullScore fromNetworkScore(@NonNull final NetworkScore score,
+ @NonNull final NetworkCapabilities caps, @NonNull final NetworkAgentConfig config) {
+ return withPolicies(score.getLegacyInt(), caps.hasCapability(NET_CAPABILITY_VALIDATED),
+ caps.hasTransport(TRANSPORT_VPN),
+ config.explicitlySelected,
+ config.acceptUnvalidated);
+ }
+
+ /**
+ * Return a new score given updated caps and config.
+ *
+ * @param caps the NetworkCapabilities of the network
+ * @param config the NetworkAgentConfig of the network
+ * @return a score with the policies from the arguments reset
+ */
+ public FullScore mixInScore(@NonNull final NetworkCapabilities caps,
+ @NonNull final NetworkAgentConfig config) {
+ return withPolicies(mLegacyInt, caps.hasCapability(NET_CAPABILITY_VALIDATED),
+ caps.hasTransport(TRANSPORT_VPN),
+ config.explicitlySelected,
+ config.acceptUnvalidated);
+ }
+
+ private static FullScore withPolicies(@NonNull final int legacyInt,
+ final boolean isValidated,
+ final boolean isVpn,
+ final boolean everUserSelected,
+ final boolean acceptUnvalidated) {
+ return new FullScore(legacyInt,
+ (isValidated ? 1L << POLICY_IS_VALIDATED : 0)
+ | (isVpn ? 1L << POLICY_IS_VPN : 0)
+ | (everUserSelected ? 1L << POLICY_EVER_USER_SELECTED : 0)
+ | (acceptUnvalidated ? 1L << POLICY_ACCEPT_UNVALIDATED : 0));
+ }
+
+ /**
+ * For backward compatibility, get the legacy int.
+ * This will be removed before S is published.
+ */
+ public int getLegacyInt() {
+ return getLegacyInt(false /* pretendValidated */);
+ }
+
+ public int getLegacyIntAsValidated() {
+ return getLegacyInt(true /* pretendValidated */);
+ }
+
+ // TODO : remove these two constants
+ // Penalty applied to scores of Networks that have not been validated.
+ private static final int UNVALIDATED_SCORE_PENALTY = 40;
+
+ // Score for a network that can be used unvalidated
+ private static final int ACCEPT_UNVALIDATED_NETWORK_SCORE = 100;
+
+ private int getLegacyInt(boolean pretendValidated) {
+ // If the user has chosen this network at least once, give it the maximum score when
+ // checking to pretend it's validated, or if it doesn't need to validate because the
+ // user said to use it even if it doesn't validate.
+ // This ensures that networks that have been selected in UI are not torn down before the
+ // user gets a chance to prefer it when a higher-scoring network (e.g., Ethernet) is
+ // available.
+ if (hasPolicy(POLICY_EVER_USER_SELECTED)
+ && (hasPolicy(POLICY_ACCEPT_UNVALIDATED) || pretendValidated)) {
+ return ACCEPT_UNVALIDATED_NETWORK_SCORE;
+ }
+
+ int score = mLegacyInt;
+ // Except for VPNs, networks are subject to a penalty for not being validated.
+ // Apply the penalty unless the network is a VPN, or it's validated or pretending to be.
+ if (!hasPolicy(POLICY_IS_VALIDATED) && !pretendValidated && !hasPolicy(POLICY_IS_VPN)) {
+ score -= UNVALIDATED_SCORE_PENALTY;
+ }
+ if (score < 0) score = 0;
+ return score;
+ }
+
+ /**
+ * @return whether this score has a particular policy.
+ */
+ @VisibleForTesting
+ public boolean hasPolicy(final int policy) {
+ return 0 != (mPolicies & (1L << policy));
+ }
+
+ // Example output :
+ // Score(50 ; Policies : EVER_USER_SELECTED&IS_VALIDATED)
+ @Override
+ public String toString() {
+ final StringJoiner sj = new StringJoiner(
+ "&", // delimiter
+ "Score(" + mLegacyInt + " ; Policies : ", // prefix
+ ")"); // suffix
+ for (int i = NetworkScore.MIN_AGENT_MANAGED_POLICY;
+ i <= NetworkScore.MAX_AGENT_MANAGED_POLICY; ++i) {
+ if (hasPolicy(i)) sj.add(policyNameOf(i));
+ }
+ for (int i = MIN_CS_MANAGED_POLICY; i <= MAX_CS_MANAGED_POLICY; ++i) {
+ if (hasPolicy(i)) sj.add(policyNameOf(i));
+ }
+ return sj.toString();
+ }
+}
diff --git a/services/core/java/com/android/server/connectivity/NetworkAgentInfo.java b/services/core/java/com/android/server/connectivity/NetworkAgentInfo.java
index e44dcf5975f1..fde4f5d87e8c 100644
--- a/services/core/java/com/android/server/connectivity/NetworkAgentInfo.java
+++ b/services/core/java/com/android/server/connectivity/NetworkAgentInfo.java
@@ -303,8 +303,9 @@ public class NetworkAgentInfo implements Comparable<NetworkAgentInfo> {
// validated).
private boolean mInactive;
- // This represents the quality of the network.
- private NetworkScore mScore;
+ // This represents the quality of the network. As opposed to NetworkScore, FullScore includes
+ // the ConnectivityService-managed bits.
+ private FullScore mScore;
// The list of NetworkRequests being satisfied by this Network.
private final SparseArray<NetworkRequest> mNetworkRequests = new SparseArray<>();
@@ -356,12 +357,12 @@ public class NetworkAgentInfo implements Comparable<NetworkAgentInfo> {
networkInfo = info;
linkProperties = lp;
networkCapabilities = nc;
- mScore = score;
+ networkAgentConfig = config;
+ setScore(score); // uses members networkCapabilities and networkAgentConfig
clatd = new Nat464Xlat(this, netd, dnsResolver, deps);
mConnService = connService;
mContext = context;
mHandler = handler;
- networkAgentConfig = config;
this.factorySerialNumber = factorySerialNumber;
this.creatorUid = creatorUid;
mQosCallbackTracker = qosCallbackTracker;
@@ -667,6 +668,7 @@ public class NetworkAgentInfo implements Comparable<NetworkAgentInfo> {
@NonNull final NetworkCapabilities nc) {
final NetworkCapabilities oldNc = networkCapabilities;
networkCapabilities = nc;
+ mScore = mScore.mixInScore(networkCapabilities, networkAgentConfig);
final NetworkMonitorManager nm = mNetworkMonitor;
if (nm != null) {
nm.notifyNetworkCapabilitiesChanged(nc);
@@ -844,30 +846,6 @@ public class NetworkAgentInfo implements Comparable<NetworkAgentInfo> {
return isVPN();
}
- private int getCurrentScore(boolean pretendValidated) {
- // TODO: We may want to refactor this into a NetworkScore class that takes a base score from
- // the NetworkAgent and signals from the NetworkAgent and uses those signals to modify the
- // score. The NetworkScore class would provide a nice place to centralize score constants
- // so they are not scattered about the transports.
-
- // If this network is explicitly selected and the user has decided to use it even if it's
- // unvalidated, give it the maximum score. Also give it the maximum score if it's explicitly
- // selected and we're trying to see what its score could be. This ensures that we don't tear
- // down an explicitly selected network before the user gets a chance to prefer it when
- // a higher-scoring network (e.g., Ethernet) is available.
- if (networkAgentConfig.explicitlySelected
- && (networkAgentConfig.acceptUnvalidated || pretendValidated)) {
- return ConnectivityConstants.EXPLICITLY_SELECTED_NETWORK_SCORE;
- }
-
- int score = mScore.getLegacyInt();
- if (!lastValidated && !pretendValidated && !ignoreWifiUnvalidationPenalty() && !isVPN()) {
- score -= ConnectivityConstants.UNVALIDATED_SCORE_PENALTY;
- }
- if (score < 0) score = 0;
- return score;
- }
-
// Return true on devices configured to ignore score penalty for wifi networks
// that become unvalidated (b/31075769).
private boolean ignoreWifiUnvalidationPenalty() {
@@ -880,17 +858,29 @@ public class NetworkAgentInfo implements Comparable<NetworkAgentInfo> {
// Get the current score for this Network. This may be modified from what the
// NetworkAgent sent, as it has modifiers applied to it.
public int getCurrentScore() {
- return getCurrentScore(false);
+ return mScore.getLegacyInt();
}
// Get the current score for this Network as if it was validated. This may be modified from
// what the NetworkAgent sent, as it has modifiers applied to it.
public int getCurrentScoreAsValidated() {
- return getCurrentScore(true);
+ return mScore.getLegacyIntAsValidated();
}
+ /**
+ * Mix-in the ConnectivityService-managed bits in the score.
+ */
public void setScore(final NetworkScore score) {
- mScore = score;
+ mScore = FullScore.fromNetworkScore(score, networkCapabilities, networkAgentConfig);
+ }
+
+ /**
+ * Update the ConnectivityService-managed bits in the score.
+ *
+ * Call this after updating the network agent config.
+ */
+ public void updateScoreForNetworkAgentConfigUpdate() {
+ mScore = mScore.mixInScore(networkCapabilities, networkAgentConfig);
}
/**
diff --git a/services/core/java/com/android/server/connectivity/NetworkNotificationManager.java b/services/core/java/com/android/server/connectivity/NetworkNotificationManager.java
index 508739f2e1e0..181a10d2a63e 100644
--- a/services/core/java/com/android/server/connectivity/NetworkNotificationManager.java
+++ b/services/core/java/com/android/server/connectivity/NetworkNotificationManager.java
@@ -156,7 +156,7 @@ public class NetworkNotificationManager {
final String tag = tagFor(id);
final int eventId = notifyType.eventId;
final int transportType;
- final String name;
+ final CharSequence name;
if (nai != null) {
transportType = approximateTransportType(nai);
final String extraInfo = nai.networkInfo.getExtraInfo();
diff --git a/services/core/java/com/android/server/connectivity/ProxyTracker.java b/services/core/java/com/android/server/connectivity/ProxyTracker.java
index f8833071d1bf..f572b46a9b58 100644
--- a/services/core/java/com/android/server/connectivity/ProxyTracker.java
+++ b/services/core/java/com/android/server/connectivity/ProxyTracker.java
@@ -34,7 +34,6 @@ import android.net.ProxyInfo;
import android.net.Uri;
import android.os.Binder;
import android.os.Handler;
-import android.os.HandlerExecutor;
import android.os.UserHandle;
import android.provider.Settings;
import android.text.TextUtils;
@@ -105,7 +104,7 @@ public class ProxyTracker {
PacProxyInstalledListener listener = new PacProxyInstalledListener(pacChangedEvent);
mPacProxyManager.addPacProxyInstalledListener(
- new HandlerExecutor(mConnectivityServiceHandler), listener);
+ mConnectivityServiceHandler::post, listener);
}
// Convert empty ProxyInfo's to null as null-checks are used to determine if proxies are present
diff --git a/services/core/java/com/android/server/connectivity/Vpn.java b/services/core/java/com/android/server/connectivity/Vpn.java
index 124c3741ad57..e35a1ab71492 100644
--- a/services/core/java/com/android/server/connectivity/Vpn.java
+++ b/services/core/java/com/android/server/connectivity/Vpn.java
@@ -68,6 +68,7 @@ import android.net.NetworkInfo;
import android.net.NetworkInfo.DetailedState;
import android.net.NetworkProvider;
import android.net.NetworkRequest;
+import android.net.NetworkScore;
import android.net.RouteInfo;
import android.net.UidRange;
import android.net.UidRangeParcel;
@@ -1174,11 +1175,13 @@ public class Vpn {
if (!allowIPv4) {
lp.addRoute(new RouteInfo(new IpPrefix(
- NetworkStackConstants.IPV4_ADDR_ANY, 0), RTN_UNREACHABLE));
+ NetworkStackConstants.IPV4_ADDR_ANY, 0), null /*gateway*/,
+ null /*iface*/, RTN_UNREACHABLE));
}
if (!allowIPv6) {
lp.addRoute(new RouteInfo(new IpPrefix(
- NetworkStackConstants.IPV6_ADDR_ANY, 0), RTN_UNREACHABLE));
+ NetworkStackConstants.IPV6_ADDR_ANY, 0), null /*gateway*/,
+ null /*iface*/, RTN_UNREACHABLE));
}
// Concatenate search domains into a string.
@@ -1239,7 +1242,7 @@ public class Vpn {
mLegacyState = LegacyVpnInfo.STATE_CONNECTING;
updateState(DetailedState.CONNECTING, "agentConnect");
- NetworkAgentConfig networkAgentConfig = new NetworkAgentConfig();
+ NetworkAgentConfig networkAgentConfig = new NetworkAgentConfig.Builder().build();
networkAgentConfig.allowBypass = mConfig.allowBypass && !mLockdown;
mNetworkCapabilities.setOwnerUid(mOwnerUID);
@@ -1258,9 +1261,11 @@ public class Vpn {
}
mNetworkAgent = new NetworkAgent(mContext, mLooper, NETWORKTYPE /* logtag */,
- mNetworkCapabilities, lp, VPN_DEFAULT_SCORE, networkAgentConfig, mNetworkProvider) {
+ mNetworkCapabilities, lp,
+ new NetworkScore.Builder().setLegacyInt(VPN_DEFAULT_SCORE).build(),
+ networkAgentConfig, mNetworkProvider) {
@Override
- public void unwanted() {
+ public void onNetworkUnwanted() {
// We are user controlled, not driven by NetworkRequest.
}
};
@@ -2696,7 +2701,8 @@ public class Vpn {
mConfig.routes.clear();
for (final RouteInfo route : oldRoutes) {
- mConfig.routes.add(new RouteInfo(route.getDestination(), RTN_UNREACHABLE));
+ mConfig.routes.add(new RouteInfo(route.getDestination(), null /*gateway*/,
+ null /*iface*/, RTN_UNREACHABLE));
}
if (mNetworkAgent != null) {
mNetworkAgent.sendLinkProperties(makeLinkProperties());
@@ -3035,10 +3041,12 @@ public class Vpn {
// Add a throw route for the VPN server endpoint, if one was specified.
if (endpointAddress instanceof Inet4Address) {
mConfig.routes.add(new RouteInfo(
- new IpPrefix(endpointAddress, 32), RTN_THROW));
+ new IpPrefix(endpointAddress, 32), null /*gateway*/,
+ null /*iface*/, RTN_THROW));
} else if (endpointAddress instanceof Inet6Address) {
mConfig.routes.add(new RouteInfo(
- new IpPrefix(endpointAddress, 128), RTN_THROW));
+ new IpPrefix(endpointAddress, 128), null /*gateway*/,
+ null /*iface*/, RTN_THROW));
} else {
Log.e(TAG, "Unknown IP address family for VPN endpoint: "
+ endpointAddress);
diff --git a/services/core/java/com/android/server/connectivity/VpnIkev2Utils.java b/services/core/java/com/android/server/connectivity/VpnIkev2Utils.java
index fa03e59f2f2e..47eb3eb70434 100644
--- a/services/core/java/com/android/server/connectivity/VpnIkev2Utils.java
+++ b/services/core/java/com/android/server/connectivity/VpnIkev2Utils.java
@@ -405,7 +405,8 @@ public class VpnIkev2Utils {
for (final IkeTrafficSelector selector : trafficSelectors) {
for (final IpPrefix prefix :
new IpRange(selector.startingAddress, selector.endingAddress).asIpPrefixes()) {
- routes.add(new RouteInfo(prefix, null));
+ routes.add(new RouteInfo(prefix, null /*gateway*/, null /*iface*/,
+ RouteInfo.RTN_UNICAST));
}
}
diff --git a/services/core/java/com/android/server/locksettings/LockSettingsService.java b/services/core/java/com/android/server/locksettings/LockSettingsService.java
index 294d7e257b6e..0215188bc1a4 100644
--- a/services/core/java/com/android/server/locksettings/LockSettingsService.java
+++ b/services/core/java/com/android/server/locksettings/LockSettingsService.java
@@ -92,7 +92,6 @@ import android.provider.Settings.SettingNotFoundException;
import android.security.AndroidKeyStoreMaintenance;
import android.security.Authorization;
import android.security.KeyStore;
-import android.security.keystore.AndroidKeyStoreProvider;
import android.security.keystore.KeyProperties;
import android.security.keystore.KeyProtection;
import android.security.keystore.UserNotAuthenticatedException;
@@ -157,7 +156,6 @@ import java.util.List;
import java.util.Map;
import java.util.NoSuchElementException;
import java.util.Objects;
-import java.util.Optional;
import java.util.Set;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
@@ -264,13 +262,7 @@ public class LockSettingsService extends ILockSettings.Stub {
@Override
public void onStart() {
- Optional<Boolean> keystore2_enabled =
- android.sysprop.Keystore2Properties.keystore2_enabled();
- if (keystore2_enabled.isPresent() && keystore2_enabled.get()) {
- android.security.keystore2.AndroidKeyStoreProvider.install();
- } else {
- AndroidKeyStoreProvider.install();
- }
+ android.security.keystore2.AndroidKeyStoreProvider.install();
mLockSettingsService = new LockSettingsService(getContext());
publishBinderService("lock_settings", mLockSettingsService);
}
diff --git a/services/core/java/com/android/server/net/NetworkPolicyManagerService.java b/services/core/java/com/android/server/net/NetworkPolicyManagerService.java
index aee0947f39f9..b7367e5170c6 100644
--- a/services/core/java/com/android/server/net/NetworkPolicyManagerService.java
+++ b/services/core/java/com/android/server/net/NetworkPolicyManagerService.java
@@ -56,6 +56,23 @@ 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;
+import static android.net.NetworkPolicyManager.ALLOWED_METERED_REASON_MASK;
+import static android.net.NetworkPolicyManager.ALLOWED_METERED_REASON_USER_EXEMPTED;
+import static android.net.NetworkPolicyManager.ALLOWED_REASON_FOREGROUND;
+import static android.net.NetworkPolicyManager.ALLOWED_REASON_NONE;
+import static android.net.NetworkPolicyManager.ALLOWED_REASON_POWER_SAVE_ALLOWLIST;
+import static android.net.NetworkPolicyManager.ALLOWED_REASON_POWER_SAVE_EXCEPT_IDLE_ALLOWLIST;
+import static android.net.NetworkPolicyManager.ALLOWED_REASON_RESTRICTED_MODE_PERMISSIONS;
+import static android.net.NetworkPolicyManager.ALLOWED_REASON_SYSTEM;
+import static android.net.NetworkPolicyManager.BLOCKED_METERED_REASON_ADMIN_DISABLED;
+import static android.net.NetworkPolicyManager.BLOCKED_METERED_REASON_DATA_SAVER;
+import static android.net.NetworkPolicyManager.BLOCKED_METERED_REASON_MASK;
+import static android.net.NetworkPolicyManager.BLOCKED_METERED_REASON_USER_RESTRICTED;
+import static android.net.NetworkPolicyManager.BLOCKED_REASON_APP_STANDBY;
+import static android.net.NetworkPolicyManager.BLOCKED_REASON_BATTERY_SAVER;
+import static android.net.NetworkPolicyManager.BLOCKED_REASON_DOZE;
+import static android.net.NetworkPolicyManager.BLOCKED_REASON_NONE;
+import static android.net.NetworkPolicyManager.BLOCKED_REASON_RESTRICTED_MODE;
import static android.net.NetworkPolicyManager.EXTRA_NETWORK_TEMPLATE;
import static android.net.NetworkPolicyManager.FIREWALL_RULE_DEFAULT;
import static android.net.NetworkPolicyManager.MASK_ALL_NETWORKS;
@@ -414,6 +431,14 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
private static final int MSG_SET_NETWORK_TEMPLATE_ENABLED = 18;
private static final int MSG_SUBSCRIPTION_PLANS_CHANGED = 19;
private static final int MSG_STATS_PROVIDER_LIMIT_REACHED = 20;
+ // TODO: Add similar docs for other messages.
+ /**
+ * Message to indicate that reasons for why an uid is blocked changed.
+ * arg1 = uid
+ * arg2 = oldBlockedReasons
+ * obj = newBlockedReasons
+ */
+ private static final int MSG_BLOCKED_REASON_CHANGED = 21;
private static final int UID_MSG_STATE_CHANGED = 100;
private static final int UID_MSG_GONE = 101;
@@ -560,7 +585,10 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
/** Foreground at UID granularity. */
@GuardedBy("mUidRulesFirstLock")
- final SparseArray<UidState> mUidState = new SparseArray<UidState>();
+ private final SparseArray<UidState> mUidState = new SparseArray<>();
+
+ @GuardedBy("mUidRulesFirstLock")
+ private final SparseArray<UidBlockedState> mUidBlockedState = new SparseArray<>();
/** Map from network ID to last observed meteredness state */
@GuardedBy("mNetworkPoliciesSecondLock")
@@ -2879,15 +2907,18 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
}
@Override
- public void registerListener(INetworkPolicyListener listener) {
+ public void registerListener(@NonNull INetworkPolicyListener listener) {
+ Objects.requireNonNull(listener);
// TODO: Remove CONNECTIVITY_INTERNAL and the *AnyPermissionOf methods above after all apps
// have declared OBSERVE_NETWORK_POLICY.
enforceAnyPermissionOf(CONNECTIVITY_INTERNAL, OBSERVE_NETWORK_POLICY);
mListeners.register(listener);
+ // TODO: Send callbacks to the newly registered listener
}
@Override
- public void unregisterListener(INetworkPolicyListener listener) {
+ public void unregisterListener(@NonNull INetworkPolicyListener listener) {
+ Objects.requireNonNull(listener);
// TODO: Remove CONNECTIVITY_INTERNAL and the *AnyPermissionOf methods above after all apps
// have declared OBSERVE_NETWORK_POLICY.
enforceAnyPermissionOf(CONNECTIVITY_INTERNAL, OBSERVE_NETWORK_POLICY);
@@ -3923,6 +3954,7 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
mUidRules.put(uid, newUidRule);
mHandler.obtainMessage(MSG_RULES_CHANGED, uid, newUidRule).sendToTarget();
}
+ updateBlockedReasonsForRestrictedModeUL(uid);
});
if (mRestrictedNetworkingMode) {
// firewall rules only need to be set when this mode is being enabled.
@@ -3943,6 +3975,7 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
mUidRules.put(uid, newUidRule);
mHandler.obtainMessage(MSG_RULES_CHANGED, uid, newUidRule).sendToTarget();
}
+ updateBlockedReasonsForRestrictedModeUL(uid);
// if restricted networking mode is on, and the app has an access exemption, the uid rule
// will not change, but the firewall rule will have to be updated.
@@ -3954,6 +3987,31 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
}
}
+ private void updateBlockedReasonsForRestrictedModeUL(int uid) {
+ UidBlockedState uidBlockedState = mUidBlockedState.get(uid);
+ if (uidBlockedState == null) {
+ uidBlockedState = new UidBlockedState();
+ mUidBlockedState.put(uid, uidBlockedState);
+ }
+ final int oldEffectiveBlockedReasons = uidBlockedState.effectiveBlockedReasons;
+ if (mRestrictedNetworkingMode) {
+ uidBlockedState.blockedReasons |= BLOCKED_REASON_RESTRICTED_MODE;
+ } else {
+ uidBlockedState.blockedReasons &= ~BLOCKED_REASON_RESTRICTED_MODE;
+ }
+ if (hasRestrictedModeAccess(uid)) {
+ uidBlockedState.allowedReasons |= ALLOWED_REASON_RESTRICTED_MODE_PERMISSIONS;
+ } else {
+ uidBlockedState.allowedReasons &= ALLOWED_REASON_RESTRICTED_MODE_PERMISSIONS;
+ }
+ uidBlockedState.updateEffectiveBlockedReasons();
+ if (oldEffectiveBlockedReasons != uidBlockedState.effectiveBlockedReasons) {
+ mHandler.obtainMessage(MSG_BLOCKED_REASON_CHANGED, uid,
+ uidBlockedState.effectiveBlockedReasons, oldEffectiveBlockedReasons)
+ .sendToTarget();
+ }
+ }
+
private int getNewRestrictedModeUidRule(int uid, int oldUidRule) {
int newRule = oldUidRule;
newRule &= ~MASK_RESTRICTED_MODE_NETWORKS;
@@ -4074,11 +4132,21 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
boolean isWhitelisted = mPowerSaveTempWhitelistAppIds.get(appId)
|| mPowerSaveWhitelistAppIds.get(appId);
if (!deviceIdleMode) {
- isWhitelisted = isWhitelisted || mPowerSaveWhitelistExceptIdleAppIds.get(appId);
+ isWhitelisted = isWhitelisted || isWhitelistedFromPowerSaveExceptIdleUL(uid);
}
return isWhitelisted;
}
+ /**
+ * Returns whether a uid is allowlisted from power saving restrictions, except Device idle
+ * (eg: Battery Saver and app idle).
+ */
+ @GuardedBy("mUidRulesFirstLock")
+ private boolean isWhitelistedFromPowerSaveExceptIdleUL(int uid) {
+ final int appId = UserHandle.getAppId(uid);
+ return mPowerSaveWhitelistExceptIdleAppIds.get(appId);
+ }
+
// NOTE: since both fw_dozable and fw_powersave uses the same map
// (mPowerSaveTempWhitelistAppIds) for allowlisting, we can reuse their logic in this method.
@GuardedBy("mUidRulesFirstLock")
@@ -4523,6 +4591,11 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
final int oldUidRules = mUidRules.get(uid, RULE_NONE);
final boolean isForeground = isUidForegroundOnRestrictBackgroundUL(uid);
final boolean isRestrictedByAdmin = isRestrictedByAdminUL(uid);
+ UidBlockedState uidBlockedState = mUidBlockedState.get(uid);
+ if (uidBlockedState == null) {
+ uidBlockedState = new UidBlockedState();
+ mUidBlockedState.put(uid, uidBlockedState);
+ }
final boolean isDenied = (uidPolicy & POLICY_REJECT_METERED_BACKGROUND) != 0;
final boolean isAllowed = (uidPolicy & POLICY_ALLOW_METERED_BACKGROUND) != 0;
@@ -4547,6 +4620,16 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
}
}
+ int newBlockedReasons = BLOCKED_REASON_NONE;
+ int newAllowedReasons = ALLOWED_REASON_NONE;
+ newBlockedReasons |= (isRestrictedByAdmin ? BLOCKED_METERED_REASON_ADMIN_DISABLED : 0);
+ newBlockedReasons |= (mRestrictBackground ? BLOCKED_METERED_REASON_DATA_SAVER : 0);
+ newBlockedReasons |= (isDenied ? BLOCKED_METERED_REASON_USER_RESTRICTED : 0);
+
+ newAllowedReasons |= (isSystem(uid) ? ALLOWED_REASON_SYSTEM : 0);
+ newAllowedReasons |= (isForeground ? ALLOWED_REASON_FOREGROUND : 0);
+ newAllowedReasons |= (isAllowed ? ALLOWED_METERED_REASON_USER_EXEMPTED : 0);
+
if (LOGV) {
Log.v(TAG, "updateRuleForRestrictBackgroundUL(" + uid + ")"
+ ": isForeground=" +isForeground
@@ -4618,6 +4701,18 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
// Dispatch changed rule to existing listeners.
mHandler.obtainMessage(MSG_RULES_CHANGED, uid, newUidRules).sendToTarget();
+
+ final int oldEffectiveBlockedReasons = uidBlockedState.effectiveBlockedReasons;
+ uidBlockedState.blockedReasons = (uidBlockedState.blockedReasons
+ & ~BLOCKED_METERED_REASON_MASK) | newBlockedReasons;
+ uidBlockedState.allowedReasons = (uidBlockedState.allowedReasons
+ & ~ALLOWED_METERED_REASON_MASK) | newAllowedReasons;
+ uidBlockedState.updateEffectiveBlockedReasons();
+ if (oldEffectiveBlockedReasons != uidBlockedState.effectiveBlockedReasons) {
+ mHandler.obtainMessage(MSG_BLOCKED_REASON_CHANGED, uid,
+ uidBlockedState.effectiveBlockedReasons, oldEffectiveBlockedReasons)
+ .sendToTarget();
+ }
}
}
@@ -4692,6 +4787,12 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
// Copy existing uid rules and clear ALL_NETWORK rules.
int newUidRules = oldUidRules & (~MASK_ALL_NETWORKS);
+ UidBlockedState uidBlockedState = mUidBlockedState.get(uid);
+ if (uidBlockedState == null) {
+ uidBlockedState = new UidBlockedState();
+ mUidBlockedState.put(uid, uidBlockedState);
+ }
+
// First step: define the new rule based on user restrictions and foreground state.
// NOTE: if statements below could be inlined, but it's easier to understand the logic
@@ -4704,6 +4805,20 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
newUidRules |= isWhitelisted ? RULE_ALLOW_ALL : RULE_REJECT_ALL;
}
+ int newBlockedReasons = BLOCKED_REASON_NONE;
+ int newAllowedReasons = ALLOWED_REASON_NONE;
+ newBlockedReasons |= (mRestrictPower ? BLOCKED_REASON_BATTERY_SAVER : 0);
+ newBlockedReasons |= (mDeviceIdleMode ? BLOCKED_REASON_DOZE : 0);
+ newBlockedReasons |= (isUidIdle ? BLOCKED_REASON_APP_STANDBY : 0);
+ newBlockedReasons |= (uidBlockedState.blockedReasons & BLOCKED_REASON_RESTRICTED_MODE);
+
+ newAllowedReasons |= (isSystem(uid) ? ALLOWED_REASON_SYSTEM : 0);
+ newAllowedReasons |= (isForeground ? ALLOWED_REASON_FOREGROUND : 0);
+ newAllowedReasons |= (isWhitelistedFromPowerSaveUL(uid, true)
+ ? ALLOWED_REASON_POWER_SAVE_ALLOWLIST : 0);
+ newAllowedReasons |= (isWhitelistedFromPowerSaveExceptIdleUL(uid)
+ ? ALLOWED_REASON_POWER_SAVE_EXCEPT_IDLE_ALLOWLIST : 0);
+
if (LOGV) {
Log.v(TAG, "updateRulesForPowerRestrictionsUL(" + uid + ")"
+ ", isIdle: " + isUidIdle
@@ -4735,6 +4850,18 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
mHandler.obtainMessage(MSG_RULES_CHANGED, uid, newUidRules).sendToTarget();
}
+ final int oldEffectiveBlockedReasons = uidBlockedState.effectiveBlockedReasons;
+ uidBlockedState.blockedReasons = (uidBlockedState.blockedReasons
+ & BLOCKED_METERED_REASON_MASK) | newBlockedReasons;
+ uidBlockedState.allowedReasons = (uidBlockedState.allowedReasons
+ & ALLOWED_METERED_REASON_MASK) | newAllowedReasons;
+ uidBlockedState.updateEffectiveBlockedReasons();
+ if (oldEffectiveBlockedReasons != uidBlockedState.effectiveBlockedReasons) {
+ mHandler.obtainMessage(MSG_BLOCKED_REASON_CHANGED, uid,
+ uidBlockedState.effectiveBlockedReasons, oldEffectiveBlockedReasons)
+ .sendToTarget();
+ }
+
return newUidRules;
}
@@ -4764,61 +4891,57 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
}
private void dispatchUidRulesChanged(INetworkPolicyListener listener, int uid, int uidRules) {
- if (listener != null) {
- try {
- listener.onUidRulesChanged(uid, uidRules);
- } catch (RemoteException ignored) {
- }
+ try {
+ listener.onUidRulesChanged(uid, uidRules);
+ } catch (RemoteException ignored) {
}
}
private void dispatchMeteredIfacesChanged(INetworkPolicyListener listener,
String[] meteredIfaces) {
- if (listener != null) {
- try {
- listener.onMeteredIfacesChanged(meteredIfaces);
- } catch (RemoteException ignored) {
- }
+ try {
+ listener.onMeteredIfacesChanged(meteredIfaces);
+ } catch (RemoteException ignored) {
}
}
private void dispatchRestrictBackgroundChanged(INetworkPolicyListener listener,
boolean restrictBackground) {
- if (listener != null) {
- try {
- listener.onRestrictBackgroundChanged(restrictBackground);
- } catch (RemoteException ignored) {
- }
+ try {
+ listener.onRestrictBackgroundChanged(restrictBackground);
+ } catch (RemoteException ignored) {
}
}
private void dispatchUidPoliciesChanged(INetworkPolicyListener listener, int uid,
int uidPolicies) {
- if (listener != null) {
- try {
- listener.onUidPoliciesChanged(uid, uidPolicies);
- } catch (RemoteException ignored) {
- }
+ try {
+ listener.onUidPoliciesChanged(uid, uidPolicies);
+ } catch (RemoteException ignored) {
}
}
private void dispatchSubscriptionOverride(INetworkPolicyListener listener, int subId,
int overrideMask, int overrideValue, int[] networkTypes) {
- if (listener != null) {
- try {
- listener.onSubscriptionOverride(subId, overrideMask, overrideValue, networkTypes);
- } catch (RemoteException ignored) {
- }
+ try {
+ listener.onSubscriptionOverride(subId, overrideMask, overrideValue, networkTypes);
+ } catch (RemoteException ignored) {
}
}
private void dispatchSubscriptionPlansChanged(INetworkPolicyListener listener, int subId,
SubscriptionPlan[] plans) {
- if (listener != null) {
- try {
- listener.onSubscriptionPlansChanged(subId, plans);
- } catch (RemoteException ignored) {
- }
+ try {
+ listener.onSubscriptionPlansChanged(subId, plans);
+ } catch (RemoteException ignored) {
+ }
+ }
+
+ private void dispatchBlockedReasonChanged(INetworkPolicyListener listener, int uid,
+ int oldBlockedReasons, int newBlockedReasons) {
+ try {
+ listener.onBlockedReasonChanged(uid, oldBlockedReasons, newBlockedReasons);
+ } catch (RemoteException ignored) {
}
}
@@ -4975,6 +5098,19 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
mListeners.finishBroadcast();
return true;
}
+ case MSG_BLOCKED_REASON_CHANGED: {
+ final int uid = msg.arg1;
+ final int newBlockedReasons = msg.arg2;
+ final int oldBlockedReasons = (int) msg.obj;
+ final int length = mListeners.beginBroadcast();
+ for (int i = 0; i < length; i++) {
+ final INetworkPolicyListener listener = mListeners.getBroadcastItem(i);
+ dispatchBlockedReasonChanged(listener, uid,
+ oldBlockedReasons, newBlockedReasons);
+ }
+ mListeners.finishBroadcast();
+ return true;
+ }
default: {
return false;
}
@@ -5706,6 +5842,51 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
return (bundle != null) ? bundle.getBoolean(key, defaultValue) : defaultValue;
}
+ private class UidBlockedState {
+ public int blockedReasons;
+ public int allowedReasons;
+ public int effectiveBlockedReasons;
+
+ UidBlockedState() {
+ blockedReasons = BLOCKED_REASON_NONE;
+ allowedReasons = ALLOWED_REASON_NONE;
+ effectiveBlockedReasons = BLOCKED_REASON_NONE;
+ }
+
+ void updateEffectiveBlockedReasons() {
+ effectiveBlockedReasons = blockedReasons;
+ // If the uid is not subject to any blocked reasons, then return early
+ if (blockedReasons == BLOCKED_REASON_NONE) {
+ return;
+ }
+ if ((allowedReasons & ALLOWED_REASON_SYSTEM) != 0) {
+ effectiveBlockedReasons = BLOCKED_REASON_NONE;
+ }
+ if ((allowedReasons & ALLOWED_REASON_FOREGROUND) != 0) {
+ effectiveBlockedReasons &= ~BLOCKED_REASON_BATTERY_SAVER;
+ effectiveBlockedReasons &= ~BLOCKED_REASON_DOZE;
+ effectiveBlockedReasons &= ~BLOCKED_REASON_APP_STANDBY;
+ effectiveBlockedReasons &= ~BLOCKED_METERED_REASON_DATA_SAVER;
+ effectiveBlockedReasons &= ~BLOCKED_METERED_REASON_USER_RESTRICTED;
+ }
+ if ((allowedReasons & ALLOWED_REASON_POWER_SAVE_ALLOWLIST) != 0) {
+ effectiveBlockedReasons &= ~BLOCKED_REASON_BATTERY_SAVER;
+ effectiveBlockedReasons &= ~BLOCKED_REASON_DOZE;
+ effectiveBlockedReasons &= ~BLOCKED_REASON_APP_STANDBY;
+ }
+ if ((allowedReasons & ALLOWED_REASON_POWER_SAVE_EXCEPT_IDLE_ALLOWLIST) != 0) {
+ effectiveBlockedReasons &= ~BLOCKED_REASON_BATTERY_SAVER;
+ effectiveBlockedReasons &= ~BLOCKED_REASON_APP_STANDBY;
+ }
+ if ((allowedReasons & ALLOWED_REASON_RESTRICTED_MODE_PERMISSIONS) != 0) {
+ effectiveBlockedReasons &= ~BLOCKED_REASON_RESTRICTED_MODE;
+ }
+ if ((allowedReasons & ALLOWED_METERED_REASON_USER_EXEMPTED) != 0) {
+ effectiveBlockedReasons &= ~BLOCKED_METERED_REASON_DATA_SAVER;
+ }
+ }
+ }
+
private class NotificationId {
private final String mTag;
private final int mId;
diff --git a/services/core/java/com/android/server/pm/dex/ArtStatsLogUtils.java b/services/core/java/com/android/server/pm/dex/ArtStatsLogUtils.java
index 0c8e36b75425..c8dc1b1ff562 100644
--- a/services/core/java/com/android/server/pm/dex/ArtStatsLogUtils.java
+++ b/services/core/java/com/android/server/pm/dex/ArtStatsLogUtils.java
@@ -146,47 +146,11 @@ public class ArtStatsLogUtils {
uid,
compilationReason,
compilerFilter,
- ArtStatsLog.ART_DATUM_REPORTED__KIND__ART_DATUM_DEX2OAT_DEX_CODE_BYTES,
- getDexBytes(path),
- dexMetadataType);
- logger.write(
- sessionId,
- uid,
- compilationReason,
- compilerFilter,
ArtStatsLog.ART_DATUM_REPORTED__KIND__ART_DATUM_DEX2OAT_TOTAL_TIME,
compileTime,
dexMetadataType);
}
- private static long getDexBytes(String apkPath) {
- StrictJarFile jarFile = null;
- long dexBytes = 0;
- try {
- jarFile = new StrictJarFile(apkPath,
- /*verify=*/ false,
- /*signatureSchemeRollbackProtectionsEnforced=*/ false);
- Iterator<ZipEntry> it = jarFile.iterator();
- while (it.hasNext()) {
- ZipEntry entry = it.next();
- if (entry.getName().matches("classes(\\d)*[.]dex")) {
- dexBytes += entry.getSize();
- }
- }
- return dexBytes;
- } catch (IOException ignore) {
- Slog.e(TAG, "Error when parsing APK " + apkPath);
- return -1L;
- } finally {
- try {
- if (jarFile != null) {
- jarFile.close();
- }
- } catch (IOException ignore) {
- }
- }
- }
-
private static int getDexMetadataType(String dexMetadataPath) {
if (dexMetadataPath == null) {
return ArtStatsLog.ART_DATUM_REPORTED__DEX_METADATA_TYPE__ART_DEX_METADATA_TYPE_NONE;
diff --git a/services/core/java/com/android/server/policy/LegacyGlobalActions.java b/services/core/java/com/android/server/policy/LegacyGlobalActions.java
index 9c3a39440054..5b48abb3e1f2 100644
--- a/services/core/java/com/android/server/policy/LegacyGlobalActions.java
+++ b/services/core/java/com/android/server/policy/LegacyGlobalActions.java
@@ -24,11 +24,11 @@ import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.IntentFilter;
+import android.content.pm.PackageManager;
import android.content.pm.UserInfo;
import android.database.ContentObserver;
import android.graphics.drawable.Drawable;
import android.media.AudioManager;
-import android.net.ConnectivityManager;
import android.os.Build;
import android.os.Handler;
import android.os.Message;
@@ -113,7 +113,7 @@ class LegacyGlobalActions implements DialogInterface.OnDismissListener, DialogIn
private boolean mDeviceProvisioned = false;
private ToggleAction.State mAirplaneState = ToggleAction.State.Off;
private boolean mIsWaitingForEcmExit = false;
- private boolean mHasTelephony;
+ private final boolean mHasTelephony;
private boolean mHasVibrator;
private final boolean mShowSilentToggle;
private final EmergencyAffordanceManager mEmergencyAffordanceManager;
@@ -137,9 +137,8 @@ class LegacyGlobalActions implements DialogInterface.OnDismissListener, DialogIn
filter.addAction(TelephonyManager.ACTION_EMERGENCY_CALLBACK_MODE_CHANGED);
context.registerReceiver(mBroadcastReceiver, filter);
- ConnectivityManager cm = (ConnectivityManager)
- context.getSystemService(Context.CONNECTIVITY_SERVICE);
- mHasTelephony = cm.isNetworkSupported(ConnectivityManager.TYPE_MOBILE);
+ mHasTelephony =
+ context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_TELEPHONY);
// get notified of phone state changes
TelephonyManager telephonyManager =
diff --git a/services/core/java/com/android/server/recoverysystem/RecoverySystemService.java b/services/core/java/com/android/server/recoverysystem/RecoverySystemService.java
index fd2d8e1b834b..beebb3145018 100644
--- a/services/core/java/com/android/server/recoverysystem/RecoverySystemService.java
+++ b/services/core/java/com/android/server/recoverysystem/RecoverySystemService.java
@@ -16,6 +16,8 @@
package com.android.server.recoverysystem;
+import static android.os.UserHandle.USER_SYSTEM;
+
import android.annotation.IntDef;
import android.content.Context;
import android.content.IntentSender;
@@ -33,12 +35,14 @@ import android.os.RemoteException;
import android.os.ResultReceiver;
import android.os.ShellCallback;
import android.os.SystemProperties;
+import android.provider.DeviceConfig;
import android.util.ArrayMap;
import android.util.ArraySet;
import android.util.Slog;
import com.android.internal.annotations.GuardedBy;
import com.android.internal.annotations.VisibleForTesting;
+import com.android.internal.util.FrameworkStatsLog;
import com.android.internal.widget.LockSettingsInternal;
import com.android.internal.widget.RebootEscrowListener;
import com.android.server.LocalServices;
@@ -52,6 +56,8 @@ import java.io.FileDescriptor;
import java.io.FileWriter;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
+import java.util.ArrayList;
+import java.util.List;
/**
* The recovery system service is responsible for coordinating recovery related
@@ -127,10 +133,28 @@ public class RecoverySystemService extends IRecoverySystem.Stub implements Reboo
/**
* The action to perform upon resume on reboot clear request for a given client.
*/
- @IntDef({ROR_NOT_REQUESTED,
+ @IntDef({ ROR_NOT_REQUESTED,
ROR_REQUESTED_NEED_CLEAR,
ROR_REQUESTED_SKIP_CLEAR})
- private @interface ResumeOnRebootActionsOnClear{}
+ private @interface ResumeOnRebootActionsOnClear {}
+
+ /**
+ * The error code for reboots initiated by resume on reboot clients.
+ */
+ private static final int REBOOT_ERROR_NONE = 0;
+ private static final int REBOOT_ERROR_UNKNOWN = 1;
+ private static final int REBOOT_ERROR_INVALID_PACKAGE_NAME = 2;
+ private static final int REBOOT_ERROR_LSKF_NOT_CAPTURED = 3;
+ private static final int REBOOT_ERROR_SLOT_MISMATCH = 4;
+ private static final int REBOOT_ERROR_ARM_REBOOT_ESCROW_FAILURE = 5;
+
+ @IntDef({ REBOOT_ERROR_NONE,
+ REBOOT_ERROR_UNKNOWN,
+ REBOOT_ERROR_INVALID_PACKAGE_NAME,
+ REBOOT_ERROR_LSKF_NOT_CAPTURED,
+ REBOOT_ERROR_SLOT_MISMATCH,
+ REBOOT_ERROR_ARM_REBOOT_ESCROW_FAILURE})
+ private @interface ResumeOnRebootRebootErrorCode {}
static class Injector {
protected final Context mContext;
@@ -202,6 +226,35 @@ public class RecoverySystemService extends IRecoverySystem.Stub implements Reboo
public void threadSleep(long millis) throws InterruptedException {
Thread.sleep(millis);
}
+
+ public int getUidFromPackageName(String packageName) {
+ try {
+ return mContext.getPackageManager().getPackageUidAsUser(packageName, USER_SYSTEM);
+ } catch (PackageManager.NameNotFoundException e) {
+ Slog.w(TAG, "Failed to find uid for " + packageName);
+ }
+ return -1;
+ }
+
+ public void reportRebootEscrowPreparationMetrics(int uid,
+ @ResumeOnRebootActionsOnRequest int requestResult, int requestedClientCount) {
+ FrameworkStatsLog.write(FrameworkStatsLog.REBOOT_ESCROW_PREPARATION_REPORTED, uid,
+ requestResult, requestedClientCount);
+ }
+
+ public void reportRebootEscrowLskfCapturedMetrics(int uid, int requestedClientCount,
+ int requestedToLskfCapturedDurationInSeconds) {
+ FrameworkStatsLog.write(FrameworkStatsLog.REBOOT_ESCROW_LSKF_CAPTURE_REPORTED, uid,
+ requestedClientCount, requestedToLskfCapturedDurationInSeconds);
+ }
+
+ public void reportRebootEscrowRebootMetrics(int errorCode, int uid,
+ int preparedClientCount, int requestCount, boolean slotSwitch, boolean serverBased,
+ int lskfCapturedToRebootDurationInSeconds, int lskfCapturedCounts) {
+ FrameworkStatsLog.write(FrameworkStatsLog.REBOOT_ESCROW_REBOOT_REPORTED, errorCode,
+ uid, preparedClientCount, requestCount, slotSwitch, serverBased,
+ lskfCapturedToRebootDurationInSeconds, lskfCapturedCounts);
+ }
}
/**
@@ -367,6 +420,16 @@ public class RecoverySystemService extends IRecoverySystem.Stub implements Reboo
}
}
+ private void reportMetricsOnRequestLskf(String packageName, int requestResult) {
+ int uid = mInjector.getUidFromPackageName(packageName);
+ int pendingRequestCount;
+ synchronized (this) {
+ pendingRequestCount = mCallerPendingRequest.size();
+ }
+
+ mInjector.reportRebootEscrowPreparationMetrics(uid, requestResult, pendingRequestCount);
+ }
+
@Override // Binder call
public boolean requestLskf(String packageName, IntentSender intentSender) {
enforcePermissionForResumeOnReboot();
@@ -378,6 +441,8 @@ public class RecoverySystemService extends IRecoverySystem.Stub implements Reboo
@ResumeOnRebootActionsOnRequest int action = updateRoRPreparationStateOnNewRequest(
packageName, intentSender);
+ reportMetricsOnRequestLskf(packageName, action);
+
switch (action) {
case ROR_SKIP_PREPARATION_AND_NOTIFY:
// We consider the preparation done if someone else has prepared.
@@ -420,12 +485,26 @@ public class RecoverySystemService extends IRecoverySystem.Stub implements Reboo
return needPreparation ? ROR_NEED_PREPARATION : ROR_SKIP_PREPARATION_NOT_NOTIFY;
}
+ private void reportMetricsOnPreparedForReboot() {
+ List<String> preparedClients;
+ synchronized (this) {
+ preparedClients = new ArrayList<>(mCallerPreparedForReboot);
+ }
+
+ for (String packageName : preparedClients) {
+ int uid = mInjector.getUidFromPackageName(packageName);
+ mInjector.reportRebootEscrowLskfCapturedMetrics(uid, preparedClients.size(),
+ -1 /* duration */);
+ }
+ }
+
@Override
public void onPreparedForReboot(boolean ready) {
if (!ready) {
return;
}
updateRoRPreparationStateOnPreparedForReboot();
+ reportMetricsOnPreparedForReboot();
}
private synchronized void updateRoRPreparationStateOnPreparedForReboot() {
@@ -548,22 +627,49 @@ public class RecoverySystemService extends IRecoverySystem.Stub implements Reboo
return true;
}
- private boolean rebootWithLskfImpl(String packageName, String reason, boolean slotSwitch) {
+ private @ResumeOnRebootRebootErrorCode int armRebootEscrow(String packageName,
+ boolean slotSwitch) {
if (packageName == null) {
Slog.w(TAG, "Missing packageName when rebooting with lskf.");
- return false;
+ return REBOOT_ERROR_INVALID_PACKAGE_NAME;
}
if (!isLskfCaptured(packageName)) {
- return false;
+ return REBOOT_ERROR_LSKF_NOT_CAPTURED;
}
if (!verifySlotForNextBoot(slotSwitch)) {
- return false;
+ return REBOOT_ERROR_SLOT_MISMATCH;
}
- // TODO(xunchang) write the vbmeta digest along with the escrowKey before reboot.
if (!mInjector.getLockSettingsService().armRebootEscrow()) {
Slog.w(TAG, "Failure to escrow key for reboot");
+ return REBOOT_ERROR_ARM_REBOOT_ESCROW_FAILURE;
+ }
+
+ return REBOOT_ERROR_NONE;
+ }
+
+ private void reportMetricsOnRebootWithLskf(String packageName, boolean slotSwitch,
+ @ResumeOnRebootRebootErrorCode int errorCode) {
+ int uid = mInjector.getUidFromPackageName(packageName);
+ boolean serverBased = DeviceConfig.getBoolean(DeviceConfig.NAMESPACE_OTA,
+ "server_based_ror_enabled", false);
+ int preparedClientCount;
+ synchronized (this) {
+ preparedClientCount = mCallerPreparedForReboot.size();
+ }
+
+ // TODO(b/179105110) report the true value of duration and counts
+ mInjector.reportRebootEscrowRebootMetrics(errorCode, uid, preparedClientCount,
+ 1 /* request count */, slotSwitch, serverBased,
+ -1 /* duration */, 1 /* lskf capture count */);
+ }
+
+ private boolean rebootWithLskfImpl(String packageName, String reason, boolean slotSwitch) {
+ @ResumeOnRebootRebootErrorCode int errorCode = armRebootEscrow(packageName, slotSwitch);
+ reportMetricsOnRebootWithLskf(packageName, slotSwitch, errorCode);
+
+ if (errorCode != REBOOT_ERROR_NONE) {
return false;
}
diff --git a/services/core/java/com/android/server/vcn/VcnGatewayConnection.java b/services/core/java/com/android/server/vcn/VcnGatewayConnection.java
index 69a153f79a1b..9589505ef251 100644
--- a/services/core/java/com/android/server/vcn/VcnGatewayConnection.java
+++ b/services/core/java/com/android/server/vcn/VcnGatewayConnection.java
@@ -42,7 +42,6 @@ import android.net.LinkAddress;
import android.net.LinkProperties;
import android.net.Network;
import android.net.NetworkAgent;
-import android.net.NetworkAgent.ValidationStatus;
import android.net.NetworkAgentConfig;
import android.net.NetworkCapabilities;
import android.net.RouteInfo;
@@ -1442,17 +1441,16 @@ public class VcnGatewayConnection extends StateMachine {
caps,
lp,
Vcn.getNetworkScore(),
- new NetworkAgentConfig(),
+ new NetworkAgentConfig.Builder().build(),
mVcnContext.getVcnNetworkProvider()) {
@Override
- public void unwanted() {
+ public void onNetworkUnwanted() {
Slog.d(TAG, "NetworkAgent was unwanted");
teardownAsynchronously();
}
@Override
- public void onValidationStatus(
- @ValidationStatus int status, @Nullable Uri redirectUri) {
+ public void onValidationStatus(int status, @Nullable Uri redirectUri) {
if (status == NetworkAgent.VALIDATION_STATUS_VALID) {
clearFailedAttemptCounterAndSafeModeAlarm();
}
@@ -1798,8 +1796,10 @@ public class VcnGatewayConnection extends StateMachine {
lp.addDnsServer(addr);
}
- lp.addRoute(new RouteInfo(new IpPrefix(Inet4Address.ANY, 0), null));
- lp.addRoute(new RouteInfo(new IpPrefix(Inet6Address.ANY, 0), null));
+ lp.addRoute(new RouteInfo(new IpPrefix(Inet4Address.ANY, 0), null /*gateway*/,
+ null /*iface*/, RouteInfo.RTN_UNICAST));
+ lp.addRoute(new RouteInfo(new IpPrefix(Inet6Address.ANY, 0), null /*gateway*/,
+ null /*iface*/, RouteInfo.RTN_UNICAST));
lp.setMtu(gatewayConnectionConfig.getMaxMtu());
diff --git a/services/tests/mockingservicestests/src/com/android/server/pm/dex/OWNERS b/services/tests/mockingservicestests/src/com/android/server/pm/dex/OWNERS
index 5a4431ee8c89..5492dc8e37a3 100644
--- a/services/tests/mockingservicestests/src/com/android/server/pm/dex/OWNERS
+++ b/services/tests/mockingservicestests/src/com/android/server/pm/dex/OWNERS
@@ -1,2 +1 @@
-calin@google.com
-ngeoffray@google.com
+include platform/art:/OWNERS \ No newline at end of file
diff --git a/services/tests/servicestests/src/com/android/server/pm/dex/ArtStatsLogUtilsTest.java b/services/tests/servicestests/src/com/android/server/pm/dex/ArtStatsLogUtilsTest.java
index e605d755183f..13d75a77507f 100644
--- a/services/tests/servicestests/src/com/android/server/pm/dex/ArtStatsLogUtilsTest.java
+++ b/services/tests/servicestests/src/com/android/server/pm/dex/ArtStatsLogUtilsTest.java
@@ -245,14 +245,6 @@ public final class ArtStatsLogUtilsTest {
UID,
COMPILATION_REASON,
COMPILER_FILTER,
- ArtStatsLog.ART_DATUM_REPORTED__KIND__ART_DATUM_DEX2OAT_DEX_CODE_BYTES,
- DEX_CONTENT.length,
- dexMetadataType);
- inorder.verify(mockLogger).write(
- SESSION_ID,
- UID,
- COMPILATION_REASON,
- COMPILER_FILTER,
ArtStatsLog.ART_DATUM_REPORTED__KIND__ART_DATUM_DEX2OAT_TOTAL_TIME,
COMPILE_TIME,
dexMetadataType);
diff --git a/services/tests/servicestests/src/com/android/server/recoverysystem/RecoverySystemServiceTest.java b/services/tests/servicestests/src/com/android/server/recoverysystem/RecoverySystemServiceTest.java
index 9b8a2a82c6df..324e5929f77f 100644
--- a/services/tests/servicestests/src/com/android/server/recoverysystem/RecoverySystemServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/recoverysystem/RecoverySystemServiceTest.java
@@ -18,6 +18,7 @@ package com.android.server.recoverysystem;
import static org.hamcrest.CoreMatchers.is;
import static org.junit.Assert.assertThat;
+import static org.mockito.AdditionalMatchers.not;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyBoolean;
import static org.mockito.ArgumentMatchers.anyInt;
@@ -70,6 +71,7 @@ public class RecoverySystemServiceTest {
private FileWriter mUncryptUpdateFileWriter;
private LockSettingsInternal mLockSettingsInternal;
private IBootControl mIBootControl;
+ private RecoverySystemServiceTestable.IMetricsReporter mMetricsReporter;
private static final String FAKE_OTA_PACKAGE_NAME = "fake.ota.package";
private static final String FAKE_OTHER_PACKAGE_NAME = "fake.other.package";
@@ -94,9 +96,11 @@ public class RecoverySystemServiceTest {
when(mIBootControl.getCurrentSlot()).thenReturn(0);
when(mIBootControl.getActiveBootSlot()).thenReturn(1);
+ mMetricsReporter = mock(RecoverySystemServiceTestable.IMetricsReporter.class);
+
mRecoverySystemService = new RecoverySystemServiceTestable(mContext, mSystemProperties,
powerManager, mUncryptUpdateFileWriter, mUncryptSocket, mLockSettingsInternal,
- mIBootControl);
+ mIBootControl, mMetricsReporter);
}
@Test
@@ -227,12 +231,24 @@ public class RecoverySystemServiceTest {
}
@Test
+ public void requestLskf_reportMetrics() throws Exception {
+ IntentSender intentSender = mock(IntentSender.class);
+ assertThat(mRecoverySystemService.requestLskf(FAKE_OTA_PACKAGE_NAME, intentSender),
+ is(true));
+ verify(mMetricsReporter).reportRebootEscrowPreparationMetrics(
+ eq(1000), eq(0) /* need preparation */, eq(1) /* client count */);
+ }
+
+
+ @Test
public void requestLskf_success() throws Exception {
IntentSender intentSender = mock(IntentSender.class);
assertThat(mRecoverySystemService.requestLskf(FAKE_OTA_PACKAGE_NAME, intentSender),
is(true));
mRecoverySystemService.onPreparedForReboot(true);
verify(intentSender).sendIntent(any(), anyInt(), any(), any(), any());
+ verify(mMetricsReporter).reportRebootEscrowLskfCapturedMetrics(
+ eq(1000), eq(1) /* client count */, anyInt() /* duration */);
}
@Test
@@ -255,6 +271,8 @@ public class RecoverySystemServiceTest {
assertThat(mRecoverySystemService.requestLskf(FAKE_OTA_PACKAGE_NAME, intentSender),
is(true));
verify(intentSender, never()).sendIntent(any(), anyInt(), any(), any(), any());
+ verify(mMetricsReporter, never()).reportRebootEscrowLskfCapturedMetrics(
+ anyInt(), anyInt(), anyInt());
}
@Test
@@ -337,6 +355,9 @@ public class RecoverySystemServiceTest {
assertThat(mRecoverySystemService.rebootWithLskf(FAKE_OTA_PACKAGE_NAME, "ab-update", true),
is(true));
verify(mIPowerManager).reboot(anyBoolean(), eq("ab-update"), anyBoolean());
+ verify(mMetricsReporter).reportRebootEscrowRebootMetrics(eq(0), eq(1000),
+ eq(1) /* client count */, eq(1) /* request count */, eq(true) /* slot switch */,
+ anyBoolean(), anyInt(), eq(1) /* lskf capture count */);
}
@@ -373,6 +394,20 @@ public class RecoverySystemServiceTest {
verify(mIPowerManager).reboot(anyBoolean(), eq("ab-update"), anyBoolean());
}
+ @Test
+ public void rebootWithLskf_multiClient_success_reportMetrics() throws Exception {
+ assertThat(mRecoverySystemService.requestLskf(FAKE_OTA_PACKAGE_NAME, null), is(true));
+ assertThat(mRecoverySystemService.requestLskf(FAKE_OTHER_PACKAGE_NAME, null), is(true));
+ mRecoverySystemService.onPreparedForReboot(true);
+
+ // Client B's clear won't affect client A's preparation.
+ assertThat(mRecoverySystemService.rebootWithLskf(FAKE_OTA_PACKAGE_NAME, "ab-update", true),
+ is(true));
+ verify(mIPowerManager).reboot(anyBoolean(), eq("ab-update"), anyBoolean());
+ verify(mMetricsReporter).reportRebootEscrowRebootMetrics(eq(0), eq(1000),
+ eq(2) /* client count */, eq(1) /* request count */, eq(true) /* slot switch */,
+ anyBoolean(), anyInt(), eq(1) /* lskf capture count */);
+ }
@Test
public void rebootWithLskf_multiClient_ClientBSuccess() throws Exception {
@@ -384,12 +419,18 @@ public class RecoverySystemServiceTest {
assertThat(mRecoverySystemService.rebootWithLskf(FAKE_OTA_PACKAGE_NAME, null, true),
is(false));
verifyNoMoreInteractions(mIPowerManager);
+ verify(mMetricsReporter).reportRebootEscrowRebootMetrics(not(eq(0)), eq(1000),
+ eq(1) /* client count */, eq(1) /* request count */, eq(true) /* slot switch */,
+ anyBoolean(), anyInt(), eq(1) /* lskf capture count */);
assertThat(mRecoverySystemService.requestLskf(FAKE_OTHER_PACKAGE_NAME, null), is(true));
assertThat(
mRecoverySystemService.rebootWithLskf(FAKE_OTHER_PACKAGE_NAME, "ab-update", true),
is(true));
verify(mIPowerManager).reboot(anyBoolean(), eq("ab-update"), anyBoolean());
+ verify(mMetricsReporter).reportRebootEscrowRebootMetrics(eq(0), eq(2000),
+ eq(1) /* client count */, eq(1) /* request count */, eq(true) /* slot switch */,
+ anyBoolean(), anyInt(), eq(1) /* lskf capture count */);
}
@Test
diff --git a/services/tests/servicestests/src/com/android/server/recoverysystem/RecoverySystemServiceTestable.java b/services/tests/servicestests/src/com/android/server/recoverysystem/RecoverySystemServiceTestable.java
index 0727e5adb9ca..a894178fca06 100644
--- a/services/tests/servicestests/src/com/android/server/recoverysystem/RecoverySystemServiceTestable.java
+++ b/services/tests/servicestests/src/com/android/server/recoverysystem/RecoverySystemServiceTestable.java
@@ -32,11 +32,12 @@ public class RecoverySystemServiceTestable extends RecoverySystemService {
private final UncryptSocket mUncryptSocket;
private final LockSettingsInternal mLockSettingsInternal;
private final IBootControl mIBootControl;
+ private final IMetricsReporter mIMetricsReporter;
MockInjector(Context context, FakeSystemProperties systemProperties,
PowerManager powerManager, FileWriter uncryptPackageFileWriter,
UncryptSocket uncryptSocket, LockSettingsInternal lockSettingsInternal,
- IBootControl bootControl) {
+ IBootControl bootControl, IMetricsReporter metricsReporter) {
super(context);
mSystemProperties = systemProperties;
mPowerManager = powerManager;
@@ -44,6 +45,7 @@ public class RecoverySystemServiceTestable extends RecoverySystemService {
mUncryptSocket = uncryptSocket;
mLockSettingsInternal = lockSettingsInternal;
mIBootControl = bootControl;
+ mIMetricsReporter = metricsReporter;
}
@Override
@@ -94,14 +96,45 @@ public class RecoverySystemServiceTestable extends RecoverySystemService {
public IBootControl getBootControl() {
return mIBootControl;
}
+ @Override
+ public int getUidFromPackageName(String packageName) {
+ if ("fake.ota.package".equals(packageName)) {
+ return 1000;
+ }
+ if ("fake.other.package".equals(packageName)) {
+ return 2000;
+ }
+ return 3000;
+ }
+
+ @Override
+ public void reportRebootEscrowPreparationMetrics(int uid, int requestResult,
+ int requestedClientCount) {
+ mIMetricsReporter.reportRebootEscrowPreparationMetrics(uid, requestResult,
+ requestedClientCount);
+ }
+
+ public void reportRebootEscrowLskfCapturedMetrics(int uid, int requestedClientCount,
+ int requestedToLskfCapturedDurationInSeconds) {
+ mIMetricsReporter.reportRebootEscrowLskfCapturedMetrics(uid, requestedClientCount,
+ requestedToLskfCapturedDurationInSeconds);
+ }
+
+ public void reportRebootEscrowRebootMetrics(int errorCode, int uid, int preparedClientCount,
+ int requestCount, boolean slotSwitch, boolean serverBased,
+ int lskfCapturedToRebootDurationInSeconds, int lskfCapturedCounts) {
+ mIMetricsReporter.reportRebootEscrowRebootMetrics(errorCode, uid, preparedClientCount,
+ requestCount, slotSwitch, serverBased, lskfCapturedToRebootDurationInSeconds,
+ lskfCapturedCounts);
+ }
}
RecoverySystemServiceTestable(Context context, FakeSystemProperties systemProperties,
PowerManager powerManager, FileWriter uncryptPackageFileWriter,
UncryptSocket uncryptSocket, LockSettingsInternal lockSettingsInternal,
- IBootControl bootControl) {
+ IBootControl bootControl, IMetricsReporter metricsReporter) {
super(new MockInjector(context, systemProperties, powerManager, uncryptPackageFileWriter,
- uncryptSocket, lockSettingsInternal, bootControl));
+ uncryptSocket, lockSettingsInternal, bootControl, metricsReporter));
}
public static class FakeSystemProperties {
@@ -131,4 +164,17 @@ public class RecoverySystemServiceTestable extends RecoverySystemService {
return mCtlStart;
}
}
+
+ public interface IMetricsReporter {
+ void reportRebootEscrowPreparationMetrics(int uid, int requestResult,
+ int requestedClientCount);
+
+ void reportRebootEscrowLskfCapturedMetrics(int uid, int requestedClientCount,
+ int requestedToLskfCapturedDurationInSeconds);
+
+ void reportRebootEscrowRebootMetrics(int errorCode, int uid, int preparedClientCount,
+ int requestCount, boolean slotSwitch, boolean serverBased,
+ int lskfCapturedToRebootDurationInSeconds, int lskfCapturedCounts);
+ }
+
}
diff --git a/services/usb/java/com/android/server/usb/UsbPortManager.java b/services/usb/java/com/android/server/usb/UsbPortManager.java
index ec7d4bd0d8c0..647a2a2ec53d 100644
--- a/services/usb/java/com/android/server/usb/UsbPortManager.java
+++ b/services/usb/java/com/android/server/usb/UsbPortManager.java
@@ -60,9 +60,9 @@ import android.os.Parcelable;
import android.os.RemoteException;
import android.os.SystemClock;
import android.os.UserHandle;
+import android.service.ServiceProtoEnums;
import android.service.usb.UsbPortInfoProto;
import android.service.usb.UsbPortManagerProto;
-import android.service.usb.UsbServiceProto;
import android.util.ArrayMap;
import android.util.Log;
import android.util.Slog;
@@ -992,15 +992,15 @@ public class UsbPortManager {
private static int convertContaminantDetectionStatusToProto(int contaminantDetectionStatus) {
switch (contaminantDetectionStatus) {
case UsbPortStatus.CONTAMINANT_DETECTION_NOT_SUPPORTED:
- return UsbServiceProto.CONTAMINANT_STATUS_NOT_SUPPORTED;
+ return ServiceProtoEnums.CONTAMINANT_STATUS_NOT_SUPPORTED;
case UsbPortStatus.CONTAMINANT_DETECTION_DISABLED:
- return UsbServiceProto.CONTAMINANT_STATUS_DISABLED;
+ return ServiceProtoEnums.CONTAMINANT_STATUS_DISABLED;
case UsbPortStatus.CONTAMINANT_DETECTION_NOT_DETECTED:
- return UsbServiceProto.CONTAMINANT_STATUS_NOT_DETECTED;
+ return ServiceProtoEnums.CONTAMINANT_STATUS_NOT_DETECTED;
case UsbPortStatus.CONTAMINANT_DETECTION_DETECTED:
- return UsbServiceProto.CONTAMINANT_STATUS_DETECTED;
+ return ServiceProtoEnums.CONTAMINANT_STATUS_DETECTED;
default:
- return UsbServiceProto.CONTAMINANT_STATUS_UNKNOWN;
+ return ServiceProtoEnums.CONTAMINANT_STATUS_UNKNOWN;
}
}
diff --git a/telephony/java/android/telephony/CarrierConfigManager.java b/telephony/java/android/telephony/CarrierConfigManager.java
index 217570e1401c..464d37510034 100644
--- a/telephony/java/android/telephony/CarrierConfigManager.java
+++ b/telephony/java/android/telephony/CarrierConfigManager.java
@@ -4268,6 +4268,14 @@ public class CarrierConfigManager {
public static final String KEY_STORE_SIM_PIN_FOR_UNATTENDED_REBOOT_BOOL =
"store_sim_pin_for_unattended_reboot_bool";
+ /**
+ * Determine whether "Enable 2G" toggle can be shown.
+ *
+ * Used to trade privacy/security against potentially reduced carrier coverage for some
+ * carriers.
+ */
+ public static final String KEY_HIDE_ENABLE_2G = "hide_enable_2g_bool";
+
/** The default value for every variable. */
private final static PersistableBundle sDefaults;
@@ -4825,6 +4833,7 @@ public class CarrierConfigManager {
sDefaults.putStringArray(KEY_ALLOWED_INITIAL_ATTACH_APN_TYPES_STRING_ARRAY,
new String[]{"ia", "default", "ims", "mms", "dun", "emergency"});
sDefaults.putBoolean(KEY_STORE_SIM_PIN_FOR_UNATTENDED_REBOOT_BOOL, true);
+ sDefaults.putBoolean(KEY_HIDE_ENABLE_2G, false);
}
/**
diff --git a/telephony/java/android/telephony/TelephonyManager.java b/telephony/java/android/telephony/TelephonyManager.java
index 99b5687ba20d..26fcf5e08508 100644
--- a/telephony/java/android/telephony/TelephonyManager.java
+++ b/telephony/java/android/telephony/TelephonyManager.java
@@ -8224,7 +8224,8 @@ public class TelephonyManager {
@IntDef({
ALLOWED_NETWORK_TYPES_REASON_USER,
ALLOWED_NETWORK_TYPES_REASON_POWER,
- ALLOWED_NETWORK_TYPES_REASON_CARRIER
+ ALLOWED_NETWORK_TYPES_REASON_CARRIER,
+ ALLOWED_NETWORK_TYPES_REASON_ENABLE_2G
})
@Retention(RetentionPolicy.SOURCE)
public @interface AllowedNetworkTypesReason {
@@ -8261,6 +8262,14 @@ public class TelephonyManager {
public static final int ALLOWED_NETWORK_TYPES_REASON_CARRIER = 2;
/**
+ * To indicate allowed network type change is requested by the user via the 2G toggle.
+ *
+ * @hide
+ */
+ @SystemApi
+ public static final int ALLOWED_NETWORK_TYPES_REASON_ENABLE_2G = 3;
+
+ /**
* Set the allowed network types of the device and
* provide the reason triggering the allowed network change.
* This can be called for following reasons
@@ -8269,6 +8278,8 @@ public class TelephonyManager {
* <li>Allowed network types control by power manager
* {@link #ALLOWED_NETWORK_TYPES_REASON_POWER}
* <li>Allowed network types control by carrier {@link #ALLOWED_NETWORK_TYPES_REASON_CARRIER}
+ * <li>Allowed network types control by the user-controlled "Allow 2G" toggle
+ * {@link #ALLOWED_NETWORK_TYPES_REASON_ENABLE_2G}
* </ol>
* This API will result in allowing an intersection of allowed network types for all reasons,
* including the configuration done through other reasons.
@@ -8358,6 +8369,7 @@ public class TelephonyManager {
case TelephonyManager.ALLOWED_NETWORK_TYPES_REASON_USER:
case TelephonyManager.ALLOWED_NETWORK_TYPES_REASON_POWER:
case TelephonyManager.ALLOWED_NETWORK_TYPES_REASON_CARRIER:
+ case TelephonyManager.ALLOWED_NETWORK_TYPES_REASON_ENABLE_2G:
return true;
}
return false;
@@ -14574,6 +14586,11 @@ public class TelephonyManager {
*/
public void registerTelephonyCallback(@NonNull @CallbackExecutor Executor executor,
@NonNull TelephonyCallback callback) {
+
+ if (mContext == null) {
+ throw new IllegalStateException("telephony service is null.");
+ }
+
if (executor == null || callback == null) {
throw new IllegalArgumentException("TelephonyCallback and executor must be non-null");
}
diff --git a/tests/net/java/com/android/server/ConnectivityServiceTest.java b/tests/net/java/com/android/server/ConnectivityServiceTest.java
index 7ac488d7de21..c4f3fea770ed 100644
--- a/tests/net/java/com/android/server/ConnectivityServiceTest.java
+++ b/tests/net/java/com/android/server/ConnectivityServiceTest.java
@@ -87,10 +87,10 @@ import static android.net.NetworkCapabilities.TRANSPORT_ETHERNET;
import static android.net.NetworkCapabilities.TRANSPORT_VPN;
import static android.net.NetworkCapabilities.TRANSPORT_WIFI;
import static android.net.NetworkCapabilities.TRANSPORT_WIFI_AWARE;
-import static android.net.NetworkPolicyManager.RULE_ALLOW_METERED;
-import static android.net.NetworkPolicyManager.RULE_NONE;
-import static android.net.NetworkPolicyManager.RULE_REJECT_ALL;
-import static android.net.NetworkPolicyManager.RULE_REJECT_METERED;
+import static android.net.NetworkPolicyManager.BLOCKED_METERED_REASON_DATA_SAVER;
+import static android.net.NetworkPolicyManager.BLOCKED_METERED_REASON_USER_RESTRICTED;
+import static android.net.NetworkPolicyManager.BLOCKED_REASON_BATTERY_SAVER;
+import static android.net.NetworkPolicyManager.BLOCKED_REASON_NONE;
import static android.net.OemNetworkPreferences.OEM_NETWORK_PREFERENCE_OEM_PAID;
import static android.net.OemNetworkPreferences.OEM_NETWORK_PREFERENCE_OEM_PAID_NO_FALLBACK;
import static android.net.OemNetworkPreferences.OEM_NETWORK_PREFERENCE_OEM_PAID_ONLY;
@@ -188,7 +188,6 @@ import android.net.IDnsResolver;
import android.net.INetd;
import android.net.INetworkMonitor;
import android.net.INetworkMonitorCallbacks;
-import android.net.INetworkPolicyListener;
import android.net.IOnCompleteListener;
import android.net.IQosCallback;
import android.net.InetAddresses;
@@ -207,6 +206,7 @@ import android.net.NetworkFactory;
import android.net.NetworkInfo;
import android.net.NetworkInfo.DetailedState;
import android.net.NetworkPolicyManager;
+import android.net.NetworkPolicyManager.NetworkPolicyCallback;
import android.net.NetworkRequest;
import android.net.NetworkScore;
import android.net.NetworkSpecifier;
@@ -423,7 +423,7 @@ public class ConnectivityServiceTest {
private TestNetworkAgentWrapper mEthernetNetworkAgent;
private MockVpn mMockVpn;
private Context mContext;
- private INetworkPolicyListener mPolicyListener;
+ private NetworkPolicyCallback mPolicyCallback;
private WrappedMultinetworkPolicyTracker mPolicyTracker;
private HandlerThread mAlarmManagerThread;
private TestNetIdManager mNetIdManager;
@@ -435,8 +435,7 @@ public class ConnectivityServiceTest {
private TestNetworkCallback mProfileDefaultNetworkCallback;
// State variables required to emulate NetworkPolicyManagerService behaviour.
- private int mUidRules = RULE_NONE;
- private boolean mRestrictBackground = false;
+ private int mBlockedReasons = BLOCKED_REASON_NONE;
@Mock DeviceIdleInternal mDeviceIdleInternal;
@Mock INetworkManagementService mNetworkManagementService;
@@ -1375,28 +1374,13 @@ public class ConnectivityServiceTest {
}
private void mockUidNetworkingBlocked() {
- doAnswer(i -> mContext.getSystemService(NetworkPolicyManager.class)
- .checkUidNetworkingBlocked(i.getArgument(0) /* uid */, mUidRules,
- i.getArgument(1) /* metered */, mRestrictBackground)
+ doAnswer(i -> NetworkPolicyManager.isUidBlocked(mBlockedReasons, i.getArgument(1))
).when(mNetworkPolicyManager).isUidNetworkingBlocked(anyInt(), anyBoolean());
-
- doAnswer(inv -> mContext.getSystemService(NetworkPolicyManager.class)
- .checkUidNetworkingBlocked(inv.getArgument(0) /* uid */,
- inv.getArgument(1) /* uidRules */,
- inv.getArgument(2) /* isNetworkMetered */,
- inv.getArgument(3) /* isBackgroundRestricted */)
- ).when(mNetworkPolicyManager).checkUidNetworkingBlocked(
- anyInt(), anyInt(), anyBoolean(), anyBoolean());
- }
-
- private void setUidRulesChanged(int uidRules) throws RemoteException {
- mUidRules = uidRules;
- mPolicyListener.onUidRulesChanged(Process.myUid(), mUidRules);
}
- private void setRestrictBackgroundChanged(boolean restrictBackground) throws RemoteException {
- mRestrictBackground = restrictBackground;
- mPolicyListener.onRestrictBackgroundChanged(mRestrictBackground);
+ private void setBlockedReasonChanged(int blockedReasons) {
+ mBlockedReasons = blockedReasons;
+ mPolicyCallback.onUidBlockedReasonChanged(Process.myUid(), blockedReasons);
}
private Nat464Xlat getNat464Xlat(NetworkAgentWrapper mna) {
@@ -1538,10 +1522,11 @@ public class ConnectivityServiceTest {
mService.mNascentDelayMs = TEST_NASCENT_DELAY_MS;
verify(mDeps).makeMultinetworkPolicyTracker(any(), any(), any());
- final ArgumentCaptor<INetworkPolicyListener> policyListenerCaptor =
- ArgumentCaptor.forClass(INetworkPolicyListener.class);
- verify(mNetworkPolicyManager).registerListener(policyListenerCaptor.capture());
- mPolicyListener = policyListenerCaptor.getValue();
+ final ArgumentCaptor<NetworkPolicyCallback> policyCallbackCaptor =
+ ArgumentCaptor.forClass(NetworkPolicyCallback.class);
+ verify(mNetworkPolicyManager).registerNetworkPolicyCallback(any(),
+ policyCallbackCaptor.capture());
+ mPolicyCallback = policyCallbackCaptor.getValue();
// Create local CM before sending system ready so that we can answer
// getSystemService() correctly.
@@ -4343,6 +4328,7 @@ public class ConnectivityServiceTest {
assertTrue(mPolicyTracker.shouldNotifyWifiUnvalidated());
}
+ @Ignore("Refactoring in progress b/178071397")
@Test
public void testAvoidBadWifi() throws Exception {
final ContentResolver cr = mServiceContext.getContentResolver();
@@ -7265,7 +7251,7 @@ public class ConnectivityServiceTest {
assertNetworkInfo(TYPE_MOBILE, DetailedState.CONNECTED);
assertExtraInfoFromCmPresent(mCellNetworkAgent);
- setUidRulesChanged(RULE_REJECT_ALL);
+ setBlockedReasonChanged(BLOCKED_REASON_BATTERY_SAVER);
cellNetworkCallback.expectBlockedStatusCallback(true, mCellNetworkAgent);
assertNull(mCm.getActiveNetwork());
assertActiveNetworkInfo(TYPE_MOBILE, DetailedState.BLOCKED);
@@ -7273,17 +7259,17 @@ public class ConnectivityServiceTest {
assertExtraInfoFromCmBlocked(mCellNetworkAgent);
// ConnectivityService should cache it not to invoke the callback again.
- setUidRulesChanged(RULE_REJECT_METERED);
+ setBlockedReasonChanged(BLOCKED_METERED_REASON_USER_RESTRICTED);
cellNetworkCallback.assertNoCallback();
- setUidRulesChanged(RULE_NONE);
+ setBlockedReasonChanged(BLOCKED_REASON_NONE);
cellNetworkCallback.expectBlockedStatusCallback(false, mCellNetworkAgent);
assertEquals(mCellNetworkAgent.getNetwork(), mCm.getActiveNetwork());
assertActiveNetworkInfo(TYPE_MOBILE, DetailedState.CONNECTED);
assertNetworkInfo(TYPE_MOBILE, DetailedState.CONNECTED);
assertExtraInfoFromCmPresent(mCellNetworkAgent);
- setUidRulesChanged(RULE_REJECT_METERED);
+ setBlockedReasonChanged(BLOCKED_METERED_REASON_DATA_SAVER);
cellNetworkCallback.expectBlockedStatusCallback(true, mCellNetworkAgent);
assertNull(mCm.getActiveNetwork());
assertActiveNetworkInfo(TYPE_MOBILE, DetailedState.BLOCKED);
@@ -7308,33 +7294,33 @@ public class ConnectivityServiceTest {
assertNetworkInfo(TYPE_MOBILE, DetailedState.BLOCKED);
assertExtraInfoFromCmBlocked(mCellNetworkAgent);
- setUidRulesChanged(RULE_ALLOW_METERED);
+ setBlockedReasonChanged(BLOCKED_REASON_NONE);
cellNetworkCallback.expectBlockedStatusCallback(false, mCellNetworkAgent);
assertEquals(mCellNetworkAgent.getNetwork(), mCm.getActiveNetwork());
assertActiveNetworkInfo(TYPE_MOBILE, DetailedState.CONNECTED);
assertNetworkInfo(TYPE_MOBILE, DetailedState.CONNECTED);
assertExtraInfoFromCmPresent(mCellNetworkAgent);
- setUidRulesChanged(RULE_NONE);
+ setBlockedReasonChanged(BLOCKED_REASON_NONE);
cellNetworkCallback.assertNoCallback();
// Restrict background data. Networking is not blocked because the network is unmetered.
- setRestrictBackgroundChanged(true);
+ setBlockedReasonChanged(BLOCKED_METERED_REASON_DATA_SAVER);
cellNetworkCallback.expectBlockedStatusCallback(true, mCellNetworkAgent);
assertNull(mCm.getActiveNetwork());
assertActiveNetworkInfo(TYPE_MOBILE, DetailedState.BLOCKED);
assertNetworkInfo(TYPE_MOBILE, DetailedState.BLOCKED);
assertExtraInfoFromCmBlocked(mCellNetworkAgent);
- setRestrictBackgroundChanged(true);
+ setBlockedReasonChanged(BLOCKED_METERED_REASON_DATA_SAVER);
cellNetworkCallback.assertNoCallback();
- setUidRulesChanged(RULE_ALLOW_METERED);
+ setBlockedReasonChanged(BLOCKED_REASON_NONE);
cellNetworkCallback.expectBlockedStatusCallback(false, mCellNetworkAgent);
assertActiveNetworkInfo(TYPE_MOBILE, DetailedState.CONNECTED);
assertNetworkInfo(TYPE_MOBILE, DetailedState.CONNECTED);
assertExtraInfoFromCmPresent(mCellNetworkAgent);
- setRestrictBackgroundChanged(false);
+ setBlockedReasonChanged(BLOCKED_REASON_NONE);
cellNetworkCallback.assertNoCallback();
assertEquals(mCellNetworkAgent.getNetwork(), mCm.getActiveNetwork());
assertActiveNetworkInfo(TYPE_MOBILE, DetailedState.CONNECTED);
@@ -7351,9 +7337,9 @@ public class ConnectivityServiceTest {
mockUidNetworkingBlocked();
// No Networkcallbacks invoked before any network is active.
- setUidRulesChanged(RULE_REJECT_ALL);
- setUidRulesChanged(RULE_NONE);
- setUidRulesChanged(RULE_REJECT_METERED);
+ setBlockedReasonChanged(BLOCKED_REASON_BATTERY_SAVER);
+ setBlockedReasonChanged(BLOCKED_REASON_NONE);
+ setBlockedReasonChanged(BLOCKED_METERED_REASON_DATA_SAVER);
defaultCallback.assertNoCallback();
mCellNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR);
@@ -7378,8 +7364,8 @@ public class ConnectivityServiceTest {
defaultCallback.expectBlockedStatusCallback(false, mCellNetworkAgent);
// Verify there's no Networkcallbacks invoked after data saver on/off.
- setRestrictBackgroundChanged(true);
- setRestrictBackgroundChanged(false);
+ setBlockedReasonChanged(BLOCKED_METERED_REASON_DATA_SAVER);
+ setBlockedReasonChanged(BLOCKED_REASON_NONE);
defaultCallback.assertNoCallback();
mCellNetworkAgent.disconnect();
diff --git a/tests/net/java/com/android/server/connectivity/FullScoreTest.kt b/tests/net/java/com/android/server/connectivity/FullScoreTest.kt
new file mode 100644
index 000000000000..eb3b4df1a282
--- /dev/null
+++ b/tests/net/java/com/android/server/connectivity/FullScoreTest.kt
@@ -0,0 +1,134 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.connectivity
+
+import android.net.NetworkAgentConfig
+import android.net.NetworkCapabilities
+import android.text.TextUtils
+import android.util.ArraySet
+import androidx.test.filters.SmallTest
+import androidx.test.runner.AndroidJUnit4
+import com.android.server.connectivity.FullScore.MAX_CS_MANAGED_POLICY
+import com.android.server.connectivity.FullScore.POLICY_ACCEPT_UNVALIDATED
+import com.android.server.connectivity.FullScore.POLICY_EVER_USER_SELECTED
+import com.android.server.connectivity.FullScore.POLICY_IS_VALIDATED
+import com.android.server.connectivity.FullScore.POLICY_IS_VPN
+import org.junit.Test
+import org.junit.runner.RunWith
+import kotlin.collections.minOfOrNull
+import kotlin.collections.maxOfOrNull
+import kotlin.reflect.full.staticProperties
+import kotlin.test.assertEquals
+import kotlin.test.assertFailsWith
+import kotlin.test.assertFalse
+import kotlin.test.assertTrue
+
+@RunWith(AndroidJUnit4::class)
+@SmallTest
+class FullScoreTest {
+ // Convenience methods
+ fun FullScore.withPolicies(
+ validated: Boolean = false,
+ vpn: Boolean = false,
+ onceChosen: Boolean = false,
+ acceptUnvalidated: Boolean = false
+ ): FullScore {
+ val nac = NetworkAgentConfig.Builder().apply {
+ setUnvalidatedConnectivityAcceptable(acceptUnvalidated)
+ setExplicitlySelected(onceChosen)
+ }.build()
+ val nc = NetworkCapabilities.Builder().apply {
+ if (vpn) addTransportType(NetworkCapabilities.TRANSPORT_VPN)
+ if (validated) addCapability(NetworkCapabilities.NET_CAPABILITY_VALIDATED)
+ }.build()
+ return mixInScore(nc, nac)
+ }
+
+ @Test
+ fun testGetLegacyInt() {
+ val ns = FullScore(50, 0L /* policy */)
+ assertEquals(10, ns.legacyInt) // -40 penalty for not being validated
+ assertEquals(50, ns.legacyIntAsValidated)
+
+ val vpnNs = FullScore(101, 0L /* policy */).withPolicies(vpn = true)
+ assertEquals(101, vpnNs.legacyInt) // VPNs are not subject to unvalidation penalty
+ assertEquals(101, vpnNs.legacyIntAsValidated)
+ assertEquals(101, vpnNs.withPolicies(validated = true).legacyInt)
+ assertEquals(101, vpnNs.withPolicies(validated = true).legacyIntAsValidated)
+
+ val validatedNs = ns.withPolicies(validated = true)
+ assertEquals(50, validatedNs.legacyInt) // No penalty, this is validated
+ assertEquals(50, validatedNs.legacyIntAsValidated)
+
+ val chosenNs = ns.withPolicies(onceChosen = true)
+ assertEquals(10, chosenNs.legacyInt)
+ assertEquals(100, chosenNs.legacyIntAsValidated)
+ assertEquals(10, chosenNs.withPolicies(acceptUnvalidated = true).legacyInt)
+ assertEquals(50, chosenNs.withPolicies(acceptUnvalidated = true).legacyIntAsValidated)
+ }
+
+ @Test
+ fun testToString() {
+ val string = FullScore(10, 0L /* policy */)
+ .withPolicies(vpn = true, acceptUnvalidated = true).toString()
+ assertTrue(string.contains("Score(10"), string)
+ assertTrue(string.contains("ACCEPT_UNVALIDATED"), string)
+ assertTrue(string.contains("IS_VPN"), string)
+ assertFalse(string.contains("IS_VALIDATED"), string)
+ val foundNames = ArraySet<String>()
+ getAllPolicies().forEach {
+ val name = FullScore.policyNameOf(it.get() as Int)
+ assertFalse(TextUtils.isEmpty(name))
+ assertFalse(foundNames.contains(name))
+ foundNames.add(name)
+ }
+ assertFailsWith<IllegalArgumentException> {
+ FullScore.policyNameOf(MAX_CS_MANAGED_POLICY + 1)
+ }
+ }
+
+ fun getAllPolicies() = Regex("POLICY_.*").let { nameRegex ->
+ FullScore::class.staticProperties.filter { it.name.matches(nameRegex) }
+ }
+
+ @Test
+ fun testHasPolicy() {
+ val ns = FullScore(50, 0L /* policy */)
+ assertFalse(ns.hasPolicy(POLICY_IS_VALIDATED))
+ assertFalse(ns.hasPolicy(POLICY_IS_VPN))
+ assertFalse(ns.hasPolicy(POLICY_EVER_USER_SELECTED))
+ assertFalse(ns.hasPolicy(POLICY_ACCEPT_UNVALIDATED))
+ assertTrue(ns.withPolicies(validated = true).hasPolicy(POLICY_IS_VALIDATED))
+ assertTrue(ns.withPolicies(vpn = true).hasPolicy(POLICY_IS_VPN))
+ assertTrue(ns.withPolicies(onceChosen = true).hasPolicy(POLICY_EVER_USER_SELECTED))
+ assertTrue(ns.withPolicies(acceptUnvalidated = true).hasPolicy(POLICY_ACCEPT_UNVALIDATED))
+ }
+
+ @Test
+ fun testMinMaxPolicyConstants() {
+ val policies = getAllPolicies()
+
+ policies.forEach { policy ->
+ assertTrue(policy.get() as Int >= FullScore.MIN_CS_MANAGED_POLICY)
+ assertTrue(policy.get() as Int <= FullScore.MAX_CS_MANAGED_POLICY)
+ }
+ assertEquals(FullScore.MIN_CS_MANAGED_POLICY,
+ policies.minOfOrNull { it.get() as Int })
+ assertEquals(FullScore.MAX_CS_MANAGED_POLICY,
+ policies.maxOfOrNull { it.get() as Int })
+ }
+}
diff --git a/tests/net/java/com/android/server/connectivity/LingerMonitorTest.java b/tests/net/java/com/android/server/connectivity/LingerMonitorTest.java
index ea2b362c537a..9ab60a41a397 100644
--- a/tests/net/java/com/android/server/connectivity/LingerMonitorTest.java
+++ b/tests/net/java/com/android/server/connectivity/LingerMonitorTest.java
@@ -357,7 +357,7 @@ public class LingerMonitorTest {
caps.addTransportType(transport);
NetworkAgentInfo nai = new NetworkAgentInfo(null, new Network(netId), info,
new LinkProperties(), caps, new NetworkScore.Builder().setLegacyInt(50).build(),
- mCtx, null, new NetworkAgentConfig() /* config */, mConnService, mNetd,
+ mCtx, null, new NetworkAgentConfig.Builder().build(), mConnService, mNetd,
mDnsResolver, NetworkProvider.ID_NONE, Binder.getCallingUid(),
mQosCallbackTracker, new ConnectivityService.Dependencies());
nai.everValidated = true;