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