tryTest to return its last evaluated expression

This is the same thing try{} does, and allows to lift
return out of tryTest.

This allows syntaxes likeĀ :
fun foo() = try {
    "Foo";
  } cleanup {
    doSomeCleanup()
  }
}

val network = try {
    registerNetworkCallback
    callback.getNetwork()
  } cleanup {
    unregisterNetworkCallback
  }
}

Note: bypassing ktlint because of b/185077240

Test: FrameworksNetTests
Change-Id: Ib8f6fde7ccfd62fdcb3c1e3b7b03909ed94d4b23
diff --git a/staticlibs/testutils/Android.bp b/staticlibs/testutils/Android.bp
index 2f0bcc3..29df759 100644
--- a/staticlibs/testutils/Android.bp
+++ b/staticlibs/testutils/Android.bp
@@ -42,26 +42,34 @@
 }
 
 java_library {
-  // Consider using net-tests-utils instead if writing device code.
-  // That library has a lot more useful tools into it for users that
-  // work on Android and includes this lib.
-  name: "net-tests-utils-host-device-common",
-  srcs: [
-      "hostdevice/**/*.java",
-      "hostdevice/**/*.kt",
-  ],
-  host_supported: true,
-  visibility: [
-      "//frameworks/libs/net/common/tests:__subpackages__",
-      "//frameworks/libs/net/client-libs/tests:__subpackages__",
-  ],
-  libs: [
-      "jsr305",
-  ],
-  static_libs: [
-      "kotlin-test"
-  ],
-  lint: { strict_updatability_linting: true },
+    // Consider using net-tests-utils instead if writing device code.
+    // That library has a lot more useful tools into it for users that
+    // work on Android and includes this lib.
+    name: "net-tests-utils-host-device-common",
+    srcs: [
+        "hostdevice/**/*.java",
+        "hostdevice/**/*.kt",
+    ],
+    host_supported: true,
+    visibility: [
+        "//frameworks/libs/net/common/tests:__subpackages__",
+        "//frameworks/libs/net/client-libs/tests:__subpackages__",
+    ],
+    // sc-mainline-prod uses an old version of Kotlin that used
+    // to reserve the right to make breaking changes to the
+    // Result type and disallowed returning an instance of it.
+    // Later versions allowed this and there was never a change,
+    // so no matter the version returning Result is always fine,
+    // but on sc-mainline-prod the compiler rejects it without
+    // the following flag.
+    kotlincflags: ["-Xallow-result-return-type"],
+    libs: [
+        "jsr305",
+    ],
+    static_libs: [
+        "kotlin-test"
+    ],
+    lint: { strict_updatability_linting: true },
 }
 
 java_test_host {
diff --git a/staticlibs/testutils/hostdevice/com/android/testutils/Cleanup.kt b/staticlibs/testutils/hostdevice/com/android/testutils/Cleanup.kt
index bacbbe3..d93c7d0 100644
--- a/staticlibs/testutils/hostdevice/com/android/testutils/Cleanup.kt
+++ b/staticlibs/testutils/hostdevice/com/android/testutils/Cleanup.kt
@@ -19,6 +19,7 @@
 package com.android.testutils
 
 import com.android.testutils.ExceptionUtils.ThrowingRunnable
+import com.android.testutils.ExceptionUtils.ThrowingSupplier
 import javax.annotation.CheckReturnValue
 
 /**
@@ -59,11 +60,15 @@
  *   cleanup code
  * });
  */
-class ExceptionCleanupBlock(val originalException: Exception?) {
-    inline infix fun cleanup(block: () -> Unit) {
+// sc-mainline-prod has an older kotlin that doesn't know about value classes. TODO : Change this
+// to "value class" when aosp no longer merges into sc-mainline-prod.
+@Suppress("INLINE_CLASS_DEPRECATED")
+inline class ExceptionCleanupBlock<T>(val result: Result<T>) {
+    inline infix fun cleanup(block: () -> Unit): T {
         try {
             block()
         } catch (e: Exception) {
+            val originalException = result.exceptionOrNull()
             if (null == originalException) {
                 throw e
             } else {
@@ -71,25 +76,26 @@
                 throw originalException
             }
         }
-        if (null != originalException) throw originalException
+        return result.getOrThrow()
     }
 }
 
 @CheckReturnValue
-fun tryTest(block: () -> Unit): ExceptionCleanupBlock {
-    try {
-        block()
-    } catch (e: Exception) {
-        return ExceptionCleanupBlock(e)
-    }
-    return ExceptionCleanupBlock(null)
-}
+fun <T> tryTest(block: () -> T) = ExceptionCleanupBlock(
+        try {
+            Result.success(block())
+        } catch (e: Exception) {
+            Result.failure(e)
+        })
 
 // Java support
-fun testAndCleanup(tryBlock: ThrowingRunnable, cleanupBlock: ThrowingRunnable) {
-    tryTest {
-        tryBlock.run()
+fun <T> testAndCleanup(tryBlock: ThrowingSupplier<T>, cleanupBlock: ThrowingRunnable): T {
+    return tryTest {
+        tryBlock.get()
     } cleanup {
         cleanupBlock.run()
     }
 }
+fun testAndCleanup(tryBlock: ThrowingRunnable, cleanupBlock: ThrowingRunnable) {
+    return testAndCleanup(ThrowingSupplier { tryBlock.run() }, cleanupBlock)
+}