Include a delegating container view

Bug: 172267951
Test: manual
Change-Id: Ia48fbb32a7ee931d5b060c9e8d83689b2de0d99b
diff --git a/car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/utils/RotaryConstants.java b/car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/utils/RotaryConstants.java
index aaaae6c..e6c62c9 100644
--- a/car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/utils/RotaryConstants.java
+++ b/car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/utils/RotaryConstants.java
@@ -55,6 +55,15 @@
     public static final String ROTARY_VERTICALLY_SCROLLABLE =
             "com.android.car.ui.utils.VERTICALLY_SCROLLABLE";
 
+    /**
+     * Content description indicating that the view is a focus delegating container. When
+     * restoring focus, FocusParkingView and FocusArea will skip non-focusable views unless it's
+     * a focus delegating container. The focus delegating container can delegate focus to one of
+     * its descendants.
+     */
+    public static final String ROTARY_FOCUS_DELEGATING_CONTAINER =
+            "com.android.car.ui.utils.FOCUS_DELEGATING_CONTAINER";
+
     /** The key to store the offset of the FocusArea's left bound in the node's extras. */
     public static final String FOCUS_AREA_LEFT_BOUND_OFFSET =
             "com.android.car.ui.utils.FOCUS_AREA_LEFT_BOUND_OFFSET";
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 fdc787b..62c189f 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
@@ -19,6 +19,7 @@
 import static android.view.accessibility.AccessibilityNodeInfo.ACTION_FOCUS;
 
 import static com.android.car.ui.utils.RotaryConstants.ROTARY_CONTAINER;
+import static com.android.car.ui.utils.RotaryConstants.ROTARY_FOCUS_DELEGATING_CONTAINER;
 import static com.android.car.ui.utils.RotaryConstants.ROTARY_HORIZONTALLY_SCROLLABLE;
 import static com.android.car.ui.utils.RotaryConstants.ROTARY_VERTICALLY_SCROLLABLE;
 
@@ -248,6 +249,11 @@
                 || TextUtils.equals(contentDescription, ROTARY_HORIZONTALLY_SCROLLABLE);
     }
 
+    private static boolean isFocusDelegatingContainer(@NonNull View view) {
+        CharSequence contentDescription = view.getContentDescription();
+        return TextUtils.equals(contentDescription, ROTARY_FOCUS_DELEGATING_CONTAINER);
+    }
+
     /**
      * Focuses on the first {@code app:defaultFocus} view in the view tree, if any.
      *
@@ -417,7 +423,8 @@
 
     /** Returns whether {@code view} can be focused. */
     private static boolean canTakeFocus(@NonNull View view) {
-        return view.isFocusable() && view.isEnabled() && view.isShown()
+        boolean focusable = view.isFocusable() || isFocusDelegatingContainer(view);
+        return focusable && view.isEnabled() && view.isShown()
                 && view.getWidth() > 0 && view.getHeight() > 0 && view.isAttachedToWindow()
                 && !(view instanceof FocusParkingView)
                 // If it's a scrollable container, it can be focused only when it has no focusable