Use the currently focused view to initialize the focus

Fixes: 170420845
Test: focus on Media, reinstall RotaryService, then
      rotate/nudge/click the controller
Test: focus on Navigation bar, reinstall RotaryService, then
      rotate/nudge/click the controller
Test: focus on Media, reinstall Media, then rotate/nudge/click
      the controller

Change-Id: I5320b74de432b4fd7f41f5f3ae4b3defbaa26b08
diff --git a/src/com/android/car/rotary/RotaryService.java b/src/com/android/car/rotary/RotaryService.java
index 2fe740c..b572083 100644
--- a/src/com/android/car/rotary/RotaryService.java
+++ b/src/com/android/car/rotary/RotaryService.java
@@ -39,6 +39,7 @@
 import static android.view.accessibility.AccessibilityNodeInfo.ACTION_SELECT;
 import static android.view.accessibility.AccessibilityNodeInfo.AccessibilityAction.ACTION_SCROLL_BACKWARD;
 import static android.view.accessibility.AccessibilityNodeInfo.AccessibilityAction.ACTION_SCROLL_FORWARD;
+import static android.view.accessibility.AccessibilityNodeInfo.FOCUS_INPUT;
 import static android.view.accessibility.AccessibilityWindowInfo.TYPE_APPLICATION;
 import static android.view.accessibility.AccessibilityWindowInfo.TYPE_INPUT_METHOD;
 
@@ -1437,6 +1438,8 @@
      * following:<ol>
      *     <li>If {@link #mFocusedNode} isn't null and represents a view that still exists, does
      *         nothing. The event isn't consumed in this case. This is the normal case.
+     *     <li>If there is a non-FocusParkingView focused in any window, set mFocusedNode to that
+     *         view.
      *     <li>If {@link #mLastTouchedNode} isn't null and represents a view that still exists,
      *         focuses it. The event is consumed in this case. This happens when the user switches
      *         from touch to rotary.
@@ -1447,7 +1450,10 @@
      *         {@link #mFocusedNode} is guaranteed to not be {@code null}.
      */
     private boolean initFocus() {
-        return initFocus(null, INVALID_NUDGE_DIRECTION);
+        List<AccessibilityWindowInfo> windows = getWindows();
+        boolean consumed = initFocus(windows, INVALID_NUDGE_DIRECTION);
+        Utils.recycleWindows(windows);
+        return consumed;
     }
 
     /**
@@ -1460,7 +1466,7 @@
      * @return whether the event was consumed by this method. When {@code false},
      *         {@link #mFocusedNode} is guaranteed to not be {@code null}.
      */
-    private boolean initFocus(@Nullable List<AccessibilityWindowInfo> windows, int direction) {
+    private boolean initFocus(@NonNull List<AccessibilityWindowInfo> windows, int direction) {
         boolean prevInRotaryMode = mInRotaryMode;
         refreshSavedNodes();
         setInRotaryMode(true);
@@ -1488,6 +1494,20 @@
             return true;
         }
 
+        // If there is a non-FocusParkingView focused in any window, set mFocusedNode to that view.
+        for (AccessibilityWindowInfo window : windows) {
+            AccessibilityNodeInfo root = window.getRoot();
+            if (root != null) {
+                AccessibilityNodeInfo focusedNode = root.findFocus(FOCUS_INPUT);
+                root.recycle();
+                if (focusedNode != null && !Utils.isFocusParkingView(focusedNode)) {
+                    setFocusedNode(focusedNode);
+                    focusedNode.recycle();
+                    return false;
+                }
+            }
+        }
+
         if (mLastTouchedNode != null && focusLastTouchedNode()) {
             return true;
         }