[26/n] Adding tests to AppCompatReachability* classes
Flag: EXEMPT refactor
Bug: 336807329
Test: atest WmTests:AppCompatReachabilityPolicyTest
Test: atest WmTests:AppCompatReachabilityOverridesTest
Change-Id: I88a589f36631ea9244580ec6f9488ba21d5a5473
diff --git a/services/core/java/com/android/server/wm/AppCompatReachabilityOverrides.java b/services/core/java/com/android/server/wm/AppCompatReachabilityOverrides.java
index b9bdc32..caff96b 100644
--- a/services/core/java/com/android/server/wm/AppCompatReachabilityOverrides.java
+++ b/services/core/java/com/android/server/wm/AppCompatReachabilityOverrides.java
@@ -35,7 +35,6 @@
import android.content.res.Configuration;
import android.graphics.Rect;
-import com.android.internal.annotations.VisibleForTesting;
import com.android.window.flags.Flags;
/**
@@ -112,12 +111,10 @@
: mAppCompatConfiguration.getLetterboxVerticalPositionMultiplier(tabletopMode);
}
- @VisibleForTesting
boolean isHorizontalReachabilityEnabled() {
return isHorizontalReachabilityEnabled(mActivityRecord.getParent().getConfiguration());
}
- @VisibleForTesting
boolean isVerticalReachabilityEnabled() {
return isVerticalReachabilityEnabled(mActivityRecord.getParent().getConfiguration());
}
diff --git a/services/core/java/com/android/server/wm/AppCompatReachabilityPolicy.java b/services/core/java/com/android/server/wm/AppCompatReachabilityPolicy.java
index 90bfddb..c3bf116 100644
--- a/services/core/java/com/android/server/wm/AppCompatReachabilityPolicy.java
+++ b/services/core/java/com/android/server/wm/AppCompatReachabilityPolicy.java
@@ -31,6 +31,8 @@
import android.annotation.Nullable;
import android.graphics.Rect;
+import com.android.internal.annotations.VisibleForTesting;
+
import java.util.function.Supplier;
/**
@@ -43,7 +45,8 @@
@NonNull
private final AppCompatConfiguration mAppCompatConfiguration;
@Nullable
- private Supplier<Rect> mLetterboxInnerBoundsSupplier;
+ @VisibleForTesting
+ Supplier<Rect> mLetterboxInnerBoundsSupplier;
AppCompatReachabilityPolicy(@NonNull ActivityRecord activityRecord,
@NonNull AppCompatConfiguration appCompatConfiguration) {
diff --git a/services/tests/wmtests/src/com/android/server/wm/AppCompatActivityRobot.java b/services/tests/wmtests/src/com/android/server/wm/AppCompatActivityRobot.java
index f8cf97e..d582b07 100644
--- a/services/tests/wmtests/src/com/android/server/wm/AppCompatActivityRobot.java
+++ b/services/tests/wmtests/src/com/android/server/wm/AppCompatActivityRobot.java
@@ -36,9 +36,12 @@
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;
@@ -74,6 +77,9 @@
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) {
@@ -96,6 +102,10 @@
/* inNewDisplay */ false);
}
+ void createActivityWithComponentWithoutTask() {
+ createActivityWithComponentInNewTask(/* inNewTask */ false, /* inNewDisplay */ false);
+ }
+
void createActivityWithComponentInNewTask() {
createActivityWithComponentInNewTask(/* inNewTask */ true, /* inNewDisplay */ false);
}
@@ -130,6 +140,14 @@
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();
@@ -169,6 +187,10 @@
.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();
@@ -378,6 +400,32 @@
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();
@@ -385,14 +433,16 @@
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());
}
/**
@@ -438,14 +488,15 @@
// 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) {
diff --git a/services/tests/wmtests/src/com/android/server/wm/AppCompatConfigurationRobot.java b/services/tests/wmtests/src/com/android/server/wm/AppCompatConfigurationRobot.java
index 6592f26..40a5347 100644
--- a/services/tests/wmtests/src/com/android/server/wm/AppCompatConfigurationRobot.java
+++ b/services/tests/wmtests/src/com/android/server/wm/AppCompatConfigurationRobot.java
@@ -19,6 +19,9 @@
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;
@@ -80,4 +83,34 @@
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());
+ }
}
diff --git a/services/tests/wmtests/src/com/android/server/wm/AppCompatReachabilityOverridesTest.java b/services/tests/wmtests/src/com/android/server/wm/AppCompatReachabilityOverridesTest.java
new file mode 100644
index 0000000..47f584a
--- /dev/null
+++ b/services/tests/wmtests/src/com/android/server/wm/AppCompatReachabilityOverridesTest.java
@@ -0,0 +1,227 @@
+/*
+ * 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();
+ }
+
+ }
+
+}
diff --git a/services/tests/wmtests/src/com/android/server/wm/AppCompatReachabilityPolicyTest.java b/services/tests/wmtests/src/com/android/server/wm/AppCompatReachabilityPolicyTest.java
new file mode 100644
index 0000000..84f89b5
--- /dev/null
+++ b/services/tests/wmtests/src/com/android/server/wm/AppCompatReachabilityPolicyTest.java
@@ -0,0 +1,294 @@
+/*
+ * 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 static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+
+import android.graphics.Rect;
+import android.platform.test.annotations.Presubmit;
+
+import androidx.annotation.NonNull;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.util.function.Consumer;
+import java.util.function.Supplier;
+
+/**
+ * Test class for {@link AppCompatReachabilityPolicy}.
+ * <p/>
+ * Build/Install/Run:
+ * atest WmTests:AppCompatReachabilityPolicyTest
+ */
+@Presubmit
+@RunWith(WindowTestRunner.class)
+public class AppCompatReachabilityPolicyTest extends WindowTestsBase {
+
+ @Test
+ public void handleHorizontalDoubleTap_reachabilityDisabled_nothingHappen() {
+ runTestScenario((robot) -> {
+ robot.activity().createActivityWithComponent();
+ robot.enableHorizontalReachability(/* enabled */ false);
+ robot.activity().setTopActivityInTransition(/* inTransition */ true);
+ robot.doubleTapAt(100, 100);
+
+ robot.checkLetterboxInnerFrameProvidedInvoked(/* invoked */ false);
+ });
+ }
+
+ @Test
+ public void handleHorizontalDoubleTap_reachabilityEnabledInTransition_nothingHappen() {
+ runTestScenario((robot) -> {
+ robot.activity().createActivityWithComponent();
+ robot.enableHorizontalReachability(/* enabled */ true);
+ robot.activity().setTopActivityInTransition(/* inTransition */ true);
+ robot.doubleTapAt(100, 100);
+
+ robot.checkLetterboxInnerFrameProvidedInvoked(/* invoked */ false);
+ });
+ }
+
+ @Test
+ public void handleHorizontalDoubleTap_reachabilityDisabledNotInTransition_nothingHappen() {
+ runTestScenario((robot) -> {
+ robot.activity().createActivityWithComponent();
+ robot.enableHorizontalReachability(/* enabled */ false);
+ robot.activity().setTopActivityInTransition(/* inTransition */ false);
+ robot.doubleTapAt(100, 100);
+
+ robot.checkLetterboxInnerFrameProvidedInvoked(/* invoked */ false);
+ });
+ }
+
+ @Test
+ public void handleHorizontalDoubleTap_leftInnerFrame_moveToLeft() {
+ runTestScenario((robot) -> {
+ robot.activity().createActivityWithComponent();
+ robot.enableHorizontalReachability(/* enabled */ true);
+ robot.activity().setTopActivityInTransition(/* inTransition */ false);
+
+ robot.configureLetterboxInnerFrameWidth(/* left */ 100, /* right */ 200);
+ robot.doubleTapAt(99, 100);
+
+ robot.checkLetterboxInnerFrameProvidedInvoked(/* invoked */ true);
+ robot.applyOnConf((c) -> {
+ c.checkToNextLeftStop(/* invoked */ true);
+ c.checkToNextRightStop(/* invoked */ false);
+ });
+ });
+ }
+
+ @Test
+ public void handleHorizontalDoubleTap_rightInnerFrame_moveToRight() {
+ runTestScenario((robot) -> {
+ robot.activity().createActivityWithComponent();
+ robot.enableHorizontalReachability(/* enabled */ true);
+ robot.activity().setTopActivityInTransition(/* inTransition */ false);
+
+ robot.configureLetterboxInnerFrameWidth(/* left */ 100, /* right */ 200);
+ robot.doubleTapAt(201, 100);
+
+ robot.checkLetterboxInnerFrameProvidedInvoked(/* invoked */ true);
+ robot.applyOnConf((c) -> {
+ c.checkToNextLeftStop(/* invoked */ false);
+ c.checkToNextRightStop(/* invoked */ true);
+ });
+ });
+ }
+
+ @Test
+ public void handleHorizontalDoubleTap_intoInnerFrame_noMove() {
+ runTestScenario((robot) -> {
+ robot.activity().createActivityWithComponent();
+ robot.enableHorizontalReachability(/* enabled */ true);
+ robot.activity().setTopActivityInTransition(/* inTransition */ false);
+
+ robot.configureLetterboxInnerFrameWidth(/* left */ 100, /* right */ 200);
+ robot.doubleTapAt(150, 100);
+
+ robot.checkLetterboxInnerFrameProvidedInvoked(/* invoked */ true);
+ robot.applyOnConf((c) -> {
+ c.checkToNextLeftStop(/* invoked */ false);
+ c.checkToNextRightStop(/* invoked */ false);
+ });
+ });
+ }
+
+
+ @Test
+ public void handleVerticalDoubleTap_reachabilityDisabled_nothingHappen() {
+ runTestScenario((robot) -> {
+ robot.activity().createActivityWithComponent();
+ robot.enableVerticalReachability(/* enabled */ false);
+ robot.activity().setTopActivityInTransition(/* inTransition */ true);
+ robot.doubleTapAt(100, 100);
+
+ robot.checkLetterboxInnerFrameProvidedInvoked(/* invoked */ false);
+ });
+ }
+
+ @Test
+ public void handleVerticalDoubleTap_reachabilityEnabledInTransition_nothingHappen() {
+ runTestScenario((robot) -> {
+ robot.activity().createActivityWithComponent();
+ robot.enableVerticalReachability(/* enabled */ true);
+ robot.activity().setTopActivityInTransition(/* inTransition */ true);
+
+ robot.checkLetterboxInnerFrameProvidedInvoked(/* invoked */ false);
+ });
+ }
+
+ @Test
+ public void handleVerticalDoubleTap_reachabilityDisabledNotInTransition_nothingHappen() {
+ runTestScenario((robot) -> {
+ robot.activity().createActivityWithComponent();
+ robot.enableVerticalReachability(/* enabled */ false);
+ robot.activity().setTopActivityInTransition(/* inTransition */ false);
+
+ robot.checkLetterboxInnerFrameProvidedInvoked(/* invoked */ false);
+ });
+ }
+
+ @Test
+ public void handleVerticalDoubleTap_topInnerFrame_moveToTop() {
+ runTestScenario((robot) -> {
+ robot.activity().createActivityWithComponent();
+ robot.enableVerticalReachability(/* enabled */ true);
+ robot.activity().setTopActivityInTransition(/* inTransition */ false);
+
+ robot.configureLetterboxInnerFrameHeight(/* top */ 100, /* bottom */ 200);
+ robot.doubleTapAt(100, 99);
+
+ robot.checkLetterboxInnerFrameProvidedInvoked(/* invoked */ true);
+ robot.applyOnConf((c) -> {
+ c.checkToNextTopStop(/* invoked */ true);
+ c.checkToNextBottomStop(/* invoked */ false);
+ });
+ });
+ }
+
+ @Test
+ public void handleVerticalDoubleTap_bottomInnerFrame_moveToBottom() {
+ runTestScenario((robot) -> {
+ robot.activity().createActivityWithComponent();
+ robot.enableVerticalReachability(/* enabled */ true);
+ robot.activity().setTopActivityInTransition(/* inTransition */ false);
+
+ robot.configureLetterboxInnerFrameHeight(/* top */ 100, /* bottom */ 200);
+ robot.doubleTapAt(100, 201);
+
+ robot.checkLetterboxInnerFrameProvidedInvoked(/* invoked */ true);
+ robot.applyOnConf((c) -> {
+ c.checkToNextTopStop(/* invoked */ false);
+ c.checkToNextBottomStop(/* invoked */ true);
+ });
+ });
+ }
+
+ @Test
+ public void handleVerticalDoubleTap_intoInnerFrame_noMove() {
+ runTestScenario((robot) -> {
+ robot.activity().createActivityWithComponent();
+ robot.enableVerticalReachability(/* enabled */ true);
+ robot.activity().setTopActivityInTransition(/* inTransition */ false);
+
+ robot.configureLetterboxInnerFrameHeight(/* top */ 100, /* bottom */ 200);
+ robot.doubleTapAt(100, 150);
+
+ robot.checkLetterboxInnerFrameProvidedInvoked(/* invoked */ true);
+ robot.applyOnConf((c) -> {
+ c.checkToNextTopStop(/* invoked */ false);
+ c.checkToNextBottomStop(/* invoked */ false);
+ });
+ });
+ }
+
+
+ /**
+ * Runs a test scenario providing a Robot.
+ */
+ void runTestScenario(@NonNull Consumer<ReachabilityPolicyRobotTest> consumer) {
+ spyOn(mWm.mAppCompatConfiguration);
+ final ReachabilityPolicyRobotTest robot =
+ new ReachabilityPolicyRobotTest(mWm, mAtm, mSupervisor);
+ consumer.accept(robot);
+ }
+
+ private static class ReachabilityPolicyRobotTest extends AppCompatRobotBase {
+
+ private final Supplier<Rect> mLetterboxInnerBoundsSupplier = spy(Rect::new);
+
+ ReachabilityPolicyRobotTest(@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 configureLetterboxInnerFrameWidth(int left, int right) {
+ doReturn(new Rect(left, /* top */ 0, right, /* bottom */ 100))
+ .when(mLetterboxInnerBoundsSupplier).get();
+ }
+
+ void configureLetterboxInnerFrameHeight(int top, int bottom) {
+ doReturn(new Rect(/* left */ 0, top, /* right */ 100, bottom))
+ .when(mLetterboxInnerBoundsSupplier).get();
+ }
+
+ void enableHorizontalReachability(boolean enabled) {
+ doReturn(enabled).when(getAppCompatReachabilityOverrides())
+ .isHorizontalReachabilityEnabled();
+ }
+
+ void enableVerticalReachability(boolean enabled) {
+ doReturn(enabled).when(getAppCompatReachabilityOverrides())
+ .isVerticalReachabilityEnabled();
+ }
+
+ void doubleTapAt(int x, int y) {
+ getAppCompatReachabilityPolicy().handleDoubleTap(x, y);
+ }
+
+ void checkLetterboxInnerFrameProvidedInvoked(boolean invoked) {
+ verify(mLetterboxInnerBoundsSupplier, times(invoked ? 1 : 0)).get();
+ }
+
+ @NonNull
+ private AppCompatReachabilityOverrides getAppCompatReachabilityOverrides() {
+ return activity().top().mAppCompatController.getAppCompatReachabilityOverrides();
+ }
+
+ @NonNull
+ private AppCompatReachabilityPolicy getAppCompatReachabilityPolicy() {
+ return activity().top().mAppCompatController.getAppCompatReachabilityPolicy();
+ }
+
+ }
+
+}
diff --git a/services/tests/wmtests/src/com/android/server/wm/AppCompatResizeOverridesTest.java b/services/tests/wmtests/src/com/android/server/wm/AppCompatResizeOverridesTest.java
index 8fc1a77..cade213 100644
--- a/services/tests/wmtests/src/com/android/server/wm/AppCompatResizeOverridesTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/AppCompatResizeOverridesTest.java
@@ -39,7 +39,7 @@
/**
* Test class for {@link AppCompatResizeOverrides}.
- * <p>
+ * <p/>
* Build/Install/Run:
* atest WmTests:AppCompatResizeOverridesTest
*/
diff --git a/services/tests/wmtests/src/com/android/server/wm/AppCompatRobotBase.java b/services/tests/wmtests/src/com/android/server/wm/AppCompatRobotBase.java
index 6939f97..57ff4f6 100644
--- a/services/tests/wmtests/src/com/android/server/wm/AppCompatRobotBase.java
+++ b/services/tests/wmtests/src/com/android/server/wm/AppCompatRobotBase.java
@@ -16,6 +16,7 @@
package com.android.server.wm;
+import androidx.annotation.CallSuper;
import androidx.annotation.NonNull;
import java.util.function.Consumer;
@@ -43,6 +44,7 @@
int displayWidth, int displayHeight) {
mActivityRobot = new AppCompatActivityRobot(wm, atm, supervisor,
displayWidth, displayHeight);
+ mActivityRobot.setOnPostActivityCreation(this::onPostActivityCreation);
mConfigurationRobot =
new AppCompatConfigurationRobot(wm.mAppCompatConfiguration);
mOptPropRobot = new AppCompatComponentPropRobot(wm);
@@ -54,6 +56,16 @@
this(wm, atm, supervisor, DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_HEIGHT);
}
+ /**
+ * 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) {
+ }
+
@NonNull
AppCompatConfigurationRobot conf() {
return mConfigurationRobot;
diff --git a/services/tests/wmtests/src/com/android/server/wm/LetterboxUiControllerTest.java b/services/tests/wmtests/src/com/android/server/wm/LetterboxUiControllerTest.java
index 33df5d8..695068a 100644
--- a/services/tests/wmtests/src/com/android/server/wm/LetterboxUiControllerTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/LetterboxUiControllerTest.java
@@ -23,11 +23,9 @@
import static com.android.dx.mockito.inline.extended.ExtendedMockito.spyOn;
import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
-import static org.junit.Assert.assertTrue;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
@@ -36,8 +34,6 @@
import android.content.ComponentName;
import android.content.res.Resources;
import android.graphics.Rect;
-import android.platform.test.annotations.DisableFlags;
-import android.platform.test.annotations.EnableFlags;
import android.platform.test.annotations.Presubmit;
import android.view.InsetsSource;
import android.view.InsetsState;
@@ -49,7 +45,6 @@
import androidx.test.filters.SmallTest;
import com.android.internal.R;
-import com.android.window.flags.Flags;
import org.junit.Before;
import org.junit.Rule;
@@ -296,106 +291,6 @@
}
@Test
- public void testIsVerticalThinLetterboxed() {
- // Vertical thin letterbox disabled
- doReturn(-1).when(mActivity.mWmService.mAppCompatConfiguration)
- .getThinLetterboxHeightPx();
- final AppCompatReachabilityOverrides reachabilityOverrides = mActivity.mAppCompatController
- .getAppCompatReachabilityOverrides();
- assertFalse(reachabilityOverrides.isVerticalThinLetterboxed());
- // Define a Task 100x100
- final Task task = mock(Task.class);
- doReturn(new Rect(0, 0, 100, 100)).when(task).getBounds();
- doReturn(10).when(mActivity.mWmService.mAppCompatConfiguration)
- .getThinLetterboxHeightPx();
-
- // Vertical thin letterbox disabled without Task
- doReturn(null).when(mActivity).getTask();
- assertFalse(reachabilityOverrides.isVerticalThinLetterboxed());
- // Assign a Task for the Activity
- doReturn(task).when(mActivity).getTask();
-
- // (task.width() - act.width()) / 2 = 5 < 10
- doReturn(new Rect(5, 5, 95, 95)).when(mActivity).getBounds();
- assertTrue(reachabilityOverrides.isVerticalThinLetterboxed());
-
- // (task.width() - act.width()) / 2 = 10 = 10
- doReturn(new Rect(10, 10, 90, 90)).when(mActivity).getBounds();
- assertTrue(reachabilityOverrides.isVerticalThinLetterboxed());
-
- // (task.width() - act.width()) / 2 = 11 > 10
- doReturn(new Rect(11, 11, 89, 89)).when(mActivity).getBounds();
- assertFalse(reachabilityOverrides.isVerticalThinLetterboxed());
- }
-
- @Test
- public void testIsHorizontalThinLetterboxed() {
- // Horizontal thin letterbox disabled
- doReturn(-1).when(mActivity.mWmService.mAppCompatConfiguration)
- .getThinLetterboxWidthPx();
- final AppCompatReachabilityOverrides reachabilityOverrides = mActivity.mAppCompatController
- .getAppCompatReachabilityOverrides();
- assertFalse(reachabilityOverrides.isHorizontalThinLetterboxed());
- // Define a Task 100x100
- final Task task = mock(Task.class);
- doReturn(new Rect(0, 0, 100, 100)).when(task).getBounds();
- doReturn(10).when(mActivity.mWmService.mAppCompatConfiguration)
- .getThinLetterboxWidthPx();
-
- // Vertical thin letterbox disabled without Task
- doReturn(null).when(mActivity).getTask();
- assertFalse(reachabilityOverrides.isHorizontalThinLetterboxed());
- // Assign a Task for the Activity
- doReturn(task).when(mActivity).getTask();
-
- // (task.height() - act.height()) / 2 = 5 < 10
- doReturn(new Rect(5, 5, 95, 95)).when(mActivity).getBounds();
- assertTrue(reachabilityOverrides.isHorizontalThinLetterboxed());
-
- // (task.height() - act.height()) / 2 = 10 = 10
- doReturn(new Rect(10, 10, 90, 90)).when(mActivity).getBounds();
- assertTrue(reachabilityOverrides.isHorizontalThinLetterboxed());
-
- // (task.height() - act.height()) / 2 = 11 > 10
- doReturn(new Rect(11, 11, 89, 89)).when(mActivity).getBounds();
- assertFalse(reachabilityOverrides.isHorizontalThinLetterboxed());
- }
-
- @Test
- @EnableFlags(Flags.FLAG_DISABLE_THIN_LETTERBOXING_POLICY)
- public void testAllowReachabilityForThinLetterboxWithFlagEnabled() {
- final AppCompatReachabilityOverrides reachabilityOverrides =
- mActivity.mAppCompatController.getAppCompatReachabilityOverrides();
- spyOn(reachabilityOverrides);
- doReturn(true).when(reachabilityOverrides).isVerticalThinLetterboxed();
- assertFalse(reachabilityOverrides.allowVerticalReachabilityForThinLetterbox());
- doReturn(true).when(reachabilityOverrides).isHorizontalThinLetterboxed();
- assertFalse(reachabilityOverrides.allowHorizontalReachabilityForThinLetterbox());
-
- doReturn(false).when(reachabilityOverrides).isVerticalThinLetterboxed();
- assertTrue(reachabilityOverrides.allowVerticalReachabilityForThinLetterbox());
- doReturn(false).when(reachabilityOverrides).isHorizontalThinLetterboxed();
- assertTrue(reachabilityOverrides.allowHorizontalReachabilityForThinLetterbox());
- }
-
- @Test
- @DisableFlags(Flags.FLAG_DISABLE_THIN_LETTERBOXING_POLICY)
- public void testAllowReachabilityForThinLetterboxWithFlagDisabled() {
- final AppCompatReachabilityOverrides reachabilityOverrides =
- mActivity.mAppCompatController.getAppCompatReachabilityOverrides();
- spyOn(reachabilityOverrides);
- doReturn(true).when(reachabilityOverrides).isVerticalThinLetterboxed();
- assertTrue(reachabilityOverrides.allowVerticalReachabilityForThinLetterbox());
- doReturn(true).when(reachabilityOverrides).isHorizontalThinLetterboxed();
- assertTrue(reachabilityOverrides.allowHorizontalReachabilityForThinLetterbox());
-
- doReturn(false).when(reachabilityOverrides).isVerticalThinLetterboxed();
- assertTrue(reachabilityOverrides.allowVerticalReachabilityForThinLetterbox());
- doReturn(false).when(reachabilityOverrides).isHorizontalThinLetterboxed();
- assertTrue(reachabilityOverrides.allowHorizontalReachabilityForThinLetterbox());
- }
-
- @Test
public void testIsLetterboxEducationEnabled() {
mController.isLetterboxEducationEnabled();
verify(mAppCompatConfiguration).getIsEducationEnabled();