Merge changes I3fb03fca,I08520f07 into androidx-main

* changes:
  Force withJava for KMP projects without Android targets
  Use annotation kmp in collections
diff --git a/benchmark/benchmark-macro/build.gradle b/benchmark/benchmark-macro/build.gradle
index bc6c8e3..e0cbd25 100644
--- a/benchmark/benchmark-macro/build.gradle
+++ b/benchmark/benchmark-macro/build.gradle
@@ -147,24 +147,6 @@
     prune 'perfetto.protos.UnsymbolizedFrames'
 }
 
-// https://github.com/square/wire/issues/1947
-// Remove when we upgrade to fixed wire library
-afterEvaluate {
-    tasks.named("compileDebugKotlin").configure {
-        it.dependsOn("generateDebugProtos")
-    }
-    tasks.named("compileReleaseKotlin").configure {
-        it.dependsOn("generateReleaseProtos")
-    }
-}
-
-androidx {
-    deviceTests {
-        targetAppProject = project(":benchmark:integration-tests:macrobenchmark-target")
-        targetAppVariant = "release"
-    }
-}
-
 // Define a task dependency so the app is installed before we run macro benchmarks.
 afterEvaluate {
     // `:benchmark:integration-tests:macrobenchmark-target:installRelease` is not in the compose
@@ -176,3 +158,10 @@
                 .dependsOn(installTask)
     }
 }
+
+androidx {
+    deviceTests {
+        targetAppProject = project(":benchmark:integration-tests:macrobenchmark-target")
+        targetAppVariant = "release"
+    }
+}
\ No newline at end of file
diff --git a/camera/camera-camera2-pipe-integration/src/main/java/androidx/camera/camera2/pipe/integration/impl/CapturePipeline.kt b/camera/camera-camera2-pipe-integration/src/main/java/androidx/camera/camera2/pipe/integration/impl/CapturePipeline.kt
index 484cd54..d696fb1 100644
--- a/camera/camera-camera2-pipe-integration/src/main/java/androidx/camera/camera2/pipe/integration/impl/CapturePipeline.kt
+++ b/camera/camera-camera2-pipe-integration/src/main/java/androidx/camera/camera2/pipe/integration/impl/CapturePipeline.kt
@@ -123,12 +123,14 @@
         requests: List<Request>,
         captureMode: Int,
         flashMode: Int,
-    ): List<Deferred<Void?>> =
-        if (hasFlashUnit && isFlashRequired(flashMode)) {
+    ): List<Deferred<Void?>> {
+        debug { "CapturePipeline#torchAsFlashCapture" }
+        return if (hasFlashUnit && isFlashRequired(flashMode)) {
             torchApplyCapture(requests, captureMode, CHECK_3A_WITH_FLASH_TIMEOUT_IN_NS)
         } else {
             defaultNoFlashCapture(requests, captureMode)
         }
+    }
 
     private suspend fun defaultCapture(
         requests: List<Request>,
@@ -154,15 +156,24 @@
         requests: List<Request>,
         captureMode: Int
     ): List<Deferred<Void?>> {
+        debug { "CapturePipeline#defaultNoFlashCapture" }
         val lock3ARequired = captureMode == CAPTURE_MODE_MAXIMIZE_QUALITY
         if (lock3ARequired) {
+            debug { "CapturePipeline#defaultNoFlashCapture: Locking 3A" }
             lock3A(CHECK_3A_TIMEOUT_IN_NS)
+            debug { "CapturePipeline#defaultNoFlashCapture: Locking 3A done" }
         }
         return submitRequestInternal(requests).also { captureSignal ->
             if (lock3ARequired) {
                 threads.sequentialScope.launch {
+                    debug { "CapturePipeline#defaultNoFlashCapture: Waiting for capture signal" }
                     captureSignal.joinAll()
-                    unlock3A()
+                    debug {
+                        "CapturePipeline#defaultNoFlashCapture: Waiting for capture signal done"
+                    }
+                    debug { "CapturePipeline#defaultNoFlashCapture: Unlocking 3A" }
+                    unlock3A(CHECK_3A_TIMEOUT_IN_NS)
+                    debug { "CapturePipeline#defaultNoFlashCapture: Unlocking 3A done" }
                 }
             }
         }
@@ -173,28 +184,39 @@
         captureMode: Int,
         timeLimitNs: Long,
     ): List<Deferred<Void?>> {
+        debug { "CapturePipeline#torchApplyCapture" }
         val torchOnRequired = torchControl.torchStateLiveData.value == TorchState.OFF
         if (torchOnRequired) {
+            debug { "CapturePipeline#torchApplyCapture: Setting torch" }
             torchControl.setTorchAsync(true).join()
+            debug { "CapturePipeline#torchApplyCapture: Setting torch done" }
         }
 
         val lock3ARequired = torchOnRequired || captureMode == CAPTURE_MODE_MAXIMIZE_QUALITY
         if (lock3ARequired) {
+            debug { "CapturePipeline#torchApplyCapture: Locking 3A" }
             lock3A(timeLimitNs)
+            debug { "CapturePipeline#torchApplyCapture: Locking 3A done" }
         }
 
         return submitRequestInternal(requests).also { captureSignal ->
             if (torchOnRequired) {
                 threads.sequentialScope.launch {
+                    debug { "CapturePipeline#torchApplyCapture: Waiting for capture signal" }
                     captureSignal.joinAll()
+                    debug { "CapturePipeline#torchApplyCapture: Unsetting torch" }
                     @Suppress("DeferredResultUnused")
                     torchControl.setTorchAsync(false)
+                    debug { "CapturePipeline#torchApplyCapture: Unsetting torch done" }
                 }
             }
             if (lock3ARequired) {
                 threads.sequentialScope.launch {
+                    debug { "CapturePipeline#torchApplyCapture: Waiting for capture signal" }
                     captureSignal.joinAll()
-                    unlock3A()
+                    debug { "CapturePipeline#torchApplyCapture: Unlocking 3A" }
+                    unlock3A(CHECK_3A_TIMEOUT_IN_NS)
+                    debug { "CapturePipeline#torchApplyCapture: Unlocking 3A done" }
                 }
             }
         }
@@ -204,16 +226,29 @@
         requests: List<Request>,
         timeLimitNs: Long,
     ): List<Deferred<Void?>> {
+        debug { "CapturePipeline#aePreCaptureApplyCapture" }
+        debug { "CapturePipeline#aePreCaptureApplyCapture: Acquiring session for locking 3A" }
         graph.acquireSession().use {
+            debug { "CapturePipeline#aePreCaptureApplyCapture: Locking 3A for capture" }
             it.lock3AForCapture(timeLimitNs = timeLimitNs).join()
+            debug { "CapturePipeline#aePreCaptureApplyCapture: Locking 3A for capture done" }
         }
 
         return submitRequestInternal(requests).also { captureSignal ->
             threads.sequentialScope.launch {
+                debug { "CapturePipeline#aePreCaptureApplyCapture: Waiting for capture signal" }
                 captureSignal.joinAll()
+                debug {
+                    "CapturePipeline#aePreCaptureApplyCapture: Waiting for capture signal done"
+                }
+                debug {
+                    "CapturePipeline#aePreCaptureApplyCapture: Acquiring session for unlocking 3A"
+                }
                 graph.acquireSession().use {
+                    debug { "CapturePipeline#aePreCaptureApplyCapture: Unlocking 3A" }
                     @Suppress("DeferredResultUnused")
                     it.unlock3APostCapture()
+                    debug { "CapturePipeline#aePreCaptureApplyCapture: Unlocking 3A done" }
                 }
             }
         }
@@ -228,8 +263,13 @@
         )
     }.await()
 
-    private suspend fun unlock3A(): Result3A = graph.acquireSession().use {
-        it.unlock3A(ae = true, af = true, awb = true)
+    private suspend fun unlock3A(timeLimitNs: Long): Result3A = graph.acquireSession().use {
+        it.unlock3A(
+            ae = true,
+            af = true,
+            awb = true,
+            timeLimitNs = timeLimitNs,
+        )
     }.await()
 
     private fun submitRequestInternal(requests: List<Request>): List<Deferred<Void?>> {
@@ -282,15 +322,17 @@
         }
 
         threads.sequentialScope.launch {
+            debug {
+                "CapturePipeline#submitRequestInternal: Acquiring session for submitting requests"
+            }
             // graph.acquireSession may fail if camera has entered closing stage
             var cameraGraphSession: CameraGraph.Session? = null
             try {
                 cameraGraphSession = graph.acquireSession()
             } catch (_: CancellationException) {
                 info {
-                    "CapturePipeline#submitRequestInternal:" +
-                        " CameraGraph.Session could not be acquired, requests may need " +
-                        "re-submission"
+                    "CapturePipeline#submitRequestInternal: " +
+                        "CameraGraph.Session could not be acquired, requests may need re-submission"
                 }
 
                 // completing the requests exceptionally so that they are retried with next camera
@@ -311,6 +353,7 @@
                     it.stopRepeating()
                 }
 
+                debug { "CapturePipeline#submitRequestInternal: Submitting $requestsToSubmit" }
                 it.submit(requestsToSubmit)
 
                 if (requiresStopRepeating) {
diff --git a/camera/camera-camera2-pipe-integration/src/main/java/androidx/camera/camera2/pipe/integration/impl/StillCaptureRequestControl.kt b/camera/camera-camera2-pipe-integration/src/main/java/androidx/camera/camera2/pipe/integration/impl/StillCaptureRequestControl.kt
index 47a80ac..e4dec65 100644
--- a/camera/camera-camera2-pipe-integration/src/main/java/androidx/camera/camera2/pipe/integration/impl/StillCaptureRequestControl.kt
+++ b/camera/camera-camera2-pipe-integration/src/main/java/androidx/camera/camera2/pipe/integration/impl/StillCaptureRequestControl.kt
@@ -19,6 +19,7 @@
 import androidx.annotation.GuardedBy
 import androidx.annotation.RequiresApi
 import androidx.camera.camera2.pipe.core.Log.debug
+import androidx.camera.camera2.pipe.core.Log.warn
 import androidx.camera.camera2.pipe.integration.adapter.asListenableFuture
 import androidx.camera.camera2.pipe.integration.adapter.propagateOnceTo
 import androidx.camera.camera2.pipe.integration.config.CameraScope
@@ -39,6 +40,7 @@
 import kotlinx.coroutines.launch
 import kotlinx.coroutines.sync.Mutex
 import kotlinx.coroutines.sync.withLock
+import kotlinx.coroutines.withTimeoutOrNull
 
 @RequiresApi(21) // TODO(b/200306659): Remove and replace with annotation on package-info.java
 @CameraScope
@@ -141,7 +143,14 @@
         // Prior to submitStillCaptures, wait until the pending flash mode session change is
         // completed. On some devices, AE preCapture triggered in submitStillCaptures may not
         // work properly if the repeating request to change the flash mode is not completed.
-        flashControl.updateSignal.join()
+        debug { "StillCaptureRequestControl: Waiting for flash control" }
+        withTimeoutOrNull(1_000L) {
+            flashControl.updateSignal.join()
+        } ?: {
+            warn { "StillCaptureRequestControl: Waiting for flash control timed out" }
+        }
+        debug { "StillCaptureRequestControl: Waiting for flash control done" }
+        debug { "StillCaptureRequestControl: Issuing single capture" }
         val deferredList = camera.requestControl.issueSingleCaptureAsync(
             request.captureConfigs,
             request.captureMode,
@@ -152,7 +161,10 @@
         return threads.sequentialScope.async {
             // requestControl.issueSingleCaptureAsync shouldn't be invoked from here directly,
             // because sequentialScope.async is may not be executed immediately
-            deferredList.awaitAll()
+            debug { "StillCaptureRequestControl: Waiting for deferred list from $request" }
+            deferredList.awaitAll().also {
+                debug { "StillCaptureRequestControl: Waiting for deferred list from $request done" }
+            }
         }
     }
 
diff --git a/camera/camera-camera2-pipe-integration/src/main/java/androidx/camera/camera2/pipe/integration/impl/UseCaseCameraRequestControl.kt b/camera/camera-camera2-pipe-integration/src/main/java/androidx/camera/camera2/pipe/integration/impl/UseCaseCameraRequestControl.kt
index fda33c0..6ce070e 100644
--- a/camera/camera-camera2-pipe-integration/src/main/java/androidx/camera/camera2/pipe/integration/impl/UseCaseCameraRequestControl.kt
+++ b/camera/camera-camera2-pipe-integration/src/main/java/androidx/camera/camera2/pipe/integration/impl/UseCaseCameraRequestControl.kt
@@ -281,6 +281,7 @@
         return synchronized(lock) {
             infoBundleMap.merge()
         }.let { infoBundle ->
+            debug { "UseCaseCameraRequestControl: Submitting still captures to capture pipeline" }
             capturePipeline.submitStillCaptures(
                 requests = captureSequence.map {
                     configAdapter.mapToRequest(
diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml
index 319b8c8..865ca20 100644
--- a/gradle/libs.versions.toml
+++ b/gradle/libs.versions.toml
@@ -57,7 +57,7 @@
 spdxGradlePlugin = "0.1.0"
 sqldelight = "1.3.0"
 retrofit = "2.7.2"
-wire = "4.5.1"
+wire = "4.7.0"
 
 [libraries]
 agpTestingPlatformCoreProto =  { module = "com.google.testing.platform:core-proto", version = "0.0.8-alpha08" }
diff --git a/gradle/verification-keyring.keys b/gradle/verification-keyring.keys
index 7ddd517..bfa94d7 100644
--- a/gradle/verification-keyring.keys
+++ b/gradle/verification-keyring.keys
@@ -6375,6 +6375,42 @@
 =2g4Z
 -----END PGP PUBLIC KEY BLOCK-----
 
+pub    DA70BCBA6D76AD03
+uid    kaml GitHub Actions <[email protected]>
+
+sub    66A2CBDE49E8A25D
+-----BEGIN PGP PUBLIC KEY BLOCK-----
+Version: BCPG v1.68
+
+mQENBGAwdRsBCADCXfWdHhywp8Rcgt834W/Z3MFEAxYdxjAJOTQhc/In1SJfIqi/
+xD7OKHA2fbwzRnS/UmXkmElTK7JI3/1gWRm8kEaaHTnlI63Z9MZV0DHMpJMgvpFM
+JXKMw9GWbOZt211YMFTkY3oi+kCIibzs4S+2zAiKX0/B5xU1gE0hnPYbXQtZ2sUb
+8t4axAkPdlDVrnBbgPD/+31c8G2Nsd3w6Rughi3SXdqp/6lKZpJNZV7ZPllA8wa3
+6hdOqWkh2Xh7uyKCXPtPyw57vwK1CeTmrAvI7Xhfh1Cxj2bnS8POnF0YsthtbG0Z
+6TupcFBrscugbl4F0aWsxCT0WjKQ75J2zgMnABEBAAG0M2thbWwgR2l0SHViIEFj
+dGlvbnMgPGdpdGh1YmFjdGlvbnNAY2hhcmxlc2tvcm4uY29tPokBTgQTAQgAOBYh
+BOAe0pOYGuSEQDtl19pwvLptdq0DBQJgMHUbAhsDBQsJCAcCBhUKCQgLAgQWAgMB
+Ah4BAheAAAoJENpwvLptdq0Dv1YIAKtEikvgdsiHjOAl30uN71sjfa2IQpczLqnX
+I+UWyFLbjkvXoYyhOwkbK+J9NqOVEn3r6mG+lQemP7CIyFixRTLw7B9kl5RAGe2g
+tfqPOufiWTAwkvgCfnR8OxOcz2tjspZpw/9I9razrJbvCzHxCc4QbMtlGQwrrDm0
+EVCH2Ks7sbiWWujl6EIKsVobuZHaRsqrpxPtC1I7xm+ed8rEKkrBThLB9Tf2itun
++w1ct7y1rgOGKh5XH9IYuSwEbWZH0dhMIsdItYZW1Uk+t6DXXTRq5OXHmr2s6JWt
+9HECR8b+xUUZIue3d8PWewiCElgz6c+Jq6ywEwGiSyZXvFBpLaC5AQ0EYDB1GwEI
+AMQiv6gHlSd5U1Jzc8vFMS/Pt7RMg2OF8Wedibqc0/EvzIHSqAkZnVs8iVmf6VYp
+bx1ihFG4ySaCmVkovJ7Yv6yHNyyqp1SsRPJJ1zGUVx5USOO8sT6FsS1Wis2NmWXf
+wcJkhO6RfBUF21vPjXkGlbkhyQxqsnCWtCDhZT9/OGacOTd+xUf9Fq2u5KACdn7h
+qlVMhaRgrPEmdh+95RjSHu+lkzoThG4S0rRd7u6XrUs4w5rqwBqWQB8jzS5I8L6H
+MpLnmLQckxnICGwRUyKywd23/zF3HN63Dbj8MCohrYRn39cXutlRbLH4dG8hPpoI
+JeP7OYZIUJGJYdsi5q+EJAsAEQEAAYkBNgQYAQgAIBYhBOAe0pOYGuSEQDtl19pw
+vLptdq0DBQJgMHUbAhsMAAoJENpwvLptdq0DtRMIAJiWNubgOvXDav3l7Wff+qPN
+zMKFh+9lNMyLaI5O8eEGjXAt90esN1MeVbKwFiNO5NSM2qLf7QJ6aXF6SIUGsWut
+1BUOt21Q5unl3n4YZ+Ff6zA/VEgniGJBJBBnBq2dJO/lJKj9tLkcbvzV0Aa+MLQ+
+lEB3lufGDU4xsApp6w18YQK2Za64drxYL9yChofSH0x+Gvx7aYaXi+K1L/HUSh7k
+qBcwgxmqlnWArnQ8sYd4WF1LOplzm4yp0XocHtcZ0hQG0ZW3kAEITPYfmVk26kO0
+Rsia71ZAHmuEYsLHz6uOIqf6XHbFUITFtdjPOSiJmQhIgiFCzvFSgrx6jKZSR04=
+=Jrn2
+-----END PGP PUBLIC KEY BLOCK-----
+
 pub    15C71C0A4E0B8EDD
 sub    891E4C2D471515FE
 -----BEGIN PGP PUBLIC KEY BLOCK-----
diff --git a/gradle/verification-metadata.xml b/gradle/verification-metadata.xml
index 1778366..55aede8 100644
--- a/gradle/verification-metadata.xml
+++ b/gradle/verification-metadata.xml
@@ -411,6 +411,7 @@
             <trusting group="com.beust"/>
             <trusting group="org.testng"/>
          </trusted-key>
+         <trusted-key id="e01ed293981ae484403b65d7da70bcba6d76ad03" group="com.charleskorn.kaml"/>
          <trusted-key id="e0d98c5fd55a8af232290e58dee12b9896f97e34" group="org.pcollections"/>
          <trusted-key id="e3a9f95079e84ce201f7cf60bede11eaf1164480" group="org.hamcrest"/>
          <trusted-key id="e62231331bca7e1f292c9b88c1b12a5d99c0729d" group="org.jetbrains"/>