diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/external/TileServicesTest.java b/packages/SystemUI/tests/src/com/android/systemui/qs/external/TileServicesTest.java
index ddd661558be59..27d781dd7a8f7 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/external/TileServicesTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/external/TileServicesTest.java
@@ -52,7 +52,6 @@ public class TileServicesTest extends SysuiTestCase {
@Before
public void setUp() throws Exception {
- TestableLooper.get(this).setAsMainLooper();
mManagers = new ArrayList<>();
QSTileHost host = new QSTileHost(mContext, null,
mock(StatusBarIconController.class));
diff --git a/tests/testables/src/android/testing/AndroidTestingRunner.java b/tests/testables/src/android/testing/AndroidTestingRunner.java
index a425f70e836ce..cf5d4cf2f8287 100644
--- a/tests/testables/src/android/testing/AndroidTestingRunner.java
+++ b/tests/testables/src/android/testing/AndroidTestingRunner.java
@@ -35,6 +35,8 @@ import java.util.List;
/**
* A runner with support for extra annotations provided by the Testables library.
+ * @see UiThreadTest
+ * @see TestableLooper.RunWithLooper
*/
public class AndroidTestingRunner extends BlockJUnit4ClassRunner {
diff --git a/tests/testables/src/android/testing/BaseFragmentTest.java b/tests/testables/src/android/testing/BaseFragmentTest.java
index 32ee091a46c94..5cedbdffed358 100644
--- a/tests/testables/src/android/testing/BaseFragmentTest.java
+++ b/tests/testables/src/android/testing/BaseFragmentTest.java
@@ -80,6 +80,10 @@ public abstract class BaseFragmentTest {
});
}
+ /**
+ * Allows tests to sub-class TestableContext if they want to provide any extended functionality
+ * or provide a {@link LeakCheck} to the TestableContext upon instantiation.
+ */
protected TestableContext getContext() {
return new TestableContext(InstrumentationRegistry.getContext());
}
diff --git a/tests/testables/src/android/testing/LeakCheck.java b/tests/testables/src/android/testing/LeakCheck.java
index 8daaa8f166640..949215b4d3119 100644
--- a/tests/testables/src/android/testing/LeakCheck.java
+++ b/tests/testables/src/android/testing/LeakCheck.java
@@ -14,6 +14,7 @@
package android.testing;
+import android.content.Context;
import android.util.ArrayMap;
import android.util.Log;
@@ -28,6 +29,35 @@ import java.util.HashMap;
import java.util.List;
import java.util.Map;
+/**
+ * Utility for dealing with the facts of Lifecycle. Creates trackers to check that for every
+ * call to registerX, addX, bindX, a corresponding call to unregisterX, removeX, and unbindX
+ * is performed. This should be applied to a test as a {@link org.junit.rules.TestRule}
+ * and will only check for leaks on successful tests.
+ *
+ * Example that will catch an allocation and fail:
+ *
+ * public class LeakCheckTest {
+ * @Rule public LeakCheck mLeakChecker = new LeakCheck();
+ *
+ * @Test
+ * public void testLeak() {
+ * Context context = new ContextWrapper(...) {
+ * public Intent registerReceiver(BroadcastReceiver receiver, IntentFilter filter) {
+ * mLeakChecker.getTracker("receivers").addAllocation(new Throwable());
+ * }
+ * public void unregisterReceiver(BroadcastReceiver receiver) {
+ * mLeakChecker.getTracker("receivers").clearAllocations();
+ * }
+ * };
+ * context.registerReceiver(...);
+ * }
+ * }
+ *
+ *
+ * Note: {@link TestableContext} supports leak tracking when using
+ * {@link TestableContext#TestableContext(Context, LeakCheck)}.
+ */
public class LeakCheck extends TestWatcher {
private final Map mTrackers = new HashMap<>();
@@ -40,6 +70,13 @@ public class LeakCheck extends TestWatcher {
verify();
}
+ /**
+ * Acquire a {@link Tracker}. Gets a tracker for the specified tag, creating one if necessary.
+ * There should be one tracker for each pair of add/remove callbacks (e.g. one tracker for
+ * registerReceiver/unregisterReceiver).
+ *
+ * @param tag Unique tag to use for this set of allocation tracking.
+ */
public Tracker getTracker(String tag) {
Tracker t = mTrackers.get(tag);
if (t == null) {
@@ -49,10 +86,13 @@ public class LeakCheck extends TestWatcher {
return t;
}
- public void verify() {
+ private void verify() {
mTrackers.values().forEach(Tracker::verify);
}
+ /**
+ * Holds allocations associated with a specific callback (such as a BroadcastReceiver).
+ */
public static class LeakInfo {
private static final String TAG = "LeakInfo";
private List mThrowables = new ArrayList<>();
@@ -60,11 +100,20 @@ public class LeakCheck extends TestWatcher {
LeakInfo() {
}
+ /**
+ * Should be called once for each callback/listener added. addAllocation may be
+ * called several times, but it only takes one clearAllocations call to remove all
+ * of them.
+ */
public void addAllocation(Throwable t) {
// TODO: Drop off the first element in the stack trace here to have a cleaner stack.
mThrowables.add(t);
}
+ /**
+ * Should be called when the callback/listener has been removed. One call to
+ * clearAllocations will counteract any number of calls to addAllocation.
+ */
public void clearAllocations() {
mThrowables.clear();
}
@@ -82,9 +131,16 @@ public class LeakCheck extends TestWatcher {
}
}
+ /**
+ * Tracks allocations related to a specific tag or method(s).
+ * @see #getTracker(String)
+ */
public static class Tracker {
private Map