• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2022 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 com.android.safetycenter.testing
18 
19 import android.Manifest.permission.REVOKE_RUNTIME_PERMISSIONS
20 import android.Manifest.permission.SEND_SAFETY_CENTER_UPDATE
21 import android.content.Context
22 import android.content.Intent
23 import android.content.Intent.ACTION_SAFETY_CENTER
24 import android.content.Intent.ACTION_VIEW_SAFETY_CENTER_QS
25 import android.content.Intent.FLAG_ACTIVITY_CLEAR_TASK
26 import android.content.Intent.FLAG_ACTIVITY_NEW_TASK
27 import android.os.Build.VERSION_CODES.TIRAMISU
28 import android.os.Bundle
29 import androidx.annotation.RequiresApi
30 import androidx.test.uiautomator.By
31 import com.android.compatibility.common.util.RetryableException
32 import com.android.compatibility.common.util.UiAutomatorUtils2.getUiDevice
33 import com.android.safetycenter.testing.ShellPermissions.callWithShellPermissionIdentity
34 import com.android.safetycenter.testing.UiTestHelper.waitDisplayed
35 
36 /** A class that provides a way to launch the SafetyCenter activity in tests. */
37 @RequiresApi(TIRAMISU)
38 object SafetyCenterActivityLauncher {
39 
40     /**
41      * Launches the SafetyCenter activity and exits it once [block] completes.
42      *
43      * @param withReceiverPermission whether we should hold the [SEND_SAFETY_CENTER_UPDATE]
44      *   permission while the activity is on the screen (e.g. to ensure the CTS package can have its
45      *   receiver called during refresh/rescan)
46      */
Contextnull47     fun Context.launchSafetyCenterActivity(
48         intentExtras: Bundle? = null,
49         withReceiverPermission: Boolean = false,
50         preventTrampolineToSettings: Boolean = true,
51         block: () -> Unit
52     ) {
53         val launchSafetyCenterIntent =
54             createIntent(
55                 ACTION_SAFETY_CENTER,
56                 intentExtras,
57                 preventTrampolineToSettings = preventTrampolineToSettings
58             )
59         if (withReceiverPermission) {
60             callWithShellPermissionIdentity(SEND_SAFETY_CENTER_UPDATE) {
61                 executeBlockAndExit(block) { startActivity(launchSafetyCenterIntent) }
62             }
63         } else {
64             executeBlockAndExit(block) { startActivity(launchSafetyCenterIntent) }
65         }
66     }
67 
68     /** Launches the SafetyCenter Quick Settings activity and exits it once [block] completes. */
Contextnull69     fun Context.launchSafetyCenterQsActivity(intentExtras: Bundle? = null, block: () -> Unit) {
70         val launchSafetyCenterQsIntent = createIntent(ACTION_VIEW_SAFETY_CENTER_QS, intentExtras)
71         executeBlockAndExit(block) {
72             callWithShellPermissionIdentity(REVOKE_RUNTIME_PERMISSIONS) {
73                 startActivity(launchSafetyCenterQsIntent)
74             }
75         }
76     }
77 
78     /** Launches a page in Safety Center and exits it once [block] completes. */
openPageAndExitnull79     fun openPageAndExit(entryPoint: String, block: () -> Unit) {
80         executeBlockAndExit(block) { waitDisplayed(By.text(entryPoint)) { it.click() } }
81     }
82 
83     /**
84      * Launches a page in Safety Center and exits it once [block] completes, throwing a
85      * [RetryableException] for any [RuntimeException] thrown by [block] to allow [RetryRule] to
86      * retry the test invocation.
87      */
openPageAndExitAllowingRetriesnull88     fun openPageAndExitAllowingRetries(entryPoint: String, block: () -> Unit) {
89         try {
90             openPageAndExit(entryPoint, block)
91         } catch (e: Throwable) {
92             throw RetryableException(e, "Exception occurred when checking a Safety Center page")
93         }
94     }
95 
createIntentnull96     private fun createIntent(
97         intentAction: String,
98         intentExtras: Bundle?,
99         preventTrampolineToSettings: Boolean = false
100     ): Intent {
101         val launchIntent =
102             Intent(intentAction).addFlags(FLAG_ACTIVITY_NEW_TASK).addFlags(FLAG_ACTIVITY_CLEAR_TASK)
103         intentExtras?.let { launchIntent.putExtras(it) }
104         if (preventTrampolineToSettings) {
105             launchIntent.putExtra(EXTRA_PREVENT_TRAMPOLINE_TO_SETTINGS, true)
106         }
107         return launchIntent
108     }
109 
executeBlockAndExitnull110     fun executeBlockAndExit(block: () -> Unit, launchActivity: () -> Unit) {
111         val uiDevice = getUiDevice()
112         uiDevice.waitForIdle()
113         launchActivity()
114         uiDevice.waitForIdle()
115         block()
116         uiDevice.pressBack()
117         uiDevice.waitForIdle()
118     }
119 
120     private const val EXTRA_PREVENT_TRAMPOLINE_TO_SETTINGS: String =
121         "com.android.permissioncontroller.safetycenter.extra.PREVENT_TRAMPOLINE_TO_SETTINGS"
122 }
123