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