summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.prebuilt_info/OWNERS1
-rw-r--r--Android.bp15
-rw-r--r--core/api/module-lib-current.txt7
-rw-r--r--core/api/system-current.txt2
-rw-r--r--core/api/test-current.txt4
-rw-r--r--core/java/android/app/ActivityThread.java2
-rw-r--r--core/java/android/bluetooth/BluetoothA2dp.java6
-rw-r--r--core/java/android/net/NetworkIdentity.java15
-rw-r--r--core/java/android/net/VpnManager.java7
-rw-r--r--core/java/android/net/vcn/VcnControlPlaneIkeConfig.java42
-rw-r--r--core/java/android/net/vcn/persistablebundleutils/CertUtils.java22
-rw-r--r--core/java/android/net/vcn/persistablebundleutils/IkeSessionParamsUtils.java513
-rw-r--r--core/java/android/os/FileUtils.java20
-rw-r--r--core/java/android/os/OWNERS2
-rw-r--r--core/java/android/os/VibrationEffect.java3
-rw-r--r--core/java/android/view/contentcapture/ContentCaptureManager.java2
-rw-r--r--core/java/com/android/internal/os/ZygoteInit.java6
-rw-r--r--core/jni/android_os_Debug.cpp2
-rw-r--r--packages/CtsShim/OWNERS2
-rw-r--r--packages/Shell/AndroidManifest.xml3
-rw-r--r--services/core/java/com/android/server/ConnectivityService.java100
-rw-r--r--services/core/java/com/android/server/ConnectivityServiceInitializer.java5
-rw-r--r--services/core/java/com/android/server/apphibernation/AppHibernationManagerInternal.java46
-rw-r--r--services/core/java/com/android/server/apphibernation/AppHibernationService.java33
-rw-r--r--services/core/java/com/android/server/locksettings/RebootEscrowManager.java4
-rw-r--r--services/core/java/com/android/server/locksettings/TEST_MAPPING11
-rw-r--r--services/core/java/com/android/server/om/OverlayManagerShellCommand.java33
-rw-r--r--services/core/java/com/android/server/vcn/UnderlyingNetworkTracker.java53
-rw-r--r--services/core/java/com/android/server/vcn/Vcn.java4
-rw-r--r--services/core/java/com/android/server/vcn/VcnGatewayConnection.java29
-rw-r--r--services/tests/servicestests/src/com/android/server/locksettings/ResumeOnRebootServiceProviderTests.java38
-rw-r--r--services/tests/servicestests/test-apps/SimpleServiceTestApp/OWNERS1
-rwxr-xr-xtelecomm/java/android/telecom/ConnectionService.java9
-rw-r--r--telephony/java/android/telephony/CarrierBandwidth.java8
-rw-r--r--telephony/java/android/telephony/TelephonyManager.java3
-rw-r--r--telephony/java/com/android/internal/telephony/RILConstants.java4
-rw-r--r--tests/net/TEST_MAPPING17
-rw-r--r--tests/net/java/com/android/server/ConnectivityServiceTest.java32
-rw-r--r--tests/vcn/assets/client-end-cert.pem21
-rw-r--r--tests/vcn/assets/client-private-key.key28
-rw-r--r--tests/vcn/java/android/net/vcn/VcnControlPlaneIkeConfigTest.java7
-rw-r--r--tests/vcn/java/android/net/vcn/persistablebundleutils/IkeSessionParamsUtilsTest.java189
-rw-r--r--tests/vcn/java/android/net/vcn/persistablebundleutils/SaProposalUtilsTest.java30
-rw-r--r--tests/vcn/java/com/android/server/vcn/UnderlyingNetworkTrackerTest.java26
-rw-r--r--tests/vcn/java/com/android/server/vcn/VcnGatewayConnectionConnectedStateTest.java9
-rw-r--r--tests/vcn/java/com/android/server/vcn/VcnGatewayConnectionConnectingStateTest.java10
-rw-r--r--tests/vcn/java/com/android/server/vcn/VcnGatewayConnectionDisconnectingStateTest.java3
-rw-r--r--tests/vcn/java/com/android/server/vcn/VcnGatewayConnectionTest.java2
48 files changed, 1251 insertions, 180 deletions
diff --git a/.prebuilt_info/OWNERS b/.prebuilt_info/OWNERS
new file mode 100644
index 000000000000..eb8b89b10e83
--- /dev/null
+++ b/.prebuilt_info/OWNERS
@@ -0,0 +1 @@
+per-file prebuilt_info_packages_CtsShim_*.asciipb = file:/packages/CtsShim/OWNERS
diff --git a/Android.bp b/Android.bp
index e79248e9d974..22246f2f4e3c 100644
--- a/Android.bp
+++ b/Android.bp
@@ -1130,6 +1130,21 @@ aidl_interface {
},
}
+// Build Rust bindings for PermissionController. Needed by keystore2.
+aidl_interface {
+ name: "android.os.permissions_aidl",
+ unstable: true,
+ local_include_dir: "core/java",
+ srcs: [
+ "core/java/android/os/IPermissionController.aidl",
+ ],
+ backend: {
+ rust: {
+ enabled: true,
+ },
+ },
+}
+
// TODO(b/77285514): remove this once the last few hidl interfaces have been
// updated to use hwbinder.stubs.
java_library {
diff --git a/core/api/module-lib-current.txt b/core/api/module-lib-current.txt
index 4d9b4aafcae1..6fb9630fe847 100644
--- a/core/api/module-lib-current.txt
+++ b/core/api/module-lib-current.txt
@@ -56,6 +56,13 @@ package android.net {
field @NonNull public final java.util.List<java.lang.String> underlyingIfaces;
}
+ public class VpnManager {
+ field @Deprecated public static final int TYPE_VPN_LEGACY = 3; // 0x3
+ field public static final int TYPE_VPN_NONE = -1; // 0xffffffff
+ field public static final int TYPE_VPN_PLATFORM = 2; // 0x2
+ field public static final int TYPE_VPN_SERVICE = 1; // 0x1
+ }
+
}
package android.os {
diff --git a/core/api/system-current.txt b/core/api/system-current.txt
index dc2e7a7e1a42..86a8e99f9733 100644
--- a/core/api/system-current.txt
+++ b/core/api/system-current.txt
@@ -10179,7 +10179,7 @@ package android.telephony {
method @NonNull @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public android.telephony.PinResult setIccLockEnabled(boolean, @NonNull String);
method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void setMobileDataPolicyEnabledStatus(int, boolean);
method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void setMultiSimCarrierRestriction(boolean);
- method public int setNrDualConnectivityState(int);
+ method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public int setNrDualConnectivityState(int);
method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public boolean setOpportunisticNetworkState(boolean);
method @Deprecated @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public boolean setPreferredNetworkTypeBitmask(long);
method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public boolean setRadio(boolean);
diff --git a/core/api/test-current.txt b/core/api/test-current.txt
index b0b45564d44d..a0ff97e1f338 100644
--- a/core/api/test-current.txt
+++ b/core/api/test-current.txt
@@ -1604,6 +1604,10 @@ package android.telecom {
method @NonNull public android.telecom.ConnectionRequest.Builder setVideoState(int);
}
+ public abstract class ConnectionService extends android.app.Service {
+ method public void onBindClient(@Nullable android.content.Intent);
+ }
+
}
package android.telephony {
diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java
index b99d5cd13a77..65f2c02faa85 100644
--- a/core/java/android/app/ActivityThread.java
+++ b/core/java/android/app/ActivityThread.java
@@ -2770,7 +2770,7 @@ public final class ActivityThread extends ClientTransactionHandler {
memInfo.getTotalPrivateDirty(),
memInfo.getTotalPrivateClean(),
memInfo.hasSwappedOutPss ? memInfo.getTotalSwappedOutPss() :
- memInfo.getTotalSwappedOut(), memInfo.getTotalPss(),
+ memInfo.getTotalSwappedOut(), memInfo.getTotalRss(),
nativeMax+dalvikMax,
nativeAllocated+dalvikAllocated, nativeFree+dalvikFree);
}
diff --git a/core/java/android/bluetooth/BluetoothA2dp.java b/core/java/android/bluetooth/BluetoothA2dp.java
index 53aaae0470e2..16413e1a1db6 100644
--- a/core/java/android/bluetooth/BluetoothA2dp.java
+++ b/core/java/android/bluetooth/BluetoothA2dp.java
@@ -139,7 +139,7 @@ public final class BluetoothA2dp implements BluetoothProfile {
* @hide
*/
@SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
- @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
+ @UnsupportedAppUsage(trackingBug = 181103983)
public static final String ACTION_CODEC_CONFIG_CHANGED =
"android.bluetooth.a2dp.profile.action.CODEC_CONFIG_CHANGED";
@@ -684,7 +684,7 @@ public final class BluetoothA2dp implements BluetoothProfile {
* @return the current codec status
* @hide
*/
- @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
+ @UnsupportedAppUsage(trackingBug = 181103983)
@Nullable
@RequiresPermission(Manifest.permission.BLUETOOTH)
public BluetoothCodecStatus getCodecStatus(@NonNull BluetoothDevice device) {
@@ -713,7 +713,7 @@ public final class BluetoothA2dp implements BluetoothProfile {
* @param codecConfig the codec configuration preference
* @hide
*/
- @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
+ @UnsupportedAppUsage(trackingBug = 181103983)
@RequiresPermission(Manifest.permission.BLUETOOTH)
public void setCodecConfigPreference(@NonNull BluetoothDevice device,
@NonNull BluetoothCodecConfig codecConfig) {
diff --git a/core/java/android/net/NetworkIdentity.java b/core/java/android/net/NetworkIdentity.java
index a5ece7b713c7..b037261f0bc2 100644
--- a/core/java/android/net/NetworkIdentity.java
+++ b/core/java/android/net/NetworkIdentity.java
@@ -179,21 +179,6 @@ public class NetworkIdentity implements Comparable<NetworkIdentity> {
}
/**
- * Build a {@link NetworkIdentity} from the given {@link NetworkState} and
- * {@code subType}, assuming that any mobile networks are using the current IMSI.
- * The subType if applicable, should be set as one of the TelephonyManager.NETWORK_TYPE_*
- * constants, or {@link android.telephony.TelephonyManager#NETWORK_TYPE_UNKNOWN} if not.
- */
- // TODO: Delete this function after NetworkPolicyManagerService finishes the migration.
- public static NetworkIdentity buildNetworkIdentity(Context context,
- NetworkState state, boolean defaultNetwork, @NetworkType int subType) {
- final NetworkStateSnapshot snapshot = new NetworkStateSnapshot(state.network,
- state.networkCapabilities, state.linkProperties, state.subscriberId,
- state.legacyNetworkType);
- return buildNetworkIdentity(context, snapshot, defaultNetwork, subType);
- }
-
- /**
* Build a {@link NetworkIdentity} from the given {@link NetworkStateSnapshot} and
* {@code subType}, assuming that any mobile networks are using the current IMSI.
* The subType if applicable, should be set as one of the TelephonyManager.NETWORK_TYPE_*
diff --git a/core/java/android/net/VpnManager.java b/core/java/android/net/VpnManager.java
index f472ed4381d1..77754d1256a7 100644
--- a/core/java/android/net/VpnManager.java
+++ b/core/java/android/net/VpnManager.java
@@ -16,12 +16,15 @@
package android.net;
+import static android.annotation.SystemApi.Client.MODULE_LIBRARIES;
+
import static com.android.internal.util.Preconditions.checkNotNull;
import android.annotation.IntDef;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.RequiresPermission;
+import android.annotation.SystemApi;
import android.annotation.UserIdInt;
import android.app.Activity;
import android.content.ComponentName;
@@ -56,18 +59,21 @@ import java.util.List;
*/
public class VpnManager {
/** Type representing a lack of VPN @hide */
+ @SystemApi(client = MODULE_LIBRARIES)
public static final int TYPE_VPN_NONE = -1;
/**
* A VPN created by an app using the {@link VpnService} API.
* @hide
*/
+ @SystemApi(client = MODULE_LIBRARIES)
public static final int TYPE_VPN_SERVICE = 1;
/**
* A VPN created using a {@link VpnManager} API such as {@link #startProvisionedVpnProfile}.
* @hide
*/
+ @SystemApi(client = MODULE_LIBRARIES)
public static final int TYPE_VPN_PLATFORM = 2;
/**
@@ -76,6 +82,7 @@ public class VpnManager {
* @hide
*/
@Deprecated
+ @SystemApi(client = MODULE_LIBRARIES)
public static final int TYPE_VPN_LEGACY = 3;
/**
diff --git a/core/java/android/net/vcn/VcnControlPlaneIkeConfig.java b/core/java/android/net/vcn/VcnControlPlaneIkeConfig.java
index de086f63b14d..22d7faf2fe18 100644
--- a/core/java/android/net/vcn/VcnControlPlaneIkeConfig.java
+++ b/core/java/android/net/vcn/VcnControlPlaneIkeConfig.java
@@ -19,11 +19,13 @@ package android.net.vcn;
import static android.net.vcn.VcnControlPlaneConfig.CONFIG_TYPE_IKE;
import android.annotation.NonNull;
-import android.annotation.Nullable;
import android.net.ipsec.ike.IkeSessionParams;
import android.net.ipsec.ike.TunnelModeChildSessionParams;
+import android.net.vcn.persistablebundleutils.IkeSessionParamsUtils;
+import android.net.vcn.persistablebundleutils.TunnelModeChildSessionParamsUtils;
import android.os.PersistableBundle;
import android.util.ArraySet;
+import android.util.Log;
import java.util.Objects;
@@ -38,14 +40,11 @@ import java.util.Objects;
public final class VcnControlPlaneIkeConfig extends VcnControlPlaneConfig {
private static final String TAG = VcnControlPlaneIkeConfig.class.getSimpleName();
- // STOPSHIP: b/163604823 Make mIkeParams and mChildParams @NonNull when it is supported to
- // construct mIkeParams and mChildParams from PersistableBundles.
-
private static final String IKE_PARAMS_KEY = "mIkeParams";
- @Nullable private final IkeSessionParams mIkeParams;
+ @NonNull private final IkeSessionParams mIkeParams;
private static final String CHILD_PARAMS_KEY = "mChildParams";
- @Nullable private final TunnelModeChildSessionParams mChildParams;
+ @NonNull private final TunnelModeChildSessionParams mChildParams;
private static final ArraySet<String> BUNDLE_KEY_SET = new ArraySet<>();
@@ -80,11 +79,19 @@ public final class VcnControlPlaneIkeConfig extends VcnControlPlaneConfig {
final PersistableBundle ikeParamsBundle = in.getPersistableBundle(IKE_PARAMS_KEY);
final PersistableBundle childParamsBundle = in.getPersistableBundle(CHILD_PARAMS_KEY);
- // STOPSHIP: b/163604823 Support constructing mIkeParams and mChildParams from
- // PersistableBundles.
+ Objects.requireNonNull(ikeParamsBundle, "IKE Session Params was null");
+ Objects.requireNonNull(childParamsBundle, "Child Session Params was null");
+
+ mIkeParams = IkeSessionParamsUtils.fromPersistableBundle(ikeParamsBundle);
+ mChildParams = TunnelModeChildSessionParamsUtils.fromPersistableBundle(childParamsBundle);
+
+ for (String key : in.keySet()) {
+ if (!BUNDLE_KEY_SET.contains(key)) {
+ Log.w(TAG, "Found an unexpected key in the PersistableBundle: " + key);
+ }
+ }
- mIkeParams = null;
- mChildParams = null;
+ validate();
}
private void validate() {
@@ -101,9 +108,11 @@ public final class VcnControlPlaneIkeConfig extends VcnControlPlaneConfig {
@NonNull
public PersistableBundle toPersistableBundle() {
final PersistableBundle result = super.toPersistableBundle();
-
- // STOPSHIP: b/163604823 Support converting mIkeParams and mChildParams to
- // PersistableBundles.
+ result.putPersistableBundle(
+ IKE_PARAMS_KEY, IkeSessionParamsUtils.toPersistableBundle(mIkeParams));
+ result.putPersistableBundle(
+ CHILD_PARAMS_KEY,
+ TunnelModeChildSessionParamsUtils.toPersistableBundle(mChildParams));
return result;
}
@@ -134,10 +143,9 @@ public final class VcnControlPlaneIkeConfig extends VcnControlPlaneConfig {
VcnControlPlaneIkeConfig other = (VcnControlPlaneIkeConfig) o;
- // STOPSHIP: b/163604823 Also check mIkeParams and mChildParams when it is supported to
- // construct mIkeParams and mChildParams from PersistableBundles. They are not checked
- // now so that VcnGatewayConnectionConfigTest and VcnConfigTest can pass.
- return super.equals(o);
+ return super.equals(o)
+ && Objects.equals(mIkeParams, other.mIkeParams)
+ && Objects.equals(mChildParams, other.mChildParams);
}
/** @hide */
diff --git a/core/java/android/net/vcn/persistablebundleutils/CertUtils.java b/core/java/android/net/vcn/persistablebundleutils/CertUtils.java
index b6036b4a6fd1..35b318687773 100644
--- a/core/java/android/net/vcn/persistablebundleutils/CertUtils.java
+++ b/core/java/android/net/vcn/persistablebundleutils/CertUtils.java
@@ -18,18 +18,24 @@ package android.net.vcn.persistablebundleutils;
import java.io.ByteArrayInputStream;
import java.io.InputStream;
+import java.security.KeyFactory;
+import java.security.NoSuchAlgorithmException;
import java.security.cert.CertificateException;
import java.security.cert.CertificateFactory;
import java.security.cert.X509Certificate;
+import java.security.interfaces.RSAPrivateKey;
+import java.security.spec.InvalidKeySpecException;
+import java.security.spec.PKCS8EncodedKeySpec;
import java.util.Objects;
/**
- * CertUtils provides utility methods for constructing Certificate.
+ * CertUtils provides utility methods for constructing Certificate and PrivateKey.
*
* @hide
*/
public class CertUtils {
private static final String CERT_TYPE_X509 = "X.509";
+ private static final String PRIVATE_KEY_TYPE_RSA = "RSA";
/** Decodes an ASN.1 DER encoded Certificate */
public static X509Certificate certificateFromByteArray(byte[] derEncoded) {
@@ -43,4 +49,18 @@ public class CertUtils {
throw new IllegalArgumentException("Fail to decode certificate", e);
}
}
+
+ /** Decodes a PKCS#8 encoded RSA private key */
+ public static RSAPrivateKey privateKeyFromByteArray(byte[] pkcs8Encoded) {
+ Objects.requireNonNull(pkcs8Encoded, "pkcs8Encoded was null");
+ PKCS8EncodedKeySpec privateKeySpec = new PKCS8EncodedKeySpec(pkcs8Encoded);
+
+ try {
+ KeyFactory keyFactory = KeyFactory.getInstance(PRIVATE_KEY_TYPE_RSA);
+
+ return (RSAPrivateKey) keyFactory.generatePrivate(privateKeySpec);
+ } catch (NoSuchAlgorithmException | InvalidKeySpecException e) {
+ throw new IllegalArgumentException("Fail to decode PrivateKey", e);
+ }
+ }
}
diff --git a/core/java/android/net/vcn/persistablebundleutils/IkeSessionParamsUtils.java b/core/java/android/net/vcn/persistablebundleutils/IkeSessionParamsUtils.java
new file mode 100644
index 000000000000..9d3462cb0b2e
--- /dev/null
+++ b/core/java/android/net/vcn/persistablebundleutils/IkeSessionParamsUtils.java
@@ -0,0 +1,513 @@
+/*
+ * 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.vcn.persistablebundleutils;
+
+import static android.system.OsConstants.AF_INET;
+import static android.system.OsConstants.AF_INET6;
+
+import static com.android.internal.annotations.VisibleForTesting.Visibility;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.net.InetAddresses;
+import android.net.eap.EapSessionConfig;
+import android.net.ipsec.ike.IkeSaProposal;
+import android.net.ipsec.ike.IkeSessionParams;
+import android.net.ipsec.ike.IkeSessionParams.ConfigRequestIpv4PcscfServer;
+import android.net.ipsec.ike.IkeSessionParams.ConfigRequestIpv6PcscfServer;
+import android.net.ipsec.ike.IkeSessionParams.IkeAuthConfig;
+import android.net.ipsec.ike.IkeSessionParams.IkeAuthDigitalSignLocalConfig;
+import android.net.ipsec.ike.IkeSessionParams.IkeAuthDigitalSignRemoteConfig;
+import android.net.ipsec.ike.IkeSessionParams.IkeAuthEapConfig;
+import android.net.ipsec.ike.IkeSessionParams.IkeAuthPskConfig;
+import android.net.ipsec.ike.IkeSessionParams.IkeConfigRequest;
+import android.os.PersistableBundle;
+import android.util.ArraySet;
+
+import com.android.internal.annotations.VisibleForTesting;
+import com.android.server.vcn.util.PersistableBundleUtils;
+
+import java.net.InetAddress;
+import java.security.PrivateKey;
+import java.security.cert.CertificateEncodingException;
+import java.security.cert.X509Certificate;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Objects;
+import java.util.Set;
+
+/**
+ * Abstract utility class to convert IkeSessionParams to/from PersistableBundle.
+ *
+ * @hide
+ */
+@VisibleForTesting(visibility = Visibility.PRIVATE)
+public final class IkeSessionParamsUtils {
+ private static final String SERVER_HOST_NAME_KEY = "SERVER_HOST_NAME_KEY";
+ private static final String SA_PROPOSALS_KEY = "SA_PROPOSALS_KEY";
+ private static final String LOCAL_ID_KEY = "LOCAL_ID_KEY";
+ private static final String REMOTE_ID_KEY = "REMOTE_ID_KEY";
+ private static final String LOCAL_AUTH_KEY = "LOCAL_AUTH_KEY";
+ private static final String REMOTE_AUTH_KEY = "REMOTE_AUTH_KEY";
+ private static final String CONFIG_REQUESTS_KEY = "CONFIG_REQUESTS_KEY";
+ private static final String RETRANS_TIMEOUTS_KEY = "RETRANS_TIMEOUTS_KEY";
+ private static final String HARD_LIFETIME_SEC_KEY = "HARD_LIFETIME_SEC_KEY";
+ private static final String SOFT_LIFETIME_SEC_KEY = "SOFT_LIFETIME_SEC_KEY";
+ private static final String DPD_DELAY_SEC_KEY = "DPD_DELAY_SEC_KEY";
+ private static final String NATT_KEEPALIVE_DELAY_SEC_KEY = "NATT_KEEPALIVE_DELAY_SEC_KEY";
+ private static final String IKE_OPTIONS_KEY = "IKE_OPTIONS_KEY";
+
+ private static final Set<Integer> IKE_OPTIONS = new ArraySet<>();
+
+ static {
+ IKE_OPTIONS.add(IkeSessionParams.IKE_OPTION_ACCEPT_ANY_REMOTE_ID);
+ IKE_OPTIONS.add(IkeSessionParams.IKE_OPTION_EAP_ONLY_AUTH);
+ IKE_OPTIONS.add(IkeSessionParams.IKE_OPTION_MOBIKE);
+ }
+
+ /** Serializes an IkeSessionParams to a PersistableBundle. */
+ @NonNull
+ public static PersistableBundle toPersistableBundle(@NonNull IkeSessionParams params) {
+ if (params.getConfiguredNetwork() != null || params.getIke3gppExtension() != null) {
+ throw new IllegalStateException(
+ "Cannot convert a IkeSessionParams with a caller configured network or with"
+ + " 3GPP extension enabled");
+ }
+
+ final PersistableBundle result = new PersistableBundle();
+
+ result.putString(SERVER_HOST_NAME_KEY, params.getServerHostname());
+
+ final PersistableBundle saProposalBundle =
+ PersistableBundleUtils.fromList(
+ params.getSaProposals(), IkeSaProposalUtils::toPersistableBundle);
+ result.putPersistableBundle(SA_PROPOSALS_KEY, saProposalBundle);
+
+ result.putPersistableBundle(
+ LOCAL_ID_KEY,
+ IkeIdentificationUtils.toPersistableBundle(params.getLocalIdentification()));
+ result.putPersistableBundle(
+ REMOTE_ID_KEY,
+ IkeIdentificationUtils.toPersistableBundle(params.getRemoteIdentification()));
+
+ result.putPersistableBundle(
+ LOCAL_AUTH_KEY, AuthConfigUtils.toPersistableBundle(params.getLocalAuthConfig()));
+ result.putPersistableBundle(
+ REMOTE_AUTH_KEY, AuthConfigUtils.toPersistableBundle(params.getRemoteAuthConfig()));
+
+ final List<ConfigRequest> reqList = new ArrayList<>();
+ for (IkeConfigRequest req : params.getConfigurationRequests()) {
+ reqList.add(new ConfigRequest(req));
+ }
+ final PersistableBundle configReqListBundle =
+ PersistableBundleUtils.fromList(reqList, ConfigRequest::toPersistableBundle);
+ result.putPersistableBundle(CONFIG_REQUESTS_KEY, configReqListBundle);
+
+ result.putIntArray(RETRANS_TIMEOUTS_KEY, params.getRetransmissionTimeoutsMillis());
+ result.putInt(HARD_LIFETIME_SEC_KEY, params.getHardLifetimeSeconds());
+ result.putInt(SOFT_LIFETIME_SEC_KEY, params.getSoftLifetimeSeconds());
+ result.putInt(DPD_DELAY_SEC_KEY, params.getDpdDelaySeconds());
+ result.putInt(NATT_KEEPALIVE_DELAY_SEC_KEY, params.getNattKeepAliveDelaySeconds());
+
+ final List<Integer> enabledIkeOptions = new ArrayList<>();
+ for (int option : IKE_OPTIONS) {
+ if (params.hasIkeOption(option)) {
+ enabledIkeOptions.add(option);
+ }
+ }
+
+ final int[] optionArray = enabledIkeOptions.stream().mapToInt(i -> i).toArray();
+ result.putIntArray(IKE_OPTIONS_KEY, optionArray);
+
+ return result;
+ }
+
+ /** Constructs an IkeSessionParams by deserializing a PersistableBundle. */
+ @NonNull
+ public static IkeSessionParams fromPersistableBundle(@NonNull PersistableBundle in) {
+ Objects.requireNonNull(in, "PersistableBundle is null");
+
+ final IkeSessionParams.Builder builder = new IkeSessionParams.Builder();
+
+ builder.setServerHostname(in.getString(SERVER_HOST_NAME_KEY));
+
+ PersistableBundle proposalBundle = in.getPersistableBundle(SA_PROPOSALS_KEY);
+ Objects.requireNonNull(in, "SA Proposals was null");
+ List<IkeSaProposal> saProposals =
+ PersistableBundleUtils.toList(
+ proposalBundle, IkeSaProposalUtils::fromPersistableBundle);
+ for (IkeSaProposal proposal : saProposals) {
+ builder.addSaProposal(proposal);
+ }
+
+ builder.setLocalIdentification(
+ IkeIdentificationUtils.fromPersistableBundle(
+ in.getPersistableBundle(LOCAL_ID_KEY)));
+ builder.setRemoteIdentification(
+ IkeIdentificationUtils.fromPersistableBundle(
+ in.getPersistableBundle(REMOTE_ID_KEY)));
+
+ AuthConfigUtils.setBuilderByReadingPersistableBundle(
+ in.getPersistableBundle(LOCAL_AUTH_KEY),
+ in.getPersistableBundle(REMOTE_AUTH_KEY),
+ builder);
+
+ builder.setRetransmissionTimeoutsMillis(in.getIntArray(RETRANS_TIMEOUTS_KEY));
+ builder.setLifetimeSeconds(
+ in.getInt(HARD_LIFETIME_SEC_KEY), in.getInt(SOFT_LIFETIME_SEC_KEY));
+ builder.setDpdDelaySeconds(in.getInt(DPD_DELAY_SEC_KEY));
+ builder.setNattKeepAliveDelaySeconds(in.getInt(NATT_KEEPALIVE_DELAY_SEC_KEY));
+
+ final PersistableBundle configReqListBundle = in.getPersistableBundle(CONFIG_REQUESTS_KEY);
+ Objects.requireNonNull(configReqListBundle, "Config request list was null");
+ final List<ConfigRequest> reqList =
+ PersistableBundleUtils.toList(configReqListBundle, ConfigRequest::new);
+ for (ConfigRequest req : reqList) {
+ switch (req.type) {
+ case ConfigRequest.IPV4_P_CSCF_ADDRESS:
+ if (req.address == null) {
+ builder.addPcscfServerRequest(AF_INET);
+ } else {
+ builder.addPcscfServerRequest(req.address);
+ }
+ break;
+ case ConfigRequest.IPV6_P_CSCF_ADDRESS:
+ if (req.address == null) {
+ builder.addPcscfServerRequest(AF_INET6);
+ } else {
+ builder.addPcscfServerRequest(req.address);
+ }
+ break;
+ default:
+ throw new IllegalArgumentException(
+ "Unrecognized config request type: " + req.type);
+ }
+ }
+
+ // Clear IKE Options that are by default enabled
+ for (int option : IKE_OPTIONS) {
+ builder.removeIkeOption(option);
+ }
+
+ final int[] optionArray = in.getIntArray(IKE_OPTIONS_KEY);
+ for (int option : optionArray) {
+ builder.addIkeOption(option);
+ }
+
+ return builder.build();
+ }
+
+ private static final class AuthConfigUtils {
+ private static final int IKE_AUTH_METHOD_PSK = 1;
+ private static final int IKE_AUTH_METHOD_PUB_KEY_SIGNATURE = 2;
+ private static final int IKE_AUTH_METHOD_EAP = 3;
+
+ private static final String AUTH_METHOD_KEY = "AUTH_METHOD_KEY";
+
+ @NonNull
+ public static PersistableBundle toPersistableBundle(@NonNull IkeAuthConfig authConfig) {
+ if (authConfig instanceof IkeAuthPskConfig) {
+ IkeAuthPskConfig config = (IkeAuthPskConfig) authConfig;
+ return IkeAuthPskConfigUtils.toPersistableBundle(
+ config, createPersistableBundle(IKE_AUTH_METHOD_PSK));
+ } else if (authConfig instanceof IkeAuthDigitalSignLocalConfig) {
+ IkeAuthDigitalSignLocalConfig config = (IkeAuthDigitalSignLocalConfig) authConfig;
+ return IkeAuthDigitalSignConfigUtils.toPersistableBundle(
+ config, createPersistableBundle(IKE_AUTH_METHOD_PUB_KEY_SIGNATURE));
+ } else if (authConfig instanceof IkeAuthDigitalSignRemoteConfig) {
+ IkeAuthDigitalSignRemoteConfig config = (IkeAuthDigitalSignRemoteConfig) authConfig;
+ return IkeAuthDigitalSignConfigUtils.toPersistableBundle(
+ config, createPersistableBundle(IKE_AUTH_METHOD_PUB_KEY_SIGNATURE));
+ } else if (authConfig instanceof IkeAuthEapConfig) {
+ IkeAuthEapConfig config = (IkeAuthEapConfig) authConfig;
+ return IkeAuthEapConfigUtils.toPersistableBundle(
+ config, createPersistableBundle(IKE_AUTH_METHOD_EAP));
+ } else {
+ throw new IllegalStateException("Invalid IkeAuthConfig subclass");
+ }
+ }
+
+ private static PersistableBundle createPersistableBundle(int type) {
+ final PersistableBundle result = new PersistableBundle();
+ result.putInt(AUTH_METHOD_KEY, type);
+ return result;
+ }
+
+ public static void setBuilderByReadingPersistableBundle(
+ @NonNull PersistableBundle localAuthBundle,
+ @NonNull PersistableBundle remoteAuthBundle,
+ @NonNull IkeSessionParams.Builder builder) {
+ Objects.requireNonNull(localAuthBundle, "localAuthBundle was null");
+ Objects.requireNonNull(remoteAuthBundle, "remoteAuthBundle was null");
+
+ final int localMethodType = localAuthBundle.getInt(AUTH_METHOD_KEY);
+ final int remoteMethodType = remoteAuthBundle.getInt(AUTH_METHOD_KEY);
+ switch (localMethodType) {
+ case IKE_AUTH_METHOD_PSK:
+ if (remoteMethodType != IKE_AUTH_METHOD_PSK) {
+ throw new IllegalArgumentException(
+ "Expect remote auth method to be PSK based, but was "
+ + remoteMethodType);
+ }
+ IkeAuthPskConfigUtils.setBuilderByReadingPersistableBundle(
+ localAuthBundle, remoteAuthBundle, builder);
+ return;
+ case IKE_AUTH_METHOD_PUB_KEY_SIGNATURE:
+ if (remoteMethodType != IKE_AUTH_METHOD_PUB_KEY_SIGNATURE) {
+ throw new IllegalArgumentException(
+ "Expect remote auth method to be digital signature based, but was "
+ + remoteMethodType);
+ }
+ IkeAuthDigitalSignConfigUtils.setBuilderByReadingPersistableBundle(
+ localAuthBundle, remoteAuthBundle, builder);
+ return;
+ case IKE_AUTH_METHOD_EAP:
+ if (remoteMethodType != IKE_AUTH_METHOD_PUB_KEY_SIGNATURE) {
+ throw new IllegalArgumentException(
+ "When using EAP for local authentication, expect remote auth"
+ + " method to be digital signature based, but was "
+ + remoteMethodType);
+ }
+ IkeAuthEapConfigUtils.setBuilderByReadingPersistableBundle(
+ localAuthBundle, remoteAuthBundle, builder);
+ return;
+ default:
+ throw new IllegalArgumentException(
+ "Invalid EAP method type " + localMethodType);
+ }
+ }
+ }
+
+ private static final class IkeAuthPskConfigUtils {
+ private static final String PSK_KEY = "PSK_KEY";
+
+ @NonNull
+ public static PersistableBundle toPersistableBundle(
+ @NonNull IkeAuthPskConfig config, @NonNull PersistableBundle result) {
+ result.putPersistableBundle(
+ PSK_KEY, PersistableBundleUtils.fromByteArray(config.getPsk()));
+ return result;
+ }
+
+ public static void setBuilderByReadingPersistableBundle(
+ @NonNull PersistableBundle localAuthBundle,
+ @NonNull PersistableBundle remoteAuthBundle,
+ @NonNull IkeSessionParams.Builder builder) {
+ Objects.requireNonNull(localAuthBundle, "localAuthBundle was null");
+ Objects.requireNonNull(remoteAuthBundle, "remoteAuthBundle was null");
+
+ final PersistableBundle localPskBundle = localAuthBundle.getPersistableBundle(PSK_KEY);
+ final PersistableBundle remotePskBundle =
+ remoteAuthBundle.getPersistableBundle(PSK_KEY);
+ Objects.requireNonNull(localAuthBundle, "Local PSK was null");
+ Objects.requireNonNull(remoteAuthBundle, "Remote PSK was null");
+
+ final byte[] localPsk = PersistableBundleUtils.toByteArray(localPskBundle);
+ final byte[] remotePsk = PersistableBundleUtils.toByteArray(remotePskBundle);
+ if (!Arrays.equals(localPsk, remotePsk)) {
+ throw new IllegalArgumentException("Local PSK and remote PSK are different");
+ }
+ builder.setAuthPsk(localPsk);
+ }
+ }
+
+ private static class IkeAuthDigitalSignConfigUtils {
+ private static final String END_CERT_KEY = "END_CERT_KEY";
+ private static final String INTERMEDIATE_CERTS_KEY = "INTERMEDIATE_CERTS_KEY";
+ private static final String PRIVATE_KEY_KEY = "PRIVATE_KEY_KEY";
+ private static final String TRUST_CERT_KEY = "TRUST_CERT_KEY";
+
+ @NonNull
+ public static PersistableBundle toPersistableBundle(
+ @NonNull IkeAuthDigitalSignLocalConfig config, @NonNull PersistableBundle result) {
+ try {
+ result.putPersistableBundle(
+ END_CERT_KEY,
+ PersistableBundleUtils.fromByteArray(
+ config.getClientEndCertificate().getEncoded()));
+
+ final List<X509Certificate> certList = config.getIntermediateCertificates();
+ final List<byte[]> encodedCertList = new ArrayList<>(certList.size());
+ for (X509Certificate cert : certList) {
+ encodedCertList.add(cert.getEncoded());
+ }
+
+ final PersistableBundle certsBundle =
+ PersistableBundleUtils.fromList(
+ encodedCertList, PersistableBundleUtils::fromByteArray);
+ result.putPersistableBundle(INTERMEDIATE_CERTS_KEY, certsBundle);
+ } catch (CertificateEncodingException e) {
+ throw new IllegalArgumentException("Fail to encode certificate");
+ }
+
+ // TODO: b/170670506 Consider putting PrivateKey in Android KeyStore
+ result.putPersistableBundle(
+ PRIVATE_KEY_KEY,
+ PersistableBundleUtils.fromByteArray(config.getPrivateKey().getEncoded()));
+ return result;
+ }
+
+ @NonNull
+ public static PersistableBundle toPersistableBundle(
+ @NonNull IkeAuthDigitalSignRemoteConfig config, @NonNull PersistableBundle result) {
+ try {
+ X509Certificate caCert = config.getRemoteCaCert();
+ if (caCert != null) {
+ result.putPersistableBundle(
+ TRUST_CERT_KEY,
+ PersistableBundleUtils.fromByteArray(caCert.getEncoded()));
+ }
+ } catch (CertificateEncodingException e) {
+ throw new IllegalArgumentException("Fail to encode the certificate");
+ }
+
+ return result;
+ }
+
+ public static void setBuilderByReadingPersistableBundle(
+ @NonNull PersistableBundle localAuthBundle,
+ @NonNull PersistableBundle remoteAuthBundle,
+ @NonNull IkeSessionParams.Builder builder) {
+ Objects.requireNonNull(localAuthBundle, "localAuthBundle was null");
+ Objects.requireNonNull(remoteAuthBundle, "remoteAuthBundle was null");
+
+ // Deserialize localAuth
+ final PersistableBundle endCertBundle =
+ localAuthBundle.getPersistableBundle(END_CERT_KEY);
+ Objects.requireNonNull(endCertBundle, "End cert was null");
+ final byte[] encodedCert = PersistableBundleUtils.toByteArray(endCertBundle);
+ final X509Certificate endCert = CertUtils.certificateFromByteArray(encodedCert);
+
+ final PersistableBundle certsBundle =
+ localAuthBundle.getPersistableBundle(INTERMEDIATE_CERTS_KEY);
+ Objects.requireNonNull(certsBundle, "Intermediate certs was null");
+ final List<byte[]> encodedCertList =
+ PersistableBundleUtils.toList(certsBundle, PersistableBundleUtils::toByteArray);
+ final List<X509Certificate> certList = new ArrayList<>(encodedCertList.size());
+ for (byte[] encoded : encodedCertList) {
+ certList.add(CertUtils.certificateFromByteArray(encoded));
+ }
+
+ final PersistableBundle privateKeyBundle =
+ localAuthBundle.getPersistableBundle(PRIVATE_KEY_KEY);
+ Objects.requireNonNull(privateKeyBundle, "PrivateKey bundle was null");
+ final PrivateKey privateKey =
+ CertUtils.privateKeyFromByteArray(
+ PersistableBundleUtils.toByteArray(privateKeyBundle));
+
+ // Deserialize remoteAuth
+ final PersistableBundle trustCertBundle =
+ remoteAuthBundle.getPersistableBundle(TRUST_CERT_KEY);
+
+ X509Certificate caCert = null;
+ if (trustCertBundle != null) {
+ final byte[] encodedCaCert = PersistableBundleUtils.toByteArray(trustCertBundle);
+ caCert = CertUtils.certificateFromByteArray(encodedCaCert);
+ }
+
+ builder.setAuthDigitalSignature(caCert, endCert, certList, privateKey);
+ }
+ }
+
+ private static final class IkeAuthEapConfigUtils {
+ private static final String EAP_CONFIG_KEY = "EAP_CONFIG_KEY";
+
+ @NonNull
+ public static PersistableBundle toPersistableBundle(
+ @NonNull IkeAuthEapConfig config, @NonNull PersistableBundle result) {
+ result.putPersistableBundle(
+ EAP_CONFIG_KEY,
+ EapSessionConfigUtils.toPersistableBundle(config.getEapConfig()));
+ return result;
+ }
+
+ public static void setBuilderByReadingPersistableBundle(
+ @NonNull PersistableBundle localAuthBundle,
+ @NonNull PersistableBundle remoteAuthBundle,
+ @NonNull IkeSessionParams.Builder builder) {
+ // Deserialize localAuth
+ final PersistableBundle eapBundle =
+ localAuthBundle.getPersistableBundle(EAP_CONFIG_KEY);
+ Objects.requireNonNull(eapBundle, "EAP Config was null");
+ final EapSessionConfig eapConfig =
+ EapSessionConfigUtils.fromPersistableBundle(eapBundle);
+
+ // Deserialize remoteAuth
+ final PersistableBundle trustCertBundle =
+ remoteAuthBundle.getPersistableBundle(
+ IkeAuthDigitalSignConfigUtils.TRUST_CERT_KEY);
+
+ X509Certificate serverCaCert = null;
+ if (trustCertBundle != null) {
+ final byte[] encodedCaCert = PersistableBundleUtils.toByteArray(trustCertBundle);
+ serverCaCert = CertUtils.certificateFromByteArray(encodedCaCert);
+ }
+ builder.setAuthEap(serverCaCert, eapConfig);
+ }
+ }
+
+ private static final class ConfigRequest {
+ private static final int IPV4_P_CSCF_ADDRESS = 1;
+ private static final int IPV6_P_CSCF_ADDRESS = 2;
+
+ private static final String TYPE_KEY = "type";
+ private static final String ADDRESS_KEY = "address";
+
+ public final int type;
+
+ // Null when it is an empty request
+ @Nullable public final InetAddress address;
+
+ ConfigRequest(IkeConfigRequest config) {
+ if (config instanceof ConfigRequestIpv4PcscfServer) {
+ type = IPV4_P_CSCF_ADDRESS;
+ address = ((ConfigRequestIpv4PcscfServer) config).getAddress();
+ } else if (config instanceof ConfigRequestIpv6PcscfServer) {
+ type = IPV6_P_CSCF_ADDRESS;
+ address = ((ConfigRequestIpv6PcscfServer) config).getAddress();
+ } else {
+ throw new IllegalStateException("Unknown TunnelModeChildConfigRequest");
+ }
+ }
+
+ ConfigRequest(PersistableBundle in) {
+ Objects.requireNonNull(in, "PersistableBundle was null");
+
+ type = in.getInt(TYPE_KEY);
+
+ String addressStr = in.getString(ADDRESS_KEY);
+ if (addressStr == null) {
+ address = null;
+ } else {
+ address = InetAddresses.parseNumericAddress(addressStr);
+ }
+ }
+
+ @NonNull
+ public PersistableBundle toPersistableBundle() {
+ final PersistableBundle result = new PersistableBundle();
+
+ result.putInt(TYPE_KEY, type);
+ if (address != null) {
+ result.putString(ADDRESS_KEY, address.getHostAddress());
+ }
+
+ return result;
+ }
+ }
+}
diff --git a/core/java/android/os/FileUtils.java b/core/java/android/os/FileUtils.java
index a4d6c3845fbf..0264d2335c4b 100644
--- a/core/java/android/os/FileUtils.java
+++ b/core/java/android/os/FileUtils.java
@@ -1235,9 +1235,9 @@ public final class FileUtils {
}
/**
- * Creates a directory with name {@code name} under an existing directory {@code baseDir}.
- * Returns a {@code File} object representing the directory on success, {@code null} on
- * failure.
+ * Creates a directory with name {@code name} under an existing directory {@code baseDir} if it
+ * doesn't exist already. Returns a {@code File} object representing the directory if it exists
+ * and {@code null} if not.
*
* @hide
*/
@@ -1247,13 +1247,23 @@ public final class FileUtils {
return createDir(dir) ? dir : null;
}
- /** @hide */
+ /**
+ * Ensure the given directory exists, creating it if needed. This method is threadsafe.
+ *
+ * @return false if the directory doesn't exist and couldn't be created
+ *
+ * @hide
+ */
public static boolean createDir(File dir) {
+ if (dir.mkdir()) {
+ return true;
+ }
+
if (dir.exists()) {
return dir.isDirectory();
}
- return dir.mkdir();
+ return false;
}
/**
diff --git a/core/java/android/os/OWNERS b/core/java/android/os/OWNERS
index 6c49b365c4f3..d9665953dceb 100644
--- a/core/java/android/os/OWNERS
+++ b/core/java/android/os/OWNERS
@@ -54,7 +54,7 @@ per-file HwRemoteBinder.java = file:platform/system/libhwbinder:/OWNERS
per-file IHwBinder.java = file:platform/system/libhwbinder:/OWNERS
per-file IHwInterface.java = file:platform/system/libhwbinder:/OWNERS
-per-file GraphicsEnvironment.java = chrisforbes@google.com, cnorthrop@google.com, lpy@google.com, timvp@google.com, zzyiwei@google.com
+per-file GraphicsEnvironment.java = file:platform/frameworks/native:/opengl/OWNERS
per-file *Network* = file:/services/core/java/com/android/server/net/OWNERS
per-file *Power* = file:/services/core/java/com/android/server/power/OWNERS
diff --git a/core/java/android/os/VibrationEffect.java b/core/java/android/os/VibrationEffect.java
index 769a34eed1dc..13871c51afe2 100644
--- a/core/java/android/os/VibrationEffect.java
+++ b/core/java/android/os/VibrationEffect.java
@@ -1083,7 +1083,8 @@ public abstract class VibrationEffect implements Parcelable {
*
* @param primitiveId The primitive to add
* @param scale The scale to apply to the intensity of the primitive.
- * @param delay The amount of time in milliseconds to wait before playing this primitive
+ * @param delay The amount of time in milliseconds to wait before playing this primitive,
+ * starting at the time the previous element in this composition is finished.
* @return The {@link Composition} object to enable adding multiple primitives in one chain.
*/
@NonNull
diff --git a/core/java/android/view/contentcapture/ContentCaptureManager.java b/core/java/android/view/contentcapture/ContentCaptureManager.java
index 10f6c610d5d3..96818fa26a73 100644
--- a/core/java/android/view/contentcapture/ContentCaptureManager.java
+++ b/core/java/android/view/contentcapture/ContentCaptureManager.java
@@ -67,7 +67,7 @@ import java.util.function.Consumer;
* <p>Content capture provides real-time, continuous capture of application activity, display and
* events to an intelligence service that is provided by the Android system. The intelligence
* service then uses that info to mediate and speed user journey through different apps. For
- * example, when the user receives a restaurant address in a chat app and switchs to a map app
+ * example, when the user receives a restaurant address in a chat app and switches to a map app
* to search for that restaurant, the intelligence service could offer an autofill dialog to
* let the user automatically select its address.
*
diff --git a/core/java/com/android/internal/os/ZygoteInit.java b/core/java/com/android/internal/os/ZygoteInit.java
index fe87b64940fb..c220428df58b 100644
--- a/core/java/com/android/internal/os/ZygoteInit.java
+++ b/core/java/com/android/internal/os/ZygoteInit.java
@@ -648,8 +648,6 @@ public class ZygoteInit {
*/
private static void performSystemServerDexOpt(String classPath) {
final String[] classPathElements = classPath.split(":");
- final IInstalld installd = IInstalld.Stub
- .asInterface(ServiceManager.getService("installd"));
final String instructionSet = VMRuntime.getRuntime().vmInstructionSet();
String classPathForElement = "";
@@ -686,6 +684,10 @@ public class ZygoteInit {
final String uuid = StorageManager.UUID_PRIVATE_INTERNAL;
final String seInfo = null;
final int targetSdkVersion = 0; // SystemServer targets the system's SDK version
+ // Wait for installd to be made available
+ IInstalld installd = IInstalld.Stub.asInterface(
+ ServiceManager.waitForService("installd"));
+
try {
installd.dexopt(classPathElement, Process.SYSTEM_UID, packageName,
instructionSet, dexoptNeeded, outputPath, dexFlags, systemServerFilter,
diff --git a/core/jni/android_os_Debug.cpp b/core/jni/android_os_Debug.cpp
index 0e3db46bd0c9..f379ba0ddebb 100644
--- a/core/jni/android_os_Debug.cpp
+++ b/core/jni/android_os_Debug.cpp
@@ -902,7 +902,7 @@ static jlong android_os_Debug_getDmabufMappedSizeKb(JNIEnv* env, jobject clazz)
continue;
}
- if (!AppendDmaBufInfo(pid, &dmabufs, false)) {
+ if (!ReadDmaBufMapRefs(pid, &dmabufs)) {
LOG(ERROR) << "Failed to read maps for pid " << pid;
}
}
diff --git a/packages/CtsShim/OWNERS b/packages/CtsShim/OWNERS
new file mode 100644
index 000000000000..ba9f2b97678a
--- /dev/null
+++ b/packages/CtsShim/OWNERS
@@ -0,0 +1,2 @@
+ioffe@google.com
+toddke@google.com \ No newline at end of file
diff --git a/packages/Shell/AndroidManifest.xml b/packages/Shell/AndroidManifest.xml
index dc1ce825368f..3fed29ac3ce2 100644
--- a/packages/Shell/AndroidManifest.xml
+++ b/packages/Shell/AndroidManifest.xml
@@ -285,6 +285,9 @@
<!-- Permission needed for CTS test - MusicRecognitionManagerTest -->
<uses-permission android:name="android.permission.MANAGE_MUSIC_RECOGNITION" />
+ <!-- Permission needed for CTS test - CtsVoiceRecognitionTestCases -->
+ <uses-permission android:name="android.permission.MANAGE_SPEECH_RECOGNITION" />
+
<!-- Permissions required to test ambient display. -->
<uses-permission android:name="android.permission.READ_DREAM_STATE"/>
<uses-permission android:name="android.permission.WRITE_DREAM_STATE"/>
diff --git a/services/core/java/com/android/server/ConnectivityService.java b/services/core/java/com/android/server/ConnectivityService.java
index a26c6cad279c..709f5b2106f3 100644
--- a/services/core/java/com/android/server/ConnectivityService.java
+++ b/services/core/java/com/android/server/ConnectivityService.java
@@ -215,7 +215,6 @@ import com.android.server.connectivity.PermissionMonitor;
import com.android.server.connectivity.ProxyTracker;
import com.android.server.connectivity.QosCallbackTracker;
import com.android.server.net.NetworkPolicyManagerInternal;
-import com.android.server.utils.PriorityDump;
import libcore.io.IoUtils;
@@ -882,27 +881,59 @@ public class ConnectivityService extends IConnectivityManager.Stub
}
private final LegacyTypeTracker mLegacyTypeTracker = new LegacyTypeTracker(this);
+ final LocalPriorityDump mPriorityDumper = new LocalPriorityDump();
/**
* Helper class which parses out priority arguments and dumps sections according to their
* priority. If priority arguments are omitted, function calls the legacy dump command.
*/
- private final PriorityDump.PriorityDumper mPriorityDumper = new PriorityDump.PriorityDumper() {
- @Override
- public void dumpHigh(FileDescriptor fd, PrintWriter pw, String[] args, boolean asProto) {
- doDump(fd, pw, new String[] {DIAG_ARG}, asProto);
- doDump(fd, pw, new String[] {SHORT_ARG}, asProto);
+ private class LocalPriorityDump {
+ private static final String PRIORITY_ARG = "--dump-priority";
+ private static final String PRIORITY_ARG_HIGH = "HIGH";
+ private static final String PRIORITY_ARG_NORMAL = "NORMAL";
+
+ LocalPriorityDump() {}
+
+ private void dumpHigh(FileDescriptor fd, PrintWriter pw) {
+ doDump(fd, pw, new String[] {DIAG_ARG});
+ doDump(fd, pw, new String[] {SHORT_ARG});
}
- @Override
- public void dumpNormal(FileDescriptor fd, PrintWriter pw, String[] args, boolean asProto) {
- doDump(fd, pw, args, asProto);
+ private void dumpNormal(FileDescriptor fd, PrintWriter pw, String[] args) {
+ doDump(fd, pw, args);
}
- @Override
- public void dump(FileDescriptor fd, PrintWriter pw, String[] args, boolean asProto) {
- doDump(fd, pw, args, asProto);
+ public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
+ if (args == null) {
+ dumpNormal(fd, pw, args);
+ return;
+ }
+
+ String priority = null;
+ for (int argIndex = 0; argIndex < args.length; argIndex++) {
+ if (args[argIndex].equals(PRIORITY_ARG) && argIndex + 1 < args.length) {
+ argIndex++;
+ priority = args[argIndex];
+ }
+ }
+
+ if (PRIORITY_ARG_HIGH.equals(priority)) {
+ dumpHigh(fd, pw);
+ } else if (PRIORITY_ARG_NORMAL.equals(priority)) {
+ dumpNormal(fd, pw, args);
+ } else {
+ // ConnectivityService publishes binder service using publishBinderService() with
+ // no priority assigned will be treated as NORMAL priority. Dumpsys does not send
+ // "--dump-priority" arguments to the service. Thus, dump both NORMAL and HIGH to
+ // align the legacy design.
+ // TODO: Integrate into signal dump.
+ dumpNormal(fd, pw, args);
+ pw.println();
+ pw.println("DUMP OF SERVICE HIGH connectivity");
+ pw.println();
+ dumpHigh(fd, pw);
+ }
}
- };
+ }
/**
* Keeps track of the number of requests made under different uids.
@@ -2597,7 +2628,7 @@ public class ConnectivityService extends IConnectivityManager.Stub
@Override
protected void dump(@NonNull FileDescriptor fd, @NonNull PrintWriter writer,
@Nullable String[] args) {
- PriorityDump.dump(mPriorityDumper, fd, writer, args);
+ mPriorityDumper.dump(fd, writer, args);
}
private boolean checkDumpPermission(Context context, String tag, PrintWriter pw) {
@@ -2612,10 +2643,9 @@ public class ConnectivityService extends IConnectivityManager.Stub
}
}
- private void doDump(FileDescriptor fd, PrintWriter writer, String[] args, boolean asProto) {
+ private void doDump(FileDescriptor fd, PrintWriter writer, String[] args) {
final IndentingPrintWriter pw = new IndentingPrintWriter(writer, " ");
if (!checkDumpPermission(mContext, TAG, pw)) return;
- if (asProto) return;
if (CollectionUtils.contains(args, DIAG_ARG)) {
dumpNetworkDiagnostics(pw);
@@ -3608,11 +3638,10 @@ public class ConnectivityService extends IConnectivityManager.Stub
// pendingIntent => NetworkRequestInfo map.
// This method assumes that every non-null PendingIntent maps to exactly 1 NetworkRequestInfo.
private NetworkRequestInfo findExistingNetworkRequestInfo(PendingIntent pendingIntent) {
- Intent intent = pendingIntent.getIntent();
for (Map.Entry<NetworkRequest, NetworkRequestInfo> entry : mNetworkRequests.entrySet()) {
PendingIntent existingPendingIntent = entry.getValue().mPendingIntent;
if (existingPendingIntent != null &&
- existingPendingIntent.getIntent().filterEquals(intent)) {
+ existingPendingIntent.intentFilterEquals(pendingIntent)) {
return entry.getValue();
}
}
@@ -3655,6 +3684,13 @@ public class ConnectivityService extends IConnectivityManager.Stub
}
}
}
+ // If this NRI has a satisfier already, it is replacing an older request that
+ // has been removed. Track it.
+ final NetworkRequest activeRequest = nri.getActiveRequest();
+ if (null != activeRequest) {
+ // If there is an active request, then for sure there is a satisfier.
+ nri.getSatisfier().addRequest(activeRequest);
+ }
}
rematchAllNetworksAndRequests();
@@ -5275,14 +5311,26 @@ public class ConnectivityService extends IConnectivityManager.Stub
ensureAllNetworkRequestsHaveType(r);
mRequests = initializeRequests(r);
mNetworkRequestForCallback = nri.getNetworkRequestForCallback();
- // Note here that the satisfier may have corresponded to an old request, that
- // this code doesn't try to take over. While it is a small discrepancy in the
- // structure of these requests, it will be fixed by the next rematch and it's
- // not as bad as having an NRI not storing its real satisfier.
- // Fixing this discrepancy would require figuring out in the copying code what
- // is the new request satisfied by this, which is a bit complex and not very
- // useful as no code is using it until rematch fixes it.
- mSatisfier = nri.mSatisfier;
+ final NetworkAgentInfo satisfier = nri.getSatisfier();
+ if (null != satisfier) {
+ // If the old NRI was satisfied by an NAI, then it may have had an active request.
+ // The active request is necessary to figure out what callbacks to send, in
+ // particular then a network updates its capabilities.
+ // As this code creates a new NRI with a new set of requests, figure out which of
+ // the list of requests should be the active request. It is always the first
+ // request of the list that can be satisfied by the satisfier since the order of
+ // requests is a priority order.
+ // Note even in the presence of a satisfier there may not be an active request,
+ // when the satisfier is the no-service network.
+ NetworkRequest activeRequest = null;
+ for (final NetworkRequest candidate : r) {
+ if (candidate.canBeSatisfiedBy(satisfier.networkCapabilities)) {
+ activeRequest = candidate;
+ break;
+ }
+ }
+ setSatisfier(satisfier, activeRequest);
+ }
mMessenger = nri.mMessenger;
mBinder = nri.mBinder;
mPid = nri.mPid;
diff --git a/services/core/java/com/android/server/ConnectivityServiceInitializer.java b/services/core/java/com/android/server/ConnectivityServiceInitializer.java
index b9922087109f..2465479aadd8 100644
--- a/services/core/java/com/android/server/ConnectivityServiceInitializer.java
+++ b/services/core/java/com/android/server/ConnectivityServiceInitializer.java
@@ -16,9 +16,6 @@
package com.android.server;
-import static android.os.IServiceManager.DUMP_FLAG_PRIORITY_HIGH;
-import static android.os.IServiceManager.DUMP_FLAG_PRIORITY_NORMAL;
-
import android.content.Context;
import android.util.Log;
@@ -42,6 +39,6 @@ public final class ConnectivityServiceInitializer extends SystemService {
public void onStart() {
Log.i(TAG, "Registering " + Context.CONNECTIVITY_SERVICE);
publishBinderService(Context.CONNECTIVITY_SERVICE, mConnectivity,
- /* allowIsolated= */ false, DUMP_FLAG_PRIORITY_HIGH | DUMP_FLAG_PRIORITY_NORMAL);
+ /* allowIsolated= */ false);
}
}
diff --git a/services/core/java/com/android/server/apphibernation/AppHibernationManagerInternal.java b/services/core/java/com/android/server/apphibernation/AppHibernationManagerInternal.java
new file mode 100644
index 000000000000..b0335fe404f4
--- /dev/null
+++ b/services/core/java/com/android/server/apphibernation/AppHibernationManagerInternal.java
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.apphibernation;
+
+/**
+ * App hibernation manager local system service interface.
+ *
+ * @hide Only for use within the system server.
+ */
+public abstract class AppHibernationManagerInternal {
+
+ /**
+ * @see AppHibernationService#isHibernatingForUser
+ */
+ public abstract boolean isHibernatingForUser(String packageName, int userId);
+
+ /**
+ * @see AppHibernationService#setHibernatingForUser
+ */
+ public abstract void setHibernatingForUser(String packageName, int userId,
+ boolean isHibernating);
+
+ /**
+ * @see AppHibernationService#isHibernatingGlobally
+ */
+ public abstract boolean isHibernatingGlobally(String packageName);
+
+ /**
+ * @see AppHibernationService#setHibernatingGlobally
+ */
+ public abstract void setHibernatingGlobally(String packageName, boolean isHibernating);
+}
diff --git a/services/core/java/com/android/server/apphibernation/AppHibernationService.java b/services/core/java/com/android/server/apphibernation/AppHibernationService.java
index 32ae87898085..968cf5f1df91 100644
--- a/services/core/java/com/android/server/apphibernation/AppHibernationService.java
+++ b/services/core/java/com/android/server/apphibernation/AppHibernationService.java
@@ -59,6 +59,7 @@ import com.android.internal.annotations.GuardedBy;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.util.DumpUtils;
import com.android.internal.util.IndentingPrintWriter;
+import com.android.server.LocalServices;
import com.android.server.SystemService;
import java.io.File;
@@ -134,6 +135,8 @@ public final class AppHibernationService extends SystemService {
intentFilter.addAction(ACTION_PACKAGE_REMOVED);
intentFilter.addDataScheme("package");
userAllContext.registerReceiver(mBroadcastReceiver, intentFilter);
+
+ LocalServices.addService(AppHibernationManagerInternal.class, mLocalService);
}
@Override
@@ -545,6 +548,36 @@ public final class AppHibernationService extends SystemService {
}
}
+ private final AppHibernationManagerInternal mLocalService = new LocalService(this);
+
+ private static final class LocalService extends AppHibernationManagerInternal {
+ private final AppHibernationService mService;
+
+ LocalService(AppHibernationService service) {
+ mService = service;
+ }
+
+ @Override
+ public boolean isHibernatingForUser(String packageName, int userId) {
+ return mService.isHibernatingForUser(packageName, userId);
+ }
+
+ @Override
+ public void setHibernatingForUser(String packageName, int userId, boolean isHibernating) {
+ mService.setHibernatingForUser(packageName, userId, isHibernating);
+ }
+
+ @Override
+ public void setHibernatingGlobally(String packageName, boolean isHibernating) {
+ mService.setHibernatingGlobally(packageName, isHibernating);
+ }
+
+ @Override
+ public boolean isHibernatingGlobally(String packageName) {
+ return mService.isHibernatingGlobally(packageName);
+ }
+ }
+
private final AppHibernationServiceStub mServiceStub = new AppHibernationServiceStub(this);
static final class AppHibernationServiceStub extends IAppHibernationService.Stub {
diff --git a/services/core/java/com/android/server/locksettings/RebootEscrowManager.java b/services/core/java/com/android/server/locksettings/RebootEscrowManager.java
index 364aa2cb41ae..240464a560af 100644
--- a/services/core/java/com/android/server/locksettings/RebootEscrowManager.java
+++ b/services/core/java/com/android/server/locksettings/RebootEscrowManager.java
@@ -207,7 +207,7 @@ class RebootEscrowManager {
public void reportMetric(boolean success) {
// TODO(b/179105110) design error code; and report the true value for other fields.
FrameworkStatsLog.write(FrameworkStatsLog.REBOOT_ESCROW_RECOVERY_REPORTED, 0, 1, 1,
- -1, 0);
+ -1, 0, -1);
}
public RebootEscrowEventLog getEventLog() {
@@ -251,6 +251,8 @@ class RebootEscrowManager {
}
if (rebootEscrowUsers.isEmpty()) {
+ Slog.i(TAG, "No reboot escrow data found for users,"
+ + " skipping loading escrow data");
return;
}
diff --git a/services/core/java/com/android/server/locksettings/TEST_MAPPING b/services/core/java/com/android/server/locksettings/TEST_MAPPING
index 56f5cc034f05..8c19c541b86f 100644
--- a/services/core/java/com/android/server/locksettings/TEST_MAPPING
+++ b/services/core/java/com/android/server/locksettings/TEST_MAPPING
@@ -10,6 +10,17 @@
"exclude-annotation": "android.platform.test.annotations.FlakyTest"
}
]
+ },
+ {
+ "name": "FrameworksServicesTests",
+ "options": [
+ {
+ "include-filter": "com.android.server.locksettings."
+ },
+ {
+ "exclude-annotation": "android.platform.test.annotations.FlakyTest"
+ }
+ ]
}
]
}
diff --git a/services/core/java/com/android/server/om/OverlayManagerShellCommand.java b/services/core/java/com/android/server/om/OverlayManagerShellCommand.java
index bf99bd6248cd..0659bc389b3c 100644
--- a/services/core/java/com/android/server/om/OverlayManagerShellCommand.java
+++ b/services/core/java/com/android/server/om/OverlayManagerShellCommand.java
@@ -114,7 +114,7 @@ final class OverlayManagerShellCommand extends ShellCommand {
out.println(" 'lowest', change priority of PACKAGE to the lowest priority.");
out.println(" If PARENT is the special keyword 'highest', change priority of");
out.println(" PACKAGE to the highest priority.");
- out.println(" lookup [--verbose] PACKAGE-TO-LOAD PACKAGE:TYPE/NAME");
+ out.println(" lookup [--user USER_ID] [--verbose] PACKAGE-TO-LOAD PACKAGE:TYPE/NAME");
out.println(" Load a package and print the value of a given resource");
out.println(" applying the current configuration and enabled overlays.");
out.println(" For a more fine-grained alernative, use 'idmap2 lookup'.");
@@ -274,7 +274,22 @@ final class OverlayManagerShellCommand extends ShellCommand {
final PrintWriter out = getOutPrintWriter();
final PrintWriter err = getErrPrintWriter();
- final boolean verbose = "--verbose".equals(getNextOption());
+ int userId = UserHandle.USER_SYSTEM;
+ boolean verbose = false;
+ String opt;
+ while ((opt = getNextOption()) != null) {
+ switch (opt) {
+ case "--user":
+ userId = UserHandle.parseUserArg(getNextArgRequired());
+ break;
+ case "--verbose":
+ verbose = true;
+ break;
+ default:
+ err.println("Error: Unknown option: " + opt);
+ return 1;
+ }
+ }
final String packageToLoad = getNextArgRequired();
@@ -286,17 +301,15 @@ final class OverlayManagerShellCommand extends ShellCommand {
return 1;
}
- final PackageManager pm = mContext.getPackageManager();
- if (pm == null) {
- err.println("Error: failed to get package manager");
- return 1;
- }
-
final Resources res;
try {
- res = pm.getResourcesForApplication(packageToLoad);
+ res = mContext
+ .createContextAsUser(UserHandle.of(userId), /* flags */ 0)
+ .getPackageManager()
+ .getResourcesForApplication(packageToLoad);
} catch (PackageManager.NameNotFoundException e) {
- err.println("Error: failed to get resources for package " + packageToLoad);
+ err.println(String.format("Error: failed to get resources for package %s for user %d",
+ packageToLoad, userId));
return 1;
}
final AssetManager assets = res.getAssets();
diff --git a/services/core/java/com/android/server/vcn/UnderlyingNetworkTracker.java b/services/core/java/com/android/server/vcn/UnderlyingNetworkTracker.java
index b2db9f5af07e..8dcc547508ec 100644
--- a/services/core/java/com/android/server/vcn/UnderlyingNetworkTracker.java
+++ b/services/core/java/com/android/server/vcn/UnderlyingNetworkTracker.java
@@ -23,7 +23,6 @@ import android.net.ConnectivityManager.NetworkCallback;
import android.net.LinkProperties;
import android.net.Network;
import android.net.NetworkCapabilities;
-import android.net.NetworkCapabilities.NetCapability;
import android.net.NetworkRequest;
import android.net.TelephonyNetworkSpecifier;
import android.os.Handler;
@@ -115,33 +114,61 @@ public class UnderlyingNetworkTracker {
getWifiNetworkRequest(), mHandler, mWifiBringupCallback);
updateSubIdsAndCellularRequests();
- // register Network-selection request used to decide selected underlying Network
+ // Register Network-selection request used to decide selected underlying Network. All
+ // underlying networks must be VCN managed in order to be used.
mConnectivityManager.requestBackgroundNetwork(
- getNetworkRequestBase().build(), mHandler, mRouteSelectionCallback);
+ getBaseNetworkRequest(true /* requireVcnManaged */).build(),
+ mHandler,
+ mRouteSelectionCallback);
}
private NetworkRequest getWifiNetworkRequest() {
- return getNetworkRequestBase().addTransportType(NetworkCapabilities.TRANSPORT_WIFI).build();
+ // Request exclusively VCN managed networks to ensure that we only ever keep carrier wifi
+ // alive.
+ return getBaseNetworkRequest(true /* requireVcnManaged */)
+ .addTransportType(NetworkCapabilities.TRANSPORT_WIFI)
+ .build();
}
private NetworkRequest getCellNetworkRequestForSubId(int subId) {
- return getNetworkRequestBase()
+ // Do not request NOT_VCN_MANAGED to ensure that the TelephonyNetworkFactory has a
+ // fulfillable request to bring up underlying cellular Networks even if the VCN is already
+ // connected.
+ return getBaseNetworkRequest(false /* requireVcnManaged */)
.addTransportType(NetworkCapabilities.TRANSPORT_CELLULAR)
.setNetworkSpecifier(new TelephonyNetworkSpecifier(subId))
.build();
}
- private NetworkRequest.Builder getNetworkRequestBase() {
- NetworkRequest.Builder requestBase = new NetworkRequest.Builder();
- for (@NetCapability int capability : mRequiredUnderlyingNetworkCapabilities) {
+ /**
+ * Builds and returns a NetworkRequest builder common to all Underlying Network requests
+ *
+ * <p>A NetworkRequest may either (1) Require the presence of a capability by using
+ * addCapability(), (2) require the absence of a capability using unwanted capabilities, or (3)
+ * allow any state. Underlying networks are never desired to have the NOT_VCN_MANAGED
+ * capability, and only cases (2) and (3) are used.
+ *
+ * @param requireVcnManaged whether the underlying network is required to be VCN managed to
+ * match this request. If {@code true}, the NOT_VCN_MANAGED capability will be set as
+ * unwanted. Else, the NOT_VCN_MANAGED capability will be removed, and any state is
+ * acceptable.
+ */
+ private NetworkRequest.Builder getBaseNetworkRequest(boolean requireVcnManaged) {
+ NetworkRequest.Builder requestBase =
+ new NetworkRequest.Builder()
+ .removeCapability(NetworkCapabilities.NET_CAPABILITY_TRUSTED)
+ .removeCapability(NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED)
+ .removeCapability(NetworkCapabilities.NET_CAPABILITY_NOT_VCN_MANAGED);
+
+ for (int capability : mRequiredUnderlyingNetworkCapabilities) {
requestBase.addCapability(capability);
}
- return requestBase
- .removeCapability(NetworkCapabilities.NET_CAPABILITY_TRUSTED)
- .removeCapability(NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED)
- .removeCapability(NetworkCapabilities.NET_CAPABILITY_NOT_VCN_MANAGED)
- .addUnwantedCapability(NetworkCapabilities.NET_CAPABILITY_NOT_VCN_MANAGED);
+ if (requireVcnManaged) {
+ requestBase.addUnwantedCapability(NetworkCapabilities.NET_CAPABILITY_NOT_VCN_MANAGED);
+ }
+
+ return requestBase;
}
/**
diff --git a/services/core/java/com/android/server/vcn/Vcn.java b/services/core/java/com/android/server/vcn/Vcn.java
index c55913e2e547..3f74938005a7 100644
--- a/services/core/java/com/android/server/vcn/Vcn.java
+++ b/services/core/java/com/android/server/vcn/Vcn.java
@@ -299,9 +299,7 @@ public class Vcn extends Handler {
for (VcnGatewayConnectionConfig gatewayConnectionConfig :
mConfig.getGatewayConnectionConfigs()) {
if (isRequestSatisfiedByGatewayConnectionConfig(request, gatewayConnectionConfig)) {
- Slog.v(
- getLogTag(),
- "Bringing up new VcnGatewayConnection for request " + request.requestId);
+ Slog.v(getLogTag(), "Bringing up new VcnGatewayConnection for request " + request);
final VcnGatewayConnection vcnGatewayConnection =
mDeps.newVcnGatewayConnection(
diff --git a/services/core/java/com/android/server/vcn/VcnGatewayConnection.java b/services/core/java/com/android/server/vcn/VcnGatewayConnection.java
index 6bc9978a0731..69a153f79a1b 100644
--- a/services/core/java/com/android/server/vcn/VcnGatewayConnection.java
+++ b/services/core/java/com/android/server/vcn/VcnGatewayConnection.java
@@ -20,6 +20,7 @@ import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_CONGESTED;
import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_METERED;
import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_ROAMING;
import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_SUSPENDED;
+import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_VCN_MANAGED;
import static android.net.NetworkCapabilities.TRANSPORT_CELLULAR;
import static android.net.NetworkCapabilities.TRANSPORT_WIFI;
import static android.net.vcn.VcnManager.VCN_ERROR_CODE_CONFIG_ERROR;
@@ -59,6 +60,7 @@ import android.net.ipsec.ike.exceptions.AuthenticationFailedException;
import android.net.ipsec.ike.exceptions.IkeException;
import android.net.ipsec.ike.exceptions.IkeInternalException;
import android.net.ipsec.ike.exceptions.IkeProtocolException;
+import android.net.vcn.VcnControlPlaneIkeConfig;
import android.net.vcn.VcnGatewayConnectionConfig;
import android.net.vcn.VcnTransportInfo;
import android.net.wifi.WifiInfo;
@@ -979,7 +981,7 @@ public class VcnGatewayConnection extends StateMachine {
// IkeSessionCallback.onClosedExceptionally(), which calls sessionClosed()
if (exception != null) {
mGatewayStatusCallback.onGatewayConnectionError(
- mConnectionConfig.getRequiredUnderlyingCapabilities(),
+ mConnectionConfig.getExposedCapabilities(),
VCN_ERROR_CODE_INTERNAL_ERROR,
RuntimeException.class.getName(),
"Received "
@@ -1016,7 +1018,7 @@ public class VcnGatewayConnection extends StateMachine {
}
mGatewayStatusCallback.onGatewayConnectionError(
- mConnectionConfig.getRequiredUnderlyingCapabilities(),
+ mConnectionConfig.getExposedCapabilities(),
errorCode,
exceptionClass,
exceptionMessage);
@@ -1348,7 +1350,7 @@ public class VcnGatewayConnection extends StateMachine {
mIkeSession = null;
}
- mIkeSession = buildIkeSession();
+ mIkeSession = buildIkeSession(mUnderlying.network);
}
@Override
@@ -1726,6 +1728,7 @@ public class VcnGatewayConnection extends StateMachine {
final NetworkCapabilities.Builder builder = new NetworkCapabilities.Builder();
builder.addTransportType(TRANSPORT_CELLULAR);
+ builder.addCapability(NET_CAPABILITY_NOT_VCN_MANAGED);
builder.addCapability(NET_CAPABILITY_NOT_CONGESTED);
builder.addCapability(NET_CAPABILITY_NOT_SUSPENDED);
@@ -1939,23 +1942,29 @@ public class VcnGatewayConnection extends StateMachine {
new EventDisconnectRequestedInfo(reason, shouldQuit));
}
- private IkeSessionParams buildIkeParams() {
- // TODO: Implement this once IkeSessionParams is persisted
- return null;
+ private IkeSessionParams buildIkeParams(@NonNull Network network) {
+ final VcnControlPlaneIkeConfig controlPlaneConfig =
+ (VcnControlPlaneIkeConfig) mConnectionConfig.getControlPlaneConfig();
+ final IkeSessionParams.Builder builder =
+ new IkeSessionParams.Builder(controlPlaneConfig.getIkeSessionParams());
+ builder.setConfiguredNetwork(network);
+
+ return builder.build();
}
private ChildSessionParams buildChildParams() {
- // TODO: Implement this once IkeSessionParams is persisted
- return null;
+ final VcnControlPlaneIkeConfig controlPlaneConfig =
+ (VcnControlPlaneIkeConfig) mConnectionConfig.getControlPlaneConfig();
+ return controlPlaneConfig.getChildSessionParams();
}
@VisibleForTesting(visibility = Visibility.PRIVATE)
- VcnIkeSession buildIkeSession() {
+ VcnIkeSession buildIkeSession(@NonNull Network network) {
final int token = ++mCurrentToken;
return mDeps.newIkeSession(
mVcnContext,
- buildIkeParams(),
+ buildIkeParams(network),
buildChildParams(),
new IkeSessionCallbackImpl(token),
new VcnChildSessionCallback(token));
diff --git a/services/tests/servicestests/src/com/android/server/locksettings/ResumeOnRebootServiceProviderTests.java b/services/tests/servicestests/src/com/android/server/locksettings/ResumeOnRebootServiceProviderTests.java
index b9af82b64c02..f3a38e6ec79c 100644
--- a/services/tests/servicestests/src/com/android/server/locksettings/ResumeOnRebootServiceProviderTests.java
+++ b/services/tests/servicestests/src/com/android/server/locksettings/ResumeOnRebootServiceProviderTests.java
@@ -19,12 +19,12 @@ package com.android.server.locksettings;
import static com.google.common.truth.Truth.assertThat;
import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import android.Manifest;
-import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
@@ -53,12 +53,9 @@ public class ResumeOnRebootServiceProviderTests {
Context mMockContext;
@Mock
PackageManager mMockPackageManager;
- @Mock
- ResolveInfo mMockResolvedInfo;
- @Mock
- ServiceInfo mMockServiceInfo;
- @Mock
- ComponentName mMockComponentName;
+
+ ResolveInfo mFakeResolvedInfo;
+ ServiceInfo mFakeServiceInfo;
@Captor
ArgumentCaptor<Intent> mIntentArgumentCaptor;
@@ -66,8 +63,13 @@ public class ResumeOnRebootServiceProviderTests {
public void setUp() {
MockitoAnnotations.initMocks(this);
when(mMockContext.getUserId()).thenReturn(0);
- when(mMockResolvedInfo.serviceInfo).thenReturn(mMockServiceInfo);
- when(mMockServiceInfo.getComponentName()).thenReturn(mMockComponentName);
+
+ mFakeServiceInfo = new ServiceInfo();
+ mFakeServiceInfo.packageName = "fakePackageName";
+ mFakeServiceInfo.name = "fakeName";
+
+ mFakeResolvedInfo = new ResolveInfo();
+ mFakeResolvedInfo.serviceInfo = mFakeServiceInfo;
}
@Test
@@ -82,10 +84,9 @@ public class ResumeOnRebootServiceProviderTests {
@Test
public void serviceNotGuardedWithPermission() throws Exception {
ArrayList<ResolveInfo> resultList = new ArrayList<>();
- when(mMockServiceInfo.permission).thenReturn("");
- resultList.add(mMockResolvedInfo);
- when(mMockPackageManager.queryIntentServices(any(), any())).thenReturn(
- resultList);
+ mFakeServiceInfo.permission = "";
+ resultList.add(mFakeResolvedInfo);
+ when(mMockPackageManager.queryIntentServices(any(), anyInt())).thenReturn(resultList);
assertThat(new ResumeOnRebootServiceProvider(mMockContext,
mMockPackageManager).getServiceConnection()).isNull();
}
@@ -93,18 +94,15 @@ public class ResumeOnRebootServiceProviderTests {
@Test
public void serviceResolved() throws Exception {
ArrayList<ResolveInfo> resultList = new ArrayList<>();
- resultList.add(mMockResolvedInfo);
- when(mMockServiceInfo.permission).thenReturn(
- Manifest.permission.BIND_RESUME_ON_REBOOT_SERVICE);
- when(mMockPackageManager.queryIntentServices(any(),
- eq(PackageManager.MATCH_SYSTEM_ONLY))).thenReturn(
- resultList);
+ resultList.add(mFakeResolvedInfo);
+ mFakeServiceInfo.permission = Manifest.permission.BIND_RESUME_ON_REBOOT_SERVICE;
+ when(mMockPackageManager.queryIntentServices(any(), anyInt())).thenReturn(resultList);
assertThat(new ResumeOnRebootServiceProvider(mMockContext,
mMockPackageManager).getServiceConnection()).isNotNull();
verify(mMockPackageManager).queryIntentServices(mIntentArgumentCaptor.capture(),
- eq(PackageManager.MATCH_SYSTEM_ONLY));
+ eq(PackageManager.MATCH_SYSTEM_ONLY | PackageManager.GET_SERVICES));
assertThat(mIntentArgumentCaptor.getValue().getAction()).isEqualTo(
ResumeOnRebootService.SERVICE_INTERFACE);
}
diff --git a/services/tests/servicestests/test-apps/SimpleServiceTestApp/OWNERS b/services/tests/servicestests/test-apps/SimpleServiceTestApp/OWNERS
new file mode 100644
index 000000000000..72c0a9e6e90c
--- /dev/null
+++ b/services/tests/servicestests/test-apps/SimpleServiceTestApp/OWNERS
@@ -0,0 +1 @@
+include /services/core/java/com/android/server/am/OWNERS
diff --git a/telecomm/java/android/telecom/ConnectionService.java b/telecomm/java/android/telecom/ConnectionService.java
index 580513c12453..b022154ea917 100755
--- a/telecomm/java/android/telecom/ConnectionService.java
+++ b/telecomm/java/android/telecom/ConnectionService.java
@@ -20,6 +20,7 @@ import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.SdkConstant;
import android.annotation.SystemApi;
+import android.annotation.TestApi;
import android.app.Service;
import android.content.ComponentName;
import android.content.Intent;
@@ -1887,6 +1888,7 @@ public abstract class ConnectionService extends Service {
/** {@inheritDoc} */
@Override
public final IBinder onBind(Intent intent) {
+ onBindClient(intent);
return mBinder;
}
@@ -1897,6 +1899,13 @@ public abstract class ConnectionService extends Service {
return super.onUnbind(intent);
}
+ /**
+ * Used for testing to let the test suite know when the connection service has been bound.
+ * @hide
+ */
+ @TestApi
+ public void onBindClient(@Nullable Intent intent) {
+ }
/**
* This can be used by telecom to either create a new outgoing conference call or attach
diff --git a/telephony/java/android/telephony/CarrierBandwidth.java b/telephony/java/android/telephony/CarrierBandwidth.java
index b153fefce6e3..9e1dee0162b9 100644
--- a/telephony/java/android/telephony/CarrierBandwidth.java
+++ b/telephony/java/android/telephony/CarrierBandwidth.java
@@ -101,7 +101,7 @@ public final class CarrierBandwidth implements Parcelable {
}
/**
- * Retrieves the upstream bandwidth for the primary network in Kbps. This always only refers to
+ * Retrieves the upstream bandwidth for the primary network in kbps. This always only refers to
* the estimated first hop transport bandwidth.
* This will be {@link #INVALID} if the network is not connected
*
@@ -112,7 +112,7 @@ public final class CarrierBandwidth implements Parcelable {
}
/**
- * Retrieves the downstream bandwidth for the primary network in Kbps. This always only refers
+ * Retrieves the downstream bandwidth for the primary network in kbps. This always only refers
* to the estimated first hop transport bandwidth.
* This will be {@link #INVALID} if the network is not connected
*
@@ -123,7 +123,7 @@ public final class CarrierBandwidth implements Parcelable {
}
/**
- * Retrieves the upstream bandwidth for the secondary network in Kbps. This always only refers
+ * Retrieves the upstream bandwidth for the secondary network in kbps. This always only refers
* to the estimated first hop transport bandwidth.
* <p/>
* This will be {@link #INVALID} if either are the case:
@@ -143,7 +143,7 @@ public final class CarrierBandwidth implements Parcelable {
}
/**
- * Retrieves the downstream bandwidth for the secondary network in Kbps. This always only
+ * Retrieves the downstream bandwidth for the secondary network in kbps. This always only
* refers to the estimated first hop transport bandwidth.
* <p/>
* This will be {@link #INVALID} if either are the case:
diff --git a/telephony/java/android/telephony/TelephonyManager.java b/telephony/java/android/telephony/TelephonyManager.java
index e3853fabfd7a..23dcee6387b8 100644
--- a/telephony/java/android/telephony/TelephonyManager.java
+++ b/telephony/java/android/telephony/TelephonyManager.java
@@ -14120,12 +14120,11 @@ public class TelephonyManager {
* {@link #NR_DUAL_CONNECTIVITY_DISABLE_IMMEDIATE}
* </ol>
* @return operation result.
- * <p>Requires Permission:
- * {@link android.Manifest.permission#MODIFY_PHONE_STATE MODIFY_PHONE_STATE}
* @throws IllegalStateException if the Telephony process is not currently available.
* @hide
*/
@SystemApi
+ @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE)
public @EnableNrDualConnectivityResult int setNrDualConnectivityState(
@NrDualConnectivityState int nrDualConnectivityState) {
try {
diff --git a/telephony/java/com/android/internal/telephony/RILConstants.java b/telephony/java/com/android/internal/telephony/RILConstants.java
index 76243a5799c3..3eda7482117f 100644
--- a/telephony/java/com/android/internal/telephony/RILConstants.java
+++ b/telephony/java/com/android/internal/telephony/RILConstants.java
@@ -522,8 +522,8 @@ public interface RILConstants {
int RIL_REQUEST_GET_SYSTEM_SELECTION_CHANNELS = 219;
int RIL_REQUEST_GET_HAL_DEVICE_CAPABILITIES = 220;
int RIL_REQUEST_SET_DATA_THROTTLING = 221;
- int RIL_REQUEST_SET_ALLOWED_NETWORK_TYPE_BITMAP = 222;
- int RIL_REQUEST_GET_ALLOWED_NETWORK_TYPE_BITMAP = 223;
+ int RIL_REQUEST_SET_ALLOWED_NETWORK_TYPES_BITMAP = 222;
+ int RIL_REQUEST_GET_ALLOWED_NETWORK_TYPES_BITMAP = 223;
/* Responses begin */
int RIL_RESPONSE_ACKNOWLEDGEMENT = 800;
diff --git a/tests/net/TEST_MAPPING b/tests/net/TEST_MAPPING
index 89fc6ea2c47b..d659688700d3 100644
--- a/tests/net/TEST_MAPPING
+++ b/tests/net/TEST_MAPPING
@@ -9,6 +9,23 @@
"name": "FrameworksNetDeflakeTest"
}
],
+ "auto-postsubmit": [
+ // Test tag for automotive targets. These are only running in postsubmit so as to harden the
+ // automotive targets to avoid introducing additional test flake and build time. The plan for
+ // presubmit testing for auto is to augment the existing tests to cover auto use cases as well.
+ // Additionally, this tag is used in targeted test suites to limit resource usage on the test
+ // infra during the hardening phase.
+ // TODO: this tag to be removed once the above is no longer an issue.
+ {
+ "name": "FrameworksNetTests"
+ },
+ {
+ "name": "FrameworksNetIntegrationTests"
+ },
+ {
+ "name": "FrameworksNetDeflakeTest"
+ }
+ ],
"imports": [
{
"path": "cts/tests/tests/net"
diff --git a/tests/net/java/com/android/server/ConnectivityServiceTest.java b/tests/net/java/com/android/server/ConnectivityServiceTest.java
index 526e190aaa78..dfebb281c6ea 100644
--- a/tests/net/java/com/android/server/ConnectivityServiceTest.java
+++ b/tests/net/java/com/android/server/ConnectivityServiceTest.java
@@ -72,6 +72,7 @@ import static android.net.NetworkCapabilities.NET_CAPABILITY_OEM_PRIVATE;
import static android.net.NetworkCapabilities.NET_CAPABILITY_PARTIAL_CONNECTIVITY;
import static android.net.NetworkCapabilities.NET_CAPABILITY_RCS;
import static android.net.NetworkCapabilities.NET_CAPABILITY_SUPL;
+import static android.net.NetworkCapabilities.NET_CAPABILITY_TEMPORARILY_NOT_METERED;
import static android.net.NetworkCapabilities.NET_CAPABILITY_TRUSTED;
import static android.net.NetworkCapabilities.NET_CAPABILITY_VALIDATED;
import static android.net.NetworkCapabilities.NET_CAPABILITY_WIFI_P2P;
@@ -5571,7 +5572,7 @@ public class ConnectivityServiceTest {
reset(mStatsManager);
// Temp metered change shouldn't update ifaces
- mCellNetworkAgent.addCapability(NetworkCapabilities.NET_CAPABILITY_TEMPORARILY_NOT_METERED);
+ mCellNetworkAgent.addCapability(NET_CAPABILITY_TEMPORARILY_NOT_METERED);
waitForIdle();
verify(mStatsManager, never()).notifyNetworkStatus(eq(Arrays.asList(onlyCell)),
any(List.class), eq(MOBILE_IFNAME), any(List.class));
@@ -10646,7 +10647,7 @@ public class ConnectivityServiceTest {
null,
null);
- // default NCs will be unregistered in tearDown
+ // default callbacks will be unregistered in tearDown
}
/**
@@ -10703,7 +10704,7 @@ public class ConnectivityServiceTest {
null,
mService.mNoServiceNetwork.network());
- // default NCs will be unregistered in tearDown
+ // default callbacks will be unregistered in tearDown
}
/**
@@ -10762,7 +10763,7 @@ public class ConnectivityServiceTest {
null,
mService.mNoServiceNetwork.network());
- // default NCs will be unregistered in tearDown
+ // default callbacks will be unregistered in tearDown
}
/**
@@ -10821,7 +10822,28 @@ public class ConnectivityServiceTest {
null,
mService.mNoServiceNetwork.network());
- // default NCs will be unregistered in tearDown
+ // default callbacks will be unregistered in tearDown
+ }
+
+ @Test
+ public void testCapabilityWithOemNetworkPreference() throws Exception {
+ @OemNetworkPreferences.OemNetworkPreference final int networkPref =
+ OemNetworkPreferences.OEM_NETWORK_PREFERENCE_OEM_PRIVATE_ONLY;
+ setupMultipleDefaultNetworksForOemNetworkPreferenceNotCurrentUidTest(networkPref);
+ registerDefaultNetworkCallbacks();
+
+ setOemNetworkPreferenceAgentConnected(TRANSPORT_CELLULAR, true);
+
+ mSystemDefaultNetworkCallback.expectAvailableThenValidatedCallbacks(mCellNetworkAgent);
+ mDefaultNetworkCallback.expectAvailableThenValidatedCallbacks(mCellNetworkAgent);
+
+ mCellNetworkAgent.addCapability(NET_CAPABILITY_TEMPORARILY_NOT_METERED);
+ mSystemDefaultNetworkCallback.expectCapabilitiesThat(mCellNetworkAgent, nc ->
+ nc.hasCapability(NET_CAPABILITY_TEMPORARILY_NOT_METERED));
+ mDefaultNetworkCallback.expectCapabilitiesThat(mCellNetworkAgent, nc ->
+ nc.hasCapability(NET_CAPABILITY_TEMPORARILY_NOT_METERED));
+
+ // default callbacks will be unregistered in tearDown
}
@Test
diff --git a/tests/vcn/assets/client-end-cert.pem b/tests/vcn/assets/client-end-cert.pem
new file mode 100644
index 000000000000..e82da85c50ab
--- /dev/null
+++ b/tests/vcn/assets/client-end-cert.pem
@@ -0,0 +1,21 @@
+-----BEGIN CERTIFICATE-----
+MIIDaDCCAlCgAwIBAgIIcorRI3n29E4wDQYJKoZIhvcNAQELBQAwQTELMAkGA1UE
+BhMCVVMxEDAOBgNVBAoTB0FuZHJvaWQxIDAeBgNVBAMTF3R3by5jYS50ZXN0LmFu
+ZHJvaWQubmV0MB4XDTIwMDQxNDA1MDM0OVoXDTIzMDQxNDA1MDM0OVowRTELMAkG
+A1UEBhMCVVMxEDAOBgNVBAoTB0FuZHJvaWQxJDAiBgNVBAMTG2NsaWVudC50ZXN0
+LmlrZS5hbmRyb2lkLm5ldDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB
+AK/cK+sIaiQlJYvy5+Dq70sJbgR7PO1uS2qkLRP7Wb3z5SNvz94nQvZRrFn1AFIE
+CpfESh5kUF6gJe7t7NR3mpQ98iEosCRBMDJT8qB+EeHiL4wkrmCE9sYMTyvaApRc
+6Qzozn/9kKma7Qpj/25AvoPluTERqhZ6AQ77BJeb6FNOAoO1Aoe9GJuB1xmRxjRw
+D0mwusL+ciQ/7uKlsFP5VO5XqACcohXSerzO8jcD9necBvka3SDepqqzn1K0NPRC
+25fMmS5kSjddKtKOif7w2NI3OpVsmP3kHv66If73VURsy0lgXPYyKkq8lAMrtmXG
+R7svFGPbEl+Swkpr3b+dzF8CAwEAAaNgMF4wHwYDVR0jBBgwFoAUcqSu1uRYT/DL
+bLoDNUz38nGvCKQwJgYDVR0RBB8wHYIbY2xpZW50LnRlc3QuaWtlLmFuZHJvaWQu
+bmV0MBMGA1UdJQQMMAoGCCsGAQUFBwMCMA0GCSqGSIb3DQEBCwUAA4IBAQCa53tK
+I9RM9/MutZ5KNG2Gfs2cqaPyv8ZRhs90HDWZhkFVu7prywJAxOd2hxxHPsvgurio
+4bKAxnT4EXevgz5YoCbj2TPIL9TdFYh59zZ97XXMxk+SRdypgF70M6ETqKPs3hDP
+ZRMMoHvvYaqaPvp4StSBX9A44gSyjHxVYJkrjDZ0uffKg5lFL5IPvqfdmSRSpGab
+SyGTP4OLTy0QiNV3pBsJGdl0h5BzuTPR9OTl4xgeqqBQy2bDjmfJBuiYyCSCkPi7
+T3ohDYCymhuSkuktHPNG1aKllUJaw0tuZuNydlgdAveXPYfM36uvK0sfd9qr9pAy
+rmkYV2MAWguFeckh
+-----END CERTIFICATE----- \ No newline at end of file
diff --git a/tests/vcn/assets/client-private-key.key b/tests/vcn/assets/client-private-key.key
new file mode 100644
index 000000000000..22736e98e030
--- /dev/null
+++ b/tests/vcn/assets/client-private-key.key
@@ -0,0 +1,28 @@
+-----BEGIN PRIVATE KEY-----
+MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCv3CvrCGokJSWL
+8ufg6u9LCW4EezztbktqpC0T+1m98+Ujb8/eJ0L2UaxZ9QBSBAqXxEoeZFBeoCXu
+7ezUd5qUPfIhKLAkQTAyU/KgfhHh4i+MJK5ghPbGDE8r2gKUXOkM6M5//ZCpmu0K
+Y/9uQL6D5bkxEaoWegEO+wSXm+hTTgKDtQKHvRibgdcZkcY0cA9JsLrC/nIkP+7i
+pbBT+VTuV6gAnKIV0nq8zvI3A/Z3nAb5Gt0g3qaqs59StDT0QtuXzJkuZEo3XSrS
+jon+8NjSNzqVbJj95B7+uiH+91VEbMtJYFz2MipKvJQDK7Zlxke7LxRj2xJfksJK
+a92/ncxfAgMBAAECggEAQztaMvW5lm35J8LKsWs/5qEJRX9T8LWs8W0oqq36Riub
+G2wgvR6ndAIPcSjAYZqX7iOl7m6NZ0+0kN63HxdGqovwKIskpAekBGmhpYftED1n
+zh0r6UyMB3UnQ22KdOv8UOokIDxxdNX8728BdUYdT9Ggdkj5jLRB+VcwD0IUlNvo
+zzTpURV9HEd87uiLqd4AAHXSI0lIHI5U43z24HI/J6/YbYHT3Rlh6CIa/LuwO6vL
+gFkgqg0/oy6yJtjrHtzNVA67F0UaH62hR4YFgbC0d955SJnDidWOv/0j2DMpfdCc
+9kFAcPwUSyykvUSLnGIKWSG4D+6gzIeAeUx4oO7kMQKBgQDVNRkX8AGTHyLg+NXf
+spUWWcodwVioXl30Q7h6+4bt8OI61UbhQ7wX61wvJ1cySpa2KOYa2UdagQVhGhhL
+ADu363R77uXF/jZgzVfmjjyJ2nfDqRgHWRTlSkuq/jCOQCz7VIPHRZg5WL/9D4ms
+TAqMjpzqeMfFZI+w4/+xpcJIuQKBgQDTKBy+ZuerWrVT9icWKvLU58o5EVj/2yFy
+GJvKm+wRAAX2WzjNnR4HVd4DmMREVz1BPYby0j5gqjvtDsxYYu39+NT7JvMioLLK
+QPj+7k5geYgNqVgCxB1vP89RhY2X1RLrN9sTXOodgFPeXOQWNYITkGp3eQpx4nTJ
++K/al3oB1wKBgAjnc8nVIyuyxDEjE0OJYMKTM2a0uXAmqMPXxC+Wq5bqVXhhidlE
+i+lv0eTCPtkB1nN7F8kNQ/aaps/cWCFhvBy9P5shagUvzbOTP9WIIS0cq53HRRKh
+fMbqqGhWv05hjb9dUzeSR341n6cA7B3++v3Nwu3j52vt/DZF/1q68nc5AoGAS0SU
+ImbKE/GsizZGLoe2sZ/CHN+LKwCwhlwxRGKaHmE0vuE7eUeVSaYZEo0lAPtb8WJ+
+NRYueASWgeTxgFwbW5mUScZTirdfo+rPFwhZVdhcYApKPgosN9i2DOgfVcz1BnWN
+mPRY25U/0BaqkyQVruWeneG+kGPZn5kPDktKiVcCgYEAkzwU9vCGhm7ZVALvx/zR
+wARz2zsL9ImBc0P4DK1ld8g90FEnHrEgeI9JEwz0zFHOCMLwlk7kG0Xev7vfjZ7G
+xSqtQYOH33Qp6rtBOgdt8hSyDFvakvDl6bqhAw52gelO3MTpAB1+ZsfZ5gFx13Jf
+idNFcaIrC52PtZIH7QCzdDY=
+-----END PRIVATE KEY----- \ No newline at end of file
diff --git a/tests/vcn/java/android/net/vcn/VcnControlPlaneIkeConfigTest.java b/tests/vcn/java/android/net/vcn/VcnControlPlaneIkeConfigTest.java
index 36f5e41462e8..2333718d0cab 100644
--- a/tests/vcn/java/android/net/vcn/VcnControlPlaneIkeConfigTest.java
+++ b/tests/vcn/java/android/net/vcn/VcnControlPlaneIkeConfigTest.java
@@ -99,6 +99,13 @@ public class VcnControlPlaneIkeConfigTest {
}
@Test
+ public void testPersistableBundle() {
+ final VcnControlPlaneIkeConfig config = buildTestConfig();
+
+ assertEquals(config, new VcnControlPlaneIkeConfig(config.toPersistableBundle()));
+ }
+
+ @Test
public void testConstructConfigWithoutIkeParams() {
try {
new VcnControlPlaneIkeConfig(null, CHILD_PARAMS);
diff --git a/tests/vcn/java/android/net/vcn/persistablebundleutils/IkeSessionParamsUtilsTest.java b/tests/vcn/java/android/net/vcn/persistablebundleutils/IkeSessionParamsUtilsTest.java
new file mode 100644
index 000000000000..546d957d417e
--- /dev/null
+++ b/tests/vcn/java/android/net/vcn/persistablebundleutils/IkeSessionParamsUtilsTest.java
@@ -0,0 +1,189 @@
+/*
+ * 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.vcn.persistablebundleutils;
+
+import static android.system.OsConstants.AF_INET;
+import static android.system.OsConstants.AF_INET6;
+import static android.telephony.TelephonyManager.APPTYPE_USIM;
+
+import static org.junit.Assert.assertEquals;
+
+import android.net.InetAddresses;
+import android.net.eap.EapSessionConfig;
+import android.net.ipsec.ike.IkeFqdnIdentification;
+import android.net.ipsec.ike.IkeSessionParams;
+import android.os.PersistableBundle;
+
+import androidx.test.InstrumentationRegistry;
+import androidx.test.filters.SmallTest;
+import androidx.test.runner.AndroidJUnit4;
+
+import com.android.internal.org.bouncycastle.util.io.pem.PemObject;
+import com.android.internal.org.bouncycastle.util.io.pem.PemReader;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.net.Inet4Address;
+import java.net.Inet6Address;
+import java.net.InetAddress;
+import java.nio.charset.StandardCharsets;
+import java.security.cert.CertificateFactory;
+import java.security.cert.X509Certificate;
+import java.security.interfaces.RSAPrivateKey;
+import java.util.concurrent.TimeUnit;
+
+@RunWith(AndroidJUnit4.class)
+@SmallTest
+public class IkeSessionParamsUtilsTest {
+ private static IkeSessionParams.Builder createBuilderMinimum() {
+ final InetAddress serverAddress = InetAddresses.parseNumericAddress("192.0.2.100");
+
+ return new IkeSessionParams.Builder()
+ .setServerHostname(serverAddress.getHostAddress())
+ .addSaProposal(SaProposalUtilsTest.buildTestIkeSaProposal())
+ .setLocalIdentification(new IkeFqdnIdentification("client.test.android.net"))
+ .setRemoteIdentification(new IkeFqdnIdentification("server.test.android.net"))
+ .setAuthPsk("psk".getBytes());
+ }
+
+ private static void verifyPersistableBundleEncodeDecodeIsLossless(IkeSessionParams params) {
+ final PersistableBundle bundle = IkeSessionParamsUtils.toPersistableBundle(params);
+ final IkeSessionParams result = IkeSessionParamsUtils.fromPersistableBundle(bundle);
+
+ assertEquals(result, params);
+ }
+
+ @Test
+ public void testEncodeRecodeParamsWithLifetimes() throws Exception {
+ final int hardLifetime = (int) TimeUnit.HOURS.toSeconds(20L);
+ final int softLifetime = (int) TimeUnit.HOURS.toSeconds(10L);
+ final IkeSessionParams params =
+ createBuilderMinimum().setLifetimeSeconds(hardLifetime, softLifetime).build();
+ verifyPersistableBundleEncodeDecodeIsLossless(params);
+ }
+
+ @Test
+ public void testEncodeRecodeParamsWithDpdDelay() throws Exception {
+ final int dpdDelay = (int) TimeUnit.MINUTES.toSeconds(10L);
+ final IkeSessionParams params = createBuilderMinimum().setDpdDelaySeconds(dpdDelay).build();
+
+ verifyPersistableBundleEncodeDecodeIsLossless(params);
+ }
+
+ @Test
+ public void testEncodeRecodeParamsWithNattKeepalive() throws Exception {
+ final int nattKeepAliveDelay = (int) TimeUnit.MINUTES.toSeconds(5L);
+ final IkeSessionParams params =
+ createBuilderMinimum().setNattKeepAliveDelaySeconds(nattKeepAliveDelay).build();
+
+ verifyPersistableBundleEncodeDecodeIsLossless(params);
+ }
+
+ @Test
+ public void testEncodeRecodeParamsWithRetransmissionTimeouts() throws Exception {
+ final int[] retransmissionTimeout = new int[] {500, 500, 500, 500, 500, 500};
+ final IkeSessionParams params =
+ createBuilderMinimum()
+ .setRetransmissionTimeoutsMillis(retransmissionTimeout)
+ .build();
+
+ verifyPersistableBundleEncodeDecodeIsLossless(params);
+ }
+
+ @Test
+ public void testEncodeRecodeParamsWithConfigRequests() throws Exception {
+ final Inet4Address ipv4Address =
+ (Inet4Address) InetAddresses.parseNumericAddress("192.0.2.100");
+ final Inet6Address ipv6Address =
+ (Inet6Address) InetAddresses.parseNumericAddress("2001:db8::1");
+
+ final IkeSessionParams params =
+ createBuilderMinimum()
+ .addPcscfServerRequest(AF_INET)
+ .addPcscfServerRequest(AF_INET6)
+ .addPcscfServerRequest(ipv4Address)
+ .addPcscfServerRequest(ipv6Address)
+ .build();
+ verifyPersistableBundleEncodeDecodeIsLossless(params);
+ }
+
+ @Test
+ public void testEncodeRecodeParamsWithAuthPsk() throws Exception {
+ final IkeSessionParams params = createBuilderMinimum().setAuthPsk("psk".getBytes()).build();
+ verifyPersistableBundleEncodeDecodeIsLossless(params);
+ }
+
+ @Test
+ public void testEncodeRecodeParamsWithIkeOptions() throws Exception {
+ final IkeSessionParams params =
+ createBuilderMinimum()
+ .addIkeOption(IkeSessionParams.IKE_OPTION_ACCEPT_ANY_REMOTE_ID)
+ .addIkeOption(IkeSessionParams.IKE_OPTION_MOBIKE)
+ .build();
+ verifyPersistableBundleEncodeDecodeIsLossless(params);
+ }
+
+ private static InputStream openAssetsFile(String fileName) throws Exception {
+ return InstrumentationRegistry.getContext().getResources().getAssets().open(fileName);
+ }
+
+ private static X509Certificate createCertFromPemFile(String fileName) throws Exception {
+ final CertificateFactory factory = CertificateFactory.getInstance("X.509");
+ return (X509Certificate) factory.generateCertificate(openAssetsFile(fileName));
+ }
+
+ private static RSAPrivateKey createRsaPrivateKeyFromKeyFile(String fileName) throws Exception {
+ final PemObject pemObject =
+ new PemReader(new InputStreamReader(openAssetsFile(fileName))).readPemObject();
+ return (RSAPrivateKey) CertUtils.privateKeyFromByteArray(pemObject.getContent());
+ }
+
+ @Test
+ public void testEncodeRecodeParamsWithDigitalSignAuth() throws Exception {
+ final X509Certificate serverCaCert = createCertFromPemFile("self-signed-ca.pem");
+ final X509Certificate clientEndCert = createCertFromPemFile("client-end-cert.pem");
+ final RSAPrivateKey clientPrivateKey =
+ createRsaPrivateKeyFromKeyFile("client-private-key.key");
+
+ final IkeSessionParams params =
+ createBuilderMinimum()
+ .setAuthDigitalSignature(serverCaCert, clientEndCert, clientPrivateKey)
+ .build();
+ verifyPersistableBundleEncodeDecodeIsLossless(params);
+ }
+
+ @Test
+ public void testEncodeRecodeParamsWithEapAuth() throws Exception {
+ final X509Certificate serverCaCert = createCertFromPemFile("self-signed-ca.pem");
+
+ final byte[] eapId = "test@android.net".getBytes(StandardCharsets.US_ASCII);
+ final int subId = 1;
+ final EapSessionConfig eapConfig =
+ new EapSessionConfig.Builder()
+ .setEapIdentity(eapId)
+ .setEapSimConfig(subId, APPTYPE_USIM)
+ .setEapAkaConfig(subId, APPTYPE_USIM)
+ .build();
+
+ final IkeSessionParams params =
+ createBuilderMinimum().setAuthEap(serverCaCert, eapConfig).build();
+ verifyPersistableBundleEncodeDecodeIsLossless(params);
+ }
+}
diff --git a/tests/vcn/java/android/net/vcn/persistablebundleutils/SaProposalUtilsTest.java b/tests/vcn/java/android/net/vcn/persistablebundleutils/SaProposalUtilsTest.java
index 8ae8692b4f75..664044a9e7d4 100644
--- a/tests/vcn/java/android/net/vcn/persistablebundleutils/SaProposalUtilsTest.java
+++ b/tests/vcn/java/android/net/vcn/persistablebundleutils/SaProposalUtilsTest.java
@@ -32,21 +32,25 @@ import org.junit.runner.RunWith;
@RunWith(AndroidJUnit4.class)
@SmallTest
public class SaProposalUtilsTest {
+ /** Package private so that IkeSessionParamsUtilsTest can use it */
+ static IkeSaProposal buildTestIkeSaProposal() {
+ return new IkeSaProposal.Builder()
+ .addEncryptionAlgorithm(
+ SaProposal.ENCRYPTION_ALGORITHM_3DES, SaProposal.KEY_LEN_UNUSED)
+ .addEncryptionAlgorithm(
+ SaProposal.ENCRYPTION_ALGORITHM_AES_CBC, SaProposal.KEY_LEN_AES_128)
+ .addIntegrityAlgorithm(SaProposal.INTEGRITY_ALGORITHM_HMAC_SHA1_96)
+ .addIntegrityAlgorithm(SaProposal.INTEGRITY_ALGORITHM_HMAC_SHA2_256_128)
+ .addPseudorandomFunction(SaProposal.PSEUDORANDOM_FUNCTION_AES128_XCBC)
+ .addPseudorandomFunction(SaProposal.PSEUDORANDOM_FUNCTION_SHA2_256)
+ .addDhGroup(SaProposal.DH_GROUP_1024_BIT_MODP)
+ .addDhGroup(SaProposal.DH_GROUP_3072_BIT_MODP)
+ .build();
+ }
+
@Test
public void testPersistableBundleEncodeDecodeIsLosslessIkeProposal() throws Exception {
- final IkeSaProposal proposal =
- new IkeSaProposal.Builder()
- .addEncryptionAlgorithm(
- SaProposal.ENCRYPTION_ALGORITHM_3DES, SaProposal.KEY_LEN_UNUSED)
- .addEncryptionAlgorithm(
- SaProposal.ENCRYPTION_ALGORITHM_AES_CBC, SaProposal.KEY_LEN_AES_128)
- .addIntegrityAlgorithm(SaProposal.INTEGRITY_ALGORITHM_HMAC_SHA1_96)
- .addIntegrityAlgorithm(SaProposal.INTEGRITY_ALGORITHM_HMAC_SHA2_256_128)
- .addPseudorandomFunction(SaProposal.PSEUDORANDOM_FUNCTION_AES128_XCBC)
- .addPseudorandomFunction(SaProposal.PSEUDORANDOM_FUNCTION_SHA2_256)
- .addDhGroup(SaProposal.DH_GROUP_1024_BIT_MODP)
- .addDhGroup(SaProposal.DH_GROUP_3072_BIT_MODP)
- .build();
+ final IkeSaProposal proposal = buildTestIkeSaProposal();
final PersistableBundle bundle = IkeSaProposalUtils.toPersistableBundle(proposal);
final SaProposal resultProposal = IkeSaProposalUtils.fromPersistableBundle(bundle);
diff --git a/tests/vcn/java/com/android/server/vcn/UnderlyingNetworkTrackerTest.java b/tests/vcn/java/com/android/server/vcn/UnderlyingNetworkTrackerTest.java
index 1d459a347526..1ef1a61f17ea 100644
--- a/tests/vcn/java/com/android/server/vcn/UnderlyingNetworkTrackerTest.java
+++ b/tests/vcn/java/com/android/server/vcn/UnderlyingNetworkTrackerTest.java
@@ -194,29 +194,35 @@ public class UnderlyingNetworkTrackerTest {
}
private NetworkRequest getWifiRequest() {
- return getExpectedRequestBase()
+ return getExpectedRequestBase(true)
.addTransportType(NetworkCapabilities.TRANSPORT_WIFI)
.build();
}
private NetworkRequest getCellRequestForSubId(int subId) {
- return getExpectedRequestBase()
+ return getExpectedRequestBase(false)
.addTransportType(NetworkCapabilities.TRANSPORT_CELLULAR)
.setNetworkSpecifier(new TelephonyNetworkSpecifier(subId))
.build();
}
private NetworkRequest getRouteSelectionRequest() {
- return getExpectedRequestBase().build();
+ return getExpectedRequestBase(true).build();
}
- private NetworkRequest.Builder getExpectedRequestBase() {
- return new NetworkRequest.Builder()
- .addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)
- .removeCapability(NetworkCapabilities.NET_CAPABILITY_TRUSTED)
- .removeCapability(NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED)
- .removeCapability(NetworkCapabilities.NET_CAPABILITY_NOT_VCN_MANAGED)
- .addUnwantedCapability(NetworkCapabilities.NET_CAPABILITY_NOT_VCN_MANAGED);
+ private NetworkRequest.Builder getExpectedRequestBase(boolean requireVcnManaged) {
+ final NetworkRequest.Builder builder =
+ new NetworkRequest.Builder()
+ .addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)
+ .removeCapability(NetworkCapabilities.NET_CAPABILITY_TRUSTED)
+ .removeCapability(NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED)
+ .removeCapability(NetworkCapabilities.NET_CAPABILITY_NOT_VCN_MANAGED);
+
+ if (requireVcnManaged) {
+ builder.addUnwantedCapability(NetworkCapabilities.NET_CAPABILITY_NOT_VCN_MANAGED);
+ }
+
+ return builder;
}
@Test
diff --git a/tests/vcn/java/com/android/server/vcn/VcnGatewayConnectionConnectedStateTest.java b/tests/vcn/java/com/android/server/vcn/VcnGatewayConnectionConnectedStateTest.java
index 69b2fb135a8d..0e5f5e43f282 100644
--- a/tests/vcn/java/com/android/server/vcn/VcnGatewayConnectionConnectedStateTest.java
+++ b/tests/vcn/java/com/android/server/vcn/VcnGatewayConnectionConnectedStateTest.java
@@ -73,7 +73,7 @@ public class VcnGatewayConnectionConnectedStateTest extends VcnGatewayConnection
mGatewayConnection.setUnderlyingNetwork(TEST_UNDERLYING_NETWORK_RECORD_1);
- mIkeSession = mGatewayConnection.buildIkeSession();
+ mIkeSession = mGatewayConnection.buildIkeSession(TEST_UNDERLYING_NETWORK_RECORD_1.network);
mGatewayConnection.setIkeSession(mIkeSession);
mGatewayConnection.transitionTo(mGatewayConnection.mConnectedState);
@@ -241,7 +241,7 @@ public class VcnGatewayConnectionConnectedStateTest extends VcnGatewayConnection
verify(mGatewayStatusCallback)
.onGatewayConnectionError(
- eq(mConfig.getRequiredUnderlyingCapabilities()),
+ eq(mConfig.getExposedCapabilities()),
eq(VCN_ERROR_CODE_INTERNAL_ERROR),
any(),
any());
@@ -275,10 +275,7 @@ public class VcnGatewayConnectionConnectedStateTest extends VcnGatewayConnection
verify(mGatewayStatusCallback)
.onGatewayConnectionError(
- eq(mConfig.getRequiredUnderlyingCapabilities()),
- eq(expectedErrorType),
- any(),
- any());
+ eq(mConfig.getExposedCapabilities()), eq(expectedErrorType), any(), any());
}
@Test
diff --git a/tests/vcn/java/com/android/server/vcn/VcnGatewayConnectionConnectingStateTest.java b/tests/vcn/java/com/android/server/vcn/VcnGatewayConnectionConnectingStateTest.java
index d07d2cf4f1bb..7afa4494ee8b 100644
--- a/tests/vcn/java/com/android/server/vcn/VcnGatewayConnectionConnectingStateTest.java
+++ b/tests/vcn/java/com/android/server/vcn/VcnGatewayConnectionConnectingStateTest.java
@@ -25,12 +25,15 @@ import static org.mockito.Matchers.any;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.verify;
+import android.net.ipsec.ike.IkeSessionParams;
+
import androidx.test.filters.SmallTest;
import androidx.test.runner.AndroidJUnit4;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
+import org.mockito.ArgumentCaptor;
/** Tests for VcnGatewayConnection.ConnectingState */
@RunWith(AndroidJUnit4.class)
@@ -51,7 +54,12 @@ public class VcnGatewayConnectionConnectingStateTest extends VcnGatewayConnectio
@Test
public void testEnterStateCreatesNewIkeSession() throws Exception {
- verify(mDeps).newIkeSession(any(), any(), any(), any(), any());
+ final ArgumentCaptor<IkeSessionParams> paramsCaptor =
+ ArgumentCaptor.forClass(IkeSessionParams.class);
+ verify(mDeps).newIkeSession(any(), paramsCaptor.capture(), any(), any(), any());
+ assertEquals(
+ TEST_UNDERLYING_NETWORK_RECORD_1.network,
+ paramsCaptor.getValue().getConfiguredNetwork());
}
@Test
diff --git a/tests/vcn/java/com/android/server/vcn/VcnGatewayConnectionDisconnectingStateTest.java b/tests/vcn/java/com/android/server/vcn/VcnGatewayConnectionDisconnectingStateTest.java
index 661e03af4f84..99feffdebc8e 100644
--- a/tests/vcn/java/com/android/server/vcn/VcnGatewayConnectionDisconnectingStateTest.java
+++ b/tests/vcn/java/com/android/server/vcn/VcnGatewayConnectionDisconnectingStateTest.java
@@ -38,7 +38,8 @@ public class VcnGatewayConnectionDisconnectingStateTest extends VcnGatewayConnec
public void setUp() throws Exception {
super.setUp();
- mGatewayConnection.setIkeSession(mGatewayConnection.buildIkeSession());
+ mGatewayConnection.setIkeSession(
+ mGatewayConnection.buildIkeSession(TEST_UNDERLYING_NETWORK_RECORD_2.network));
// ensure that mGatewayConnection has an underlying Network before entering
// DisconnectingState
diff --git a/tests/vcn/java/com/android/server/vcn/VcnGatewayConnectionTest.java b/tests/vcn/java/com/android/server/vcn/VcnGatewayConnectionTest.java
index 748c7924685d..d08af9dd3370 100644
--- a/tests/vcn/java/com/android/server/vcn/VcnGatewayConnectionTest.java
+++ b/tests/vcn/java/com/android/server/vcn/VcnGatewayConnectionTest.java
@@ -18,6 +18,7 @@ package com.android.server.vcn;
import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_METERED;
import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_ROAMING;
+import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_VCN_MANAGED;
import static android.net.NetworkCapabilities.TRANSPORT_CELLULAR;
import static android.net.NetworkCapabilities.TRANSPORT_WIFI;
@@ -87,6 +88,7 @@ public class VcnGatewayConnectionTest extends VcnGatewayConnectionTestBase {
private void verifyBuildNetworkCapabilitiesCommon(int transportType) {
final NetworkCapabilities underlyingCaps = new NetworkCapabilities();
underlyingCaps.addTransportType(transportType);
+ underlyingCaps.addCapability(NET_CAPABILITY_NOT_VCN_MANAGED);
underlyingCaps.addCapability(NET_CAPABILITY_NOT_METERED);
underlyingCaps.addCapability(NET_CAPABILITY_NOT_ROAMING);