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