From 83b8a6f4e4337998812241a23f7ec7a4ce4975d1 Mon Sep 17 00:00:00 2001 From: AndroidX Test Team Date: Fri, 1 May 2026 14:02:40 -0700 Subject: [PATCH] Clarify IdlingResource.ResourceCallback usage. Adds javadoc to IdlingResource.ResourceCallback.onTransitionToIdle() to warn that it should be called before isIdleNow() returns true to avoid race conditions. If the order is inverted a race can cause consistency error to be thrown: ``` java.lang.RuntimeException: java.util.concurrent.ExecutionException: java.lang.IllegalStateException: Resource MyIdlingResource isIdleNow() is returning true, but a message indicating that the resource has transitioned from busy to idle was never sent. at androidx.test.espresso.Espresso.onIdle(Espresso.java:356) at androidx.test.espresso.Espresso.onIdle(Espresso.java:376) ``` If the `IdlingResource` changes its `isIdleNow()` to true on a thread other than the main thread, Espresso may observe that change from the main thread and subsequently complete a consistency check to verify that it did not observe a call to `onTransitionToIdle()` before the other thread has proceeded to call it. PiperOrigin-RevId: 908888181 --- .../java/androidx/test/espresso/IdlingResource.java | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/espresso/idling_resource/java/androidx/test/espresso/IdlingResource.java b/espresso/idling_resource/java/androidx/test/espresso/IdlingResource.java index ba368249d..6618a37f5 100644 --- a/espresso/idling_resource/java/androidx/test/espresso/IdlingResource.java +++ b/espresso/idling_resource/java/androidx/test/espresso/IdlingResource.java @@ -60,7 +60,14 @@ public interface IdlingResource { /** Registered by an {@link IdlingResource} to notify Espresso of a transition to idle. */ public interface ResourceCallback { - /** Called when the resource goes from busy to idle. */ + /** + * Called when the resource goes from busy to idle. + * + *

If the idle state is updated on a thread other than the main thread, this method should be + * called before the state is updated to return true. Failing to do so can cause a race + * condition where Espresso throws a consistency error due to observing {@link #isIdleNow()} + * returning true before the callback is invoked. + */ public void onTransitionToIdle(); } }