Fixes flaky on CtsAutoFillServiceTestCases

The RetryRule will retry tests when the tests fail due to a
RetryableException. But it does not clean all launched activities which
causes the retries are blocked on the exception:
"Could not launch intent Intent { ... } within 45 seconds."
To avoid the same issue, adds a RetryCleaner interface to clean between
the retries.

Bug: 145244166
Test: atest CtsAutoFillServiceTestCases
Change-Id: I583f0421862b796d3ba7920e4851cd59b790c53c
diff --git a/common/device-side/util-axt/src/com/android/compatibility/common/util/RetryRule.java b/common/device-side/util-axt/src/com/android/compatibility/common/util/RetryRule.java
index 32dedea..ca0e3e2 100644
--- a/common/device-side/util-axt/src/com/android/compatibility/common/util/RetryRule.java
+++ b/common/device-side/util-axt/src/com/android/compatibility/common/util/RetryRule.java
@@ -18,6 +18,8 @@
 
 import android.util.Log;
 
+import androidx.annotation.Nullable;
+
 import org.junit.rules.TestRule;
 import org.junit.runner.Description;
 import org.junit.runners.model.Statement;
@@ -28,7 +30,17 @@
 public class RetryRule implements TestRule {
 
     private static final String TAG = "RetryRule";
+
+    /**
+     * An interface is used to clean up testing objects between the retries to make sure
+     * the testing environment is clean.
+     */
+    public interface RetryCleaner {
+        void clean();
+    }
+
     private final int mMaxAttempts;
+    private final RetryCleaner mCleaner;
 
     /**
      * Retries the underlying test when it catches a {@link RetryableException}.
@@ -38,10 +50,24 @@
      * @throws IllegalArgumentException if {@code retries} is less than {@code 0}.
      */
     public RetryRule(int retries) {
+        this(retries, null);
+    }
+
+    /**
+     * Retries the underlying test when it catches a {@link RetryableException}.
+     *
+     * @param retries number of retries. Use {@code 0} to disable rule.
+     * @param cleaner a {@link RetryCleaner} to clean up the objects generated by the testing
+     *               between retries
+     *
+     * @throws IllegalArgumentException if {@code retries} is less than {@code 0}.
+     */
+    public RetryRule(int retries, @Nullable RetryCleaner cleaner) {
         if (retries < 0) {
             throw new IllegalArgumentException("retries must be more than 0");
         }
         mMaxAttempts = retries + 1;
+        mCleaner = cleaner;
     }
 
     @Override
@@ -78,6 +104,9 @@
                                     + " to " + timeout.ms() + "ms");
                         }
                         caught = e;
+                        if (i != mMaxAttempts && mCleaner != null) {
+                            mCleaner.clean();
+                        }
                     }
                     Log.w(TAG, "Arrrr! " + name + " failed at attempt " + i + "/" + mMaxAttempts
                             + ": " + caught);
diff --git a/tests/autofillservice/src/android/autofillservice/cts/AutoFillServiceTestCase.java b/tests/autofillservice/src/android/autofillservice/cts/AutoFillServiceTestCase.java
index ecdf90a..a5ac282 100644
--- a/tests/autofillservice/src/android/autofillservice/cts/AutoFillServiceTestCase.java
+++ b/tests/autofillservice/src/android/autofillservice/cts/AutoFillServiceTestCase.java
@@ -53,7 +53,6 @@
 import org.junit.Rule;
 import org.junit.rules.RuleChain;
 import org.junit.rules.TestRule;
-import org.junit.rules.TestWatcher;
 import org.junit.runner.Description;
 import org.junit.runner.RunWith;
 import org.junit.runners.model.Statement;
@@ -199,9 +198,15 @@
         protected static final RequiredFeatureRule sRequiredFeatureRule =
                 new RequiredFeatureRule(PackageManager.FEATURE_AUTOFILL);
 
-        private final TestWatcher mTestWatcher = new AutofillTestWatcher();
+        private final AutofillTestWatcher mTestWatcher = new AutofillTestWatcher();
 
-        private final RetryRule mRetryRule = new RetryRule(getNumberRetries());
+        private final RetryRule mRetryRule =
+                new RetryRule(getNumberRetries(), () -> {
+                    // Between testing and retries, clean all launched activities to avoid
+                    // exception:
+                    //     Could not launch intent Intent { ... } within 45 seconds.
+                    mTestWatcher.cleanAllActivities();
+                });
 
         private final AutofillLoggingTestRule mLoggingRule = new AutofillLoggingTestRule(TAG);
 
diff --git a/tests/autofillservice/src/android/autofillservice/cts/AutofillTestWatcher.java b/tests/autofillservice/src/android/autofillservice/cts/AutofillTestWatcher.java
index 6879a8c..6c29197 100644
--- a/tests/autofillservice/src/android/autofillservice/cts/AutofillTestWatcher.java
+++ b/tests/autofillservice/src/android/autofillservice/cts/AutofillTestWatcher.java
@@ -36,6 +36,18 @@
  */
 public final class AutofillTestWatcher extends TestWatcher {
 
+    /**
+     * Cleans up all launched activities between the tests and retries.
+     */
+    public void cleanAllActivities() {
+        try {
+            finishActivities();
+            waitUntilAllDestroyed();
+        } finally {
+            resetStaticState();
+        }
+    }
+
     private static final String TAG = "AutofillTestWatcher";
 
     @GuardedBy("sUnfinishedBusiness")
@@ -55,12 +67,7 @@
     @Override
     protected void finished(Description description) {
         final String testName = description.getDisplayName();
-        try {
-            finishActivities();
-            waitUntilAllDestroyed();
-        } finally {
-            resetStaticState();
-        }
+        cleanAllActivities();
         Log.i(TAG, "Finished " + testName);
         TestNameUtils.setCurrentTestName(null);
     }