DO NOT MERGE Add generic rotary support for sysui overlay window
Bug: 181138897 Test: manual Change-Id: I353d9587fce09c5dff7328b5dec7e973230f2a9c
This commit is contained in:
@@ -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"
|
||||
|
||||
@@ -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>
|
||||
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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">
|
||||
|
||||
<include
|
||||
layout="@layout/car_status_bar_header"
|
||||
android:layout_alignParentTop="true"
|
||||
android:theme="@android:style/Theme"/>
|
||||
|
||||
|
||||
<FrameLayout
|
||||
android:gravity="center">
|
||||
<com.android.systemui.car.userswitcher.UserSwitcherContainer
|
||||
android:id="@+id/container"
|
||||
android:layout_width="match_parent"
|
||||
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>
|
||||
android:layout_height="match_parent"
|
||||
android:background="@color/car_user_switcher_background_color"
|
||||
android:orientation="vertical">
|
||||
|
||||
</com.android.systemui.car.userswitcher.UserSwitcherContainer>
|
||||
<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"
|
||||
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.car.ui.FocusArea>
|
||||
|
||||
@@ -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"/>
|
||||
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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>
|
||||
@@ -147,6 +147,11 @@ public class CarKeyguardViewController extends OverlayViewController implements
|
||||
registerUserSwitchedListener();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int getFocusAreaViewId() {
|
||||
return R.id.keyguard_container;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean shouldShowNavigationBarInsets() {
|
||||
return true;
|
||||
|
||||
@@ -218,6 +218,11 @@ public class NotificationPanelViewController extends OverlayPanelViewController
|
||||
mNotificationVisibilityLogger.stop();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int getFocusAreaViewId() {
|
||||
return R.id.notification_container;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean shouldShowNavigationBarInsets() {
|
||||
return true;
|
||||
|
||||
@@ -76,7 +76,7 @@ public class FullScreenUserSwitcherViewController extends OverlayViewController
|
||||
}
|
||||
|
||||
if (event.getAction() == KeyEvent.ACTION_UP && getLayout().isVisibleToUser()) {
|
||||
getLayout().setVisibility(View.GONE);
|
||||
stop();
|
||||
}
|
||||
return true;
|
||||
});
|
||||
@@ -91,6 +91,11 @@ public class FullScreenUserSwitcherViewController extends OverlayViewController
|
||||
registerCarUserManagerIfPossible();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int getFocusAreaViewId() {
|
||||
return R.id.user_switcher_container;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean shouldFocusWindow() {
|
||||
return true;
|
||||
|
||||
@@ -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.
|
||||
*/
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -214,6 +214,16 @@ public class OverlayViewGlobalStateControllerTest extends SysuiTestCase {
|
||||
verify(mSystemUIOverlayWindowController).setWindowVisible(true);
|
||||
}
|
||||
|
||||
@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
|
||||
@@ -331,6 +340,30 @@ public class OverlayViewGlobalStateControllerTest extends SysuiTestCase {
|
||||
OVERLAY_VIEW_CONTROLLER_2_Z_ORDER).toArray());
|
||||
}
|
||||
|
||||
@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();
|
||||
@@ -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);
|
||||
|
||||
@@ -425,6 +460,30 @@ public class OverlayViewGlobalStateControllerTest extends SysuiTestCase {
|
||||
OVERLAY_VIEW_CONTROLLER_2_Z_ORDER).toArray());
|
||||
}
|
||||
|
||||
@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();
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user