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