Merge "Enable defining system bar side to fit by the side."

This commit is contained in:
Youngjun Kwak
2020-10-23 19:16:12 +00:00
committed by Android (Google) Code Review
6 changed files with 166 additions and 6 deletions

View File

@@ -154,4 +154,13 @@
<!-- The Activity name for the Rear View Camera, if empty, the feature will be disabled. -->
<string name="config_rearViewCameraActivity" translatable="false"></string>
<!-- Whether the Notification Panel should be inset by the top system bar. -->
<bool name="config_notif_panel_inset_by_top_systembar" translatable="false">false</bool>
<!-- Whether the Notification Panel should be inset by the bottom system bar. -->
<bool name="config_notif_panel_inset_by_bottom_systembar" translatable="false">true</bool>
<!-- Whether the Notification Panel should be inset by the left system bar. -->
<bool name="config_notif_panel_inset_by_left_systembar" translatable="false">false</bool>
<!-- Whether the Notification Panel should be inset by the right system bar. -->
<bool name="config_notif_panel_inset_by_right_systembar" translatable="false">false</bool>
</resources>

View File

@@ -49,6 +49,7 @@ import com.android.systemui.R;
import com.android.systemui.car.CarDeviceProvisionedController;
import com.android.systemui.car.CarServiceProvider;
import com.android.systemui.car.window.OverlayPanelViewController;
import com.android.systemui.car.window.OverlayViewController;
import com.android.systemui.car.window.OverlayViewGlobalStateController;
import com.android.systemui.dagger.SysUISingleton;
import com.android.systemui.dagger.qualifiers.Main;
@@ -84,6 +85,11 @@ public class NotificationPanelViewController extends OverlayPanelViewController
private final boolean mEnableHeadsUpNotificationWhenNotificationShadeOpen;
private final NotificationVisibilityLogger mNotificationVisibilityLogger;
private final boolean mFitTopSystemBarInset;
private final boolean mFitBottomSystemBarInset;
private final boolean mFitLeftSystemBarInset;
private final boolean mFitRightSystemBarInset;
private float mInitialBackgroundAlpha;
private float mBackgroundAlphaDiff;
@@ -164,6 +170,15 @@ public class NotificationPanelViewController extends OverlayPanelViewController
mEnableHeadsUpNotificationWhenNotificationShadeOpen = mResources.getBoolean(
com.android.car.notification.R.bool
.config_enableHeadsUpNotificationWhenNotificationShadeOpen);
mFitTopSystemBarInset = mResources.getBoolean(
R.bool.config_notif_panel_inset_by_top_systembar);
mFitBottomSystemBarInset = mResources.getBoolean(
R.bool.config_notif_panel_inset_by_bottom_systembar);
mFitLeftSystemBarInset = mResources.getBoolean(
R.bool.config_notif_panel_inset_by_left_systembar);
mFitRightSystemBarInset = mResources.getBoolean(
R.bool.config_notif_panel_inset_by_right_systembar);
}
// CommandQueue.Callbacks
@@ -215,8 +230,26 @@ public class NotificationPanelViewController extends OverlayPanelViewController
}
@Override
protected int getInsetTypesToFit() {
return WindowInsets.Type.navigationBars();
protected int getInsetSidesToFit() {
int insetSidesToFit = OverlayViewController.NO_INSET_SIDE;
if (mFitTopSystemBarInset) {
insetSidesToFit = insetSidesToFit | WindowInsets.Side.TOP;
}
if (mFitBottomSystemBarInset) {
insetSidesToFit = insetSidesToFit | WindowInsets.Side.BOTTOM;
}
if (mFitLeftSystemBarInset) {
insetSidesToFit = insetSidesToFit | WindowInsets.Side.LEFT;
}
if (mFitRightSystemBarInset) {
insetSidesToFit = insetSidesToFit | WindowInsets.Side.RIGHT;
}
return insetSidesToFit;
}
@Override

View File

@@ -27,6 +27,9 @@ import android.view.WindowInsets;
* Owns a {@link View} that is present in SystemUIOverlayWindow.
*/
public class OverlayViewController {
protected static final int INVALID_INSET_SIDE = -1;
protected static final int NO_INSET_SIDE = 0;
private final int mStubId;
private final OverlayViewGlobalStateController mOverlayViewGlobalStateController;
@@ -188,4 +191,28 @@ public class OverlayViewController {
protected int getInsetTypesToFit() {
return statusBars();
}
/**
* Optionally returns the sides of enabled system bar insets to fit to the sysui overlay window
* when this {@link OverlayViewController} is in the foreground.
*
* For example, if the bottom and left system bars are enabled and this method returns
* WindowInsets.Side.LEFT, then the inset from the bottom system bar will be ignored.
*
* NOTE: By default, this method returns {@link #INVALID_INSET_SIDE}, so insets to fit are
* defined by {@link #getInsetTypesToFit()}, and not by this method, unless it is overridden
* by subclasses.
*
* NOTE: {@link #NO_INSET_SIDE} signifies no insets from any system bars will be honored. Each
* {@link OverlayViewController} can first take this value and add sides of the system bar
* insets to honor to it.
*
* NOTE: If getInsetSidesToFit is overridden to return {@link WindowInsets.Side}, it always
* takes precedence over {@link #getInsetTypesToFit()}. That is, the return value of {@link
* #getInsetTypesToFit()} will be ignored.
*/
@WindowInsets.Side.InsetsSide
protected int getInsetSidesToFit() {
return INVALID_INSET_SIDE;
}
}

View File

@@ -21,6 +21,8 @@ import static android.view.WindowInsets.Type.statusBars;
import android.annotation.Nullable;
import android.util.Log;
import android.view.WindowInsets;
import android.view.WindowInsets.Side.InsetsSide;
import android.view.WindowInsets.Type.InsetsType;
import android.view.WindowInsetsController;
@@ -119,7 +121,7 @@ public class OverlayViewGlobalStateController {
updateInternalsWhenShowingView(viewController);
refreshUseStableInsets();
refreshInsetTypesToFit();
refreshInsetsToFit();
refreshWindowFocus();
refreshNavigationBarVisibility();
refreshStatusBarVisibility();
@@ -193,7 +195,7 @@ public class OverlayViewGlobalStateController {
mZOrderVisibleSortedMap.remove(mZOrderMap.get(viewController));
refreshHighestZOrderWhenHidingView(viewController);
refreshUseStableInsets();
refreshInsetTypesToFit();
refreshInsetsToFit();
refreshWindowFocus();
refreshNavigationBarVisibility();
refreshStatusBarVisibility();
@@ -255,11 +257,25 @@ public class OverlayViewGlobalStateController {
mHighestZOrder == null ? false : mHighestZOrder.shouldUseStableInsets());
}
private void refreshInsetTypesToFit() {
/**
* Refreshes the insets to fit (or honor) either by {@link InsetsType} or {@link InsetsSide}.
*
* By default, the insets to fit are defined by the {@link InsetsType}. But if an
* {@link OverlayViewController} overrides {@link OverlayViewController#getInsetSidesToFit()} to
* return an {@link InsetsSide}, then that takes precedence over {@link InsetsType}.
*/
private void refreshInsetsToFit() {
if (mZOrderVisibleSortedMap.isEmpty()) {
setFitInsetsTypes(statusBars());
} else {
setFitInsetsTypes(mHighestZOrder.getInsetTypesToFit());
if (mHighestZOrder.getInsetSidesToFit() != OverlayViewController.INVALID_INSET_SIDE) {
// First fit all system bar insets as setFitInsetsSide defines which sides of system
// bar insets to actually honor.
setFitInsetsTypes(WindowInsets.Type.systemBars());
setFitInsetsSides(mHighestZOrder.getInsetSidesToFit());
} else {
setFitInsetsTypes(mHighestZOrder.getInsetTypesToFit());
}
}
}
@@ -272,10 +288,16 @@ public class OverlayViewGlobalStateController {
mSystemUIOverlayWindowController.setWindowVisible(visible);
}
/** Sets the insets to fit based on the {@link InsetsType} */
private void setFitInsetsTypes(@InsetsType int types) {
mSystemUIOverlayWindowController.setFitInsetsTypes(types);
}
/** Sets the insets to fit based on the {@link InsetsSide} */
private void setFitInsetsSides(@InsetsSide int sides) {
mSystemUIOverlayWindowController.setFitInsetsSides(sides);
}
/**
* Sets the {@link android.view.WindowManager.LayoutParams#FLAG_ALT_FOCUSABLE_IM} flag of the
* sysui overlay window.

View File

@@ -120,6 +120,13 @@ public class SystemUIOverlayWindowController implements
updateWindow();
}
/** Sets the sides of system bar insets to fit. Note: This should be rarely used. */
public void setFitInsetsSides(@WindowInsets.Side.InsetsSide int sides) {
mLpChanged.setFitInsetsSides(sides);
mLpChanged.setFitInsetsIgnoringVisibility(mUsingStableInsets);
updateWindow();
}
/** Sets the window to the visible state. */
public void setWindowVisible(boolean visible) {
mVisible = visible;

View File

@@ -33,6 +33,7 @@ import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewStub;
import android.view.WindowInsets;
import android.view.WindowInsetsController;
import androidx.test.filters.SmallTest;
@@ -887,6 +888,65 @@ public class OverlayViewGlobalStateControllerTest extends SysuiTestCase {
verify(mOverlayViewController2, never()).inflate(mBaseLayout);
}
@Test
public void showView_setInsetsToFitByType_setsFitInsetsType() {
int insetTypeToFit = WindowInsets.Type.navigationBars();
setupOverlayViewController1();
when(mOverlayViewController1.getInsetTypesToFit()).thenReturn(insetTypeToFit);
mOverlayViewGlobalStateController.showView(mOverlayViewController1, mRunnable);
verify(mSystemUIOverlayWindowController).setFitInsetsTypes(insetTypeToFit);
}
@Test
public void refreshInsetsToFit_setInsetsToFitBySide_setsFitInsetsSides() {
int insetSidesToFit = WindowInsets.Side.LEFT;
setupOverlayViewController1();
when(mOverlayViewController1.getInsetSidesToFit()).thenReturn(insetSidesToFit);
mOverlayViewGlobalStateController.showView(mOverlayViewController1, mRunnable);
verify(mSystemUIOverlayWindowController).setFitInsetsSides(insetSidesToFit);
}
@Test
public void refreshInsetsToFit_setInsetsToFitBySideUsed_firstFitsAllSystemBars() {
int insetSidesToFit = WindowInsets.Side.LEFT;
setupOverlayViewController1();
when(mOverlayViewController1.getInsetSidesToFit()).thenReturn(insetSidesToFit);
mOverlayViewGlobalStateController.showView(mOverlayViewController1, mRunnable);
verify(mSystemUIOverlayWindowController).setFitInsetsTypes(WindowInsets.Type.systemBars());
}
@Test
public void refreshInsetsToFit_bothInsetTypeAndSideDefined_insetSideTakesPrecedence() {
int insetTypesToFit = WindowInsets.Type.navigationBars();
int insetSidesToFit = WindowInsets.Side.LEFT;
setupOverlayViewController1();
when(mOverlayViewController1.getInsetTypesToFit()).thenReturn(insetTypesToFit);
when(mOverlayViewController1.getInsetSidesToFit()).thenReturn(insetSidesToFit);
mOverlayViewGlobalStateController.showView(mOverlayViewController1, mRunnable);
verify(mSystemUIOverlayWindowController).setFitInsetsSides(insetSidesToFit);
}
@Test
public void refreshInsetsToFit_bothInsetTypeAndSideDefined_insetTypeIgnored() {
int insetTypesToFit = WindowInsets.Type.navigationBars();
int insetSidesToFit = WindowInsets.Side.LEFT;
setupOverlayViewController1();
when(mOverlayViewController1.getInsetTypesToFit()).thenReturn(insetTypesToFit);
when(mOverlayViewController1.getInsetSidesToFit()).thenReturn(insetSidesToFit);
mOverlayViewGlobalStateController.showView(mOverlayViewController1, mRunnable);
verify(mSystemUIOverlayWindowController, never()).setFitInsetsTypes(insetTypesToFit);
}
private void setupOverlayViewController1() {
setupOverlayViewController(mOverlayViewController1, R.id.overlay_view_controller_stub_1,
R.id.overlay_view_controller_1);
@@ -913,6 +973,8 @@ public class OverlayViewGlobalStateControllerTest extends SysuiTestCase {
}
when(overlayViewController.getLayout()).thenReturn(layout);
when(overlayViewController.isInflated()).thenReturn(true);
when(overlayViewController.getInsetSidesToFit()).thenReturn(
OverlayViewController.INVALID_INSET_SIDE);
}
private void setOverlayViewControllerAsShowing(OverlayViewController overlayViewController) {