Merge changes Idc218e5f,I26c3fafc

* changes:
  Remove more FDE methods from StorageManager
  Drop FDE status checks from DevicePolicyManagerService
diff --git a/Android.bp b/Android.bp
index 8c5a855..ceb35bd 100644
--- a/Android.bp
+++ b/Android.bp
@@ -65,7 +65,6 @@
         // Java/AIDL sources under frameworks/base
         ":framework-annotations",
         ":framework-blobstore-sources",
-        ":framework-connectivity-tiramisu-sources",
         ":framework-core-sources",
         ":framework-drm-sources",
         ":framework-graphics-nonupdatable-sources",
diff --git a/apct-tests/perftests/core/src/android/libcore/AdditionPerfTest.java b/apct-tests/perftests/core/src/android/libcore/AdditionPerfTest.java
new file mode 100644
index 0000000..ea3d172
--- /dev/null
+++ b/apct-tests/perftests/core/src/android/libcore/AdditionPerfTest.java
@@ -0,0 +1,115 @@
+/*
+ * Copyright (C) 2016 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.libcore;
+
+import android.perftests.utils.BenchmarkState;
+import android.perftests.utils.PerfStatusReporter;
+import android.test.suitebuilder.annotation.LargeTest;
+
+import androidx.test.runner.AndroidJUnit4;
+
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+/**
+ * What do various kinds of addition cost?
+ */
+@RunWith(AndroidJUnit4.class)
+@LargeTest
+public class AdditionPerfTest {
+
+    @Rule
+    public PerfStatusReporter mPerfStatusReporter = new PerfStatusReporter();
+
+    @Test
+    public int timeAddConstantToLocalInt() {
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        int result = 0;
+        while (state.keepRunning()) {
+            result += 123;
+        }
+        return result;
+    }
+    @Test
+    public int timeAddTwoLocalInts() {
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        int result = 0;
+        int constant = 123;
+        while (state.keepRunning()) {
+            result += constant;
+        }
+        return result;
+    }
+    @Test
+    public long timeAddConstantToLocalLong() {
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        long result = 0;
+        while (state.keepRunning()) {
+            result += 123L;
+        }
+        return result;
+    }
+    @Test
+    public long timeAddTwoLocalLongs() {
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        long result = 0;
+        long constant = 123L;
+        while (state.keepRunning()) {
+            result += constant;
+        }
+        return result;
+    }
+    @Test
+    public float timeAddConstantToLocalFloat() {
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        float result = 0.0f;
+        while (state.keepRunning()) {
+            result += 123.0f;
+        }
+        return result;
+    }
+    @Test
+    public float timeAddTwoLocalFloats() {
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        float result = 0.0f;
+        float constant = 123.0f;
+        while (state.keepRunning()) {
+            result += constant;
+        }
+        return result;
+    }
+    @Test
+    public double timeAddConstantToLocalDouble() {
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        double result = 0.0;
+        while (state.keepRunning()) {
+            result += 123.0;
+        }
+        return result;
+    }
+    @Test
+    public double timeAddTwoLocalDoubles() {
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        double result = 0.0;
+        double constant = 123.0;
+        while (state.keepRunning()) {
+            result += constant;
+        }
+        return result;
+    }
+}
diff --git a/apct-tests/perftests/core/src/android/libcore/ArrayCopyPerfTest.java b/apct-tests/perftests/core/src/android/libcore/ArrayCopyPerfTest.java
new file mode 100644
index 0000000..97ab6c7
--- /dev/null
+++ b/apct-tests/perftests/core/src/android/libcore/ArrayCopyPerfTest.java
@@ -0,0 +1,77 @@
+/*
+ * Copyright (C) 2016 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.libcore;
+
+import android.perftests.utils.BenchmarkState;
+import android.perftests.utils.PerfStatusReporter;
+import android.test.suitebuilder.annotation.LargeTest;
+
+import androidx.test.runner.AndroidJUnit4;
+
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.util.Arrays;
+
+@RunWith(AndroidJUnit4.class)
+@LargeTest
+public class ArrayCopyPerfTest {
+
+    @Rule
+    public PerfStatusReporter mPerfStatusReporter = new PerfStatusReporter();
+
+    @Test
+    public void timeManualArrayCopy() {
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        char[] src = new char[8192];
+        while (state.keepRunning()) {
+            char[] dst = new char[8192];
+            for (int i = 0; i < 8192; ++i) {
+                dst[i] = src[i];
+            }
+        }
+    }
+
+    @Test
+    public void time_System_arrayCopy() {
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        char[] src = new char[8192];
+        while (state.keepRunning()) {
+            char[] dst = new char[8192];
+            System.arraycopy(src, 0, dst, 0, 8192);
+        }
+    }
+
+    @Test
+    public void time_Arrays_copyOf() {
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        char[] src = new char[8192];
+        while (state.keepRunning()) {
+            char[] dst = Arrays.copyOf(src, 8192);
+        }
+    }
+
+    @Test
+    public void time_Arrays_copyOfRange() {
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        char[] src = new char[8192];
+        while (state.keepRunning()) {
+            char[] dst = Arrays.copyOfRange(src, 0, 8192);
+        }
+    }
+}
diff --git a/apct-tests/perftests/core/src/android/libcore/ArrayIterationPerfTest.java b/apct-tests/perftests/core/src/android/libcore/ArrayIterationPerfTest.java
new file mode 100644
index 0000000..bb452d3
--- /dev/null
+++ b/apct-tests/perftests/core/src/android/libcore/ArrayIterationPerfTest.java
@@ -0,0 +1,80 @@
+/*
+ * Copyright (C) 2016 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.libcore;
+
+import android.perftests.utils.BenchmarkState;
+import android.perftests.utils.PerfStatusReporter;
+import android.test.suitebuilder.annotation.LargeTest;
+
+import androidx.test.runner.AndroidJUnit4;
+
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+/**
+ * How do various ways of iterating through an array compare?
+ */
+@RunWith(AndroidJUnit4.class)
+@LargeTest
+public class ArrayIterationPerfTest {
+
+    public class Foo {
+        int mSplat;
+    }
+
+    @Rule
+    public PerfStatusReporter mPerfStatusReporter = new PerfStatusReporter();
+
+    Foo[] mArray = new Foo[27];
+    {
+        for (int i = 0; i < mArray.length; ++i) mArray[i] = new Foo();
+    }
+    @Test
+    public void timeArrayIteration() {
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            int sum = 0;
+            for (int i = 0; i < mArray.length; i++) {
+                sum += mArray[i].mSplat;
+            }
+        }
+    }
+    @Test
+    public void timeArrayIterationCached() {
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            int sum = 0;
+            Foo[] localArray = mArray;
+            int len = localArray.length;
+
+            for (int i = 0; i < len; i++) {
+                sum += localArray[i].mSplat;
+            }
+        }
+    }
+    @Test
+    public void timeArrayIterationForEach() {
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            int sum = 0;
+            for (Foo a: mArray) {
+                sum += a.mSplat;
+            }
+        }
+    }
+}
diff --git a/apct-tests/perftests/core/src/android/libcore/ArrayListIterationPerfTest.java b/apct-tests/perftests/core/src/android/libcore/ArrayListIterationPerfTest.java
new file mode 100644
index 0000000..ff6d46f
--- /dev/null
+++ b/apct-tests/perftests/core/src/android/libcore/ArrayListIterationPerfTest.java
@@ -0,0 +1,70 @@
+/*
+ * Copyright (C) 2016 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.libcore;
+
+import android.perftests.utils.BenchmarkState;
+import android.perftests.utils.PerfStatusReporter;
+import android.test.suitebuilder.annotation.LargeTest;
+
+import androidx.test.runner.AndroidJUnit4;
+
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.util.ArrayList;
+
+/**
+ * Is a hand-coded counted loop through an ArrayList cheaper than enhanced for?
+ */
+@RunWith(AndroidJUnit4.class)
+@LargeTest
+public class ArrayListIterationPerfTest {
+
+    public class Foo {
+        int mSplat;
+    }
+    @Rule
+    public PerfStatusReporter mPerfStatusReporter = new PerfStatusReporter();
+
+    ArrayList<Foo> mList = new ArrayList<Foo>();
+    {
+        for (int i = 0; i < 27; ++i) mList.add(new Foo());
+    }
+    @Test
+    public void timeArrayListIterationIndexed() {
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            int sum = 0;
+            ArrayList<Foo> list = mList;
+            int len = list.size();
+            for (int i = 0; i < len; ++i) {
+                sum += list.get(i).mSplat;
+            }
+        }
+    }
+    @Test
+    public void timeArrayListIterationForEach() {
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            int sum = 0;
+            for (Foo a : mList) {
+                sum += a.mSplat;
+            }
+        }
+    }
+}
diff --git a/apct-tests/perftests/core/src/android/libcore/OWNERS b/apct-tests/perftests/core/src/android/libcore/OWNERS
new file mode 100644
index 0000000..2d36574
--- /dev/null
+++ b/apct-tests/perftests/core/src/android/libcore/OWNERS
@@ -0,0 +1,2 @@
+# Bug component: 24949
+include platform/libcore:/OWNERS
diff --git a/core/api/test-current.txt b/core/api/test-current.txt
index 6b588f9..59db4d6 100644
--- a/core/api/test-current.txt
+++ b/core/api/test-current.txt
@@ -34,6 +34,7 @@
     field public static final String READ_PRIVILEGED_PHONE_STATE = "android.permission.READ_PRIVILEGED_PHONE_STATE";
     field public static final String RECORD_BACKGROUND_AUDIO = "android.permission.RECORD_BACKGROUND_AUDIO";
     field public static final String REMOVE_TASKS = "android.permission.REMOVE_TASKS";
+    field public static final String REQUEST_UNIQUE_ID_ATTESTATION = "android.permission.REQUEST_UNIQUE_ID_ATTESTATION";
     field public static final String RESET_APP_ERRORS = "android.permission.RESET_APP_ERRORS";
     field public static final String SET_AND_VERIFY_LOCKSCREEN_CREDENTIALS = "android.permission.SET_AND_VERIFY_LOCKSCREEN_CREDENTIALS";
     field public static final String START_TASKS_FROM_RECENTS = "android.permission.START_TASKS_FROM_RECENTS";
diff --git a/core/java/android/content/res/Configuration.java b/core/java/android/content/res/Configuration.java
index 755114e..bd6fcd8 100644
--- a/core/java/android/content/res/Configuration.java
+++ b/core/java/android/content/res/Configuration.java
@@ -751,11 +751,25 @@
     public static final int SCREEN_WIDTH_DP_UNDEFINED = 0;
 
     /**
-     * The current width of the available screen space, in dp units,
-     * corresponding to
-     * <a href="{@docRoot}guide/topics/resources/providing-resources.html#ScreenWidthQualifier">screen
-     * width</a> resource qualifier.  Set to
+     * The current width of the available screen space in dp units, excluding
+     * the area occupied by screen decorations at the edges of the display.
+     * Corresponds to the
+     * <a href="{@docRoot}guide/topics/resources/providing-resources.html#AvailableWidthHeightQualifier">
+     * available width</a> resource qualifier. Defaults to
      * {@link #SCREEN_WIDTH_DP_UNDEFINED} if no width is specified.
+     *
+     * <p>In multi-window mode, equals the width of the available display area
+     * of the app window, not the available display area of the device screen
+     * (for example, when apps are displayed side by side in split-screen mode
+     * in landscape orientation).
+     *
+     * <p>Differs from {@link android.view.WindowMetrics} by not including
+     * screen decorations in the width measurement and by expressing the
+     * measurement in dp rather than px. Use {@code screenWidthDp} to obtain the
+     * horizontal display area available to the app, excluding the area occupied
+     * by screen decorations. Use {@link android.view.WindowMetrics#getBounds()}
+     * to obtain the width of the display area available to the app, including
+     * the area occupied by screen decorations.
      */
     public int screenWidthDp;
 
@@ -766,11 +780,26 @@
     public static final int SCREEN_HEIGHT_DP_UNDEFINED = 0;
 
     /**
-     * The current height of the available screen space, in dp units,
-     * corresponding to
-     * <a href="{@docRoot}guide/topics/resources/providing-resources.html#ScreenHeightQualifier">screen
-     * height</a> resource qualifier.  Set to
+     * The current height of the available screen space in dp units, excluding
+     * the area occupied by screen decorations at the edges of the display (such
+     * as the status bar, navigation bar, and cutouts). Corresponds to the
+     * <a href="{@docRoot}guide/topics/resources/providing-resources.html#AvailableWidthHeightQualifier">
+     * available height</a> resource qualifier. Defaults to
      * {@link #SCREEN_HEIGHT_DP_UNDEFINED} if no height is specified.
+     *
+     * <p>In multi-window mode, equals the height of the available display area
+     * of the app window, not the available display area of the device screen
+     * (for example, when apps are displayed one above another in split-screen
+     * mode in portrait orientation).
+     *
+     * <p>Differs from {@link android.view.WindowMetrics} by not including
+     * screen decorations in the height measurement and by expressing the
+     * measurement in dp rather than px. Use {@code screenHeightDp} to obtain
+     * the vertical display area available to the app, excluding the area
+     * occupied by screen decorations. Use
+     * {@link android.view.WindowMetrics#getBounds()} to obtain the height of
+     * the display area available to the app, including the area occupied by
+     * screen decorations.
      */
     public int screenHeightDp;
 
diff --git a/core/java/android/net/Ikev2VpnProfile.java b/core/java/android/net/Ikev2VpnProfile.java
index 3abe83b..1b503b1 100644
--- a/core/java/android/net/Ikev2VpnProfile.java
+++ b/core/java/android/net/Ikev2VpnProfile.java
@@ -25,12 +25,6 @@
 import static android.net.IpSecAlgorithm.AUTH_HMAC_SHA512;
 import static android.net.IpSecAlgorithm.CRYPT_AES_CBC;
 import static android.net.IpSecAlgorithm.CRYPT_AES_CTR;
-import static android.net.eap.EapSessionConfig.EapMsChapV2Config;
-import static android.net.ipsec.ike.IkeSessionParams.IkeAuthConfig;
-import static android.net.ipsec.ike.IkeSessionParams.IkeAuthDigitalSignLocalConfig;
-import static android.net.ipsec.ike.IkeSessionParams.IkeAuthDigitalSignRemoteConfig;
-import static android.net.ipsec.ike.IkeSessionParams.IkeAuthEapConfig;
-import static android.net.ipsec.ike.IkeSessionParams.IkeAuthPskConfig;
 
 import static com.android.internal.annotations.VisibleForTesting.Visibility;
 import static com.android.internal.util.Preconditions.checkStringNotEmpty;
@@ -40,6 +34,7 @@
 import android.annotation.Nullable;
 import android.annotation.RequiresFeature;
 import android.content.pm.PackageManager;
+import android.net.ipsec.ike.IkeDerAsn1DnIdentification;
 import android.net.ipsec.ike.IkeFqdnIdentification;
 import android.net.ipsec.ike.IkeIdentification;
 import android.net.ipsec.ike.IkeIpv4AddrIdentification;
@@ -119,8 +114,8 @@
         DEFAULT_ALGORITHMS = Collections.unmodifiableList(algorithms);
     }
 
-    @NonNull private final String mServerAddr;
-    @NonNull private final String mUserIdentity;
+    @Nullable private final String mServerAddr;
+    @Nullable private final String mUserIdentity;
 
     // PSK authentication
     @Nullable private final byte[] mPresharedKey;
@@ -146,8 +141,8 @@
 
     private Ikev2VpnProfile(
             int type,
-            @NonNull String serverAddr,
-            @NonNull String userIdentity,
+            @Nullable String serverAddr,
+            @Nullable String userIdentity,
             @Nullable byte[] presharedKey,
             @Nullable X509Certificate serverRootCaCert,
             @Nullable String username,
@@ -165,8 +160,6 @@
             @Nullable IkeTunnelConnectionParams ikeTunConnParams) {
         super(type, excludeLocalRoutes, requiresInternetValidation);
 
-        checkNotNull(serverAddr, MISSING_PARAM_MSG_TMPL, "Server address");
-        checkNotNull(userIdentity, MISSING_PARAM_MSG_TMPL, "User Identity");
         checkNotNull(allowedAlgorithms, MISSING_PARAM_MSG_TMPL, "Allowed Algorithms");
 
         mServerAddr = serverAddr;
@@ -191,18 +184,12 @@
         mIsMetered = isMetered;
         mMaxMtu = maxMtu;
         mIsRestrictedToTestNetworks = restrictToTestNetworks;
-
         mIkeTunConnParams = ikeTunConnParams;
 
         validate();
     }
 
     private void validate() {
-        // Server Address not validated except to check an address was provided. This allows for
-        // dual-stack servers and hostname based addresses.
-        checkStringNotEmpty(mServerAddr, MISSING_PARAM_MSG_TMPL, "Server Address");
-        checkStringNotEmpty(mUserIdentity, MISSING_PARAM_MSG_TMPL, "User Identity");
-
         // IPv6 MTU is greater; since profiles may be started by the system on IPv4 and IPv6
         // networks, the VPN must provide a link fulfilling the stricter of the two conditions
         // (at least that of the IPv6 MTU).
@@ -210,6 +197,15 @@
             throw new IllegalArgumentException("Max MTU must be at least" + IPV6_MIN_MTU);
         }
 
+        // Skip validating the other fields if mIkeTunConnParams is set because the required
+        // information should all come from the mIkeTunConnParams.
+        if (mIkeTunConnParams != null) return;
+
+        // Server Address not validated except to check an address was provided. This allows for
+        // dual-stack servers and hostname based addresses.
+        checkStringNotEmpty(mServerAddr, MISSING_PARAM_MSG_TMPL, "Server Address");
+        checkStringNotEmpty(mUserIdentity, MISSING_PARAM_MSG_TMPL, "User Identity");
+
         switch (mType) {
             case TYPE_IKEV2_IPSEC_USER_PASS:
                 checkNotNull(mUsername, MISSING_PARAM_MSG_TMPL, "Username");
@@ -286,22 +282,31 @@
     /** Retrieves the server address string. */
     @NonNull
     public String getServerAddr() {
-        return mServerAddr;
+        if (mIkeTunConnParams == null) return mServerAddr;
+
+        final IkeSessionParams ikeSessionParams = mIkeTunConnParams.getIkeSessionParams();
+        return ikeSessionParams.getServerHostname();
     }
 
     /** Retrieves the user identity. */
     @NonNull
     public String getUserIdentity() {
-        return mUserIdentity;
+        if (mIkeTunConnParams == null) return mUserIdentity;
+
+        final IkeSessionParams ikeSessionParams = mIkeTunConnParams.getIkeSessionParams();
+        return getUserIdentityFromIkeSession(ikeSessionParams);
     }
 
     /**
      * Retrieves the pre-shared key.
      *
-     * <p>May be null if the profile is not using Pre-shared key authentication.
+     * <p>May be null if the profile is not using Pre-shared key authentication, or the profile is
+     * built from an {@link IkeTunnelConnectionParams}.
      */
     @Nullable
     public byte[] getPresharedKey() {
+        if (mIkeTunConnParams != null) return null;
+
         return mPresharedKey == null ? null : Arrays.copyOf(mPresharedKey, mPresharedKey.length);
     }
 
@@ -309,46 +314,62 @@
      * Retrieves the certificate for the server's root CA.
      *
      * <p>May be null if the profile is not using RSA Digital Signature Authentication or
-     * Username/Password authentication
+     * Username/Password authentication, or the profile is built from an
+     * {@link IkeTunnelConnectionParams}.
      */
     @Nullable
     public X509Certificate getServerRootCaCert() {
+        if (mIkeTunConnParams != null) return null;
+
         return mServerRootCaCert;
     }
-
     /**
      * Retrieves the username.
      *
-     * <p>May be null if the profile is not using Username/Password authentication
+     * <p>May be null if the profile is not using Username/Password authentication, or the profile
+     * is built from an {@link IkeTunnelConnectionParams}.
      */
     @Nullable
     public String getUsername() {
+        if (mIkeTunConnParams != null) return null;
+
         return mUsername;
     }
 
     /**
      * Retrieves the password.
      *
-     * <p>May be null if the profile is not using Username/Password authentication
+     * <p>May be null if the profile is not using Username/Password authentication, or the profile
+     * is built from an {@link IkeTunnelConnectionParams}.
      */
     @Nullable
     public String getPassword() {
+        if (mIkeTunConnParams != null) return null;
+
         return mPassword;
     }
 
     /**
      * Retrieves the RSA private key.
      *
-     * <p>May be null if the profile is not using RSA Digital Signature authentication
+     * <p>May be null if the profile is not using RSA Digital Signature authentication, or the
+     * profile is built from an {@link IkeTunnelConnectionParams}.
      */
     @Nullable
     public PrivateKey getRsaPrivateKey() {
+        if (mIkeTunConnParams != null) return null;
+
         return mRsaPrivateKey;
     }
 
-    /** Retrieves the user certificate, if any was set. */
+    /** Retrieves the user certificate, if any was set.
+     *
+     * <p>May be null if the profile is built from an {@link IkeTunnelConnectionParams}.
+     */
     @Nullable
     public X509Certificate getUserCert() {
+        if (mIkeTunConnParams != null) return null;
+
         return mUserCert;
     }
 
@@ -358,9 +379,14 @@
         return mProxyInfo;
     }
 
-    /** Returns all the algorithms allowed by this VPN profile. */
+    /** Returns all the algorithms allowed by this VPN profile.
+     *
+     *  <p>May be an empty list if the profile is built from an {@link IkeTunnelConnectionParams}.
+     */
     @NonNull
     public List<String> getAllowedAlgorithms() {
+        if (mIkeTunConnParams != null) return new ArrayList<>();
+
         return mAllowedAlgorithms;
     }
 
@@ -455,18 +481,25 @@
     @NonNull
     public VpnProfile toVpnProfile() throws IOException, GeneralSecurityException {
         final VpnProfile profile = new VpnProfile("" /* Key; value unused by IKEv2VpnProfile(s) */,
-                mIsRestrictedToTestNetworks, mExcludeLocalRoutes, mRequiresInternetValidation);
-        profile.type = mType;
-        profile.server = mServerAddr;
-        profile.ipsecIdentifier = mUserIdentity;
+                mIsRestrictedToTestNetworks, mExcludeLocalRoutes, mRequiresInternetValidation,
+                mIkeTunConnParams);
+
+        profile.server = getServerAddr();
+        profile.ipsecIdentifier = getUserIdentity();
         profile.proxy = mProxyInfo;
-        profile.setAllowedAlgorithms(mAllowedAlgorithms);
         profile.isBypassable = mIsBypassable;
         profile.isMetered = mIsMetered;
         profile.maxMtu = mMaxMtu;
         profile.areAuthParamsInline = true;
         profile.saveLogin = true;
+        // The other fields should come from mIkeTunConnParams if it's available.
+        if (mIkeTunConnParams != null) {
+            profile.type = VpnProfile.TYPE_IKEV2_FROM_IKE_TUN_CONN_PARAMS;
+            return profile;
+        }
 
+        profile.type = mType;
+        profile.setAllowedAlgorithms(mAllowedAlgorithms);
         switch (mType) {
             case TYPE_IKEV2_IPSEC_USER_PASS:
                 profile.username = mUsername;
@@ -516,10 +549,47 @@
     @NonNull
     public static Ikev2VpnProfile fromVpnProfile(@NonNull VpnProfile profile)
             throws GeneralSecurityException {
-        // TODO: Build the VpnProfile from mIkeTunConnParams if it exists.
-        final Builder builder = new Builder(profile.server, profile.ipsecIdentifier);
+        final Builder builder;
+        if (profile.ikeTunConnParams == null) {
+            builder = new Builder(profile.server, profile.ipsecIdentifier);
+            builder.setAllowedAlgorithms(profile.getAllowedAlgorithms());
+
+            switch (profile.type) {
+                case TYPE_IKEV2_IPSEC_USER_PASS:
+                    builder.setAuthUsernamePassword(
+                            profile.username,
+                            profile.password,
+                            certificateFromPemString(profile.ipsecCaCert));
+                    break;
+                case TYPE_IKEV2_IPSEC_PSK:
+                    builder.setAuthPsk(decodeFromIpsecSecret(profile.ipsecSecret));
+                    break;
+                case TYPE_IKEV2_IPSEC_RSA:
+                    final PrivateKey key;
+                    if (profile.ipsecSecret.startsWith(PREFIX_KEYSTORE_ALIAS)) {
+                        final String alias =
+                                profile.ipsecSecret.substring(PREFIX_KEYSTORE_ALIAS.length());
+                        key = getPrivateKeyFromAndroidKeystore(alias);
+                    } else if (profile.ipsecSecret.startsWith(PREFIX_INLINE)) {
+                        key = getPrivateKey(profile.ipsecSecret.substring(PREFIX_INLINE.length()));
+                    } else {
+                        throw new IllegalArgumentException("Invalid RSA private key prefix");
+                    }
+
+                    final X509Certificate userCert =
+                            certificateFromPemString(profile.ipsecUserCert);
+                    final X509Certificate serverRootCa =
+                            certificateFromPemString(profile.ipsecCaCert);
+                    builder.setAuthDigitalSignature(userCert, key, serverRootCa);
+                    break;
+                default:
+                    throw new IllegalArgumentException("Invalid auth method set");
+            }
+        } else {
+            builder = new Builder(profile.ikeTunConnParams);
+        }
+
         builder.setProxy(profile.proxy);
-        builder.setAllowedAlgorithms(profile.getAllowedAlgorithms());
         builder.setBypassable(profile.isBypassable);
         builder.setMetered(profile.isMetered);
         builder.setMaxMtu(profile.maxMtu);
@@ -527,36 +597,6 @@
             builder.restrictToTestNetworks();
         }
 
-        switch (profile.type) {
-            case TYPE_IKEV2_IPSEC_USER_PASS:
-                builder.setAuthUsernamePassword(
-                        profile.username,
-                        profile.password,
-                        certificateFromPemString(profile.ipsecCaCert));
-                break;
-            case TYPE_IKEV2_IPSEC_PSK:
-                builder.setAuthPsk(decodeFromIpsecSecret(profile.ipsecSecret));
-                break;
-            case TYPE_IKEV2_IPSEC_RSA:
-                final PrivateKey key;
-                if (profile.ipsecSecret.startsWith(PREFIX_KEYSTORE_ALIAS)) {
-                    final String alias =
-                            profile.ipsecSecret.substring(PREFIX_KEYSTORE_ALIAS.length());
-                    key = getPrivateKeyFromAndroidKeystore(alias);
-                } else if (profile.ipsecSecret.startsWith(PREFIX_INLINE)) {
-                    key = getPrivateKey(profile.ipsecSecret.substring(PREFIX_INLINE.length()));
-                } else {
-                    throw new IllegalArgumentException("Invalid RSA private key prefix");
-                }
-
-                final X509Certificate userCert = certificateFromPemString(profile.ipsecUserCert);
-                final X509Certificate serverRootCa = certificateFromPemString(profile.ipsecCaCert);
-                builder.setAuthDigitalSignature(userCert, key, serverRootCa);
-                break;
-            default:
-                throw new IllegalArgumentException("Invalid auth method set");
-        }
-
         if (profile.excludeLocalRoutes && !profile.isBypassable) {
             Log.w(TAG, "ExcludeLocalRoutes should only be set in the bypassable VPN");
         }
@@ -678,82 +718,13 @@
     }
 
     private static void checkBuilderSetter(boolean constructedFromIkeTunConParams,
-            @NonNull String message) {
+            @NonNull String field) {
         if (constructedFromIkeTunConParams) {
-            throw new IllegalArgumentException("Constructed using IkeTunnelConnectionParams "
-                    + "should not set " + message);
+            throw new IllegalArgumentException(
+                    field + " can't be set with IkeTunnelConnectionParams builder");
         }
     }
 
-    private static int getTypeFromIkeSession(@NonNull IkeSessionParams params) {
-        final IkeAuthConfig config = params.getLocalAuthConfig();
-        if (config instanceof IkeAuthDigitalSignLocalConfig) {
-            return TYPE_IKEV2_IPSEC_RSA;
-        } else if (config instanceof IkeAuthEapConfig) {
-            return TYPE_IKEV2_IPSEC_USER_PASS;
-        } else if (config instanceof IkeAuthPskConfig) {
-            return TYPE_IKEV2_IPSEC_PSK;
-        } else {
-            throw new IllegalStateException("Invalid local IkeAuthConfig");
-        }
-    }
-
-    @Nullable
-    private static String getPasswordFromIkeSession(@NonNull IkeSessionParams params) {
-        if (!(params.getLocalAuthConfig() instanceof IkeAuthEapConfig)) return null;
-
-        final IkeAuthEapConfig ikeAuthEapConfig = (IkeAuthEapConfig) params.getLocalAuthConfig();
-        final EapMsChapV2Config eapMsChapV2Config =
-                ikeAuthEapConfig.getEapConfig().getEapMsChapV2Config();
-        return (eapMsChapV2Config != null) ? eapMsChapV2Config.getPassword() : null;
-    }
-
-    @Nullable
-    private static String getUsernameFromIkeSession(@NonNull IkeSessionParams params) {
-        if (!(params.getLocalAuthConfig() instanceof IkeAuthEapConfig)) return null;
-
-        final IkeAuthEapConfig ikeAuthEapConfig = (IkeAuthEapConfig) params.getLocalAuthConfig();
-        final EapMsChapV2Config eapMsChapV2Config =
-                ikeAuthEapConfig.getEapConfig().getEapMsChapV2Config();
-        return (eapMsChapV2Config != null) ? eapMsChapV2Config.getUsername() : null;
-    }
-
-    @Nullable
-    private static X509Certificate getUserCertFromIkeSession(@NonNull IkeSessionParams params) {
-        if (!(params.getLocalAuthConfig() instanceof IkeAuthDigitalSignLocalConfig)) return null;
-
-        final IkeAuthDigitalSignLocalConfig config =
-                (IkeAuthDigitalSignLocalConfig) params.getLocalAuthConfig();
-        return config.getClientEndCertificate();
-    }
-
-    @Nullable
-    private static X509Certificate getServerRootCaCertFromIkeSession(
-            @NonNull IkeSessionParams params) {
-        if (!(params.getRemoteAuthConfig() instanceof IkeAuthDigitalSignRemoteConfig)) return null;
-
-        final IkeAuthDigitalSignRemoteConfig config =
-                (IkeAuthDigitalSignRemoteConfig) params.getRemoteAuthConfig();
-        return config.getRemoteCaCert();
-    }
-
-    @Nullable
-    private static PrivateKey getRsaPrivateKeyFromIkeSession(@NonNull IkeSessionParams params) {
-        if (!(params.getLocalAuthConfig() instanceof IkeAuthDigitalSignLocalConfig)) return null;
-
-        final IkeAuthDigitalSignLocalConfig config =
-                (IkeAuthDigitalSignLocalConfig) params.getLocalAuthConfig();
-        return config.getPrivateKey();
-    }
-
-    @Nullable
-    private static byte[] getPresharedKeyFromIkeSession(@NonNull IkeSessionParams params) {
-        if (!(params.getLocalAuthConfig() instanceof IkeAuthPskConfig)) return null;
-
-        final IkeAuthPskConfig config = (IkeAuthPskConfig) params.getLocalAuthConfig();
-        return config.getPsk();
-    }
-
     @NonNull
     private static String getUserIdentityFromIkeSession(@NonNull IkeSessionParams params) {
         final IkeIdentification ident = params.getLocalIdentification();
@@ -768,6 +739,8 @@
             return ((IkeIpv4AddrIdentification) ident).ipv4Address.getHostAddress();
         } else if (ident instanceof IkeIpv6AddrIdentification) {
             return ((IkeIpv6AddrIdentification) ident).ipv6Address.getHostAddress();
+        } else if (ident instanceof IkeDerAsn1DnIdentification) {
+            throw new IllegalArgumentException("Unspported ASN.1 encoded identities");
         } else {
             throw new IllegalArgumentException("Unknown IkeIdentification to get user identity");
         }
@@ -776,8 +749,8 @@
     /** A incremental builder for IKEv2 VPN profiles */
     public static final class Builder {
         private int mType = -1;
-        @NonNull private final String mServerAddr;
-        @NonNull private final String mUserIdentity;
+        @Nullable private final String mServerAddr;
+        @Nullable private final String mUserIdentity;
 
         // PSK authentication
         @Nullable private byte[] mPresharedKey;
@@ -831,19 +804,8 @@
             checkNotNull(ikeTunConnParams, MISSING_PARAM_MSG_TMPL, "ikeTunConnParams");
 
             mIkeTunConnParams = ikeTunConnParams;
-
-            final IkeSessionParams ikeSessionParams = mIkeTunConnParams.getIkeSessionParams();
-            mServerAddr = ikeSessionParams.getServerHostname();
-
-            mType = getTypeFromIkeSession(ikeSessionParams);
-            mUserCert = getUserCertFromIkeSession(ikeSessionParams);
-            mServerRootCaCert = getServerRootCaCertFromIkeSession(ikeSessionParams);
-            mRsaPrivateKey = getRsaPrivateKeyFromIkeSession(ikeSessionParams);
-            mServerRootCaCert = getServerRootCaCertFromIkeSession(ikeSessionParams);
-            mUsername = getUsernameFromIkeSession(ikeSessionParams);
-            mPassword = getPasswordFromIkeSession(ikeSessionParams);
-            mPresharedKey = getPresharedKeyFromIkeSession(ikeSessionParams);
-            mUserIdentity = getUserIdentityFromIkeSession(ikeSessionParams);
+            mServerAddr = null;
+            mUserIdentity = null;
         }
 
         private void resetAuthParams() {
@@ -862,6 +824,10 @@
          * authentication method may be set. This method will overwrite any previously set
          * authentication method.
          *
+         * <p>It's not allowed to set this if this {@link Builder} is constructed from an
+         * {@link IkeTunnelConnectionParams}. This information should be retrieved from
+         * {@link IkeTunnelConnectionParams}
+         *
          * @param user the username to be used for EAP-MSCHAPv2 authentication
          * @param pass the password to be used for EAP-MSCHAPv2 authentication
          * @param serverRootCa the root certificate to be used for verifying the identity of the
@@ -898,6 +864,10 @@
          * Only one authentication method may be set. This method will overwrite any previously set
          * authentication method.
          *
+         * <p>It's not allowed to set this if this {@link Builder} is constructed from an
+         * {@link IkeTunnelConnectionParams}. This information should be retrieved from
+         * {@link IkeTunnelConnectionParams}
+         *
          * @param userCert the username to be used for RSA Digital signiture authentication
          * @param key the PrivateKey instance associated with the user ceritificate, used for
          *     constructing the signature
@@ -936,6 +906,10 @@
          * authentication method may be set. This method will overwrite any previously set
          * authentication method.
          *
+         * <p>It's not allowed to set this if this {@link Builder} is constructed from an
+         * {@link IkeTunnelConnectionParams}. This information should be retrieved from
+         * {@link IkeTunnelConnectionParams}
+         *
          * @param psk the key to be used for Pre-Shared Key authentication
          * @return this {@link Builder} object to facilitate chaining of method calls
          */
@@ -1068,6 +1042,10 @@
          * Authentication, and one that provides Encryption. Authenticated Encryption with
          * Associated Data (AEAD) algorithms provide both Authentication and Encryption.
          *
+         * <p>It's not allowed to set this if this {@link Builder} is constructed from an
+         * {@link IkeTunnelConnectionParams}. This information should be retrieved from
+         * {@link IkeTunnelConnectionParams}
+         *
          * <p>By default, this profile will use any algorithm defined in {@link IpSecAlgorithm},
          * with the exception of those considered insecure (as described above).
          *
@@ -1079,6 +1057,7 @@
         @RequiresFeature(PackageManager.FEATURE_IPSEC_TUNNELS)
         public Builder setAllowedAlgorithms(@NonNull List<String> algorithmNames) {
             checkNotNull(algorithmNames, MISSING_PARAM_MSG_TMPL, "algorithmNames");
+            checkBuilderSetter(mIkeTunConnParams != null, "algorithmNames");
             validateAllowedAlgorithms(algorithmNames);
 
             mAllowedAlgorithms = algorithmNames;
diff --git a/core/java/android/net/TEST_MAPPING b/core/java/android/net/TEST_MAPPING
index a379c33..3df5616 100644
--- a/core/java/android/net/TEST_MAPPING
+++ b/core/java/android/net/TEST_MAPPING
@@ -17,7 +17,7 @@
       "path": "frameworks/opt/net/wifi"
     }
   ],
-  "postsubmit": [
+  "presubmit": [
     {
       "name": "FrameworksCoreTests",
       "options": [
diff --git a/core/java/android/provider/DeviceConfig.java b/core/java/android/provider/DeviceConfig.java
index 1777f56..4c1cc97 100644
--- a/core/java/android/provider/DeviceConfig.java
+++ b/core/java/android/provider/DeviceConfig.java
@@ -829,7 +829,8 @@
      * @param name        The name of the property to create or update.
      * @param value       The value to store for the property.
      * @param makeDefault Whether to make the new value the default one.
-     * @return True if the value was set, false if the storage implementation throws errors.
+     * @return {@code true} if the value was set, {@code false} if the storage implementation throws
+     * errors.
      * @hide
      * @see #resetToDefaults(int, String).
      */
@@ -853,7 +854,7 @@
      *
      * @param properties the complete set of properties to set for a specific namespace.
      * @throws BadConfigException if the provided properties are banned by RescueParty.
-     * @return True if the values were set, false otherwise.
+     * @return {@code true} if the values were set, {@code false} otherwise.
      * @hide
      */
     @SystemApi
@@ -869,8 +870,8 @@
      *
      * @param namespace   The namespace containing the property to delete.
      * @param name        The name of the property to delete.
-     * @return True if the property was deleted or it did not exist in the first place.
-     * False if the storage implementation throws errors.
+     * @return {@code true} if the property was deleted or it did not exist in the first place.
+     * Return {@code false} if the storage implementation throws errors.
      * @hide
      */
     @SystemApi
diff --git a/core/java/android/util/NtpTrustedTime.java b/core/java/android/util/NtpTrustedTime.java
index 01a037a..4e7b3a5 100644
--- a/core/java/android/util/NtpTrustedTime.java
+++ b/core/java/android/util/NtpTrustedTime.java
@@ -193,6 +193,16 @@
             }
             final Network network = connectivityManager.getActiveNetwork();
             final NetworkInfo ni = connectivityManager.getNetworkInfo(network);
+
+            // This connectivity check is to avoid performing a DNS lookup for the time server on a
+            // unconnected network. There are races to obtain time in Android when connectivity
+            // changes, which means that forceRefresh() can be called by various components before
+            // the network is actually available. This led in the past to DNS lookup failures being
+            // cached (~2 seconds) thereby preventing the device successfully making an NTP request
+            // when connectivity had actually been established.
+            // A side effect of check is that tests that run a fake NTP server on the device itself
+            // will only be able to use it if the active network is connected, even though loopback
+            // addresses are actually reachable.
             if (ni == null || !ni.isConnected()) {
                 if (LOGD) Log.d(TAG, "forceRefresh: no connectivity");
                 return false;
diff --git a/core/java/com/android/internal/net/VpnProfile.java b/core/java/com/android/internal/net/VpnProfile.java
index bd3e898..8797381 100644
--- a/core/java/com/android/internal/net/VpnProfile.java
+++ b/core/java/com/android/internal/net/VpnProfile.java
@@ -22,12 +22,17 @@
 import android.net.PlatformVpnProfile;
 import android.net.ProxyInfo;
 import android.net.Uri;
+import android.net.ipsec.ike.IkeTunnelConnectionParams;
+import android.net.vcn.persistablebundleutils.TunnelConnectionParamsUtils;
 import android.os.Build;
 import android.os.Parcel;
 import android.os.Parcelable;
+import android.os.PersistableBundle;
 import android.text.TextUtils;
+import android.util.Log;
 
 import com.android.internal.annotations.VisibleForTesting;
+import com.android.internal.util.HexDump;
 import com.android.net.module.util.ProxyUtils;
 
 import java.io.UnsupportedEncodingException;
@@ -69,7 +74,8 @@
     public static final int TYPE_IKEV2_IPSEC_USER_PASS = 6;
     public static final int TYPE_IKEV2_IPSEC_PSK = 7;
     public static final int TYPE_IKEV2_IPSEC_RSA = 8;
-    public static final int TYPE_MAX = 8;
+    public static final int TYPE_IKEV2_FROM_IKE_TUN_CONN_PARAMS = 9;
+    public static final int TYPE_MAX = 9;
 
     // Match these constants with R.array.vpn_proxy_settings.
     public static final int PROXY_NONE = 0;
@@ -145,25 +151,27 @@
 
     public final boolean excludeLocalRoutes;                     // 25
     public final boolean requiresInternetValidation;             // 26
+    public final IkeTunnelConnectionParams ikeTunConnParams;     // 27
 
     // Helper fields.
     @UnsupportedAppUsage
     public transient boolean saveLogin = false;
 
     public VpnProfile(String key) {
-        this(key, false, false, false);
+        this(key, false, false, false, null);
     }
 
     public VpnProfile(String key, boolean isRestrictedToTestNetworks) {
-        this(key, isRestrictedToTestNetworks, false, false);
+        this(key, isRestrictedToTestNetworks, false, false, null);
     }
 
     public VpnProfile(String key, boolean isRestrictedToTestNetworks, boolean excludeLocalRoutes,
-            boolean requiresInternetValidation) {
+            boolean requiresInternetValidation, IkeTunnelConnectionParams ikeTunConnParams) {
         this.key = key;
         this.isRestrictedToTestNetworks = isRestrictedToTestNetworks;
         this.excludeLocalRoutes = excludeLocalRoutes;
         this.requiresInternetValidation = requiresInternetValidation;
+        this.ikeTunConnParams = ikeTunConnParams;
     }
 
     @UnsupportedAppUsage
@@ -195,6 +203,10 @@
         isRestrictedToTestNetworks = in.readBoolean();
         excludeLocalRoutes = in.readBoolean();
         requiresInternetValidation = in.readBoolean();
+        final PersistableBundle bundle =
+                in.readParcelable(PersistableBundle.class.getClassLoader());
+        ikeTunConnParams = (bundle == null) ? null
+                : TunnelConnectionParamsUtils.fromPersistableBundle(bundle);
     }
 
     /**
@@ -244,6 +256,8 @@
         out.writeBoolean(isRestrictedToTestNetworks);
         out.writeBoolean(excludeLocalRoutes);
         out.writeBoolean(requiresInternetValidation);
+        out.writeParcelable(ikeTunConnParams == null ? null
+                : TunnelConnectionParamsUtils.toPersistableBundle(ikeTunConnParams), flags);
     }
 
     /**
@@ -259,15 +273,17 @@
             }
 
             String[] values = new String(value, StandardCharsets.UTF_8).split(VALUE_DELIMITER, -1);
+
             // Acceptable numbers of values are:
             // 14-19: Standard profile, with option for serverCert, proxy
             // 24: Standard profile with serverCert, proxy and platform-VPN parameters
             // 25: Standard profile with platform-VPN parameters and isRestrictedToTestNetworks
             // 26:                                            ...and excludeLocalRoutes
-            //     (26 can only be found on dogfood devices)
             // 27:                                            ...and requiresInternetValidation
+            //     (26,27 can only be found on dogfood devices)
+            // 28:                                            ...and ikeTunConnParams
             if ((values.length < 14 || (values.length > 19 && values.length < 24)
-                    || values.length > 27)) {
+                    || values.length > 28)) {
                 return null;
             }
 
@@ -292,8 +308,22 @@
                 requiresInternetValidation = false;
             }
 
+            final IkeTunnelConnectionParams tempIkeTunConnParams;
+            // Assign null directly if the ikeTunConParams field is empty.
+            if (values.length >= 28 && values[27].length() != 0) {
+                final Parcel parcel = Parcel.obtain();
+                final byte[] bytes = HexDump.hexStringToByteArray(values[27]);
+                parcel.unmarshall(bytes, 0, bytes.length);
+                parcel.setDataPosition(0);
+                final PersistableBundle bundle = (PersistableBundle) parcel.readValue(
+                        PersistableBundle.class.getClassLoader());
+                tempIkeTunConnParams = TunnelConnectionParamsUtils.fromPersistableBundle(bundle);
+            } else {
+                tempIkeTunConnParams = null;
+            }
+
             VpnProfile profile = new VpnProfile(key, isRestrictedToTestNetworks,
-                    excludeLocalRoutes, requiresInternetValidation);
+                    excludeLocalRoutes, requiresInternetValidation, tempIkeTunConnParams);
             profile.name = values[0];
             profile.type = Integer.parseInt(values[1]);
             if (profile.type < 0 || profile.type > TYPE_MAX) {
@@ -345,6 +375,7 @@
             profile.saveLogin = !profile.username.isEmpty() || !profile.password.isEmpty();
             return profile;
         } catch (Exception e) {
+            Log.d(TAG, "Got exception in decode.", e);
             // ignore
         }
         return null;
@@ -406,6 +437,17 @@
         builder.append(VALUE_DELIMITER).append(excludeLocalRoutes);
         builder.append(VALUE_DELIMITER).append(requiresInternetValidation);
 
+        if (ikeTunConnParams != null) {
+            final PersistableBundle bundle =
+                    TunnelConnectionParamsUtils.toPersistableBundle(ikeTunConnParams);
+            final Parcel parcel = Parcel.obtain();
+            parcel.writeValue(bundle);
+            final byte[] bytes = parcel.marshall();
+            builder.append(VALUE_DELIMITER).append(HexDump.toHexString(bytes));
+        } else {
+            builder.append(VALUE_DELIMITER).append("");
+        }
+
         return builder.toString().getBytes(StandardCharsets.UTF_8);
     }
 
@@ -486,7 +528,8 @@
             key, type, server, username, password, dnsServers, searchDomains, routes, mppe,
             l2tpSecret, ipsecIdentifier, ipsecSecret, ipsecUserCert, ipsecCaCert, ipsecServerCert,
             proxy, mAllowedAlgorithms, isBypassable, isMetered, maxMtu, areAuthParamsInline,
-            isRestrictedToTestNetworks, excludeLocalRoutes, requiresInternetValidation);
+            isRestrictedToTestNetworks, excludeLocalRoutes, requiresInternetValidation,
+            ikeTunConnParams);
     }
 
     /** Checks VPN profiles for interior equality. */
@@ -521,7 +564,8 @@
                 && areAuthParamsInline == other.areAuthParamsInline
                 && isRestrictedToTestNetworks == other.isRestrictedToTestNetworks
                 && excludeLocalRoutes == other.excludeLocalRoutes
-                && requiresInternetValidation == other.requiresInternetValidation;
+                && requiresInternetValidation == other.requiresInternetValidation
+                && Objects.equals(ikeTunConnParams, other.ikeTunConnParams);
     }
 
     @NonNull
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index b87befb..f81ac3d 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -3409,6 +3409,12 @@
     <permission android:name="android.permission.UPDATE_FONTS"
         android:protectionLevel="signature|privileged" />
 
+    <!-- Allows the caller to generate keymint keys with the INCLUDE_UNIQUE_ID tag, which
+         uniquely identifies the device via the attestation certificate.
+         @hide @TestApi -->
+    <permission android:name="android.permission.REQUEST_UNIQUE_ID_ATTESTATION"
+         android:protectionLevel="signature" />
+
     <!-- ========================================= -->
     <!-- Permissions for special development tools -->
     <!-- ========================================= -->
diff --git a/libs/WindowManager/Jetpack/tests/OWNERS b/libs/WindowManager/Jetpack/tests/OWNERS
index f2c3388..ac522b2 100644
--- a/libs/WindowManager/Jetpack/tests/OWNERS
+++ b/libs/WindowManager/Jetpack/tests/OWNERS
@@ -1,4 +1,4 @@
-# Bug component: 909476
+# Bug component: 1157642
 # includes OWNERS from parent directories
 charlesccchen@google.com
 diegovela@google.com
diff --git a/libs/WindowManager/Shell/tests/OWNERS b/libs/WindowManager/Shell/tests/OWNERS
index f49e80a..c877250 100644
--- a/libs/WindowManager/Shell/tests/OWNERS
+++ b/libs/WindowManager/Shell/tests/OWNERS
@@ -1,4 +1,4 @@
-# Bug component: 909476
+# Bug component: 1157642
 # includes OWNERS from parent directories
 natanieljr@google.com
 pablogamito@google.com
diff --git a/packages/Shell/AndroidManifest.xml b/packages/Shell/AndroidManifest.xml
index c03ed03..208bfbbf 100644
--- a/packages/Shell/AndroidManifest.xml
+++ b/packages/Shell/AndroidManifest.xml
@@ -609,6 +609,9 @@
     <!-- Permission required for ATS test - CarDevicePolicyManagerTest -->
     <uses-permission android:name="android.permission.LOCK_DEVICE" />
 
+    <!-- Permission required for CTS test - CtsKeystoreTestCases -->
+    <uses-permission android:name="android.permission.REQUEST_UNIQUE_ID_ATTESTATION" />
+
     <application android:label="@string/app_label"
                 android:theme="@android:style/Theme.DeviceDefault.DayNight"
                 android:defaultToDeviceProtectedStorage="true"
diff --git a/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsImpl.java b/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsImpl.java
index 96ae646..290bf0d 100644
--- a/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsImpl.java
@@ -41,26 +41,23 @@
 
 import javax.inject.Inject;
 
-import dagger.Lazy;
-
 public class GlobalActionsImpl implements GlobalActions, CommandQueue.Callbacks {
 
     private final Context mContext;
-    private final Lazy<GlobalActionsDialogLite> mGlobalActionsDialogLazy;
     private final KeyguardStateController mKeyguardStateController;
     private final DeviceProvisionedController mDeviceProvisionedController;
     private final BlurUtils mBlurUtils;
     private final CommandQueue mCommandQueue;
-    private GlobalActionsDialogLite mGlobalActionsDialog;
+    private final GlobalActionsDialogLite mGlobalActionsDialog;
     private boolean mDisabled;
 
     @Inject
     public GlobalActionsImpl(Context context, CommandQueue commandQueue,
-            Lazy<GlobalActionsDialogLite> globalActionsDialogLazy, BlurUtils blurUtils,
+            GlobalActionsDialogLite globalActionsDialog, BlurUtils blurUtils,
             KeyguardStateController keyguardStateController,
             DeviceProvisionedController deviceProvisionedController) {
         mContext = context;
-        mGlobalActionsDialogLazy = globalActionsDialogLazy;
+        mGlobalActionsDialog = globalActionsDialog;
         mKeyguardStateController = keyguardStateController;
         mDeviceProvisionedController = deviceProvisionedController;
         mCommandQueue = commandQueue;
@@ -71,16 +68,12 @@
     @Override
     public void destroy() {
         mCommandQueue.removeCallback(this);
-        if (mGlobalActionsDialog != null) {
-            mGlobalActionsDialog.destroy();
-            mGlobalActionsDialog = null;
-        }
+        mGlobalActionsDialog.destroy();
     }
 
     @Override
     public void showGlobalActions(GlobalActionsManager manager) {
         if (mDisabled) return;
-        mGlobalActionsDialog = mGlobalActionsDialogLazy.get();
         mGlobalActionsDialog.showOrHideDialog(mKeyguardStateController.isShowing(),
                 mDeviceProvisionedController.isDeviceProvisioned(), null /* view */);
     }
@@ -189,7 +182,7 @@
         final boolean disabled = (state2 & DISABLE2_GLOBAL_ACTIONS) != 0;
         if (displayId != mContext.getDisplayId() || disabled == mDisabled) return;
         mDisabled = disabled;
-        if (disabled && mGlobalActionsDialog != null) {
+        if (disabled) {
             mGlobalActionsDialog.dismissDialog();
         }
     }
diff --git a/services/core/Android.bp b/services/core/Android.bp
index b7e39a1..e4a0097 100644
--- a/services/core/Android.bp
+++ b/services/core/Android.bp
@@ -112,7 +112,6 @@
         "java/com/android/server/am/EventLogTags.logtags",
         "java/com/android/server/wm/EventLogTags.logtags",
         "java/com/android/server/policy/EventLogTags.logtags",
-        ":services.connectivity-tiramisu-sources",
     ],
 
     libs: [
@@ -165,9 +164,6 @@
         "overlayable_policy_aidl-java",
         "SurfaceFlingerProperties",
         "com.android.sysprop.watchdog",
-        // This is used for services.connectivity-tiramisu-sources.
-        // TODO: delete when NetworkStatsService is moved to the mainline module.
-        "net-utils-device-common-bpf",
     ],
     javac_shard_size: 50,
 }
diff --git a/services/core/java/com/android/server/hdmi/HdmiCecLocalDevicePlayback.java b/services/core/java/com/android/server/hdmi/HdmiCecLocalDevicePlayback.java
index 1be8d32..7ff65f5 100644
--- a/services/core/java/com/android/server/hdmi/HdmiCecLocalDevicePlayback.java
+++ b/services/core/java/com/android/server/hdmi/HdmiCecLocalDevicePlayback.java
@@ -275,7 +275,9 @@
         try {
             String iso3Language = new String(message.getParams(), 0, 3, "US-ASCII");
             Locale currentLocale = mService.getContext().getResources().getConfiguration().locale;
-            if (currentLocale.getISO3Language().equals(iso3Language)) {
+            String curIso3Language = mService.localeToMenuLanguage(currentLocale);
+            HdmiLogger.debug("handleSetMenuLanguage " + iso3Language + " cur:" + curIso3Language);
+            if (curIso3Language.equals(iso3Language)) {
                 // Do not switch language if the new language is the same as the current one.
                 // This helps avoid accidental country variant switching from en_US to en_AU
                 // due to the limitation of CEC. See the warning below.
@@ -287,7 +289,7 @@
             final List<LocaleInfo> localeInfos = LocalePicker.getAllAssetLocales(
                     mService.getContext(), false);
             for (LocaleInfo localeInfo : localeInfos) {
-                if (localeInfo.getLocale().getISO3Language().equals(iso3Language)) {
+                if (mService.localeToMenuLanguage(localeInfo.getLocale()).equals(iso3Language)) {
                     // WARNING: CEC adopts ISO/FDIS-2 for language code, while Android requires
                     // additional country variant to pinpoint the locale. This keeps the right
                     // locale from being chosen. 'eng' in the CEC command, for instance,
diff --git a/services/core/java/com/android/server/locksettings/LockSettingsShellCommand.java b/services/core/java/com/android/server/locksettings/LockSettingsShellCommand.java
index a73c8e0..0e4bbbb 100644
--- a/services/core/java/com/android/server/locksettings/LockSettingsShellCommand.java
+++ b/services/core/java/com/android/server/locksettings/LockSettingsShellCommand.java
@@ -18,12 +18,14 @@
 
 import static com.android.internal.widget.LockPatternUtils.CREDENTIAL_TYPE_NONE;
 import static com.android.internal.widget.LockPatternUtils.CREDENTIAL_TYPE_PATTERN;
+import static com.android.internal.widget.LockPatternUtils.StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_USER_LOCKDOWN;
 
 import android.app.ActivityManager;
 import android.app.admin.PasswordMetrics;
 import android.content.Context;
 import android.os.ShellCommand;
 import android.os.SystemProperties;
+import android.os.UserHandle;
 import android.text.TextUtils;
 import android.util.Slog;
 
@@ -48,6 +50,8 @@
     private static final String COMMAND_REMOVE_CACHE = "remove-cache";
     private static final String COMMAND_SET_ROR_PROVIDER_PACKAGE =
             "set-resume-on-reboot-provider-package";
+    private static final String COMMAND_REQUIRE_STRONG_AUTH =
+            "require-strong-auth";
     private static final String COMMAND_HELP = "help";
 
     private int mCurrentUserId;
@@ -97,6 +101,9 @@
                 case COMMAND_SET_ROR_PROVIDER_PACKAGE:
                     runSetResumeOnRebootProviderPackage();
                     return 0;
+                case COMMAND_REQUIRE_STRONG_AUTH:
+                    runRequireStrongAuth();
+                    return 0;
                 case COMMAND_HELP:
                     onHelp();
                     return 0;
@@ -192,6 +199,10 @@
             pw.println("    Sets the package name for server based resume on reboot service "
                     + "provider.");
             pw.println("");
+            pw.println("  require-strong-auth [--user USER_ID] <reason>");
+            pw.println("    Requires the strong authentication. The current supported reasons: "
+                    + "STRONG_AUTH_REQUIRED_AFTER_USER_LOCKDOWN.");
+            pw.println("");
         }
     }
 
@@ -288,6 +299,24 @@
         return true;
     }
 
+    private boolean runRequireStrongAuth() {
+        final String reason = mNew;
+        int strongAuthReason;
+        switch (reason) {
+            case "STRONG_AUTH_REQUIRED_AFTER_USER_LOCKDOWN":
+                strongAuthReason = STRONG_AUTH_REQUIRED_AFTER_USER_LOCKDOWN;
+                mCurrentUserId = UserHandle.USER_ALL;
+                break;
+            default:
+                getErrPrintWriter().println("Unsupported reason: " + reason);
+                return false;
+        }
+        mLockPatternUtils.requireStrongAuth(strongAuthReason, mCurrentUserId);
+        getOutPrintWriter().println("Require strong auth for USER_ID "
+                + mCurrentUserId + " because of " + mNew);
+        return true;
+    }
+
     private boolean runClear() {
         LockscreenCredential none = LockscreenCredential.createNone();
         if (!isNewCredentialSufficient(none)) {
diff --git a/services/core/java/com/android/server/net/TEST_MAPPING b/services/core/java/com/android/server/net/TEST_MAPPING
index 02095eb..4ccf09e 100644
--- a/services/core/java/com/android/server/net/TEST_MAPPING
+++ b/services/core/java/com/android/server/net/TEST_MAPPING
@@ -2,12 +2,8 @@
   "presubmit-large": [
     {
       "name": "CtsHostsideNetworkTests",
-      "file_patterns": ["(/|^)NetworkPolicy[^/]*\\.java"],
       "options": [
         {
-          "include-filter": "com.android.cts.net.HostsideRestrictBackgroundNetworkTests"
-        },
-        {
           "exclude-annotation": "androidx.test.filters.FlakyTest"
         },
         {
diff --git a/services/core/java/com/android/server/pm/PackageManagerShellCommand.java b/services/core/java/com/android/server/pm/PackageManagerShellCommand.java
index 265e606..d01f962 100644
--- a/services/core/java/com/android/server/pm/PackageManagerShellCommand.java
+++ b/services/core/java/com/android/server/pm/PackageManagerShellCommand.java
@@ -3516,7 +3516,7 @@
             }
             List<PermissionInfo> ps = mPermissionManager
                     .queryPermissionsByGroup(groupList.get(i), 0 /*flags*/);
-            final int count = ps.size();
+            final int count = (ps == null ? 0 : ps.size());
             boolean first = true;
             for (int p = 0 ; p < count ; p++) {
                 PermissionInfo pi = ps.get(p);
diff --git a/services/tests/servicestests/src/com/android/server/locksettings/LockSettingsShellCommandTest.java b/services/tests/servicestests/src/com/android/server/locksettings/LockSettingsShellCommandTest.java
index 33ea710..b9ae670 100644
--- a/services/tests/servicestests/src/com/android/server/locksettings/LockSettingsShellCommandTest.java
+++ b/services/tests/servicestests/src/com/android/server/locksettings/LockSettingsShellCommandTest.java
@@ -25,6 +25,8 @@
 import static android.app.admin.DevicePolicyManager.PASSWORD_QUALITY_SOMETHING;
 import static android.app.admin.DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED;
 
+import static com.android.internal.widget.LockPatternUtils.StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_USER_LOCKDOWN;
+
 import static junit.framework.Assert.assertEquals;
 
 import static org.mockito.ArgumentMatchers.anyInt;
@@ -48,6 +50,7 @@
 import android.os.Process;
 import android.os.ResultReceiver;
 import android.os.ShellCallback;
+import android.os.UserHandle;
 import android.platform.test.annotations.Presubmit;
 
 import androidx.test.InstrumentationRegistry;
@@ -370,6 +373,19 @@
                 mUserId);
     }
 
+    @Test
+    public void testRequireStrongAuth_STRONG_AUTH_REQUIRED_AFTER_USER_LOCKDOWN() throws Exception {
+        when(mLockPatternUtils.isSecure(mUserId)).thenReturn(true);
+
+        assertEquals(0, mCommand.exec(new Binder(), in, out, err,
+                new String[] { "require-strong-auth", "STRONG_AUTH_REQUIRED_AFTER_USER_LOCKDOWN"},
+                mShellCallback, mResultReceiver));
+
+        verify(mLockPatternUtils).requireStrongAuth(
+                STRONG_AUTH_REQUIRED_AFTER_USER_LOCKDOWN,
+                UserHandle.USER_ALL);
+    }
+
     private List<LockPatternView.Cell> stringToPattern(String str) {
         return LockPatternUtils.byteArrayToPattern(str.getBytes());
     }
diff --git a/telephony/java/android/telephony/data/DataServiceCallback.java b/telephony/java/android/telephony/data/DataServiceCallback.java
index ec73471..77d4837 100644
--- a/telephony/java/android/telephony/data/DataServiceCallback.java
+++ b/telephony/java/android/telephony/data/DataServiceCallback.java
@@ -50,12 +50,13 @@
      */
     @Retention(RetentionPolicy.SOURCE)
     @IntDef({RESULT_SUCCESS, RESULT_ERROR_UNSUPPORTED, RESULT_ERROR_INVALID_ARG, RESULT_ERROR_BUSY,
-            RESULT_ERROR_ILLEGAL_STATE})
+            RESULT_ERROR_ILLEGAL_STATE, RESULT_ERROR_TEMPORARILY_UNAVAILABLE,
+            RESULT_ERROR_INVALID_RESPONSE})
     public @interface ResultCode {}
 
     /** Request is completed successfully */
     public static final int RESULT_SUCCESS              = 0;
-    /** Request is not support */
+    /** Request is not supported */
     public static final int RESULT_ERROR_UNSUPPORTED    = 1;
     /** Request contains invalid arguments */
     public static final int RESULT_ERROR_INVALID_ARG    = 2;
@@ -68,6 +69,11 @@
      * @hide
      */
     public static final int RESULT_ERROR_TEMPORARILY_UNAVAILABLE = 5;
+    /**
+     * Request failed to complete due to an invalid response.
+     * @hide
+     */
+    public static final int RESULT_ERROR_INVALID_RESPONSE = 6;
 
     private final IDataServiceCallback mCallback;
 
@@ -255,6 +261,8 @@
                 return "RESULT_ERROR_ILLEGAL_STATE";
             case RESULT_ERROR_TEMPORARILY_UNAVAILABLE:
                 return "RESULT_ERROR_TEMPORARILY_UNAVAILABLE";
+            case RESULT_ERROR_INVALID_RESPONSE:
+                return "RESULT_ERROR_INVALID_RESPONSE";
             default:
                 return "Unknown(" + resultCode + ")";
         }
diff --git a/tests/FlickerTests/OWNERS b/tests/FlickerTests/OWNERS
index c1221e3..d40ff56 100644
--- a/tests/FlickerTests/OWNERS
+++ b/tests/FlickerTests/OWNERS
@@ -1,4 +1,4 @@
-# Bug component: 909476
+# Bug component: 1157642
 include /services/core/java/com/android/server/wm/OWNERS
 natanieljr@google.com
 pablogamito@google.com
diff --git a/tools/aapt2/Android.bp b/tools/aapt2/Android.bp
index 740b44e..50cd455 100644
--- a/tools/aapt2/Android.bp
+++ b/tools/aapt2/Android.bp
@@ -165,6 +165,7 @@
     ],
     proto: {
         export_proto_headers: true,
+        type: "full",
     },
     defaults: ["aapt2_defaults"],
 }