finalStringpackageName= getNextArg(); if (packageName == null) { pw.println("Error: package name not specified"); return1; }
/ if a split is specified, just remove it and not the whole package ArrayList<String> splitNames = getRemainingArgs(); if (!splitNames.isEmpty()) { return runRemoveSplits(packageName, splitNames); } // 不加--user是卸载所有用户的应用 if (userId == UserHandle.USER_ALL) { flags |= PackageManager.DELETE_ALL_USERS; } finalinttranslatedUserId= translateUserId(userId, UserHandle.USER_SYSTEM, "runUninstall"); finalLocalIntentReceiverreceiver=newLocalIntentReceiver(); finalPackageManagerInternalinternal= LocalServices.getService(PackageManagerInternal.class);
if (internal.isApexPackage(packageName)) { internal.uninstallApex( packageName, versionCode, translatedUserId, receiver.getIntentSender(), flags); } else { //如果删除某一个用户的应用,走这里 if ((flags & PackageManager.DELETE_ALL_USERS) == 0) { finalPackageInfoinfo= mInterface.getPackageInfo(packageName, PackageManager.MATCH_STATIC_SHARED_AND_SDK_LIBRARIES, translatedUserId); if (info == null) { pw.println("Failure [not installed for " + translatedUserId + "]"); return1; } finalbooleanisSystem= (info.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0; // If we are being asked to delete a system app for just one // user set flag so it disables rather than reverting to system // version of the app. if (isSystem) { flags |= PackageManager.DELETE_SYSTEM_APP; } } mInterface.getPackageInstaller().uninstall(newVersionedPackage(packageName, versionCode), null/*callerPackageName*/, flags, receiver.getIntentSender(), translatedUserId); }
/** * Uninstall the given package with a specific version code, removing it * completely from the device. If the version code of the package * does not match the one passed in the versioned package argument this * method is a no-op. Use {@link PackageManager#VERSION_CODE_HIGHEST} to * uninstall the latest version of the package. * <p> * This method is available to: * <ul> * <li>the current "installer of record" for the package * <li>the device owner * <li>the affiliated profile owner * </ul> * * @param versionedPackage The versioned package to uninstall. * @param statusReceiver Where to deliver the result. * * @see android.app.admin.DevicePolicyManager */ @RequiresPermission(anyOf = { Manifest.permission.DELETE_PACKAGES, Manifest.permission.REQUEST_DELETE_PACKAGES}) publicvoiduninstall(@NonNull VersionedPackage versionedPackage, @NonNull IntentSender statusReceiver) { uninstall(versionedPackage, 0/*flags*/, statusReceiver); }
/** * Uninstall the given package with a specific version code, removing it * completely from the device. This method is only available to the current * "installer of record" for the package. If the version code of the package * does not match the one passed in the versioned package argument this * method is a no-op. Use {@link PackageManager#VERSION_CODE_HIGHEST} to * uninstall the latest version of the package. * * @param versionedPackage The versioned package to uninstall. * @param flags Flags for uninstall. * @param statusReceiver Where to deliver the result. * * @hide */ @RequiresPermission(anyOf = { Manifest.permission.DELETE_PACKAGES, Manifest.permission.REQUEST_DELETE_PACKAGES}) publicvoiduninstall(@NonNull VersionedPackage versionedPackage, @DeleteFlagsint flags, @NonNull IntentSender statusReceiver) { Objects.requireNonNull(versionedPackage, "versionedPackage cannot be null"); try { //binder调用 mInstaller.uninstall(versionedPackage, mInstallerPackageName, flags, statusReceiver, mUserId); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } }
// Check whether the caller is device owner or affiliated profile owner, in which case we do // it silently. DevicePolicyManagerInternaldpmi= LocalServices.getService(DevicePolicyManagerInternal.class); finalbooleancanSilentlyInstallPackage= dpmi != null && dpmi.canSilentlyInstallPackage(callerPackageName, callingUid);
finalPackageDeleteObserverAdapteradapter=newPackageDeleteObserverAdapter(mContext, statusReceiver, versionedPackage.getPackageName(), canSilentlyInstallPackage, userId); if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DELETE_PACKAGES) == PackageManager.PERMISSION_GRANTED) { // Sweet, call straight through! mPm.deletePackageVersioned(versionedPackage, adapter.getBinder(), userId, flags); } elseif (canSilentlyInstallPackage) { // Allow the device owner and affiliated profile owner to silently delete packages // Need to clear the calling identity to get DELETE_PACKAGES permission finallongident= Binder.clearCallingIdentity(); try { mPm.deletePackageVersioned(versionedPackage, adapter.getBinder(), userId, flags); } finally { Binder.restoreCallingIdentity(ident); } DevicePolicyEventLogger .createEvent(DevicePolicyEnums.UNINSTALL_PACKAGE) .setAdmin(callerPackageName) .write(); } else { ApplicationInfoappInfo= snapshot.getApplicationInfo(callerPackageName, 0, userId); if (appInfo.targetSdkVersion >= Build.VERSION_CODES.P) { mContext.enforceCallingOrSelfPermission(Manifest.permission.REQUEST_DELETE_PACKAGES, null); }
// Take a short detour to confirm with user finalIntentintent=newIntent(Intent.ACTION_UNINSTALL_PACKAGE); intent.setData(Uri.fromParts("package", versionedPackage.getPackageName(), null)); intent.putExtra(PackageInstaller.EXTRA_CALLBACK, adapter.getBinder().asBinder()); adapter.onUserActionRequired(intent); } }
com/android/server/pm/IPackageManagerBase.java
1 2 3 4 5 6 7 8
@Override @Deprecated publicfinalvoiddeletePackageAsUser(String packageName, int versionCode, IPackageDeleteObserver observer, int userId, int flags) { deletePackageVersioned(newVersionedPackage(packageName, versionCode), newPackageManager.LegacyPackageDeleteObserver(observer).getBinder(), userId, flags); }