1 /*
2  * Copyright (C) 2024 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package android.companion.cts.multidevice
18 
19 import android.companion.AssociationInfo
20 import android.companion.CompanionDeviceManager
21 import android.companion.CompanionException
22 import android.content.IntentSender
23 import android.os.OutcomeReceiver
24 import java.util.concurrent.CountDownLatch
25 import java.util.concurrent.TimeUnit.SECONDS
26 import java.util.concurrent.TimeoutException
27 
28 /** Blocking callbacks for CDM callbacks. */
29 object CallbackUtils {
30     private const val TAG = "CDM_CallbackUtils"
31     private const val CALLBACK_TIMEOUT_SEC = 30L
32 
33     class AssociationCallback : CompanionDeviceManager.Callback() {
34         private val pending = CountDownLatch(1)
35         private val created = CountDownLatch(1)
36 
37         private var pendingIntent: IntentSender? = null
38         private var associationInfo: AssociationInfo? = null
39         private var error: String? = null
40 
onAssociationPendingnull41         override fun onAssociationPending(intentSender: IntentSender) {
42             this.pendingIntent = intentSender
43             pending.countDown()
44         }
45 
onAssociationCreatednull46         override fun onAssociationCreated(associationInfo: AssociationInfo) {
47             this.associationInfo = associationInfo
48             created.countDown()
49         }
50 
onFailurenull51         override fun onFailure(error: CharSequence?) {
52             this.error = error?.toString() ?: "There was an unexpected failure."
53             pending.countDown()
54             created.countDown()
55         }
56 
waitForPendingIntentnull57         fun waitForPendingIntent(): IntentSender? {
58             if (!pending.await(CALLBACK_TIMEOUT_SEC, SECONDS)) {
59                 throw TimeoutException("Pending association request timed out.")
60             }
61 
62             error?.let {
63                 throw RuntimeException(it)
64             }
65 
66             return pendingIntent
67         }
68 
waitForAssociationnull69         fun waitForAssociation(): AssociationInfo? {
70             if (!created.await(CALLBACK_TIMEOUT_SEC, SECONDS)) {
71                 throw TimeoutException("Association request timed out.")
72             }
73 
74             error?.let {
75                 throw RuntimeException(it)
76             }
77 
78             return associationInfo
79         }
80     }
81 
82     class SystemDataTransferCallback : OutcomeReceiver<Void, CompanionException> {
83         private val completed = CountDownLatch(1)
84 
85         private var error: CompanionException? = null
86 
onResultnull87         override fun onResult(result: Void?) {
88             completed.countDown()
89         }
90 
onErrornull91         override fun onError(error: CompanionException) {
92             this.error = error
93             completed.countDown()
94         }
95 
waitForCompletionnull96         fun waitForCompletion() {
97             if (!completed.await(CALLBACK_TIMEOUT_SEC, SECONDS)) {
98                 throw TimeoutException("System data transfer timed out.")
99             }
100 
101             error?.let {
102                 throw it
103             }
104         }
105     }
106 }
107