Merge tag 'android-13.0.0_r52' into int/13/fp3

Android 13.0.0 Release 52 (TQ3A.230605.012)

* tag 'android-13.0.0_r52': (22 commits)
  Update pre-hide animation logic
  [DO NOT MERGE] Re-focus pin view when focus becomes allowed
  Change order of views in notification_center_activity.xml
  [DO NOT MERGE] Update constructor
  Revert "[DO NOT MERGE] Update constructor"
  Revert "[DO NOT MERGE] Update constructor"
  Revert "[DO NOT MERGE] Update constructor"
  [DO NOT MERGE] Update constructor
  Import translations. DO NOT MERGE ANYWHERE
  Remove BouncerInteractor#onFinishedGoingToSleep
  [DO NOT MERGE] Add StatusBarEventsModule to CarSystemUIModule
  Revert^2 "Remove host_view xml"
  Removed GarbageMonitor Service Bind
  Revert "Remove host_view xml"
  Remove host_view xml
  DO NOT MERGE Prevent privacy dot from showing on status bar
  Remove keyguard bouncer in carsysui.
  Handle config changes in ActivityBlockingActivity to prevent restart
  [DO NOT MERGE] Update dependencies for DisplayTracker
  Import translations. DO NOT MERGE ANYWHERE
  ...

Change-Id: Ic9d4d87073c3544be158f491ddeb4cd46852145c
diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index 1de33dc..8222822 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -55,6 +55,7 @@
             android:name=".car.activity.ActivityBlockingActivity"
             android:documentLaunchMode="always"
             android:excludeFromRecents="true"
+            android:configChanges="screenSize|smallestScreenSize|screenLayout|orientation"
             android:exported="false"
             android:theme="@android:style/Theme.Translucent.NoTitleBar">
             <intent-filter>
diff --git a/res-keyguard/layout/keyguard_bouncer.xml b/res-keyguard/layout/keyguard_bouncer.xml
index e3e32bd..a6fd243 100644
--- a/res-keyguard/layout/keyguard_bouncer.xml
+++ b/res-keyguard/layout/keyguard_bouncer.xml
@@ -23,7 +23,7 @@
              android:background="@android:color/black"
              android:fitsSystemWindows="true">
     <include
-        layout="@layout/keyguard_host_view"
+        layout="@layout/keyguard_security_container_view"
         android:layout_width="match_parent"
         android:layout_height="wrap_content"
         android:layout_above="@+id/managed_device"/>
diff --git a/res/layout/notification_center_activity.xml b/res/layout/notification_center_activity.xml
index 6343f05..def7dde 100644
--- a/res/layout/notification_center_activity.xml
+++ b/res/layout/notification_center_activity.xml
@@ -30,8 +30,17 @@
         app:layout_constraintBottom_toBottomOf="parent"
         app:layout_constraintEnd_toEndOf="parent"
         app:layout_constraintStart_toStartOf="parent"
-        app:layout_constraintTop_toTopOf="parent"
-    />
+        app:layout_constraintTop_toTopOf="parent"/>
+
+    <androidx.recyclerview.widget.RecyclerView
+        android:id="@+id/notifications"
+        android:layout_width="match_parent"
+        android:layout_height="match_parent"
+        android:paddingBottom="@dimen/notification_shade_list_padding_bottom"
+        app:layout_constraintBottom_toBottomOf="parent"
+        app:layout_constraintEnd_toEndOf="parent"
+        app:layout_constraintStart_toStartOf="parent"
+        app:layout_constraintTop_toTopOf="parent"/>
 
     <TextView
         android:id="@+id/empty_notification_text"
@@ -60,18 +69,7 @@
         android:text="@string/manage_text"
         android:visibility="gone"/>
 
-    <androidx.recyclerview.widget.RecyclerView
-        android:id="@+id/notifications"
-        android:layout_width="match_parent"
-        android:layout_height="match_parent"
-        android:paddingBottom="@dimen/notification_shade_list_padding_bottom"
-        app:layout_constraintBottom_toBottomOf="parent"
-        app:layout_constraintEnd_toEndOf="parent"
-        app:layout_constraintStart_toStartOf="parent"
-        app:layout_constraintTop_toTopOf="parent"/>
-
     <include
         layout="@layout/notification_handle_bar"
         app:layout_constraintBottom_toBottomOf="parent"/>
-
 </com.android.car.notification.CarNotificationView>
diff --git a/res/values-it/strings.xml b/res/values-it/strings.xml
index ddeb519..11137bf 100644
--- a/res/values-it/strings.xml
+++ b/res/values-it/strings.xml
@@ -77,7 +77,7 @@
     <string name="exit_button_go_back" msgid="7988866855775300902">"Indietro"</string>
     <string name="qc_footer_settings" msgid="5471523941092316743">"Impostazioni"</string>
     <string name="qc_footer_bluetooth_settings" msgid="2870204430643762847">"Impostazioni Bluetooth"</string>
-    <string name="qc_footer_network_internet_settings" msgid="2480582764252681575">"Impostazioni di rete e Internet"</string>
+    <string name="qc_footer_network_internet_settings" msgid="2480582764252681575">"Impostazioni di rete e internet"</string>
     <string name="qc_footer_display_settings" msgid="2950539240110437704">"Impostazioni Display"</string>
     <string name="qc_footer_network_sound_settings" msgid="5117011034908775097">"Impostazioni audio"</string>
     <string name="qc_footer_profiles_accounts_settings" msgid="4456419248123950232">"Impostazioni del profilo e dell\'account"</string>
diff --git a/res/values-ky/strings.xml b/res/values-ky/strings.xml
index a51f526..38c015a 100644
--- a/res/values-ky/strings.xml
+++ b/res/values-ky/strings.xml
@@ -36,7 +36,7 @@
     <string name="privacy_chip_off_content" msgid="8406415098507955316">"<xliff:g id="SENSOR">%1$s</xliff:g> өчүк."</string>
     <string name="privacy_chip_use_sensor" msgid="7688230720803089653">"<xliff:g id="SENSOR">%1$s</xliff:g> колдонуу"</string>
     <string name="privacy_chip_use_sensor_subtext" msgid="5655148288310815742">"Уруксаты бар колдонмолор үчүн"</string>
-    <string name="mic_privacy_chip_microphone_settings" msgid="4520886720588226450">"Микрофондун жөндөөлөрү"</string>
+    <string name="mic_privacy_chip_microphone_settings" msgid="4520886720588226450">"Микрофондун параметрлери"</string>
     <string name="privacy_chip_app_using_sensor_suffix" msgid="7921315376271490004">"<xliff:g id="APP">%1$s</xliff:g> төмөнкүнү колдонуп жатат: <xliff:g id="SENSOR">%2$s</xliff:g>"</string>
     <string name="mic_privacy_chip_apps_using_mic_suffix" msgid="6656026041668305817">"<xliff:g id="APP_LIST">%s</xliff:g> микрофонду колдонуп жатышат"</string>
     <string name="privacy_chip_app_recently_used_sensor_suffix" msgid="4632772067170022529">"<xliff:g id="APP">%1$s</xliff:g> жакында төмөнкүнү колдонду: <xliff:g id="SENSOR">%2$s</xliff:g>"</string>
@@ -46,7 +46,7 @@
     <string name="mic_privacy_chip_dialog_ok" msgid="2298690833121720237">"Макул"</string>
     <string name="sensor_privacy_start_use_mic_dialog_title" msgid="8774244900043105266">"Унаанын микрофону күйгүзүлсүнбү?"</string>
     <string name="sensor_privacy_start_use_mic_dialog_content" msgid="8382980879434990801">"Улантуу үчүн инфозоок тутумунун микрофонун күйгүзүңүз. Ушуну менен уруксаты бар бардык колдонмолор үчүн микрофон иштетилет."</string>
-    <string name="camera_privacy_chip_camera_settings" msgid="96342672670928980">"Камеранын жөндөөлөрү"</string>
+    <string name="camera_privacy_chip_camera_settings" msgid="96342672670928980">"Камеранын параметрлери"</string>
     <string name="camera_privacy_chip_app_using_camera_suffix" msgid="2591363552459967509">"<xliff:g id="APP">%s</xliff:g> камераны колдонуп жатат"</string>
     <string name="camera_privacy_chip_apps_using_camera_suffix" msgid="8033118959615498419">"<xliff:g id="APP_LIST">%s</xliff:g> камераны колдонуп жатышат"</string>
     <string name="camera_privacy_chip_app_recently_used_camera_suffix" msgid="4534950658276502559">"<xliff:g id="APP">%s</xliff:g> жакында камераны колдонду"</string>
@@ -75,11 +75,11 @@
     <string name="activity_blocked_text" msgid="5353157279548801554">"Бул функцияны унаа айдап баратканда колдоно албайсыз"</string>
     <string name="exit_button_close_application" msgid="112227710467017144">"Колдонмону жабуу"</string>
     <string name="exit_button_go_back" msgid="7988866855775300902">"Артка"</string>
-    <string name="qc_footer_settings" msgid="5471523941092316743">"Жөндөөлөр"</string>
-    <string name="qc_footer_bluetooth_settings" msgid="2870204430643762847">"Bluetooth жөндөөлөрү"</string>
-    <string name="qc_footer_network_internet_settings" msgid="2480582764252681575">"Тармактын жана Интернеттин жөндөөлөрү"</string>
-    <string name="qc_footer_display_settings" msgid="2950539240110437704">"Көрүнүш жөндөөлөрү"</string>
-    <string name="qc_footer_network_sound_settings" msgid="5117011034908775097">"Добуштун жөндөөлөрү"</string>
-    <string name="qc_footer_profiles_accounts_settings" msgid="4456419248123950232">"Профилдердин жана аккаунттардын жөндөөлөрү"</string>
+    <string name="qc_footer_settings" msgid="5471523941092316743">"Параметрлер"</string>
+    <string name="qc_footer_bluetooth_settings" msgid="2870204430643762847">"Bluetooth параметрлери"</string>
+    <string name="qc_footer_network_internet_settings" msgid="2480582764252681575">"Тармактын жана Интернеттин параметрлери"</string>
+    <string name="qc_footer_display_settings" msgid="2950539240110437704">"Көрүнүш параметрлери"</string>
+    <string name="qc_footer_network_sound_settings" msgid="5117011034908775097">"Добуштун параметрлери"</string>
+    <string name="qc_footer_profiles_accounts_settings" msgid="4456419248123950232">"Профилдердин жана аккаунттардын параметрлери"</string>
     <string name="lockpattern_does_not_support_rotary" msgid="4605787900312103476">"Графикалык ачкычта буруу колдоого алынбайт; тийүүнү колдонуңуз"</string>
 </resources>
diff --git a/src/com/android/systemui/CarSystemUICoreStartableModule.kt b/src/com/android/systemui/CarSystemUICoreStartableModule.kt
index 1497667..062c74c 100644
--- a/src/com/android/systemui/CarSystemUICoreStartableModule.kt
+++ b/src/com/android/systemui/CarSystemUICoreStartableModule.kt
@@ -32,7 +32,6 @@
 import com.android.systemui.theme.ThemeOverlayController
 import com.android.systemui.usb.StorageNotification
 import com.android.systemui.util.NotificationChannels
-import com.android.systemui.util.leak.GarbageMonitor
 import com.android.systemui.wmshell.WMShell
 import dagger.Binds
 import dagger.Module
@@ -79,12 +78,6 @@
         service: ConnectedDeviceVoiceRecognitionNotifier
     ): CoreStartable
 
-    /** Inject into GarbageMonitor.Service.  */
-    @Binds
-    @IntoMap
-    @ClassKey(GarbageMonitor::class)
-    abstract fun bindGarbageMonitorService(sysui: GarbageMonitor.Service): CoreStartable
-
     /** Inject into KeyguardBiometricLockoutLogger.  */
     @Binds
     @IntoMap
@@ -161,4 +154,4 @@
     @IntoMap
     @ClassKey(WMShell::class)
     abstract fun bindWMShell(sysui: WMShell): CoreStartable
-}
\ No newline at end of file
+}
diff --git a/src/com/android/systemui/CarSystemUIModule.java b/src/com/android/systemui/CarSystemUIModule.java
index 31a2d62..2bb3209 100644
--- a/src/com/android/systemui/CarSystemUIModule.java
+++ b/src/com/android/systemui/CarSystemUIModule.java
@@ -28,6 +28,7 @@
 import com.android.keyguard.KeyguardViewController;
 import com.android.systemui.car.CarDeviceProvisionedController;
 import com.android.systemui.car.CarDeviceProvisionedControllerImpl;
+import com.android.systemui.car.decor.CarPrivacyChipViewController;
 import com.android.systemui.car.keyguard.CarKeyguardViewController;
 import com.android.systemui.car.notification.NotificationShadeWindowControllerImpl;
 import com.android.systemui.car.statusbar.DozeServiceHost;
@@ -54,6 +55,8 @@
 import com.android.systemui.statusbar.NotificationLockscreenUserManager;
 import com.android.systemui.statusbar.NotificationLockscreenUserManagerImpl;
 import com.android.systemui.statusbar.NotificationShadeWindowController;
+import com.android.systemui.statusbar.events.PrivacyDotViewController;
+import com.android.systemui.statusbar.events.StatusBarEventsModule;
 import com.android.systemui.statusbar.notification.collection.provider.VisualStabilityProvider;
 import com.android.systemui.statusbar.notification.collection.render.GroupMembershipManager;
 import com.android.systemui.statusbar.phone.HeadsUpManagerPhone;
@@ -84,7 +87,8 @@
                 GestureModule.class,
                 PowerModule.class,
                 QSModule.class,
-                ReferenceScreenshotModule.class
+                ReferenceScreenshotModule.class,
+                StatusBarEventsModule.class,
         }
         )
 abstract class CarSystemUIModule {
@@ -206,4 +210,8 @@
 
     @Binds
     abstract DozeHost bindDozeHost(DozeServiceHost dozeServiceHost);
+
+    @Binds
+    abstract PrivacyDotViewController providePrivacyDotViewController(
+            CarPrivacyChipViewController carPrivacyChipViewController);
 }
diff --git a/src/com/android/systemui/car/decor/CarPrivacyChipViewController.java b/src/com/android/systemui/car/decor/CarPrivacyChipViewController.java
new file mode 100644
index 0000000..f33904a
--- /dev/null
+++ b/src/com/android/systemui/car/decor/CarPrivacyChipViewController.java
@@ -0,0 +1,68 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.car.decor;
+
+import android.view.View;
+
+import androidx.annotation.UiThread;
+
+import com.android.systemui.dagger.SysUISingleton;
+import com.android.systemui.dagger.qualifiers.Main;
+import com.android.systemui.plugins.statusbar.StatusBarStateController;
+import com.android.systemui.shade.ShadeExpansionStateManager;
+import com.android.systemui.statusbar.events.PrivacyDotViewController;
+import com.android.systemui.statusbar.events.SystemStatusAnimationScheduler;
+import com.android.systemui.statusbar.phone.StatusBarContentInsetsProvider;
+import com.android.systemui.statusbar.policy.ConfigurationController;
+
+import org.jetbrains.annotations.NotNull;
+
+import java.util.concurrent.Executor;
+
+import javax.inject.Inject;
+
+/**
+ * Subclass of {@link PrivacyDotViewController}.
+ * This class is used to avoid showing the privacy dot.
+ */
+@SysUISingleton
+public class CarPrivacyChipViewController extends PrivacyDotViewController {
+
+    @Inject
+    public CarPrivacyChipViewController(
+            @NotNull @Main Executor mainExecutor,
+            @NotNull StatusBarStateController stateController,
+            @NotNull ConfigurationController configurationController,
+            @NotNull StatusBarContentInsetsProvider contentInsetsProvider,
+            @NotNull SystemStatusAnimationScheduler animationScheduler,
+            ShadeExpansionStateManager shadeExpansionStateManager) {
+        super(mainExecutor, stateController, configurationController, contentInsetsProvider,
+                animationScheduler, shadeExpansionStateManager);
+    }
+
+    @Override
+    @UiThread
+    public void showDotView(View dot, boolean animate) {
+        // Do nothing.
+    }
+
+    @Override
+    @UiThread
+    public void hideDotView(View dot, boolean animate) {
+        // Do nothing.
+    }
+}
diff --git a/src/com/android/systemui/car/keyguard/CarKeyguardPatternView.java b/src/com/android/systemui/car/keyguard/CarKeyguardPatternView.java
index d11b2e1..6000e91 100644
--- a/src/com/android/systemui/car/keyguard/CarKeyguardPatternView.java
+++ b/src/com/android/systemui/car/keyguard/CarKeyguardPatternView.java
@@ -54,9 +54,4 @@
             Log.w(TAG, "Pattern is inivisble for the current user. Setting it to be visible.");
         }
     }
-
-    @Override
-    public void startAppearAnimation() {
-        setAlpha(1f);
-    }
 }
diff --git a/src/com/android/systemui/car/keyguard/CarKeyguardViewController.java b/src/com/android/systemui/car/keyguard/CarKeyguardViewController.java
index 9307e30..347e08c 100644
--- a/src/com/android/systemui/car/keyguard/CarKeyguardViewController.java
+++ b/src/com/android/systemui/car/keyguard/CarKeyguardViewController.java
@@ -26,17 +26,19 @@
 import android.util.Log;
 import android.view.Gravity;
 import android.view.View;
+import android.view.ViewGroup;
 import android.view.ViewRootImpl;
 import android.view.WindowManager;
 
 import androidx.annotation.MainThread;
-import androidx.annotation.VisibleForTesting;
 
 import com.android.car.ui.FocusParkingView;
 import com.android.internal.widget.LockPatternView;
+import com.android.keyguard.KeyguardSecurityModel;
 import com.android.keyguard.KeyguardUpdateMonitor;
 import com.android.keyguard.KeyguardViewController;
 import com.android.keyguard.ViewMediatorCallback;
+import com.android.keyguard.dagger.KeyguardBouncerComponent;
 import com.android.systemui.R;
 import com.android.systemui.car.systembar.CarSystemBarController;
 import com.android.systemui.car.window.OverlayViewController;
@@ -44,12 +46,16 @@
 import com.android.systemui.car.window.SystemUIOverlayWindowController;
 import com.android.systemui.dagger.SysUISingleton;
 import com.android.systemui.dagger.qualifiers.Main;
+import com.android.systemui.keyguard.domain.interactor.PrimaryBouncerCallbackInteractor;
+import com.android.systemui.keyguard.domain.interactor.PrimaryBouncerCallbackInteractor.PrimaryBouncerExpansionCallback;
+import com.android.systemui.keyguard.domain.interactor.PrimaryBouncerInteractor;
+import com.android.systemui.keyguard.ui.binder.KeyguardBouncerViewBinder;
+import com.android.systemui.keyguard.ui.viewmodel.KeyguardBouncerViewModel;
+import com.android.systemui.keyguard.ui.viewmodel.PrimaryBouncerToGoneTransitionViewModel;
 import com.android.systemui.shade.NotificationPanelViewController;
 import com.android.systemui.shade.ShadeExpansionStateManager;
 import com.android.systemui.statusbar.phone.BiometricUnlockController;
 import com.android.systemui.statusbar.phone.CentralSurfaces;
-import com.android.systemui.statusbar.phone.KeyguardBouncer;
-import com.android.systemui.statusbar.phone.KeyguardBouncer.Factory;
 import com.android.systemui.statusbar.phone.KeyguardBypassController;
 import com.android.systemui.statusbar.policy.KeyguardStateController;
 import com.android.systemui.toast.SystemUIToast;
@@ -82,10 +88,12 @@
     private final Lazy<BiometricUnlockController> mBiometricUnlockControllerLazy;
     private final ViewMediatorCallback mViewMediatorCallback;
     private final CarSystemBarController mCarSystemBarController;
-    private final Factory mKeyguardBouncerFactory;
-    // Needed to instantiate mBouncer.
-    private final KeyguardBouncer.PrimaryBouncerExpansionCallback mExpansionCallback =
-            new KeyguardBouncer.PrimaryBouncerExpansionCallback() {
+    private final PrimaryBouncerInteractor mPrimaryBouncerInteractor;
+    private final KeyguardSecurityModel mKeyguardSecurityModel;
+    private final KeyguardBouncerViewModel mKeyguardBouncerViewModel;
+    private final KeyguardBouncerComponent.Factory mKeyguardBouncerComponentFactory;
+    private final PrimaryBouncerExpansionCallback mExpansionCallback =
+            new PrimaryBouncerExpansionCallback() {
                 @Override
                 public void onFullyShown() {
                     LockPatternView patternView = getLayout().findViewById(R.id.lockPatternView);
@@ -112,14 +120,23 @@
                 @Override
                 public void onFullyHidden() {
                 }
+
+                @Override
+                public void onVisibilityChanged(boolean isVisible) {
+                }
+
+                @Override
+                public void onExpansionChanged(float bouncerHideAmount) {
+                }
             };
 
-    private KeyguardBouncer mBouncer;
     private OnKeyguardCancelClickedListener mKeyguardCancelClickedListener;
     private boolean mShowing;
     private boolean mIsOccluded;
     private boolean mIsSleeping;
     private int mToastShowDurationMillisecond;
+    private ViewGroup mKeyguardContainer;
+    private PrimaryBouncerToGoneTransitionViewModel mPrimaryBouncerToGoneTransitionViewModel;
 
     @Inject
     public CarKeyguardViewController(
@@ -134,7 +151,12 @@
             Lazy<BiometricUnlockController> biometricUnlockControllerLazy,
             ViewMediatorCallback viewMediatorCallback,
             CarSystemBarController carSystemBarController,
-            KeyguardBouncer.Factory keyguardBouncerFactory) {
+            PrimaryBouncerCallbackInteractor primaryBouncerCallbackInteractor,
+            PrimaryBouncerInteractor primaryBouncerInteractor,
+            KeyguardSecurityModel keyguardSecurityModel,
+            KeyguardBouncerViewModel keyguardBouncerViewModel,
+            PrimaryBouncerToGoneTransitionViewModel primaryBouncerToGoneTransitionViewModel,
+            KeyguardBouncerComponent.Factory keyguardBouncerComponentFactory) {
 
         super(R.id.keyguard_stub, overlayViewGlobalStateController);
 
@@ -149,10 +171,15 @@
         mBiometricUnlockControllerLazy = biometricUnlockControllerLazy;
         mViewMediatorCallback = viewMediatorCallback;
         mCarSystemBarController = carSystemBarController;
-        mKeyguardBouncerFactory = keyguardBouncerFactory;
+        mPrimaryBouncerInteractor = primaryBouncerInteractor;
+        mKeyguardSecurityModel = keyguardSecurityModel;
+        mKeyguardBouncerViewModel = keyguardBouncerViewModel;
+        mKeyguardBouncerComponentFactory = keyguardBouncerComponentFactory;
+        mPrimaryBouncerToGoneTransitionViewModel = primaryBouncerToGoneTransitionViewModel;
 
         mToastShowDurationMillisecond = mContext.getResources().getInteger(
                 R.integer.car_keyguard_toast_show_duration_millisecond);
+        primaryBouncerCallbackInteractor.addBouncerExpansionCallback(mExpansionCallback);
     }
 
     @Override
@@ -167,24 +194,24 @@
 
     @Override
     public void onFinishInflate() {
-        mBouncer = mKeyguardBouncerFactory
-                .create(getLayout().findViewById(R.id.keyguard_container), mExpansionCallback);
+        mKeyguardContainer = getLayout().findViewById(R.id.keyguard_container);
+        KeyguardBouncerViewBinder.bind(mKeyguardContainer,
+                mKeyguardBouncerViewModel, mPrimaryBouncerToGoneTransitionViewModel,
+                mKeyguardBouncerComponentFactory);
         mBiometricUnlockControllerLazy.get().setKeyguardViewController(this);
     }
 
     @Override
     @MainThread
     public void notifyKeyguardAuthenticated(boolean strongAuth) {
-        if (mBouncer != null) {
-            mBouncer.notifyKeyguardAuthenticated(strongAuth);
-        }
+        mPrimaryBouncerInteractor.notifyKeyguardAuthenticated(strongAuth);
     }
 
     @Override
     @MainThread
     public void showPrimaryBouncer(boolean scrimmed) {
-        if (mShowing && !mBouncer.isShowing()) {
-            mBouncer.show(/* resetSecuritySelection= */ false);
+        if (mShowing && !mPrimaryBouncerInteractor.isFullyShowing()) {
+            mPrimaryBouncerInteractor.show(/* isScrimmed= */ true);
         }
     }
 
@@ -209,7 +236,7 @@
         mViewMediatorCallback.readyForKeyguardDone();
         mShowing = false;
         mKeyguardStateController.notifyKeyguardState(mShowing, /* occluded= */ false);
-        mBouncer.hide(/* destroyView= */ true);
+        mPrimaryBouncerInteractor.hide();
         mCarSystemBarController.showAllNavigationButtons(/* isSetUp= */ true);
         stop();
         mKeyguardStateController.notifyKeyguardDoneFading();
@@ -223,12 +250,10 @@
 
         mMainExecutor.execute(() -> {
             if (mShowing) {
-                if (mBouncer != null) {
-                    if (!mBouncer.isSecure()) {
-                        dismissAndCollapse();
-                    }
-                    resetBouncer();
+                if (!isSecure()) {
+                    dismissAndCollapse();
                 }
+                resetBouncer();
                 mKeyguardUpdateMonitor.sendKeyguardReset();
                 notifyKeyguardUpdateMonitor();
             } else {
@@ -248,9 +273,7 @@
     @Override
     @MainThread
     public void onFinishedGoingToSleep() {
-        if (mBouncer != null) {
-            mBouncer.onScreenTurnedOff();
-        }
+        mPrimaryBouncerInteractor.hide();
     }
 
     @Override
@@ -261,7 +284,7 @@
         if (occluded) {
             mCarSystemBarController.showAllOcclusionButtons(/* isSetup= */ true);
         } else {
-            if (mShowing && mBouncer.isSecure()) {
+            if (mShowing && isSecure()) {
                 mCarSystemBarController.showAllKeyguardButtons(/* isSetup= */ true);
             } else {
                 mCarSystemBarController.showAllNavigationButtons(/* isSetUp= */ true);
@@ -272,11 +295,8 @@
     @Override
     @MainThread
     public void onCancelClicked() {
-        if (mBouncer == null) return;
-
         getOverlayViewGlobalStateController().setWindowNeedsInput(/* needsInput= */ false);
-
-        mBouncer.hide(/* destroyView= */ true);
+        mPrimaryBouncerInteractor.hide();
         mKeyguardCancelClickedListener.onCancelClicked();
     }
 
@@ -289,7 +309,7 @@
         if (mIsOccluded) {
             setOccluded(/* occluded= */ false, /* animate= */ false);
         }
-        if (mBouncer != null && !mBouncer.isSecure()) {
+        if (!isSecure()) {
             hide(/* startTime= */ 0, /* fadeoutDuration= */ 0);
         }
     }
@@ -297,9 +317,11 @@
     @Override
     @MainThread
     public void startPreHideAnimation(Runnable finishRunnable) {
-        if (mBouncer == null) return;
-
-        mBouncer.startPreHideAnimation(finishRunnable);
+        if (isBouncerShowing()) {
+            mPrimaryBouncerInteractor.startDisappearAnimation(finishRunnable);
+        } else if (finishRunnable != null) {
+            finishRunnable.run();
+        }
     }
 
     @Override
@@ -342,13 +364,14 @@
     @Override
     @MainThread
     public boolean isBouncerShowing() {
-        return mBouncer != null && mBouncer.isShowing();
+        return mPrimaryBouncerInteractor.isFullyShowing();
     }
 
     @Override
     @MainThread
     public boolean primaryBouncerIsOrWillBeShowing() {
-        return mBouncer != null && (mBouncer.isShowing() || mBouncer.inTransit());
+        return mPrimaryBouncerInteractor.isFullyShowing()
+                || mPrimaryBouncerInteractor.isInTransit();
     }
 
     @Override
@@ -408,22 +431,28 @@
         getLayout().setVisibility(View.INVISIBLE);
     }
 
-    @VisibleForTesting
-    void setKeyguardBouncer(KeyguardBouncer keyguardBouncer) {
-        mBouncer = keyguardBouncer;
+    @Override
+    public boolean setAllowRotaryFocus(boolean allowRotaryFocus) {
+        boolean changed = super.setAllowRotaryFocus(allowRotaryFocus);
+        // When focus on keyguard becomes allowed, focus needs to be restored back to the pin entry
+        // view. Depending on the timing of the calls, pinView may believe it is focused
+        // (isFocused()=true) but the root view does not believe anything is focused
+        // (findFocus()=null). To guarantee that the view is fully focused, it is necessary to
+        // clear and refocus the element.
+        if (changed && allowRotaryFocus && getLayout() != null) {
+            View pinView = getLayout().findViewById(R.id.pinEntry);
+            if (pinView != null) {
+                pinView.clearFocus();
+                pinView.requestFocus();
+            }
+        }
+        return changed;
     }
 
     private void revealKeyguardIfBouncerPrepared() {
         int reattemptDelayMillis = 50;
         Runnable revealKeyguard = () -> {
-            if (mBouncer == null) {
-                if (DEBUG) {
-                    Log.d(TAG, "revealKeyguardIfBouncerPrepared: revealKeyguard request is ignored "
-                            + "since the Bouncer has not been initialized yet.");
-                }
-                return;
-            }
-            if (!mBouncer.inTransit() || !mBouncer.isSecure()) {
+            if (!mPrimaryBouncerInteractor.isInTransit() || !isSecure()) {
                 if (mShowing) {
                     // Only set the layout as visible if the keyguard should be showing
                     showInternal();
@@ -441,17 +470,24 @@
     }
 
     private void notifyKeyguardUpdateMonitor() {
-        if (mBouncer != null) {
-            mKeyguardUpdateMonitor.sendPrimaryBouncerChanged(
-                    primaryBouncerIsOrWillBeShowing(), isBouncerShowing());
-        }
+        mKeyguardUpdateMonitor.sendPrimaryBouncerChanged(
+                primaryBouncerIsOrWillBeShowing(), isBouncerShowing());
     }
 
+    /**
+     * WARNING: This method might cause Binder calls.
+     */
+    private boolean isSecure() {
+        return mKeyguardSecurityModel.getSecurityMode(
+                KeyguardUpdateMonitor.getCurrentUser()) != KeyguardSecurityModel.SecurityMode.None;
+    }
+
+
     private void resetBouncer() {
         mMainExecutor.execute(() -> {
             hideInternal();
-            mBouncer.hide(/* destroyView= */ false);
-            mBouncer.show(/* resetSecuritySelection= */ true);
+            mPrimaryBouncerInteractor.hide();
+            mPrimaryBouncerInteractor.show(/* isScrimmed= */ true);
             revealKeyguardIfBouncerPrepared();
         });
     }
diff --git a/src/com/android/systemui/car/window/OverlayViewController.java b/src/com/android/systemui/car/window/OverlayViewController.java
index 45b2d00..87d5e23 100644
--- a/src/com/android/systemui/car/window/OverlayViewController.java
+++ b/src/com/android/systemui/car/window/OverlayViewController.java
@@ -177,20 +177,23 @@
     /**
      * Sets whether this view allows rotary focus. This should be set to {@code true} for the
      * topmost layer in the overlay window and {@code false} for the others.
+     *
+     * @return true if the rotary focus allowed state has changed.
      */
-    public void setAllowRotaryFocus(boolean allowRotaryFocus) {
-        if (!isInflated()) {
-            return;
-        }
-
-        if (!(mLayout instanceof ViewGroup)) {
-            return;
+    public boolean setAllowRotaryFocus(boolean allowRotaryFocus) {
+        if (!isInflated() || !(mLayout instanceof ViewGroup)) {
+            return false;
         }
 
         ViewGroup viewGroup = (ViewGroup) mLayout;
-        viewGroup.setDescendantFocusability(allowRotaryFocus
+        int newFocusability = allowRotaryFocus
                 ? ViewGroup.FOCUS_BEFORE_DESCENDANTS
-                : ViewGroup.FOCUS_BLOCK_DESCENDANTS);
+                : ViewGroup.FOCUS_BLOCK_DESCENDANTS;
+        if (viewGroup.getDescendantFocusability() == newFocusability) {
+            return false;
+        }
+        viewGroup.setDescendantFocusability(newFocusability);
+        return true;
     }
 
     /**
diff --git a/tests/src/com/android/systemui/car/keyguard/CarKeyguardViewControllerTest.java b/tests/src/com/android/systemui/car/keyguard/CarKeyguardViewControllerTest.java
index 3d49259..24dd694 100644
--- a/tests/src/com/android/systemui/car/keyguard/CarKeyguardViewControllerTest.java
+++ b/tests/src/com/android/systemui/car/keyguard/CarKeyguardViewControllerTest.java
@@ -17,7 +17,7 @@
 package com.android.systemui.car.keyguard;
 
 import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.ArgumentMatchers.anyBoolean;
+import static org.mockito.ArgumentMatchers.anyInt;
 import static org.mockito.ArgumentMatchers.eq;
 import static org.mockito.Mockito.inOrder;
 import static org.mockito.Mockito.mock;
@@ -35,16 +35,22 @@
 
 import androidx.test.filters.SmallTest;
 
+import com.android.keyguard.KeyguardSecurityContainerController;
+import com.android.keyguard.KeyguardSecurityModel;
 import com.android.keyguard.KeyguardUpdateMonitor;
 import com.android.keyguard.ViewMediatorCallback;
+import com.android.keyguard.dagger.KeyguardBouncerComponent;
 import com.android.systemui.R;
 import com.android.systemui.SysuiTestCase;
 import com.android.systemui.car.CarSystemUiTest;
 import com.android.systemui.car.systembar.CarSystemBarController;
 import com.android.systemui.car.window.OverlayViewGlobalStateController;
 import com.android.systemui.car.window.SystemUIOverlayWindowController;
+import com.android.systemui.keyguard.domain.interactor.PrimaryBouncerCallbackInteractor;
+import com.android.systemui.keyguard.domain.interactor.PrimaryBouncerInteractor;
+import com.android.systemui.keyguard.ui.viewmodel.KeyguardBouncerViewModel;
+import com.android.systemui.keyguard.ui.viewmodel.PrimaryBouncerToGoneTransitionViewModel;
 import com.android.systemui.statusbar.phone.BiometricUnlockController;
-import com.android.systemui.statusbar.phone.KeyguardBouncer;
 import com.android.systemui.statusbar.policy.KeyguardStateController;
 import com.android.systemui.toast.ToastFactory;
 import com.android.systemui.util.concurrency.FakeExecutor;
@@ -55,11 +61,12 @@
 import org.junit.runner.RunWith;
 import org.mockito.InOrder;
 import org.mockito.Mock;
+import org.mockito.Mockito;
 import org.mockito.MockitoAnnotations;
 
 @CarSystemUiTest
 @RunWith(AndroidTestingRunner.class)
-@TestableLooper.RunWithLooper
+@TestableLooper.RunWithLooper(setAsMainLooper = true)
 @SmallTest
 public class CarKeyguardViewControllerTest extends SysuiTestCase {
 
@@ -73,9 +80,17 @@
     @Mock
     private CarKeyguardViewController.OnKeyguardCancelClickedListener mCancelClickedListener;
     @Mock
-    private KeyguardBouncer.Factory mKeyguardBouncerFactory;
+    private PrimaryBouncerCallbackInteractor mPrimaryBouncerCallbackInteractor;
     @Mock
-    private KeyguardBouncer mBouncer;
+    private PrimaryBouncerInteractor mPrimaryBouncerInteractor;
+    @Mock
+    private KeyguardSecurityModel mKeyguardSecurityModel;
+    @Mock
+    private KeyguardBouncerViewModel mKeyguardBouncerViewModel;
+    @Mock
+    private KeyguardBouncerComponent.Factory mKeyguardBouncerComponentFactory;
+    @Mock
+    private PrimaryBouncerToGoneTransitionViewModel mPrimaryBouncerToGoneTransitionViewModel;
 
     @Before
     public void setUp() {
@@ -83,13 +98,17 @@
 
         ViewGroup mockBaseLayout = new FrameLayout(mContext);
 
-        when(mKeyguardBouncerFactory.create(
-                any(ViewGroup.class),
-                any(KeyguardBouncer.PrimaryBouncerExpansionCallback.class)))
-                .thenReturn(mBouncer);
         when(mSystemUIOverlayWindowController.getBaseLayout()).thenReturn(mockBaseLayout);
         mExecutor = new FakeExecutor(new FakeSystemClock());
 
+        KeyguardBouncerComponent keyguardBouncerComponent = mock(KeyguardBouncerComponent.class);
+        KeyguardSecurityContainerController securityContainerController = mock(
+                KeyguardSecurityContainerController.class);
+        when(mKeyguardBouncerComponentFactory.create(any(ViewGroup.class))).thenReturn(
+                keyguardBouncerComponent);
+        when(keyguardBouncerComponent.getSecurityContainerController()).thenReturn(
+                securityContainerController);
+
         mCarKeyguardViewController = new CarKeyguardViewController(
                 mContext,
                 mExecutor,
@@ -102,7 +121,12 @@
                 () -> mock(BiometricUnlockController.class),
                 mock(ViewMediatorCallback.class),
                 mock(CarSystemBarController.class),
-                mKeyguardBouncerFactory
+                mPrimaryBouncerCallbackInteractor,
+                mPrimaryBouncerInteractor,
+                mKeyguardSecurityModel,
+                mKeyguardBouncerViewModel,
+                mPrimaryBouncerToGoneTransitionViewModel,
+                mKeyguardBouncerComponentFactory
         );
         mCarKeyguardViewController.inflate((ViewGroup) LayoutInflater.from(mContext).inflate(
                 R.layout.sysui_overlay_window, /* root= */ null));
@@ -110,16 +134,16 @@
 
     @Test
     public void onShow_bouncerIsSecure_showsBouncerWithSecuritySelectionReset() {
-        when(mBouncer.isSecure()).thenReturn(true);
+        setIsSecure(true);
         mCarKeyguardViewController.show(/* options= */ null);
         waitForDelayableExecutor();
 
-        verify(mBouncer).show(/* resetSecuritySelection= */ true);
+        verify(mPrimaryBouncerInteractor).show(/* isScrimmed= */ true);
     }
 
     @Test
     public void onShow_bouncerIsSecure_keyguardIsVisible() {
-        when(mBouncer.isSecure()).thenReturn(true);
+        setIsSecure(true);
         mCarKeyguardViewController.show(/* options= */ null);
 
         verify(mOverlayViewGlobalStateController).showView(eq(mCarKeyguardViewController), any());
@@ -127,16 +151,16 @@
 
     @Test
     public void onShow_bouncerNotSecure_hidesBouncerAndDestroysTheView() {
-        when(mBouncer.isSecure()).thenReturn(false);
+        setIsSecure(false);
         mCarKeyguardViewController.show(/* options= */ null);
         waitForDelayableExecutor();
 
-        verify(mBouncer).hide(/* destroyView= */ true);
+        verify(mPrimaryBouncerInteractor, Mockito.times(2)).hide();
     }
 
     @Test
     public void onShow_bouncerNotSecure_keyguardIsNotVisible() {
-        when(mBouncer.isSecure()).thenReturn(false);
+        setIsSecure(false);
         mCarKeyguardViewController.show(/* options= */ null);
         waitForDelayableExecutor();
 
@@ -155,23 +179,23 @@
 
     @Test
     public void onHide_keyguardShowing_hidesBouncerAndDestroysTheView() {
-        when(mBouncer.isSecure()).thenReturn(true);
+        setIsSecure(true);
         mCarKeyguardViewController.show(/* options= */ null);
         mCarKeyguardViewController.hide(/* startTime= */ 0, /* fadeoutDelay= */ 0);
 
-        verify(mBouncer).hide(/* destroyView= */ true);
+        verify(mPrimaryBouncerInteractor).hide();
     }
 
     @Test
     public void onHide_keyguardNotShown_doesNotHideOrDestroyBouncer() {
         mCarKeyguardViewController.hide(/* startTime= */ 0, /* fadeoutDelay= */ 0);
 
-        verify(mBouncer, never()).hide(anyBoolean());
+        verify(mPrimaryBouncerInteractor, never()).hide();
     }
 
     @Test
     public void onHide_KeyguardNotVisible() {
-        when(mBouncer.isSecure()).thenReturn(true);
+        setIsSecure(true);
         mCarKeyguardViewController.show(/* options= */ null);
         mCarKeyguardViewController.hide(/* startTime= */ 0, /* fadeoutDelay= */ 0);
 
@@ -184,20 +208,20 @@
 
     @Test
     public void setOccludedFalse_currentlyOccluded_showsKeyguard() {
-        when(mBouncer.isSecure()).thenReturn(true);
+        setIsSecure(true);
         mCarKeyguardViewController.show(/* options= */ null);
         mCarKeyguardViewController.setOccluded(/* occluded= */ true, /* animate= */ false);
-        reset(mBouncer);
+        reset(mPrimaryBouncerInteractor);
 
         mCarKeyguardViewController.setOccluded(/* occluded= */ false, /* animate= */ false);
         waitForDelayableExecutor();
 
-        verify(mBouncer).show(true);
+        verify(mPrimaryBouncerInteractor).show(/* isScrimmed= */ true);
     }
 
     @Test
     public void onCancelClicked_callsCancelClickedListener() {
-        when(mBouncer.isSecure()).thenReturn(true);
+        setIsSecure(true);
         mCarKeyguardViewController.show(/* options= */ null);
         mCarKeyguardViewController.registerOnKeyguardCancelClickedListener(mCancelClickedListener);
         mCarKeyguardViewController.onCancelClicked();
@@ -207,7 +231,7 @@
 
     @Test
     public void onEnterSleepModeAndThenShowKeyguard_bouncerNotSecure_keyguardIsVisible() {
-        when(mBouncer.isSecure()).thenReturn(false);
+        setIsSecure(false);
         mCarKeyguardViewController.onStartedGoingToSleep();
         mCarKeyguardViewController.show(/* options= */ null);
         waitForDelayableExecutor();
@@ -222,8 +246,14 @@
     }
 
     @Test
+    public void onFinishedGoingToSleep() {
+        mCarKeyguardViewController.onFinishedGoingToSleep();
+        verify(mPrimaryBouncerInteractor).hide();
+    }
+
+    @Test
     public void onDeviceWakeUpWhileKeyguardShown_bouncerNotSecure_keyguardIsNotVisible() {
-        when(mBouncer.isSecure()).thenReturn(false);
+        setIsSecure(false);
         mCarKeyguardViewController.onStartedGoingToSleep();
         mCarKeyguardViewController.show(/* options= */ null);
         mCarKeyguardViewController.onStartedWakingUp();
@@ -240,16 +270,22 @@
 
     @Test
     public void onCancelClicked_hidesBouncerAndDestroysTheView() {
-        when(mBouncer.isSecure()).thenReturn(true);
+        setIsSecure(true);
         mCarKeyguardViewController.show(/* options= */ null);
         mCarKeyguardViewController.registerOnKeyguardCancelClickedListener(mCancelClickedListener);
         mCarKeyguardViewController.onCancelClicked();
 
-        verify(mBouncer).hide(/* destroyView= */ true);
+        verify(mPrimaryBouncerInteractor).hide();
     }
 
     private void waitForDelayableExecutor() {
         mExecutor.advanceClockToLast();
         mExecutor.runAllReady();
     }
+
+    private void setIsSecure(boolean isSecure) {
+        when(mKeyguardSecurityModel.getSecurityMode(anyInt())).thenReturn(
+                isSecure ? KeyguardSecurityModel.SecurityMode.PIN
+                        : KeyguardSecurityModel.SecurityMode.None);
+    }
 }
diff --git a/tests/src/com/android/systemui/car/systembar/CarSystemBarTest.java b/tests/src/com/android/systemui/car/systembar/CarSystemBarTest.java
index f7f2b42..17c9442 100644
--- a/tests/src/com/android/systemui/car/systembar/CarSystemBarTest.java
+++ b/tests/src/com/android/systemui/car/systembar/CarSystemBarTest.java
@@ -56,6 +56,7 @@
 import com.android.systemui.car.CarDeviceProvisionedController;
 import com.android.systemui.car.CarSystemUiTest;
 import com.android.systemui.car.hvac.HvacController;
+import com.android.systemui.settings.FakeDisplayTracker;
 import com.android.systemui.statusbar.CommandQueue;
 import com.android.systemui.statusbar.phone.AutoHideController;
 import com.android.systemui.statusbar.phone.LightBarController;
@@ -169,9 +170,9 @@
     private void initCarSystemBar() {
         mCarSystemBar = new CarSystemBar(mContext, mCarSystemBarController, mLightBarController,
                 mStatusBarIconController, mWindowManager, mDeviceProvisionedController,
-                new CommandQueue(mContext), mAutoHideController, mButtonSelectionStateListener,
-                mExecutor, mUiBgExecutor, mBarService, () -> mKeyguardStateController,
-                () -> mIconPolicy, mHvacController, mSignalPolicy,
+                new CommandQueue(mContext, new FakeDisplayTracker(mContext)), mAutoHideController,
+                mButtonSelectionStateListener, mExecutor, mUiBgExecutor, mBarService,
+                () -> mKeyguardStateController, () -> mIconPolicy, mHvacController, mSignalPolicy,
                 new SystemBarConfigs(mTestableResources.getResources()),
                 mock(ConfigurationController.class));
         mCarSystemBar.setSignalPolicy(mSignalPolicy);