1 /* <lambda>null2 * Copyright (C) 2023 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 package android.devicepolicy.cts 17 18 import android.app.admin.DevicePolicyManager 19 import android.content.ComponentName 20 import android.os.PersistableBundle 21 import com.android.bedstead.harrier.BedsteadJUnit4 22 import com.android.bedstead.harrier.DeviceState 23 import com.android.bedstead.harrier.annotations.Postsubmit 24 import com.android.bedstead.harrier.annotations.RequireRunOnSystemUser 25 import com.android.bedstead.enterprise.annotations.CanSetPolicyTest 26 import com.android.bedstead.enterprise.annotations.CannotSetPolicyTest 27 import com.android.bedstead.enterprise.annotations.EnsureHasDeviceOwner 28 import com.android.bedstead.enterprise.annotations.EnsureHasProfileOwner 29 import com.android.bedstead.enterprise.annotations.PolicyAppliesTest 30 import com.android.bedstead.harrier.policies.TransferOwnership 31 import com.android.bedstead.harrier.policies.TransferOwnershipForDeviceOwner 32 import com.android.bedstead.harrier.policies.TransferOwnershipForProfileOwner 33 import com.android.bedstead.nene.TestApis 34 import com.android.compatibility.common.util.ApiTest 35 import com.android.eventlib.truth.EventLogsSubject 36 import com.android.eventlib.truth.EventLogsSubject.assertThat 37 import com.android.queryable.queries.BundleQuery 38 import com.android.queryable.queries.ReceiverQuery 39 import com.google.common.truth.Truth 40 import com.google.common.truth.Truth.assertThat 41 import org.junit.ClassRule 42 import org.junit.Rule 43 import org.junit.Test 44 import org.junit.runner.RunWith 45 import org.testng.Assert 46 import org.testng.Assert.assertThrows 47 48 // TODO(b/298202673: Add tests for behavior for all policies) 49 @RunWith(BedsteadJUnit4::class) 50 class TransferOwnershipTest { 51 @ApiTest(apis = ["android.app.admin.DevicePolicyManager#transferOwnership", "android.app.admin.DevicePolicyManager#getTransferOwnershipBundle"]) 52 @Postsubmit(reason = "new test") 53 @CanSetPolicyTest(policy = [TransferOwnership::class]) 54 fun transferOwnership_getTransferOwnershipBundle_bundleReceivedByTargetAdmin() { 55 targetDeviceAdminTestAppSupportsTransferOwnership.install().use { testApp -> 56 try { 57 deviceState.dpc().devicePolicyManager().transferOwnership( 58 deviceState.dpc().componentName(), targetAdmin, bundle 59 ) 60 61 assertThat( 62 testApp.devicePolicyManager().transferOwnershipBundle.getBoolean(KEY)).isTrue() 63 } finally { 64 removeDeviceAdmin() 65 } 66 } 67 } 68 69 @ApiTest(apis = ["android.app.admin.DevicePolicyManager#transferOwnership"]) 70 @Postsubmit(reason = "new test") 71 @CannotSetPolicyTest(policy = [TransferOwnership::class], includeNonDeviceAdminStates = false) 72 fun transferOwnership_cannotSet_throwsException() { 73 targetDeviceAdminTestAppSupportsTransferOwnership.install().use { 74 assertThrows(SecurityException::class.java) { 75 deviceState.dpc().devicePolicyManager().transferOwnership( 76 deviceState.dpc().componentName(), targetAdmin, bundle 77 ) 78 } 79 } 80 } 81 82 @ApiTest(apis = ["android.app.admin.DevicePolicyManager#transferOwnership", "android.app.admin.DevicePolicyManager#getTransferOwnershipBundle"]) 83 @Postsubmit(reason = "new test") 84 @CanSetPolicyTest(policy = [TransferOwnership::class]) 85 fun transferOwnership_nullBundleTransferred_getTransferOwnershipBundle_emptyBundleReceivedByTargetAdmin() { 86 targetDeviceAdminTestAppSupportsTransferOwnership.install().use { testApp -> 87 try { 88 deviceState.dpc().devicePolicyManager().transferOwnership( 89 deviceState.dpc().componentName(), targetAdmin, /* bundle= */null 90 ) 91 92 assertThat( 93 testApp.devicePolicyManager().transferOwnershipBundle.isEmpty()).isTrue() 94 } finally { 95 removeDeviceAdmin() 96 } 97 } 98 } 99 100 @ApiTest(apis = ["android.app.admin.DevicePolicyManager#transferOwnership"]) 101 @Postsubmit(reason = "new test") 102 @CanSetPolicyTest(policy = [TransferOwnershipForDeviceOwner::class]) 103 fun transferOwnership_deviceOwner_ownershipTransferredToTargetAdmin() { 104 targetDeviceAdminTestAppSupportsTransferOwnership.install().use { 105 try { 106 deviceState.dpc().devicePolicyManager().transferOwnership( 107 deviceState.dpc().componentName(), targetAdmin, bundle 108 ) 109 110 assertThat(TestApis.devicePolicy().getDeviceOwner()!!.componentName()) 111 .isEqualTo(targetAdmin) 112 } finally { 113 removeDeviceAdmin() 114 } 115 } 116 } 117 118 @ApiTest(apis = ["android.app.admin.DevicePolicyManager#transferOwnership"]) 119 @Postsubmit(reason = "new test") 120 @CanSetPolicyTest(policy = [TransferOwnershipForProfileOwner::class]) 121 fun transferOwnership_profileOwner_ownershipTransferredToTargetAdmin() { 122 targetDeviceAdminTestAppSupportsTransferOwnership.install().use { 123 try { 124 deviceState.dpc().devicePolicyManager().transferOwnership( 125 deviceState.dpc().componentName(), targetAdmin, bundle 126 ) 127 128 assertThat(TestApis.devicePolicy().getProfileOwner()!!.componentName()) 129 .isEqualTo(targetAdmin) 130 } finally { 131 removeDeviceAdmin() 132 } 133 } 134 } 135 136 @CanSetPolicyTest(policy = [TransferOwnership::class]) 137 @Postsubmit(reason = "new test") 138 @ApiTest(apis = ["android.app.admin.DevicePolicyManager#getTransferOwnershipBundle"]) 139 fun getTransferOwnershipBundle_nonDpc_throwsException() { 140 targetDeviceAdminTestAppSupportsTransferOwnership.install().use { 141 try { 142 deviceState.dpc().devicePolicyManager().transferOwnership( 143 deviceState.dpc().componentName(), targetAdmin, bundle 144 ) 145 assertThrows(SecurityException::class.java) { 146 localDevicePolicyManager.transferOwnershipBundle 147 } 148 } finally { 149 removeDeviceAdmin() 150 } 151 } 152 } 153 154 @ApiTest(apis = ["android.app.admin.DevicePolicyManager#transferOwnership"]) 155 @Postsubmit(reason = "new test") 156 @CanSetPolicyTest(policy = [TransferOwnership::class]) 157 fun transferOwnership_invalidTarget_throwsException() { 158 try { 159 assertThrows(IllegalArgumentException::class.java) { 160 deviceState.dpc().devicePolicyManager().transferOwnership( 161 deviceState.dpc().componentName(), invalidComponentName, bundle 162 ) 163 } 164 } finally { 165 removeDeviceAdmin() 166 } 167 } 168 169 @ApiTest(apis = ["android.app.admin.DevicePolicyManager#transferOwnership"]) 170 @EnsureHasProfileOwner 171 @Postsubmit(reason = "new test") 172 @Test 173 fun transferOwnership_disableCamera_policyRetainedAfterTransfer() { 174 targetDeviceAdminTestAppSupportsTransferOwnership.install().use { testApp -> 175 try { 176 deviceState.dpc().devicePolicyManager().setCameraDisabled( 177 deviceState.dpc().componentName(), true 178 ) 179 deviceState.dpc().devicePolicyManager().transferOwnership( 180 deviceState.dpc().componentName(), targetAdmin, bundle 181 ) 182 assertThat(testApp.devicePolicyManager().getCameraDisabled(targetAdmin)).isTrue() 183 } finally { 184 removeDeviceAdmin() 185 } 186 } 187 } 188 189 @ApiTest(apis = ["android.app.admin.DevicePolicyManager#transferOwnership"]) 190 @Postsubmit(reason = "new test") 191 @EnsureHasProfileOwner 192 @Test 193 fun transferOwnership_profileOwner_sendsOwnerChangedBroadcast() { 194 targetDeviceAdminTestAppSupportsTransferOwnership.install().use { 195 try { 196 deviceState.registerBroadcastReceiver(ACTION_PROFILE_OWNER_CHANGED) 197 .use { receiver -> 198 deviceState.dpc().devicePolicyManager().transferOwnership( 199 deviceState.dpc().componentName(), targetAdmin, bundle 200 ) 201 assertThat(receiver.awaitForBroadcast()!!.action).isEqualTo( 202 ACTION_PROFILE_OWNER_CHANGED 203 ) 204 } 205 } finally { 206 removeDeviceAdmin() 207 } 208 } 209 } 210 211 @ApiTest(apis = ["android.app.admin.DevicePolicyManager#transferOwnership"]) 212 @Postsubmit(reason = "new test") 213 @EnsureHasDeviceOwner 214 @RequireRunOnSystemUser // Same as device owner 215 @Test 216 fun transferOwnership_deviceOwner_sendsOwnerChangedBroadcast() { 217 targetDeviceAdminTestAppSupportsTransferOwnership.install().use { 218 try { 219 deviceState.registerBroadcastReceiver(ACTION_DEVICE_OWNER_CHANGED) 220 .use { receiver -> 221 deviceState.dpc().devicePolicyManager().transferOwnership( 222 deviceState.dpc().componentName(), targetAdmin, bundle 223 ) 224 225 receiver.awaitForBroadcastOrFail() 226 } 227 } finally { 228 removeDeviceAdmin() 229 } 230 } 231 } 232 233 @ApiTest(apis = ["android.app.admin.DevicePolicyManager#transferOwnership"]) 234 @Postsubmit(reason = "new test") 235 @CanSetPolicyTest(policy = [TransferOwnership::class]) 236 fun transferOwnership_noMetadata_throwsException() { 237 targetDeviceAdminTestAppDoesNotSupportTransferOwnership.install().use { 238 assertThrows(IllegalArgumentException::class.java) { 239 deviceState.dpc().devicePolicyManager().transferOwnership( 240 deviceState.dpc().componentName(), targetAdmin, emptyBundle 241 ) 242 } 243 } 244 } 245 246 @ApiTest(apis = ["android.app.admin.DevicePolicyManager#transferOwnership"]) 247 @Postsubmit(reason = "new test") 248 @CanSetPolicyTest(policy = [TransferOwnership::class]) 249 fun transferOwnership_sameAdmin_throwsException() { 250 targetDeviceAdminTestAppSupportsTransferOwnership.install().use { 251 assertThrows(IllegalArgumentException::class.java) { 252 deviceState.dpc().devicePolicyManager().transferOwnership( 253 deviceState.dpc().componentName(), deviceState.dpc().componentName(), 254 emptyBundle 255 ) 256 } 257 } 258 } 259 260 /** 261 * Remove whichever device admin (device owner or profile owner) the test is running for. 262 */ 263 private fun removeDeviceAdmin() { 264 TestApis.devicePolicy().getDeviceOwner()?.remove() 265 TestApis.users().all().forEach { 266 TestApis.devicePolicy().getProfileOwner(it)?.remove() 267 } 268 } 269 270 @ApiTest(apis = ["android.app.admin.DeviceAdminReceiver#onTransferOwnershipCompleted"]) 271 @Postsubmit(reason = "new test") 272 @PolicyAppliesTest(policy = [TransferOwnership::class]) 273 @Test 274 fun transferOwnership_callsOnTransferOwnershipCompletedCallback() { 275 targetDeviceAdminTestAppSupportsTransferOwnership.install().use {testApp -> 276 try { 277 deviceState.dpc().devicePolicyManager().transferOwnership( 278 deviceState.dpc().componentName(), targetAdmin, bundle 279 ) 280 281 assertThat(testApp.events().transferOwnershipComplete() 282 .whereDeviceAdminReceiver().broadcastReceiver().receiverClass().className().isEqualTo( 283 targetAdmin.className) 284 .whereBundle().key(KEY).booleanValue().isEqualTo(bundle.getBoolean(KEY))).eventOccurred() 285 } finally { 286 removeDeviceAdmin() 287 } 288 } 289 } 290 291 // TODO: Add test of onTransferAffiliatedProfileOwnershipComplete 292 companion object { 293 @JvmField 294 @ClassRule 295 @Rule 296 val deviceState = DeviceState() 297 private val transferOwnershipMetadataQuery = BundleQuery.bundle().where().key( 298 "supports-transfer-ownership" 299 ).stringValue().isEqualTo("true") 300 private val targetDeviceAdminTestAppSupportsTransferOwnership = 301 deviceState.testApps().query() 302 .whereIsDeviceAdmin().isTrue() 303 .whereReceivers().contains( 304 ReceiverQuery.receiver().where().metadata().contains( 305 transferOwnershipMetadataQuery 306 ) 307 ).get() 308 private val targetDeviceAdminTestAppDoesNotSupportTransferOwnership = 309 deviceState.testApps().query() 310 .whereIsDeviceAdmin().isTrue() 311 .whereReceivers().contains( 312 ReceiverQuery.receiver().where().metadata().doesNotContain( 313 transferOwnershipMetadataQuery 314 ) 315 ).get() 316 private const val KEY = "VALUE" 317 private const val ACTION_DEVICE_OWNER_CHANGED = "android.app.action.DEVICE_OWNER_CHANGED" 318 private const val ACTION_PROFILE_OWNER_CHANGED = "android.app.action.PROFILE_OWNER_CHANGED" 319 private val bundle = PersistableBundle().apply { putBoolean(KEY, true) } 320 321 private val emptyBundle = PersistableBundle() 322 private val targetAdmin = ComponentName( 323 targetDeviceAdminTestAppSupportsTransferOwnership.packageName(), 324 targetDeviceAdminTestAppSupportsTransferOwnership.packageName() 325 + ".DeviceAdminReceiver" 326 ) 327 private val invalidComponentName = ComponentName("invalid", "invalid") 328 private val localDevicePolicyManager = 329 TestApis.context().instrumentedContext().getSystemService( 330 DevicePolicyManager::class.java 331 )!! 332 } 333 } 334