Loading services/core/java/com/android/server/wm/AppCompatReachabilityOverrides.java +0 −3 Original line number Diff line number Diff line Loading @@ -35,7 +35,6 @@ import android.annotation.NonNull; import android.content.res.Configuration; import android.graphics.Rect; import com.android.internal.annotations.VisibleForTesting; import com.android.window.flags.Flags; /** Loading Loading @@ -112,12 +111,10 @@ class AppCompatReachabilityOverrides { : mAppCompatConfiguration.getLetterboxVerticalPositionMultiplier(tabletopMode); } @VisibleForTesting boolean isHorizontalReachabilityEnabled() { return isHorizontalReachabilityEnabled(mActivityRecord.getParent().getConfiguration()); } @VisibleForTesting boolean isVerticalReachabilityEnabled() { return isVerticalReachabilityEnabled(mActivityRecord.getParent().getConfiguration()); } Loading services/core/java/com/android/server/wm/AppCompatReachabilityPolicy.java +4 −1 Original line number Diff line number Diff line Loading @@ -31,6 +31,8 @@ import android.annotation.NonNull; import android.annotation.Nullable; import android.graphics.Rect; import com.android.internal.annotations.VisibleForTesting; import java.util.function.Supplier; /** Loading @@ -43,7 +45,8 @@ class AppCompatReachabilityPolicy { @NonNull private final AppCompatConfiguration mAppCompatConfiguration; @Nullable private Supplier<Rect> mLetterboxInnerBoundsSupplier; @VisibleForTesting Supplier<Rect> mLetterboxInnerBoundsSupplier; AppCompatReachabilityPolicy(@NonNull ActivityRecord activityRecord, @NonNull AppCompatConfiguration appCompatConfiguration) { Loading services/tests/wmtests/src/com/android/server/wm/AppCompatActivityRobot.java +59 −8 Original line number Diff line number Diff line Loading @@ -36,9 +36,12 @@ import android.content.ComponentName; import android.content.pm.ActivityInfo; import android.content.pm.PackageManager; import android.content.res.Configuration; import android.graphics.Rect; import android.view.Surface; import androidx.annotation.CallSuper; import androidx.annotation.NonNull; import androidx.annotation.Nullable; import com.android.server.wm.utils.TestComponentStack; Loading Loading @@ -74,6 +77,9 @@ class AppCompatActivityRobot { private final int mDisplayHeight; private DisplayContent mDisplayContent; @Nullable private Consumer<ActivityRecord> mOnPostActivityCreation; AppCompatActivityRobot(@NonNull WindowManagerService wm, @NonNull ActivityTaskManagerService atm, @NonNull ActivityTaskSupervisor supervisor, int displayWidth, int displayHeight) { Loading @@ -96,6 +102,10 @@ class AppCompatActivityRobot { /* inNewDisplay */ false); } void createActivityWithComponentWithoutTask() { createActivityWithComponentInNewTask(/* inNewTask */ false, /* inNewDisplay */ false); } void createActivityWithComponentInNewTask() { createActivityWithComponentInNewTask(/* inNewTask */ true, /* inNewDisplay */ false); } Loading Loading @@ -130,6 +140,14 @@ class AppCompatActivityRobot { doReturn(naturalOrientation).when(mDisplayContent).getNaturalOrientation(); } void configureTaskBounds(@NonNull Rect taskBounds) { doReturn(taskBounds).when(mTaskStack.top()).getBounds(); } void configureTopActivityBounds(@NonNull Rect activityBounds) { doReturn(activityBounds).when(mActivityStack.top()).getBounds(); } @NonNull ActivityRecord top() { return mActivityStack.top(); Loading Loading @@ -169,6 +187,10 @@ class AppCompatActivityRobot { .isActivityEligibleForOrientationOverride(eq(mActivityStack.top())); } void setTopActivityInTransition(boolean inTransition) { doReturn(inTransition).when(mActivityStack.top()).isInTransition(); } void setShouldApplyUserMinAspectRatioOverride(boolean enabled) { doReturn(enabled).when(mActivityStack.top().mAppCompatController .getAppCompatAspectRatioOverrides()).shouldApplyUserMinAspectRatioOverride(); Loading Loading @@ -378,6 +400,32 @@ class AppCompatActivityRobot { pushActivity(newActivity); } /** * Specific Robots can override this method to add operation to run on a newly created * {@link ActivityRecord}. Common case is to invoke spyOn(). * * @param activity The newly created {@link ActivityRecord}. */ @CallSuper void onPostActivityCreation(@NonNull ActivityRecord activity) { spyOn(activity); spyOn(activity.mLetterboxUiController); if (mOnPostActivityCreation != null) { mOnPostActivityCreation.accept(activity); } } /** * Each Robot can specify its own set of operation to execute on a newly created * {@link ActivityRecord}. Most common the use of spyOn(). * * @param onPostActivityCreation The reference to the code to execute after the creation of a * new {@link ActivityRecord}. */ void setOnPostActivityCreation(@Nullable Consumer<ActivityRecord> onPostActivityCreation) { mOnPostActivityCreation = onPostActivityCreation; } private void createActivityWithComponentInNewTask(boolean inNewTask, boolean inNewDisplay) { if (inNewDisplay) { createNewDisplay(); Loading @@ -385,14 +433,16 @@ class AppCompatActivityRobot { if (inNewTask) { createNewTask(); } final ActivityRecord activity = new WindowTestsBase.ActivityBuilder(mAtm) .setOnTop(true) .setTask(mTaskStack.top()) final WindowTestsBase.ActivityBuilder activityBuilder = new WindowTestsBase.ActivityBuilder(mAtm).setOnTop(true) // Set the component to be that of the test class in order // to enable compat changes .setComponent(ComponentName.createRelative(mAtm.mContext, TEST_COMPONENT_NAME)) .build(); pushActivity(activity); .setComponent(ComponentName.createRelative(mAtm.mContext, TEST_COMPONENT_NAME)); if (!mTaskStack.isEmpty()) { // We put the Activity in the current task if any. activityBuilder.setTask(mTaskStack.top()); } pushActivity(activityBuilder.build()); } /** Loading Loading @@ -438,14 +488,15 @@ class AppCompatActivityRobot { // We add the activity to the stack and spyOn() on its properties. private void pushActivity(@NonNull ActivityRecord activity) { mActivityStack.push(activity); spyOn(activity); onPostActivityCreation(activity); // TODO (b/351763164): Use these spyOn calls only when necessary. spyOn(activity.mAppCompatController.getTransparentPolicy()); spyOn(activity.mAppCompatController.getAppCompatAspectRatioOverrides()); spyOn(activity.mAppCompatController.getAppCompatAspectRatioPolicy()); spyOn(activity.mAppCompatController.getAppCompatFocusOverrides()); spyOn(activity.mAppCompatController.getAppCompatResizeOverrides()); spyOn(activity.mLetterboxUiController); spyOn(activity.mAppCompatController.getAppCompatReachabilityPolicy()); spyOn(activity.mAppCompatController.getAppCompatReachabilityOverrides()); } private void pushTask(@NonNull Task task) { Loading services/tests/wmtests/src/com/android/server/wm/AppCompatConfigurationRobot.java +33 −0 Original line number Diff line number Diff line Loading @@ -19,6 +19,9 @@ package com.android.server.wm; import static com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn; import static com.android.dx.mockito.inline.extended.ExtendedMockito.spyOn; import static org.mockito.ArgumentMatchers.anyBoolean; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; import androidx.annotation.NonNull; Loading Loading @@ -80,4 +83,34 @@ class AppCompatConfigurationRobot { doReturn(aspectRatio).when(mAppCompatConfiguration) .getFixedOrientationLetterboxAspectRatio(); } void setThinLetterboxWidthPx(int thinWidthPx) { doReturn(thinWidthPx).when(mAppCompatConfiguration) .getThinLetterboxWidthPx(); } void setThinLetterboxHeightPx(int thinHeightPx) { doReturn(thinHeightPx).when(mAppCompatConfiguration) .getThinLetterboxHeightPx(); } void checkToNextLeftStop(boolean invoked) { verify(mAppCompatConfiguration, times(invoked ? 1 : 0)) .movePositionForHorizontalReachabilityToNextLeftStop(anyBoolean()); } void checkToNextRightStop(boolean invoked) { verify(mAppCompatConfiguration, times(invoked ? 1 : 0)) .movePositionForHorizontalReachabilityToNextRightStop(anyBoolean()); } void checkToNextBottomStop(boolean invoked) { verify(mAppCompatConfiguration, times(invoked ? 1 : 0)) .movePositionForVerticalReachabilityToNextBottomStop(anyBoolean()); } void checkToNextTopStop(boolean invoked) { verify(mAppCompatConfiguration, times(invoked ? 1 : 0)) .movePositionForVerticalReachabilityToNextTopStop(anyBoolean()); } } services/tests/wmtests/src/com/android/server/wm/AppCompatReachabilityOverridesTest.java 0 → 100644 +227 −0 Original line number Diff line number Diff line /* * Copyright (C) 2024 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.wm; import static com.android.dx.mockito.inline.extended.ExtendedMockito.spyOn; import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.spy; import android.compat.testing.PlatformCompatChangeRule; import android.graphics.Rect; import android.platform.test.annotations.DisableFlags; import android.platform.test.annotations.EnableFlags; import android.platform.test.annotations.Presubmit; import androidx.annotation.NonNull; import com.android.window.flags.Flags; import junit.framework.Assert; import org.junit.Rule; import org.junit.Test; import org.junit.rules.TestRule; import org.junit.runner.RunWith; import java.util.function.Consumer; import java.util.function.Supplier; /** * Test class for {@link AppCompatReachabilityOverrides}. * <p> * Build/Install/Run: * atest WmTests:AppCompatReachabilityOverridesTest */ @Presubmit @RunWith(WindowTestRunner.class) public class AppCompatReachabilityOverridesTest extends WindowTestsBase { @Rule public TestRule compatChangeRule = new PlatformCompatChangeRule(); @Test public void testIsThinLetterboxed_NegativePx_returnsFalse() { runTestScenario((robot) -> { robot.activity().createActivityWithComponentWithoutTask(); robot.conf().setThinLetterboxHeightPx(/* thinHeightPx */ -1); robot.checkIsVerticalThinLetterboxed(/* expected */ false); robot.conf().setThinLetterboxWidthPx(/* thinHeightPx */ -1); robot.checkIsHorizontalThinLetterboxed(/* expected */ false); }); } @Test public void testIsThinLetterboxed_noTask_returnsFalse() { runTestScenario((robot) -> { robot.activity().createActivityWithComponentWithoutTask(); robot.conf().setThinLetterboxHeightPx(/* thinHeightPx */ 10); robot.checkIsVerticalThinLetterboxed(/* expected */ false); robot.conf().setThinLetterboxWidthPx(/* thinHeightPx */ 10); robot.checkIsHorizontalThinLetterboxed(/* expected */ false); }); } @Test public void testIsVerticalThinLetterboxed() { runTestScenario((robot) -> { robot.conf().setThinLetterboxHeightPx(/* thinHeightPx */ 10); robot.applyOnActivity((a) -> { a.createActivityWithComponent(); a.configureTaskBounds(new Rect(0, 0, 100, 100)); // (task.width() - act.width()) / 2 = 5 < 10 a.configureTopActivityBounds(new Rect(5, 5, 95, 95)); robot.checkIsVerticalThinLetterboxed(/* expected */ true); // (task.width() - act.width()) / 2 = 10 = 10 a.configureTopActivityBounds(new Rect(10, 10, 90, 90)); robot.checkIsVerticalThinLetterboxed(/* expected */ true); // (task.width() - act.width()) / 2 = 11 > 10 a.configureTopActivityBounds(new Rect(11, 11, 89, 89)); robot.checkIsVerticalThinLetterboxed(/* expected */ false); }); }); } @Test public void testIsHorizontalThinLetterboxed() { runTestScenario((robot) -> { robot.conf().setThinLetterboxWidthPx(/* thinHeightPx */ 10); robot.applyOnActivity((a) -> { a.createActivityWithComponent(); a.configureTaskBounds(new Rect(0, 0, 100, 100)); // (task.height() - act.height()) / 2 = 5 < 10 a.configureTopActivityBounds(new Rect(5, 5, 95, 95)); robot.checkIsHorizontalThinLetterboxed(/* expected */ true); // (task.height() - act.height()) / 2 = 10 = 10 a.configureTopActivityBounds(new Rect(10, 10, 90, 90)); robot.checkIsHorizontalThinLetterboxed(/* expected */ true); // (task.height() - act.height()) / 2 = 11 > 10 a.configureTopActivityBounds(new Rect(11, 11, 89, 89)); robot.checkIsHorizontalThinLetterboxed(/* expected */ false); }); }); } @Test @EnableFlags(Flags.FLAG_DISABLE_THIN_LETTERBOXING_POLICY) public void testAllowReachabilityForThinLetterboxWithFlagEnabled() { runTestScenario((robot) -> { robot.activity().createActivityWithComponent(); robot.configureIsVerticalThinLetterboxed(/* isThin */ true); robot.checkAllowVerticalReachabilityForThinLetterbox(/* expected */ false); robot.configureIsHorizontalThinLetterboxed(/* isThin */ true); robot.checkAllowHorizontalReachabilityForThinLetterbox(/* expected */ false); robot.configureIsVerticalThinLetterboxed(/* isThin */ false); robot.checkAllowVerticalReachabilityForThinLetterbox(/* expected */ true); robot.configureIsHorizontalThinLetterboxed(/* isThin */ false); robot.checkAllowHorizontalReachabilityForThinLetterbox(/* expected */ true); }); } @Test @DisableFlags(Flags.FLAG_DISABLE_THIN_LETTERBOXING_POLICY) public void testAllowReachabilityForThinLetterboxWithFlagDisabled() { runTestScenario((robot) -> { robot.activity().createActivityWithComponent(); robot.configureIsVerticalThinLetterboxed(/* isThin */ true); robot.checkAllowVerticalReachabilityForThinLetterbox(/* expected */ true); robot.configureIsHorizontalThinLetterboxed(/* isThin */ true); robot.checkAllowHorizontalReachabilityForThinLetterbox(/* expected */ true); robot.configureIsVerticalThinLetterboxed(/* isThin */ false); robot.checkAllowVerticalReachabilityForThinLetterbox(/* expected */ true); robot.configureIsHorizontalThinLetterboxed(/* isThin */ false); robot.checkAllowHorizontalReachabilityForThinLetterbox(/* expected */ true); }); } /** * Runs a test scenario providing a Robot. */ void runTestScenario(@NonNull Consumer<ReachabilityOverridesRobotTest> consumer) { spyOn(mWm.mAppCompatConfiguration); final ReachabilityOverridesRobotTest robot = new ReachabilityOverridesRobotTest(mWm, mAtm, mSupervisor); consumer.accept(robot); } private static class ReachabilityOverridesRobotTest extends AppCompatRobotBase { private final Supplier<Rect> mLetterboxInnerBoundsSupplier = spy(Rect::new); ReachabilityOverridesRobotTest(@NonNull WindowManagerService wm, @NonNull ActivityTaskManagerService atm, @NonNull ActivityTaskSupervisor supervisor) { super(wm, atm, supervisor); } @Override void onPostActivityCreation(@NonNull ActivityRecord activity) { super.onPostActivityCreation(activity); activity.mAppCompatController.getAppCompatReachabilityPolicy() .setLetterboxInnerBoundsSupplier(mLetterboxInnerBoundsSupplier); } void configureIsVerticalThinLetterboxed(boolean isThin) { doReturn(isThin).when(getAppCompatReachabilityOverrides()) .isVerticalThinLetterboxed(); } void configureIsHorizontalThinLetterboxed(boolean isThin) { doReturn(isThin).when(getAppCompatReachabilityOverrides()) .isHorizontalThinLetterboxed(); } void checkIsVerticalThinLetterboxed(boolean expected) { Assert.assertEquals(expected, getAppCompatReachabilityOverrides().isVerticalThinLetterboxed()); } void checkIsHorizontalThinLetterboxed(boolean expected) { Assert.assertEquals(expected, getAppCompatReachabilityOverrides().isHorizontalThinLetterboxed()); } void checkAllowVerticalReachabilityForThinLetterbox(boolean expected) { Assert.assertEquals(expected, getAppCompatReachabilityOverrides() .allowVerticalReachabilityForThinLetterbox()); } void checkAllowHorizontalReachabilityForThinLetterbox(boolean expected) { Assert.assertEquals(expected, getAppCompatReachabilityOverrides() .allowHorizontalReachabilityForThinLetterbox()); } @NonNull private AppCompatReachabilityOverrides getAppCompatReachabilityOverrides() { return activity().top().mAppCompatController.getAppCompatReachabilityOverrides(); } } } Loading
services/core/java/com/android/server/wm/AppCompatReachabilityOverrides.java +0 −3 Original line number Diff line number Diff line Loading @@ -35,7 +35,6 @@ import android.annotation.NonNull; import android.content.res.Configuration; import android.graphics.Rect; import com.android.internal.annotations.VisibleForTesting; import com.android.window.flags.Flags; /** Loading Loading @@ -112,12 +111,10 @@ class AppCompatReachabilityOverrides { : mAppCompatConfiguration.getLetterboxVerticalPositionMultiplier(tabletopMode); } @VisibleForTesting boolean isHorizontalReachabilityEnabled() { return isHorizontalReachabilityEnabled(mActivityRecord.getParent().getConfiguration()); } @VisibleForTesting boolean isVerticalReachabilityEnabled() { return isVerticalReachabilityEnabled(mActivityRecord.getParent().getConfiguration()); } Loading
services/core/java/com/android/server/wm/AppCompatReachabilityPolicy.java +4 −1 Original line number Diff line number Diff line Loading @@ -31,6 +31,8 @@ import android.annotation.NonNull; import android.annotation.Nullable; import android.graphics.Rect; import com.android.internal.annotations.VisibleForTesting; import java.util.function.Supplier; /** Loading @@ -43,7 +45,8 @@ class AppCompatReachabilityPolicy { @NonNull private final AppCompatConfiguration mAppCompatConfiguration; @Nullable private Supplier<Rect> mLetterboxInnerBoundsSupplier; @VisibleForTesting Supplier<Rect> mLetterboxInnerBoundsSupplier; AppCompatReachabilityPolicy(@NonNull ActivityRecord activityRecord, @NonNull AppCompatConfiguration appCompatConfiguration) { Loading
services/tests/wmtests/src/com/android/server/wm/AppCompatActivityRobot.java +59 −8 Original line number Diff line number Diff line Loading @@ -36,9 +36,12 @@ import android.content.ComponentName; import android.content.pm.ActivityInfo; import android.content.pm.PackageManager; import android.content.res.Configuration; import android.graphics.Rect; import android.view.Surface; import androidx.annotation.CallSuper; import androidx.annotation.NonNull; import androidx.annotation.Nullable; import com.android.server.wm.utils.TestComponentStack; Loading Loading @@ -74,6 +77,9 @@ class AppCompatActivityRobot { private final int mDisplayHeight; private DisplayContent mDisplayContent; @Nullable private Consumer<ActivityRecord> mOnPostActivityCreation; AppCompatActivityRobot(@NonNull WindowManagerService wm, @NonNull ActivityTaskManagerService atm, @NonNull ActivityTaskSupervisor supervisor, int displayWidth, int displayHeight) { Loading @@ -96,6 +102,10 @@ class AppCompatActivityRobot { /* inNewDisplay */ false); } void createActivityWithComponentWithoutTask() { createActivityWithComponentInNewTask(/* inNewTask */ false, /* inNewDisplay */ false); } void createActivityWithComponentInNewTask() { createActivityWithComponentInNewTask(/* inNewTask */ true, /* inNewDisplay */ false); } Loading Loading @@ -130,6 +140,14 @@ class AppCompatActivityRobot { doReturn(naturalOrientation).when(mDisplayContent).getNaturalOrientation(); } void configureTaskBounds(@NonNull Rect taskBounds) { doReturn(taskBounds).when(mTaskStack.top()).getBounds(); } void configureTopActivityBounds(@NonNull Rect activityBounds) { doReturn(activityBounds).when(mActivityStack.top()).getBounds(); } @NonNull ActivityRecord top() { return mActivityStack.top(); Loading Loading @@ -169,6 +187,10 @@ class AppCompatActivityRobot { .isActivityEligibleForOrientationOverride(eq(mActivityStack.top())); } void setTopActivityInTransition(boolean inTransition) { doReturn(inTransition).when(mActivityStack.top()).isInTransition(); } void setShouldApplyUserMinAspectRatioOverride(boolean enabled) { doReturn(enabled).when(mActivityStack.top().mAppCompatController .getAppCompatAspectRatioOverrides()).shouldApplyUserMinAspectRatioOverride(); Loading Loading @@ -378,6 +400,32 @@ class AppCompatActivityRobot { pushActivity(newActivity); } /** * Specific Robots can override this method to add operation to run on a newly created * {@link ActivityRecord}. Common case is to invoke spyOn(). * * @param activity The newly created {@link ActivityRecord}. */ @CallSuper void onPostActivityCreation(@NonNull ActivityRecord activity) { spyOn(activity); spyOn(activity.mLetterboxUiController); if (mOnPostActivityCreation != null) { mOnPostActivityCreation.accept(activity); } } /** * Each Robot can specify its own set of operation to execute on a newly created * {@link ActivityRecord}. Most common the use of spyOn(). * * @param onPostActivityCreation The reference to the code to execute after the creation of a * new {@link ActivityRecord}. */ void setOnPostActivityCreation(@Nullable Consumer<ActivityRecord> onPostActivityCreation) { mOnPostActivityCreation = onPostActivityCreation; } private void createActivityWithComponentInNewTask(boolean inNewTask, boolean inNewDisplay) { if (inNewDisplay) { createNewDisplay(); Loading @@ -385,14 +433,16 @@ class AppCompatActivityRobot { if (inNewTask) { createNewTask(); } final ActivityRecord activity = new WindowTestsBase.ActivityBuilder(mAtm) .setOnTop(true) .setTask(mTaskStack.top()) final WindowTestsBase.ActivityBuilder activityBuilder = new WindowTestsBase.ActivityBuilder(mAtm).setOnTop(true) // Set the component to be that of the test class in order // to enable compat changes .setComponent(ComponentName.createRelative(mAtm.mContext, TEST_COMPONENT_NAME)) .build(); pushActivity(activity); .setComponent(ComponentName.createRelative(mAtm.mContext, TEST_COMPONENT_NAME)); if (!mTaskStack.isEmpty()) { // We put the Activity in the current task if any. activityBuilder.setTask(mTaskStack.top()); } pushActivity(activityBuilder.build()); } /** Loading Loading @@ -438,14 +488,15 @@ class AppCompatActivityRobot { // We add the activity to the stack and spyOn() on its properties. private void pushActivity(@NonNull ActivityRecord activity) { mActivityStack.push(activity); spyOn(activity); onPostActivityCreation(activity); // TODO (b/351763164): Use these spyOn calls only when necessary. spyOn(activity.mAppCompatController.getTransparentPolicy()); spyOn(activity.mAppCompatController.getAppCompatAspectRatioOverrides()); spyOn(activity.mAppCompatController.getAppCompatAspectRatioPolicy()); spyOn(activity.mAppCompatController.getAppCompatFocusOverrides()); spyOn(activity.mAppCompatController.getAppCompatResizeOverrides()); spyOn(activity.mLetterboxUiController); spyOn(activity.mAppCompatController.getAppCompatReachabilityPolicy()); spyOn(activity.mAppCompatController.getAppCompatReachabilityOverrides()); } private void pushTask(@NonNull Task task) { Loading
services/tests/wmtests/src/com/android/server/wm/AppCompatConfigurationRobot.java +33 −0 Original line number Diff line number Diff line Loading @@ -19,6 +19,9 @@ package com.android.server.wm; import static com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn; import static com.android.dx.mockito.inline.extended.ExtendedMockito.spyOn; import static org.mockito.ArgumentMatchers.anyBoolean; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; import androidx.annotation.NonNull; Loading Loading @@ -80,4 +83,34 @@ class AppCompatConfigurationRobot { doReturn(aspectRatio).when(mAppCompatConfiguration) .getFixedOrientationLetterboxAspectRatio(); } void setThinLetterboxWidthPx(int thinWidthPx) { doReturn(thinWidthPx).when(mAppCompatConfiguration) .getThinLetterboxWidthPx(); } void setThinLetterboxHeightPx(int thinHeightPx) { doReturn(thinHeightPx).when(mAppCompatConfiguration) .getThinLetterboxHeightPx(); } void checkToNextLeftStop(boolean invoked) { verify(mAppCompatConfiguration, times(invoked ? 1 : 0)) .movePositionForHorizontalReachabilityToNextLeftStop(anyBoolean()); } void checkToNextRightStop(boolean invoked) { verify(mAppCompatConfiguration, times(invoked ? 1 : 0)) .movePositionForHorizontalReachabilityToNextRightStop(anyBoolean()); } void checkToNextBottomStop(boolean invoked) { verify(mAppCompatConfiguration, times(invoked ? 1 : 0)) .movePositionForVerticalReachabilityToNextBottomStop(anyBoolean()); } void checkToNextTopStop(boolean invoked) { verify(mAppCompatConfiguration, times(invoked ? 1 : 0)) .movePositionForVerticalReachabilityToNextTopStop(anyBoolean()); } }
services/tests/wmtests/src/com/android/server/wm/AppCompatReachabilityOverridesTest.java 0 → 100644 +227 −0 Original line number Diff line number Diff line /* * Copyright (C) 2024 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.wm; import static com.android.dx.mockito.inline.extended.ExtendedMockito.spyOn; import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.spy; import android.compat.testing.PlatformCompatChangeRule; import android.graphics.Rect; import android.platform.test.annotations.DisableFlags; import android.platform.test.annotations.EnableFlags; import android.platform.test.annotations.Presubmit; import androidx.annotation.NonNull; import com.android.window.flags.Flags; import junit.framework.Assert; import org.junit.Rule; import org.junit.Test; import org.junit.rules.TestRule; import org.junit.runner.RunWith; import java.util.function.Consumer; import java.util.function.Supplier; /** * Test class for {@link AppCompatReachabilityOverrides}. * <p> * Build/Install/Run: * atest WmTests:AppCompatReachabilityOverridesTest */ @Presubmit @RunWith(WindowTestRunner.class) public class AppCompatReachabilityOverridesTest extends WindowTestsBase { @Rule public TestRule compatChangeRule = new PlatformCompatChangeRule(); @Test public void testIsThinLetterboxed_NegativePx_returnsFalse() { runTestScenario((robot) -> { robot.activity().createActivityWithComponentWithoutTask(); robot.conf().setThinLetterboxHeightPx(/* thinHeightPx */ -1); robot.checkIsVerticalThinLetterboxed(/* expected */ false); robot.conf().setThinLetterboxWidthPx(/* thinHeightPx */ -1); robot.checkIsHorizontalThinLetterboxed(/* expected */ false); }); } @Test public void testIsThinLetterboxed_noTask_returnsFalse() { runTestScenario((robot) -> { robot.activity().createActivityWithComponentWithoutTask(); robot.conf().setThinLetterboxHeightPx(/* thinHeightPx */ 10); robot.checkIsVerticalThinLetterboxed(/* expected */ false); robot.conf().setThinLetterboxWidthPx(/* thinHeightPx */ 10); robot.checkIsHorizontalThinLetterboxed(/* expected */ false); }); } @Test public void testIsVerticalThinLetterboxed() { runTestScenario((robot) -> { robot.conf().setThinLetterboxHeightPx(/* thinHeightPx */ 10); robot.applyOnActivity((a) -> { a.createActivityWithComponent(); a.configureTaskBounds(new Rect(0, 0, 100, 100)); // (task.width() - act.width()) / 2 = 5 < 10 a.configureTopActivityBounds(new Rect(5, 5, 95, 95)); robot.checkIsVerticalThinLetterboxed(/* expected */ true); // (task.width() - act.width()) / 2 = 10 = 10 a.configureTopActivityBounds(new Rect(10, 10, 90, 90)); robot.checkIsVerticalThinLetterboxed(/* expected */ true); // (task.width() - act.width()) / 2 = 11 > 10 a.configureTopActivityBounds(new Rect(11, 11, 89, 89)); robot.checkIsVerticalThinLetterboxed(/* expected */ false); }); }); } @Test public void testIsHorizontalThinLetterboxed() { runTestScenario((robot) -> { robot.conf().setThinLetterboxWidthPx(/* thinHeightPx */ 10); robot.applyOnActivity((a) -> { a.createActivityWithComponent(); a.configureTaskBounds(new Rect(0, 0, 100, 100)); // (task.height() - act.height()) / 2 = 5 < 10 a.configureTopActivityBounds(new Rect(5, 5, 95, 95)); robot.checkIsHorizontalThinLetterboxed(/* expected */ true); // (task.height() - act.height()) / 2 = 10 = 10 a.configureTopActivityBounds(new Rect(10, 10, 90, 90)); robot.checkIsHorizontalThinLetterboxed(/* expected */ true); // (task.height() - act.height()) / 2 = 11 > 10 a.configureTopActivityBounds(new Rect(11, 11, 89, 89)); robot.checkIsHorizontalThinLetterboxed(/* expected */ false); }); }); } @Test @EnableFlags(Flags.FLAG_DISABLE_THIN_LETTERBOXING_POLICY) public void testAllowReachabilityForThinLetterboxWithFlagEnabled() { runTestScenario((robot) -> { robot.activity().createActivityWithComponent(); robot.configureIsVerticalThinLetterboxed(/* isThin */ true); robot.checkAllowVerticalReachabilityForThinLetterbox(/* expected */ false); robot.configureIsHorizontalThinLetterboxed(/* isThin */ true); robot.checkAllowHorizontalReachabilityForThinLetterbox(/* expected */ false); robot.configureIsVerticalThinLetterboxed(/* isThin */ false); robot.checkAllowVerticalReachabilityForThinLetterbox(/* expected */ true); robot.configureIsHorizontalThinLetterboxed(/* isThin */ false); robot.checkAllowHorizontalReachabilityForThinLetterbox(/* expected */ true); }); } @Test @DisableFlags(Flags.FLAG_DISABLE_THIN_LETTERBOXING_POLICY) public void testAllowReachabilityForThinLetterboxWithFlagDisabled() { runTestScenario((robot) -> { robot.activity().createActivityWithComponent(); robot.configureIsVerticalThinLetterboxed(/* isThin */ true); robot.checkAllowVerticalReachabilityForThinLetterbox(/* expected */ true); robot.configureIsHorizontalThinLetterboxed(/* isThin */ true); robot.checkAllowHorizontalReachabilityForThinLetterbox(/* expected */ true); robot.configureIsVerticalThinLetterboxed(/* isThin */ false); robot.checkAllowVerticalReachabilityForThinLetterbox(/* expected */ true); robot.configureIsHorizontalThinLetterboxed(/* isThin */ false); robot.checkAllowHorizontalReachabilityForThinLetterbox(/* expected */ true); }); } /** * Runs a test scenario providing a Robot. */ void runTestScenario(@NonNull Consumer<ReachabilityOverridesRobotTest> consumer) { spyOn(mWm.mAppCompatConfiguration); final ReachabilityOverridesRobotTest robot = new ReachabilityOverridesRobotTest(mWm, mAtm, mSupervisor); consumer.accept(robot); } private static class ReachabilityOverridesRobotTest extends AppCompatRobotBase { private final Supplier<Rect> mLetterboxInnerBoundsSupplier = spy(Rect::new); ReachabilityOverridesRobotTest(@NonNull WindowManagerService wm, @NonNull ActivityTaskManagerService atm, @NonNull ActivityTaskSupervisor supervisor) { super(wm, atm, supervisor); } @Override void onPostActivityCreation(@NonNull ActivityRecord activity) { super.onPostActivityCreation(activity); activity.mAppCompatController.getAppCompatReachabilityPolicy() .setLetterboxInnerBoundsSupplier(mLetterboxInnerBoundsSupplier); } void configureIsVerticalThinLetterboxed(boolean isThin) { doReturn(isThin).when(getAppCompatReachabilityOverrides()) .isVerticalThinLetterboxed(); } void configureIsHorizontalThinLetterboxed(boolean isThin) { doReturn(isThin).when(getAppCompatReachabilityOverrides()) .isHorizontalThinLetterboxed(); } void checkIsVerticalThinLetterboxed(boolean expected) { Assert.assertEquals(expected, getAppCompatReachabilityOverrides().isVerticalThinLetterboxed()); } void checkIsHorizontalThinLetterboxed(boolean expected) { Assert.assertEquals(expected, getAppCompatReachabilityOverrides().isHorizontalThinLetterboxed()); } void checkAllowVerticalReachabilityForThinLetterbox(boolean expected) { Assert.assertEquals(expected, getAppCompatReachabilityOverrides() .allowVerticalReachabilityForThinLetterbox()); } void checkAllowHorizontalReachabilityForThinLetterbox(boolean expected) { Assert.assertEquals(expected, getAppCompatReachabilityOverrides() .allowHorizontalReachabilityForThinLetterbox()); } @NonNull private AppCompatReachabilityOverrides getAppCompatReachabilityOverrides() { return activity().top().mAppCompatController.getAppCompatReachabilityOverrides(); } } }