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.permissionui.cts 18 19 import android.app.Activity 20 import android.app.AppOpsManager 21 import android.content.ComponentName 22 import android.content.Intent 23 import android.location.LocationManager 24 import android.os.Build 25 import android.permission.cts.MtsIgnore 26 import android.permission.cts.PermissionUtils 27 import androidx.test.filters.FlakyTest 28 import androidx.test.filters.SdkSuppress 29 import androidx.test.uiautomator.By 30 import com.android.compatibility.common.util.AppOpsUtils 31 import com.android.compatibility.common.util.CddTest 32 import com.android.compatibility.common.util.SystemUtil 33 import java.util.concurrent.TimeUnit 34 import org.junit.Assert 35 import org.junit.Assume.assumeFalse 36 import org.junit.Before 37 import org.junit.Ignore 38 import org.junit.Test 39 40 private const val EXTRA_PACKAGE_NAME = "android.intent.extra.PACKAGE_NAME" 41 private const val ACTION_MANAGE_APP_PERMISSIONS = "android.intent.action.MANAGE_APP_PERMISSIONS" 42 43 /** 44 * Tests that LocationProviderInterceptDialog (a warning dialog) shows when attempting to view the 45 * location permission for location a service provider app (e.g., usually GMS, but we use a custom 46 * app in this test). 47 */ 48 @SdkSuppress(minSdkVersion = Build.VERSION_CODES.S) 49 @FlakyTest 50 @CddTest(requirement = "9.1/C-0-1") 51 class LocationProviderInterceptDialogTest : BaseUsePermissionTest() { 52 @Before setupnull53 fun setup() { 54 assumeFalse(isAutomotive) 55 assumeFalse(isTv) 56 assumeFalse(isWatch) 57 installPackage(MIC_LOCATION_PROVIDER_APP_APK_PATH, grantRuntimePermissions = true) 58 AppOpsUtils.setOpMode( 59 MIC_LOCATION_PROVIDER_APP_PACKAGE_NAME, 60 AppOpsManager.OPSTR_MOCK_LOCATION, 61 AppOpsManager.MODE_ALLOWED 62 ) 63 enableMicrophoneAppAsLocationProvider() 64 } 65 66 @Test 67 @Ignore("b/288471744") 68 @MtsIgnore(bugId = 288471744) clickLocationPermission_showDialog_clickOknull69 fun clickLocationPermission_showDialog_clickOk() { 70 openPermissionScreenForApp() 71 clickAndWaitForWindowTransition(By.text("Location")) 72 findView(By.textContains("Location access can be modified from location settings"), true) 73 click(By.res(OK_BUTTON_RES)) 74 } 75 76 @Test 77 @Ignore("b/288471744") 78 @MtsIgnore(bugId = 288471744) clickLocationPermission_showDialog_clickLocationAccessnull79 fun clickLocationPermission_showDialog_clickLocationAccess() { 80 openPermissionScreenForApp() 81 clickAndWaitForWindowTransition(By.text("Location")) 82 findView(By.textContains("Location access can be modified from location settings"), true) 83 clickAndWaitForWindowTransition(By.res(LOCATION_ACCESS_BUTTON_RES)) 84 findView(By.res(USE_LOCATION_LABEL_ID), true) 85 } 86 87 @Test 88 @Ignore("b/288471744") 89 @MtsIgnore(bugId = 288471744) checkRestrictedPermissionsnull90 fun checkRestrictedPermissions() { 91 context.sendBroadcast( 92 Intent(PermissionTapjackingTest.ACTION_SHOW_OVERLAY) 93 .putExtra("package", MIC_LOCATION_PROVIDER_APP_PACKAGE_NAME) 94 .putExtra("permission", "android.permission.BACKGROUND_CAMERA") 95 ) 96 } 97 openPermissionScreenForAppnull98 private fun openPermissionScreenForApp() { 99 restartPermissionController() 100 doAndWaitForWindowTransition { 101 SystemUtil.runWithShellPermissionIdentity { 102 context.startActivity( 103 Intent(ACTION_MANAGE_APP_PERMISSIONS).apply { 104 addFlags(Intent.FLAG_ACTIVITY_NEW_TASK) 105 addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK) 106 putExtra(EXTRA_PACKAGE_NAME, MIC_LOCATION_PROVIDER_APP_PACKAGE_NAME) 107 } 108 ) 109 } 110 } 111 } 112 restartPermissionControllernull113 private fun restartPermissionController() { 114 PermissionUtils.clearAppState(permissionControllerPackageName) 115 } 116 enableMicrophoneAppAsLocationProvidernull117 private fun enableMicrophoneAppAsLocationProvider() { 118 val locationManager = context.getSystemService(LocationManager::class.java)!! 119 val future = 120 startActivityForFuture( 121 Intent().apply { 122 component = 123 ComponentName( 124 MIC_LOCATION_PROVIDER_APP_PACKAGE_NAME, 125 "$MIC_LOCATION_PROVIDER_APP_PACKAGE_NAME.AddLocationProviderActivity" 126 ) 127 } 128 ) 129 val result = future.get(TIMEOUT_MILLIS, TimeUnit.MILLISECONDS) 130 Assert.assertEquals(Activity.RESULT_OK, result.resultCode) 131 Assert.assertTrue( 132 SystemUtil.callWithShellPermissionIdentity { 133 locationManager.isProviderPackage(MIC_LOCATION_PROVIDER_APP_PACKAGE_NAME) 134 } 135 ) 136 } 137 138 companion object { 139 private const val USE_LOCATION_LABEL_ID = "com.android.settings:id/switch_text" 140 private const val MIC_LOCATION_PROVIDER_APP_APK_PATH = 141 "$APK_DIRECTORY/CtsAccessMicrophoneAppLocationProvider.apk" 142 private const val MIC_LOCATION_PROVIDER_APP_PACKAGE_NAME = 143 "android.permissionui.cts.accessmicrophoneapplocationprovider" 144 private const val OK_BUTTON_RES = "android:id/button2" 145 private const val LOCATION_ACCESS_BUTTON_RES = "android:id/button1" 146 private val permissionControllerPackageName = 147 context.packageManager.permissionControllerPackageName 148 } 149 } 150