diff options
7 files changed, 92 insertions, 4 deletions
diff --git a/core/java/android/view/WindowManagerPolicy.java b/core/java/android/view/WindowManagerPolicy.java index 7538f6561c1e..ba9e05c2d870 100644 --- a/core/java/android/view/WindowManagerPolicy.java +++ b/core/java/android/view/WindowManagerPolicy.java @@ -150,6 +150,11 @@ public interface WindowManagerPolicy { public final static int PRESENCE_INTERNAL = 1 << 0; public final static int PRESENCE_EXTERNAL = 1 << 1; + // Navigation bar position values + int NAV_BAR_LEFT = 1 << 0; + int NAV_BAR_RIGHT = 1 << 1; + int NAV_BAR_BOTTOM = 1 << 2; + public final static boolean WATCH_POINTER = false; /** @@ -1676,6 +1681,14 @@ public interface WindowManagerPolicy { public boolean isNavBarForcedShownLw(WindowState win); /** + * @return The side of the screen where navigation bar is positioned. + * @see #NAV_BAR_LEFT + * @see #NAV_BAR_RIGHT + * @see #NAV_BAR_BOTTOM + */ + int getNavBarPosition(); + + /** * Calculates the insets for the areas that could never be removed in Honeycomb, i.e. system * bar or button bar. See {@link #getNonDecorDisplayWidth}. * diff --git a/services/core/java/com/android/server/am/ActivityRecord.java b/services/core/java/com/android/server/am/ActivityRecord.java index e668c1f4ec4c..1a7bba05c898 100644 --- a/services/core/java/com/android/server/am/ActivityRecord.java +++ b/services/core/java/com/android/server/am/ActivityRecord.java @@ -74,6 +74,7 @@ import static android.os.Build.VERSION_CODES.HONEYCOMB; import static android.os.Build.VERSION_CODES.O; import static android.os.Process.SYSTEM_UID; import static android.os.Trace.TRACE_TAG_ACTIVITY_MANAGER; +import static android.view.WindowManagerPolicy.NAV_BAR_LEFT; import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_CONFIGURATION; import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_SAVED_STATE; @@ -154,6 +155,7 @@ import android.view.IAppTransitionAnimationSpecsFuture; import android.view.IApplicationToken; import android.view.WindowManager.LayoutParams; +import com.android.internal.annotations.VisibleForTesting; import com.android.internal.app.ResolverActivity; import com.android.internal.content.ReferrerIntent; import com.android.internal.util.XmlUtils; @@ -2360,6 +2362,17 @@ final class ActivityRecord extends ConfigurationContainer implements AppWindowCo // Compute configuration based on max supported width and height. outBounds.set(0, 0, maxActivityWidth, maxActivityHeight); + // Position the activity frame on the opposite side of the nav bar. + final int navBarPosition = service.mWindowManager.getNavBarPosition(); + final int left = navBarPosition == NAV_BAR_LEFT + ? configuration.appBounds.right - outBounds.width() : 0; + outBounds.offsetTo(left, 0 /* top */); + } + + /** Get bounds of the activity. */ + @VisibleForTesting + Rect getBounds() { + return new Rect(mBounds); } /** diff --git a/services/core/java/com/android/server/policy/PhoneWindowManager.java b/services/core/java/com/android/server/policy/PhoneWindowManager.java index 8425d235fe66..75fc25aaec77 100644 --- a/services/core/java/com/android/server/policy/PhoneWindowManager.java +++ b/services/core/java/com/android/server/policy/PhoneWindowManager.java @@ -358,10 +358,6 @@ public class PhoneWindowManager implements WindowManagerPolicy { private static final String SYSUI_SCREENSHOT_ERROR_RECEIVER = "com.android.systemui.screenshot.ScreenshotServiceErrorReceiver"; - private static final int NAV_BAR_BOTTOM = 0; - private static final int NAV_BAR_RIGHT = 1; - private static final int NAV_BAR_LEFT = 2; - /** * Keyguard stuff */ @@ -6943,6 +6939,12 @@ public class PhoneWindowManager implements WindowManagerPolicy { } @Override + public int getNavBarPosition() { + // TODO(multi-display): Support system decor on secondary displays. + return mNavigationBarPosition; + } + + @Override public boolean isDockSideAllowed(int dockSide) { // We do not allow all dock sides at which the navigation bar touches the docked stack. diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java index 1b4c34d21257..17e87a04e2c2 100644 --- a/services/core/java/com/android/server/wm/WindowManagerService.java +++ b/services/core/java/com/android/server/wm/WindowManagerService.java @@ -6292,6 +6292,22 @@ public class WindowManagerService extends IWindowManager.Stub } } + /** + * Used by ActivityManager to determine where to position an app with aspect ratio shorter then + * the screen is. + * @see WindowManagerPolicy#getNavBarPosition() + */ + public int getNavBarPosition() { + synchronized (mWindowMap) { + // Perform layout if it was scheduled before to make sure that we get correct nav bar + // position when doing rotations. + final DisplayContent defaultDisplayContent = getDefaultDisplayContentLocked(); + defaultDisplayContent.performLayout(false /* initial */, + false /* updateInputWindows */); + return mPolicy.getNavBarPosition(); + } + } + @Override public WindowManagerPolicy.InputConsumer createInputConsumer(Looper looper, String name, InputEventReceiver.Factory inputEventReceiverFactory) { diff --git a/services/tests/servicestests/src/com/android/server/am/ActivityRecordTests.java b/services/tests/servicestests/src/com/android/server/am/ActivityRecordTests.java index f75d49cae574..2252c85dddf2 100644 --- a/services/tests/servicestests/src/com/android/server/am/ActivityRecordTests.java +++ b/services/tests/servicestests/src/com/android/server/am/ActivityRecordTests.java @@ -16,10 +16,15 @@ package com.android.server.am; +import static android.view.WindowManagerPolicy.NAV_BAR_BOTTOM; +import static android.view.WindowManagerPolicy.NAV_BAR_LEFT; +import static android.view.WindowManagerPolicy.NAV_BAR_RIGHT; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNull; +import static org.mockito.Mockito.when; import android.content.ComponentName; +import android.graphics.Rect; import android.platform.test.annotations.Presubmit; import android.support.test.filters.MediumTest; import android.support.test.runner.AndroidJUnit4; @@ -94,4 +99,36 @@ public class ActivityRecordTests extends ActivityTestsBase { return -1; } + + @Test + public void testPositionLimitedAspectRatioNavBarBottom() throws Exception { + verifyPositionWithLimitedAspectRatio(NAV_BAR_BOTTOM, new Rect(0, 0, 1000, 2000), 1.5f, + new Rect(0, 0, 1000, 1500)); + } + + @Test + public void testPositionLimitedAspectRatioNavBarLeft() throws Exception { + verifyPositionWithLimitedAspectRatio(NAV_BAR_LEFT, new Rect(0, 0, 2000, 1000), 1.5f, + new Rect(500, 0, 2000, 1000)); + } + + @Test + public void testPositionLimitedAspectRatioNavBarRight() throws Exception { + verifyPositionWithLimitedAspectRatio(NAV_BAR_RIGHT, new Rect(0, 0, 2000, 1000), 1.5f, + new Rect(0, 0, 1500, 1000)); + } + + private void verifyPositionWithLimitedAspectRatio(int navBarPosition, Rect taskBounds, + float aspectRatio, Rect expectedActivityBounds) { + final ActivityManagerService service = createActivityManagerService(); + final TaskRecord task = createTask(service, testActivityComponent, TEST_STACK_ID); + final ActivityRecord record = createActivity(service, testActivityComponent, task); + + // Verify with nav bar on the right. + when(service.mWindowManager.getNavBarPosition()).thenReturn(navBarPosition); + task.getConfiguration().setAppBounds(taskBounds); + record.info.maxAspectRatio = aspectRatio; + record.ensureActivityConfigurationLocked(0 /* globalChanges */, false /* preserveWindow */); + assertEquals(expectedActivityBounds, record.getBounds()); + } } diff --git a/services/tests/servicestests/src/com/android/server/am/ActivityTestsBase.java b/services/tests/servicestests/src/com/android/server/am/ActivityTestsBase.java index bac121695ed9..16bc011f97b5 100644 --- a/services/tests/servicestests/src/com/android/server/am/ActivityTestsBase.java +++ b/services/tests/servicestests/src/com/android/server/am/ActivityTestsBase.java @@ -120,6 +120,7 @@ public class ActivityTestsBase { null /*_taskDescription*/, new ActivityManager.TaskThumbnailInfo()); final ActivityStack stack = service.mStackSupervisor.getStack(stackId, true /*createStaticStackIfNeeded*/, true /*onTop*/); + service.mStackSupervisor.setFocusStackUnchecked("test", stack); stack.addTask(task, true, "creating test task"); task.setStack(stack); task.setWindowContainerController(mock(TaskWindowContainerController.class)); 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 a4e56fc9f745..0a7a5f26d35e 100644 --- a/services/tests/servicestests/src/com/android/server/wm/TestWindowManagerPolicy.java +++ b/services/tests/servicestests/src/com/android/server/wm/TestWindowManagerPolicy.java @@ -17,6 +17,7 @@ package com.android.server.wm; import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_STARTING; +import static android.view.WindowManagerPolicy.NAV_BAR_BOTTOM; import static org.mockito.Matchers.anyInt; import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.mock; @@ -614,6 +615,11 @@ class TestWindowManagerPolicy implements WindowManagerPolicy { } @Override + public int getNavBarPosition() { + return NAV_BAR_BOTTOM; + } + + @Override public void getNonDecorInsetsLw(int displayRotation, int displayWidth, int displayHeight, Rect outInsets) { |