diff options
| author | 2018-01-11 08:26:16 +0000 | |
|---|---|---|
| committer | 2018-01-11 08:26:16 +0000 | |
| commit | 2162b71ccd8fac7686da6b7b086a47875426b1db (patch) | |
| tree | eb6858b9803961728a3d5018aff5aa879b19f645 | |
| parent | ad222c7f059f6daf1b6db570012ae0d0dd3a0303 (diff) | |
| parent | d0a66b21ae86a33c43e6f614cf2d4e6c4e9ea281 (diff) | |
Merge "Add a test for updateLightNavigationBarLw()"
6 files changed, 235 insertions, 11 deletions
diff --git a/services/core/java/com/android/server/policy/PhoneWindowManager.java b/services/core/java/com/android/server/policy/PhoneWindowManager.java index 0c3b9c425dba..d79fcb645ce7 100644 --- a/services/core/java/com/android/server/policy/PhoneWindowManager.java +++ b/services/core/java/com/android/server/policy/PhoneWindowManager.java @@ -469,6 +469,7 @@ public class PhoneWindowManager implements WindowManagerPolicy { WindowState mNavigationBar = null; boolean mHasNavigationBar = false; boolean mNavigationBarCanMove = false; // can the navigation bar ever move to the side? + @NavigationBarPosition int mNavigationBarPosition = NAV_BAR_BOTTOM; int[] mNavigationBarHeightForRotationDefault = new int[4]; int[] mNavigationBarWidthForRotationDefault = new int[4]; @@ -4685,6 +4686,7 @@ public class PhoneWindowManager implements WindowManagerPolicy { return mNavigationBarController.checkHiddenLw(); } + @NavigationBarPosition private int navigationBarPosition(int displayWidth, int displayHeight, int displayRotation) { if (mNavigationBarCanMove && displayWidth > displayHeight) { if (displayRotation == Surface.ROTATION_270) { @@ -7852,16 +7854,21 @@ public class PhoneWindowManager implements WindowManagerPolicy { return vis; } - private int updateLightNavigationBarLw(int vis, WindowState opaque, - WindowState opaqueOrDimming) { - final WindowState imeWin = mWindowManagerFuncs.getInputMethodWindowLw(); - - final WindowState navColorWin; - if (imeWin != null && imeWin.isVisibleLw() && mNavigationBarPosition == NAV_BAR_BOTTOM) { - navColorWin = imeWin; + @VisibleForTesting + @Nullable + static WindowState chooseNavigationColorWindowLw(WindowState opaque, + WindowState opaqueOrDimming, WindowState imeWindow, + @NavigationBarPosition int navBarPosition) { + if (imeWindow != null && imeWindow.isVisibleLw() && navBarPosition == NAV_BAR_BOTTOM) { + return imeWindow; } else { - navColorWin = opaqueOrDimming; + return opaqueOrDimming; } + } + + @VisibleForTesting + static int updateLightNavigationBarLw(int vis, WindowState opaque, WindowState opaqueOrDimming, + WindowState imeWindow, WindowState navColorWin) { if (navColorWin != null) { if (navColorWin == opaque) { @@ -7870,7 +7877,8 @@ public class PhoneWindowManager implements WindowManagerPolicy { vis &= ~View.SYSTEM_UI_FLAG_LIGHT_NAVIGATION_BAR; vis |= PolicyControl.getSystemUiVisibility(navColorWin, null) & View.SYSTEM_UI_FLAG_LIGHT_NAVIGATION_BAR; - } else if (navColorWin.isDimming() || navColorWin == imeWin) { + } else if ((navColorWin == opaqueOrDimming && navColorWin.isDimming()) + || navColorWin == imeWindow) { // Otherwise if it's dimming or it's the IME window, clear the light flag. vis &= ~View.SYSTEM_UI_FLAG_LIGHT_NAVIGATION_BAR; } @@ -8009,8 +8017,12 @@ public class PhoneWindowManager implements WindowManagerPolicy { vis = mNavigationBarController.updateVisibilityLw(transientNavBarAllowed, oldVis, vis); + final WindowState navColorWin = chooseNavigationColorWindowLw( + mTopFullscreenOpaqueWindowState, mTopFullscreenOpaqueOrDimmingWindowState, + mWindowManagerFuncs.getInputMethodWindowLw(), mNavigationBarPosition); vis = updateLightNavigationBarLw(vis, mTopFullscreenOpaqueWindowState, - mTopFullscreenOpaqueOrDimmingWindowState); + mTopFullscreenOpaqueOrDimmingWindowState, + mWindowManagerFuncs.getInputMethodWindowLw(), navColorWin); return vis; } diff --git a/services/core/java/com/android/server/policy/WindowManagerPolicy.java b/services/core/java/com/android/server/policy/WindowManagerPolicy.java index cfe4088781b4..40b656d0d607 100644 --- a/services/core/java/com/android/server/policy/WindowManagerPolicy.java +++ b/services/core/java/com/android/server/policy/WindowManagerPolicy.java @@ -61,6 +61,8 @@ import static android.view.WindowManager.LayoutParams.TYPE_VOLUME_OVERLAY; import static android.view.WindowManager.LayoutParams.TYPE_WALLPAPER; import static android.view.WindowManager.LayoutParams.isSystemAlertWindowType; +import static java.lang.annotation.RetentionPolicy.SOURCE; + import android.Manifest; import android.annotation.IntDef; import android.annotation.Nullable; @@ -141,6 +143,10 @@ public interface WindowManagerPolicy extends WindowManagerPolicyConstants { int NAV_BAR_RIGHT = 1 << 1; int NAV_BAR_BOTTOM = 1 << 2; + @Retention(SOURCE) + @IntDef({NAV_BAR_LEFT, NAV_BAR_RIGHT, NAV_BAR_BOTTOM}) + @interface NavigationBarPosition {} + /** * Pass this event to the user / app. To be returned from * {@link #interceptKeyBeforeQueueing}. @@ -1637,6 +1643,7 @@ public interface WindowManagerPolicy extends WindowManagerPolicyConstants { * @see #NAV_BAR_RIGHT * @see #NAV_BAR_BOTTOM */ + @NavigationBarPosition int getNavBarPosition(); /** diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java index c6eb12b1bd86..fcc9988e8dff 100644 --- a/services/core/java/com/android/server/wm/WindowManagerService.java +++ b/services/core/java/com/android/server/wm/WindowManagerService.java @@ -5894,6 +5894,7 @@ public class WindowManagerService extends IWindowManager.Stub * the screen is. * @see WindowManagerPolicy#getNavBarPosition() */ + @WindowManagerPolicy.NavigationBarPosition public int getNavBarPosition() { synchronized (mWindowMap) { // Perform layout if it was scheduled before to make sure that we get correct nav bar diff --git a/services/tests/servicestests/src/com/android/server/policy/FakeWindowState.java b/services/tests/servicestests/src/com/android/server/policy/FakeWindowState.java index d1e0132ee248..62f7cd076758 100644 --- a/services/tests/servicestests/src/com/android/server/policy/FakeWindowState.java +++ b/services/tests/servicestests/src/com/android/server/policy/FakeWindowState.java @@ -43,6 +43,7 @@ public class FakeWindowState implements WindowManagerPolicy.WindowState { public boolean inMultiWindowMode; public boolean visible = true; public int surfaceLayer = 1; + public boolean isDimming = false; public boolean policyVisible = true; @@ -221,7 +222,7 @@ public class FakeWindowState implements WindowManagerPolicy.WindowState { @Override public boolean isDimming() { - throw new UnsupportedOperationException("not implemented"); + return isDimming; } @Override diff --git a/services/tests/servicestests/src/com/android/server/policy/PhoneWindowManagerTest.java b/services/tests/servicestests/src/com/android/server/policy/PhoneWindowManagerTest.java new file mode 100644 index 000000000000..4ebf7e7dfb46 --- /dev/null +++ b/services/tests/servicestests/src/com/android/server/policy/PhoneWindowManagerTest.java @@ -0,0 +1,202 @@ +/* + * Copyright (C) 2018 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.server.policy; + +import static android.view.View.SYSTEM_UI_FLAG_LIGHT_NAVIGATION_BAR; +import static android.view.ViewGroup.LayoutParams.MATCH_PARENT; +import static android.view.ViewGroup.LayoutParams.WRAP_CONTENT; +import static android.view.WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM; +import static android.view.WindowManager.LayoutParams.FLAG_DIM_BEHIND; +import static android.view.WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS; +import static android.view.WindowManager.LayoutParams.FLAG_LAYOUT_INSET_DECOR; +import static android.view.WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN; +import static android.view.WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE; +import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION; +import static android.view.WindowManager.LayoutParams.TYPE_BASE_APPLICATION; +import static android.view.WindowManager.LayoutParams.TYPE_INPUT_METHOD; + +import static com.android.server.policy.WindowManagerPolicy.NAV_BAR_BOTTOM; +import static com.android.server.policy.WindowManagerPolicy.NAV_BAR_RIGHT; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNull; + +import android.graphics.PixelFormat; +import android.platform.test.annotations.Presubmit; +import android.support.test.filters.SmallTest; +import android.support.test.runner.AndroidJUnit4; +import android.view.WindowManager; + +import org.junit.Test; +import org.junit.runner.RunWith; + +@RunWith(AndroidJUnit4.class) +@SmallTest +@Presubmit +public class PhoneWindowManagerTest { + + private static FakeWindowState createOpaqueFullscreen(boolean hasLightNavBar) { + final FakeWindowState state = new FakeWindowState(); + state.attrs = new WindowManager.LayoutParams(MATCH_PARENT, MATCH_PARENT, + TYPE_BASE_APPLICATION, + FLAG_LAYOUT_IN_SCREEN | FLAG_LAYOUT_INSET_DECOR | FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS, + PixelFormat.OPAQUE); + state.attrs.subtreeSystemUiVisibility = + hasLightNavBar ? SYSTEM_UI_FLAG_LIGHT_NAVIGATION_BAR : 0; + return state; + } + + private static FakeWindowState createDimmingDialogWindow(boolean canBeImTarget) { + final FakeWindowState state = new FakeWindowState(); + state.attrs = new WindowManager.LayoutParams(WRAP_CONTENT, WRAP_CONTENT, + TYPE_APPLICATION, + FLAG_DIM_BEHIND | (canBeImTarget ? 0 : FLAG_ALT_FOCUSABLE_IM), + PixelFormat.TRANSLUCENT); + state.isDimming = true; + return state; + } + + private static FakeWindowState createInputMethodWindow(boolean visible, boolean drawNavBar, + boolean hasLightNavBar) { + final FakeWindowState state = new FakeWindowState(); + state.attrs = new WindowManager.LayoutParams(MATCH_PARENT, MATCH_PARENT, + TYPE_INPUT_METHOD, + FLAG_NOT_FOCUSABLE | FLAG_LAYOUT_IN_SCREEN + | (drawNavBar ? FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS : 0), + PixelFormat.TRANSPARENT); + state.attrs.subtreeSystemUiVisibility = + hasLightNavBar ? SYSTEM_UI_FLAG_LIGHT_NAVIGATION_BAR : 0; + state.visible = visible; + state.policyVisible = visible; + return state; + } + + + @Test + public void testChooseNavigationColorWindowLw() throws Exception { + final FakeWindowState opaque = createOpaqueFullscreen(false); + + final FakeWindowState dimmingImTarget = createDimmingDialogWindow(true); + final FakeWindowState dimmingNonImTarget = createDimmingDialogWindow(false); + + final FakeWindowState visibleIme = createInputMethodWindow(true, true, false); + final FakeWindowState invisibleIme = createInputMethodWindow(false, true, false); + final FakeWindowState imeNonDrawNavBar = createInputMethodWindow(true, false, false); + + // If everything is null, return null + assertNull(null, PhoneWindowManager.chooseNavigationColorWindowLw( + null, null, null, NAV_BAR_BOTTOM)); + + assertEquals(opaque, PhoneWindowManager.chooseNavigationColorWindowLw( + opaque, opaque, null, NAV_BAR_BOTTOM)); + assertEquals(dimmingImTarget, PhoneWindowManager.chooseNavigationColorWindowLw( + opaque, dimmingImTarget, null, NAV_BAR_BOTTOM)); + assertEquals(dimmingNonImTarget, PhoneWindowManager.chooseNavigationColorWindowLw( + opaque, dimmingNonImTarget, null, NAV_BAR_BOTTOM)); + + assertEquals(visibleIme, PhoneWindowManager.chooseNavigationColorWindowLw( + null, null, visibleIme, NAV_BAR_BOTTOM)); + assertEquals(visibleIme, PhoneWindowManager.chooseNavigationColorWindowLw( + null, dimmingImTarget, visibleIme, NAV_BAR_BOTTOM)); + // TODO(b/69002467): A dimming window that is shown above the IME window should win. + assertEquals(visibleIme, PhoneWindowManager.chooseNavigationColorWindowLw( + null, dimmingNonImTarget, visibleIme, NAV_BAR_BOTTOM)); + assertEquals(visibleIme, PhoneWindowManager.chooseNavigationColorWindowLw( + opaque, opaque, visibleIme, NAV_BAR_BOTTOM)); + assertEquals(visibleIme, PhoneWindowManager.chooseNavigationColorWindowLw( + opaque, dimmingImTarget, visibleIme, NAV_BAR_BOTTOM)); + // TODO(b/69002467): A dimming window that is shown above the IME window should win. + assertEquals(visibleIme, PhoneWindowManager.chooseNavigationColorWindowLw( + opaque, dimmingNonImTarget, visibleIme, NAV_BAR_BOTTOM)); + + assertEquals(opaque, PhoneWindowManager.chooseNavigationColorWindowLw( + opaque, opaque, invisibleIme, NAV_BAR_BOTTOM)); + assertEquals(opaque, PhoneWindowManager.chooseNavigationColorWindowLw( + opaque, opaque, invisibleIme, NAV_BAR_BOTTOM)); + assertEquals(opaque, PhoneWindowManager.chooseNavigationColorWindowLw( + opaque, opaque, visibleIme, NAV_BAR_RIGHT)); + + // Only IME windows that have FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS should be navigation color + // window, but it's not yet implemented. + // TODO(b/69002467): Support this. + assertEquals(imeNonDrawNavBar, PhoneWindowManager.chooseNavigationColorWindowLw( + opaque, opaque, imeNonDrawNavBar, NAV_BAR_BOTTOM)); + // TODO(b/69002467): Support this. + assertEquals(imeNonDrawNavBar, PhoneWindowManager.chooseNavigationColorWindowLw( + opaque, dimmingImTarget, imeNonDrawNavBar, NAV_BAR_BOTTOM)); + // TODO(b/69002467): Support this. + assertEquals(imeNonDrawNavBar, PhoneWindowManager.chooseNavigationColorWindowLw( + opaque, dimmingNonImTarget, imeNonDrawNavBar, NAV_BAR_BOTTOM)); + } + + @Test + public void testUpdateLightNavigationBarLw() throws Exception { + final FakeWindowState opaqueDarkNavBar = createOpaqueFullscreen(false); + final FakeWindowState opaqueLightNavBar = createOpaqueFullscreen(true); + + final FakeWindowState dimming = createDimmingDialogWindow(false); + + final FakeWindowState imeDrawDarkNavBar = createInputMethodWindow(true,true, false); + final FakeWindowState imeDrawLightNavBar = createInputMethodWindow(true,true, true); + + assertEquals(SYSTEM_UI_FLAG_LIGHT_NAVIGATION_BAR, + PhoneWindowManager.updateLightNavigationBarLw( + SYSTEM_UI_FLAG_LIGHT_NAVIGATION_BAR, null, null, + null, null)); + + // Opaque top fullscreen window overrides SYSTEM_UI_FLAG_LIGHT_NAVIGATION_BAR flag. + assertEquals(0, PhoneWindowManager.updateLightNavigationBarLw( + 0, opaqueDarkNavBar, opaqueDarkNavBar, null, opaqueDarkNavBar)); + assertEquals(0, PhoneWindowManager.updateLightNavigationBarLw( + SYSTEM_UI_FLAG_LIGHT_NAVIGATION_BAR, opaqueDarkNavBar, opaqueDarkNavBar, null, + opaqueDarkNavBar)); + assertEquals(SYSTEM_UI_FLAG_LIGHT_NAVIGATION_BAR, + PhoneWindowManager.updateLightNavigationBarLw(0, opaqueLightNavBar, + opaqueLightNavBar, null, opaqueLightNavBar)); + assertEquals(SYSTEM_UI_FLAG_LIGHT_NAVIGATION_BAR, + PhoneWindowManager.updateLightNavigationBarLw(SYSTEM_UI_FLAG_LIGHT_NAVIGATION_BAR, + opaqueLightNavBar, opaqueLightNavBar, null, opaqueLightNavBar)); + + // Dimming window clears SYSTEM_UI_FLAG_LIGHT_NAVIGATION_BAR. + assertEquals(0, PhoneWindowManager.updateLightNavigationBarLw( + 0, opaqueDarkNavBar, dimming, null, dimming)); + assertEquals(0, PhoneWindowManager.updateLightNavigationBarLw( + 0, opaqueLightNavBar, dimming, null, dimming)); + assertEquals(0, PhoneWindowManager.updateLightNavigationBarLw( + SYSTEM_UI_FLAG_LIGHT_NAVIGATION_BAR, opaqueDarkNavBar, dimming, null, dimming)); + assertEquals(0, PhoneWindowManager.updateLightNavigationBarLw( + SYSTEM_UI_FLAG_LIGHT_NAVIGATION_BAR, opaqueLightNavBar, dimming, null, dimming)); + assertEquals(0, PhoneWindowManager.updateLightNavigationBarLw( + SYSTEM_UI_FLAG_LIGHT_NAVIGATION_BAR, opaqueLightNavBar, dimming, imeDrawLightNavBar, + dimming)); + + // IME window clears SYSTEM_UI_FLAG_LIGHT_NAVIGATION_BAR + assertEquals(0, PhoneWindowManager.updateLightNavigationBarLw( + SYSTEM_UI_FLAG_LIGHT_NAVIGATION_BAR, null, null, imeDrawDarkNavBar, + imeDrawDarkNavBar)); + + // Even if the top fullscreen has SYSTEM_UI_FLAG_LIGHT_NAVIGATION_BAR, IME window wins. + assertEquals(0, PhoneWindowManager.updateLightNavigationBarLw( + SYSTEM_UI_FLAG_LIGHT_NAVIGATION_BAR, opaqueLightNavBar, opaqueLightNavBar, + imeDrawDarkNavBar, imeDrawDarkNavBar)); + + // Currently SYSTEM_UI_FLAG_LIGHT_NAVIGATION_BAR in IME windows is ignored. + // TODO(b/69002467): Support this. + assertEquals(0, PhoneWindowManager.updateLightNavigationBarLw( + 0, opaqueDarkNavBar, opaqueDarkNavBar, imeDrawLightNavBar, imeDrawLightNavBar)); + } +} diff --git a/services/tests/servicestests/src/com/android/server/wm/TestWindowManagerPolicy.java b/services/tests/servicestests/src/com/android/server/wm/TestWindowManagerPolicy.java index c73534196f45..a3177062b448 100644 --- a/services/tests/servicestests/src/com/android/server/wm/TestWindowManagerPolicy.java +++ b/services/tests/servicestests/src/com/android/server/wm/TestWindowManagerPolicy.java @@ -588,6 +588,7 @@ class TestWindowManagerPolicy implements WindowManagerPolicy { return false; } + @NavigationBarPosition @Override public int getNavBarPosition() { return NAV_BAR_BOTTOM; |