Exit touch mode when requested
Fix a bug introduced in ag/12951584. Rather than always checking for
touch mode, only do so when restoreDefaultFocus() is called by the
framework, not when performing ACTION_RESTORE_DEFAULT_FOCUS.
Test: switch from touch to rotary mode
Test: launch Settings using touch
Test: atest com.android.car.ui.FocusParkingViewTouchModeTest
Bug: 170907011
Change-Id: I9dcbe974ce25a388d0695018bb73db3ab2df831a
diff --git a/car-ui-lib/car-ui-lib/src/androidTest/java/com/android/car/ui/FocusParkingViewTouchModeTest.java b/car-ui-lib/car-ui-lib/src/androidTest/java/com/android/car/ui/FocusParkingViewTouchModeTest.java
index 3c69854..d872bb6 100644
--- a/car-ui-lib/car-ui-lib/src/androidTest/java/com/android/car/ui/FocusParkingViewTouchModeTest.java
+++ b/car-ui-lib/car-ui-lib/src/androidTest/java/com/android/car/ui/FocusParkingViewTouchModeTest.java
@@ -16,9 +16,13 @@
package com.android.car.ui;
+import static com.android.car.ui.utils.RotaryConstants.ACTION_RESTORE_DEFAULT_FOCUS;
+
import static com.google.common.truth.Truth.assertThat;
import static com.google.common.truth.Truth.assertWithMessage;
+import android.view.View;
+
import androidx.test.rule.ActivityTestRule;
import com.android.car.ui.test.R;
@@ -48,10 +52,38 @@
mFpv.post(() -> {
assertThat(mFpv.getRootView().findFocus()).isNull();
- mFpv.restoreDefaultFocus();
+ boolean result = mFpv.restoreDefaultFocus();
+ assertWithMessage("restoreDefaultFocus returned").that(result).isFalse();
assertWithMessage("No view should be focused")
.that(mFpv.getRootView().findFocus()).isNull();
});
}
+
+ @Test
+ public void testRequestFocus_doesNothing() {
+ mFpv.post(() -> {
+ assertThat(mFpv.getRootView().findFocus()).isNull();
+
+ boolean result = mFpv.requestFocus(View.FOCUS_DOWN, /* previouslyFocusedRect= */ null);
+
+ assertWithMessage("requestFocus returned").that(result).isFalse();
+ assertWithMessage("No view should be focused")
+ .that(mFpv.getRootView().findFocus()).isNull();
+ });
+ }
+
+ @Test
+ public void testPerformActionRestoreDefaultFocus_exitsTouchMode() {
+ mFpv.post(() -> {
+ assertThat(mFpv.getRootView().findFocus()).isNull();
+
+ boolean result = mFpv.performAccessibilityAction(
+ ACTION_RESTORE_DEFAULT_FOCUS, /* arguments= */ null);
+
+ assertWithMessage("performAccessibilityAction returned").that(result).isTrue();
+ assertWithMessage("A view should be focused")
+ .that(mFpv.getRootView().findFocus()).isNotNull();
+ });
+ }
}
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 e1d8010..e5a2533 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
@@ -145,7 +145,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();
+ restoreFocusInRoot(/* checkForTouchMode= */ true);
}
super.onWindowFocusChanged(hasWindowFocus);
}
@@ -159,7 +159,7 @@
public boolean performAccessibilityAction(int action, Bundle arguments) {
switch (action) {
case ACTION_RESTORE_DEFAULT_FOCUS:
- return restoreFocusInRoot();
+ return restoreFocusInRoot(/* checkForTouchMode= */ false);
case ACTION_HIDE_IME:
InputMethodManager inputMethodManager =
getContext().getSystemService(InputMethodManager.class);
@@ -179,19 +179,19 @@
public boolean requestFocus(int direction, Rect previouslyFocusedRect) {
// Find a better target to focus instead of focusing this FocusParkingView when the
// framework wants to focus it.
- return restoreFocusInRoot();
+ return restoreFocusInRoot(/* checkForTouchMode= */ true);
}
@Override
public boolean restoreDefaultFocus() {
// Find a better target to focus instead of focusing this FocusParkingView when the
// framework wants to focus it.
- return restoreFocusInRoot();
+ return restoreFocusInRoot(/* checkForTouchMode= */ true);
}
- private boolean restoreFocusInRoot() {
- // Don't do anything in touch mode.
- if (isInTouchMode()) {
+ private boolean restoreFocusInRoot(boolean checkForTouchMode) {
+ // Don't do anything in touch mode if checkForTouchMode is true.
+ if (checkForTouchMode && isInTouchMode()) {
return false;
}
// The focused view was in a scrollable container and the Framework unfocused it because it