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 android.permission.cts 18 19 import android.app.Instrumentation 20 import android.app.UiAutomation 21 import android.content.Context 22 import android.content.Intent 23 import android.content.res.Resources 24 import android.os.Build 25 import android.os.UserHandle 26 import android.provider.DeviceConfig 27 import android.safetycenter.SafetyCenterIssue 28 import android.safetycenter.SafetyCenterManager 29 import androidx.annotation.RequiresApi 30 import androidx.test.platform.app.InstrumentationRegistry 31 import androidx.test.uiautomator.By 32 import com.android.compatibility.common.util.SystemUtil.runWithShellPermissionIdentity 33 import com.android.compatibility.common.util.UiAutomatorUtils2.waitFindObject 34 import com.android.safetycenter.internaldata.SafetyCenterIds 35 import com.android.safetycenter.internaldata.SafetyCenterIssueId 36 import com.android.safetycenter.internaldata.SafetyCenterIssueKey 37 import org.junit.Assert 38 39 object SafetyCenterUtils { 40 /** Name of the flag that determines whether SafetyCenter is enabled. */ 41 const val PROPERTY_SAFETY_CENTER_ENABLED = "safety_center_is_enabled" 42 43 private val instrumentation: Instrumentation = InstrumentationRegistry.getInstrumentation() 44 45 /** Returns whether the device supports Safety Center. */ 46 @JvmStatic deviceSupportsSafetyCenternull47 fun deviceSupportsSafetyCenter(context: Context): Boolean { 48 return context.resources.getBoolean( 49 Resources.getSystem().getIdentifier("config_enableSafetyCenter", "bool", "android")) 50 } 51 52 /** Enabled or disable Safety Center */ 53 @JvmStatic setSafetyCenterEnablednull54 fun setSafetyCenterEnabled(enabled: Boolean) { 55 setDeviceConfigPrivacyProperty(PROPERTY_SAFETY_CENTER_ENABLED, enabled.toString()) 56 } 57 58 @RequiresApi(Build.VERSION_CODES.TIRAMISU) 59 @JvmStatic startSafetyCenterActivitynull60 fun startSafetyCenterActivity(context: Context) { 61 context.startActivity( 62 Intent(Intent.ACTION_SAFETY_CENTER) 63 .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK) 64 .addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK)) 65 } 66 67 @JvmStatic assertSafetyCenterStartednull68 fun assertSafetyCenterStarted() { 69 // CollapsingToolbar title can't be found by text, so using description instead. 70 waitFindObject(By.desc("Security & privacy")) 71 } 72 73 @JvmStatic setDeviceConfigPrivacyPropertynull74 fun setDeviceConfigPrivacyProperty( 75 propertyName: String, 76 value: String, 77 uiAutomation: UiAutomation = instrumentation.uiAutomation 78 ) { 79 runWithShellPermissionIdentity(uiAutomation) { 80 val valueWasSet = 81 DeviceConfig.setProperty( 82 DeviceConfig.NAMESPACE_PRIVACY, 83 /* name = */ propertyName, 84 /* value = */ value, 85 /* makeDefault = */ false) 86 check(valueWasSet) { "Could not set $propertyName to $value" } 87 } 88 } 89 90 @JvmStatic deleteDeviceConfigPrivacyPropertynull91 fun deleteDeviceConfigPrivacyProperty( 92 propertyName: String, 93 uiAutomation: UiAutomation = instrumentation.uiAutomation 94 ) { 95 runWithShellPermissionIdentity(uiAutomation) { 96 DeviceConfig.deleteProperty(DeviceConfig.NAMESPACE_PRIVACY, propertyName) 97 } 98 } 99 100 @JvmStatic getSafetyCenterIssuesnull101 private fun getSafetyCenterIssues( 102 automation: UiAutomation = instrumentation.uiAutomation 103 ): List<SafetyCenterIssue> { 104 val safetyCenterManager = 105 instrumentation.targetContext.getSystemService(SafetyCenterManager::class.java) 106 val issues = ArrayList<SafetyCenterIssue>() 107 runWithShellPermissionIdentity(automation) { 108 val safetyCenterData = safetyCenterManager!!.safetyCenterData 109 issues.addAll(safetyCenterData.issues) 110 } 111 return issues 112 } 113 114 @JvmStatic assertSafetyCenterIssueExistnull115 fun assertSafetyCenterIssueExist( 116 sourceId: String, 117 issueId: String, 118 issueTypeId: String, 119 automation: UiAutomation = instrumentation.uiAutomation 120 ) { 121 val safetyCenterIssueId = safetyCenterIssueId(sourceId, issueId, issueTypeId) 122 Assert.assertTrue( 123 "Expect issues in safety center", 124 getSafetyCenterIssues(automation).any { safetyCenterIssueId == it.id }) 125 } 126 127 @JvmStatic assertSafetyCenterIssueDoesNotExistnull128 fun assertSafetyCenterIssueDoesNotExist( 129 sourceId: String, 130 issueId: String, 131 issueTypeId: String, 132 automation: UiAutomation = instrumentation.uiAutomation 133 ) { 134 val safetyCenterIssueId = safetyCenterIssueId(sourceId, issueId, issueTypeId) 135 Assert.assertTrue( 136 "Expect no issue in safety center", 137 getSafetyCenterIssues(automation).none { safetyCenterIssueId == it.id }) 138 } 139 safetyCenterIssueIdnull140 private fun safetyCenterIssueId(sourceId: String, sourceIssueId: String, issueTypeId: String) = 141 SafetyCenterIds.encodeToString( 142 SafetyCenterIssueId.newBuilder() 143 .setSafetyCenterIssueKey( 144 SafetyCenterIssueKey.newBuilder() 145 .setSafetySourceId(sourceId) 146 .setSafetySourceIssueId(sourceIssueId) 147 .setUserId(UserHandle.myUserId()) 148 .build()) 149 .setIssueTypeId(issueTypeId) 150 .build()) 151 } 152