Loading quickstep/tests/src/com/android/quickstep/FallbackRecentsTest.java +1 −1 Original line number Diff line number Diff line Loading @@ -144,7 +144,7 @@ public class FallbackRecentsTest { .around(new NavigationModeSwitchRule(mLauncher)) .around(new FailureWatcher(mLauncher, viewCaptureRule::getViewCaptureData)) .around(viewCaptureRule) .around(new TestIsolationRule(mLauncher)) .around(new TestIsolationRule(mLauncher, false)) .around(setLauncherCommand); mOtherLauncherActivity = context.getPackageManager().queryIntentActivities( Loading tests/src/com/android/launcher3/ui/AbstractLauncherUiTest.java +18 −8 Original line number Diff line number Diff line Loading @@ -111,15 +111,22 @@ public abstract class AbstractLauncherUiTest { protected String mTargetPackage; private int mLauncherPid; /** Detects activity leaks and throws an exception if a leak is found. */ public static void checkDetectedLeaks(LauncherInstrumentation launcher) { checkDetectedLeaks(launcher, false); } /** Detects activity leaks and throws an exception if a leak is found. */ public static void checkDetectedLeaks(LauncherInstrumentation launcher, boolean requireOneActiveActivity) { if (sActivityLeakReported) return; // Check whether activity leak detector has found leaked activities. Wait.atMost(() -> getActivityLeakErrorMessage(launcher), Wait.atMost(() -> getActivityLeakErrorMessage(launcher, requireOneActiveActivity), () -> { launcher.forceGc(); return MAIN_EXECUTOR.submit( () -> launcher.noLeakedActivities()).get(); () -> launcher.noLeakedActivities(requireOneActiveActivity)).get(); }, DEFAULT_UI_TIMEOUT, launcher); } Loading @@ -127,13 +134,16 @@ public abstract class AbstractLauncherUiTest { return getInstrumentation().getContext().getPackageName(); } private static String getActivityLeakErrorMessage(LauncherInstrumentation launcher) { private static String getActivityLeakErrorMessage(LauncherInstrumentation launcher, boolean requireOneActiveActivity) { sActivityLeakReported = true; return "Activity leak detector has found leaked activities, " + dumpHprofData(launcher, false) + "."; return "Activity leak detector has found leaked activities, requirining 1 activity: " + requireOneActiveActivity + "; " + dumpHprofData(launcher, false, requireOneActiveActivity) + "."; } public static String dumpHprofData(LauncherInstrumentation launcher, boolean intentionalLeak) { private static String dumpHprofData(LauncherInstrumentation launcher, boolean intentionalLeak, boolean requireOneActiveActivity) { if (intentionalLeak) return "intentional leak; not generating dump"; String result; Loading @@ -152,7 +162,7 @@ public abstract class AbstractLauncherUiTest { "am dumpheap " + device.getLauncherPackageName() + " " + fileName); } Log.d(TAG, "Saved leak dump, the leak is still present: " + !launcher.noLeakedActivities()); + !launcher.noLeakedActivities(requireOneActiveActivity)); sDumpWasGenerated = true; result = "saved memory dump as an artifact"; } catch (Throwable e) { Loading Loading @@ -211,7 +221,7 @@ public abstract class AbstractLauncherUiTest { .outerRule(new PortraitLandscapeRunner(this)) .around(new FailureWatcher(mLauncher, viewCaptureRule::getViewCaptureData)) .around(viewCaptureRule) .around(new TestIsolationRule(mLauncher)); .around(new TestIsolationRule(mLauncher, true)); return TestHelpers.isInLauncherProcess() ? RuleChain.outerRule(ShellCommandRule.setDefaultLauncher()).around(inner) Loading tests/src/com/android/launcher3/ui/TaplTestsLauncher3.java +1 −1 Original line number Diff line number Diff line Loading @@ -85,7 +85,7 @@ public class TaplTestsLauncher3 extends AbstractLauncherUiTest { test.waitForResumed("Launcher internal state is still Background"); // Check that we switched to home. test.mLauncher.getWorkspace(); AbstractLauncherUiTest.checkDetectedLeaks(test.mLauncher); AbstractLauncherUiTest.checkDetectedLeaks(test.mLauncher, true); } @After Loading tests/src/com/android/launcher3/util/rule/TestIsolationRule.java +5 −3 Original line number Diff line number Diff line Loading @@ -30,10 +30,12 @@ import org.junit.runners.model.Statement; * Isolates tests from some of the state created by the previous test. */ public class TestIsolationRule implements TestRule { final LauncherInstrumentation mLauncher; private final LauncherInstrumentation mLauncher; private final boolean mRequireOneActiveActivity; public TestIsolationRule(LauncherInstrumentation launcher) { public TestIsolationRule(LauncherInstrumentation launcher, boolean requireOneActiveActivity) { mLauncher = launcher; mRequireOneActiveActivity = requireOneActiveActivity; } @NonNull Loading @@ -46,7 +48,7 @@ public class TestIsolationRule implements TestRule { // Make sure that Launcher workspace looks correct. UiDevice.getInstance(InstrumentationRegistry.getInstrumentation()).pressHome(); AbstractLauncherUiTest.checkDetectedLeaks(mLauncher); AbstractLauncherUiTest.checkDetectedLeaks(mLauncher, mRequireOneActiveActivity); } }; } Loading tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java +7 −4 Original line number Diff line number Diff line Loading @@ -704,6 +704,7 @@ public final class LauncherInstrumentation { /** * Set the trackpad gesture type of the interaction. * * @param trackpadGestureType whether it's not from trackpad, two-finger, three-finger, or * four-finger gesture. */ Loading Loading @@ -2072,14 +2073,16 @@ public final class LauncherInstrumentation { return String.join(", ", getActivities()); } public boolean noLeakedActivities() { /** Returns whether no leaked activities are detected. */ public boolean noLeakedActivities(boolean requireOneActiveActivity) { final String[] activities = getActivities(); for (String activity : activities) { if (activity.contains("(destroyed)")) { return false; } } return activities.length <= 2; return activities.length <= (requireOneActiveActivity ? 1 : 2); } public int getActivitiesCreated() { Loading Loading
quickstep/tests/src/com/android/quickstep/FallbackRecentsTest.java +1 −1 Original line number Diff line number Diff line Loading @@ -144,7 +144,7 @@ public class FallbackRecentsTest { .around(new NavigationModeSwitchRule(mLauncher)) .around(new FailureWatcher(mLauncher, viewCaptureRule::getViewCaptureData)) .around(viewCaptureRule) .around(new TestIsolationRule(mLauncher)) .around(new TestIsolationRule(mLauncher, false)) .around(setLauncherCommand); mOtherLauncherActivity = context.getPackageManager().queryIntentActivities( Loading
tests/src/com/android/launcher3/ui/AbstractLauncherUiTest.java +18 −8 Original line number Diff line number Diff line Loading @@ -111,15 +111,22 @@ public abstract class AbstractLauncherUiTest { protected String mTargetPackage; private int mLauncherPid; /** Detects activity leaks and throws an exception if a leak is found. */ public static void checkDetectedLeaks(LauncherInstrumentation launcher) { checkDetectedLeaks(launcher, false); } /** Detects activity leaks and throws an exception if a leak is found. */ public static void checkDetectedLeaks(LauncherInstrumentation launcher, boolean requireOneActiveActivity) { if (sActivityLeakReported) return; // Check whether activity leak detector has found leaked activities. Wait.atMost(() -> getActivityLeakErrorMessage(launcher), Wait.atMost(() -> getActivityLeakErrorMessage(launcher, requireOneActiveActivity), () -> { launcher.forceGc(); return MAIN_EXECUTOR.submit( () -> launcher.noLeakedActivities()).get(); () -> launcher.noLeakedActivities(requireOneActiveActivity)).get(); }, DEFAULT_UI_TIMEOUT, launcher); } Loading @@ -127,13 +134,16 @@ public abstract class AbstractLauncherUiTest { return getInstrumentation().getContext().getPackageName(); } private static String getActivityLeakErrorMessage(LauncherInstrumentation launcher) { private static String getActivityLeakErrorMessage(LauncherInstrumentation launcher, boolean requireOneActiveActivity) { sActivityLeakReported = true; return "Activity leak detector has found leaked activities, " + dumpHprofData(launcher, false) + "."; return "Activity leak detector has found leaked activities, requirining 1 activity: " + requireOneActiveActivity + "; " + dumpHprofData(launcher, false, requireOneActiveActivity) + "."; } public static String dumpHprofData(LauncherInstrumentation launcher, boolean intentionalLeak) { private static String dumpHprofData(LauncherInstrumentation launcher, boolean intentionalLeak, boolean requireOneActiveActivity) { if (intentionalLeak) return "intentional leak; not generating dump"; String result; Loading @@ -152,7 +162,7 @@ public abstract class AbstractLauncherUiTest { "am dumpheap " + device.getLauncherPackageName() + " " + fileName); } Log.d(TAG, "Saved leak dump, the leak is still present: " + !launcher.noLeakedActivities()); + !launcher.noLeakedActivities(requireOneActiveActivity)); sDumpWasGenerated = true; result = "saved memory dump as an artifact"; } catch (Throwable e) { Loading Loading @@ -211,7 +221,7 @@ public abstract class AbstractLauncherUiTest { .outerRule(new PortraitLandscapeRunner(this)) .around(new FailureWatcher(mLauncher, viewCaptureRule::getViewCaptureData)) .around(viewCaptureRule) .around(new TestIsolationRule(mLauncher)); .around(new TestIsolationRule(mLauncher, true)); return TestHelpers.isInLauncherProcess() ? RuleChain.outerRule(ShellCommandRule.setDefaultLauncher()).around(inner) Loading
tests/src/com/android/launcher3/ui/TaplTestsLauncher3.java +1 −1 Original line number Diff line number Diff line Loading @@ -85,7 +85,7 @@ public class TaplTestsLauncher3 extends AbstractLauncherUiTest { test.waitForResumed("Launcher internal state is still Background"); // Check that we switched to home. test.mLauncher.getWorkspace(); AbstractLauncherUiTest.checkDetectedLeaks(test.mLauncher); AbstractLauncherUiTest.checkDetectedLeaks(test.mLauncher, true); } @After Loading
tests/src/com/android/launcher3/util/rule/TestIsolationRule.java +5 −3 Original line number Diff line number Diff line Loading @@ -30,10 +30,12 @@ import org.junit.runners.model.Statement; * Isolates tests from some of the state created by the previous test. */ public class TestIsolationRule implements TestRule { final LauncherInstrumentation mLauncher; private final LauncherInstrumentation mLauncher; private final boolean mRequireOneActiveActivity; public TestIsolationRule(LauncherInstrumentation launcher) { public TestIsolationRule(LauncherInstrumentation launcher, boolean requireOneActiveActivity) { mLauncher = launcher; mRequireOneActiveActivity = requireOneActiveActivity; } @NonNull Loading @@ -46,7 +48,7 @@ public class TestIsolationRule implements TestRule { // Make sure that Launcher workspace looks correct. UiDevice.getInstance(InstrumentationRegistry.getInstrumentation()).pressHome(); AbstractLauncherUiTest.checkDetectedLeaks(mLauncher); AbstractLauncherUiTest.checkDetectedLeaks(mLauncher, mRequireOneActiveActivity); } }; } Loading
tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java +7 −4 Original line number Diff line number Diff line Loading @@ -704,6 +704,7 @@ public final class LauncherInstrumentation { /** * Set the trackpad gesture type of the interaction. * * @param trackpadGestureType whether it's not from trackpad, two-finger, three-finger, or * four-finger gesture. */ Loading Loading @@ -2072,14 +2073,16 @@ public final class LauncherInstrumentation { return String.join(", ", getActivities()); } public boolean noLeakedActivities() { /** Returns whether no leaked activities are detected. */ public boolean noLeakedActivities(boolean requireOneActiveActivity) { final String[] activities = getActivities(); for (String activity : activities) { if (activity.contains("(destroyed)")) { return false; } } return activities.length <= 2; return activities.length <= (requireOneActiveActivity ? 1 : 2); } public int getActivitiesCreated() { Loading