Restore focus history properly

Fixes: 171573648
Test: manually tested the dialog in Launcher
Change-Id: Id6079e3cf1a25d38dcdc1cb609cd07c33292788a
diff --git a/car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/FocusArea.java b/car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/FocusArea.java
index 3ccbd88..b20758a 100644
--- a/car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/FocusArea.java
+++ b/car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/FocusArea.java
@@ -480,16 +480,26 @@
     @Override
     public void onWindowFocusChanged(boolean hasWindowFocus) {
         // To ensure the focus is initialized properly in rotary mode when there is a window focus
-        // change, this FocusArea will grab the focus from the currently focused view if one of this
-        // FocusArea's descendants is a better focus candidate than the currently focused view.
+        // change, this FocusArea will grab the focus if nothing is focused or the currently
+        // focused view's FocusLevel is lower than REGULAR_FOCUS.
         if (hasWindowFocus && !isInTouchMode()) {
-            maybeAdjustFocus();
+            maybeInitFocus();
         }
         super.onWindowFocusChanged(hasWindowFocus);
     }
 
     /**
-     * Focuses on another view in this FocusArea if the view is a better focus candidate than the
+     * Focuses on another view in this FocusArea if nothing is focused or the currently focused
+     * view's FocusLevel is lower than REGULAR_FOCUS.
+     */
+    private boolean maybeInitFocus() {
+        View root = getRootView();
+        View focus = root.findFocus();
+        return ViewUtils.initFocus(root, focus);
+    }
+
+    /**
+     * Focuses on a view in this FocusArea if the view is a better focus candidate than the
      * currently focused view.
      */
     private boolean maybeAdjustFocus() {
diff --git a/car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/FocusParkingView.java b/car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/FocusParkingView.java
index 2cddee6..aac5c03 100644
--- a/car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/FocusParkingView.java
+++ b/car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/FocusParkingView.java
@@ -160,7 +160,9 @@
     }
 
     private void updateFocusedView(@Nullable View focusedView) {
-        mFocusCache.setFocusedView(mFocusedView, SystemClock.uptimeMillis());
+        if (mFocusedView != null) {
+            mFocusCache.setFocusedView(mFocusedView, SystemClock.uptimeMillis());
+        }
         mFocusedView = focusedView;
         mScrollableContainer = ViewUtils.getAncestorScrollableContainer(focusedView);
     }
@@ -201,7 +203,7 @@
         } else if (isFocused()) {
             // When FocusParkingView is focused and the window just gets focused, transfer the view
             // focus to a non-FocusParkingView in the window.
-            restoreFocusInRoot(/* checkForTouchMode= */ true, /* checkFocusHistory= */ false);
+            restoreFocusInRoot(/* checkForTouchMode= */ true);
         }
         super.onWindowFocusChanged(hasWindowFocus);
     }
@@ -215,8 +217,7 @@
     public boolean performAccessibilityAction(int action, Bundle arguments) {
         switch (action) {
             case ACTION_RESTORE_DEFAULT_FOCUS:
-                return restoreFocusInRoot(
-                        /* checkForTouchMode= */ false, /* checkFocusHistory= */ true);
+                return restoreFocusInRoot(/* checkForTouchMode= */ false);
             case ACTION_HIDE_IME:
                 InputMethodManager inputMethodManager =
                         getContext().getSystemService(InputMethodManager.class);
@@ -239,7 +240,7 @@
         }
         // Find a better target to focus instead of focusing this FocusParkingView when the
         // framework wants to focus it.
-        return restoreFocusInRoot(/* checkForTouchMode= */ true, /* checkFocusHistory= */ false);
+        return restoreFocusInRoot(/* checkForTouchMode= */ true);
     }
 
     @Override
@@ -249,7 +250,7 @@
         }
         // Find a better target to focus instead of focusing this FocusParkingView when the
         // framework wants to focus it.
-        return restoreFocusInRoot(/* checkForTouchMode= */ true, /* checkFocusHistory= */ false);
+        return restoreFocusInRoot(/* checkForTouchMode= */ true);
     }
 
     /**
@@ -261,7 +262,7 @@
         mShouldRestoreFocus = shouldRestoreFocus;
     }
 
-    private boolean restoreFocusInRoot(boolean checkForTouchMode, boolean checkFocusHistory) {
+    private boolean restoreFocusInRoot(boolean checkForTouchMode) {
         // Don't do anything in touch mode if checkForTouchMode is true.
         if (checkForTouchMode && isInTouchMode()) {
             return false;
@@ -274,9 +275,7 @@
         }
 
         // Otherwise try to find the best target view to focus.
-        View cachedFocusedView = checkFocusHistory
-                ? mFocusCache.getFocusedView(SystemClock.uptimeMillis())
-                : null;
+        View cachedFocusedView = mFocusCache.getFocusedView(SystemClock.uptimeMillis());
         if (ViewUtils.adjustFocus(
                 getRootView(), cachedFocusedView, mDefaultFocusOverridesHistory)) {
             return true;
diff --git a/car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/utils/ViewUtils.java b/car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/utils/ViewUtils.java
index a23e641..bc5a583 100644
--- a/car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/utils/ViewUtils.java
+++ b/car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/utils/ViewUtils.java
@@ -174,6 +174,21 @@
     }
 
     /**
+     * If the {@code currentFocus}'s FocusLevel is lower than REGULAR_FOCUS, adjusts focus within
+     * {@code root}. See {@link #adjustFocus(View, int)}. Otherwise no-op.
+     *
+     * @return whether the focus has changed
+     */
+    public static boolean initFocus(@NonNull View root, @Nullable View currentFocus) {
+        @FocusLevel int currentLevel = getFocusLevel(currentFocus);
+        if (currentLevel >= REGULAR_FOCUS) {
+            return false;
+        }
+        return adjustFocus(root, currentLevel, /* cachedFocusedView= */ null,
+                /* defaultFocusOverridesHistory= */ false);
+    }
+
+    /**
      * Searches the {@code root}'s descendants for a view with the highest {@link FocusLevel}. If
      * the view's FocusLevel is higher than {@code currentLevel}, focuses on the view.
      *