1 /*
2 * Copyright (C) 2021 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.common
18
19 import android.app.Activity
20 import android.content.Context
21 import android.content.Intent
22 import android.content.Intent.FLAG_ACTIVITY_NEW_TASK
23 import android.content.IntentSender
24 import android.os.Bundle
25 import android.util.Log
26 import kotlin.time.Duration.Companion.milliseconds
27 import kotlin.time.Duration.Companion.seconds
28
29 /**
30 * An [Activity] for launching confirmation UI via an [android.content.IntentSender.sendIntent] and
31 * receiving result in [onActivityResult].
32 */
33 class CompanionActivity : Activity() {
34 private var result: Pair<Int, Intent?>? = null
35
onCreatenull36 override fun onCreate(savedInstanceState: Bundle?) {
37 Log.d(TAG, "$this.onCreate()")
38 super.onCreate(savedInstanceState)
39 unsafeInstance = this
40 }
41
onDestroynull42 override fun onDestroy() {
43 Log.d(TAG, "$this.onDestroy()")
44 unsafeInstance = null
45 super.onDestroy()
46 }
47
onActivityResultnull48 override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
49 Log.i(TAG, "onActivityResult() code=${resultCode.codeToString()}, " +
50 "data=${intent.extras}")
51 result = resultCode to data
52 }
53
54 companion object {
55 private var unsafeInstance: CompanionActivity? = null
56 val instance: CompanionActivity
57 get() = unsafeInstance ?: error("There is no CompanionActivity")
58
launchAndWaitnull59 fun launchAndWait(context: Context) {
60 val intent = Intent(context, CompanionActivity::class.java)
61 intent.addFlags(FLAG_ACTIVITY_NEW_TASK)
62 context.startActivity(intent)
63
64 waitForResult(timeout = 3.seconds, interval = 100.milliseconds) {
65 unsafeInstance?.takeIf { it.isResumed }
66 } ?: error("CompanionActivity has not appeared")
67 }
68
startIntentSendernull69 fun startIntentSender(intentSender: IntentSender) =
70 instance.startIntentSenderForResult(intentSender, 0, null, 0, 0, 0)
71
72 fun waitForActivityResult(): Pair<Int, Intent?> {
73 val result = waitForResult(timeout = 1.seconds, interval = 100.milliseconds) {
74 instance.result
75 } ?: error("onActivityResult() has not been invoked")
76 instance.result = null
77 return result
78 }
79
finishnull80 fun finish() = instance.finish()
81
82 fun safeFinish() = unsafeInstance?.finish()
83
84 fun waitUntilGone() = waitFor { unsafeInstance == null }
85 }
86 }
87
codeToStringnull88 private fun Int.codeToString() = when (this) {
89 Activity.RESULT_OK -> "RESULT_OK"
90 Activity.RESULT_CANCELED -> "RESULT_CANCELED"
91 else -> "Unknown"
92 } + "($this)"
93