diff options
14 files changed, 236 insertions, 85 deletions
diff --git a/packages/CarSystemUI/res-keyguard/layout/keyguard_container.xml b/packages/CarSystemUI/res-keyguard/layout/keyguard_container.xml index 3e35df9d9b0c..f617ec06ae52 100644 --- a/packages/CarSystemUI/res-keyguard/layout/keyguard_container.xml +++ b/packages/CarSystemUI/res-keyguard/layout/keyguard_container.xml @@ -14,10 +14,7 @@ ~ limitations under the License. --> -<!-- Car customizations - Car has solid black background instead of a transparent one ---> -<LinearLayout +<com.android.car.ui.FocusArea xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/keyguard_container" android:layout_width="match_parent" diff --git a/packages/CarSystemUI/res-keyguard/layout/num_pad_keys.xml b/packages/CarSystemUI/res-keyguard/layout/num_pad_keys.xml index 8306cb4a708a..c5974e3c7167 100644 --- a/packages/CarSystemUI/res-keyguard/layout/num_pad_keys.xml +++ b/packages/CarSystemUI/res-keyguard/layout/num_pad_keys.xml @@ -66,7 +66,6 @@ android:src="@drawable/ic_backspace" android:clickable="true" android:tint="@android:color/white" - android:background="@drawable/ripple_drawable" android:contentDescription="@string/keyboardview_keycode_delete" /> <com.android.keyguard.NumPadKey android:id="@+id/key0" @@ -77,7 +76,6 @@ style="@style/NumPadKeyButton.LastRow" android:src="@drawable/ic_done" android:tint="@android:color/white" - android:background="@drawable/ripple_drawable" android:contentDescription="@string/keyboardview_keycode_enter" /> </merge> diff --git a/packages/CarSystemUI/res-keyguard/values/dimens.xml b/packages/CarSystemUI/res-keyguard/values/dimens.xml index 8dfe1716ef54..3c139586c2cc 100644 --- a/packages/CarSystemUI/res-keyguard/values/dimens.xml +++ b/packages/CarSystemUI/res-keyguard/values/dimens.xml @@ -17,10 +17,8 @@ <resources> <dimen name="num_pad_margin_left">112dp</dimen> <dimen name="num_pad_margin_right">144dp</dimen> - <dimen name="num_pad_key_width">80dp</dimen> + <dimen name="num_pad_key_width">120dp</dimen> <dimen name="num_pad_key_height">80dp</dimen> - <dimen name="num_pad_key_margin_horizontal">@*android:dimen/car_padding_5</dimen> - <dimen name="num_pad_key_margin_bottom">@*android:dimen/car_padding_5</dimen> <dimen name="pin_entry_height">@dimen/num_pad_key_height</dimen> <dimen name="divider_height">1dp</dimen> <dimen name="key_enter_margin_top">128dp</dimen> diff --git a/packages/CarSystemUI/res-keyguard/values/styles.xml b/packages/CarSystemUI/res-keyguard/values/styles.xml index ecea30a13ced..ca37428a9fd9 100644 --- a/packages/CarSystemUI/res-keyguard/values/styles.xml +++ b/packages/CarSystemUI/res-keyguard/values/styles.xml @@ -23,12 +23,11 @@ <item name="android:layout_width">@dimen/num_pad_key_width</item> <item name="android:layout_height">@dimen/num_pad_key_height</item> <item name="android:layout_marginBottom">@dimen/num_pad_key_margin_bottom</item> + <item name="android:background">?android:attr/selectableItemBackground</item> <item name="textView">@id/pinEntry</item> </style> <style name="NumPadKeyButton.MiddleColumn"> - <item name="android:layout_marginStart">@dimen/num_pad_key_margin_horizontal</item> - <item name="android:layout_marginEnd">@dimen/num_pad_key_margin_horizontal</item> </style> <style name="NumPadKeyButton.LastRow"> @@ -36,12 +35,10 @@ </style> <style name="NumPadKeyButton.LastRow.MiddleColumn"> - <item name="android:layout_marginStart">@dimen/num_pad_key_margin_horizontal</item> - <item name="android:layout_marginEnd">@dimen/num_pad_key_margin_horizontal</item> </style> <style name="KeyguardButton" parent="@android:style/Widget.DeviceDefault.Button"> - <item name="android:background">@drawable/keyguard_button_background</item> + <item name="android:background">?android:attr/selectableItemBackground</item> <item name="android:textColor">@color/button_text</item> <item name="android:textAllCaps">false</item> </style> diff --git a/packages/CarSystemUI/res/layout/car_fullscreen_user_switcher.xml b/packages/CarSystemUI/res/layout/car_fullscreen_user_switcher.xml index 99df6d52de07..f987b5a650bc 100644 --- a/packages/CarSystemUI/res/layout/car_fullscreen_user_switcher.xml +++ b/packages/CarSystemUI/res/layout/car_fullscreen_user_switcher.xml @@ -14,29 +14,36 @@ See the License for the specific language governing permissions and limitations under the License. --> -<com.android.systemui.car.userswitcher.UserSwitcherContainer + +<com.android.car.ui.FocusArea xmlns:android="http://schemas.android.com/apk/res/android" - android:id="@+id/container" + android:id="@+id/user_switcher_container" android:layout_width="match_parent" android:layout_height="match_parent" - android:background="@color/car_user_switcher_background_color" - android:orientation="vertical"> + android:gravity="center"> + <com.android.systemui.car.userswitcher.UserSwitcherContainer + android:id="@+id/container" + android:layout_width="match_parent" + android:layout_height="match_parent" + android:background="@color/car_user_switcher_background_color" + android:orientation="vertical"> - <include - layout="@layout/car_status_bar_header" - android:layout_alignParentTop="true" - android:theme="@android:style/Theme"/> + <include + layout="@layout/car_status_bar_header" + android:layout_alignParentTop="true" + android:theme="@android:style/Theme"/> - <FrameLayout - android:layout_width="match_parent" - android:layout_height="match_parent"> - <com.android.systemui.car.userswitcher.UserGridRecyclerView - android:id="@+id/user_grid" + <FrameLayout android:layout_width="match_parent" - android:layout_height="wrap_content" - android:layout_gravity="center_vertical" - android:layout_marginTop="@dimen/car_user_switcher_margin_top"/> - </FrameLayout> + android:layout_height="match_parent"> + <com.android.systemui.car.userswitcher.UserGridRecyclerView + android:id="@+id/user_grid" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:layout_gravity="center_vertical" + android:layout_marginTop="@dimen/car_user_switcher_margin_top"/> + </FrameLayout> -</com.android.systemui.car.userswitcher.UserSwitcherContainer> + </com.android.systemui.car.userswitcher.UserSwitcherContainer> +</com.android.car.ui.FocusArea> diff --git a/packages/CarSystemUI/res/layout/notification_center_activity.xml b/packages/CarSystemUI/res/layout/notification_center_activity.xml index 0e45e43132de..51d23db79e8d 100644 --- a/packages/CarSystemUI/res/layout/notification_center_activity.xml +++ b/packages/CarSystemUI/res/layout/notification_center_activity.xml @@ -22,10 +22,6 @@ android:layout_height="match_parent" android:background="@color/notification_shade_background_color"> - <com.android.car.ui.FocusParkingView - android:layout_width="wrap_content" - android:layout_height="wrap_content"/> - <View android:id="@+id/glass_pane" android:layout_width="match_parent" @@ -37,20 +33,15 @@ app:layout_constraintTop_toTopOf="parent" /> - <com.android.car.ui.FocusArea - android:layout_width="0dp" - android:layout_height="0dp" - android:orientation="vertical" + <androidx.recyclerview.widget.RecyclerView + android:id="@+id/notifications" + android:layout_width="match_parent" + android:layout_height="match_parent" + android:paddingBottom="@dimen/notification_shade_list_padding_bottom" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" - app:layout_constraintTop_toTopOf="parent"> - <androidx.recyclerview.widget.RecyclerView - android:id="@+id/notifications" - android:layout_width="match_parent" - android:layout_height="match_parent" - android:paddingBottom="@dimen/notification_shade_list_padding_bottom"/> - </com.android.car.ui.FocusArea> + app:layout_constraintTop_toTopOf="parent"/> <include layout="@layout/notification_handle_bar"/> diff --git a/packages/CarSystemUI/res/layout/notification_panel_container.xml b/packages/CarSystemUI/res/layout/notification_panel_container.xml index 3b53c6aaeac3..de69769b2bb0 100644 --- a/packages/CarSystemUI/res/layout/notification_panel_container.xml +++ b/packages/CarSystemUI/res/layout/notification_panel_container.xml @@ -14,7 +14,7 @@ ~ See the License for the specific language governing permissions and ~ limitations under the License. --> -<FrameLayout +<com.android.car.ui.FocusArea xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/notification_container" android:layout_width="match_parent" diff --git a/packages/CarSystemUI/res/layout/sysui_overlay_window.xml b/packages/CarSystemUI/res/layout/sysui_overlay_window.xml index e7295aa6383d..3d6085c55b5b 100644 --- a/packages/CarSystemUI/res/layout/sysui_overlay_window.xml +++ b/packages/CarSystemUI/res/layout/sysui_overlay_window.xml @@ -22,25 +22,29 @@ android:layout_width="match_parent" android:layout_height="match_parent"> + <com.android.car.ui.FocusParkingView + android:layout_width="wrap_content" + android:layout_height="wrap_content"/> + <ViewStub android:id="@+id/notification_panel_stub" - android:layout_width="match_parent" - android:layout_height="match_parent" - android:layout="@layout/notification_panel_container" - android:layout_marginBottom="@dimen/car_bottom_navigation_bar_height"/> + android:layout_width="match_parent" + android:layout_height="match_parent" + android:layout="@layout/notification_panel_container" + android:layout_marginBottom="@dimen/car_bottom_navigation_bar_height"/> <ViewStub android:id="@+id/keyguard_stub" - android:layout_width="match_parent" - android:layout_height="match_parent" - android:layout="@layout/keyguard_container" /> + android:layout_width="match_parent" + android:layout_height="match_parent" + android:layout="@layout/keyguard_container" /> <ViewStub android:id="@+id/fullscreen_user_switcher_stub" - android:layout_width="match_parent" - android:layout_height="match_parent" - android:layout="@layout/car_fullscreen_user_switcher"/> + android:layout_width="match_parent" + android:layout_height="match_parent" + android:layout="@layout/car_fullscreen_user_switcher"/> <ViewStub android:id="@+id/user_switching_dialog_stub" - android:layout_width="match_parent" - android:layout_height="match_parent" - android:layout="@layout/car_user_switching_dialog"/> + android:layout_width="match_parent" + android:layout_height="match_parent" + android:layout="@layout/car_user_switching_dialog"/> </FrameLayout>
\ No newline at end of file diff --git a/packages/CarSystemUI/src/com/android/systemui/car/keyguard/CarKeyguardViewController.java b/packages/CarSystemUI/src/com/android/systemui/car/keyguard/CarKeyguardViewController.java index ec018f9bb62e..53d2320b3f9f 100644 --- a/packages/CarSystemUI/src/com/android/systemui/car/keyguard/CarKeyguardViewController.java +++ b/packages/CarSystemUI/src/com/android/systemui/car/keyguard/CarKeyguardViewController.java @@ -148,6 +148,11 @@ public class CarKeyguardViewController extends OverlayViewController implements } @Override + protected int getFocusAreaViewId() { + return R.id.keyguard_container; + } + + @Override protected boolean shouldShowNavigationBarInsets() { return true; } diff --git a/packages/CarSystemUI/src/com/android/systemui/car/notification/NotificationPanelViewController.java b/packages/CarSystemUI/src/com/android/systemui/car/notification/NotificationPanelViewController.java index b83fcf4bf8b5..6597144a088a 100644 --- a/packages/CarSystemUI/src/com/android/systemui/car/notification/NotificationPanelViewController.java +++ b/packages/CarSystemUI/src/com/android/systemui/car/notification/NotificationPanelViewController.java @@ -219,6 +219,11 @@ public class NotificationPanelViewController extends OverlayPanelViewController } @Override + protected int getFocusAreaViewId() { + return R.id.notification_container; + } + + @Override protected boolean shouldShowNavigationBarInsets() { return true; } diff --git a/packages/CarSystemUI/src/com/android/systemui/car/userswitcher/FullScreenUserSwitcherViewController.java b/packages/CarSystemUI/src/com/android/systemui/car/userswitcher/FullScreenUserSwitcherViewController.java index 5fc7299f68c5..dd59efa7b0b2 100644 --- a/packages/CarSystemUI/src/com/android/systemui/car/userswitcher/FullScreenUserSwitcherViewController.java +++ b/packages/CarSystemUI/src/com/android/systemui/car/userswitcher/FullScreenUserSwitcherViewController.java @@ -76,7 +76,7 @@ public class FullScreenUserSwitcherViewController extends OverlayViewController } if (event.getAction() == KeyEvent.ACTION_UP && getLayout().isVisibleToUser()) { - getLayout().setVisibility(View.GONE); + stop(); } return true; }); @@ -92,6 +92,11 @@ public class FullScreenUserSwitcherViewController extends OverlayViewController } @Override + protected int getFocusAreaViewId() { + return R.id.user_switcher_container; + } + + @Override protected boolean shouldFocusWindow() { return true; } diff --git a/packages/CarSystemUI/src/com/android/systemui/car/window/OverlayViewController.java b/packages/CarSystemUI/src/com/android/systemui/car/window/OverlayViewController.java index 8adc1adcc41c..7bc17765d9fc 100644 --- a/packages/CarSystemUI/src/com/android/systemui/car/window/OverlayViewController.java +++ b/packages/CarSystemUI/src/com/android/systemui/car/window/OverlayViewController.java @@ -17,12 +17,17 @@ package com.android.systemui.car.window; import static android.view.WindowInsets.Type.statusBars; +import static android.view.accessibility.AccessibilityNodeInfo.ACTION_FOCUS; import android.view.View; import android.view.ViewGroup; import android.view.ViewStub; import android.view.WindowInsets; +import androidx.annotation.IdRes; + +import com.android.car.ui.FocusArea; + /** * Owns a {@link View} that is present in SystemUIOverlayWindow. */ @@ -128,6 +133,66 @@ public class OverlayViewController { return mOverlayViewGlobalStateController; } + /** Returns whether the view controlled by this controller is visible. */ + public final boolean isVisible() { + return mLayout.getVisibility() == View.VISIBLE; + } + + /** + * Returns the ID of the focus area that should receive focus when this view is the + * topmost view or {@link View#NO_ID} if there is no focus area. + */ + @IdRes + protected int getFocusAreaViewId() { + return View.NO_ID; + } + + /** Returns whether the view controlled by this controller has rotary focus. */ + protected final boolean hasRotaryFocus() { + return !mLayout.isInTouchMode() && mLayout.hasFocus(); + } + + /** + * Sets whether this view allows rotary focus. This should be set to {@code true} for the + * topmost layer in the overlay window and {@code false} for the others. + */ + public void setAllowRotaryFocus(boolean allowRotaryFocus) { + if (!isInflated()) { + return; + } + + if (!(mLayout instanceof ViewGroup)) { + return; + } + + ViewGroup viewGroup = (ViewGroup) mLayout; + viewGroup.setDescendantFocusability(allowRotaryFocus + ? ViewGroup.FOCUS_BEFORE_DESCENDANTS + : ViewGroup.FOCUS_BLOCK_DESCENDANTS); + } + + /** + * Refreshes the rotary focus in this view if we are in rotary mode. If the view already has + * rotary focus, it leaves the focus alone. Returns {@code true} if a new view was focused. + */ + public boolean refreshRotaryFocusIfNeeded() { + if (mLayout.isInTouchMode()) { + return false; + } + + if (hasRotaryFocus()) { + return false; + } + + View view = mLayout.findViewById(getFocusAreaViewId()); + if (view == null || !(view instanceof FocusArea)) { + return mLayout.requestFocus(); + } + + FocusArea focusArea = (FocusArea) view; + return focusArea.performAccessibilityAction(ACTION_FOCUS, /* arguments= */ null); + } + /** * Returns {@code true} if heads up notifications should be displayed over this view. */ diff --git a/packages/CarSystemUI/src/com/android/systemui/car/window/OverlayViewGlobalStateController.java b/packages/CarSystemUI/src/com/android/systemui/car/window/OverlayViewGlobalStateController.java index 55f0975aeccf..204dde7e87b7 100644 --- a/packages/CarSystemUI/src/com/android/systemui/car/window/OverlayViewGlobalStateController.java +++ b/packages/CarSystemUI/src/com/android/systemui/car/window/OverlayViewGlobalStateController.java @@ -29,6 +29,7 @@ import androidx.annotation.VisibleForTesting; import java.util.HashMap; import java.util.HashSet; import java.util.Map; +import java.util.Objects; import java.util.Set; import java.util.SortedMap; import java.util.TreeMap; @@ -120,6 +121,7 @@ public class OverlayViewGlobalStateController { refreshWindowFocus(); refreshNavigationBarVisibility(); refreshStatusBarVisibility(); + refreshRotaryFocusIfNeeded(); Log.d(TAG, "Content shown: " + viewController.getClass().getName()); debugLog(); @@ -193,6 +195,7 @@ public class OverlayViewGlobalStateController { refreshWindowFocus(); refreshNavigationBarVisibility(); refreshStatusBarVisibility(); + refreshRotaryFocusIfNeeded(); if (mZOrderVisibleSortedMap.isEmpty()) { setWindowVisible(false); @@ -254,6 +257,17 @@ public class OverlayViewGlobalStateController { } } + private void refreshRotaryFocusIfNeeded() { + for (OverlayViewController controller : mZOrderVisibleSortedMap.values()) { + boolean isTop = Objects.equals(controller, mHighestZOrder); + controller.setAllowRotaryFocus(isTop); + } + + if (!mZOrderVisibleSortedMap.isEmpty()) { + mHighestZOrder.refreshRotaryFocusIfNeeded(); + } + } + /** Returns {@code true} is the window is visible. */ public boolean isWindowVisible() { return mSystemUIOverlayWindowController.isWindowVisible(); diff --git a/packages/CarSystemUI/tests/src/com/android/systemui/car/window/OverlayViewGlobalStateControllerTest.java b/packages/CarSystemUI/tests/src/com/android/systemui/car/window/OverlayViewGlobalStateControllerTest.java index 294aa0d3cf9b..d97b2329350f 100644 --- a/packages/CarSystemUI/tests/src/com/android/systemui/car/window/OverlayViewGlobalStateControllerTest.java +++ b/packages/CarSystemUI/tests/src/com/android/systemui/car/window/OverlayViewGlobalStateControllerTest.java @@ -215,6 +215,16 @@ public class OverlayViewGlobalStateControllerTest extends SysuiTestCase { } @Test + public void showView_nothingAlreadyShown_newHighestZOrder_isVisible() { + setupOverlayViewController1(); + + mOverlayViewGlobalStateController.showView(mOverlayViewController1, mRunnable); + + assertThat(mOverlayViewGlobalStateController.mZOrderVisibleSortedMap.containsKey( + OVERLAY_VIEW_CONTROLLER_1_Z_ORDER)).isTrue(); + } + + @Test public void showView_nothingAlreadyShown_newHighestZOrder() { setupOverlayViewController1(); @@ -225,13 +235,12 @@ public class OverlayViewGlobalStateControllerTest extends SysuiTestCase { } @Test - public void showView_nothingAlreadyShown_newHighestZOrder_isVisible() { + public void showView_nothingAlreadyShown_descendantsFocusable() { setupOverlayViewController1(); mOverlayViewGlobalStateController.showView(mOverlayViewController1, mRunnable); - assertThat(mOverlayViewGlobalStateController.mZOrderVisibleSortedMap.containsKey( - OVERLAY_VIEW_CONTROLLER_1_Z_ORDER)).isTrue(); + verify(mOverlayViewController1).setAllowRotaryFocus(true); } @Test @@ -332,6 +341,30 @@ public class OverlayViewGlobalStateControllerTest extends SysuiTestCase { } @Test + public void showView_newHighestZOrder_topDescendantsFocusable() { + setupOverlayViewController1(); + setOverlayViewControllerAsShowing(mOverlayViewController1); + setupOverlayViewController2(); + + mOverlayViewGlobalStateController.showView(mOverlayViewController2, mRunnable); + + verify(mOverlayViewController1).setAllowRotaryFocus(false); + verify(mOverlayViewController2).setAllowRotaryFocus(true); + } + + @Test + public void showView_newHighestZOrder_refreshTopFocus() { + setupOverlayViewController1(); + setOverlayViewControllerAsShowing(mOverlayViewController1); + setupOverlayViewController2(); + + mOverlayViewGlobalStateController.showView(mOverlayViewController2, mRunnable); + + verify(mOverlayViewController1, never()).refreshRotaryFocusIfNeeded(); + verify(mOverlayViewController2).refreshRotaryFocusIfNeeded(); + } + + @Test public void showView_oldHighestZOrder() { setupOverlayViewController2(); setOverlayViewControllerAsShowing(mOverlayViewController2); @@ -345,9 +378,9 @@ public class OverlayViewGlobalStateControllerTest extends SysuiTestCase { @Test public void showView_oldHighestZOrder_shouldShowNavBarFalse_navigationBarsHidden() { setupOverlayViewController2(); + setOverlayViewControllerAsShowing(mOverlayViewController2); when(mOverlayViewController1.shouldFocusWindow()).thenReturn(true); when(mOverlayViewController2.shouldFocusWindow()).thenReturn(true); - setOverlayViewControllerAsShowing(mOverlayViewController2); when(mOverlayViewController1.shouldShowNavigationBarInsets()).thenReturn(true); when(mOverlayViewController2.shouldShowNavigationBarInsets()).thenReturn(false); reset(mWindowInsetsController); @@ -360,11 +393,12 @@ public class OverlayViewGlobalStateControllerTest extends SysuiTestCase { @Test public void showView_oldHighestZOrder_shouldShowNavBarTrue_navigationBarsShown() { setupOverlayViewController2(); + setOverlayViewControllerAsShowing(mOverlayViewController2); when(mOverlayViewController1.shouldFocusWindow()).thenReturn(true); when(mOverlayViewController2.shouldFocusWindow()).thenReturn(true); - setOverlayViewControllerAsShowing(mOverlayViewController2); when(mOverlayViewController1.shouldShowNavigationBarInsets()).thenReturn(false); when(mOverlayViewController2.shouldShowNavigationBarInsets()).thenReturn(true); + reset(mWindowInsetsController); mOverlayViewGlobalStateController.showView(mOverlayViewController1, mRunnable); @@ -374,9 +408,9 @@ public class OverlayViewGlobalStateControllerTest extends SysuiTestCase { @Test public void showView_oldHighestZOrder_shouldShowStatusBarFalse_statusBarsHidden() { setupOverlayViewController2(); + setOverlayViewControllerAsShowing(mOverlayViewController2); when(mOverlayViewController1.shouldFocusWindow()).thenReturn(true); when(mOverlayViewController2.shouldFocusWindow()).thenReturn(true); - setOverlayViewControllerAsShowing(mOverlayViewController2); when(mOverlayViewController1.shouldShowStatusBarInsets()).thenReturn(true); when(mOverlayViewController2.shouldShowStatusBarInsets()).thenReturn(false); reset(mWindowInsetsController); @@ -389,11 +423,12 @@ public class OverlayViewGlobalStateControllerTest extends SysuiTestCase { @Test public void showView_oldHighestZOrder_shouldShowStatusBarTrue_statusBarsShown() { setupOverlayViewController2(); + setOverlayViewControllerAsShowing(mOverlayViewController2); when(mOverlayViewController1.shouldFocusWindow()).thenReturn(true); when(mOverlayViewController2.shouldFocusWindow()).thenReturn(true); - setOverlayViewControllerAsShowing(mOverlayViewController2); when(mOverlayViewController1.shouldShowStatusBarInsets()).thenReturn(false); when(mOverlayViewController2.shouldShowStatusBarInsets()).thenReturn(true); + reset(mWindowInsetsController); mOverlayViewGlobalStateController.showView(mOverlayViewController1, mRunnable); @@ -426,6 +461,30 @@ public class OverlayViewGlobalStateControllerTest extends SysuiTestCase { } @Test + public void showView_oldHighestZOrder_topDescendantsFocusable() { + setupOverlayViewController1(); + setupOverlayViewController2(); + setOverlayViewControllerAsShowing(mOverlayViewController2); + + mOverlayViewGlobalStateController.showView(mOverlayViewController1, mRunnable); + + verify(mOverlayViewController1).setAllowRotaryFocus(false); + verify(mOverlayViewController2).setAllowRotaryFocus(true); + } + + @Test + public void showView_oldHighestZOrder_refreshTopFocus() { + setupOverlayViewController1(); + setupOverlayViewController2(); + setOverlayViewControllerAsShowing(mOverlayViewController2); + + mOverlayViewGlobalStateController.showView(mOverlayViewController1, mRunnable); + + verify(mOverlayViewController1, never()).refreshRotaryFocusIfNeeded(); + verify(mOverlayViewController2).refreshRotaryFocusIfNeeded(); + } + + @Test public void showView_somethingAlreadyShown_windowVisibleNotCalled() { setupOverlayViewController1(); setOverlayViewControllerAsShowing(mOverlayViewController1); @@ -577,10 +636,10 @@ public class OverlayViewGlobalStateControllerTest extends SysuiTestCase { public void hideView_newHighestZOrder_shouldShowNavBarFalse_navigationBarHidden() { setupOverlayViewController1(); setupOverlayViewController2(); - when(mOverlayViewController1.shouldFocusWindow()).thenReturn(true); - when(mOverlayViewController2.shouldFocusWindow()).thenReturn(true); setOverlayViewControllerAsShowing(mOverlayViewController1); setOverlayViewControllerAsShowing(mOverlayViewController2); + when(mOverlayViewController1.shouldFocusWindow()).thenReturn(true); + when(mOverlayViewController2.shouldFocusWindow()).thenReturn(true); when(mOverlayViewController1.shouldShowNavigationBarInsets()).thenReturn(false); reset(mWindowInsetsController); @@ -593,10 +652,10 @@ public class OverlayViewGlobalStateControllerTest extends SysuiTestCase { public void hideView_newHighestZOrder_shouldShowNavBarTrue_navigationBarShown() { setupOverlayViewController1(); setupOverlayViewController2(); - when(mOverlayViewController1.shouldFocusWindow()).thenReturn(true); - when(mOverlayViewController2.shouldFocusWindow()).thenReturn(true); setOverlayViewControllerAsShowing(mOverlayViewController1); setOverlayViewControllerAsShowing(mOverlayViewController2); + when(mOverlayViewController1.shouldFocusWindow()).thenReturn(true); + when(mOverlayViewController2.shouldFocusWindow()).thenReturn(true); when(mOverlayViewController1.shouldShowNavigationBarInsets()).thenReturn(true); reset(mWindowInsetsController); @@ -609,10 +668,10 @@ public class OverlayViewGlobalStateControllerTest extends SysuiTestCase { public void hideView_newHighestZOrder_shouldShowStatusBarFalse_statusBarHidden() { setupOverlayViewController1(); setupOverlayViewController2(); - when(mOverlayViewController1.shouldFocusWindow()).thenReturn(true); - when(mOverlayViewController2.shouldFocusWindow()).thenReturn(true); setOverlayViewControllerAsShowing(mOverlayViewController1); setOverlayViewControllerAsShowing(mOverlayViewController2); + when(mOverlayViewController1.shouldFocusWindow()).thenReturn(true); + when(mOverlayViewController2.shouldFocusWindow()).thenReturn(true); when(mOverlayViewController1.shouldShowStatusBarInsets()).thenReturn(false); reset(mWindowInsetsController); @@ -625,10 +684,10 @@ public class OverlayViewGlobalStateControllerTest extends SysuiTestCase { public void hideView_newHighestZOrder_shouldShowStatusBarTrue_statusBarShown() { setupOverlayViewController1(); setupOverlayViewController2(); - when(mOverlayViewController1.shouldFocusWindow()).thenReturn(true); - when(mOverlayViewController2.shouldFocusWindow()).thenReturn(true); setOverlayViewControllerAsShowing(mOverlayViewController1); setOverlayViewControllerAsShowing(mOverlayViewController2); + when(mOverlayViewController1.shouldFocusWindow()).thenReturn(true); + when(mOverlayViewController2.shouldFocusWindow()).thenReturn(true); when(mOverlayViewController1.shouldShowStatusBarInsets()).thenReturn(true); reset(mWindowInsetsController); @@ -668,10 +727,10 @@ public class OverlayViewGlobalStateControllerTest extends SysuiTestCase { public void hideView_oldHighestZOrder_shouldShowNavBarFalse_navigationBarHidden() { setupOverlayViewController1(); setupOverlayViewController2(); - when(mOverlayViewController1.shouldFocusWindow()).thenReturn(true); - when(mOverlayViewController2.shouldFocusWindow()).thenReturn(true); setOverlayViewControllerAsShowing(mOverlayViewController1); setOverlayViewControllerAsShowing(mOverlayViewController2); + when(mOverlayViewController1.shouldFocusWindow()).thenReturn(true); + when(mOverlayViewController2.shouldFocusWindow()).thenReturn(true); when(mOverlayViewController2.shouldShowNavigationBarInsets()).thenReturn(false); reset(mWindowInsetsController); @@ -684,11 +743,12 @@ public class OverlayViewGlobalStateControllerTest extends SysuiTestCase { public void hideView_oldHighestZOrder_shouldShowNavBarTrue_navigationBarShown() { setupOverlayViewController1(); setupOverlayViewController2(); - when(mOverlayViewController1.shouldFocusWindow()).thenReturn(true); - when(mOverlayViewController2.shouldFocusWindow()).thenReturn(true); setOverlayViewControllerAsShowing(mOverlayViewController1); setOverlayViewControllerAsShowing(mOverlayViewController2); + when(mOverlayViewController1.shouldFocusWindow()).thenReturn(true); + when(mOverlayViewController2.shouldFocusWindow()).thenReturn(true); when(mOverlayViewController2.shouldShowNavigationBarInsets()).thenReturn(true); + reset(mWindowInsetsController); mOverlayViewGlobalStateController.hideView(mOverlayViewController1, mRunnable); @@ -699,10 +759,10 @@ public class OverlayViewGlobalStateControllerTest extends SysuiTestCase { public void hideView_oldHighestZOrder_shouldShowStatusBarFalse_statusBarHidden() { setupOverlayViewController1(); setupOverlayViewController2(); - when(mOverlayViewController1.shouldFocusWindow()).thenReturn(true); - when(mOverlayViewController2.shouldFocusWindow()).thenReturn(true); setOverlayViewControllerAsShowing(mOverlayViewController1); setOverlayViewControllerAsShowing(mOverlayViewController2); + when(mOverlayViewController1.shouldFocusWindow()).thenReturn(true); + when(mOverlayViewController2.shouldFocusWindow()).thenReturn(true); when(mOverlayViewController2.shouldShowStatusBarInsets()).thenReturn(false); reset(mWindowInsetsController); @@ -715,11 +775,12 @@ public class OverlayViewGlobalStateControllerTest extends SysuiTestCase { public void hideView_oldHighestZOrder_shouldShowStatusBarTrue_statusBarShown() { setupOverlayViewController1(); setupOverlayViewController2(); - when(mOverlayViewController1.shouldFocusWindow()).thenReturn(true); - when(mOverlayViewController2.shouldFocusWindow()).thenReturn(true); setOverlayViewControllerAsShowing(mOverlayViewController1); setOverlayViewControllerAsShowing(mOverlayViewController2); + when(mOverlayViewController1.shouldFocusWindow()).thenReturn(true); + when(mOverlayViewController2.shouldFocusWindow()).thenReturn(true); when(mOverlayViewController2.shouldShowStatusBarInsets()).thenReturn(true); + reset(mWindowInsetsController); mOverlayViewGlobalStateController.hideView(mOverlayViewController1, mRunnable); @@ -917,7 +978,11 @@ public class OverlayViewGlobalStateControllerTest extends SysuiTestCase { private void setOverlayViewControllerAsShowing(OverlayViewController overlayViewController) { mOverlayViewGlobalStateController.showView(overlayViewController, /* show= */ null); + View layout = overlayViewController.getLayout(); reset(mSystemUIOverlayWindowController); + reset(overlayViewController); when(mSystemUIOverlayWindowController.getBaseLayout()).thenReturn(mBaseLayout); + when(overlayViewController.getLayout()).thenReturn(layout); + when(overlayViewController.isInflated()).thenReturn(true); } } |