Merge "Fix min size in TaskFragmentOrganizerControllerTest" into main
diff --git a/apct-tests/perftests/core/src/android/graphics/perftests/TypefaceSerializationPerfTest.java b/apct-tests/perftests/core/src/android/graphics/perftests/TypefaceSerializationPerfTest.java
index bc8fc53..2de6f36 100644
--- a/apct-tests/perftests/core/src/android/graphics/perftests/TypefaceSerializationPerfTest.java
+++ b/apct-tests/perftests/core/src/android/graphics/perftests/TypefaceSerializationPerfTest.java
@@ -147,28 +147,4 @@
             out.clear();
         }
     }
-
-    @ManualBenchmarkState.ManualBenchmarkTest(
-            warmupDurationNs = WARMUP_DURATION_NS,
-            targetTestDurationNs = TARGET_TEST_DURATION_NS)
-    @Test
-    public void testSetSystemFontMap() throws Exception {
-        SharedMemory memory = null;
-        ManualBenchmarkState state = mPerfManualStatusReporter.getBenchmarkState();
-
-        long elapsedTime = 0;
-        while (state.keepRunning(elapsedTime)) {
-            // Explicitly destroy lazy-loaded typefaces, so that we don't hit the mmap limit
-            // (max_map_count).
-            Typeface.destroySystemFontMap();
-            Typeface.loadPreinstalledSystemFontMap();
-            if (memory != null) {
-                memory.close();
-            }
-            memory = Typeface.serializeFontMap(Typeface.getSystemFontMap());
-            long startTime = System.nanoTime();
-            Typeface.setSystemFontMap(memory);
-            elapsedTime = System.nanoTime() - startTime;
-        }
-    }
 }
diff --git a/core/java/android/app/ApplicationPackageManager.java b/core/java/android/app/ApplicationPackageManager.java
index 9121cf0..7be4b15 100644
--- a/core/java/android/app/ApplicationPackageManager.java
+++ b/core/java/android/app/ApplicationPackageManager.java
@@ -179,6 +179,10 @@
     @GuardedBy("mDelegates")
     private final ArrayList<MoveCallbackDelegate> mDelegates = new ArrayList<>();
 
+    @NonNull
+    @GuardedBy("mPackageMonitorCallbacks")
+    private final ArraySet<IRemoteCallback> mPackageMonitorCallbacks = new ArraySet<>();
+
     UserManager getUserManager() {
         if (mUserManager == null) {
             mUserManager = UserManager.get(mContext);
@@ -3926,6 +3930,14 @@
         Objects.requireNonNull(callback);
         try {
             mPM.registerPackageMonitorCallback(callback, userId);
+            synchronized (mPackageMonitorCallbacks) {
+                if (mPackageMonitorCallbacks.contains(callback)) {
+                    throw new IllegalStateException(
+                            "registerPackageMonitorCallback: callback already registered: "
+                                    + callback);
+                }
+                mPackageMonitorCallbacks.add(callback);
+            }
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
         }
@@ -3936,6 +3948,9 @@
         Objects.requireNonNull(callback);
         try {
             mPM.unregisterPackageMonitorCallback(callback);
+            synchronized (mPackageMonitorCallbacks) {
+                mPackageMonitorCallbacks.remove(callback);
+            }
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
         }
diff --git a/core/java/android/hardware/fingerprint/FingerprintAuthenticateOptions.java b/core/java/android/hardware/fingerprint/FingerprintAuthenticateOptions.java
index 763246e..dc66542 100644
--- a/core/java/android/hardware/fingerprint/FingerprintAuthenticateOptions.java
+++ b/core/java/android/hardware/fingerprint/FingerprintAuthenticateOptions.java
@@ -21,6 +21,7 @@
 import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.hardware.biometrics.AuthenticateOptions;
+import android.hardware.biometrics.common.AuthenticateReason;
 import android.os.Parcelable;
 
 import com.android.internal.util.DataClass;
@@ -85,7 +86,16 @@
         return null;
     }
 
-
+    /**
+     * The Vendor extension, if any.
+     *
+     * This option may be present when a vendor would like to send additional information for each
+     * auth attempt.
+     */
+    @Nullable private AuthenticateReason.Vendor mVendorReason;
+    private static AuthenticateReason.Vendor defaultVendorReason() {
+        return null;
+    }
 
     // Code below generated by codegen v1.0.23.
     //
@@ -107,7 +117,8 @@
             boolean ignoreEnrollmentState,
             @AuthenticateOptions.DisplayState int displayState,
             @NonNull String opPackageName,
-            @Nullable String attributionTag) {
+            @Nullable String attributionTag,
+            @Nullable AuthenticateReason.Vendor vendorReason) {
         this.mUserId = userId;
         this.mSensorId = sensorId;
         this.mIgnoreEnrollmentState = ignoreEnrollmentState;
@@ -118,6 +129,7 @@
         com.android.internal.util.AnnotationValidations.validate(
                 NonNull.class, null, mOpPackageName);
         this.mAttributionTag = attributionTag;
+        this.mVendorReason = vendorReason;
 
         // onConstructed(); // You can define this method to get a callback
     }
@@ -176,6 +188,17 @@
     }
 
     /**
+     * The Vendor extension, if any.
+     *
+     * This option may be present when a vendor would like to send additional information for each
+     * auth attempt.
+     */
+    @DataClass.Generated.Member
+    public @Nullable AuthenticateReason.Vendor getVendorReason() {
+        return mVendorReason;
+    }
+
+    /**
      * The sensor id for this operation.
      */
     @DataClass.Generated.Member
@@ -209,6 +232,18 @@
         return this;
     }
 
+    /**
+     * The Vendor extension, if any.
+     *
+     * This option may be present when a vendor would like to send additional information for each
+     * auth attempt.
+     */
+    @DataClass.Generated.Member
+    public @NonNull FingerprintAuthenticateOptions setVendorReason(@NonNull AuthenticateReason.Vendor value) {
+        mVendorReason = value;
+        return this;
+    }
+
     @Override
     @DataClass.Generated.Member
     public boolean equals(@Nullable Object o) {
@@ -227,7 +262,8 @@
                 && mIgnoreEnrollmentState == that.mIgnoreEnrollmentState
                 && mDisplayState == that.mDisplayState
                 && java.util.Objects.equals(mOpPackageName, that.mOpPackageName)
-                && java.util.Objects.equals(mAttributionTag, that.mAttributionTag);
+                && java.util.Objects.equals(mAttributionTag, that.mAttributionTag)
+                && java.util.Objects.equals(mVendorReason, that.mVendorReason);
     }
 
     @Override
@@ -243,6 +279,7 @@
         _hash = 31 * _hash + mDisplayState;
         _hash = 31 * _hash + java.util.Objects.hashCode(mOpPackageName);
         _hash = 31 * _hash + java.util.Objects.hashCode(mAttributionTag);
+        _hash = 31 * _hash + java.util.Objects.hashCode(mVendorReason);
         return _hash;
     }
 
@@ -255,12 +292,14 @@
         byte flg = 0;
         if (mIgnoreEnrollmentState) flg |= 0x4;
         if (mAttributionTag != null) flg |= 0x20;
+        if (mVendorReason != null) flg |= 0x40;
         dest.writeByte(flg);
         dest.writeInt(mUserId);
         dest.writeInt(mSensorId);
         dest.writeInt(mDisplayState);
         dest.writeString(mOpPackageName);
         if (mAttributionTag != null) dest.writeString(mAttributionTag);
+        if (mVendorReason != null) dest.writeTypedObject(mVendorReason, flags);
     }
 
     @Override
@@ -281,6 +320,7 @@
         int displayState = in.readInt();
         String opPackageName = in.readString();
         String attributionTag = (flg & 0x20) == 0 ? null : in.readString();
+        AuthenticateReason.Vendor vendorReason = (flg & 0x40) == 0 ? null : (AuthenticateReason.Vendor) in.readTypedObject(AuthenticateReason.Vendor.CREATOR);
 
         this.mUserId = userId;
         this.mSensorId = sensorId;
@@ -292,6 +332,7 @@
         com.android.internal.util.AnnotationValidations.validate(
                 NonNull.class, null, mOpPackageName);
         this.mAttributionTag = attributionTag;
+        this.mVendorReason = vendorReason;
 
         // onConstructed(); // You can define this method to get a callback
     }
@@ -323,6 +364,7 @@
         private @AuthenticateOptions.DisplayState int mDisplayState;
         private @NonNull String mOpPackageName;
         private @Nullable String mAttributionTag;
+        private @Nullable AuthenticateReason.Vendor mVendorReason;
 
         private long mBuilderFieldsSet = 0L;
 
@@ -400,10 +442,24 @@
             return this;
         }
 
+        /**
+         * The Vendor extension, if any.
+         *
+         * This option may be present when a vendor would like to send additional information for each
+         * auth attempt.
+         */
+        @DataClass.Generated.Member
+        public @NonNull Builder setVendorReason(@NonNull AuthenticateReason.Vendor value) {
+            checkNotUsed();
+            mBuilderFieldsSet |= 0x40;
+            mVendorReason = value;
+            return this;
+        }
+
         /** Builds the instance. This builder should not be touched after calling this! */
         public @NonNull FingerprintAuthenticateOptions build() {
             checkNotUsed();
-            mBuilderFieldsSet |= 0x40; // Mark builder used
+            mBuilderFieldsSet |= 0x80; // Mark builder used
 
             if ((mBuilderFieldsSet & 0x1) == 0) {
                 mUserId = defaultUserId();
@@ -423,18 +479,22 @@
             if ((mBuilderFieldsSet & 0x20) == 0) {
                 mAttributionTag = defaultAttributionTag();
             }
+            if ((mBuilderFieldsSet & 0x40) == 0) {
+                mVendorReason = defaultVendorReason();
+            }
             FingerprintAuthenticateOptions o = new FingerprintAuthenticateOptions(
                     mUserId,
                     mSensorId,
                     mIgnoreEnrollmentState,
                     mDisplayState,
                     mOpPackageName,
-                    mAttributionTag);
+                    mAttributionTag,
+                    mVendorReason);
             return o;
         }
 
         private void checkNotUsed() {
-            if ((mBuilderFieldsSet & 0x40) != 0) {
+            if ((mBuilderFieldsSet & 0x80) != 0) {
                 throw new IllegalStateException(
                         "This Builder should not be reused. Use a new Builder instance instead");
             }
@@ -442,10 +502,10 @@
     }
 
     @DataClass.Generated(
-            time = 1677119626721L,
+            time = 1689703591032L,
             codegenVersion = "1.0.23",
             sourceFile = "frameworks/base/core/java/android/hardware/fingerprint/FingerprintAuthenticateOptions.java",
-            inputSignatures = "private final  int mUserId\nprivate  int mSensorId\nprivate final  boolean mIgnoreEnrollmentState\nprivate final @android.hardware.biometrics.AuthenticateOptions.DisplayState int mDisplayState\nprivate @android.annotation.NonNull java.lang.String mOpPackageName\nprivate @android.annotation.Nullable java.lang.String mAttributionTag\nprivate static  int defaultUserId()\nprivate static  int defaultSensorId()\nprivate static  boolean defaultIgnoreEnrollmentState()\nprivate static  int defaultDisplayState()\nprivate static  java.lang.String defaultOpPackageName()\nprivate static  java.lang.String defaultAttributionTag()\nclass FingerprintAuthenticateOptions extends java.lang.Object implements [android.hardware.biometrics.AuthenticateOptions, android.os.Parcelable]\n@com.android.internal.util.DataClass(genParcelable=true, genAidl=true, genBuilder=true, genSetters=true, genEqualsHashCode=true)")
+            inputSignatures = "private final  int mUserId\nprivate  int mSensorId\nprivate final  boolean mIgnoreEnrollmentState\nprivate final @android.hardware.biometrics.AuthenticateOptions.DisplayState int mDisplayState\nprivate @android.annotation.NonNull java.lang.String mOpPackageName\nprivate @android.annotation.Nullable java.lang.String mAttributionTag\nprivate @android.annotation.Nullable android.hardware.biometrics.common.AuthenticateReason.Vendor mVendorReason\nprivate static  int defaultUserId()\nprivate static  int defaultSensorId()\nprivate static  boolean defaultIgnoreEnrollmentState()\nprivate static  int defaultDisplayState()\nprivate static  java.lang.String defaultOpPackageName()\nprivate static  java.lang.String defaultAttributionTag()\nprivate static  android.hardware.biometrics.common.AuthenticateReason.Vendor defaultVendorReason()\nclass FingerprintAuthenticateOptions extends java.lang.Object implements [android.hardware.biometrics.AuthenticateOptions, android.os.Parcelable]\n@com.android.internal.util.DataClass(genParcelable=true, genAidl=true, genBuilder=true, genSetters=true, genEqualsHashCode=true)")
     @Deprecated
     private void __metadata() {}
 
diff --git a/core/java/android/os/UserManager.java b/core/java/android/os/UserManager.java
index ba1f979..d8cf4de 100644
--- a/core/java/android/os/UserManager.java
+++ b/core/java/android/os/UserManager.java
@@ -4618,6 +4618,26 @@
     }
 
     /**
+     * Returns number of full users on the device.
+     * @hide
+     */
+    @RequiresPermission(anyOf = {
+            android.Manifest.permission.MANAGE_USERS,
+            android.Manifest.permission.CREATE_USERS
+    })
+    public int getFullUserCount() {
+        List<UserInfo> users = getUsers(/* excludePartial= */ true, /* excludeDying= */ true,
+                /* excludePreCreated= */ true);
+        int count = 0;
+        for (UserInfo user : users) {
+            if (user.isFull()) {
+                count++;
+            }
+        }
+        return count;
+    }
+
+    /**
      * @deprecated use {@link #getAliveUsers()} for {@code getUsers(true)}, or
      * {@link #getUsers()} for @code getUsers(false)}.
      *
diff --git a/core/tests/packagemonitortests/src/com/android/internal/content/PackageMonitorVisibilityTest.java b/core/tests/packagemonitortests/src/com/android/internal/content/PackageMonitorVisibilityTest.java
index a310edc..da8e4cc 100644
--- a/core/tests/packagemonitortests/src/com/android/internal/content/PackageMonitorVisibilityTest.java
+++ b/core/tests/packagemonitortests/src/com/android/internal/content/PackageMonitorVisibilityTest.java
@@ -20,9 +20,12 @@
 
 import static com.google.common.truth.Truth.assertThat;
 
+import static org.junit.Assert.assertThrows;
+
 import android.content.Context;
 import android.content.pm.PackageManager;
 import android.os.Handler;
+import android.os.IRemoteCallback;
 import android.os.Looper;
 import android.os.UserHandle;
 
@@ -45,6 +48,25 @@
             TEST_DATA_PATH + "TestVisibilityApp.apk";
     private static final String TEAT_APK_PACKAGE_NAME = "com.example.android.testvisibilityapp";
     private static final int WAIT_CALLBACK_CALLED_IN_SECONDS = 1;
+
+    @Test
+    public void testPackageMonitorCallbackMultipleRegisterThrowsException() throws Exception {
+        Context context = InstrumentationRegistry.getInstrumentation().getContext();
+        final IRemoteCallback callback = new IRemoteCallback.Stub() {
+            @Override
+            public void sendResult(android.os.Bundle bundle) {
+                // do-nothing
+            }
+        };
+        try {
+            context.getPackageManager().registerPackageMonitorCallback(callback, 0);
+            assertThrows(IllegalStateException.class,
+                    () -> context.getPackageManager().registerPackageMonitorCallback(callback, 0));
+        } finally {
+            context.getPackageManager().unregisterPackageMonitorCallback(callback);
+        }
+    }
+
     @Test
     public void testPackageMonitorPackageVisible() throws Exception {
         TestVisibilityPackageMonitor testPackageMonitor = new TestVisibilityPackageMonitor();
diff --git a/packages/SettingsLib/Spa/build.gradle.kts b/packages/SettingsLib/Spa/build.gradle.kts
index e76139f..1cc2867 100644
--- a/packages/SettingsLib/Spa/build.gradle.kts
+++ b/packages/SettingsLib/Spa/build.gradle.kts
@@ -14,6 +14,7 @@
  * limitations under the License.
  */
 
+import com.android.build.api.dsl.CommonExtension
 import com.android.build.gradle.BaseExtension
 import com.android.build.gradle.api.AndroidBasePlugin
 import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
@@ -25,7 +26,7 @@
 }
 
 allprojects {
-    extra["jetpackComposeVersion"] = "1.6.0-alpha01"
+    extra["jetpackComposeVersion"] = "1.6.0-alpha02"
 }
 
 subprojects {
@@ -47,10 +48,10 @@
 
     afterEvaluate {
         plugins.withType<AndroidBasePlugin> {
-            configure<BaseExtension> {
+            the(CommonExtension::class).apply {
                 if (buildFeatures.compose == true) {
                     composeOptions {
-                        kotlinCompilerExtensionVersion = "1.4.4"
+                        kotlinCompilerExtensionVersion = libs.versions.compose.compiler.get()
                     }
                 }
             }
diff --git a/packages/SettingsLib/Spa/gradle/libs.versions.toml b/packages/SettingsLib/Spa/gradle/libs.versions.toml
index ee40b02..0f467b9 100644
--- a/packages/SettingsLib/Spa/gradle/libs.versions.toml
+++ b/packages/SettingsLib/Spa/gradle/libs.versions.toml
@@ -16,8 +16,9 @@
 
 [versions]
 agp = "8.1.0"
+compose-compiler = "1.5.1"
 dexmaker-mockito = "2.28.3"
-kotlin = "1.8.10"
+kotlin = "1.9.0"
 truth = "1.1"
 
 [libraries]
diff --git a/packages/SettingsLib/Spa/spa/build.gradle.kts b/packages/SettingsLib/Spa/spa/build.gradle.kts
index 73ec251..84198de 100644
--- a/packages/SettingsLib/Spa/spa/build.gradle.kts
+++ b/packages/SettingsLib/Spa/spa/build.gradle.kts
@@ -63,7 +63,7 @@
     api("androidx.compose.ui:ui-tooling-preview:$jetpackComposeVersion")
     api("androidx.lifecycle:lifecycle-livedata-ktx")
     api("androidx.lifecycle:lifecycle-runtime-compose")
-    api("androidx.navigation:navigation-compose:2.7.0-beta01")
+    api("androidx.navigation:navigation-compose:2.7.0-rc01")
     api("com.github.PhilJay:MPAndroidChart:v3.1.0-alpha")
     api("com.google.android.material:material:1.7.0-alpha03")
     debugApi("androidx.compose.ui:ui-tooling:$jetpackComposeVersion")
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardFingerprintListenModel.kt b/packages/SystemUI/src/com/android/keyguard/KeyguardFingerprintListenModel.kt
index f23ae67..4160ae1 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardFingerprintListenModel.kt
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardFingerprintListenModel.kt
@@ -42,7 +42,6 @@
     var keyguardIsVisible: Boolean = false,
     var keyguardOccluded: Boolean = false,
     var occludingAppRequestingFp: Boolean = false,
-    var shouldListenSfpsState: Boolean = false,
     var shouldListenForFingerprintAssistant: Boolean = false,
     var strongerAuthRequired: Boolean = false,
     var switchingUser: Boolean = false,
@@ -74,7 +73,6 @@
             keyguardIsVisible.toString(),
             keyguardOccluded.toString(),
             occludingAppRequestingFp.toString(),
-            shouldListenSfpsState.toString(),
             shouldListenForFingerprintAssistant.toString(),
             strongerAuthRequired.toString(),
             switchingUser.toString(),
@@ -115,7 +113,6 @@
                 keyguardIsVisible = model.keyguardIsVisible
                 keyguardOccluded = model.keyguardOccluded
                 occludingAppRequestingFp = model.occludingAppRequestingFp
-                shouldListenSfpsState = model.shouldListenSfpsState
                 shouldListenForFingerprintAssistant = model.shouldListenForFingerprintAssistant
                 strongerAuthRequired = model.strongerAuthRequired
                 switchingUser = model.switchingUser
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java b/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java
index 853a62a..0ba6c05 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java
@@ -3128,18 +3128,9 @@
                 && !strongerAuthRequired
                 && userDoesNotHaveTrust);
 
-        boolean shouldListenSideFpsState = true;
-        if (isSideFps) {
-            final boolean interactiveToAuthEnabled =
-                    mFingerprintInteractiveToAuthProvider != null &&
-                            mFingerprintInteractiveToAuthProvider.isEnabled(getCurrentUser());
-            shouldListenSideFpsState =
-                    interactiveToAuthEnabled ? isDeviceInteractive() && !mGoingToSleep : true;
-        }
 
         boolean shouldListen = shouldListenKeyguardState && shouldListenUserState
-                && shouldListenBouncerState && shouldListenUdfpsState
-                && shouldListenSideFpsState;
+                && shouldListenBouncerState && shouldListenUdfpsState;
         logListenerModelData(
                 new KeyguardFingerprintListenModel(
                     System.currentTimeMillis(),
@@ -3160,7 +3151,6 @@
                     isKeyguardVisible(),
                     mKeyguardOccluded,
                     mOccludingAppRequestingFp,
-                    shouldListenSideFpsState,
                     shouldListenForFingerprintAssistant,
                     strongerAuthRequired,
                     mSwitchingUser,
@@ -3314,6 +3304,9 @@
                         mFingerprintDetectionCallback,
                         new FingerprintAuthenticateOptions.Builder()
                                 .setUserId(userId)
+                                .setVendorReason(
+                                        mFingerprintInteractiveToAuthProvider.getVendorExtension(
+                                                getCurrentUser()))
                                 .build());
             } else {
                 mLogger.v("startListeningForFingerprint");
@@ -3322,6 +3315,9 @@
                         null /* handler */,
                         new FingerprintAuthenticateOptions.Builder()
                                 .setUserId(userId)
+                                .setVendorReason(
+                                        mFingerprintInteractiveToAuthProvider.getVendorExtension(
+                                                getCurrentUser()))
                                 .build()
                 );
             }
@@ -4497,14 +4493,6 @@
             } else if (isSfpsSupported()) {
                 pw.println("        sfpsEnrolled=" + isSfpsEnrolled());
                 pw.println("        shouldListenForSfps=" + shouldListenForFingerprint(false));
-                if (isSfpsEnrolled()) {
-                    final boolean interactiveToAuthEnabled =
-                                    mFingerprintInteractiveToAuthProvider != null &&
-                                            mFingerprintInteractiveToAuthProvider
-                                            .isEnabled(getCurrentUser());
-                    pw.println("        interactiveToAuthEnabled="
-                            + interactiveToAuthEnabled);
-                }
             }
             new DumpsysTableLogger(
                     "KeyguardFingerprintListen",
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/FingerprintInteractiveToAuthProvider.java b/packages/SystemUI/src/com/android/systemui/biometrics/FingerprintInteractiveToAuthProvider.java
index 902bb18..4bc07e8 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/FingerprintInteractiveToAuthProvider.java
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/FingerprintInteractiveToAuthProvider.java
@@ -16,6 +16,8 @@
 
 package com.android.systemui.biometrics;
 
+import android.hardware.biometrics.common.AuthenticateReason;
+
 /** Provides the status of the interactive to auth feature. */
 public interface FingerprintInteractiveToAuthProvider {
     /**
@@ -24,4 +26,11 @@
      * @return true if the InteractiveToAuthFeature is enabled, false if disabled.
      */
     boolean isEnabled(int userId);
+
+    /**
+     *
+     * @param userId the user Id.
+     * @return Vendor extension if needed for authentication.
+     */
+    AuthenticateReason.Vendor getVendorExtension(int userId);
 }
diff --git a/packages/SystemUI/src/com/android/systemui/wallpapers/ImageWallpaper.java b/packages/SystemUI/src/com/android/systemui/wallpapers/ImageWallpaper.java
index 316b54e..9dca013 100644
--- a/packages/SystemUI/src/com/android/systemui/wallpapers/ImageWallpaper.java
+++ b/packages/SystemUI/src/com/android/systemui/wallpapers/ImageWallpaper.java
@@ -133,6 +133,7 @@
             setShowForAllUsers(true);
             mWallpaperLocalColorExtractor = new WallpaperLocalColorExtractor(
                     mLongExecutor,
+                    mLock,
                     new WallpaperLocalColorExtractor.WallpaperLocalColorExtractorCallback() {
                         @Override
                         public void onColorsProcessed(List<RectF> regions,
diff --git a/packages/SystemUI/src/com/android/systemui/wallpapers/WallpaperLocalColorExtractor.java b/packages/SystemUI/src/com/android/systemui/wallpapers/WallpaperLocalColorExtractor.java
index 1e8446f..e2ec8dc 100644
--- a/packages/SystemUI/src/com/android/systemui/wallpapers/WallpaperLocalColorExtractor.java
+++ b/packages/SystemUI/src/com/android/systemui/wallpapers/WallpaperLocalColorExtractor.java
@@ -61,7 +61,7 @@
     private int mBitmapWidth = -1;
     private int mBitmapHeight = -1;
 
-    private final Object mLock = new Object();
+    private final Object mLock;
 
     private final List<RectF> mPendingRegions = new ArrayList<>();
     private final Set<RectF> mProcessedRegions = new ArraySet<>();
@@ -102,12 +102,15 @@
     /**
      * Creates a new color extractor.
      * @param longExecutor the executor on which the color extraction will be performed
+     * @param lock the lock object to use for computing colors or processing the bitmap
      * @param wallpaperLocalColorExtractorCallback an interface to handle the callbacks from
      *                                        the color extractor.
      */
     public WallpaperLocalColorExtractor(@LongRunning Executor longExecutor,
+            Object lock,
             WallpaperLocalColorExtractorCallback wallpaperLocalColorExtractorCallback) {
         mLongExecutor = longExecutor;
+        mLock = lock;
         mWallpaperLocalColorExtractorCallback = wallpaperLocalColorExtractorCallback;
     }
 
@@ -149,6 +152,12 @@
 
     private void onBitmapChangedSynchronized(@NonNull Bitmap bitmap) {
         synchronized (mLock) {
+            if (bitmap.isRecycled()) {
+                // ImageWallpaper loaded a new bitmap before the extraction of the previous one
+                // In that case, ImageWallpaper also scheduled the extraction of the next bitmap
+                Log.i(TAG, "Wallpaper has changed; deferring color extraction");
+                return;
+            }
             if (bitmap.getWidth() <= 0 || bitmap.getHeight() <= 0) {
                 Log.e(TAG, "Attempt to extract colors from an invalid bitmap");
                 return;
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java
index 6f3322a..0cd82f0 100644
--- a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java
+++ b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java
@@ -1694,71 +1694,6 @@
     }
 
     @Test
-    public void startsListeningForSfps_whenKeyguardIsVisible_ifRequireInteractiveToAuthEnabled()
-            throws RemoteException {
-        // SFPS supported and enrolled
-        when(mAuthController.isSfpsSupported()).thenReturn(true);
-        when(mAuthController.isSfpsEnrolled(anyInt())).thenReturn(true);
-
-        // WHEN require interactive to auth is disabled, and keyguard is not awake
-        when(mInteractiveToAuthProvider.isEnabled(anyInt())).thenReturn(false);
-
-        // Preconditions for sfps auth to run
-        keyguardNotGoingAway();
-        currentUserIsSystem();
-        currentUserDoesNotHaveTrust();
-        biometricsNotDisabledThroughDevicePolicyManager();
-        biometricsEnabledForCurrentUser();
-        userNotCurrentlySwitching();
-
-        statusBarShadeIsLocked();
-        mTestableLooper.processAllMessages();
-
-        // THEN we should listen for sfps when screen off, because require screen on is disabled
-        assertThat(mKeyguardUpdateMonitor.shouldListenForFingerprint(false)).isTrue();
-
-        // WHEN require interactive to auth is enabled, and keyguard is not awake
-        when(mInteractiveToAuthProvider.isEnabled(anyInt())).thenReturn(true);
-
-        // THEN we shouldn't listen for sfps when screen off, because require screen on is enabled
-        assertThat(mKeyguardUpdateMonitor.shouldListenForFingerprint(false)).isFalse();
-
-        // Device now awake & keyguard is now interactive
-        deviceNotGoingToSleep();
-        deviceIsInteractive();
-        keyguardIsVisible();
-
-        // THEN we should listen for sfps when screen on, and require screen on is enabled
-        assertThat(mKeyguardUpdateMonitor.shouldListenForFingerprint(false)).isTrue();
-    }
-
-    @Test
-    public void notListeningForSfps_whenGoingToSleep_ifRequireInteractiveToAuthEnabled()
-            throws RemoteException {
-        // GIVEN SFPS supported and enrolled
-        when(mAuthController.isSfpsSupported()).thenReturn(true);
-        when(mAuthController.isSfpsEnrolled(anyInt())).thenReturn(true);
-
-        // GIVEN Preconditions for sfps auth to run
-        keyguardNotGoingAway();
-        currentUserIsSystem();
-        currentUserDoesNotHaveTrust();
-        biometricsNotDisabledThroughDevicePolicyManager();
-        biometricsEnabledForCurrentUser();
-        userNotCurrentlySwitching();
-        statusBarShadeIsLocked();
-
-        // WHEN require interactive to auth is enabled & keyguard is going to sleep
-        when(mInteractiveToAuthProvider.isEnabled(anyInt())).thenReturn(true);
-        deviceGoingToSleep();
-
-        mTestableLooper.processAllMessages();
-
-        // THEN we should NOT listen for sfps because device is going to sleep
-        assertThat(mKeyguardUpdateMonitor.shouldListenForFingerprint(false)).isFalse();
-    }
-
-    @Test
     public void listeningForSfps_whenGoingToSleep_ifRequireInteractiveToAuthDisabled()
             throws RemoteException {
         // GIVEN SFPS supported and enrolled
diff --git a/packages/SystemUI/tests/src/com/android/systemui/wallpapers/WallpaperLocalColorExtractorTest.java b/packages/SystemUI/tests/src/com/android/systemui/wallpapers/WallpaperLocalColorExtractorTest.java
index fc5f782..1125d41 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/wallpapers/WallpaperLocalColorExtractorTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/wallpapers/WallpaperLocalColorExtractorTest.java
@@ -109,6 +109,7 @@
 
         WallpaperLocalColorExtractor colorExtractor = new WallpaperLocalColorExtractor(
                 mBackgroundExecutor,
+                new Object(),
                 new WallpaperLocalColorExtractor.WallpaperLocalColorExtractorCallback() {
                     @Override
                     public void onColorsProcessed(List<RectF> regions,
diff --git a/services/core/java/com/android/server/biometrics/log/OperationContextExt.java b/services/core/java/com/android/server/biometrics/log/OperationContextExt.java
index 4a10e8e..f78ca43 100644
--- a/services/core/java/com/android/server/biometrics/log/OperationContextExt.java
+++ b/services/core/java/com/android/server/biometrics/log/OperationContextExt.java
@@ -103,8 +103,14 @@
      */
     @NonNull
     public OperationContext toAidlContext(@NonNull FingerprintAuthenticateOptions options) {
-        mAidlContext.authenticateReason = AuthenticateReason
-                .fingerprintAuthenticateReason(getAuthReason(options));
+        if (options.getVendorReason() != null) {
+            mAidlContext.authenticateReason = AuthenticateReason
+                    .vendorAuthenticateReason(options.getVendorReason());
+
+        } else {
+            mAidlContext.authenticateReason = AuthenticateReason
+                    .fingerprintAuthenticateReason(getAuthReason(options));
+        }
         mAidlContext.wakeReason = getWakeReason(options);
 
         return mAidlContext;
diff --git a/services/tests/servicestests/src/com/android/server/pm/UserManagerTest.java b/services/tests/servicestests/src/com/android/server/pm/UserManagerTest.java
index d77ceb2..cb659b6 100644
--- a/services/tests/servicestests/src/com/android/server/pm/UserManagerTest.java
+++ b/services/tests/servicestests/src/com/android/server/pm/UserManagerTest.java
@@ -326,6 +326,24 @@
         assertThat(hasUser(user2.id)).isTrue();
     }
 
+
+    @MediumTest
+    @Test
+    public void testGetFullUserCount() throws Exception {
+        assertThat(mUserManager.getFullUserCount()).isEqualTo(1);
+        UserInfo user1 = createUser("User 1", UserInfo.FLAG_FULL);
+        UserInfo user2 = createUser("User 2", UserInfo.FLAG_ADMIN);
+
+        assertThat(user1).isNotNull();
+        assertThat(user2).isNotNull();
+
+        assertThat(mUserManager.getFullUserCount()).isEqualTo(3);
+        removeUser(user1.id);
+        assertThat(mUserManager.getFullUserCount()).isEqualTo(2);
+        removeUser(user2.id);
+        assertThat(mUserManager.getFullUserCount()).isEqualTo(1);
+    }
+
     /**
      * Tests that UserManager knows how many users can be created.
      *
diff --git a/services/tests/wmtests/src/com/android/server/wm/ActivityTaskManagerServiceTests.java b/services/tests/wmtests/src/com/android/server/wm/ActivityTaskManagerServiceTests.java
index 4290f4b..d169a58 100644
--- a/services/tests/wmtests/src/com/android/server/wm/ActivityTaskManagerServiceTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/ActivityTaskManagerServiceTests.java
@@ -490,6 +490,11 @@
                 .build();
         final Task task = activity.getTask();
         final TaskDisplayArea tda = task.getDisplayArea();
+        // Ensure the display is not a large screen
+        if (tda.getConfiguration().smallestScreenWidthDp
+                >= WindowManager.LARGE_SCREEN_SMALLEST_SCREEN_WIDTH_DP) {
+            resizeDisplay(activity.mDisplayContent, 500, 800);
+        }
 
         // Ignore the activity min width/height for determine multi window eligibility.
         mAtm.mRespectsActivityMinWidthHeightMultiWindow = -1;
diff --git a/services/tests/wmtests/src/com/android/server/wm/RecentsAnimationControllerTest.java b/services/tests/wmtests/src/com/android/server/wm/RecentsAnimationControllerTest.java
index 6e52af1..c1be5ca 100644
--- a/services/tests/wmtests/src/com/android/server/wm/RecentsAnimationControllerTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/RecentsAnimationControllerTest.java
@@ -353,6 +353,7 @@
 
     @Test
     public void testRecentViewInFixedPortraitWhenTopAppInLandscape() {
+        makeDisplayPortrait(mDefaultDisplay);
         unblockDisplayRotation(mDefaultDisplay);
         mWm.setRecentsAnimationController(mController);
 
@@ -488,6 +489,7 @@
 
     @Test
     public void testWallpaperHasFixedRotationApplied() {
+        makeDisplayPortrait(mDefaultDisplay);
         unblockDisplayRotation(mDefaultDisplay);
         mWm.setRecentsAnimationController(mController);
 
diff --git a/services/tests/wmtests/src/com/android/server/wm/WallpaperControllerTests.java b/services/tests/wmtests/src/com/android/server/wm/WallpaperControllerTests.java
index 6305bb6..6216acb 100644
--- a/services/tests/wmtests/src/com/android/server/wm/WallpaperControllerTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/WallpaperControllerTests.java
@@ -116,10 +116,7 @@
     public void testWallpaperSizeWithFixedTransform() {
         // No wallpaper
         final DisplayContent dc = mDisplayContent;
-        if (dc.mBaseDisplayHeight == dc.mBaseDisplayWidth) {
-            // Make sure the size is different when changing orientation.
-            resizeDisplay(dc, 500, 1000);
-        }
+        makeDisplayPortrait(dc);
 
         // No wallpaper WSA Surface
         final WindowState wallpaperWindow = createWallpaperWindow(dc);
diff --git a/services/tests/wmtests/src/com/android/server/wm/WindowTestsBase.java b/services/tests/wmtests/src/com/android/server/wm/WindowTestsBase.java
index 62de67a..3b7362e 100644
--- a/services/tests/wmtests/src/com/android/server/wm/WindowTestsBase.java
+++ b/services/tests/wmtests/src/com/android/server/wm/WindowTestsBase.java
@@ -971,11 +971,19 @@
     static void resizeDisplay(DisplayContent displayContent, int width, int height) {
         displayContent.updateBaseDisplayMetrics(width, height, displayContent.mBaseDisplayDensity,
                 displayContent.mBaseDisplayPhysicalXDpi, displayContent.mBaseDisplayPhysicalYDpi);
+        displayContent.getDisplayRotation().configure(width, height);
         final Configuration c = new Configuration();
         displayContent.computeScreenConfiguration(c);
         displayContent.onRequestedOverrideConfigurationChanged(c);
     }
 
+    /** Used for the tests that assume the display is portrait by default. */
+    static void makeDisplayPortrait(DisplayContent displayContent) {
+        if (displayContent.mBaseDisplayHeight <= displayContent.mBaseDisplayWidth) {
+            resizeDisplay(displayContent, 500, 1000);
+        }
+    }
+
     // The window definition for UseTestDisplay#addWindows. The test can declare to add only
     // necessary windows, that avoids adding unnecessary overhead of unused windows.
     static final int W_NOTIFICATION_SHADE = TYPE_NOTIFICATION_SHADE;