Don't focus on views that are detached from window

Fixes: 169273707
Test: atest CarUILibUnitTests, and manual test
Change-Id: I3d5eff609e75471209f373688e88826509c1eb48
diff --git a/car-ui-lib/car-ui-lib/src/androidTest/java/com/android/car/ui/FocusAreaTest.java b/car-ui-lib/car-ui-lib/src/androidTest/java/com/android/car/ui/FocusAreaTest.java
index 7524b27..9c1ce88 100644
--- a/car-ui-lib/car-ui-lib/src/androidTest/java/com/android/car/ui/FocusAreaTest.java
+++ b/car-ui-lib/car-ui-lib/src/androidTest/java/com/android/car/ui/FocusAreaTest.java
@@ -55,6 +55,8 @@
     private View mChild;
     private View mDefaultFocus;
     private View mNonChild;
+    private View mChild1;
+    private View mChild2;
 
     @Before
     public void setUp() {
@@ -65,6 +67,8 @@
         mChild = mActivity.findViewById(R.id.child);
         mDefaultFocus = mActivity.findViewById(R.id.default_focus);
         mNonChild = mActivity.findViewById(R.id.non_child);
+        mChild1 = mActivity.findViewById(R.id.child1);
+        mChild2 = mActivity.findViewById(R.id.child2);
     }
 
     @Test
@@ -176,6 +180,24 @@
         node.recycle();
     }
 
+    @Test
+    public void testLastFocusedViewRemoved() {
+        mChild1.post(() -> {
+            // Focus on mChild1 in mFocusArea2, then mChild in mFocusArea .
+            mChild1.requestFocus();
+            assertThat(mChild1.isFocused()).isTrue();
+            mChild.requestFocus();
+            assertThat(mChild.isFocused()).isTrue();
+
+            // Remove mChild1 in mFocusArea2, then Perform ACTION_FOCUS on mFocusArea2.
+            mFocusArea2.removeView(mChild1);
+            mFocusArea2.performAccessibilityAction(ACTION_FOCUS, null);
+
+            // mChild2 in mFocusArea2 should get focused.
+            assertThat(mChild2.isFocused()).isTrue();
+        });
+    }
+
     private void assertBoundsOffset(
             @NonNull AccessibilityNodeInfo node, int leftPx, int topPx, int rightPx, int bottomPx) {
         Bundle extras = node.getExtras();
diff --git a/car-ui-lib/car-ui-lib/src/androidTest/res/layout/focus_area_test_activity.xml b/car-ui-lib/car-ui-lib/src/androidTest/res/layout/focus_area_test_activity.xml
index 209e911..524de8d 100644
--- a/car-ui-lib/car-ui-lib/src/androidTest/res/layout/focus_area_test_activity.xml
+++ b/car-ui-lib/car-ui-lib/src/androidTest/res/layout/focus_area_test_activity.xml
@@ -50,11 +50,22 @@
         android:layout_height="100dp"/>
     <com.android.car.ui.TestFocusArea
         android:id="@+id/focus_area2"
-        android:layout_width="100dp"
-        android:layout_height="100dp"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
         app:highlightPaddingHorizontal="10dp"
         app:highlightPaddingVertical="20dp"
         app:highlightPaddingStart="30dp"
         app:highlightPaddingTop="40dp"
-        app:startBoundOffset="50dp"/>
+        app:startBoundOffset="50dp">
+        <View
+            android:id="@+id/child1"
+            android:focusable="true"
+            android:layout_width="100dp"
+            android:layout_height="100dp"/>
+        <View
+            android:id="@+id/child2"
+            android:focusable="true"
+            android:layout_width="100dp"
+            android:layout_height="100dp"/>
+    </com.android.car.ui.TestFocusArea>
 </LinearLayout>
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 72261a7..f5c6c1d 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
@@ -673,7 +673,7 @@
     }
 
     private boolean requestFocus(@Nullable View view) {
-        if (view == null) {
+        if (view == null || !view.isAttachedToWindow()) {
             return false;
         }
         // Exit touch mode and focus the view. The view may not be focusable in touch mode, so we