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 static android.Manifest.permission.CONTROL_KEYGUARD; 20 import static android.Manifest.permission.MANAGE_PROFILE_AND_DEVICE_OWNERS; 21 import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_DEFAULT; 22 import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_ENABLED; 23 import static android.content.pm.PackageManager.DELETE_KEEP_DATA; 24 import static android.content.pm.PackageManager.DELETE_SUCCEEDED; 25 import static android.content.pm.PackageManager.MATCH_KNOWN_PACKAGES; 26 import static android.content.pm.PackageManager.PERMISSION_GRANTED; 27 28 import static com.android.server.pm.InstructionSets.getAppDexInstructionSets; 29 import static com.android.server.pm.PackageManagerService.DEBUG_COMPRESSION; 30 import static com.android.server.pm.PackageManagerService.DEBUG_REMOVE; 31 import static com.android.server.pm.PackageManagerService.EMPTY_INT_ARRAY; 32 import static com.android.server.pm.PackageManagerService.PACKAGE_SCHEME; 33 import static com.android.server.pm.PackageManagerService.TAG; 34 35 import android.Manifest; 36 import android.annotation.NonNull; 37 import android.annotation.Nullable; 38 import android.app.ApplicationExitInfo; 39 import android.app.ApplicationPackageManager; 40 import android.content.Intent; 41 import android.content.pm.ApplicationInfo; 42 import android.content.pm.Flags; 43 import android.content.pm.IPackageDeleteObserver2; 44 import android.content.pm.PackageInstaller; 45 import android.content.pm.PackageManager; 46 import android.content.pm.SharedLibraryInfo; 47 import android.content.pm.UserInfo; 48 import android.content.pm.UserProperties; 49 import android.content.pm.VersionedPackage; 50 import android.net.Uri; 51 import android.os.Binder; 52 import android.os.Process; 53 import android.os.RemoteException; 54 import android.os.UserHandle; 55 import android.os.UserManager; 56 import android.text.TextUtils; 57 import android.util.ArraySet; 58 import android.util.EventLog; 59 import android.util.Log; 60 import android.util.Slog; 61 import android.util.SparseArray; 62 import android.util.SparseBooleanArray; 63 64 import com.android.internal.annotations.GuardedBy; 65 import com.android.internal.util.ArrayUtils; 66 import com.android.internal.util.Preconditions; 67 import com.android.server.pm.pkg.AndroidPackage; 68 import com.android.server.pm.pkg.ArchiveState; 69 import com.android.server.pm.pkg.PackageStateInternal; 70 import com.android.server.pm.pkg.PackageUserState; 71 import com.android.server.wm.ActivityTaskManagerInternal; 72 73 import dalvik.system.VMRuntime; 74 75 /** 76 * Deletes a package. Uninstall if installed, or at least deletes the base directory if it's called 77 * from a failed installation. Fixes user state after deletion. 78 * Handles special treatments to system apps. 79 * Relies on RemovePackageHelper to clear internal data structures and remove app data. 80 */ 81 final class DeletePackageHelper { 82 private static final boolean DEBUG_CLEAN_APKS = false; 83 // ------- apps on sdcard specific code ------- 84 private static final boolean DEBUG_SD_INSTALL = false; 85 86 private final PackageManagerService mPm; 87 private final UserManagerInternal mUserManagerInternal; 88 private final RemovePackageHelper mRemovePackageHelper; 89 private final BroadcastHelper mBroadcastHelper; 90 91 // TODO(b/198166813): remove PMS dependency DeletePackageHelper(PackageManagerService pm, RemovePackageHelper removePackageHelper, BroadcastHelper broadcastHelper)92 DeletePackageHelper(PackageManagerService pm, RemovePackageHelper removePackageHelper, 93 BroadcastHelper broadcastHelper) { 94 mPm = pm; 95 mUserManagerInternal = mPm.mInjector.getUserManagerInternal(); 96 mRemovePackageHelper = removePackageHelper; 97 mBroadcastHelper = broadcastHelper; 98 } 99 100 /** 101 * This method is an internal method that could be invoked either 102 * to delete an installed package or to clean up a failed installation. 103 * After deleting an installed package, a broadcast is sent to notify any 104 * listeners that the package has been removed. For cleaning up a failed 105 * installation, the broadcast is not necessary since the package's 106 * installation wouldn't have sent the initial broadcast either 107 * The key steps in deleting a package are 108 * deleting the package information in internal structures like mPackages, 109 * deleting the packages base directories through installd 110 * updating mSettings to reflect current status 111 * persisting settings for later use 112 * sending a broadcast if necessary 113 * 114 * @param removedBySystem A boolean to indicate the package was removed automatically without 115 * the user-initiated action. 116 */ deletePackageX(String packageName, long versionCode, int userId, int deleteFlags, boolean removedBySystem)117 public int deletePackageX(String packageName, long versionCode, int userId, int deleteFlags, 118 boolean removedBySystem) { 119 final PackageRemovedInfo info = new PackageRemovedInfo(); 120 final boolean res; 121 122 final int removeUser = (deleteFlags & PackageManager.DELETE_ALL_USERS) != 0 123 ? UserHandle.USER_ALL : userId; 124 125 final PackageSetting uninstalledPs; 126 final PackageSetting disabledSystemPs; 127 final AndroidPackage pkg; 128 129 // for the uninstall-updates case and restricted profiles, remember the per- 130 // user handle installed state 131 int[] allUsers; 132 final int freezeUser; 133 final SparseArray<TempUserState> priorUserStates; 134 135 final boolean isInstallerPackage; 136 /** enabled state of the uninstalled application */ 137 synchronized (mPm.mLock) { 138 final Computer computer = mPm.snapshotComputer(); 139 uninstalledPs = mPm.mSettings.getPackageLPr(packageName); 140 if (uninstalledPs == null) { 141 Slog.w(TAG, "Not removing non-existent package " + packageName); 142 return PackageManager.DELETE_FAILED_INTERNAL_ERROR; 143 } 144 145 if (versionCode != PackageManager.VERSION_CODE_HIGHEST 146 && uninstalledPs.getVersionCode() != versionCode) { 147 Slog.w(TAG, "Not removing package " + packageName + " with versionCode " 148 + uninstalledPs.getVersionCode() + " != " + versionCode); 149 return PackageManager.DELETE_FAILED_INTERNAL_ERROR; 150 } 151 152 if (PackageManagerServiceUtils.isUpdatedSystemApp(uninstalledPs) 153 && ((deleteFlags & PackageManager.DELETE_SYSTEM_APP) == 0)) { 154 UserInfo userInfo = mUserManagerInternal.getUserInfo(userId); 155 if (userInfo == null || (!userInfo.isAdmin() && !mUserManagerInternal.getUserInfo( 156 mUserManagerInternal.getProfileParentId(userId)).isAdmin())) { 157 Slog.w(TAG, "Not removing package " + packageName 158 + " as only admin user (or their profile) may downgrade system apps"); 159 EventLog.writeEvent(0x534e4554, "170646036", -1, packageName); 160 return PackageManager.DELETE_FAILED_USER_RESTRICTED; 161 } 162 } 163 164 disabledSystemPs = mPm.mSettings.getDisabledSystemPkgLPr(packageName); 165 // Static shared libs can be declared by any package, so let us not 166 // allow removing a package if it provides a lib others depend on. 167 pkg = mPm.mPackages.get(packageName); 168 169 allUsers = mUserManagerInternal.getUserIds(); 170 171 if (pkg != null) { 172 SharedLibraryInfo libraryInfo = null; 173 if (pkg.getStaticSharedLibraryName() != null) { 174 libraryInfo = computer.getSharedLibraryInfo(pkg.getStaticSharedLibraryName(), 175 pkg.getStaticSharedLibraryVersion()); 176 } else if (pkg.getSdkLibraryName() != null) { 177 libraryInfo = computer.getSharedLibraryInfo(pkg.getSdkLibraryName(), 178 pkg.getSdkLibVersionMajor()); 179 } 180 181 if (libraryInfo != null) { 182 boolean flagSdkLibIndependence = Flags.sdkLibIndependence(); 183 for (int currUserId : allUsers) { 184 if (removeUser != UserHandle.USER_ALL && removeUser != currUserId) { 185 continue; 186 } 187 var libClientPackagesPair = computer.getPackagesUsingSharedLibrary( 188 libraryInfo, MATCH_KNOWN_PACKAGES, Process.SYSTEM_UID, currUserId); 189 var libClientPackages = libClientPackagesPair.first; 190 var libClientOptional = libClientPackagesPair.second; 191 // We by default don't allow removing a package if the host lib is still be 192 // used by other client packages 193 boolean allowLibIndependence = false; 194 // Only when the sdkLibIndependence flag is enabled we will respect the 195 // "optional" attr in uses-sdk-library. Only allow to remove sdk-lib host 196 // package if no required clients depend on it 197 if ((pkg.getSdkLibraryName() != null) 198 && !ArrayUtils.isEmpty(libClientPackages) 199 && !ArrayUtils.isEmpty(libClientOptional) 200 && (libClientPackages.size() == libClientOptional.size()) 201 && flagSdkLibIndependence) { 202 allowLibIndependence = true; 203 for (int i = 0; i < libClientPackages.size(); i++) { 204 boolean usesSdkLibOptional = libClientOptional.get(i); 205 if (!usesSdkLibOptional) { 206 allowLibIndependence = false; 207 break; 208 } 209 } 210 } 211 if (!ArrayUtils.isEmpty(libClientPackages) && !allowLibIndependence) { 212 Slog.w(TAG, "Not removing package " + pkg.getManifestPackageName() 213 + " hosting lib " + libraryInfo.getName() + " version " 214 + libraryInfo.getLongVersion() + " used by " + libClientPackages 215 + " for user " + currUserId); 216 return PackageManager.DELETE_FAILED_USED_SHARED_LIBRARY; 217 } 218 } 219 } 220 } 221 222 info.mOrigUsers = uninstalledPs.queryInstalledUsers(allUsers, true); 223 224 if (PackageManagerServiceUtils.isUpdatedSystemApp(uninstalledPs) 225 && ((deleteFlags & PackageManager.DELETE_SYSTEM_APP) == 0)) { 226 // We're downgrading a system app, which will apply to all users, so 227 // freeze them all during the downgrade 228 freezeUser = UserHandle.USER_ALL; 229 priorUserStates = new SparseArray<>(); 230 for (int i = 0; i < allUsers.length; i++) { 231 PackageUserState userState = uninstalledPs.readUserState(allUsers[i]); 232 priorUserStates.put(allUsers[i], 233 new TempUserState(userState.getEnabledState(), 234 userState.getLastDisableAppCaller(), userState.isInstalled())); 235 } 236 } else { 237 freezeUser = removeUser; 238 priorUserStates = null; 239 } 240 241 isInstallerPackage = mPm.mSettings.isInstallerPackage(packageName); 242 } 243 244 try (PackageManagerTracedLock installLock = mPm.mInstallLock.acquireLock()) { 245 if (DEBUG_REMOVE) Slog.d(TAG, "deletePackageX: pkg=" + packageName + " user=" + userId); 246 try (PackageFreezer freezer = mPm.freezePackageForDelete(packageName, freezeUser, 247 deleteFlags, "deletePackageX", ApplicationExitInfo.REASON_OTHER)) { 248 res = deletePackageLIF(packageName, UserHandle.of(removeUser), true, allUsers, 249 deleteFlags | PackageManager.DELETE_CHATTY, info, true); 250 } 251 if (res && pkg != null) { 252 final boolean packageInstalledForSomeUsers; 253 synchronized (mPm.mLock) { 254 packageInstalledForSomeUsers = mPm.mPackages.get(pkg.getPackageName()) != null; 255 } 256 mPm.mInstantAppRegistry.onPackageUninstalled(pkg, uninstalledPs, 257 info.mRemovedUsers, packageInstalledForSomeUsers); 258 } 259 synchronized (mPm.mLock) { 260 if (res) { 261 mPm.updateSequenceNumberLP(uninstalledPs, info.mRemovedUsers); 262 mPm.updateInstantAppInstallerLocked(packageName); 263 } 264 } 265 ApplicationPackageManager.invalidateGetPackagesForUidCache(); 266 } 267 268 if (res) { 269 final boolean killApp = (deleteFlags & PackageManager.DELETE_DONT_KILL_APP) == 0; 270 final boolean isArchived = (deleteFlags & PackageManager.DELETE_ARCHIVE) != 0; 271 mBroadcastHelper.sendPackageRemovedBroadcasts(info, mPm, killApp, 272 removedBySystem, isArchived); 273 mBroadcastHelper.sendSystemPackageUpdatedBroadcasts(info); 274 PackageMetrics.onUninstallSucceeded(info, deleteFlags, removeUser); 275 } 276 277 // Force a gc to clear up things. 278 // Ask for a background one, it's fine to go on and not block here. 279 VMRuntime.getRuntime().requestConcurrentGC(); 280 281 // Delete the resources here after sending the broadcast to let 282 // other processes clean up before deleting resources. 283 try (PackageManagerTracedLock installLock = mPm.mInstallLock.acquireLock()) { 284 if (info.mArgs != null) { 285 mRemovePackageHelper.cleanUpResources(info.mArgs.getPackageName(), 286 info.mArgs.getCodeFile(), info.mArgs.getInstructionSets()); 287 } 288 289 boolean reEnableStub = false; 290 291 if (priorUserStates != null) { 292 synchronized (mPm.mLock) { 293 PackageSetting pkgSetting = mPm.getPackageSettingForMutation(packageName); 294 if (pkgSetting != null) { 295 AndroidPackage aPkg = pkgSetting.getPkg(); 296 boolean pkgEnabled = aPkg != null && aPkg.isEnabled(); 297 for (int i = 0; i < allUsers.length; i++) { 298 TempUserState priorUserState = priorUserStates.get(allUsers[i]); 299 int enabledState = priorUserState.enabledState; 300 pkgSetting.setEnabled(enabledState, allUsers[i], 301 priorUserState.lastDisableAppCaller); 302 if (!reEnableStub && priorUserState.installed 303 && ( 304 (enabledState == COMPONENT_ENABLED_STATE_DEFAULT && pkgEnabled) 305 || enabledState == COMPONENT_ENABLED_STATE_ENABLED)) { 306 reEnableStub = true; 307 } 308 } 309 } else { 310 // This should not happen. If priorUserStates != null, we are uninstalling 311 // an update of a system app. In that case, mPm.mSettings.getPackageLpr() 312 // should return a non-null value for the target packageName because 313 // restoreDisabledSystemPackageLIF() is called during deletePackageLIF(). 314 Slog.w(TAG, "Missing PackageSetting after uninstalling the update for" 315 + " system app: " + packageName + ". This should not happen."); 316 } 317 mPm.mSettings.writeAllUsersPackageRestrictionsLPr(); 318 } 319 } 320 321 final AndroidPackage stubPkg = 322 (disabledSystemPs == null) ? null : disabledSystemPs.getPkg(); 323 if (stubPkg != null && stubPkg.isStub()) { 324 final PackageSetting stubPs; 325 synchronized (mPm.mLock) { 326 stubPs = mPm.mSettings.getPackageLPr(stubPkg.getPackageName()); 327 } 328 329 if (stubPs != null) { 330 if (reEnableStub) { 331 if (DEBUG_COMPRESSION) { 332 Slog.i(TAG, "Enabling system stub after removal; pkg: " 333 + stubPkg.getPackageName()); 334 } 335 mPm.enableCompressedPackage(stubPkg, stubPs); 336 } else if (DEBUG_COMPRESSION) { 337 Slog.i(TAG, "System stub disabled for all users, leaving uncompressed " 338 + "after removal; pkg: " + stubPkg.getPackageName()); 339 } 340 } 341 } 342 } 343 344 if (res && isInstallerPackage) { 345 final PackageInstallerService packageInstallerService = 346 mPm.mInjector.getPackageInstallerService(); 347 packageInstallerService.onInstallerPackageDeleted(uninstalledPs.getAppId(), removeUser); 348 } 349 350 return res ? DELETE_SUCCEEDED : PackageManager.DELETE_FAILED_INTERNAL_ERROR; 351 } 352 353 /** Deletes dexopt artifacts for the given package*/ deleteArtDexoptArtifacts(String packageName)354 private void deleteArtDexoptArtifacts(String packageName) { 355 try (PackageManagerLocal.FilteredSnapshot filteredSnapshot = 356 PackageManagerServiceUtils.getPackageManagerLocal() 357 .withFilteredSnapshot()) { 358 try { 359 DexOptHelper.getArtManagerLocal().deleteDexoptArtifacts( 360 filteredSnapshot, packageName); 361 } catch (IllegalArgumentException | IllegalStateException e) { 362 Slog.w(TAG, e.toString()); 363 } 364 } 365 } 366 367 /* 368 * This method handles package deletion in general 369 */ 370 @GuardedBy("mPm.mInstallLock") deletePackageLIF(@onNull String packageName, UserHandle user, boolean deleteCodeAndResources, @NonNull int[] allUserHandles, int flags, @NonNull PackageRemovedInfo outInfo, boolean writeSettings)371 public boolean deletePackageLIF(@NonNull String packageName, UserHandle user, 372 boolean deleteCodeAndResources, @NonNull int[] allUserHandles, int flags, 373 @NonNull PackageRemovedInfo outInfo, boolean writeSettings) { 374 final DeletePackageAction action; 375 synchronized (mPm.mLock) { 376 final PackageSetting ps = mPm.mSettings.getPackageLPr(packageName); 377 if (ps == null) { 378 if (DEBUG_REMOVE) { 379 Slog.d(TAG, "Attempted to remove non-existent package " + packageName); 380 } 381 return false; 382 } 383 final PackageSetting disabledPs = mPm.mSettings.getDisabledSystemPkgLPr(ps); 384 if (PackageManagerServiceUtils.isSystemApp(ps) 385 && mPm.checkPermission(CONTROL_KEYGUARD, packageName, UserHandle.USER_SYSTEM) 386 == PERMISSION_GRANTED) { 387 Slog.w(TAG, "Attempt to delete keyguard system package " + packageName); 388 return false; 389 } 390 action = mayDeletePackageLocked(outInfo, ps, disabledPs, flags, user); 391 } 392 if (DEBUG_REMOVE) Slog.d(TAG, "deletePackageLI: " + packageName + " user " + user); 393 if (null == action) { 394 if (DEBUG_REMOVE) Slog.d(TAG, "deletePackageLI: action was null"); 395 return false; 396 } 397 398 try { 399 executeDeletePackageLIF(action, packageName, deleteCodeAndResources, 400 allUserHandles, writeSettings); 401 } catch (SystemDeleteException e) { 402 if (DEBUG_REMOVE) Slog.d(TAG, "deletePackageLI: system deletion failure", e); 403 return false; 404 } 405 return true; 406 } 407 408 /** 409 * @return a {@link DeletePackageAction} if the provided package and related state may be 410 * deleted, {@code null} otherwise. 411 */ 412 @Nullable mayDeletePackageLocked(@onNull PackageRemovedInfo outInfo, PackageSetting ps, @Nullable PackageSetting disabledPs, int flags, UserHandle user)413 public static DeletePackageAction mayDeletePackageLocked(@NonNull PackageRemovedInfo outInfo, 414 PackageSetting ps, @Nullable PackageSetting disabledPs, 415 int flags, UserHandle user) { 416 if (ps == null) { 417 return null; 418 } 419 if (PackageManagerServiceUtils.isSystemApp(ps)) { 420 final boolean deleteSystem = (flags & PackageManager.DELETE_SYSTEM_APP) != 0; 421 final boolean deleteAllUsers = 422 user == null || user.getIdentifier() == UserHandle.USER_ALL; 423 if ((!deleteSystem || deleteAllUsers) && disabledPs == null) { 424 Slog.w(TAG, "Attempt to delete unknown system package " 425 + ps.getPkg().getPackageName()); 426 return null; 427 } 428 // Confirmed if the system package has been updated 429 // An updated system app can be deleted. This will also have to restore 430 // the system pkg from system partition reader 431 } 432 return new DeletePackageAction(ps, disabledPs, outInfo, flags, user); 433 } 434 executeDeletePackage(DeletePackageAction action, String packageName, boolean deleteCodeAndResources, @NonNull int[] allUserHandles, boolean writeSettings)435 public void executeDeletePackage(DeletePackageAction action, String packageName, 436 boolean deleteCodeAndResources, @NonNull int[] allUserHandles, boolean writeSettings) 437 throws SystemDeleteException { 438 try (PackageManagerTracedLock installLock = mPm.mInstallLock.acquireLock()) { 439 executeDeletePackageLIF(action, packageName, deleteCodeAndResources, allUserHandles, 440 writeSettings); 441 } 442 } 443 444 /** Deletes a package. Only throws when install of a disabled package fails. */ 445 @GuardedBy("mPm.mInstallLock") executeDeletePackageLIF(DeletePackageAction action, String packageName, boolean deleteCodeAndResources, @NonNull int[] allUserHandles, boolean writeSettings)446 private void executeDeletePackageLIF(DeletePackageAction action, 447 String packageName, boolean deleteCodeAndResources, 448 @NonNull int[] allUserHandles, boolean writeSettings) throws SystemDeleteException { 449 final PackageSetting ps = action.mDeletingPs; 450 final PackageRemovedInfo outInfo = action.mRemovedInfo; 451 final UserHandle user = action.mUser; 452 final int flags = action.mFlags; 453 final boolean systemApp = PackageManagerServiceUtils.isSystemApp(ps); 454 455 // We need to get the permission state before package state is (potentially) destroyed. 456 final SparseBooleanArray hadSuspendAppsPermission = new SparseBooleanArray(); 457 for (int userId : allUserHandles) { 458 hadSuspendAppsPermission.put(userId, mPm.checkPermission( 459 Manifest.permission.SUSPEND_APPS, packageName, userId) == PERMISSION_GRANTED); 460 } 461 462 final int userId = user == null ? UserHandle.USER_ALL : user.getIdentifier(); 463 // Remember which users are affected, before the installed states are modified 464 outInfo.mRemovedUsers = userId == UserHandle.USER_ALL 465 ? ps.queryUsersInstalledOrHasData(allUserHandles) 466 : new int[]{userId}; 467 outInfo.populateBroadcastUsers(ps); 468 outInfo.mDataRemoved = (flags & PackageManager.DELETE_KEEP_DATA) == 0; 469 outInfo.mRemovedPackage = ps.getPackageName(); 470 outInfo.mInstallerPackageName = ps.getInstallSource().mInstallerPackageName; 471 outInfo.mIsStaticSharedLib = 472 ps.getPkg() != null && ps.getPkg().getStaticSharedLibraryName() != null; 473 outInfo.mIsExternal = ps.isExternalStorage(); 474 outInfo.mRemovedPackageVersionCode = ps.getVersionCode(); 475 476 if ((!systemApp || (flags & PackageManager.DELETE_SYSTEM_APP) != 0) 477 && userId != UserHandle.USER_ALL) { 478 // The caller is asking that the package only be deleted for a single 479 // user. To do this, we just mark its uninstalled state and delete 480 // its data. If this is a system app, we only allow this to happen if 481 // they have set the special DELETE_SYSTEM_APP which requests different 482 // semantics than normal for uninstalling system apps. 483 final boolean clearPackageStateAndReturn; 484 synchronized (mPm.mLock) { 485 markPackageUninstalledForUserLPw(ps, user, flags); 486 if (!systemApp) { 487 // Do not uninstall the APK if an app should be cached 488 boolean keepUninstalledPackage = 489 mPm.shouldKeepUninstalledPackageLPr(packageName); 490 if (ps.isInstalledOnAnyOtherUser( 491 mUserManagerInternal.getUserIds(), userId) || keepUninstalledPackage) { 492 // Other users still have this package installed, so all 493 // we need to do is clear this user's data and save that 494 // it is uninstalled. 495 if (DEBUG_REMOVE) Slog.d(TAG, "Still installed by other users"); 496 clearPackageStateAndReturn = true; 497 } else { 498 if (DEBUG_REMOVE) Slog.d(TAG, "Not installed by other users, full delete"); 499 mPm.mSettings.writeKernelMappingLPr(ps); 500 clearPackageStateAndReturn = false; 501 } 502 } else { 503 // This is a system app, so we assume that the 504 // other users still have this package installed, so all 505 // we need to do is clear this user's data and save that 506 // it is uninstalled. 507 if (DEBUG_REMOVE) Slog.d(TAG, "Deleting system app"); 508 clearPackageStateAndReturn = true; 509 } 510 } 511 if (clearPackageStateAndReturn) { 512 mRemovePackageHelper.clearPackageStateForUserLIF(ps, userId, flags); 513 // Legacy behavior to report appId as UID here. 514 // The final broadcasts will contain a per-user UID. 515 outInfo.mUid = ps.getAppId(); 516 // Only send Intent.ACTION_UID_REMOVED when flag & DELETE_KEEP_DATA is 0 517 // i.e. the mDataRemoved is true 518 if (outInfo.mDataRemoved) { 519 outInfo.mIsAppIdRemoved = true; 520 } 521 mPm.scheduleWritePackageRestrictions(user); 522 return; 523 } 524 } 525 526 // TODO(b/109941548): break reasons for ret = false out into mayDelete method 527 if (systemApp) { 528 if (DEBUG_REMOVE) Slog.d(TAG, "Removing system package: " + ps.getPackageName()); 529 // When an updated system application is deleted we delete the existing resources 530 // as well and fall back to existing code in system partition 531 deleteInstalledSystemPackage(action, allUserHandles, writeSettings); 532 mPm.restoreDisabledSystemPackageLIF(action, allUserHandles, writeSettings); 533 } else { 534 if (DEBUG_REMOVE) Slog.d(TAG, "Removing non-system package: " + ps.getPackageName()); 535 if (ps.isIncremental()) { 536 // Explicitly delete dexopt artifacts for incremental app because the 537 // artifacts are not stored in the same directory as the APKs 538 deleteArtDexoptArtifacts(packageName); 539 } 540 deleteInstalledPackageLIF(ps, userId, deleteCodeAndResources, flags, allUserHandles, 541 outInfo, writeSettings); 542 } 543 544 // If the package removed had SUSPEND_APPS, unset any restrictions that might have been in 545 // place for all affected users. 546 final Computer snapshot = mPm.snapshotComputer(); 547 for (final int affectedUserId : outInfo.mRemovedUsers) { 548 if (hadSuspendAppsPermission.get(affectedUserId)) { 549 mPm.unsuspendForSuspendingPackage(snapshot, packageName, 550 affectedUserId /*suspendingUserId*/, true /*inAllUsers*/); 551 mPm.removeAllDistractingPackageRestrictions(snapshot, affectedUserId); 552 } 553 } 554 555 // Take a note whether we deleted the package for all users 556 synchronized (mPm.mLock) { 557 outInfo.mRemovedForAllUsers = mPm.mPackages.get(ps.getPackageName()) == null; 558 } 559 } 560 561 @GuardedBy("mPm.mInstallLock") deleteInstalledPackageLIF(PackageSetting ps, int userId, boolean deleteCodeAndResources, int flags, @NonNull int[] allUserHandles, @NonNull PackageRemovedInfo outInfo, boolean writeSettings)562 private void deleteInstalledPackageLIF(PackageSetting ps, int userId, 563 boolean deleteCodeAndResources, int flags, @NonNull int[] allUserHandles, 564 @NonNull PackageRemovedInfo outInfo, boolean writeSettings) { 565 synchronized (mPm.mLock) { 566 // Since the package is being deleted in all users, report appId as the uid 567 outInfo.mUid = ps.getAppId(); 568 outInfo.mBroadcastAllowList = mPm.mAppsFilter.getVisibilityAllowList( 569 mPm.snapshotComputer(), ps, allUserHandles, 570 mPm.mSettings.getPackagesLocked()); 571 } 572 573 // Delete package data from internal structures and also remove data if flag is set 574 mRemovePackageHelper.removePackageDataLIF( 575 ps, userId, allUserHandles, outInfo, flags, writeSettings); 576 577 // Delete application code and resources only for parent packages 578 if (deleteCodeAndResources) { 579 outInfo.mArgs = new CleanUpArgs(ps.getName(), 580 ps.getPathString(), getAppDexInstructionSets( 581 ps.getPrimaryCpuAbiLegacy(), ps.getSecondaryCpuAbiLegacy())); 582 if (DEBUG_SD_INSTALL) Slog.i(TAG, "args=" + outInfo.mArgs); 583 } 584 } 585 586 @GuardedBy("mPm.mLock") markPackageUninstalledForUserLPw(PackageSetting ps, UserHandle user, int flags)587 private void markPackageUninstalledForUserLPw(PackageSetting ps, UserHandle user, int flags) { 588 final int[] userIds = (user == null || user.getIdentifier() == UserHandle.USER_ALL) 589 ? mUserManagerInternal.getUserIds() 590 : new int[] {user.getIdentifier()}; 591 for (int nextUserId : userIds) { 592 if (DEBUG_REMOVE) { 593 Slog.d(TAG, "Marking package:" + ps.getPackageName() 594 + " uninstalled for user:" + nextUserId); 595 } 596 597 // Keep enabled and disabled components in case of DELETE_KEEP_DATA 598 ArraySet<String> enabledComponents = null; 599 ArraySet<String> disabledComponents = null; 600 if ((flags & PackageManager.DELETE_KEEP_DATA) != 0) { 601 enabledComponents = new ArraySet<String>( 602 ps.readUserState(nextUserId).getEnabledComponents()); 603 disabledComponents = new ArraySet<String>( 604 ps.readUserState(nextUserId).getDisabledComponents()); 605 } 606 607 // Preserve ArchiveState if this is not a full uninstall 608 ArchiveState archiveState = 609 (flags & DELETE_KEEP_DATA) == 0 610 ? null 611 : ps.getUserStateOrDefault(nextUserId).getArchiveState(); 612 613 // Preserve firstInstallTime in case of DELETE_KEEP_DATA 614 // For full uninstalls, reset firstInstallTime to 0 as if it has never been installed 615 final long firstInstallTime = (flags & DELETE_KEEP_DATA) == 0 616 ? 0 617 : ps.getUserStateOrDefault(nextUserId).getFirstInstallTimeMillis(); 618 619 ps.setUserState(nextUserId, 620 ps.getCeDataInode(nextUserId), 621 ps.getDeDataInode(nextUserId), 622 COMPONENT_ENABLED_STATE_DEFAULT, 623 false /*installed*/, 624 true /*stopped*/, 625 true /*notLaunched*/, 626 false /*hidden*/, 627 0 /*distractionFlags*/, 628 null /*suspendParams*/, 629 false /*instantApp*/, 630 false /*virtualPreload*/, 631 null /*lastDisableAppCaller*/, 632 enabledComponents, 633 disabledComponents, 634 PackageManager.INSTALL_REASON_UNKNOWN, 635 PackageManager.UNINSTALL_REASON_UNKNOWN, 636 null /*harmfulAppWarning*/, 637 null /*splashScreenTheme*/, 638 firstInstallTime, 639 PackageManager.USER_MIN_ASPECT_RATIO_UNSET, 640 archiveState); 641 } 642 mPm.mSettings.writeKernelMappingLPr(ps); 643 } 644 deleteInstalledSystemPackage(DeletePackageAction action, @NonNull int[] allUserHandles, boolean writeSettings)645 private void deleteInstalledSystemPackage(DeletePackageAction action, 646 @NonNull int[] allUserHandles, boolean writeSettings) { 647 int flags = action.mFlags; 648 final PackageSetting deletedPs = action.mDeletingPs; 649 final PackageRemovedInfo outInfo = action.mRemovedInfo; 650 final boolean applyUserRestrictions = outInfo.mOrigUsers != null; 651 final AndroidPackage deletedPkg = deletedPs.getPkg(); 652 // Confirm if the system package has been updated 653 // An updated system app can be deleted. This will also have to restore 654 // the system pkg from system partition 655 // reader 656 final PackageSetting disabledPs = action.mDisabledPs; 657 if (DEBUG_REMOVE) { 658 Slog.d(TAG, "deleteSystemPackageLI: newPs=" + deletedPkg.getPackageName() 659 + " disabledPs=" + disabledPs); 660 } 661 Slog.d(TAG, "Deleting system pkg from data partition"); 662 663 if (DEBUG_REMOVE) { 664 if (applyUserRestrictions) { 665 Slog.d(TAG, "Remembering install states:"); 666 for (int userId : allUserHandles) { 667 final boolean finstalled = ArrayUtils.contains(outInfo.mOrigUsers, userId); 668 Slog.d(TAG, " u=" + userId + " inst=" + finstalled); 669 } 670 } 671 } 672 673 // Delete the updated package 674 outInfo.mIsRemovedPackageSystemUpdate = true; 675 676 if (disabledPs.getVersionCode() < deletedPs.getVersionCode() 677 || disabledPs.getAppId() != deletedPs.getAppId()) { 678 // Delete data for downgrades, or when the system app changed appId 679 flags &= ~PackageManager.DELETE_KEEP_DATA; 680 } else { 681 // Preserve data by setting flag 682 flags |= PackageManager.DELETE_KEEP_DATA; 683 } 684 try (PackageManagerTracedLock installLock = mPm.mInstallLock.acquireLock()) { 685 deleteInstalledPackageLIF(deletedPs, UserHandle.USER_ALL, true, flags, allUserHandles, 686 outInfo, writeSettings); 687 } 688 } 689 deletePackageVersionedInternal(VersionedPackage versionedPackage, final IPackageDeleteObserver2 observer, final int userId, final int deleteFlags, final boolean allowSilentUninstall)690 public void deletePackageVersionedInternal(VersionedPackage versionedPackage, 691 final IPackageDeleteObserver2 observer, final int userId, final int deleteFlags, 692 final boolean allowSilentUninstall) { 693 final int callingUid = Binder.getCallingUid(); 694 mPm.mContext.enforceCallingOrSelfPermission( 695 android.Manifest.permission.DELETE_PACKAGES, null); 696 final Computer snapshot = mPm.snapshotComputer(); 697 final boolean canViewInstantApps = snapshot.canViewInstantApps(callingUid, userId); 698 Preconditions.checkNotNull(versionedPackage); 699 Preconditions.checkNotNull(observer); 700 Preconditions.checkArgumentInRange(versionedPackage.getLongVersionCode(), 701 PackageManager.VERSION_CODE_HIGHEST, 702 Long.MAX_VALUE, "versionCode must be >= -1"); 703 704 final String packageName = versionedPackage.getPackageName(); 705 final long versionCode = versionedPackage.getLongVersionCode(); 706 707 try { 708 if (mPm.mInjector.getLocalService(ActivityTaskManagerInternal.class) 709 .isBaseOfLockedTask(packageName)) { 710 observer.onPackageDeleted( 711 packageName, PackageManager.DELETE_FAILED_APP_PINNED, null); 712 EventLog.writeEvent(0x534e4554, "127605586", -1, ""); 713 return; 714 } 715 } catch (RemoteException e) { 716 e.rethrowFromSystemServer(); 717 } 718 719 // Normalize package name to handle renamed packages and static libs 720 final String internalPackageName = 721 snapshot.resolveInternalPackageName(packageName, versionCode); 722 723 final int uid = Binder.getCallingUid(); 724 if (!isOrphaned(snapshot, internalPackageName) 725 && !allowSilentUninstall 726 && !isCallerAllowedToSilentlyUninstall( 727 snapshot, uid, internalPackageName, userId)) { 728 mPm.mHandler.post(() -> { 729 try { 730 final Intent intent = new Intent(Intent.ACTION_UNINSTALL_PACKAGE); 731 intent.setData(Uri.fromParts(PACKAGE_SCHEME, packageName, null)); 732 intent.putExtra(PackageInstaller.EXTRA_CALLBACK, observer.asBinder()); 733 observer.onUserActionRequired(intent); 734 } catch (RemoteException re) { 735 } 736 }); 737 return; 738 } 739 final boolean deleteAllUsers = (deleteFlags & PackageManager.DELETE_ALL_USERS) != 0; 740 final int[] users = deleteAllUsers ? mUserManagerInternal.getUserIds() : new int[]{userId}; 741 if (UserHandle.getUserId(uid) != userId || (deleteAllUsers && users.length > 1)) { 742 mPm.mContext.enforceCallingOrSelfPermission( 743 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, 744 "deletePackage for user " + userId); 745 } 746 747 final long token = Binder.clearCallingIdentity(); 748 try { 749 // If a package is device admin, or is data protected for any user, it should not be 750 // uninstalled from that user, or from any users if DELETE_ALL_USERS flag is passed. 751 for (int user : users) { 752 if (mPm.isPackageDeviceAdmin(packageName, user)) { 753 mPm.mHandler.post(() -> { 754 try { 755 Slog.w(TAG, "Not removing package " + packageName 756 + ": has active device admin"); 757 observer.onPackageDeleted(packageName, 758 PackageManager.DELETE_FAILED_DEVICE_POLICY_MANAGER, null); 759 } catch (RemoteException e) { 760 // no-op 761 } 762 }); 763 return; 764 } 765 if (mPm.mProtectedPackages.isPackageDataProtected(user, packageName)) { 766 mPm.mHandler.post(() -> { 767 try { 768 Slog.w(TAG, "Attempted to delete protected package: " + packageName); 769 observer.onPackageDeleted(packageName, 770 PackageManager.DELETE_FAILED_INTERNAL_ERROR, null); 771 } catch (RemoteException re) { 772 // no-op 773 } 774 }); 775 return; 776 } 777 } 778 } finally { 779 Binder.restoreCallingIdentity(token); 780 } 781 782 if (mPm.isUserRestricted(userId, UserManager.DISALLOW_UNINSTALL_APPS)) { 783 mPm.mHandler.post(() -> { 784 try { 785 observer.onPackageDeleted(packageName, 786 PackageManager.DELETE_FAILED_USER_RESTRICTED, null); 787 } catch (RemoteException re) { 788 } 789 }); 790 return; 791 } 792 793 if (!deleteAllUsers && snapshot.getBlockUninstallForUser(internalPackageName, userId)) { 794 mPm.mHandler.post(() -> { 795 try { 796 observer.onPackageDeleted(packageName, 797 PackageManager.DELETE_FAILED_OWNER_BLOCKED, null); 798 } catch (RemoteException re) { 799 } 800 }); 801 return; 802 } 803 804 if (DEBUG_REMOVE) { 805 Slog.d(TAG, "deletePackageAsUser: pkg=" + internalPackageName + " user=" + userId 806 + " deleteAllUsers: " + deleteAllUsers + " version=" 807 + (versionCode == PackageManager.VERSION_CODE_HIGHEST 808 ? "VERSION_CODE_HIGHEST" : versionCode)); 809 } 810 // Queue up an async operation since the package deletion may take a little while. 811 mPm.mHandler.post(() -> { 812 int returnCode; 813 final Computer innerSnapshot = mPm.snapshotComputer(); 814 final PackageStateInternal packageState = 815 innerSnapshot.getPackageStateInternal(internalPackageName); 816 boolean doDeletePackage = true; 817 if (packageState != null) { 818 final boolean targetIsInstantApp = 819 packageState.getUserStateOrDefault(UserHandle.getUserId(callingUid)) 820 .isInstantApp(); 821 doDeletePackage = !targetIsInstantApp 822 || canViewInstantApps; 823 } 824 if (doDeletePackage) { 825 if (!deleteAllUsers) { 826 returnCode = deletePackageX(internalPackageName, versionCode, 827 userId, deleteFlags, false /*removedBySystem*/); 828 829 // Delete package in child only if successfully deleted in parent. 830 if (returnCode == DELETE_SUCCEEDED && packageState != null) { 831 // Get a list of child user profiles and delete if package is 832 // present in that profile. 833 int[] childUserIds = mUserManagerInternal.getProfileIds(userId, true); 834 int returnCodeOfChild; 835 for (int childId : childUserIds) { 836 if (childId == userId) continue; 837 if (mUserManagerInternal.getProfileParentId(childId) != userId) { 838 continue; 839 } 840 841 // If package is not present in child then don't attempt to delete. 842 if (!packageState.getUserStateOrDefault(childId).isInstalled()) { 843 continue; 844 } 845 846 UserProperties userProperties = mUserManagerInternal 847 .getUserProperties(childId); 848 if (userProperties != null && userProperties.getDeleteAppWithParent()) { 849 returnCodeOfChild = deletePackageX(internalPackageName, versionCode, 850 childId, deleteFlags, false /*removedBySystem*/); 851 if (returnCodeOfChild != DELETE_SUCCEEDED) { 852 Slog.w(TAG, "Package delete failed for user " + childId 853 + ", returnCode " + returnCodeOfChild); 854 returnCode = PackageManager.DELETE_FAILED_FOR_CHILD_PROFILE; 855 } 856 } 857 } 858 } 859 } else { 860 int[] blockUninstallUserIds = getBlockUninstallForUsers(innerSnapshot, 861 internalPackageName, users); 862 // If nobody is blocking uninstall, proceed with delete for all users 863 if (ArrayUtils.isEmpty(blockUninstallUserIds)) { 864 returnCode = deletePackageX(internalPackageName, versionCode, 865 userId, deleteFlags, false /*removedBySystem*/); 866 } else { 867 // Otherwise uninstall individually for users with blockUninstalls=false 868 final int userFlags = deleteFlags & ~PackageManager.DELETE_ALL_USERS; 869 for (int userId1 : users) { 870 if (!ArrayUtils.contains(blockUninstallUserIds, userId1)) { 871 returnCode = deletePackageX(internalPackageName, versionCode, 872 userId1, userFlags, false /*removedBySystem*/); 873 if (returnCode != DELETE_SUCCEEDED) { 874 Slog.w(TAG, "Package delete failed for user " + userId1 875 + ", returnCode " + returnCode); 876 } 877 } 878 } 879 // The app has only been marked uninstalled for certain users. 880 // We still need to report that delete was blocked 881 returnCode = PackageManager.DELETE_FAILED_OWNER_BLOCKED; 882 } 883 } 884 } else { 885 returnCode = PackageManager.DELETE_FAILED_INTERNAL_ERROR; 886 } 887 try { 888 observer.onPackageDeleted(packageName, returnCode, null); 889 } catch (RemoteException e) { 890 Log.i(TAG, "Observer no longer exists."); 891 } //end catch 892 893 // Prune unused static shared libraries which have been cached a period of time 894 mPm.schedulePruneUnusedStaticSharedLibraries(true /* delay */); 895 }); 896 } 897 isOrphaned(@onNull Computer snapshot, String packageName)898 private boolean isOrphaned(@NonNull Computer snapshot, String packageName) { 899 final PackageStateInternal packageState = snapshot.getPackageStateInternal(packageName); 900 return packageState != null && packageState.getInstallSource().mIsOrphaned; 901 } 902 isCallerAllowedToSilentlyUninstall(@onNull Computer snapshot, int callingUid, String pkgName, int userId)903 private boolean isCallerAllowedToSilentlyUninstall(@NonNull Computer snapshot, int callingUid, 904 String pkgName, int userId) { 905 if (PackageManagerServiceUtils.isRootOrShell(callingUid) 906 || UserHandle.getAppId(callingUid) == Process.SYSTEM_UID) { 907 return true; 908 } 909 final int callingUserId = UserHandle.getUserId(callingUid); 910 // If the caller installed the pkgName, then allow it to silently uninstall. 911 if (callingUid == snapshot.getPackageUid( 912 snapshot.getInstallerPackageName(pkgName, userId), 0, callingUserId)) { 913 return true; 914 } 915 916 // Allow package verifier to silently uninstall. 917 for (String verifierPackageName : mPm.mRequiredVerifierPackages) { 918 if (callingUid == snapshot.getPackageUid(verifierPackageName, 0, callingUserId)) { 919 return true; 920 } 921 } 922 923 // Allow package uninstaller to silently uninstall. 924 if (mPm.mRequiredUninstallerPackage != null && callingUid == snapshot 925 .getPackageUid(mPm.mRequiredUninstallerPackage, 0, callingUserId)) { 926 return true; 927 } 928 929 // Allow storage manager to silently uninstall. 930 if (mPm.mStorageManagerPackage != null && callingUid == snapshot.getPackageUid( 931 mPm.mStorageManagerPackage, 0, callingUserId)) { 932 return true; 933 } 934 935 // Allow caller having MANAGE_PROFILE_AND_DEVICE_OWNERS permission to silently 936 // uninstall for device owner provisioning. 937 return snapshot.checkUidPermission(MANAGE_PROFILE_AND_DEVICE_OWNERS, callingUid) 938 == PERMISSION_GRANTED; 939 } 940 getBlockUninstallForUsers(@onNull Computer snapshot, String packageName, int[] userIds)941 private int[] getBlockUninstallForUsers(@NonNull Computer snapshot, String packageName, 942 int[] userIds) { 943 int[] result = EMPTY_INT_ARRAY; 944 for (int userId : userIds) { 945 if (snapshot.getBlockUninstallForUser(packageName, userId)) { 946 result = ArrayUtils.appendInt(result, userId); 947 } 948 } 949 return result; 950 } 951 952 private static class TempUserState { 953 public final int enabledState; 954 @Nullable 955 public final String lastDisableAppCaller; 956 public final boolean installed; 957 TempUserState(int enabledState, @Nullable String lastDisableAppCaller, boolean installed)958 private TempUserState(int enabledState, @Nullable String lastDisableAppCaller, 959 boolean installed) { 960 this.enabledState = enabledState; 961 this.lastDisableAppCaller = lastDisableAppCaller; 962 this.installed = installed; 963 } 964 } 965 966 /** 967 * We're removing userId and would like to remove any downloaded packages 968 * that are no longer in use by any other user. 969 * @param userId the user being removed 970 */ 971 @GuardedBy("mPm.mLock") removeUnusedPackagesLPw(UserManagerService userManager, final int userId)972 public void removeUnusedPackagesLPw(UserManagerService userManager, final int userId) { 973 int [] users = userManager.getUserIds(); 974 final int numPackages = mPm.mSettings.getPackagesLocked().size(); 975 for (int index = 0; index < numPackages; index++) { 976 final PackageSetting ps = mPm.mSettings.getPackagesLocked().valueAt(index); 977 if (ps.getPkg() == null) { 978 continue; 979 } 980 final String packageName = ps.getPkg().getPackageName(); 981 // Skip over if system app, static shared library or and SDK library. 982 if ((ps.getFlags() & ApplicationInfo.FLAG_SYSTEM) != 0 983 || !TextUtils.isEmpty(ps.getPkg().getStaticSharedLibraryName()) 984 || !TextUtils.isEmpty(ps.getPkg().getSdkLibraryName())) { 985 continue; 986 } 987 if (DEBUG_CLEAN_APKS) { 988 Slog.i(TAG, "Checking package " + packageName); 989 } 990 boolean keep = mPm.shouldKeepUninstalledPackageLPr(packageName); 991 if (keep) { 992 if (DEBUG_CLEAN_APKS) { 993 Slog.i(TAG, " Keeping package " + packageName + " - requested by DO"); 994 } 995 } else { 996 for (int i = 0; i < users.length; i++) { 997 if (users[i] != userId && ps.getInstalled(users[i])) { 998 keep = true; 999 if (DEBUG_CLEAN_APKS) { 1000 Slog.i(TAG, " Keeping package " + packageName + " for user " 1001 + users[i]); 1002 } 1003 break; 1004 } 1005 } 1006 } 1007 if (!keep) { 1008 if (DEBUG_CLEAN_APKS) { 1009 Slog.i(TAG, " Removing package " + packageName); 1010 } 1011 //end run 1012 mPm.mHandler.post(() -> deletePackageX( 1013 packageName, PackageManager.VERSION_CODE_HIGHEST, 1014 userId, 0, true /*removedBySystem*/)); 1015 } 1016 } 1017 } 1018 deleteExistingPackageAsUser(VersionedPackage versionedPackage, final IPackageDeleteObserver2 observer, final int userId)1019 public void deleteExistingPackageAsUser(VersionedPackage versionedPackage, 1020 final IPackageDeleteObserver2 observer, final int userId) { 1021 mPm.mContext.enforceCallingOrSelfPermission( 1022 android.Manifest.permission.DELETE_PACKAGES, null); 1023 Preconditions.checkNotNull(versionedPackage); 1024 Preconditions.checkNotNull(observer); 1025 final String packageName = versionedPackage.getPackageName(); 1026 final long versionCode = versionedPackage.getLongVersionCode(); 1027 1028 int installedForUsersCount = 0; 1029 synchronized (mPm.mLock) { 1030 // Normalize package name to handle renamed packages and static libs 1031 final String internalPkgName = mPm.snapshotComputer() 1032 .resolveInternalPackageName(packageName, versionCode); 1033 final PackageSetting ps = mPm.mSettings.getPackageLPr(internalPkgName); 1034 if (ps != null) { 1035 int[] installedUsers = ps.queryInstalledUsers(mUserManagerInternal.getUserIds(), 1036 true); 1037 installedForUsersCount = installedUsers.length; 1038 } 1039 } 1040 1041 if (installedForUsersCount > 1) { 1042 deletePackageVersionedInternal(versionedPackage, observer, userId, 0, true); 1043 } else { 1044 try { 1045 observer.onPackageDeleted(packageName, PackageManager.DELETE_FAILED_INTERNAL_ERROR, 1046 null); 1047 } catch (RemoteException re) { 1048 } 1049 } 1050 } 1051 } 1052