• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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