diff --git a/espresso/CHANGELOG.md b/espresso/CHANGELOG.md index a1888dc4e..a0993d9c1 100644 --- a/espresso/CHANGELOG.md +++ b/espresso/CHANGELOG.md @@ -16,6 +16,8 @@ The following artifacts were released: **Bug Fixes** +* Fix deadlock in espresso in Robolectric INSTRUMENTATION_TEST + paused looper. + **New Features** **Breaking Changes** diff --git a/espresso/core/java/androidx/test/espresso/base/ThreadPoolExecutorExtractor.java b/espresso/core/java/androidx/test/espresso/base/ThreadPoolExecutorExtractor.java index 0cd67686e..b016f7d44 100644 --- a/espresso/core/java/androidx/test/espresso/base/ThreadPoolExecutorExtractor.java +++ b/espresso/core/java/androidx/test/espresso/base/ThreadPoolExecutorExtractor.java @@ -19,6 +19,8 @@ import android.os.Handler; import android.os.Looper; import androidx.annotation.Nullable; +import androidx.test.internal.platform.ServiceLoaderWrapper; +import androidx.test.internal.platform.os.ControlledLooper; import java.lang.reflect.Field; import java.util.concurrent.Callable; import java.util.concurrent.CountDownLatch; @@ -42,6 +44,10 @@ final class ThreadPoolExecutorExtractor { private static final String MODERN_ASYNC_TASK_FIELD_NAME = "THREAD_POOL_EXECUTOR"; private final Handler mainHandler; + private final ControlledLooper controlledLooper = + ServiceLoaderWrapper.loadSingleService( + ControlledLooper.class, () -> ControlledLooper.NO_OP_CONTROLLED_LOOPER); + @Inject ThreadPoolExecutorExtractor(Looper looper) { mainHandler = new Handler(looper); @@ -85,6 +91,7 @@ public void run() { } }); try { + controlledLooper.drainMainThreadUntilIdle(); latch.await(); } catch (InterruptedException ie) { if (!futureToRun.isDone()) {