android 卸载应用流程
文章目录如果在手机中卸载会有提示卸载页面等,这个一般是 UninstallerActivity;在这里点击卸载调用的是下面代码:ActivityThread.getPackageManager().getPackageInstaller().uninstall(new VersionedPackage(mDialogInfo.appInfo.packageName,PackageMan
·
文章目录
- 如果在手机中卸载会有提示卸载页面等,这个一般是 UninstallerActivity;在这里点击卸载调用的是下面代码:
ActivityThread.getPackageManager().getPackageInstaller().uninstall(
new VersionedPackage(mDialogInfo.appInfo.packageName,
PackageManager.VERSION_CODE_HIGHEST),
getPackageName(), flags, pendingIntent.getIntentSender(),
mDialogInfo.user.getIdentifier());
上面代码是IPC操作 getPackageManager() 为下面代码
public static IPackageManager getPackageManager() {
if (sPackageManager != null) {
//Slog.v("PackageManager", "returning cur default = " + sPackageManager);
return sPackageManager;
}
IBinder b = ServiceManager.getService("package");
//Slog.v("PackageManager", "default service binder = " + b);
sPackageManager = IPackageManager.Stub.asInterface(b);
//Slog.v("PackageManager", "default service = " + sPackageManager);
return sPackageManager;
}
对应的IPackageManager 就是 PMS;所以调用的 PMS 中的 getPackageInstaller() ,代码如下:
@Override
public IPackageInstaller getPackageInstaller() {
if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
return null;
}
return mInstallerService;
}
mInstallerService 为 PackageInstallerService ,所以看一下 PackageInstallerService 中的 uninstall() 方法
PackageInstallerService >> uninstall()
@Override
private final PackageManagerService mPm;
public void uninstall(VersionedPackage versionedPackage, String callerPackageName, int flags,
IntentSender statusReceiver, int userId) throws RemoteException {
// 先获取 UID
final int callingUid = Binder.getCallingUid();
// 检查执行权限
mPermissionManager.enforceCrossUserPermission(callingUid, userId, true, true, "uninstall");
if ((callingUid != Process.SHELL_UID) && (callingUid != Process.ROOT_UID)) {
mAppOps.checkPackage(callingUid, callerPackageName);
}
// Check whether the caller is device owner or affiliated profile owner, in which case we do
// it silently.
final int callingUserId = UserHandle.getUserId(callingUid);
DevicePolicyManagerInternal dpmi =
LocalServices.getService(DevicePolicyManagerInternal.class);
final boolean isDeviceOwnerOrAffiliatedProfileOwner =
dpmi != null && dpmi.isActiveAdminWithPolicy(callingUid,
DeviceAdminInfo.USES_POLICY_PROFILE_OWNER)
&& dpmi.isUserAffiliatedWithDevice(callingUserId);
final PackageDeleteObserverAdapter adapter = new PackageDeleteObserverAdapter(mContext,
statusReceiver, versionedPackage.getPackageName(),
isDeviceOwnerOrAffiliatedProfileOwner, userId);
if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DELETE_PACKAGES)
== PackageManager.PERMISSION_GRANTED) {
// Sweet, call straight through!
// 调用 mPm mPm.deletePackageVersioned
mPm.deletePackageVersioned(versionedPackage, adapter.getBinder(), userId, flags);
} else if (isDeviceOwnerOrAffiliatedProfileOwner) {
// Allow the device owner and affiliated profile owner to silently delete packages
// Need to clear the calling identity to get DELETE_PACKAGES permission
long ident = Binder.clearCallingIdentity();
try {
mPm.deletePackageVersioned(versionedPackage, adapter.getBinder(), userId, flags);
} finally {
Binder.restoreCallingIdentity(ident);
}
} else {
// 需要和用户确认卸载消息
ApplicationInfo appInfo = mPm.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
final Intent intent = new Intent(Intent.ACTION_UNINSTALL_PACKAGE);
intent.setData(Uri.fromParts("package", versionedPackage.getPackageName(), null));
intent.putExtra(PackageInstaller.EXTRA_CALLBACK, adapter.getBinder().asBinder());
adapter.onUserActionRequired(intent);
}
}
最后卸载调用了 mPm.deletePackageVersioned(versionedPackage, adapter.getBinder(), userId, flags); 所以走到了 PackageManagerService 的 deletePackageVersioned()
- deletePackageVersioned() 主要功能
@Override
public void deletePackageVersioned(VersionedPackage versionedPackage,
final IPackageDeleteObserver2 observer, final int userId, final int deleteFlags) {
// 获取 UID
final int callingUid = Binder.getCallingUid();
// 检查权限
mContext.enforceCallingOrSelfPermission(
android.Manifest.permission.DELETE_PACKAGES, null);
// 。。。
// 。。。
// 卸载应用是耗时的 所以开启异步线程
mHandler.post(new Runnable() {
public void run() {
// 为了防止重复发送
mHandler.removeCallbacks(this);
int returnCode;
// ...
// ...
// 最后就是调用了 deletePackageX
returnCode = deletePackageX(internalPackageName, versionCode,
userId, deleteFlags);
});
}
- deletePackageX()
int deletePackageX(String packageName, long versionCode, int userId, int deleteFlags) {
final PackageRemovedInfo info = new PackageRemovedInfo(this);
final boolean res;
final int removeUser = (deleteFlags & PackageManager.DELETE_ALL_USERS) != 0
? UserHandle.USER_ALL : userId;
// 检查该用户是否有删除这个应用的权限
if (isPackageDeviceAdmin(packageName, removeUser)) {
Slog.w(TAG, "Not removing package " + packageName + ": has active device admin");
return PackageManager.DELETE_FAILED_DEVICE_POLICY_MANAGER;
}
PackageSetting uninstalledPs = null;
PackageParser.Package pkg = null;
// for the uninstall-updates case and restricted profiles, remember the per-
// user handle installed state
int[] allUsers;
synchronized (mPackages) {
// 获取应用在 mSettings 中的信息
uninstalledPs = mSettings.mPackages.get(packageName);
if (uninstalledPs == null) {
return PackageManager.DELETE_FAILED_INTERNAL_ERROR;
}
if (versionCode != PackageManager.VERSION_CODE_HIGHEST
&& uninstalledPs.versionCode != versionCode) {
return PackageManager.DELETE_FAILED_INTERNAL_ERROR;
}
pkg = mPackages.get(packageName);
allUsers = sUserManager.getUserIds();
if (pkg != null && pkg.staticSharedLibName != null) {
SharedLibraryEntry libEntry = getSharedLibraryEntryLPr(pkg.staticSharedLibName,
pkg.staticSharedLibVersion);
if (libEntry != null) {
for (int currUserId : allUsers) {
if (removeUser != UserHandle.USER_ALL && removeUser != currUserId) {
continue;
}
List<VersionedPackage> libClientPackages = getPackagesUsingSharedLibraryLPr(
libEntry.info, 0, currUserId);
if (!ArrayUtils.isEmpty(libClientPackages)) {
return PackageManager.DELETE_FAILED_USED_SHARED_LIBRARY;
}
}
}
}
info.origUsers = uninstalledPs.queryInstalledUsers(allUsers, true);
}
final int freezeUser;
if (isUpdatedSystemApp(uninstalledPs)
&& ((deleteFlags & PackageManager.DELETE_SYSTEM_APP) == 0)) {
freezeUser = UserHandle.USER_ALL;
} else {
freezeUser = removeUser;
}
synchronized (mInstallLock) {
try (PackageFreezer freezer = freezePackageForDelete(packageName, freezeUser,
deleteFlags, "deletePackageX")) {
// 调用 deletePackageLIF 完成卸载应用
res = deletePackageLIF(packageName, UserHandle.of(removeUser), true, allUsers,
deleteFlags | PackageManager.DELETE_CHATTY, info, true, null);
}
synchronized (mPackages) {
if (res) {
if (pkg != null) {
mInstantAppRegistry.onPackageUninstalledLPw(pkg, info.removedUsers);
}
updateSequenceNumberLP(uninstalledPs, info.removedUsers);
updateInstantAppInstallerLocked(packageName);
}
}
}
if (res) {
final boolean killApp = (deleteFlags & PackageManager.DELETE_DONT_KILL_APP) == 0;
info.sendPackageRemovedBroadcasts(killApp);
info.sendSystemPackageUpdatedBroadcasts();
info.sendSystemPackageAppearedBroadcasts();
}
// Force a gc here.
Runtime.getRuntime().gc();
// Delete the resources here after sending the broadcast to let
// other processes clean up before deleting resources.
if (info.args != null) {
synchronized (mInstallLock) {
info.args.doPostDeleteLI(true);
}
}
return res ? PackageManager.DELETE_SUCCEEDED : PackageManager.DELETE_FAILED_INTERNAL_ERROR;
}
- deletePackageLIF()
private boolean deletePackageLIF(String packageName, UserHandle user,
boolean deleteCodeAndResources, int[] allUserHandles, int flags,
PackageRemovedInfo outInfo, boolean writeSettings,
PackageParser.Package replacingPackage) {
// ...
// ...
if (((!isSystemApp(ps) || (flags&PackageManager.DELETE_SYSTEM_APP) != 0) && user != null
&& user.getIdentifier() != UserHandle.USER_ALL)) {
// 调用者要求仅为单个用户删除包。
// 为此,我们只需标记其已卸载状态并删除其数据。
// 如果这是一个系统应用程序,只是标记状态和删除数据
// 如果他们设置了特殊的DELETE_SYSTEM_APP,则将调用不同的方式卸载系统app
// 设置一些状态属性
markPackageUninstalledForUserLPw(ps, user);
// 判断是不是系统 app
if (!isSystemApp(ps)) {
// Do not uninstall the APK if an app should be cached
boolean keepUninstalledPackage = shouldKeepUninstalledPackageLPr(packageName);
// 如果调用者只要求卸载某个用户下的应用
if (ps.isAnyInstalled(sUserManager.getUserIds()) || keepUninstalledPackage) {
// Other user still have this package installed, so all
// we need to do is clear this user's data and save that
// it is uninstalled.
// 其他用户仍然安装了这个包,所以我们需要做的就是清除该用户的数据,并将其保存为已卸载。
if (DEBUG_REMOVE) Slog.d(TAG, "Still installed by other users");
if (!clearPackageStateForUserLIF(ps, user.getIdentifier(), outInfo)) {
return false;
}
scheduleWritePackageRestrictionsLocked(user);
return true;
} else {
// We need to set it back to 'installed' so the uninstall
// broadcasts will be sent correctly.
if (DEBUG_REMOVE) Slog.d(TAG, "Not installed by other users, full delete");
ps.setInstalled(true, user.getIdentifier());
mSettings.writeKernelMappingLPr(ps);
}
} else {
// This is a system app, so we assume that the
// other users still have this package installed, so all
// we need to do is clear this user's data and save that
// it is uninstalled.
// 如果是系统应用程序,因此我们假设其他用户仍然安装了这个包,因此我们需要做的就是清除该用户的数据,并保存为已卸载。
if (DEBUG_REMOVE) Slog.d(TAG, "Deleting system app");
if (!clearPackageStateForUserLIF(ps, user.getIdentifier(), outInfo)) {
return false;
}
scheduleWritePackageRestrictionsLocked(user);
return true;
}
}
// 安装的时候有安装包集 卸载也一样 查看packageSetting 下是否是复合包
if (ps.childPackageNames != null && outInfo != null) {
synchronized (mPackages) {
final int childCount = ps.childPackageNames.size();
outInfo.removedChildPackages = new ArrayMap<>(childCount);
for (int i = 0; i < childCount; i++) {
String childPackageName = ps.childPackageNames.get(i);
PackageRemovedInfo childInfo = new PackageRemovedInfo(this);
childInfo.removedPackage = childPackageName;
childInfo.installerPackageName = ps.installerPackageName;
outInfo.removedChildPackages.put(childPackageName, childInfo);
PackageSetting childPs = mSettings.getPackageLPr(childPackageName);
if (childPs != null) {
childInfo.origUsers = childPs.queryInstalledUsers(allUserHandles, true);
}
}
}
}
boolean ret = false;
if (isSystemApp(ps)) {
if (DEBUG_REMOVE) Slog.d(TAG, "Removing system package: " + ps.name);
// 当一个更新的系统应用程序被删除时,我们也会删除现有的资源 设置一下分区
ret = deleteSystemPackageLIF(ps.pkg, ps, allUserHandles, flags, outInfo, writeSettings);
} else {
// kill app ; 删除非系统的包和资源 ;删除各种缓存 和 为package.xml packageSetting 修改对应的数据等
ret = deleteInstalledPackageLIF(ps, deleteCodeAndResources, flags, allUserHandles,
outInfo, writeSettings, replacingPackage);
}
// ...
// ...
}
整体流程是根据不用用户删除app和数据;包括 package 和 PMS 等缓存数据等。
更多推荐
已为社区贡献4条内容
所有评论(0)