Snap for 10342904 from 0694284e2a35d423758bc8056ffb1e694d971cd9 to udc-qpr1-release

Change-Id: I7958f1cb0a126ff5457b05adc7bf7928e05e35f2
diff --git a/common/tests/unit/src/com/android/testutils/HandlerUtilsTest.kt b/common/tests/unit/src/com/android/testutils/HandlerUtilsTest.kt
index 30e0daf..0f6fa48 100644
--- a/common/tests/unit/src/com/android/testutils/HandlerUtilsTest.kt
+++ b/common/tests/unit/src/com/android/testutils/HandlerUtilsTest.kt
@@ -18,8 +18,10 @@
 
 import android.os.Handler
 import android.os.HandlerThread
+import com.android.testutils.FunctionalUtils.ThrowingSupplier
 import kotlin.test.assertEquals
 import kotlin.test.assertFailsWith
+import kotlin.test.assertNull
 import org.junit.Test
 import org.junit.runner.RunWith
 import org.junit.runners.JUnit4
@@ -69,13 +71,18 @@
 
         repeat(ATTEMPTS) { attempt ->
             var x = -10
-            visibleOnHandlerThread(handler) { x = attempt }
+            var y = -11
+            y = visibleOnHandlerThread(handler, ThrowingSupplier<Int> { x = attempt; attempt })
             assertEquals(attempt, x)
+            assertEquals(attempt, y)
             handler.post { assertEquals(attempt, x) }
         }
 
         assertFailsWith<IllegalArgumentException> {
             visibleOnHandlerThread(handler) { throw IllegalArgumentException() }
         }
+
+        // Null values may be returned by the supplier
+        assertNull(visibleOnHandlerThread(handler, ThrowingSupplier<Nothing?> { null }))
     }
 }
diff --git a/common/testutils/devicetests/com/android/testutils/HandlerUtils.kt b/common/testutils/devicetests/com/android/testutils/HandlerUtils.kt
index aa252a5..f00ca11 100644
--- a/common/testutils/devicetests/com/android/testutils/HandlerUtils.kt
+++ b/common/testutils/devicetests/com/android/testutils/HandlerUtils.kt
@@ -23,6 +23,7 @@
 import android.os.HandlerThread
 import android.util.Log
 import com.android.testutils.FunctionalUtils.ThrowingRunnable
+import com.android.testutils.FunctionalUtils.ThrowingSupplier
 import java.lang.Exception
 import java.util.concurrent.Executor
 import kotlin.test.fail
@@ -55,7 +56,8 @@
 }
 
 /**
- * Executes a block of code, making its side effects visible on the caller and the handler thread
+ * Executes a block of code that returns a value, making its side effects visible on the caller and
+ * the handler thread.
  *
  * After this function returns, the side effects of the passed block of code are guaranteed to be
  * observed both on the thread running the handler and on the thread running this method.
@@ -63,15 +65,15 @@
  * until it's executed, so keep in mind this method will block, (including, if the handler isn't
  * running, blocking forever).
  */
-fun visibleOnHandlerThread(handler: Handler, r: ThrowingRunnable) {
+fun <T> visibleOnHandlerThread(handler: Handler, supplier: ThrowingSupplier<T>): T {
     val cv = ConditionVariable()
-    var e: Exception? = null
+    var rv: Result<T> = Result.failure(RuntimeException("Not run"))
     handler.post {
         try {
-            r.run()
+            rv = Result.success(supplier.get())
         } catch (exception: Exception) {
             Log.e(TAG, "visibleOnHandlerThread caught exception", exception)
-            e = exception
+            rv = Result.failure(exception)
         }
         cv.open()
     }
@@ -79,5 +81,10 @@
     // and this thread also has seen the change (since cv.open() happens-before cv.block()
     // returns).
     cv.block()
-    e?.let { throw it }
+    return rv.getOrThrow()
+}
+
+/** Overload of visibleOnHandlerThread but executes a block of code that does not return a value. */
+inline fun visibleOnHandlerThread(handler: Handler, r: ThrowingRunnable){
+    visibleOnHandlerThread(handler, ThrowingSupplier<Unit> { r.run() })
 }