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 53 /** Enabled or disable Safety Center */ 54 @JvmStatic setSafetyCenterEnablednull55 fun setSafetyCenterEnabled(enabled: Boolean) { 56 setDeviceConfigPrivacyProperty(PROPERTY_SAFETY_CENTER_ENABLED, enabled.toString()) 57 } 58 59 @RequiresApi(Build.VERSION_CODES.TIRAMISU) 60 @JvmStatic startSafetyCenterActivitynull61 fun startSafetyCenterActivity(context: Context) { 62 context.startActivity( 63 Intent(Intent.ACTION_SAFETY_CENTER) 64 .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK) 65 .addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK) 66 ) 67 } 68 69 @JvmStatic assertSafetyCenterStartednull70 fun assertSafetyCenterStarted() { 71 // CollapsingToolbar title can't be found by text, so using description instead. 72 waitFindObject(By.desc("Security & privacy")) 73 } 74 75 @JvmStatic setDeviceConfigPrivacyPropertynull76 fun setDeviceConfigPrivacyProperty( 77 propertyName: String, 78 value: String, 79 uiAutomation: UiAutomation = instrumentation.uiAutomation 80 ) { 81 runWithShellPermissionIdentity(uiAutomation) { 82 val valueWasSet = 83 DeviceConfig.setProperty( 84 DeviceConfig.NAMESPACE_PRIVACY, 85 /* name = */ propertyName, 86 /* value = */ value, 87 /* makeDefault = */ false 88 ) 89 check(valueWasSet) { "Could not set $propertyName to $value" } 90 } 91 } 92 93 @JvmStatic deleteDeviceConfigPrivacyPropertynull94 fun deleteDeviceConfigPrivacyProperty( 95 propertyName: String, 96 uiAutomation: UiAutomation = instrumentation.uiAutomation 97 ) { 98 runWithShellPermissionIdentity(uiAutomation) { 99 DeviceConfig.deleteProperty(DeviceConfig.NAMESPACE_PRIVACY, propertyName) 100 } 101 } 102 103 @JvmStatic getSafetyCenterIssuesnull104 private fun getSafetyCenterIssues( 105 automation: UiAutomation = instrumentation.uiAutomation 106 ): List<SafetyCenterIssue> { 107 val safetyCenterManager = 108 instrumentation.targetContext.getSystemService(SafetyCenterManager::class.java) 109 val issues = ArrayList<SafetyCenterIssue>() 110 runWithShellPermissionIdentity(automation) { 111 val safetyCenterData = safetyCenterManager!!.safetyCenterData 112 issues.addAll(safetyCenterData.issues) 113 } 114 return issues 115 } 116 117 @JvmStatic assertSafetyCenterIssueExistnull118 fun assertSafetyCenterIssueExist( 119 sourceId: String, 120 issueId: String, 121 issueTypeId: String, 122 automation: UiAutomation = instrumentation.uiAutomation 123 ) { 124 val safetyCenterIssueId = safetyCenterIssueId(sourceId, issueId, issueTypeId) 125 Assert.assertTrue( 126 "Expect issues in safety center", 127 getSafetyCenterIssues(automation).any { safetyCenterIssueId == it.id } 128 ) 129 } 130 131 @JvmStatic assertSafetyCenterIssueDoesNotExistnull132 fun assertSafetyCenterIssueDoesNotExist( 133 sourceId: String, 134 issueId: String, 135 issueTypeId: String, 136 automation: UiAutomation = instrumentation.uiAutomation 137 ) { 138 val safetyCenterIssueId = safetyCenterIssueId(sourceId, issueId, issueTypeId) 139 Assert.assertTrue( 140 "Expect no issue in safety center", 141 getSafetyCenterIssues(automation).none { safetyCenterIssueId == it.id } 142 ) 143 } 144 safetyCenterIssueIdnull145 private fun safetyCenterIssueId(sourceId: String, sourceIssueId: String, issueTypeId: String) = 146 SafetyCenterIds.encodeToString( 147 SafetyCenterIssueId.newBuilder() 148 .setSafetyCenterIssueKey( 149 SafetyCenterIssueKey.newBuilder() 150 .setSafetySourceId(sourceId) 151 .setSafetySourceIssueId(sourceIssueId) 152 .setUserId(UserHandle.myUserId()) 153 .build() 154 ) 155 .setIssueTypeId(issueTypeId) 156 .build() 157 ) 158 } 159