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