Merge "Update set|getRetryIntervalsMs to Millis"
diff --git a/StubLibraries.bp b/StubLibraries.bp
index 00d0771..5a0439b 100644
--- a/StubLibraries.bp
+++ b/StubLibraries.bp
@@ -471,6 +471,22 @@
     },
 }
 
+java_library {
+    name: "android_system_server_stubs_current",
+    defaults: ["android_stubs_dists_default"],
+    srcs: [":services-non-updatable-stubs"],
+    installable: false,
+    static_libs: [
+        "android_module_lib_stubs_current",
+    ],
+    sdk_version: "none",
+    system_modules: "none",
+    java_version: "1.8",
+    dist: {
+        dir: "apistubs/android/system-server",
+    },
+}
+
 /////////////////////////////////////////////////////////////////////
 // hwbinder.stubs provides APIs required for building HIDL Java
 // libraries.
diff --git a/api/Android.bp b/api/Android.bp
index 6e83c08..2df31ec 100644
--- a/api/Android.bp
+++ b/api/Android.bp
@@ -341,7 +341,7 @@
         {
             targets: ["sdk", "win_sdk"],
             dir: "apistubs/android/system-server/api",
-            dest: "merge-android.txt",
+            dest: "android.txt",
         },
     ],
 }
@@ -364,7 +364,7 @@
         {
             targets: ["sdk", "win_sdk"],
             dir: "apistubs/android/system-server/api",
-            dest: "merge-removed.txt",
+            dest: "removed.txt",
         },
     ],
 }
diff --git a/core/api/current.txt b/core/api/current.txt
index c592891..d82cd72 100644
--- a/core/api/current.txt
+++ b/core/api/current.txt
@@ -40406,7 +40406,6 @@
     method @IntRange(from=1, to=261) public int getBand();
     method @IntRange(from=1) public int getCellBandwidthDownlinkKhz();
     method @IntRange(from=1) public int getCellBandwidthUplinkKhz();
-    method @Deprecated public int getChannelNumber();
     method public int getConnectionStatus();
     method @IntRange(from=0) public int getDownlinkChannelNumber();
     method @IntRange(from=0) public int getDownlinkFrequencyKhz();
diff --git a/core/api/test-current.txt b/core/api/test-current.txt
index fd6d47e..e8f8f3a 100644
--- a/core/api/test-current.txt
+++ b/core/api/test-current.txt
@@ -1683,6 +1683,7 @@
   public class TelephonyManager {
     method public int addDevicePolicyOverrideApn(@NonNull android.content.Context, @NonNull android.telephony.data.ApnSetting);
     method public int getCarrierIdListVersion();
+    method @NonNull @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public java.util.List<java.lang.String> getCertsFromCarrierPrivilegeAccessRules();
     method @NonNull public java.util.List<android.telephony.data.ApnSetting> getDevicePolicyOverrideApns(@NonNull android.content.Context);
     method @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE) public String getLine1AlphaTag();
     method public android.util.Pair<java.lang.Integer,java.lang.Integer> getRadioHalVersion();
diff --git a/core/java/android/app/compat/PackageOverride.java b/core/java/android/app/compat/PackageOverride.java
index 59b3555..fad6cd3 100644
--- a/core/java/android/app/compat/PackageOverride.java
+++ b/core/java/android/app/compat/PackageOverride.java
@@ -19,6 +19,7 @@
 import android.annotation.IntDef;
 import android.annotation.NonNull;
 import android.annotation.SystemApi;
+import android.content.pm.PackageInfo;
 import android.os.Parcel;
 
 import java.lang.annotation.Retention;
@@ -101,12 +102,20 @@
         return VALUE_UNDEFINED;
     }
 
-    /** Returns the minimum version code the override applies to. */
+    /**
+     * Returns the minimum APK version code the override applies to.
+     *
+     * @see PackageInfo#getLongVersionCode()
+     */
     public long getMinVersionCode() {
         return mMinVersionCode;
     }
 
-    /** Returns the minimum version code the override applies from. */
+    /**
+     * Returns the maximum APK version code the override applies from.
+     *
+     * @see PackageInfo#getLongVersionCode()
+     */
     public long getMaxVersionCode() {
         return mMaxVersionCode;
     }
@@ -146,9 +155,11 @@
         private boolean mEnabled;
 
         /**
-         * Sets the minimum version code the override should apply from.
+         * Sets the minimum APK version code the override should apply from.
          *
          * default value: {@code Long.MIN_VALUE}.
+         *
+         * @see PackageInfo#getLongVersionCode()
          */
         @NonNull
         public Builder setMinVersionCode(long minVersionCode) {
@@ -157,9 +168,11 @@
         }
 
         /**
-         * Sets the maximum version code the override should apply to.
+         * Sets the maximum APK version code the override should apply to.
          *
          * default value: {@code Long.MAX_VALUE}.
+         *
+         * @see PackageInfo#getLongVersionCode()
          */
         @NonNull
         public Builder setMaxVersionCode(long maxVersionCode) {
diff --git a/core/java/android/content/pm/OWNERS b/core/java/android/content/pm/OWNERS
index f0def805..4e674f6 100644
--- a/core/java/android/content/pm/OWNERS
+++ b/core/java/android/content/pm/OWNERS
@@ -4,7 +4,8 @@
 toddke@google.com
 patb@google.com
 
-per-file PackageParser.java = chiuwinson@google.com
+per-file PackageParser.java = set noparent
+per-file PackageParser.java = chiuwinson@google.com,patb@google.com,toddke@google.com
 per-file *Shortcut* = file:/core/java/android/content/pm/SHORTCUT_OWNERS
 per-file AppSearchPerson.java = file:/core/java/android/content/pm/SHORTCUT_OWNERS
 per-file *Launcher* = file:/core/java/android/content/pm/LAUNCHER_OWNERS
diff --git a/core/java/android/hardware/biometrics/BiometricManager.java b/core/java/android/hardware/biometrics/BiometricManager.java
index e385cd2..362a205 100644
--- a/core/java/android/hardware/biometrics/BiometricManager.java
+++ b/core/java/android/hardware/biometrics/BiometricManager.java
@@ -26,6 +26,7 @@
 import android.annotation.SystemService;
 import android.content.Context;
 import android.os.RemoteException;
+import android.os.UserHandle;
 import android.security.keystore.KeyGenParameterSpec;
 import android.security.keystore.KeyProperties;
 import android.util.Slog;
@@ -334,11 +335,23 @@
      * in Keystore land as SIDs, and are used during key generation.
      * @hide
      */
-    @RequiresPermission(USE_BIOMETRIC_INTERNAL)
     public long[] getAuthenticatorIds() {
+        return getAuthenticatorIds(UserHandle.myUserId());
+    }
+
+    /**
+     * Get a list of AuthenticatorIDs for biometric authenticators which have 1) enrolled templates,
+     * and 2) meet the requirements for integrating with Keystore. The AuthenticatorIDs are known
+     * in Keystore land as SIDs, and are used during key generation.
+     *
+     * @param userId Android user ID for user to look up.
+     *
+     * @hide
+     */
+    public long[] getAuthenticatorIds(int userId) {
         if (mService != null) {
             try {
-                return mService.getAuthenticatorIds();
+                return mService.getAuthenticatorIds(userId);
             } catch (RemoteException e) {
                 throw e.rethrowFromSystemServer();
             }
@@ -347,6 +360,5 @@
             return new long[0];
         }
     }
-
 }
 
diff --git a/core/java/android/hardware/biometrics/IAuthService.aidl b/core/java/android/hardware/biometrics/IAuthService.aidl
index a6f6c1e..35424829 100644
--- a/core/java/android/hardware/biometrics/IAuthService.aidl
+++ b/core/java/android/hardware/biometrics/IAuthService.aidl
@@ -55,5 +55,7 @@
     // Get a list of AuthenticatorIDs for authenticators which have enrolled templates and meet
     // the requirements for integrating with Keystore. The AuthenticatorID are known in Keystore
     // land as SIDs, and are used during key generation.
-    long[] getAuthenticatorIds();
+    // If userId is not equal to the calling user ID, the caller must have the
+    // USE_BIOMETRIC_INTERNAL permission.
+    long[] getAuthenticatorIds(in int userId);
 }
diff --git a/core/java/android/net/vcn/VcnTransportInfo.java b/core/java/android/net/vcn/VcnTransportInfo.java
index 4d8cf91..0e9ccf1 100644
--- a/core/java/android/net/vcn/VcnTransportInfo.java
+++ b/core/java/android/net/vcn/VcnTransportInfo.java
@@ -16,14 +16,23 @@
 
 package android.net.vcn;
 
+import static android.net.NetworkCapabilities.REDACT_ALL;
+import static android.net.NetworkCapabilities.REDACT_FOR_NETWORK_SETTINGS;
+import static android.telephony.SubscriptionManager.INVALID_SUBSCRIPTION_ID;
+
+import static com.android.internal.annotations.VisibleForTesting.Visibility.PRIVATE;
+
 import android.annotation.NonNull;
 import android.annotation.Nullable;
+import android.net.NetworkCapabilities;
 import android.net.TransportInfo;
 import android.net.wifi.WifiInfo;
 import android.os.Parcel;
 import android.os.Parcelable;
 import android.telephony.SubscriptionManager;
 
+import com.android.internal.annotations.VisibleForTesting;
+
 import java.util.Objects;
 
 /**
@@ -37,28 +46,41 @@
  * SubscriptionManager#INVALID_SUBSCRIPTION_ID}. If the underlying Network is Cellular, the WifiInfo
  * will be {@code null}.
  *
+ * <p>Receipt of a VcnTransportInfo requires the NETWORK_SETTINGS permission; else the entire
+ * VcnTransportInfo instance will be redacted.
+ *
  * @hide
  */
 public class VcnTransportInfo implements TransportInfo, Parcelable {
     @Nullable private final WifiInfo mWifiInfo;
     private final int mSubId;
 
+    /**
+     * The redaction scheme to use when parcelling.
+     *
+     * <p>The TransportInfo/NetworkCapabilities redaction mechanisms rely on redaction being
+     * performed at parcelling time. This means that the redaction scheme must be stored for later
+     * use.
+     *
+     * <p>Since the redaction scheme itself is not parcelled, this field is listed as a transient.
+     *
+     * <p>Defaults to REDACT_ALL when constructed using public constructors, or creating from
+     * parcels.
+     */
+    private final transient long mRedactions;
+
     public VcnTransportInfo(@NonNull WifiInfo wifiInfo) {
-        this(wifiInfo, SubscriptionManager.INVALID_SUBSCRIPTION_ID);
+        this(wifiInfo, INVALID_SUBSCRIPTION_ID, REDACT_ALL);
     }
 
     public VcnTransportInfo(int subId) {
-        this(null /* wifiInfo */, subId);
+        this(null /* wifiInfo */, subId, REDACT_ALL);
     }
 
-    private VcnTransportInfo(@Nullable WifiInfo wifiInfo, int subId) {
-        if (wifiInfo == null && subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
-            throw new IllegalArgumentException(
-                    "VcnTransportInfo requires either non-null WifiInfo or valid subId");
-        }
-
+    private VcnTransportInfo(@Nullable WifiInfo wifiInfo, int subId, long redactions) {
         mWifiInfo = wifiInfo;
         mSubId = subId;
+        mRedactions = redactions;
     }
 
     /**
@@ -86,8 +108,19 @@
         return mSubId;
     }
 
+    /**
+     * Gets the redaction scheme
+     *
+     * @hide
+     */
+    @VisibleForTesting(visibility = PRIVATE)
+    public long getRedaction() {
+        return mRedactions;
+    }
+
     @Override
     public int hashCode() {
+        // mRedactions not hashed, as it is a transient, for control of parcelling
         return Objects.hash(mWifiInfo, mSubId);
     }
 
@@ -96,6 +129,7 @@
         if (!(o instanceof VcnTransportInfo)) return false;
         final VcnTransportInfo that = (VcnTransportInfo) o;
 
+        // mRedactions not compared, as it is a transient, for control of parcelling
         return Objects.equals(mWifiInfo, that.mWifiInfo) && mSubId == that.mSubId;
     }
 
@@ -105,17 +139,59 @@
         return 0;
     }
 
+    @Override
+    @NonNull
+    public TransportInfo makeCopy(long redactions) {
+        return new VcnTransportInfo(
+                mWifiInfo == null ? null : mWifiInfo.makeCopy(redactions), mSubId, redactions);
+    }
+
+    @Override
+    public long getApplicableRedactions() {
+        long redactions = REDACT_FOR_NETWORK_SETTINGS;
+
+        // Add additional wifi redactions if necessary
+        if (mWifiInfo != null) {
+            redactions |= mWifiInfo.getApplicableRedactions();
+        }
+
+        return redactions;
+    }
+
+    private boolean shouldParcelNetworkSettingsFields() {
+        return (mRedactions & NetworkCapabilities.REDACT_FOR_NETWORK_SETTINGS) == 0;
+    }
+
     /** {@inheritDoc} */
     @Override
-    public void writeToParcel(@NonNull Parcel dest, int flags) {}
+    public void writeToParcel(@NonNull Parcel dest, int flags) {
+        dest.writeInt(shouldParcelNetworkSettingsFields() ? mSubId : INVALID_SUBSCRIPTION_ID);
+        dest.writeParcelable(
+                shouldParcelNetworkSettingsFields() ? (Parcelable) mWifiInfo : null, flags);
+    }
+
+    @Override
+    public String toString() {
+        return "VcnTransportInfo { mWifiInfo = " + mWifiInfo + ", mSubId = " + mSubId + " }";
+    }
 
     /** Implement the Parcelable interface */
     public static final @NonNull Creator<VcnTransportInfo> CREATOR =
             new Creator<VcnTransportInfo>() {
                 public VcnTransportInfo createFromParcel(Parcel in) {
-                    // return null instead of a default VcnTransportInfo to avoid leaking
-                    // information about this being a VCN Network (instead of macro cellular, etc)
-                    return null;
+                    final int subId = in.readInt();
+                    final WifiInfo wifiInfo = in.readParcelable(null);
+
+                    // If all fields are their null values, return null TransportInfo to avoid
+                    // leaking information about this being a VCN Network (instead of macro
+                    // cellular, etc)
+                    if (wifiInfo == null && subId == INVALID_SUBSCRIPTION_ID) {
+                        return null;
+                    }
+
+                    // Prevent further forwarding by redacting everything in future parcels from
+                    // this VcnTransportInfo
+                    return new VcnTransportInfo(wifiInfo, subId, REDACT_ALL);
                 }
 
                 public VcnTransportInfo[] newArray(int size) {
diff --git a/core/java/android/nfc/NfcControllerAlwaysOnListener.java b/core/java/android/nfc/NfcControllerAlwaysOnListener.java
index 96707bb..6ae58fd 100644
--- a/core/java/android/nfc/NfcControllerAlwaysOnListener.java
+++ b/core/java/android/nfc/NfcControllerAlwaysOnListener.java
@@ -52,6 +52,14 @@
      */
     public void register(@NonNull Executor executor,
             @NonNull ControllerAlwaysOnListener listener) {
+        try {
+            if (!mAdapter.isControllerAlwaysOnSupported()) {
+                return;
+            }
+        } catch (RemoteException e) {
+            Log.w(TAG, "Failed to register");
+            return;
+        }
         synchronized (this) {
             if (mListenerMap.containsKey(listener)) {
                 return;
@@ -75,6 +83,14 @@
      * @param listener user implementation of the {@link ControllerAlwaysOnListener}
      */
     public void unregister(@NonNull ControllerAlwaysOnListener listener) {
+        try {
+            if (!mAdapter.isControllerAlwaysOnSupported()) {
+                return;
+            }
+        } catch (RemoteException e) {
+            Log.w(TAG, "Failed to unregister");
+            return;
+        }
         synchronized (this) {
             if (!mListenerMap.containsKey(listener)) {
                 return;
diff --git a/core/java/com/android/internal/graphics/OWNERS b/core/java/com/android/internal/graphics/OWNERS
new file mode 100644
index 0000000..5851cbb
--- /dev/null
+++ b/core/java/com/android/internal/graphics/OWNERS
@@ -0,0 +1 @@
+include /graphics/java/android/graphics/OWNERS
\ No newline at end of file
diff --git a/core/jni/include/android_runtime/AndroidRuntime.h b/core/jni/include/android_runtime/AndroidRuntime.h
index d86d934..bf2ba77 100644
--- a/core/jni/include/android_runtime/AndroidRuntime.h
+++ b/core/jni/include/android_runtime/AndroidRuntime.h
@@ -19,7 +19,6 @@
 #ifndef _RUNTIME_ANDROID_RUNTIME_H
 #define _RUNTIME_ANDROID_RUNTIME_H
 
-#include <binder/IBinder.h>
 #include <jni.h>
 #include <pthread.h>
 #include <utils/Errors.h>
diff --git a/core/tests/nfctests/src/android/nfc/NfcControllerAlwaysOnListenerTest.java b/core/tests/nfctests/src/android/nfc/NfcControllerAlwaysOnListenerTest.java
index 43f9b6f..48f4288 100644
--- a/core/tests/nfctests/src/android/nfc/NfcControllerAlwaysOnListenerTest.java
+++ b/core/tests/nfctests/src/android/nfc/NfcControllerAlwaysOnListenerTest.java
@@ -19,6 +19,7 @@
 import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.ArgumentMatchers.anyBoolean;
 import static org.mockito.Mockito.doNothing;
+import static org.mockito.Mockito.doReturn;
 import static org.mockito.Mockito.doThrow;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.times;
@@ -62,7 +63,36 @@
     }
 
     @Test
+    public void testRegister_RegisterUnregisterWhenNotSupported() throws RemoteException {
+        // isControllerAlwaysOnSupported() returns false, not supported.
+        doReturn(false).when(mNfcAdapter).isControllerAlwaysOnSupported();
+        NfcControllerAlwaysOnListener mListener =
+                new NfcControllerAlwaysOnListener(mNfcAdapter);
+        ControllerAlwaysOnListener mockListener1 = mock(ControllerAlwaysOnListener.class);
+        ControllerAlwaysOnListener mockListener2 = mock(ControllerAlwaysOnListener.class);
+
+        // Verify that the state listener will not registered with the NFC Adapter
+        mListener.register(getExecutor(), mockListener1);
+        verify(mNfcAdapter, times(0)).registerControllerAlwaysOnListener(any());
+
+        // Register a second client and no any call to NFC Adapter
+        mListener.register(getExecutor(), mockListener2);
+        verify(mNfcAdapter, times(0)).registerControllerAlwaysOnListener(any());
+
+        // Unregister first listener, and no any call to NFC Adapter
+        mListener.unregister(mockListener1);
+        verify(mNfcAdapter, times(0)).registerControllerAlwaysOnListener(any());
+        verify(mNfcAdapter, times(0)).unregisterControllerAlwaysOnListener(any());
+
+        // Unregister second listener, and no any call to NFC Adapter
+        mListener.unregister(mockListener2);
+        verify(mNfcAdapter, times(0)).registerControllerAlwaysOnListener(any());
+        verify(mNfcAdapter, times(0)).unregisterControllerAlwaysOnListener(any());
+    }
+
+    @Test
     public void testRegister_RegisterUnregister() throws RemoteException {
+        doReturn(true).when(mNfcAdapter).isControllerAlwaysOnSupported();
         NfcControllerAlwaysOnListener mListener =
                 new NfcControllerAlwaysOnListener(mNfcAdapter);
         ControllerAlwaysOnListener mockListener1 = mock(ControllerAlwaysOnListener.class);
@@ -89,6 +119,7 @@
 
     @Test
     public void testRegister_FirstRegisterFails() throws RemoteException {
+        doReturn(true).when(mNfcAdapter).isControllerAlwaysOnSupported();
         NfcControllerAlwaysOnListener mListener =
                 new NfcControllerAlwaysOnListener(mNfcAdapter);
         ControllerAlwaysOnListener mockListener1 = mock(ControllerAlwaysOnListener.class);
@@ -116,6 +147,7 @@
 
     @Test
     public void testRegister_RegisterSameListenerTwice() throws RemoteException {
+        doReturn(true).when(mNfcAdapter).isControllerAlwaysOnSupported();
         NfcControllerAlwaysOnListener mListener =
                 new NfcControllerAlwaysOnListener(mNfcAdapter);
         ControllerAlwaysOnListener mockListener = mock(ControllerAlwaysOnListener.class);
@@ -132,7 +164,7 @@
 
     @Test
     public void testNotify_AllListenersNotified() throws RemoteException {
-
+        doReturn(true).when(mNfcAdapter).isControllerAlwaysOnSupported();
         NfcControllerAlwaysOnListener listener = new NfcControllerAlwaysOnListener(mNfcAdapter);
         List<ControllerAlwaysOnListener> mockListeners = new ArrayList<>();
         for (int i = 0; i < 10; i++) {
@@ -149,7 +181,8 @@
     }
 
     @Test
-    public void testStateChange_CorrectValue() {
+    public void testStateChange_CorrectValue() throws RemoteException {
+        doReturn(true).when(mNfcAdapter).isControllerAlwaysOnSupported();
         runStateChangeValue(true, true);
         runStateChangeValue(false, false);
 
diff --git a/keystore/java/android/security/Authorization.java b/keystore/java/android/security/Authorization.java
index bd72d45..00219e7 100644
--- a/keystore/java/android/security/Authorization.java
+++ b/keystore/java/android/security/Authorization.java
@@ -74,16 +74,19 @@
      * @param locked            - whether it is a lock (true) or unlock (false) event
      * @param syntheticPassword - if it is an unlock event with the password, pass the synthetic
      *                            password provided by the LockSettingService
+     * @param unlockingSids     - KeyMint secure user IDs that should be permitted to unlock
+     *                            UNLOCKED_DEVICE_REQUIRED keys.
      *
      * @return 0 if successful or a {@code ResponseCode}.
      */
     public static int onLockScreenEvent(@NonNull boolean locked, @NonNull int userId,
-            @Nullable byte[] syntheticPassword) {
+            @Nullable byte[] syntheticPassword, @Nullable long[] unlockingSids) {
         try {
             if (locked) {
-                getService().onLockScreenEvent(LockScreenEvent.LOCK, userId, null);
+                getService().onLockScreenEvent(LockScreenEvent.LOCK, userId, null, unlockingSids);
             } else {
-                getService().onLockScreenEvent(LockScreenEvent.UNLOCK, userId, syntheticPassword);
+                getService().onLockScreenEvent(
+                        LockScreenEvent.UNLOCK, userId, syntheticPassword, unlockingSids);
             }
             return 0;
         } catch (RemoteException | NullPointerException e) {
diff --git a/packages/InputDevices/res/raw/keyboard_layout_arabic.kcm b/packages/InputDevices/res/raw/keyboard_layout_arabic.kcm
index 2a95cfe..44d5a0c 100644
--- a/packages/InputDevices/res/raw/keyboard_layout_arabic.kcm
+++ b/packages/InputDevices/res/raw/keyboard_layout_arabic.kcm
@@ -85,14 +85,14 @@
 key 9 {
     label:                              '9'
     base:                               '\u0669'
-    shift:                              '('
+    shift:                              ')'
     capslock:                           '9'
 }
 
 key 0 {
     label:                              '0'
     base:                               '\u0660'
-    shift:                              ')'
+    shift:                              '('
     capslock:                           '0'
 }
 
diff --git a/services/Android.bp b/services/Android.bp
index 0a01c95..57a7bc5 100644
--- a/services/Android.bp
+++ b/services/Android.bp
@@ -146,68 +146,12 @@
         " --hide-package com.google.android.startop.iorap" +
         " --hide DeprecationMismatch" +
         " --hide HiddenTypedefConstant",
-    visibility: ["//visibility:private"],
+    visibility: ["//frameworks/base:__subpackages__"],
     filter_packages: ["com.android."],
 }
 
 droidstubs {
-    name: "services-stubs.sources",
-    srcs: [":services-all-sources"],
-    defaults: ["services-stubs-default"],
-    check_api: {
-        current: {
-            api_file: "api/current.txt",
-            removed_api_file: "api/removed.txt",
-        },
-        last_released: {
-            api_file: ":android.api.system-server.latest",
-            removed_api_file: ":removed.api.system-server.latest",
-            baseline_file: ":android-incompatibilities.api.system-server.latest",
-        },
-        api_lint: {
-            enabled: true,
-            new_since: ":android.api.system-server.latest",
-            baseline_file: "api/lint-baseline.txt",
-        },
-    },
-    dists: [
-        {
-            targets: [
-                "sdk",
-                "win_sdk",
-            ],
-            dir: "apistubs/android/system-server/api",
-            dest: "android.txt",
-            tag: ".api.txt",
-        },
-        {
-            targets: [
-                "sdk",
-                "win_sdk",
-            ],
-            dir: "apistubs/android/system-server/api",
-            dest: "removed.txt",
-            tag: ".removed-api.txt",
-        },
-    ],
-}
-
-java_library {
-    name: "android_system_server_stubs_current",
-    defaults: ["android_stubs_dists_default"],
-    srcs: [":services-stubs.sources"],
-    installable: false,
-    static_libs: ["android_module_lib_stubs_current"],
-    sdk_version: "none",
-    system_modules: "none",
-    java_version: "1.8",
-    dist: {
-        dir: "apistubs/android/system-server",
-    },
-}
-
-droidstubs {
-    name: "services-non-updatable-stubs.sources",
+    name: "services-non-updatable-stubs",
     srcs: [":services-non-updatable-sources"],
     defaults: ["services-stubs-default"],
     check_api: {
diff --git a/services/core/java/com/android/server/biometrics/AuthService.java b/services/core/java/com/android/server/biometrics/AuthService.java
index 1312679..8fd8b5c 100644
--- a/services/core/java/com/android/server/biometrics/AuthService.java
+++ b/services/core/java/com/android/server/biometrics/AuthService.java
@@ -289,7 +289,7 @@
         }
 
         @Override
-        public long[] getAuthenticatorIds() throws RemoteException {
+        public long[] getAuthenticatorIds(int userId) throws RemoteException {
             // In this method, we're not checking whether the caller is permitted to use face
             // API because current authenticator ID is leaked (in a more contrived way) via Android
             // Keystore (android.security.keystore package): the user of that API can create a key
@@ -307,9 +307,13 @@
             // method from inside app processes.
 
             final int callingUserId = UserHandle.getCallingUserId();
+            if (userId != callingUserId) {
+                getContext().enforceCallingOrSelfPermission(USE_BIOMETRIC_INTERNAL,
+                        "Must have " + USE_BIOMETRIC_INTERNAL + " permission.");
+            }
             final long identity = Binder.clearCallingIdentity();
             try {
-                return mBiometricService.getAuthenticatorIds(callingUserId);
+                return mBiometricService.getAuthenticatorIds(userId);
             } finally {
                 Binder.restoreCallingIdentity(identity);
             }
diff --git a/services/core/java/com/android/server/locksettings/LockSettingsService.java b/services/core/java/com/android/server/locksettings/LockSettingsService.java
index 117c85b..ea1c68d 100644
--- a/services/core/java/com/android/server/locksettings/LockSettingsService.java
+++ b/services/core/java/com/android/server/locksettings/LockSettingsService.java
@@ -1266,7 +1266,7 @@
 
     private void unlockKeystore(byte[] password, int userHandle) {
         if (DEBUG) Slog.v(TAG, "Unlock keystore for user: " + userHandle);
-        Authorization.onLockScreenEvent(false, userHandle, password);
+        Authorization.onLockScreenEvent(false, userHandle, password, null);
     }
 
     @VisibleForTesting /** Note: this method is overridden in unit tests */
diff --git a/services/core/java/com/android/server/trust/TrustManagerService.java b/services/core/java/com/android/server/trust/TrustManagerService.java
index ff763fc..90b095b 100644
--- a/services/core/java/com/android/server/trust/TrustManagerService.java
+++ b/services/core/java/com/android/server/trust/TrustManagerService.java
@@ -39,6 +39,7 @@
 import android.content.res.XmlResourceParser;
 import android.database.ContentObserver;
 import android.graphics.drawable.Drawable;
+import android.hardware.biometrics.BiometricManager;
 import android.hardware.biometrics.BiometricSourceType;
 import android.net.Uri;
 import android.os.Binder;
@@ -185,8 +186,6 @@
     private boolean mTrustAgentsCanRun = false;
     private int mCurrentUser = UserHandle.USER_SYSTEM;
 
-    private Authorization mAuthorizationService;
-
     public TrustManagerService(Context context) {
         super(context);
         mContext = context;
@@ -196,7 +195,6 @@
         mStrongAuthTracker = new StrongAuthTracker(context);
         mAlarmManager = (AlarmManager) mContext.getSystemService(Context.ALARM_SERVICE);
         mSettingsObserver = new SettingsObserver(mHandler);
-        mAuthorizationService = new Authorization();
     }
 
     @Override
@@ -698,13 +696,14 @@
         }
         if (changed) {
             dispatchDeviceLocked(userId, locked);
-
-            Authorization.onLockScreenEvent(locked, userId, null);
+            Authorization.onLockScreenEvent(locked, userId, null,
+                    getBiometricSids(userId));
             // Also update the user's profiles who have unified challenge, since they
             // share the same unlocked state (see {@link #isDeviceLocked(int)})
             for (int profileHandle : mUserManager.getEnabledProfileIds(userId)) {
                 if (mLockPatternUtils.isManagedProfileWithUnifiedChallenge(profileHandle)) {
-                    mAuthorizationService.onLockScreenEvent(locked, profileHandle, null);
+                    Authorization.onLockScreenEvent(locked, profileHandle, null,
+                            getBiometricSids(profileHandle));
                 }
             }
         }
@@ -1044,6 +1043,14 @@
         }
     }
 
+    private long[] getBiometricSids(int userId) {
+        BiometricManager biometricManager = mContext.getSystemService(BiometricManager.class);
+        if (biometricManager == null) {
+            return null;
+        }
+        return biometricManager.getAuthenticatorIds(userId);
+    }
+
     // User lifecycle
 
     @Override
@@ -1255,7 +1262,8 @@
                         mDeviceLockedForUser.put(userId, locked);
                     }
 
-                    Authorization.onLockScreenEvent(locked, userId, null);
+                    Authorization.onLockScreenEvent(locked, userId, null,
+                            getBiometricSids(userId));
 
                     if (locked) {
                         try {
diff --git a/services/core/java/com/android/server/vcn/VcnGatewayConnection.java b/services/core/java/com/android/server/vcn/VcnGatewayConnection.java
index dc2b576..65b947c 100644
--- a/services/core/java/com/android/server/vcn/VcnGatewayConnection.java
+++ b/services/core/java/com/android/server/vcn/VcnGatewayConnection.java
@@ -1558,8 +1558,22 @@
                                 teardownAsynchronously();
                             } /* networkUnwantedCallback */,
                             (status) -> {
-                                if (status == NetworkAgent.VALIDATION_STATUS_VALID) {
-                                    clearFailedAttemptCounterAndSafeModeAlarm();
+                                switch (status) {
+                                    case NetworkAgent.VALIDATION_STATUS_VALID:
+                                        clearFailedAttemptCounterAndSafeModeAlarm();
+                                        break;
+                                    case NetworkAgent.VALIDATION_STATUS_NOT_VALID:
+                                        // Will only set a new alarm if no safe mode alarm is
+                                        // currently scheduled.
+                                        setSafeModeAlarm();
+                                        break;
+                                    default:
+                                        Slog.wtf(
+                                                TAG,
+                                                "Unknown validation status "
+                                                        + status
+                                                        + "; ignoring");
+                                        break;
                                 }
                             } /* validationStatusCallback */);
 
diff --git a/services/core/jni/OWNERS b/services/core/jni/OWNERS
index bbcc2c1..e8050fa 100644
--- a/services/core/jni/OWNERS
+++ b/services/core/jni/OWNERS
@@ -29,3 +29,4 @@
 per-file com_android_server_security_* = file:/core/java/android/security/OWNERS
 per-file com_android_server_tv_* = file:/media/java/android/media/tv/OWNERS
 per-file com_android_server_vibrator_* = file:/services/core/java/com/android/server/vibrator/OWNERS
+per-file com_android_server_am_CachedAppOptimizer.cpp = timmurray@google.com, edgararriaga@google.com, dualli@google.com, carmenjackson@google.com, philipcuadra@google.com
\ No newline at end of file
diff --git a/services/profcollect/src/com/android/server/profcollect/ProfcollectForwardingService.java b/services/profcollect/src/com/android/server/profcollect/ProfcollectForwardingService.java
index 1208ecc..9706d7f 100644
--- a/services/profcollect/src/com/android/server/profcollect/ProfcollectForwardingService.java
+++ b/services/profcollect/src/com/android/server/profcollect/ProfcollectForwardingService.java
@@ -23,11 +23,13 @@
 import android.content.ComponentName;
 import android.content.Context;
 import android.content.Intent;
+import android.content.pm.ResolveInfo;
 import android.os.Handler;
 import android.os.IBinder.DeathRecipient;
 import android.os.Looper;
 import android.os.RemoteException;
 import android.os.ServiceManager;
+import android.os.SystemProperties;
 import android.os.UpdateEngine;
 import android.os.UpdateEngineCallback;
 import android.os.UserHandle;
@@ -42,6 +44,9 @@
 import com.android.server.wm.ActivityMetricsLaunchObserverRegistry;
 import com.android.server.wm.ActivityTaskManagerInternal;
 
+import java.nio.file.Files;
+import java.nio.file.Paths;
+import java.util.List;
 import java.util.concurrent.ThreadLocalRandom;
 import java.util.concurrent.TimeUnit;
 
@@ -75,7 +80,7 @@
      */
     public static boolean enabled() {
         return DeviceConfig.getBoolean(DeviceConfig.NAMESPACE_PROFCOLLECT_NATIVE_BOOT, "enabled",
-            false);
+            false) || SystemProperties.getBoolean("persist.profcollectd.enabled_override", false);
     }
 
     @Override
@@ -297,24 +302,20 @@
             return;
         }
 
-        final boolean uploadReport =
-                DeviceConfig.getBoolean(DeviceConfig.NAMESPACE_PROFCOLLECT_NATIVE_BOOT,
-                                        "upload_report", false);
-
         new Thread(() -> {
             try {
                 String reportUuid = mIProfcollect.report();
 
-                if (!uploadReport) {
+                final int profileId = getBBProfileId();
+                String reportDir = "/data/user/" + profileId
+                        + "/com.google.android.apps.internal.betterbug/cache/";
+                String reportPath = reportDir + reportUuid + ".zip";
+
+                if (!Files.exists(Paths.get(reportDir))) {
+                    Log.i(LOG_TAG, "Destination directory does not exist, abort upload.");
                     return;
                 }
 
-                final int profileId = getBBProfileId();
-                mIProfcollect.copy_report_to_bb(profileId, reportUuid);
-                String reportPath =
-                        "/data/user/" + profileId
-                        + "/com.google.android.apps.internal.betterbug/cache/"
-                        + reportUuid + ".zip";
                 Intent uploadIntent =
                         new Intent("com.google.android.apps.betterbug.intent.action.UPLOAD_PROFILE")
                         .setPackage("com.google.android.apps.internal.betterbug")
@@ -323,9 +324,15 @@
                         .putExtra("EXTRA_PROFILE_PATH", reportPath)
                         .addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
                 Context context = getContext();
-                if (context.getPackageManager().queryBroadcastReceivers(uploadIntent, 0) != null) {
-                    context.sendBroadcast(uploadIntent);
+
+                List<ResolveInfo> receivers =
+                        context.getPackageManager().queryBroadcastReceivers(uploadIntent, 0);
+                if (receivers == null || receivers.isEmpty()) {
+                    Log.i(LOG_TAG, "No one to receive upload intent, abort upload.");
+                    return;
                 }
+                mIProfcollect.copy_report_to_bb(profileId, reportUuid);
+                context.sendBroadcast(uploadIntent);
                 mIProfcollect.delete_report(reportUuid);
             } catch (RemoteException e) {
                 Log.e(LOG_TAG, e.getMessage());
diff --git a/telephony/common/com/android/internal/telephony/SipMessageParsingUtils.java b/telephony/common/com/android/internal/telephony/SipMessageParsingUtils.java
index 179248d..33b0bbd2 100644
--- a/telephony/common/com/android/internal/telephony/SipMessageParsingUtils.java
+++ b/telephony/common/com/android/internal/telephony/SipMessageParsingUtils.java
@@ -81,6 +81,15 @@
     }
 
     /**
+     * @return true if the SIP message start line is considered a response.
+     */
+    public static boolean isSipResponse(String startLine) {
+        String[] splitLine = splitStartLineAndVerify(startLine);
+        if (splitLine == null) return false;
+        return verifySipResponse(splitLine);
+    }
+
+    /**
      * Return the via branch parameter, which is used to identify the transaction ID (request and
      * response pair) in a SIP transaction.
      * @param headerString The string containing the headers of the SIP message.
@@ -140,7 +149,12 @@
         return !headers.isEmpty() ? headers.get(0).second : null;
     }
 
-    private static String[] splitStartLineAndVerify(String startLine) {
+    /**
+     * Validate that the start line is correct and split into its three segments.
+     * @param startLine The start line to verify and split.
+     * @return The split start line, which will always have three segments.
+     */
+    public static String[] splitStartLineAndVerify(String startLine) {
         String[] splitLine = startLine.split(" ");
         if (isStartLineMalformed(splitLine)) return null;
         return splitLine;
@@ -184,7 +198,7 @@
      *                           (This is internally an equalsIgnoreMatch comparison).
      * @return the matched header keys and values.
      */
-    private static List<Pair<String, String>> parseHeaders(String headerString,
+    public static List<Pair<String, String>> parseHeaders(String headerString,
             boolean stopAtFirstMatch, String... matchingHeaderKeys) {
         // Ensure there is no leading whitespace
         headerString = removeLeadingWhitespace(headerString);
diff --git a/telephony/java/android/telephony/PhysicalChannelConfig.java b/telephony/java/android/telephony/PhysicalChannelConfig.java
index 1c9cd94..8a4bb46 100644
--- a/telephony/java/android/telephony/PhysicalChannelConfig.java
+++ b/telephony/java/android/telephony/PhysicalChannelConfig.java
@@ -182,16 +182,6 @@
     }
 
     /**
-     * @return the absolute radio frequency channel number for this physical channel,
-     * {@link #CHANNEL_NUMBER_UNKNOWN} if unknown.
-     * @deprecated Use {@link #getDownlinkChannelNumber()} to get the channel number.
-     */
-    @Deprecated
-    public int getChannelNumber() {
-        return getDownlinkChannelNumber();
-    }
-
-    /**
      * @return the rough frequency range for this physical channel,
      * {@link ServiceState#FREQUENCY_RANGE_UNKNOWN} if unknown.
      * @see {@link ServiceState#FREQUENCY_RANGE_LOW}
diff --git a/telephony/java/android/telephony/TelephonyManager.java b/telephony/java/android/telephony/TelephonyManager.java
index 1cfb1d4..ae6a3e8 100644
--- a/telephony/java/android/telephony/TelephonyManager.java
+++ b/telephony/java/android/telephony/TelephonyManager.java
@@ -11205,26 +11205,26 @@
     }
 
     /**
-     * Return a list of certs in hex string from loaded carrier privileges access rules.
+     * Return a list of certs as hex strings from loaded carrier privileges access rules.
      *
-     * @return a list of certificate in hex string. return {@code null} if there is no certs
-     * or privilege rules are not loaded yet.
-     *
-     * <p>Requires Permission:
-     * {@link android.Manifest.permission#READ_PRIVILEGED_PHONE_STATE}
+     * @return a list of certificates as hex strings, or an empty list if there are no certs or
+     *     privilege rules are not loaded yet.
      * @hide
      */
+    @TestApi
     @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
+    @NonNull
     public List<String> getCertsFromCarrierPrivilegeAccessRules() {
+        List<String> certs = null;
         try {
             ITelephony service = getITelephony();
             if (service != null) {
-                return service.getCertsFromCarrierPrivilegeAccessRules(getSubId());
+                certs = service.getCertsFromCarrierPrivilegeAccessRules(getSubId());
             }
         } catch (RemoteException ex) {
             // This could happen if binder process crashes.
         }
-        return null;
+        return certs == null ? Collections.emptyList() : certs;
     }
 
     /**
diff --git a/telephony/java/android/telephony/ims/SipDelegateManager.java b/telephony/java/android/telephony/ims/SipDelegateManager.java
index 625364b..9258e44 100644
--- a/telephony/java/android/telephony/ims/SipDelegateManager.java
+++ b/telephony/java/android/telephony/ims/SipDelegateManager.java
@@ -80,13 +80,18 @@
     public static final int MESSAGE_FAILURE_REASON_DELEGATE_CLOSED = 2;
 
     /**
-     * The SIP message has an invalid start line and the message can not be sent.
+     * The SIP message has an invalid start line and the message can not be sent or the start line
+     * failed validation due to the request containing a restricted SIP request method.
+     * {@link SipDelegateConnection}s can not send SIP requests for the methods: REGISTER, PUBLISH,
+     * or OPTIONS.
      */
     public static final int MESSAGE_FAILURE_REASON_INVALID_START_LINE = 3;
 
     /**
      * One or more of the header fields in the header section of the outgoing SIP message is invalid
-     * and the SIP message can not be sent.
+     * or contains a restricted header value and the SIP message can not be sent.
+     * {@link SipDelegateConnection}s can not send SIP SUBSCRIBE requests for the "Event" header
+     * value of "presence".
      */
     public static final int MESSAGE_FAILURE_REASON_INVALID_HEADER_FIELDS = 4;
 
diff --git a/tests/vcn/java/android/net/vcn/VcnTransportInfoTest.java b/tests/vcn/java/android/net/vcn/VcnTransportInfoTest.java
index 3156190..582275d 100644
--- a/tests/vcn/java/android/net/vcn/VcnTransportInfoTest.java
+++ b/tests/vcn/java/android/net/vcn/VcnTransportInfoTest.java
@@ -16,6 +16,8 @@
 
 package android.net.vcn;
 
+import static android.net.NetworkCapabilities.REDACT_ALL;
+import static android.net.NetworkCapabilities.REDACT_FOR_NETWORK_SETTINGS;
 import static android.telephony.SubscriptionManager.INVALID_SUBSCRIPTION_ID;
 
 import static org.junit.Assert.assertEquals;
@@ -37,6 +39,12 @@
     private static final VcnTransportInfo WIFI_UNDERLYING_INFO = new VcnTransportInfo(WIFI_INFO);
 
     @Test
+    public void testRedactionDefaults() {
+        assertEquals(REDACT_ALL, CELL_UNDERLYING_INFO.getRedaction());
+        assertEquals(REDACT_ALL, WIFI_UNDERLYING_INFO.getRedaction());
+    }
+
+    @Test
     public void testGetWifiInfo() {
         assertEquals(WIFI_INFO, WIFI_UNDERLYING_INFO.getWifiInfo());
 
@@ -51,6 +59,18 @@
     }
 
     @Test
+    public void testMakeCopySetsRedactions() {
+        assertEquals(
+                REDACT_FOR_NETWORK_SETTINGS,
+                ((VcnTransportInfo) CELL_UNDERLYING_INFO.makeCopy(REDACT_FOR_NETWORK_SETTINGS))
+                        .getRedaction());
+        assertEquals(
+                REDACT_FOR_NETWORK_SETTINGS,
+                ((VcnTransportInfo) WIFI_UNDERLYING_INFO.makeCopy(REDACT_FOR_NETWORK_SETTINGS))
+                        .getRedaction());
+    }
+
+    @Test
     public void testEquals() {
         assertEquals(CELL_UNDERLYING_INFO, CELL_UNDERLYING_INFO);
         assertEquals(WIFI_UNDERLYING_INFO, WIFI_UNDERLYING_INFO);
@@ -64,8 +84,29 @@
     }
 
     private void verifyParcelingIsNull(VcnTransportInfo vcnTransportInfo) {
+        // Verify redacted by default
         Parcel parcel = Parcel.obtain();
         vcnTransportInfo.writeToParcel(parcel, 0 /* flags */);
+        parcel.setDataPosition(0);
+
         assertNull(VcnTransportInfo.CREATOR.createFromParcel(parcel));
     }
+
+    @Test
+    public void testParcelUnparcelNotRedactedForSysUi() {
+        verifyParcelingForSysUi(CELL_UNDERLYING_INFO);
+        verifyParcelingForSysUi(WIFI_UNDERLYING_INFO);
+    }
+
+    private void verifyParcelingForSysUi(VcnTransportInfo vcnTransportInfo) {
+        // Allow fully unredacted; SysUI will have all the relevant permissions.
+        final VcnTransportInfo unRedacted = (VcnTransportInfo) vcnTransportInfo.makeCopy(0);
+        final Parcel parcel = Parcel.obtain();
+        unRedacted.writeToParcel(parcel, 0 /* flags */);
+        parcel.setDataPosition(0);
+
+        final VcnTransportInfo unparceled = VcnTransportInfo.CREATOR.createFromParcel(parcel);
+        assertEquals(vcnTransportInfo, unparceled);
+        assertEquals(REDACT_ALL, unparceled.getRedaction());
+    }
 }
diff --git a/tests/vcn/java/com/android/server/vcn/VcnGatewayConnectionConnectedStateTest.java b/tests/vcn/java/com/android/server/vcn/VcnGatewayConnectionConnectedStateTest.java
index 90ee738..eedaac4 100644
--- a/tests/vcn/java/com/android/server/vcn/VcnGatewayConnectionConnectedStateTest.java
+++ b/tests/vcn/java/com/android/server/vcn/VcnGatewayConnectionConnectedStateTest.java
@@ -343,6 +343,31 @@
         assertFalse(mGatewayConnection.isInSafeMode());
     }
 
+    @Test
+    public void testSubsequentFailedValidationTriggersSafeMode() throws Exception {
+        triggerChildOpened();
+        mTestLooper.dispatchAll();
+
+        triggerValidation(NetworkAgent.VALIDATION_STATUS_VALID);
+        assertFalse(mGatewayConnection.isInSafeMode());
+
+        // Trigger a failed validation, and the subsequent safemode timeout.
+        triggerValidation(NetworkAgent.VALIDATION_STATUS_NOT_VALID);
+        mTestLooper.dispatchAll();
+
+        final ArgumentCaptor<Runnable> runnableCaptor = ArgumentCaptor.forClass(Runnable.class);
+        verify(mDeps, times(2))
+                .newWakeupMessage(
+                        eq(mVcnContext),
+                        any(),
+                        eq(VcnGatewayConnection.SAFEMODE_TIMEOUT_ALARM),
+                        runnableCaptor.capture());
+        runnableCaptor.getValue().run();
+        mTestLooper.dispatchAll();
+
+        assertTrue(mGatewayConnection.isInSafeMode());
+    }
+
     private Consumer<VcnNetworkAgent> setupNetworkAndGetUnwantedCallback() {
         triggerChildOpened();
         mTestLooper.dispatchAll();