diff options
17 files changed, 703 insertions, 302 deletions
diff --git a/core/api/system-current.txt b/core/api/system-current.txt index f6b1d0627312..d047a99a834f 100644 --- a/core/api/system-current.txt +++ b/core/api/system-current.txt @@ -6175,6 +6175,7 @@ package android.net { method public final void sendNetworkCapabilities(@NonNull android.net.NetworkCapabilities); method public final void sendNetworkScore(@IntRange(from=0, to=99) int); method public final void sendSocketKeepaliveEvent(int, int); + method public final void setUnderlyingNetworks(@Nullable java.util.List<android.net.Network>); method public void unregister(); field public static final int VALIDATION_STATUS_NOT_VALID = 2; // 0x2 field public static final int VALIDATION_STATUS_VALID = 1; // 0x1 diff --git a/core/java/android/net/NetworkAgent.java b/core/java/android/net/NetworkAgent.java index 44ebff99f3e9..0676ad4e2322 100644 --- a/core/java/android/net/NetworkAgent.java +++ b/core/java/android/net/NetworkAgent.java @@ -40,6 +40,7 @@ import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.time.Duration; import java.util.ArrayList; +import java.util.List; import java.util.Objects; import java.util.concurrent.atomic.AtomicBoolean; @@ -174,6 +175,14 @@ public abstract class NetworkAgent { public static final int EVENT_NETWORK_SCORE_CHANGED = BASE + 4; /** + * Sent by the NetworkAgent to ConnectivityService to pass the current + * list of underlying networks. + * obj = array of Network objects + * @hide + */ + public static final int EVENT_UNDERLYING_NETWORKS_CHANGED = BASE + 5; + + /** * Sent by ConnectivityService to the NetworkAgent to inform the agent of the * networks status - whether we could use the network or could not, due to * either a bad network configuration (no internet link) or captive portal. @@ -217,7 +226,13 @@ public abstract class NetworkAgent { * The key for the redirect URL in the Bundle argument of {@code CMD_REPORT_NETWORK_STATUS}. * @hide */ - public static String REDIRECT_URL_KEY = "redirect URL"; + public static final String REDIRECT_URL_KEY = "redirect URL"; + + /** + * Bundle key for the underlying networks in {@code EVENT_UNDERLYING_NETWORKS_CHANGED}. + * @hide + */ + public static final String UNDERLYING_NETWORKS_KEY = "underlyingNetworks"; /** * Sent by the NetworkAgent to ConnectivityService to indicate this network was @@ -650,6 +665,33 @@ public abstract class NetworkAgent { } /** + * Must be called by the agent when the network's underlying networks change. + * + * <p>{@code networks} is one of the following: + * <ul> + * <li><strong>a non-empty array</strong>: an array of one or more {@link Network}s, in + * decreasing preference order. For example, if this VPN uses both wifi and mobile (cellular) + * networks to carry app traffic, but prefers or uses wifi more than mobile, wifi should appear + * first in the array.</li> + * <li><strong>an empty array</strong>: a zero-element array, meaning that the VPN has no + * underlying network connection, and thus, app traffic will not be sent or received.</li> + * <li><strong>null</strong>: (default) signifies that the VPN uses whatever is the system's + * default network. I.e., it doesn't use the {@code bindSocket} or {@code bindDatagramSocket} + * APIs mentioned above to send traffic over specific channels.</li> + * </ul> + * + * @param underlyingNetworks the new list of underlying networks. + * @see {@link VpnService.Builder#setUnderlyingNetworks(Network[])} + */ + public final void setUnderlyingNetworks(@Nullable List<Network> underlyingNetworks) { + final ArrayList<Network> underlyingArray = (underlyingNetworks != null) + ? new ArrayList<>(underlyingNetworks) : null; + final Bundle bundle = new Bundle(); + bundle.putParcelableArrayList(UNDERLYING_NETWORKS_KEY, underlyingArray); + queueOrSendMessage(EVENT_UNDERLYING_NETWORKS_CHANGED, bundle); + } + + /** * Inform ConnectivityService that this agent has now connected. * Call {@link #unregister} to disconnect. */ diff --git a/core/java/android/net/NetworkCapabilities.java b/core/java/android/net/NetworkCapabilities.java index 40bb8bf11d0b..8dad11ffa731 100644 --- a/core/java/android/net/NetworkCapabilities.java +++ b/core/java/android/net/NetworkCapabilities.java @@ -712,6 +712,7 @@ public final class NetworkCapabilities implements Parcelable { if (ArrayUtils.contains(originalAdministratorUids, creatorUid)) { setAdministratorUids(new int[] {creatorUid}); } + // There is no need to clear the UIDs, they have already been cleared by clearAll() above. } /** @@ -805,7 +806,9 @@ public final class NetworkCapabilities implements Parcelable { */ private static final int TEST_NETWORKS_ALLOWED_TRANSPORTS = 1 << TRANSPORT_TEST // Test ethernet networks can be created with EthernetManager#setIncludeTestInterfaces - | 1 << TRANSPORT_ETHERNET; + | 1 << TRANSPORT_ETHERNET + // Test VPN networks can be created but their UID ranges must be empty. + | 1 << TRANSPORT_VPN; /** * Adds the given transport type to this {@code NetworkCapability} instance. diff --git a/core/java/android/security/keymaster/KeymasterDefs.java b/core/java/android/security/keymaster/KeymasterDefs.java index 18921639f55d..6ef9e7e3d9b8 100644 --- a/core/java/android/security/keymaster/KeymasterDefs.java +++ b/core/java/android/security/keymaster/KeymasterDefs.java @@ -16,6 +16,19 @@ package android.security.keymaster; +import android.hardware.keymint.Algorithm; +import android.hardware.keymint.BlockMode; +import android.hardware.keymint.Digest; +import android.hardware.keymint.ErrorCode; +import android.hardware.keymint.HardwareAuthenticatorType; +import android.hardware.keymint.KeyFormat; +import android.hardware.keymint.KeyOrigin; +import android.hardware.keymint.KeyPurpose; +import android.hardware.keymint.PaddingMode; +import android.hardware.keymint.SecurityLevel; +import android.hardware.keymint.Tag; +import android.hardware.keymint.TagType; + import java.util.HashMap; import java.util.Map; @@ -30,206 +43,284 @@ public final class KeymasterDefs { private KeymasterDefs() {} // Tag types. - public static final int KM_INVALID = 0 << 28; - public static final int KM_ENUM = 1 << 28; - public static final int KM_ENUM_REP = 2 << 28; - public static final int KM_UINT = 3 << 28; - public static final int KM_UINT_REP = 4 << 28; - public static final int KM_ULONG = 5 << 28; - public static final int KM_DATE = 6 << 28; - public static final int KM_BOOL = 7 << 28; - public static final int KM_BIGNUM = 8 << 28; - public static final int KM_BYTES = 9 << 28; - public static final int KM_ULONG_REP = 10 << 28; + public static final int KM_INVALID = TagType.INVALID; + public static final int KM_ENUM = TagType.ENUM; + public static final int KM_ENUM_REP = TagType.ENUM_REP; + public static final int KM_UINT = TagType.UINT; + public static final int KM_UINT_REP = TagType.UINT_REP; + public static final int KM_ULONG = TagType.ULONG; + public static final int KM_DATE = TagType.DATE; + public static final int KM_BOOL = TagType.BOOL; + public static final int KM_BIGNUM = TagType.BIGNUM; + public static final int KM_BYTES = TagType.BYTES; + public static final int KM_ULONG_REP = TagType.ULONG_REP; // Tag values. - public static final int KM_TAG_INVALID = KM_INVALID | 0; - public static final int KM_TAG_PURPOSE = KM_ENUM_REP | 1; - public static final int KM_TAG_ALGORITHM = KM_ENUM | 2; - public static final int KM_TAG_KEY_SIZE = KM_UINT | 3; - public static final int KM_TAG_BLOCK_MODE = KM_ENUM_REP | 4; - public static final int KM_TAG_DIGEST = KM_ENUM_REP | 5; - public static final int KM_TAG_PADDING = KM_ENUM_REP | 6; - public static final int KM_TAG_CALLER_NONCE = KM_BOOL | 7; - public static final int KM_TAG_MIN_MAC_LENGTH = KM_UINT | 8; + public static final int KM_TAG_INVALID = Tag.INVALID; // KM_INVALID | 0; + public static final int KM_TAG_PURPOSE = Tag.PURPOSE; // KM_ENUM_REP | 1; + public static final int KM_TAG_ALGORITHM = Tag.ALGORITHM; // KM_ENUM | 2; + public static final int KM_TAG_KEY_SIZE = Tag.KEY_SIZE; // KM_UINT | 3; + public static final int KM_TAG_BLOCK_MODE = Tag.BLOCK_MODE; // KM_ENUM_REP | 4; + public static final int KM_TAG_DIGEST = Tag.DIGEST; // KM_ENUM_REP | 5; + public static final int KM_TAG_PADDING = Tag.PADDING; // KM_ENUM_REP | 6; + public static final int KM_TAG_CALLER_NONCE = Tag.CALLER_NONCE; // KM_BOOL | 7; + public static final int KM_TAG_MIN_MAC_LENGTH = Tag.MIN_MAC_LENGTH; // KM_UINT | 8; - public static final int KM_TAG_RESCOPING_ADD = KM_ENUM_REP | 101; - public static final int KM_TAG_RESCOPING_DEL = KM_ENUM_REP | 102; - public static final int KM_TAG_BLOB_USAGE_REQUIREMENTS = KM_ENUM | 705; + public static final int KM_TAG_BLOB_USAGE_REQUIREMENTS = + Tag.BLOB_USAGE_REQUIREMENTS; // KM_ENUM | 705; - public static final int KM_TAG_RSA_PUBLIC_EXPONENT = KM_ULONG | 200; - public static final int KM_TAG_INCLUDE_UNIQUE_ID = KM_BOOL | 202; + public static final int KM_TAG_RSA_PUBLIC_EXPONENT = Tag.RSA_PUBLIC_EXPONENT; // KM_ULONG | 200; + public static final int KM_TAG_INCLUDE_UNIQUE_ID = Tag.INCLUDE_UNIQUE_ID; // KM_BOOL | 202; - public static final int KM_TAG_ACTIVE_DATETIME = KM_DATE | 400; - public static final int KM_TAG_ORIGINATION_EXPIRE_DATETIME = KM_DATE | 401; - public static final int KM_TAG_USAGE_EXPIRE_DATETIME = KM_DATE | 402; - public static final int KM_TAG_MIN_SECONDS_BETWEEN_OPS = KM_UINT | 403; - public static final int KM_TAG_MAX_USES_PER_BOOT = KM_UINT | 404; + public static final int KM_TAG_ACTIVE_DATETIME = Tag.ACTIVE_DATETIME; // KM_DATE | 400; + public static final int KM_TAG_ORIGINATION_EXPIRE_DATETIME = + Tag.ORIGINATION_EXPIRE_DATETIME; // KM_DATE | 401; + public static final int KM_TAG_USAGE_EXPIRE_DATETIME = + Tag.USAGE_EXPIRE_DATETIME; // KM_DATE | 402; + public static final int KM_TAG_MIN_SECONDS_BETWEEN_OPS = + Tag.MIN_SECONDS_BETWEEN_OPS; // KM_UINT | 403; + public static final int KM_TAG_MAX_USES_PER_BOOT = Tag.MAX_USES_PER_BOOT; // KM_UINT | 404; - public static final int KM_TAG_ALL_USERS = KM_BOOL | 500; - public static final int KM_TAG_USER_ID = KM_UINT | 501; - public static final int KM_TAG_USER_SECURE_ID = KM_ULONG_REP | 502; - public static final int KM_TAG_NO_AUTH_REQUIRED = KM_BOOL | 503; - public static final int KM_TAG_USER_AUTH_TYPE = KM_ENUM | 504; - public static final int KM_TAG_AUTH_TIMEOUT = KM_UINT | 505; - public static final int KM_TAG_ALLOW_WHILE_ON_BODY = KM_BOOL | 506; - public static final int KM_TAG_TRUSTED_USER_PRESENCE_REQUIRED = KM_BOOL | 507; - public static final int KM_TAG_TRUSTED_CONFIRMATION_REQUIRED = KM_BOOL | 508; - public static final int KM_TAG_UNLOCKED_DEVICE_REQUIRED = KM_BOOL | 509; + public static final int KM_TAG_USER_ID = Tag.USER_ID; // KM_UINT | 501; + public static final int KM_TAG_USER_SECURE_ID = Tag.USER_SECURE_ID; // KM_ULONG_REP | 502; + public static final int KM_TAG_NO_AUTH_REQUIRED = Tag.NO_AUTH_REQUIRED; // KM_BOOL | 503; + public static final int KM_TAG_USER_AUTH_TYPE = Tag.USER_AUTH_TYPE; // KM_ENUM | 504; + public static final int KM_TAG_AUTH_TIMEOUT = Tag.AUTH_TIMEOUT; // KM_UINT | 505; + public static final int KM_TAG_ALLOW_WHILE_ON_BODY = Tag.ALLOW_WHILE_ON_BODY; // KM_BOOL | 506; + public static final int KM_TAG_TRUSTED_USER_PRESENCE_REQUIRED = + Tag.TRUSTED_USER_PRESENCE_REQUIRED; // KM_BOOL | 507; + public static final int KM_TAG_TRUSTED_CONFIRMATION_REQUIRED = + Tag.TRUSTED_CONFIRMATION_REQUIRED; // KM_BOOL | 508; + public static final int KM_TAG_UNLOCKED_DEVICE_REQUIRED = + Tag.UNLOCKED_DEVICE_REQUIRED; // KM_BOOL | 509; - public static final int KM_TAG_ALL_APPLICATIONS = KM_BOOL | 600; - public static final int KM_TAG_APPLICATION_ID = KM_BYTES | 601; + public static final int KM_TAG_APPLICATION_ID = Tag.APPLICATION_ID; // KM_BYTES | 601; - public static final int KM_TAG_CREATION_DATETIME = KM_DATE | 701; - public static final int KM_TAG_ORIGIN = KM_ENUM | 702; - public static final int KM_TAG_ROLLBACK_RESISTANT = KM_BOOL | 703; - public static final int KM_TAG_ROOT_OF_TRUST = KM_BYTES | 704; - public static final int KM_TAG_UNIQUE_ID = KM_BYTES | 707; - public static final int KM_TAG_ATTESTATION_CHALLENGE = KM_BYTES | 708; - public static final int KM_TAG_ATTESTATION_ID_BRAND = KM_BYTES | 710; - public static final int KM_TAG_ATTESTATION_ID_DEVICE = KM_BYTES | 711; - public static final int KM_TAG_ATTESTATION_ID_PRODUCT = KM_BYTES | 712; - public static final int KM_TAG_ATTESTATION_ID_SERIAL = KM_BYTES | 713; - public static final int KM_TAG_ATTESTATION_ID_IMEI = KM_BYTES | 714; - public static final int KM_TAG_ATTESTATION_ID_MEID = KM_BYTES | 715; - public static final int KM_TAG_ATTESTATION_ID_MANUFACTURER = KM_BYTES | 716; - public static final int KM_TAG_ATTESTATION_ID_MODEL = KM_BYTES | 717; - public static final int KM_TAG_VENDOR_PATCHLEVEL = KM_UINT | 718; - public static final int KM_TAG_BOOT_PATCHLEVEL = KM_UINT | 719; - public static final int KM_TAG_DEVICE_UNIQUE_ATTESTATION = KM_BOOL | 720; + public static final int KM_TAG_CREATION_DATETIME = Tag.CREATION_DATETIME; // KM_DATE | 701; + public static final int KM_TAG_ORIGIN = Tag.ORIGIN; // KM_ENUM | 702; + public static final int KM_TAG_ROLLBACK_RESISTANT = Tag.ROLLBACK_RESISTANCE; // KM_BOOL | 703; + public static final int KM_TAG_ROOT_OF_TRUST = Tag.ROOT_OF_TRUST; // KM_BYTES | 704; + public static final int KM_TAG_UNIQUE_ID = Tag.UNIQUE_ID; // KM_BYTES | 707; + public static final int KM_TAG_ATTESTATION_CHALLENGE = + Tag.ATTESTATION_CHALLENGE; // KM_BYTES | 708; + public static final int KM_TAG_ATTESTATION_ID_BRAND = + Tag.ATTESTATION_ID_BRAND; // KM_BYTES | 710; + public static final int KM_TAG_ATTESTATION_ID_DEVICE = + Tag.ATTESTATION_ID_DEVICE; // KM_BYTES | 711; + public static final int KM_TAG_ATTESTATION_ID_PRODUCT = + Tag.ATTESTATION_ID_PRODUCT; // KM_BYTES | 712; + public static final int KM_TAG_ATTESTATION_ID_SERIAL = + Tag.ATTESTATION_ID_SERIAL; // KM_BYTES | 713; + public static final int KM_TAG_ATTESTATION_ID_IMEI = + Tag.ATTESTATION_ID_IMEI; // KM_BYTES | 714; + public static final int KM_TAG_ATTESTATION_ID_MEID = + Tag.ATTESTATION_ID_MEID; // KM_BYTES | 715; + public static final int KM_TAG_ATTESTATION_ID_MANUFACTURER = + Tag.ATTESTATION_ID_MANUFACTURER; // KM_BYTES | 716; + public static final int KM_TAG_ATTESTATION_ID_MODEL = + Tag.ATTESTATION_ID_MODEL; // KM_BYTES | 717; + public static final int KM_TAG_VENDOR_PATCHLEVEL = + Tag.VENDOR_PATCHLEVEL; // KM_UINT | 718; + public static final int KM_TAG_BOOT_PATCHLEVEL = + Tag.BOOT_PATCHLEVEL; // KM_UINT | 719; + public static final int KM_TAG_DEVICE_UNIQUE_ATTESTATION = + Tag.DEVICE_UNIQUE_ATTESTATION; // KM_BOOL | 720; - public static final int KM_TAG_ASSOCIATED_DATA = KM_BYTES | 1000; - public static final int KM_TAG_NONCE = KM_BYTES | 1001; - public static final int KM_TAG_AUTH_TOKEN = KM_BYTES | 1002; - public static final int KM_TAG_MAC_LENGTH = KM_UINT | 1003; + public static final int KM_TAG_ASSOCIATED_DATA = Tag.ASSOCIATED_DATA; // KM_BYTES | 1000; + public static final int KM_TAG_NONCE = Tag.NONCE; // KM_BYTES | 1001; + public static final int KM_TAG_MAC_LENGTH = Tag.MAC_LENGTH; // KM_UINT | 1003; // Algorithm values. - public static final int KM_ALGORITHM_RSA = 1; - public static final int KM_ALGORITHM_EC = 3; - public static final int KM_ALGORITHM_AES = 32; - public static final int KM_ALGORITHM_3DES = 33; - public static final int KM_ALGORITHM_HMAC = 128; + public static final int KM_ALGORITHM_RSA = Algorithm.RSA; + public static final int KM_ALGORITHM_EC = Algorithm.EC; + public static final int KM_ALGORITHM_AES = Algorithm.AES; + public static final int KM_ALGORITHM_3DES = Algorithm.TRIPLE_DES; + public static final int KM_ALGORITHM_HMAC = Algorithm.HMAC; // Block modes. - public static final int KM_MODE_ECB = 1; - public static final int KM_MODE_CBC = 2; - public static final int KM_MODE_CTR = 3; - public static final int KM_MODE_GCM = 32; + public static final int KM_MODE_ECB = BlockMode.ECB; + public static final int KM_MODE_CBC = BlockMode.CBC; + public static final int KM_MODE_CTR = BlockMode.CTR; + public static final int KM_MODE_GCM = BlockMode.GCM; // Padding modes. - public static final int KM_PAD_NONE = 1; - public static final int KM_PAD_RSA_OAEP = 2; - public static final int KM_PAD_RSA_PSS = 3; - public static final int KM_PAD_RSA_PKCS1_1_5_ENCRYPT = 4; - public static final int KM_PAD_RSA_PKCS1_1_5_SIGN = 5; - public static final int KM_PAD_PKCS7 = 64; + public static final int KM_PAD_NONE = PaddingMode.NONE; + public static final int KM_PAD_RSA_OAEP = PaddingMode.RSA_OAEP; + public static final int KM_PAD_RSA_PSS = PaddingMode.RSA_PSS; + public static final int KM_PAD_RSA_PKCS1_1_5_ENCRYPT = PaddingMode.RSA_PKCS1_1_5_ENCRYPT; + public static final int KM_PAD_RSA_PKCS1_1_5_SIGN = PaddingMode.RSA_PKCS1_1_5_SIGN; + public static final int KM_PAD_PKCS7 = PaddingMode.PKCS7; // Digest modes. - public static final int KM_DIGEST_NONE = 0; - public static final int KM_DIGEST_MD5 = 1; - public static final int KM_DIGEST_SHA1 = 2; - public static final int KM_DIGEST_SHA_2_224 = 3; - public static final int KM_DIGEST_SHA_2_256 = 4; - public static final int KM_DIGEST_SHA_2_384 = 5; - public static final int KM_DIGEST_SHA_2_512 = 6; + public static final int KM_DIGEST_NONE = Digest.NONE; + public static final int KM_DIGEST_MD5 = Digest.MD5; + public static final int KM_DIGEST_SHA1 = Digest.SHA1; + public static final int KM_DIGEST_SHA_2_224 = Digest.SHA_2_224; + public static final int KM_DIGEST_SHA_2_256 = Digest.SHA_2_256; + public static final int KM_DIGEST_SHA_2_384 = Digest.SHA_2_384; + public static final int KM_DIGEST_SHA_2_512 = Digest.SHA_2_512; // Key origins. - public static final int KM_ORIGIN_GENERATED = 0; - public static final int KM_ORIGIN_IMPORTED = 2; - public static final int KM_ORIGIN_UNKNOWN = 3; - public static final int KM_ORIGIN_SECURELY_IMPORTED = 4; + public static final int KM_ORIGIN_GENERATED = KeyOrigin.GENERATED; + public static final int KM_ORIGIN_DERIVED = KeyOrigin.DERIVED; + public static final int KM_ORIGIN_IMPORTED = KeyOrigin.IMPORTED; + public static final int KM_ORIGIN_UNKNOWN = KeyOrigin.RESERVED; + public static final int KM_ORIGIN_SECURELY_IMPORTED = KeyOrigin.SECURELY_IMPORTED; // Key usability requirements. public static final int KM_BLOB_STANDALONE = 0; public static final int KM_BLOB_REQUIRES_FILE_SYSTEM = 1; // Operation Purposes. - public static final int KM_PURPOSE_ENCRYPT = 0; - public static final int KM_PURPOSE_DECRYPT = 1; - public static final int KM_PURPOSE_SIGN = 2; - public static final int KM_PURPOSE_VERIFY = 3; - public static final int KM_PURPOSE_WRAP = 5; + public static final int KM_PURPOSE_ENCRYPT = KeyPurpose.ENCRYPT; + public static final int KM_PURPOSE_DECRYPT = KeyPurpose.DECRYPT; + public static final int KM_PURPOSE_SIGN = KeyPurpose.SIGN; + public static final int KM_PURPOSE_VERIFY = KeyPurpose.VERIFY; + public static final int KM_PURPOSE_WRAP = KeyPurpose.WRAP_KEY; // Key formats. - public static final int KM_KEY_FORMAT_X509 = 0; - public static final int KM_KEY_FORMAT_PKCS8 = 1; - public static final int KM_KEY_FORMAT_RAW = 3; + public static final int KM_KEY_FORMAT_X509 = KeyFormat.X509; + public static final int KM_KEY_FORMAT_PKCS8 = KeyFormat.PKCS8; + public static final int KM_KEY_FORMAT_RAW = KeyFormat.RAW; // User authenticators. - public static final int HW_AUTH_PASSWORD = 1 << 0; - public static final int HW_AUTH_BIOMETRIC = 1 << 1; + public static final int HW_AUTH_PASSWORD = HardwareAuthenticatorType.PASSWORD; + public static final int HW_AUTH_BIOMETRIC = HardwareAuthenticatorType.FINGERPRINT; // Security Levels. - public static final int KM_SECURITY_LEVEL_SOFTWARE = 0; - public static final int KM_SECURITY_LEVEL_TRUSTED_ENVIRONMENT = 1; - public static final int KM_SECURITY_LEVEL_STRONGBOX = 2; + public static final int KM_SECURITY_LEVEL_SOFTWARE = SecurityLevel.SOFTWARE; + public static final int KM_SECURITY_LEVEL_TRUSTED_ENVIRONMENT = + SecurityLevel.TRUSTED_ENVIRONMENT; + public static final int KM_SECURITY_LEVEL_STRONGBOX = SecurityLevel.STRONGBOX; // Error codes. - public static final int KM_ERROR_OK = 0; - public static final int KM_ERROR_ROOT_OF_TRUST_ALREADY_SET = -1; - public static final int KM_ERROR_UNSUPPORTED_PURPOSE = -2; - public static final int KM_ERROR_INCOMPATIBLE_PURPOSE = -3; - public static final int KM_ERROR_UNSUPPORTED_ALGORITHM = -4; - public static final int KM_ERROR_INCOMPATIBLE_ALGORITHM = -5; - public static final int KM_ERROR_UNSUPPORTED_KEY_SIZE = -6; - public static final int KM_ERROR_UNSUPPORTED_BLOCK_MODE = -7; - public static final int KM_ERROR_INCOMPATIBLE_BLOCK_MODE = -8; - public static final int KM_ERROR_UNSUPPORTED_MAC_LENGTH = -9; - public static final int KM_ERROR_UNSUPPORTED_PADDING_MODE = -10; - public static final int KM_ERROR_INCOMPATIBLE_PADDING_MODE = -11; - public static final int KM_ERROR_UNSUPPORTED_DIGEST = -12; - public static final int KM_ERROR_INCOMPATIBLE_DIGEST = -13; - public static final int KM_ERROR_INVALID_EXPIRATION_TIME = -14; - public static final int KM_ERROR_INVALID_USER_ID = -15; - public static final int KM_ERROR_INVALID_AUTHORIZATION_TIMEOUT = -16; - public static final int KM_ERROR_UNSUPPORTED_KEY_FORMAT = -17; - public static final int KM_ERROR_INCOMPATIBLE_KEY_FORMAT = -18; - public static final int KM_ERROR_UNSUPPORTED_KEY_ENCRYPTION_ALGORITHM = -19; - public static final int KM_ERROR_UNSUPPORTED_KEY_VERIFICATION_ALGORITHM = -20; - public static final int KM_ERROR_INVALID_INPUT_LENGTH = -21; - public static final int KM_ERROR_KEY_EXPORT_OPTIONS_INVALID = -22; - public static final int KM_ERROR_DELEGATION_NOT_ALLOWED = -23; - public static final int KM_ERROR_KEY_NOT_YET_VALID = -24; - public static final int KM_ERROR_KEY_EXPIRED = -25; - public static final int KM_ERROR_KEY_USER_NOT_AUTHENTICATED = -26; - public static final int KM_ERROR_OUTPUT_PARAMETER_NULL = -27; - public static final int KM_ERROR_INVALID_OPERATION_HANDLE = -28; - public static final int KM_ERROR_INSUFFICIENT_BUFFER_SPACE = -29; - public static final int KM_ERROR_VERIFICATION_FAILED = -30; - public static final int KM_ERROR_TOO_MANY_OPERATIONS = -31; - public static final int KM_ERROR_UNEXPECTED_NULL_POINTER = -32; - public static final int KM_ERROR_INVALID_KEY_BLOB = -33; - public static final int KM_ERROR_IMPORTED_KEY_NOT_ENCRYPTED = -34; - public static final int KM_ERROR_IMPORTED_KEY_DECRYPTION_FAILED = -35; - public static final int KM_ERROR_IMPORTED_KEY_NOT_SIGNED = -36; - public static final int KM_ERROR_IMPORTED_KEY_VERIFICATION_FAILED = -37; - public static final int KM_ERROR_INVALID_ARGUMENT = -38; - public static final int KM_ERROR_UNSUPPORTED_TAG = -39; - public static final int KM_ERROR_INVALID_TAG = -40; - public static final int KM_ERROR_MEMORY_ALLOCATION_FAILED = -41; - public static final int KM_ERROR_INVALID_RESCOPING = -42; - public static final int KM_ERROR_IMPORT_PARAMETER_MISMATCH = -44; - public static final int KM_ERROR_SECURE_HW_ACCESS_DENIED = -45; - public static final int KM_ERROR_OPERATION_CANCELLED = -46; - public static final int KM_ERROR_CONCURRENT_ACCESS_CONFLICT = -47; - public static final int KM_ERROR_SECURE_HW_BUSY = -48; - public static final int KM_ERROR_SECURE_HW_COMMUNICATION_FAILED = -49; - public static final int KM_ERROR_UNSUPPORTED_EC_FIELD = -50; - public static final int KM_ERROR_MISSING_NONCE = -51; - public static final int KM_ERROR_INVALID_NONCE = -52; - public static final int KM_ERROR_MISSING_MAC_LENGTH = -53; - public static final int KM_ERROR_KEY_RATE_LIMIT_EXCEEDED = -54; - public static final int KM_ERROR_CALLER_NONCE_PROHIBITED = -55; - public static final int KM_ERROR_KEY_MAX_OPS_EXCEEDED = -56; - public static final int KM_ERROR_INVALID_MAC_LENGTH = -57; - public static final int KM_ERROR_MISSING_MIN_MAC_LENGTH = -58; - public static final int KM_ERROR_UNSUPPORTED_MIN_MAC_LENGTH = -59; - public static final int KM_ERROR_CANNOT_ATTEST_IDS = -66; - public static final int KM_ERROR_HARDWARE_TYPE_UNAVAILABLE = -68; - public static final int KM_ERROR_DEVICE_LOCKED = -72; - public static final int KM_ERROR_UNIMPLEMENTED = -100; - public static final int KM_ERROR_VERSION_MISMATCH = -101; - public static final int KM_ERROR_UNKNOWN_ERROR = -1000; + public static final int KM_ERROR_OK = ErrorCode.OK; + public static final int KM_ERROR_ROOT_OF_TRUST_ALREADY_SET = + ErrorCode.ROOT_OF_TRUST_ALREADY_SET; // -1; + public static final int KM_ERROR_UNSUPPORTED_PURPOSE = + ErrorCode.UNSUPPORTED_PURPOSE; // -2; + public static final int KM_ERROR_INCOMPATIBLE_PURPOSE = + ErrorCode.INCOMPATIBLE_PURPOSE; // -3; + public static final int KM_ERROR_UNSUPPORTED_ALGORITHM = + ErrorCode.UNSUPPORTED_ALGORITHM; // -4; + public static final int KM_ERROR_INCOMPATIBLE_ALGORITHM = + ErrorCode.INCOMPATIBLE_ALGORITHM; // -5; + public static final int KM_ERROR_UNSUPPORTED_KEY_SIZE = + ErrorCode.UNSUPPORTED_KEY_SIZE; // -6; + public static final int KM_ERROR_UNSUPPORTED_BLOCK_MODE = + ErrorCode.UNSUPPORTED_BLOCK_MODE; // -7; + public static final int KM_ERROR_INCOMPATIBLE_BLOCK_MODE = + ErrorCode.INCOMPATIBLE_BLOCK_MODE; // -8; + public static final int KM_ERROR_UNSUPPORTED_MAC_LENGTH = + ErrorCode.UNSUPPORTED_MAC_LENGTH; // -9; + public static final int KM_ERROR_UNSUPPORTED_PADDING_MODE = + ErrorCode.UNSUPPORTED_PADDING_MODE; // -10; + public static final int KM_ERROR_INCOMPATIBLE_PADDING_MODE = + ErrorCode.INCOMPATIBLE_PADDING_MODE; // -11; + public static final int KM_ERROR_UNSUPPORTED_DIGEST = + ErrorCode.UNSUPPORTED_DIGEST; // -12; + public static final int KM_ERROR_INCOMPATIBLE_DIGEST = + ErrorCode.INCOMPATIBLE_DIGEST; // -13; + public static final int KM_ERROR_INVALID_EXPIRATION_TIME = + ErrorCode.INVALID_EXPIRATION_TIME; // -14; + public static final int KM_ERROR_INVALID_USER_ID = + ErrorCode.INVALID_USER_ID; // -15; + public static final int KM_ERROR_INVALID_AUTHORIZATION_TIMEOUT = + ErrorCode.INVALID_AUTHORIZATION_TIMEOUT; // -16; + public static final int KM_ERROR_UNSUPPORTED_KEY_FORMAT = + ErrorCode.UNSUPPORTED_KEY_FORMAT; // -17; + public static final int KM_ERROR_INCOMPATIBLE_KEY_FORMAT = + ErrorCode.INCOMPATIBLE_KEY_FORMAT; // -18; + public static final int KM_ERROR_UNSUPPORTED_KEY_ENCRYPTION_ALGORITHM = + ErrorCode.UNSUPPORTED_KEY_ENCRYPTION_ALGORITHM; // -19; + public static final int KM_ERROR_UNSUPPORTED_KEY_VERIFICATION_ALGORITHM = + ErrorCode.UNSUPPORTED_KEY_VERIFICATION_ALGORITHM; // -20; + public static final int KM_ERROR_INVALID_INPUT_LENGTH = + ErrorCode.INVALID_INPUT_LENGTH; // -21; + public static final int KM_ERROR_KEY_EXPORT_OPTIONS_INVALID = + ErrorCode.KEY_EXPORT_OPTIONS_INVALID; // -22; + public static final int KM_ERROR_DELEGATION_NOT_ALLOWED = + ErrorCode.DELEGATION_NOT_ALLOWED; // -23; + public static final int KM_ERROR_KEY_NOT_YET_VALID = + ErrorCode.KEY_NOT_YET_VALID; // -24; + public static final int KM_ERROR_KEY_EXPIRED = + ErrorCode.KEY_EXPIRED; // -25; + public static final int KM_ERROR_KEY_USER_NOT_AUTHENTICATED = + ErrorCode.KEY_USER_NOT_AUTHENTICATED; // -26; + public static final int KM_ERROR_OUTPUT_PARAMETER_NULL = + ErrorCode.OUTPUT_PARAMETER_NULL; // -27; + public static final int KM_ERROR_INVALID_OPERATION_HANDLE = + ErrorCode.INVALID_OPERATION_HANDLE; // -28; + public static final int KM_ERROR_INSUFFICIENT_BUFFER_SPACE = + ErrorCode.INSUFFICIENT_BUFFER_SPACE; // -29; + public static final int KM_ERROR_VERIFICATION_FAILED = + ErrorCode.VERIFICATION_FAILED; // -30; + public static final int KM_ERROR_TOO_MANY_OPERATIONS = + ErrorCode.TOO_MANY_OPERATIONS; // -31; + public static final int KM_ERROR_UNEXPECTED_NULL_POINTER = + ErrorCode.UNEXPECTED_NULL_POINTER; // -32; + public static final int KM_ERROR_INVALID_KEY_BLOB = + ErrorCode.INVALID_KEY_BLOB; // -33; + public static final int KM_ERROR_IMPORTED_KEY_NOT_ENCRYPTED = + ErrorCode.IMPORTED_KEY_NOT_ENCRYPTED; // -34; + public static final int KM_ERROR_IMPORTED_KEY_DECRYPTION_FAILED = + ErrorCode.IMPORTED_KEY_DECRYPTION_FAILED; // -35; + public static final int KM_ERROR_IMPORTED_KEY_NOT_SIGNED = + ErrorCode.IMPORTED_KEY_NOT_SIGNED; // -36; + public static final int KM_ERROR_IMPORTED_KEY_VERIFICATION_FAILED = + ErrorCode.IMPORTED_KEY_VERIFICATION_FAILED; // -37; + public static final int KM_ERROR_INVALID_ARGUMENT = + ErrorCode.INVALID_ARGUMENT; // -38; + public static final int KM_ERROR_UNSUPPORTED_TAG = + ErrorCode.UNSUPPORTED_TAG; // -39; + public static final int KM_ERROR_INVALID_TAG = + ErrorCode.INVALID_TAG; // -40; + public static final int KM_ERROR_MEMORY_ALLOCATION_FAILED = + ErrorCode.MEMORY_ALLOCATION_FAILED; // -41; + public static final int KM_ERROR_IMPORT_PARAMETER_MISMATCH = + ErrorCode.IMPORT_PARAMETER_MISMATCH; // -44; + public static final int KM_ERROR_SECURE_HW_ACCESS_DENIED = + ErrorCode.SECURE_HW_ACCESS_DENIED; // -45; + public static final int KM_ERROR_OPERATION_CANCELLED = + ErrorCode.OPERATION_CANCELLED; // -46; + public static final int KM_ERROR_CONCURRENT_ACCESS_CONFLICT = + ErrorCode.CONCURRENT_ACCESS_CONFLICT; // -47; + public static final int KM_ERROR_SECURE_HW_BUSY = + ErrorCode.SECURE_HW_BUSY; // -48; + public static final int KM_ERROR_SECURE_HW_COMMUNICATION_FAILED = + ErrorCode.SECURE_HW_COMMUNICATION_FAILED; // -49; + public static final int KM_ERROR_UNSUPPORTED_EC_FIELD = + ErrorCode.UNSUPPORTED_EC_FIELD; // -50; + public static final int KM_ERROR_MISSING_NONCE = + ErrorCode.MISSING_NONCE; // -51; + public static final int KM_ERROR_INVALID_NONCE = + ErrorCode.INVALID_NONCE; // -52; + public static final int KM_ERROR_MISSING_MAC_LENGTH = + ErrorCode.MISSING_MAC_LENGTH; // -53; + public static final int KM_ERROR_KEY_RATE_LIMIT_EXCEEDED = + ErrorCode.KEY_RATE_LIMIT_EXCEEDED; // -54; + public static final int KM_ERROR_CALLER_NONCE_PROHIBITED = + ErrorCode.CALLER_NONCE_PROHIBITED; // -55; + public static final int KM_ERROR_KEY_MAX_OPS_EXCEEDED = + ErrorCode.KEY_MAX_OPS_EXCEEDED; // -56; + public static final int KM_ERROR_INVALID_MAC_LENGTH = + ErrorCode.INVALID_MAC_LENGTH; // -57; + public static final int KM_ERROR_MISSING_MIN_MAC_LENGTH = + ErrorCode.MISSING_MIN_MAC_LENGTH; // -58; + public static final int KM_ERROR_UNSUPPORTED_MIN_MAC_LENGTH = + ErrorCode.UNSUPPORTED_MIN_MAC_LENGTH; // -59; + public static final int KM_ERROR_CANNOT_ATTEST_IDS = + ErrorCode.CANNOT_ATTEST_IDS; // -66; + public static final int KM_ERROR_HARDWARE_TYPE_UNAVAILABLE = + ErrorCode.HARDWARE_TYPE_UNAVAILABLE; // -68; + public static final int KM_ERROR_DEVICE_LOCKED = + ErrorCode.DEVICE_LOCKED; // -72; + public static final int KM_ERROR_UNIMPLEMENTED = + ErrorCode.UNIMPLEMENTED; // -100; + public static final int KM_ERROR_VERSION_MISMATCH = + ErrorCode.VERSION_MISMATCH; // -101; + public static final int KM_ERROR_UNKNOWN_ERROR = + ErrorCode.UNKNOWN_ERROR; // -1000; public static final Map<Integer, String> sErrorCodeToString = new HashMap<Integer, String>(); static { diff --git a/keystore/java/android/security/keystore/AndroidKeyStoreProvider.java b/keystore/java/android/security/keystore/AndroidKeyStoreProvider.java index 5867ef6eaea5..b1b6306e0cf6 100644 --- a/keystore/java/android/security/keystore/AndroidKeyStoreProvider.java +++ b/keystore/java/android/security/keystore/AndroidKeyStoreProvider.java @@ -83,8 +83,7 @@ public class AndroidKeyStoreProvider extends Provider { boolean supports3DES = "true".equals(android.os.SystemProperties.get(DESEDE_SYSTEM_PROPERTY)); // java.security.KeyStore - put("KeyStore.AndroidKeyStore", PACKAGE_NAME + ".AndroidKeyStoreSpi"); - put("Alg.Alias.KeyStore.AndroidKeyStoreLegacy", "AndroidKeyStore"); + put("KeyStore." + providerName, PACKAGE_NAME + ".AndroidKeyStoreSpi"); // java.security.KeyPairGenerator put("KeyPairGenerator.EC", PACKAGE_NAME + ".AndroidKeyStoreKeyPairGeneratorSpi$EC"); diff --git a/services/core/java/com/android/server/ConnectivityService.java b/services/core/java/com/android/server/ConnectivityService.java index f7de5c023b4f..5420ee2f11af 100644 --- a/services/core/java/com/android/server/ConnectivityService.java +++ b/services/core/java/com/android/server/ConnectivityService.java @@ -2771,6 +2771,7 @@ public class ConnectivityService extends IConnectivityManager.Stub networkCapabilities = new NetworkCapabilities(networkCapabilities); networkCapabilities.restrictCapabilitesForTestNetwork(nai.creatorUid); } + processCapabilitiesFromAgent(nai, networkCapabilities); updateCapabilities(nai.getCurrentScore(), nai, networkCapabilities); break; } @@ -2809,6 +2810,31 @@ public class ConnectivityService extends IConnectivityManager.Stub mKeepaliveTracker.handleEventSocketKeepalive(nai, msg); break; } + case NetworkAgent.EVENT_UNDERLYING_NETWORKS_CHANGED: { + if (!nai.supportsUnderlyingNetworks()) { + Log.wtf(TAG, "Non-virtual networks cannot have underlying networks"); + break; + } + final ArrayList<Network> underlying; + try { + underlying = ((Bundle) msg.obj).getParcelableArrayList( + NetworkAgent.UNDERLYING_NETWORKS_KEY); + } catch (NullPointerException | ClassCastException e) { + break; + } + final Network[] oldUnderlying = nai.declaredUnderlyingNetworks; + nai.declaredUnderlyingNetworks = (underlying != null) + ? underlying.toArray(new Network[0]) : null; + + if (!Arrays.equals(oldUnderlying, nai.declaredUnderlyingNetworks)) { + if (DBG) { + log(nai.toShortString() + " changed underlying networks to " + + Arrays.toString(nai.declaredUnderlyingNetworks)); + } + updateCapabilities(nai.getCurrentScore(), nai, nai.networkCapabilities); + notifyIfacesChangedForNetworkStats(); + } + } } } @@ -3394,7 +3420,7 @@ public class ConnectivityService extends IConnectivityManager.Stub } mLegacyTypeTracker.remove(nai, wasDefault); if (!nai.networkCapabilities.hasTransport(TRANSPORT_VPN)) { - updateAllVpnsCapabilities(); + propagateUnderlyingNetworkCapabilities(); } rematchAllNetworksAndRequests(); mLingerMonitor.noteDisconnect(nai); @@ -4704,10 +4730,9 @@ public class ConnectivityService extends IConnectivityManager.Stub if (mLockdownEnabled) { return new VpnInfo[0]; } - List<VpnInfo> infoList = new ArrayList<>(); - for (int i = 0; i < mVpns.size(); i++) { - VpnInfo info = createVpnInfo(mVpns.valueAt(i)); + for (NetworkAgentInfo nai : mNetworkAgentInfos.values()) { + VpnInfo info = createVpnInfo(nai); if (info != null) { infoList.add(info); } @@ -4720,13 +4745,10 @@ public class ConnectivityService extends IConnectivityManager.Stub * @return VPN information for accounting, or null if we can't retrieve all required * information, e.g underlying ifaces. */ - @Nullable - private VpnInfo createVpnInfo(Vpn vpn) { - VpnInfo info = vpn.getVpnInfo(); - if (info == null) { - return null; - } - Network[] underlyingNetworks = vpn.getUnderlyingNetworks(); + private VpnInfo createVpnInfo(NetworkAgentInfo nai) { + if (!nai.isVPN()) return null; + + Network[] underlyingNetworks = nai.declaredUnderlyingNetworks; // see VpnService.setUnderlyingNetworks()'s javadoc about how to interpret // the underlyingNetworks list. if (underlyingNetworks == null) { @@ -4735,23 +4757,33 @@ public class ConnectivityService extends IConnectivityManager.Stub underlyingNetworks = new Network[] { defaultNai.network }; } } - if (underlyingNetworks != null && underlyingNetworks.length > 0) { - List<String> interfaces = new ArrayList<>(); - for (Network network : underlyingNetworks) { - LinkProperties lp = getLinkProperties(network); - if (lp != null) { - for (String iface : lp.getAllInterfaceNames()) { - if (!TextUtils.isEmpty(iface)) { - interfaces.add(iface); - } - } + + if (ArrayUtils.isEmpty(underlyingNetworks)) return null; + + List<String> interfaces = new ArrayList<>(); + for (Network network : underlyingNetworks) { + NetworkAgentInfo underlyingNai = getNetworkAgentInfoForNetwork(network); + if (underlyingNai == null) continue; + LinkProperties lp = underlyingNai.linkProperties; + for (String iface : lp.getAllInterfaceNames()) { + if (!TextUtils.isEmpty(iface)) { + interfaces.add(iface); } } - if (!interfaces.isEmpty()) { - info.underlyingIfaces = interfaces.toArray(new String[interfaces.size()]); - } } - return info.underlyingIfaces == null ? null : info; + + if (interfaces.isEmpty()) return null; + + VpnInfo info = new VpnInfo(); + info.ownerUid = nai.networkCapabilities.getOwnerUid(); + info.vpnIface = nai.linkProperties.getInterfaceName(); + // Must be non-null or NetworkStatsService will crash. + // Cannot happen in production code because Vpn only registers the NetworkAgent after the + // tun or ipsec interface is created. + if (info.vpnIface == null) return null; + info.underlyingIfaces = interfaces.toArray(new String[0]); + + return info; } /** @@ -4774,22 +4806,17 @@ public class ConnectivityService extends IConnectivityManager.Stub } /** - * Ask all VPN objects to recompute and update their capabilities. + * Ask all networks with underlying networks to recompute and update their capabilities. * - * When underlying networks change, VPNs may have to update capabilities to reflect things - * like the metered bit, their transports, and so on. This asks the VPN objects to update - * their capabilities, and as this will cause them to send messages to the ConnectivityService - * handler thread through their agent, this is asynchronous. When the capabilities objects - * are computed they will be up-to-date as they are computed synchronously from here and - * this is running on the ConnectivityService thread. + * When underlying networks change, such networks may have to update capabilities to reflect + * things like the metered bit, their transports, and so on. The capabilities are calculated + * immediately. This method runs on the ConnectivityService thread. */ - private void updateAllVpnsCapabilities() { - Network defaultNetwork = getNetwork(getDefaultNetwork()); - synchronized (mVpns) { - for (int i = 0; i < mVpns.size(); i++) { - final Vpn vpn = mVpns.valueAt(i); - NetworkCapabilities nc = vpn.updateCapabilities(defaultNetwork); - updateVpnCapabilities(vpn, nc); + private void propagateUnderlyingNetworkCapabilities() { + ensureRunningOnConnectivityServiceThread(); + for (NetworkAgentInfo nai : mNetworkAgentInfos.values()) { + if (nai.supportsUnderlyingNetworks()) { + updateCapabilities(nai.getCurrentScore(), nai, nai.networkCapabilities); } } } @@ -5959,13 +5986,29 @@ public class ConnectivityService extends IConnectivityManager.Stub int currentScore, NetworkAgentConfig networkAgentConfig, int providerId) { if (networkCapabilities.hasTransport(TRANSPORT_TEST)) { enforceAnyPermissionOf(Manifest.permission.MANAGE_TEST_NETWORKS); + } else { + enforceNetworkFactoryPermission(); + } + + final int uid = Binder.getCallingUid(); + final long token = Binder.clearCallingIdentity(); + try { + return registerNetworkAgentInternal(messenger, networkInfo, linkProperties, + networkCapabilities, currentScore, networkAgentConfig, providerId, uid); + } finally { + Binder.restoreCallingIdentity(token); + } + } + + private Network registerNetworkAgentInternal(Messenger messenger, NetworkInfo networkInfo, + LinkProperties linkProperties, NetworkCapabilities networkCapabilities, + int currentScore, NetworkAgentConfig networkAgentConfig, int providerId, int uid) { + if (networkCapabilities.hasTransport(TRANSPORT_TEST)) { // Strictly, sanitizing here is unnecessary as the capabilities will be sanitized in // the call to mixInCapabilities below anyway, but sanitizing here means the NAI never // sees capabilities that may be malicious, which might prevent mistakes in the future. networkCapabilities = new NetworkCapabilities(networkCapabilities); - networkCapabilities.restrictCapabilitesForTestNetwork(Binder.getCallingUid()); - } else { - enforceNetworkFactoryPermission(); + networkCapabilities.restrictCapabilitesForTestNetwork(uid); } LinkProperties lp = new LinkProperties(linkProperties); @@ -5976,9 +6019,10 @@ public class ConnectivityService extends IConnectivityManager.Stub final NetworkAgentInfo nai = new NetworkAgentInfo(messenger, new AsyncChannel(), new Network(mNetIdManager.reserveNetId()), new NetworkInfo(networkInfo), lp, nc, currentScore, mContext, mTrackerHandler, new NetworkAgentConfig(networkAgentConfig), - this, mNetd, mDnsResolver, mNMS, providerId, Binder.getCallingUid()); + this, mNetd, mDnsResolver, mNMS, providerId, uid); // Make sure the LinkProperties and NetworkCapabilities reflect what the agent info says. + processCapabilitiesFromAgent(nai, nc); nai.getAndSetNetworkCapabilities(mixInCapabilities(nai, nc)); processLinkPropertiesFromAgent(nai, nai.linkProperties); @@ -5986,13 +6030,8 @@ public class ConnectivityService extends IConnectivityManager.Stub final String name = TextUtils.isEmpty(extraInfo) ? nai.networkCapabilities.getSsid() : extraInfo; if (DBG) log("registerNetworkAgent " + nai); - final long token = Binder.clearCallingIdentity(); - try { - mDeps.getNetworkStack().makeNetworkMonitor( - nai.network, name, new NetworkMonitorCallbacks(nai)); - } finally { - Binder.restoreCallingIdentity(token); - } + mDeps.getNetworkStack().makeNetworkMonitor( + nai.network, name, new NetworkMonitorCallbacks(nai)); // NetworkAgentInfo registration will finish when the NetworkMonitor is created. // If the network disconnects or sends any other event before that, messages are deferred by // NetworkAgent until nai.asyncChannel.connect(), which will be called when finalizing the @@ -6019,6 +6058,12 @@ public class ConnectivityService extends IConnectivityManager.Stub updateUids(nai, null, nai.networkCapabilities); } + /** + * Called when receiving LinkProperties directly from a NetworkAgent. + * Stores into |nai| any data coming from the agent that might also be written to the network's + * LinkProperties by ConnectivityService itself. This ensures that the data provided by the + * agent is not lost when updateLinkProperties is called. + */ private void processLinkPropertiesFromAgent(NetworkAgentInfo nai, LinkProperties lp) { lp.ensureDirectlyConnectedRoutes(); nai.clatd.setNat64PrefixFromRa(lp.getNat64Prefix()); @@ -6315,6 +6360,30 @@ public class ConnectivityService extends IConnectivityManager.Stub } /** + * Called when receiving NetworkCapabilities directly from a NetworkAgent. + * Stores into |nai| any data coming from the agent that might also be written to the network's + * NetworkCapabilities by ConnectivityService itself. This ensures that the data provided by the + * agent is not lost when updateCapabilities is called. + */ + private void processCapabilitiesFromAgent(NetworkAgentInfo nai, NetworkCapabilities nc) { + nai.declaredMetered = !nc.hasCapability(NET_CAPABILITY_NOT_METERED); + } + + /** Propagates to |nc| the capabilities declared by the underlying networks of |nai|. */ + private void mixInUnderlyingCapabilities(NetworkAgentInfo nai, NetworkCapabilities nc) { + Network[] underlyingNetworks = nai.declaredUnderlyingNetworks; + Network defaultNetwork = getNetwork(getDefaultNetwork()); + if (underlyingNetworks == null && defaultNetwork != null) { + // null underlying networks means to track the default. + underlyingNetworks = new Network[] { defaultNetwork }; + } + + // TODO(b/124469351): Get capabilities directly from ConnectivityService instead. + final ConnectivityManager cm = mContext.getSystemService(ConnectivityManager.class); + Vpn.applyUnderlyingCapabilities(cm, underlyingNetworks, nc, nai.declaredMetered); + } + + /** * Augments the NetworkCapabilities passed in by a NetworkAgent with capabilities that are * maintained here that the NetworkAgent is not aware of (e.g., validated, captive portal, * and foreground status). @@ -6367,6 +6436,10 @@ public class ConnectivityService extends IConnectivityManager.Stub newNc.addCapability(NET_CAPABILITY_NOT_ROAMING); } + if (nai.supportsUnderlyingNetworks()) { + mixInUnderlyingCapabilities(nai, newNc); + } + return newNc; } @@ -6446,7 +6519,7 @@ public class ConnectivityService extends IConnectivityManager.Stub if (!newNc.hasTransport(TRANSPORT_VPN)) { // Tell VPNs about updated capabilities, since they may need to // bubble those changes through. - updateAllVpnsCapabilities(); + propagateUnderlyingNetworkCapabilities(); } if (!newNc.equalsTransportTypes(prevNc)) { @@ -6766,7 +6839,7 @@ public class ConnectivityService extends IConnectivityManager.Stub ? newNetwork.linkProperties.getTcpBufferSizes() : null); notifyIfacesChangedForNetworkStats(); // Fix up the NetworkCapabilities of any VPNs that don't specify underlying networks. - updateAllVpnsCapabilities(); + propagateUnderlyingNetworkCapabilities(); } private void processListenRequests(@NonNull final NetworkAgentInfo nai) { @@ -7228,7 +7301,7 @@ public class ConnectivityService extends IConnectivityManager.Stub // onCapabilitiesUpdated being sent in updateAllVpnCapabilities below as // the VPN would switch from its default, blank capabilities to those // that reflect the capabilities of its underlying networks. - updateAllVpnsCapabilities(); + propagateUnderlyingNetworkCapabilities(); } networkAgent.created = true; } @@ -7270,8 +7343,8 @@ public class ConnectivityService extends IConnectivityManager.Stub // doing. updateSignalStrengthThresholds(networkAgent, "CONNECT", null); - if (networkAgent.isVPN()) { - updateAllVpnsCapabilities(); + if (networkAgent.supportsUnderlyingNetworks()) { + propagateUnderlyingNetworkCapabilities(); } // Consider network even though it is not yet validated. @@ -7528,13 +7601,6 @@ public class ConnectivityService extends IConnectivityManager.Stub throwIfLockdownEnabled(); success = mVpns.get(user).setUnderlyingNetworks(networks); } - if (success) { - mHandler.post(() -> { - // Update VPN's capabilities based on updated underlying network set. - updateAllVpnsCapabilities(); - notifyIfacesChangedForNetworkStats(); - }); - } return success; } diff --git a/services/core/java/com/android/server/OWNERS b/services/core/java/com/android/server/OWNERS index 8099f8f37bc7..3d1e709ab3bd 100644 --- a/services/core/java/com/android/server/OWNERS +++ b/services/core/java/com/android/server/OWNERS @@ -7,3 +7,6 @@ per-file VibratorService.java, DisplayThread.java = ogunwale@google.com # Zram writeback per-file ZramWriteback.java = minchan@google.com, rajekumar@google.com, srnvs@google.com + +# Userspace reboot +per-file UserspaceRebootLogger.java = ioffe@google.com, tomcherry@google.com diff --git a/services/core/java/com/android/server/UserspaceRebootLogger.java b/services/core/java/com/android/server/UserspaceRebootLogger.java index 2403b637581f..89327b50883c 100644 --- a/services/core/java/com/android/server/UserspaceRebootLogger.java +++ b/services/core/java/com/android/server/UserspaceRebootLogger.java @@ -59,7 +59,7 @@ public final class UserspaceRebootLogger { */ public static void noteUserspaceRebootWasRequested() { if (!PowerManager.isRebootingUserspaceSupportedImpl()) { - Slog.wtf(TAG, "Userspace reboot is not supported."); + Slog.wtf(TAG, "noteUserspaceRebootWasRequested: Userspace reboot is not supported."); return; } @@ -77,7 +77,7 @@ public final class UserspaceRebootLogger { */ public static void noteUserspaceRebootSuccess() { if (!PowerManager.isRebootingUserspaceSupportedImpl()) { - Slog.wtf(TAG, "Userspace reboot is not supported."); + Slog.wtf(TAG, "noteUserspaceRebootSuccess: Userspace reboot is not supported."); return; } @@ -88,11 +88,11 @@ public final class UserspaceRebootLogger { /** * Returns {@code true} if {@code UserspaceRebootReported} atom should be logged. * - * <p>This call should only be made on devices supporting userspace reboot. + * <p>On devices that do not support userspace reboot this method will always return {@code + * false}. */ public static boolean shouldLogUserspaceRebootEvent() { if (!PowerManager.isRebootingUserspaceSupportedImpl()) { - Slog.wtf(TAG, "Userspace reboot is not supported."); return false; } @@ -110,7 +110,7 @@ public final class UserspaceRebootLogger { */ public static void logEventAsync(boolean userUnlocked, Executor executor) { if (!PowerManager.isRebootingUserspaceSupportedImpl()) { - Slog.wtf(TAG, "Userspace reboot is not supported."); + Slog.wtf(TAG, "logEventAsync: Userspace reboot is not supported."); return; } diff --git a/services/core/java/com/android/server/connectivity/NetworkAgentInfo.java b/services/core/java/com/android/server/connectivity/NetworkAgentInfo.java index a9f62d91592d..3270dd55218c 100644 --- a/services/core/java/com/android/server/connectivity/NetworkAgentInfo.java +++ b/services/core/java/com/android/server/connectivity/NetworkAgentInfo.java @@ -132,6 +132,16 @@ public class NetworkAgentInfo implements Comparable<NetworkAgentInfo> { // TODO: make this private with a getter. public NetworkCapabilities networkCapabilities; public final NetworkAgentConfig networkAgentConfig; + + // Underlying networks declared by the agent. Only set if supportsUnderlyingNetworks is true. + // The networks in this list might be declared by a VPN app using setUnderlyingNetworks and are + // not guaranteed to be current or correct, or even to exist. + public @Nullable Network[] declaredUnderlyingNetworks; + + // Whether this network is always metered even if its underlying networks are unmetered. + // Only relevant if #supportsUnderlyingNetworks is true. + public boolean declaredMetered; + // Indicates if netd has been told to create this Network. From this point on the appropriate // routing rules are setup and routes are added so packets can begin flowing over the Network. // This is a sticky bit; once set it is never cleared. @@ -474,10 +484,16 @@ public class NetworkAgentInfo implements Comparable<NetworkAgentInfo> { networkCapabilities); } + /** Whether this network is a VPN. */ public boolean isVPN() { return networkCapabilities.hasTransport(NetworkCapabilities.TRANSPORT_VPN); } + /** Whether this network might have underlying networks. Currently only true for VPNs. */ + public boolean supportsUnderlyingNetworks() { + 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 diff --git a/services/core/java/com/android/server/connectivity/Vpn.java b/services/core/java/com/android/server/connectivity/Vpn.java index ff1a9c0ab35f..4f5c13db1231 100644 --- a/services/core/java/com/android/server/connectivity/Vpn.java +++ b/services/core/java/com/android/server/connectivity/Vpn.java @@ -112,7 +112,6 @@ import com.android.internal.net.VpnConfig; import com.android.internal.net.VpnInfo; import com.android.internal.net.VpnProfile; import com.android.internal.util.ArrayUtils; -import com.android.server.ConnectivityService; import com.android.server.DeviceIdleInternal; import com.android.server.LocalServices; import com.android.server.net.BaseNetworkObserver; @@ -1262,6 +1261,15 @@ public class Vpn { mNetworkCapabilities.setAdministratorUids(new int[] {mOwnerUID}); mNetworkCapabilities.setUids(createUserAndRestrictedProfilesRanges(mUserId, mConfig.allowedApplications, mConfig.disallowedApplications)); + + // Only apps targeting Q and above can explicitly declare themselves as metered. + // These VPNs are assumed metered unless they state otherwise. + if (mIsPackageTargetingAtLeastQ && mConfig.isMetered) { + mNetworkCapabilities.removeCapability(NET_CAPABILITY_NOT_METERED); + } else { + mNetworkCapabilities.addCapability(NET_CAPABILITY_NOT_METERED); + } + final long token = Binder.clearCallingIdentity(); try { mNetworkAgent = new NetworkAgent(mLooper, mContext, NETWORKTYPE /* logtag */, @@ -1276,6 +1284,8 @@ public class Vpn { } finally { Binder.restoreCallingIdentity(token); } + mNetworkAgent.setUnderlyingNetworks((mConfig.underlyingNetworks != null) + ? Arrays.asList(mConfig.underlyingNetworks) : null); mNetworkInfo.setIsAvailable(true); updateState(DetailedState.CONNECTED, "agentConnect"); } @@ -1857,6 +1867,8 @@ public class Vpn { } } } + mNetworkAgent.setUnderlyingNetworks((mConfig.underlyingNetworks != null) + ? Arrays.asList(mConfig.underlyingNetworks) : null); return true; } diff --git a/services/core/java/com/android/server/timedetector/TimeDetectorService.java b/services/core/java/com/android/server/timedetector/TimeDetectorService.java index c63f306ec84f..6dac6b1773c4 100644 --- a/services/core/java/com/android/server/timedetector/TimeDetectorService.java +++ b/services/core/java/com/android/server/timedetector/TimeDetectorService.java @@ -125,7 +125,7 @@ public final class TimeDetectorService extends ITimeDetectorService.Stub { /** Internal method for handling the auto time setting being changed. */ @VisibleForTesting public void handleAutoTimeDetectionChanged() { - mHandler.post(mTimeDetectorStrategy::handleAutoTimeDetectionChanged); + mHandler.post(mTimeDetectorStrategy::handleAutoTimeConfigChanged); } @Override diff --git a/services/core/java/com/android/server/timedetector/TimeDetectorStrategy.java b/services/core/java/com/android/server/timedetector/TimeDetectorStrategy.java index 13f0ab605b3a..abd4c8c63a07 100644 --- a/services/core/java/com/android/server/timedetector/TimeDetectorStrategy.java +++ b/services/core/java/com/android/server/timedetector/TimeDetectorStrategy.java @@ -16,6 +16,7 @@ package com.android.server.timedetector; +import android.annotation.IntDef; import android.annotation.NonNull; import android.annotation.Nullable; import android.app.timedetector.ManualTimeSuggestion; @@ -24,6 +25,8 @@ import android.app.timedetector.TelephonyTimeSuggestion; import android.os.TimestampedValue; import java.io.PrintWriter; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; /** * The interface for the class that implements the time detection algorithm used by the @@ -37,22 +40,41 @@ import java.io.PrintWriter; */ public interface TimeDetectorStrategy { - /** Process the suggested time from telephony sources. */ + @IntDef({ ORIGIN_TELEPHONY, ORIGIN_MANUAL, ORIGIN_NETWORK }) + @Retention(RetentionPolicy.SOURCE) + @interface Origin {} + + /** Used when a time value originated from a telephony signal. */ + @Origin + int ORIGIN_TELEPHONY = 1; + + /** Used when a time value originated from a user / manual settings. */ + @Origin + int ORIGIN_MANUAL = 2; + + /** Used when a time value originated from a network signal. */ + @Origin + int ORIGIN_NETWORK = 3; + + /** Processes the suggested time from telephony sources. */ void suggestTelephonyTime(@NonNull TelephonyTimeSuggestion timeSuggestion); /** - * Process the suggested manually entered time. Returns {@code false} if the suggestion was + * Processes the suggested manually entered time. Returns {@code false} if the suggestion was * invalid, or the device configuration prevented the suggestion being used, {@code true} if the * suggestion was accepted. A suggestion that is valid but does not change the time because it * matches the current device time is considered accepted. */ boolean suggestManualTime(@NonNull ManualTimeSuggestion timeSuggestion); - /** Process the suggested time from network sources. */ + /** Processes the suggested time from network sources. */ void suggestNetworkTime(@NonNull NetworkTimeSuggestion timeSuggestion); - /** Handle the auto-time setting being toggled on or off. */ - void handleAutoTimeDetectionChanged(); + /** + * Handles the auto-time configuration changing For example, when the auto-time setting is + * toggled on or off. + */ + void handleAutoTimeConfigChanged(); /** Dump debug information. */ void dump(@NonNull PrintWriter pw, @Nullable String[] args); @@ -67,4 +89,38 @@ public interface TimeDetectorStrategy { return (referenceClockMillisNow - timeValue.getReferenceTimeMillis()) + timeValue.getValue(); } + + /** + * Converts one of the {@code ORIGIN_} constants to a human readable string suitable for config + * and debug usage. Throws an {@link IllegalArgumentException} if the value is unrecognized. + */ + static String originToString(@Origin int origin) { + switch (origin) { + case ORIGIN_MANUAL: + return "manual"; + case ORIGIN_NETWORK: + return "network"; + case ORIGIN_TELEPHONY: + return "telephony"; + default: + throw new IllegalArgumentException("origin=" + origin); + } + } + + /** + * Converts a human readable config string to one of the {@code ORIGIN_} constants. + * Throws an {@link IllegalArgumentException} if the value is unrecognized. + */ + static @Origin int stringToOrigin(String originString) { + switch (originString) { + case "manual": + return ORIGIN_MANUAL; + case "network": + return ORIGIN_NETWORK; + case "telephony": + return ORIGIN_TELEPHONY; + default: + throw new IllegalArgumentException("originString=" + originString); + } + } } diff --git a/services/core/java/com/android/server/timedetector/TimeDetectorStrategyCallbackImpl.java b/services/core/java/com/android/server/timedetector/TimeDetectorStrategyCallbackImpl.java index 6bd107fffeaa..5b6de0518999 100644 --- a/services/core/java/com/android/server/timedetector/TimeDetectorStrategyCallbackImpl.java +++ b/services/core/java/com/android/server/timedetector/TimeDetectorStrategyCallbackImpl.java @@ -16,6 +16,8 @@ package com.android.server.timedetector; +import static com.android.server.timedetector.TimeDetectorStrategy.stringToOrigin; + import android.annotation.NonNull; import android.app.AlarmManager; import android.content.ContentResolver; @@ -58,6 +60,7 @@ public final class TimeDetectorStrategyCallbackImpl implements TimeDetectorStrat @NonNull private final ContentResolver mContentResolver; @NonNull private final PowerManager.WakeLock mWakeLock; @NonNull private final AlarmManager mAlarmManager; + @NonNull private final int[] mOriginPriorities; public TimeDetectorStrategyCallbackImpl(@NonNull Context context) { mContext = Objects.requireNonNull(context); @@ -72,6 +75,15 @@ public final class TimeDetectorStrategyCallbackImpl implements TimeDetectorStrat mSystemClockUpdateThresholdMillis = SystemProperties.getInt("ro.sys.time_detector_update_diff", SYSTEM_CLOCK_UPDATE_THRESHOLD_MILLIS_DEFAULT); + + // TODO(b/172230856): Obtain these values from configuration. + String[] originStrings = { "telephony", "network" }; + int[] origins = new int[originStrings.length]; + for (int i = 0; i < originStrings.length; i++) { + int origin = stringToOrigin(originStrings[i]); + origins[i] = origin; + } + mOriginPriorities = origins; } @Override @@ -94,6 +106,11 @@ public final class TimeDetectorStrategyCallbackImpl implements TimeDetectorStrat } @Override + public int[] getAutoOriginPriorities() { + return mOriginPriorities; + } + + @Override public void acquireWakeLock() { if (mWakeLock.isHeld()) { Slog.wtf(TAG, "WakeLock " + mWakeLock + " already held"); diff --git a/services/core/java/com/android/server/timedetector/TimeDetectorStrategyImpl.java b/services/core/java/com/android/server/timedetector/TimeDetectorStrategyImpl.java index a889bdfe17b6..36a3ddd73d89 100644 --- a/services/core/java/com/android/server/timedetector/TimeDetectorStrategyImpl.java +++ b/services/core/java/com/android/server/timedetector/TimeDetectorStrategyImpl.java @@ -16,7 +16,8 @@ package com.android.server.timedetector; -import android.annotation.IntDef; +import static com.android.server.timedetector.TimeDetectorStrategy.originToString; + import android.annotation.NonNull; import android.annotation.Nullable; import android.app.AlarmManager; @@ -34,9 +35,8 @@ import com.android.server.timezonedetector.ArrayMapWithHistory; import com.android.server.timezonedetector.ReferenceWithHistory; import java.io.PrintWriter; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; import java.time.Instant; +import java.util.Arrays; /** * An implementation of {@link TimeDetectorStrategy} that passes telephony and manual suggestions to @@ -64,22 +64,6 @@ public final class TimeDetectorStrategyImpl implements TimeDetectorStrategy { static final long MAX_UTC_TIME_AGE_MILLIS = TELEPHONY_BUCKET_COUNT * TELEPHONY_BUCKET_SIZE_MILLIS; - @IntDef({ ORIGIN_TELEPHONY, ORIGIN_MANUAL, ORIGIN_NETWORK }) - @Retention(RetentionPolicy.SOURCE) - public @interface Origin {} - - /** Used when a time value originated from a telephony signal. */ - @Origin - private static final int ORIGIN_TELEPHONY = 1; - - /** Used when a time value originated from a user / manual settings. */ - @Origin - private static final int ORIGIN_MANUAL = 2; - - /** Used when a time value originated from a network signal. */ - @Origin - private static final int ORIGIN_NETWORK = 3; - /** * CLOCK_PARANOIA: The maximum difference allowed between the expected system clock time and the * actual system clock time before a warning is logged. Used to help identify situations where @@ -153,6 +137,12 @@ public final class TimeDetectorStrategyImpl implements TimeDetectorStrategy { @NonNull Instant autoTimeLowerBound(); + /** + * Returns the order to look at time suggestions when automatically detecting time. + * See {@code #ORIGIN_} constants + */ + @Origin int[] getAutoOriginPriorities(); + /** Acquire a suitable wake lock. Must be followed by {@link #releaseWakeLock()} */ void acquireWakeLock(); @@ -237,12 +227,12 @@ public final class TimeDetectorStrategyImpl implements TimeDetectorStrategy { } @Override - public synchronized void handleAutoTimeDetectionChanged() { + public synchronized void handleAutoTimeConfigChanged() { boolean enabled = mCallback.isAutoTimeDetectionEnabled(); // When automatic time detection is enabled we update the system clock instantly if we can. // Conversely, when automatic time detection is disabled we leave the clock as it is. if (enabled) { - String reason = "Auto time zone detection setting enabled."; + String reason = "Auto time zone detection config changed."; doAutoTimeDetection(reason); } else { // CLOCK_PARANOIA: We are losing "control" of the system clock so we cannot predict what @@ -365,33 +355,44 @@ public final class TimeDetectorStrategyImpl implements TimeDetectorStrategy { return; } - // Android devices currently prioritize any telephony over network signals. There are - // carrier compliance tests that would need to be changed before we could ignore NITZ or - // prefer NTP generally. This check is cheap on devices without telephony hardware. - TelephonyTimeSuggestion bestTelephonySuggestion = findBestTelephonySuggestion(); - if (bestTelephonySuggestion != null) { - final TimestampedValue<Long> newUtcTime = bestTelephonySuggestion.getUtcTime(); - String cause = "Found good telephony suggestion." - + ", bestTelephonySuggestion=" + bestTelephonySuggestion - + ", detectionReason=" + detectionReason; - setSystemClockIfRequired(ORIGIN_TELEPHONY, newUtcTime, cause); - return; - } + // Try the different origins one at a time. + int[] originPriorities = mCallback.getAutoOriginPriorities(); + for (int origin : originPriorities) { + TimestampedValue<Long> newUtcTime = null; + String cause = null; + if (origin == ORIGIN_TELEPHONY) { + TelephonyTimeSuggestion bestTelephonySuggestion = findBestTelephonySuggestion(); + if (bestTelephonySuggestion != null) { + newUtcTime = bestTelephonySuggestion.getUtcTime(); + cause = "Found good telephony suggestion." + + ", bestTelephonySuggestion=" + bestTelephonySuggestion + + ", detectionReason=" + detectionReason; + } + } else if (origin == ORIGIN_NETWORK) { + NetworkTimeSuggestion networkSuggestion = findLatestValidNetworkSuggestion(); + if (networkSuggestion != null) { + newUtcTime = networkSuggestion.getUtcTime(); + cause = "Found good network suggestion." + + ", networkSuggestion=" + networkSuggestion + + ", detectionReason=" + detectionReason; + } + } else { + Slog.w(LOG_TAG, "Unknown or unsupported origin=" + origin + + " in " + Arrays.toString(originPriorities) + + ": Skipping"); + } - // There is no good telephony suggestion, try network. - NetworkTimeSuggestion networkSuggestion = findLatestValidNetworkSuggestion(); - if (networkSuggestion != null) { - final TimestampedValue<Long> newUtcTime = networkSuggestion.getUtcTime(); - String cause = "Found good network suggestion." - + ", networkSuggestion=" + networkSuggestion - + ", detectionReason=" + detectionReason; - setSystemClockIfRequired(ORIGIN_NETWORK, newUtcTime, cause); - return; + // Update the system clock if a good suggestion has been found. + if (newUtcTime != null) { + setSystemClockIfRequired(origin, newUtcTime, cause); + return; + } } if (DBG) { - Slog.d(LOG_TAG, "Could not determine time: No best telephony or network suggestion." - + " detectionReason=" + detectionReason); + Slog.d(LOG_TAG, "Could not determine time: No suggestion found in" + + " originPriorities=" + Arrays.toString(originPriorities) + + ", detectionReason=" + detectionReason); } } @@ -476,7 +477,7 @@ public final class TimeDetectorStrategyImpl implements TimeDetectorStrategy { // Validate first. TimestampedValue<Long> utcTime = timeSuggestion.getUtcTime(); if (!validateSuggestionUtcTime(elapsedRealtimeMillis, utcTime)) { - Slog.w(LOG_TAG, "Existing suggestion found to be invalid " + Slog.w(LOG_TAG, "Existing suggestion found to be invalid" + " elapsedRealtimeMillis=" + elapsedRealtimeMillis + ", timeSuggestion=" + timeSuggestion); return TELEPHONY_INVALID_SCORE; @@ -525,7 +526,7 @@ public final class TimeDetectorStrategyImpl implements TimeDetectorStrategy { if (!mCallback.isAutoTimeDetectionEnabled()) { if (DBG) { Slog.d(LOG_TAG, "Auto time detection is not enabled." - + " origin=" + origin + + " origin=" + originToString(origin) + ", time=" + time + ", cause=" + cause); } @@ -535,7 +536,7 @@ public final class TimeDetectorStrategyImpl implements TimeDetectorStrategy { if (mCallback.isAutoTimeDetectionEnabled()) { if (DBG) { Slog.d(LOG_TAG, "Auto time detection is enabled." - + " origin=" + origin + + " origin=" + originToString(origin) + ", time=" + time + ", cause=" + cause); } @@ -557,7 +558,7 @@ public final class TimeDetectorStrategyImpl implements TimeDetectorStrategy { @GuardedBy("this") private boolean setSystemClockUnderWakeLock( - int origin, @NonNull TimestampedValue<Long> newTime, @NonNull Object cause) { + @Origin int origin, @NonNull TimestampedValue<Long> newTime, @NonNull String cause) { long elapsedRealtimeMillis = mCallback.elapsedRealtimeMillis(); boolean isOriginAutomatic = isOriginAutomatic(origin); diff --git a/services/tests/servicestests/src/com/android/server/timedetector/TimeDetectorServiceTest.java b/services/tests/servicestests/src/com/android/server/timedetector/TimeDetectorServiceTest.java index 02031bc4f210..22addf948a53 100644 --- a/services/tests/servicestests/src/com/android/server/timedetector/TimeDetectorServiceTest.java +++ b/services/tests/servicestests/src/com/android/server/timedetector/TimeDetectorServiceTest.java @@ -242,7 +242,7 @@ public class TimeDetectorServiceTest { } @Override - public void handleAutoTimeDetectionChanged() { + public void handleAutoTimeConfigChanged() { mHandleAutoTimeDetectionChangedCalled = true; } diff --git a/services/tests/servicestests/src/com/android/server/timedetector/TimeDetectorStrategyImplTest.java b/services/tests/servicestests/src/com/android/server/timedetector/TimeDetectorStrategyImplTest.java index 217de55fb400..c23fb8028224 100644 --- a/services/tests/servicestests/src/com/android/server/timedetector/TimeDetectorStrategyImplTest.java +++ b/services/tests/servicestests/src/com/android/server/timedetector/TimeDetectorStrategyImplTest.java @@ -16,6 +16,9 @@ package com.android.server.timedetector; +import static com.android.server.timedetector.TimeDetectorStrategy.ORIGIN_NETWORK; +import static com.android.server.timedetector.TimeDetectorStrategy.ORIGIN_TELEPHONY; + import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNull; @@ -29,6 +32,8 @@ import android.os.TimestampedValue; import androidx.test.runner.AndroidJUnit4; +import com.android.server.timedetector.TimeDetectorStrategy.Origin; + import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; @@ -48,6 +53,9 @@ public class TimeDetectorStrategyImplTest { 123456789L /* realtimeClockMillis */, createUtcTime(2010, 5, 23, 12, 0, 0)); + // This is the traditional ordering for time detection on Android. + private static final @Origin int [] PROVIDERS_PRIORITY = { ORIGIN_TELEPHONY, ORIGIN_NETWORK }; + /** * An arbitrary time, very different from the {@link #ARBITRARY_CLOCK_INITIALIZATION_INFO} * time. Can be used as the basis for time suggestions. @@ -488,11 +496,8 @@ public class TimeDetectorStrategyImplTest { .assertLatestTelephonySuggestion(slotIndex, telephonyTimeSuggestion); } - /** - * Manual suggestions should be ignored if auto time is enabled. - */ @Test - public void testSuggestManualTime_autoTimeEnabled() { + public void manualTimeSuggestion_isIgnored_whenAutoTimeEnabled() { mScript.pokeFakeClocks(ARBITRARY_CLOCK_INITIALIZATION_INFO) .pokeAutoTimeDetectionEnabled(true); @@ -505,7 +510,7 @@ public class TimeDetectorStrategyImplTest { } @Test - public void suggestManualTime_ignoresTimeLowerBound() { + public void manualTimeSuggestion_ignoresTimeLowerBound() { mScript.pokeFakeClocks(ARBITRARY_CLOCK_INITIALIZATION_INFO) .pokeAutoTimeDetectionEnabled(false); Instant suggestedTime = TIME_LOWER_BOUND.minus(Duration.ofDays(1)); @@ -658,6 +663,73 @@ public class TimeDetectorStrategyImplTest { .assertLatestNetworkSuggestion(null); } + @Test + public void whenAllTimeSuggestionsAreAvailable_higherPriorityWins_lowerPriorityComesFirst() { + mScript.pokeFakeClocks(ARBITRARY_CLOCK_INITIALIZATION_INFO) + .pokeAutoTimeDetectionEnabled(true); + + Instant networkTime = ARBITRARY_TEST_TIME; + Instant telephonyTime = ARBITRARY_TEST_TIME.plus(Duration.ofDays(30)); + + NetworkTimeSuggestion networkTimeSuggestion = + mScript.generateNetworkTimeSuggestion(networkTime); + TelephonyTimeSuggestion telephonyTimeSuggestion = + mScript.generateTelephonyTimeSuggestion(ARBITRARY_SLOT_INDEX, telephonyTime); + + mScript.simulateNetworkTimeSuggestion(networkTimeSuggestion) + .simulateTelephonyTimeSuggestion(telephonyTimeSuggestion) + .assertLatestNetworkSuggestion(networkTimeSuggestion) + .assertLatestTelephonySuggestion(ARBITRARY_SLOT_INDEX, telephonyTimeSuggestion) + .verifySystemClockWasSetAndResetCallTracking(telephonyTime.toEpochMilli()); + } + + @Test + public void whenAllTimeSuggestionsAreAvailable_higherPriorityWins_higherPriorityComesFirst() { + mScript.pokeFakeClocks(ARBITRARY_CLOCK_INITIALIZATION_INFO) + .pokeAutoTimeDetectionEnabled(true); + + Instant networkTime = ARBITRARY_TEST_TIME; + Instant telephonyTime = ARBITRARY_TEST_TIME.plus(Duration.ofDays(30)); + + NetworkTimeSuggestion networkTimeSuggestion = + mScript.generateNetworkTimeSuggestion(networkTime); + TelephonyTimeSuggestion telephonyTimeSuggestion = + mScript.generateTelephonyTimeSuggestion(ARBITRARY_SLOT_INDEX, telephonyTime); + + mScript.simulateTelephonyTimeSuggestion(telephonyTimeSuggestion) + .simulateNetworkTimeSuggestion(networkTimeSuggestion) + .assertLatestNetworkSuggestion(networkTimeSuggestion) + .assertLatestTelephonySuggestion(ARBITRARY_SLOT_INDEX, telephonyTimeSuggestion) + .verifySystemClockWasSetAndResetCallTracking(telephonyTime.toEpochMilli()); + } + + @Test + public void whenHighestPrioritySuggestionIsNotAvailable_fallbacksToNext() { + mScript.pokeFakeClocks(ARBITRARY_CLOCK_INITIALIZATION_INFO) + .pokeAutoTimeDetectionEnabled(true); + + NetworkTimeSuggestion timeSuggestion = + mScript.generateNetworkTimeSuggestion(ARBITRARY_TEST_TIME); + + mScript.simulateNetworkTimeSuggestion(timeSuggestion) + .assertLatestNetworkSuggestion(timeSuggestion) + .verifySystemClockWasSetAndResetCallTracking(ARBITRARY_TEST_TIME.toEpochMilli()); + } + + @Test + public void suggestionsFromSourceNotListedInPrioritiesList_areIgnored() { + mScript.pokeFakeClocks(ARBITRARY_CLOCK_INITIALIZATION_INFO) + .pokeAutoTimeDetectionEnabled(true) + .pokeAutoOriginPriorities(new int[]{ORIGIN_TELEPHONY}); + + NetworkTimeSuggestion timeSuggestion = mScript.generateNetworkTimeSuggestion( + ARBITRARY_TEST_TIME); + + mScript.simulateNetworkTimeSuggestion(timeSuggestion) + .assertLatestNetworkSuggestion(timeSuggestion) + .verifySystemClockWasNotSetAndResetCallTracking(); + } + /** * A fake implementation of TimeDetectorStrategy.Callback. Besides tracking changes and behaving * like the real thing should, it also asserts preconditions. @@ -668,6 +740,7 @@ public class TimeDetectorStrategyImplTest { private long mElapsedRealtimeMillis; private long mSystemClockMillis; private int mSystemClockUpdateThresholdMillis = 2000; + private int[] mAutoOriginPriorities = PROVIDERS_PRIORITY; // Tracking operations. private boolean mSystemClockWasSet; @@ -688,6 +761,11 @@ public class TimeDetectorStrategyImplTest { } @Override + public int[] getAutoOriginPriorities() { + return mAutoOriginPriorities; + } + + @Override public void acquireWakeLock() { if (mWakeLockAcquired) { fail("Wake lock already acquired"); @@ -736,6 +814,10 @@ public class TimeDetectorStrategyImplTest { mAutoTimeDetectionEnabled = enabled; } + void pokeAutoOriginPriorities(@Origin int[] autoOriginPriorities) { + mAutoOriginPriorities = autoOriginPriorities; + } + long peekElapsedRealtimeMillis() { return mElapsedRealtimeMillis; } @@ -804,6 +886,11 @@ public class TimeDetectorStrategyImplTest { return this; } + Script pokeAutoOriginPriorities(@Origin int[] autoOriginPriorites) { + mFakeCallback.pokeAutoOriginPriorities(autoOriginPriorites); + return this; + } + long peekElapsedRealtimeMillis() { return mFakeCallback.peekElapsedRealtimeMillis(); } @@ -836,7 +923,7 @@ public class TimeDetectorStrategyImplTest { Script simulateAutoTimeDetectionToggle() { mFakeCallback.simulateAutoTimeZoneDetectionToggle(); - mTimeDetectorStrategy.handleAutoTimeDetectionChanged(); + mTimeDetectorStrategy.handleAutoTimeConfigChanged(); return this; } @@ -870,7 +957,7 @@ public class TimeDetectorStrategyImplTest { Script assertLatestTelephonySuggestion(int slotIndex, TelephonyTimeSuggestion expected) { assertEquals( "Expected to see " + expected + " at slotIndex=" + slotIndex + ", but got " - + mTimeDetectorStrategy.getLatestTelephonySuggestion(slotIndex), + + mTimeDetectorStrategy.getLatestTelephonySuggestion(slotIndex), expected, mTimeDetectorStrategy.getLatestTelephonySuggestion(slotIndex)); return this; } diff --git a/tests/net/java/com/android/server/ConnectivityServiceTest.java b/tests/net/java/com/android/server/ConnectivityServiceTest.java index 99f1985ff691..561c6bab9c6d 100644 --- a/tests/net/java/com/android/server/ConnectivityServiceTest.java +++ b/tests/net/java/com/android/server/ConnectivityServiceTest.java @@ -1084,7 +1084,7 @@ public class ConnectivityServiceTest { throws Exception { if (mAgentRegistered) throw new IllegalStateException("already registered"); setUids(uids); - mConfig.isMetered = isAlwaysMetered; + if (!isAlwaysMetered) mNetworkCapabilities.addCapability(NET_CAPABILITY_NOT_METERED); mInterface = VPN_IFNAME; mMockNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_VPN, lp, mNetworkCapabilities); @@ -5053,6 +5053,13 @@ public class ConnectivityServiceTest { waitForIdle(); expectForceUpdateIfaces(wifiAndVpn, null); reset(mStatsService); + + // Passing in null again means follow the default network again. + mService.setUnderlyingNetworksForVpn(null); + waitForIdle(); + expectForceUpdateIfaces(wifiAndVpn, WIFI_IFNAME, Process.myUid(), VPN_IFNAME, + new String[]{WIFI_IFNAME}); + reset(mStatsService); } @Test |