1 /* 2 * Copyright (C) 2021 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.server.pm 18 19 import android.content.Intent 20 import android.content.pm.SuspendDialogInfo 21 import android.os.Binder 22 import android.os.PersistableBundle 23 import com.android.server.testutils.any 24 import com.android.server.testutils.eq 25 import com.android.server.testutils.nullable 26 import com.google.common.truth.Truth.assertThat 27 import org.junit.Test 28 import org.junit.runner.RunWith 29 import org.junit.runners.JUnit4 30 import org.mockito.ArgumentMatchers.anyInt 31 import org.mockito.Mockito.times 32 import org.mockito.Mockito.verify 33 34 @RunWith(JUnit4::class) 35 class SuspendPackageHelperTest : PackageHelperTestBase() { 36 37 @Test 38 fun setPackagesSuspended() { 39 val targetPackages = arrayOf(TEST_PACKAGE_1, TEST_PACKAGE_2) 40 val failedNames = suspendPackageHelper.setPackagesSuspended(pms.snapshotComputer(), 41 targetPackages, true /* suspended */, null /* appExtras */, 42 null /* launcherExtras */, null /* dialogInfo */, DEVICE_OWNER_PACKAGE, 43 TEST_USER_ID, deviceOwnerUid, false /* forQuietMode */) 44 testHandler.flush() 45 46 verify(pms).scheduleWritePackageRestrictions(eq(TEST_USER_ID)) 47 verify(broadcastHelper).sendPackageBroadcast(eq(Intent.ACTION_PACKAGES_SUSPENDED), 48 nullable(), bundleCaptor.capture(), anyInt(), nullable(), nullable(), any(), 49 nullable(), nullable(), nullable(), nullable()) 50 verify(broadcastHelper).doSendBroadcast(eq(Intent.ACTION_MY_PACKAGE_SUSPENDED), nullable(), 51 nullable(), any(), eq(TEST_PACKAGE_1), nullable(), any(), any(), nullable(), 52 nullable(), nullable()) 53 verify(broadcastHelper).doSendBroadcast(eq(Intent.ACTION_MY_PACKAGE_SUSPENDED), nullable(), 54 nullable(), any(), eq(TEST_PACKAGE_2), nullable(), any(), any(), nullable(), 55 nullable(), nullable()) 56 57 var modifiedPackages = bundleCaptor.value.getStringArray(Intent.EXTRA_CHANGED_PACKAGE_LIST) 58 assertThat(modifiedPackages).asList().containsExactly(TEST_PACKAGE_1, TEST_PACKAGE_2) 59 assertThat(failedNames).isEmpty() 60 } 61 62 @Test 63 fun setPackagesSuspended_emptyPackageName() { 64 var failedNames = suspendPackageHelper.setPackagesSuspended(pms.snapshotComputer(), 65 null /* packageNames */, true /* suspended */, null /* appExtras */, 66 null /* launcherExtras */, null /* dialogInfo */, DEVICE_OWNER_PACKAGE, 67 TEST_USER_ID, deviceOwnerUid, false /* forQuietMode */) 68 69 assertThat(failedNames).isNull() 70 71 failedNames = suspendPackageHelper.setPackagesSuspended(pms.snapshotComputer(), 72 arrayOfNulls(0), true /* suspended */, null /* appExtras */, 73 null /* launcherExtras */, null /* dialogInfo */, DEVICE_OWNER_PACKAGE, 74 TEST_USER_ID, deviceOwnerUid, false /* forQuietMode */) 75 76 assertThat(failedNames).isEmpty() 77 } 78 79 @Test 80 fun setPackagesSuspended_callerIsNotAllowed() { 81 val failedNames = suspendPackageHelper.setPackagesSuspended(pms.snapshotComputer(), 82 arrayOf(TEST_PACKAGE_2), true /* suspended */, null /* appExtras */, 83 null /* launcherExtras */, null /* dialogInfo */, TEST_PACKAGE_1, TEST_USER_ID, 84 Binder.getCallingUid(), false /* forQuietMode */) 85 86 assertThat(failedNames).asList().hasSize(1) 87 assertThat(failedNames).asList().contains(TEST_PACKAGE_2) 88 } 89 90 @Test 91 fun setPackagesSuspended_callerSuspendItself() { 92 val failedNames = suspendPackageHelper.setPackagesSuspended(pms.snapshotComputer(), 93 arrayOf(DEVICE_OWNER_PACKAGE), true /* suspended */, null /* appExtras */, 94 null /* launcherExtras */, null /* dialogInfo */, DEVICE_OWNER_PACKAGE, 95 TEST_USER_ID, deviceOwnerUid, false /* forQuietMode */) 96 97 assertThat(failedNames).asList().hasSize(1) 98 assertThat(failedNames).asList().contains(DEVICE_OWNER_PACKAGE) 99 } 100 101 @Test 102 fun setPackagesSuspended_nonexistentPackage() { 103 val failedNames = suspendPackageHelper.setPackagesSuspended(pms.snapshotComputer(), 104 arrayOf(NONEXISTENT_PACKAGE), true /* suspended */, null /* appExtras */, 105 null /* launcherExtras */, null /* dialogInfo */, DEVICE_OWNER_PACKAGE, 106 TEST_USER_ID, deviceOwnerUid, false /* forQuietMode */) 107 108 assertThat(failedNames).asList().hasSize(1) 109 assertThat(failedNames).asList().contains(NONEXISTENT_PACKAGE) 110 } 111 112 @Test 113 fun setPackagesSuspended_knownPackages() { 114 val knownPackages = arrayOf(DEVICE_ADMIN_PACKAGE, DEFAULT_HOME_PACKAGE, DIALER_PACKAGE, 115 INSTALLER_PACKAGE, UNINSTALLER_PACKAGE, VERIFIER_PACKAGE, PERMISSION_CONTROLLER_PACKAGE) 116 val failedNames = suspendPackageHelper.setPackagesSuspended(pms.snapshotComputer(), 117 knownPackages, true /* suspended */, null /* appExtras */, 118 null /* launcherExtras */, null /* dialogInfo */, DEVICE_OWNER_PACKAGE, 119 TEST_USER_ID, deviceOwnerUid, false /* forQuietMode */)!! 120 121 assertThat(failedNames.size).isEqualTo(knownPackages.size) 122 for (pkg in knownPackages) { 123 assertThat(failedNames).asList().contains(pkg) 124 } 125 } 126 127 @Test 128 fun setPackagesSuspended_forQuietMode() { 129 val knownPackages = arrayOf(DEVICE_ADMIN_PACKAGE, DEFAULT_HOME_PACKAGE, DIALER_PACKAGE, 130 INSTALLER_PACKAGE, UNINSTALLER_PACKAGE, VERIFIER_PACKAGE, 131 PERMISSION_CONTROLLER_PACKAGE, MGMT_ROLE_HOLDER_PACKAGE) 132 val failedNames = suspendPackageHelper.setPackagesSuspended(pms.snapshotComputer(), 133 knownPackages, true /* suspended */, null /* appExtras */, 134 null /* launcherExtras */, null /* dialogInfo */, DEVICE_OWNER_PACKAGE, 135 TEST_USER_ID, deviceOwnerUid, true /* forQuietMode */)!! 136 137 assertThat(failedNames.size).isEqualTo(1) 138 assertThat(failedNames[0]).isEqualTo(MGMT_ROLE_HOLDER_PACKAGE) 139 } 140 141 @Test 142 fun setPackagesUnsuspended() { 143 val targetPackages = arrayOf(TEST_PACKAGE_1, TEST_PACKAGE_2) 144 var failedNames = suspendPackageHelper.setPackagesSuspended(pms.snapshotComputer(), 145 targetPackages, true /* suspended */, null /* appExtras */, 146 null /* launcherExtras */, null /* dialogInfo */, DEVICE_OWNER_PACKAGE, 147 TEST_USER_ID, deviceOwnerUid, false /* forQuietMode */) 148 testHandler.flush() 149 assertThat(failedNames).isEmpty() 150 failedNames = suspendPackageHelper.setPackagesSuspended(pms.snapshotComputer(), 151 targetPackages, false /* suspended */, null /* appExtras */, 152 null /* launcherExtras */, null /* dialogInfo */, DEVICE_OWNER_PACKAGE, 153 TEST_USER_ID, deviceOwnerUid, false /* forQuietMode */) 154 testHandler.flush() 155 156 verify(pms, times(2)).scheduleWritePackageRestrictions(eq(TEST_USER_ID)) 157 verify(broadcastHelper).sendPackageBroadcast(eq(Intent.ACTION_PACKAGES_UNSUSPENDED), 158 nullable(), bundleCaptor.capture(), anyInt(), nullable(), nullable(), any(), 159 nullable(), nullable(), nullable(), nullable()) 160 verify(broadcastHelper).doSendBroadcast(eq(Intent.ACTION_MY_PACKAGE_UNSUSPENDED), 161 nullable(), nullable(), any(), eq(TEST_PACKAGE_1), nullable(), any(), any(), 162 nullable(), nullable(), nullable()) 163 verify(broadcastHelper).doSendBroadcast(eq(Intent.ACTION_MY_PACKAGE_UNSUSPENDED), 164 nullable(), nullable(), any(), eq(TEST_PACKAGE_2), nullable(), any(), any(), 165 nullable(), nullable(), nullable()) 166 167 var modifiedPackages = bundleCaptor.value.getStringArray(Intent.EXTRA_CHANGED_PACKAGE_LIST) 168 assertThat(modifiedPackages).asList().containsExactly(TEST_PACKAGE_1, TEST_PACKAGE_2) 169 assertThat(failedNames).isEmpty() 170 } 171 172 @Test 173 fun getUnsuspendablePackagesForUser() { 174 val suspendables = arrayOf(TEST_PACKAGE_1, TEST_PACKAGE_2) 175 val unsuspendables = arrayOf(DEVICE_ADMIN_PACKAGE, DEFAULT_HOME_PACKAGE, DIALER_PACKAGE, 176 INSTALLER_PACKAGE, UNINSTALLER_PACKAGE, VERIFIER_PACKAGE, PERMISSION_CONTROLLER_PACKAGE) 177 val results = suspendPackageHelper.getUnsuspendablePackagesForUser(pms.snapshotComputer(), 178 suspendables + unsuspendables, TEST_USER_ID, deviceOwnerUid) 179 180 assertThat(results.size).isEqualTo(unsuspendables.size) 181 for (pkg in unsuspendables) { 182 assertThat(results).asList().contains(pkg) 183 } 184 } 185 186 @Test 187 fun getUnsuspendablePackagesForUser_callerIsNotAllowed() { 188 val suspendables = arrayOf(TEST_PACKAGE_1, TEST_PACKAGE_2) 189 val results = suspendPackageHelper.getUnsuspendablePackagesForUser(pms.snapshotComputer(), 190 suspendables, TEST_USER_ID, Binder.getCallingUid()) 191 192 assertThat(results.size).isEqualTo(suspendables.size) 193 for (pkg in suspendables) { 194 assertThat(results).asList().contains(pkg) 195 } 196 } 197 198 @Test 199 fun getSuspendedPackageAppExtras() { 200 val appExtras = PersistableBundle() 201 appExtras.putString(TEST_PACKAGE_1, TEST_PACKAGE_1) 202 var failedNames = suspendPackageHelper.setPackagesSuspended(pms.snapshotComputer(), 203 arrayOf(TEST_PACKAGE_1), true /* suspended */, appExtras, null /* launcherExtras */, 204 null /* dialogInfo */, DEVICE_OWNER_PACKAGE, TEST_USER_ID, deviceOwnerUid, 205 false /* forQuietMode */) 206 testHandler.flush() 207 assertThat(failedNames).isEmpty() 208 209 val result = suspendPackageHelper.getSuspendedPackageAppExtras(pms.snapshotComputer(), 210 TEST_PACKAGE_1, TEST_USER_ID, deviceOwnerUid)!! 211 212 assertThat(result.getString(TEST_PACKAGE_1)).isEqualTo(TEST_PACKAGE_1) 213 } 214 215 @Test 216 fun removeSuspensionsBySuspendingPackage() { 217 val appExtras = PersistableBundle() 218 appExtras.putString(TEST_PACKAGE_1, TEST_PACKAGE_2) 219 val targetPackages = arrayOf(TEST_PACKAGE_1, TEST_PACKAGE_2) 220 var failedNames = suspendPackageHelper.setPackagesSuspended(pms.snapshotComputer(), 221 targetPackages, true /* suspended */, appExtras, null /* launcherExtras */, 222 null /* dialogInfo */, DEVICE_OWNER_PACKAGE, TEST_USER_ID, deviceOwnerUid, 223 false /* forQuietMode */) 224 testHandler.flush() 225 assertThat(failedNames).isEmpty() 226 assertThat(suspendPackageHelper.getSuspendingPackage(pms.snapshotComputer(), 227 TEST_PACKAGE_1, TEST_USER_ID, deviceOwnerUid)).isEqualTo(DEVICE_OWNER_PACKAGE) 228 assertThat(suspendPackageHelper.getSuspendingPackage(pms.snapshotComputer(), 229 TEST_PACKAGE_2, TEST_USER_ID, deviceOwnerUid)).isEqualTo(DEVICE_OWNER_PACKAGE) 230 assertThat(suspendPackageHelper.getSuspendedPackageAppExtras(pms.snapshotComputer(), 231 TEST_PACKAGE_1, TEST_USER_ID, deviceOwnerUid)).isNotNull() 232 assertThat(suspendPackageHelper.getSuspendedPackageAppExtras(pms.snapshotComputer(), 233 TEST_PACKAGE_2, TEST_USER_ID, deviceOwnerUid)).isNotNull() 234 235 suspendPackageHelper.removeSuspensionsBySuspendingPackage(pms.snapshotComputer(), 236 targetPackages, { suspendingPackage -> suspendingPackage == DEVICE_OWNER_PACKAGE }, 237 TEST_USER_ID) 238 239 testHandler.flush() 240 verify(pms, times(2)).scheduleWritePackageRestrictions(eq(TEST_USER_ID)) 241 verify(broadcastHelper).sendPackageBroadcast(eq(Intent.ACTION_PACKAGES_UNSUSPENDED), 242 nullable(), bundleCaptor.capture(), anyInt(), nullable(), nullable(), any(), 243 nullable(), nullable(), nullable(), nullable()) 244 verify(broadcastHelper).doSendBroadcast(eq(Intent.ACTION_MY_PACKAGE_UNSUSPENDED), 245 nullable(), nullable(), any(), eq(TEST_PACKAGE_1), nullable(), any(), any(), 246 nullable(), nullable(), nullable()) 247 verify(broadcastHelper).doSendBroadcast(eq(Intent.ACTION_MY_PACKAGE_UNSUSPENDED), 248 nullable(), nullable(), any(), eq(TEST_PACKAGE_2), nullable(), any(), any(), 249 nullable(), nullable(), nullable()) 250 251 assertThat(suspendPackageHelper.getSuspendingPackage(pms.snapshotComputer(), 252 TEST_PACKAGE_1, TEST_USER_ID, deviceOwnerUid)).isNull() 253 assertThat(suspendPackageHelper.getSuspendingPackage(pms.snapshotComputer(), 254 TEST_PACKAGE_2, TEST_USER_ID, deviceOwnerUid)).isNull() 255 assertThat(suspendPackageHelper.getSuspendedPackageAppExtras(pms.snapshotComputer(), 256 TEST_PACKAGE_1, TEST_USER_ID, deviceOwnerUid)).isNull() 257 assertThat(suspendPackageHelper.getSuspendedPackageAppExtras(pms.snapshotComputer(), 258 TEST_PACKAGE_2, TEST_USER_ID, deviceOwnerUid)).isNull() 259 } 260 261 @Test 262 fun getSuspendedPackageLauncherExtras() { 263 val launcherExtras = PersistableBundle() 264 launcherExtras.putString(TEST_PACKAGE_2, TEST_PACKAGE_2) 265 var failedNames = suspendPackageHelper.setPackagesSuspended(pms.snapshotComputer(), 266 arrayOf(TEST_PACKAGE_2), true /* suspended */, null /* appExtras */, launcherExtras, 267 null /* dialogInfo */, DEVICE_OWNER_PACKAGE, TEST_USER_ID, deviceOwnerUid, 268 false /* forQuietMode */) 269 testHandler.flush() 270 assertThat(failedNames).isEmpty() 271 272 val result = suspendPackageHelper.getSuspendedPackageLauncherExtras(pms.snapshotComputer(), 273 TEST_PACKAGE_2, TEST_USER_ID, deviceOwnerUid)!! 274 275 assertThat(result.getString(TEST_PACKAGE_2)).isEqualTo(TEST_PACKAGE_2) 276 } 277 278 @Test 279 fun isPackageSuspended() { 280 var failedNames = suspendPackageHelper.setPackagesSuspended(pms.snapshotComputer(), 281 arrayOf(TEST_PACKAGE_1), true /* suspended */, null /* appExtras */, 282 null /* launcherExtras */, null /* dialogInfo */, DEVICE_OWNER_PACKAGE, 283 TEST_USER_ID, deviceOwnerUid, false /* forQuietMode */) 284 testHandler.flush() 285 assertThat(failedNames).isEmpty() 286 287 assertThat(suspendPackageHelper.isPackageSuspended(pms.snapshotComputer(), 288 TEST_PACKAGE_1, TEST_USER_ID, deviceOwnerUid)).isTrue() 289 } 290 291 @Test 292 fun getSuspendingPackage() { 293 val launcherExtras = PersistableBundle() 294 launcherExtras.putString(TEST_PACKAGE_2, TEST_PACKAGE_2) 295 var failedNames = suspendPackageHelper.setPackagesSuspended(pms.snapshotComputer(), 296 arrayOf(TEST_PACKAGE_2), true /* suspended */, null /* appExtras */, launcherExtras, 297 null /* dialogInfo */, DEVICE_OWNER_PACKAGE, TEST_USER_ID, deviceOwnerUid, 298 false /* forQuietMode */) 299 testHandler.flush() 300 assertThat(failedNames).isEmpty() 301 302 assertThat(suspendPackageHelper.getSuspendingPackage(pms.snapshotComputer(), 303 TEST_PACKAGE_2, TEST_USER_ID, deviceOwnerUid)).isEqualTo(DEVICE_OWNER_PACKAGE) 304 } 305 306 @Test 307 fun getSuspendedDialogInfo() { 308 val dialogInfo = SuspendDialogInfo.Builder() 309 .setTitle(TEST_PACKAGE_1).build() 310 var failedNames = suspendPackageHelper.setPackagesSuspended(pms.snapshotComputer(), 311 arrayOf(TEST_PACKAGE_1), true /* suspended */, null /* appExtras */, 312 null /* launcherExtras */, dialogInfo, DEVICE_OWNER_PACKAGE, TEST_USER_ID, 313 deviceOwnerUid, false /* forQuietMode */) 314 testHandler.flush() 315 assertThat(failedNames).isEmpty() 316 317 val result = suspendPackageHelper.getSuspendedDialogInfo(pms.snapshotComputer(), 318 TEST_PACKAGE_1, DEVICE_OWNER_PACKAGE, TEST_USER_ID, deviceOwnerUid)!! 319 320 assertThat(result.title).isEqualTo(TEST_PACKAGE_1) 321 } 322 323 @Test 324 @Throws(Exception::class) 325 fun sendPackagesSuspendedForUser() { 326 suspendPackageHelper.sendPackagesSuspendedForUser( 327 Intent.ACTION_PACKAGES_SUSPENDED, packagesToChange, uidsToChange, TEST_USER_ID) 328 testHandler.flush() 329 verify(broadcastHelper).sendPackageBroadcast(any(), nullable(), bundleCaptor.capture(), 330 anyInt(), nullable(), nullable(), any(), nullable(), nullable(), nullable(), 331 nullable()) 332 333 var changedPackages = bundleCaptor.value.getStringArray(Intent.EXTRA_CHANGED_PACKAGE_LIST) 334 var changedUids = bundleCaptor.value.getIntArray(Intent.EXTRA_CHANGED_UID_LIST) 335 assertThat(changedPackages).asList().containsExactly(TEST_PACKAGE_1, TEST_PACKAGE_2) 336 assertThat(changedUids).asList().containsExactly( 337 packageSetting1.appId, packageSetting2.appId) 338 } 339 340 @Test 341 @Throws(Exception::class) 342 fun sendPackagesSuspendModifiedForUser() { 343 suspendPackageHelper.sendPackagesSuspendedForUser( 344 Intent.ACTION_PACKAGES_SUSPENSION_CHANGED, packagesToChange, uidsToChange, TEST_USER_ID) 345 testHandler.flush() 346 verify(broadcastHelper).sendPackageBroadcast( 347 eq(Intent.ACTION_PACKAGES_SUSPENSION_CHANGED), nullable(), bundleCaptor.capture(), 348 anyInt(), nullable(), nullable(), any(), nullable(), nullable(), nullable(), 349 nullable()) 350 351 var modifiedPackages = bundleCaptor.value.getStringArray(Intent.EXTRA_CHANGED_PACKAGE_LIST) 352 var modifiedUids = bundleCaptor.value.getIntArray(Intent.EXTRA_CHANGED_UID_LIST) 353 assertThat(modifiedPackages).asList().containsExactly(TEST_PACKAGE_1, TEST_PACKAGE_2) 354 assertThat(modifiedUids).asList().containsExactly( 355 packageSetting1.appId, packageSetting2.appId) 356 } 357 } 358