diff --git a/src/com/android/launcher3/Launcher.java b/src/com/android/launcher3/Launcher.java index 496cb4eb30..798b238d40 100644 --- a/src/com/android/launcher3/Launcher.java +++ b/src/com/android/launcher3/Launcher.java @@ -411,6 +411,8 @@ public class Launcher extends StatefulActivity private final SettingsCache.OnChangeListener mNaturalScrollingChangedListener = enabled -> mIsNaturalScrollingEnabled = enabled; + private int mActivityStopCount; // Used only by tests + public static Launcher getLauncher(Context context) { return fromContext(context); } @@ -1052,10 +1054,18 @@ public class Launcher extends StatefulActivity mAppWidgetHolder.setActivityStarted(false); NotificationListener.removeNotificationsChangedListener(getPopupDataProvider()); FloatingIconView.resetIconLoadResult(); + ++mActivityStopCount; AccessibilityManagerCompat.sendTestProtocolEventToTest( this, LAUNCHER_ACTIVITY_STOPPED_MESSAGE); } + /** Return activity stop count and reset it. Used only by tests. */ + public int getAndResetActivityStopCount() { + final int activityStopCount = mActivityStopCount; + mActivityStopCount = 0; + return activityStopCount; + } + @Override protected void onStart() { TraceHelper.INSTANCE.beginSection(ON_START_EVT); diff --git a/src/com/android/launcher3/testing/TestInformationHandler.java b/src/com/android/launcher3/testing/TestInformationHandler.java index 5636405600..27a153b48f 100644 --- a/src/com/android/launcher3/testing/TestInformationHandler.java +++ b/src/com/android/launcher3/testing/TestInformationHandler.java @@ -214,6 +214,16 @@ public class TestInformationHandler implements ResourceBasedOverride { .forceAllowRotationForTesting(Boolean.parseBoolean(arg))); return response; + case TestProtocol.REQUEST_GET_AND_RESET_ACTIVITY_STOP_COUNT: { + final Bundle bundle = getLauncherUIProperty(Bundle::putInt, + launcher -> launcher.getAndResetActivityStopCount()); + if (bundle != null) return bundle; + + // If Launcher activity wasn't created, 'it' was stopped 0 times. + response.putInt(TestProtocol.TEST_INFO_RESPONSE_FIELD, 0); + return response; + } + case TestProtocol.REQUEST_WORKSPACE_CELL_LAYOUT_SIZE: return getLauncherUIProperty(Bundle::putIntArray, launcher -> { final Workspace workspace = launcher.getWorkspace(); diff --git a/tests/multivalentTests/shared/com/android/launcher3/testing/shared/TestProtocol.java b/tests/multivalentTests/shared/com/android/launcher3/testing/shared/TestProtocol.java index 2f9945d17e..187dacabc0 100644 --- a/tests/multivalentTests/shared/com/android/launcher3/testing/shared/TestProtocol.java +++ b/tests/multivalentTests/shared/com/android/launcher3/testing/shared/TestProtocol.java @@ -178,6 +178,9 @@ public final class TestProtocol { public static final String REQUEST_UNSTASH_BUBBLE_BAR_IF_STASHED = "unstash-bubble-bar-if-stashed"; + public static final String REQUEST_GET_AND_RESET_ACTIVITY_STOP_COUNT = + "get-and-reset-activity-stops"; + /** Logs {@link Log#d(String, String)} if {@link #sDebugTracing} is true. */ public static void testLogD(String tag, String message) { if (!sDebugTracing) { diff --git a/tests/multivalentTests/src/com/android/launcher3/ui/AbstractLauncherUiTest.java b/tests/multivalentTests/src/com/android/launcher3/ui/AbstractLauncherUiTest.java index f0d2e20829..dcf56f85ce 100644 --- a/tests/multivalentTests/src/com/android/launcher3/ui/AbstractLauncherUiTest.java +++ b/tests/multivalentTests/src/com/android/launcher3/ui/AbstractLauncherUiTest.java @@ -599,6 +599,9 @@ public abstract class AbstractLauncherUiTest { Wait.atMost("Launcher activity didn't stop", () -> !launcherInstrumentation.isLauncherActivityStarted(), DEFAULT_ACTIVITY_TIMEOUT, launcherInstrumentation); + + // Reset activity stop count. + launcherInstrumentation.getAndResetActivityStopCount(); } public static ActivityInfo resolveSystemAppInfo(String category) { diff --git a/tests/multivalentTests/src/com/android/launcher3/util/rule/TestIsolationRule.java b/tests/multivalentTests/src/com/android/launcher3/util/rule/TestIsolationRule.java index 2b45902813..e98dcf4dee 100644 --- a/tests/multivalentTests/src/com/android/launcher3/util/rule/TestIsolationRule.java +++ b/tests/multivalentTests/src/com/android/launcher3/util/rule/TestIsolationRule.java @@ -44,11 +44,15 @@ public class TestIsolationRule implements TestRule { return new Statement() { @Override public void evaluate() throws Throwable { - base.evaluate(); - // Make sure that Launcher workspace looks correct. + // Reset activity stop count. + mLauncher.getAndResetActivityStopCount(); + base.evaluate(); + + // Make sure that Launcher workspace looks correct. UiDevice.getInstance(InstrumentationRegistry.getInstrumentation()).pressHome(); AbstractLauncherUiTest.checkDetectedLeaks(mLauncher, mRequireOneActiveActivity); + mLauncher.assertNoUnexpectedStops(); } }; } diff --git a/tests/multivalentTests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java b/tests/multivalentTests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java index 6c9f5ed620..90ca990f0e 100644 --- a/tests/multivalentTests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java +++ b/tests/multivalentTests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java @@ -207,6 +207,7 @@ public final class LauncherInstrumentation { private TrackpadGestureType mTrackpadGestureType = TrackpadGestureType.NONE; private int mPointerCount = 0; + private final boolean mIsLauncherTest; private static Pattern getKeyEventPattern(String action, String keyCode) { return Pattern.compile("Key event: KeyEvent.*action=" + action + ".*keyCode=" + keyCode); @@ -243,6 +244,7 @@ public final class LauncherInstrumentation { */ @Deprecated public LauncherInstrumentation(Instrumentation instrumentation, boolean isLauncherTest) { + mIsLauncherTest = isLauncherTest; mInstrumentation = instrumentation; mDevice = UiDevice.getInstance(instrumentation); @@ -415,6 +417,11 @@ public final class LauncherInstrumentation { TestProtocol.TEST_INFO_RESPONSE_FIELD); } + public int getAndResetActivityStopCount() { + return getTestInfo(TestProtocol.REQUEST_GET_AND_RESET_ACTIVITY_STOP_COUNT).getInt( + TestProtocol.TEST_INFO_RESPONSE_FIELD); + } + Rect getGridTaskRectForTablet() { return ((Rect) getTestInfo(TestProtocol.REQUEST_GET_GRID_TASK_SIZE_RECT_FOR_TABLET) .getParcelable(TestProtocol.TEST_INFO_RESPONSE_FIELD)); @@ -628,10 +635,19 @@ public final class LauncherInstrumentation { public void onTestStart() { mTestStartTime = System.currentTimeMillis(); + assertNoUnexpectedStops(); } public void onTestFinish() { mTestStartTime = -1; + assertNoUnexpectedStops(); + } + + /** Verify that the activity stop count is zero. */ + public void assertNoUnexpectedStops() { + if (mIsLauncherTest) { + assertEquals("Unexpected activity stops", 0, getAndResetActivityStopCount()); + } } private String formatSystemHealthMessage(String message) { @@ -1005,6 +1021,9 @@ public final class LauncherInstrumentation { event -> TestProtocol.LAUNCHER_ACTIVITY_STOPPED_MESSAGE .equals(event.getClassName().toString()), () -> "Launcher activity didn't stop", actionName); + + // Reset activity stop count. + getAndResetActivityStopCount(); } /** @@ -2257,6 +2276,7 @@ public final class LauncherInstrumentation { } public Closable eventsCheck() { + assertNoUnexpectedStops(); Assert.assertTrue("Nested event checking", mEventChecker == null); disableSensorRotation(); final Integer initialPid = getPid(); @@ -2264,6 +2284,7 @@ public final class LauncherInstrumentation { if (eventChecker.start()) mEventChecker = eventChecker; return () -> { + assertNoUnexpectedStops(); if (initialPid != null && initialPid.intValue() != getPid()) { if (mOnLauncherCrashed != null) mOnLauncherCrashed.run(); checkForAnomaly();