本文基于Android10.0
主要从以下几个方面着手:
PKMS启动
PKMS安装APK
PKMS卸载APK
PKMS启动
这里我简单的将其分为以下几个步骤:
- 1.SystemServer通过PKMS的main方法启动PKMS
- 2.PKMS构造方法中初始化Settings
- 3.扫描各个系统目录下APP相关信息
1.SystemServer通过PKMS的main方法启动PKMS
PKMS启动是在SystemServer.startBootstrapServices:
mPackageManagerService = PackageManagerService.main(mSystemContext, installer,
mFactoryTestMode != FactoryTest.FACTORY_TEST_OFF, mOnlyCore);
PackageManagerService.main方法:
public static PackageManagerService main(Context context, Installer installer,
boolean factoryTest, boolean onlyCore) {
.....
//构造方法
PackageManagerService m = new PackageManagerService(context, installer,
factoryTest, onlyCore);
m.enableSystemUserPackages();
ServiceManager.addService("package", m);
final PackageManagerNative pmn = m.new PackageManagerNative();
ServiceManager.addService("package_native", pmn);
return m;
}
2.PKMS构造方法中初始化Settings
PackageManagerService.PackageManagerService
public PackageManagerService(Context context, Installer installer,
boolean factoryTest, boolean onlyCore) {
......
//Settings的初始化
mSettings = new Settings(Environment.getDataDirectory(),
mPermissionManager.getPermissionSettings(), mPackages);
mSettings是全局的,它主要协助PMS保存系统中安装APP包名,权限,四大组件等相关信息的存储,Settings会在/data/system目录下创建相关的文件来保存这些APP相关的信息
frameworks\base\services\core\java\com\android\server\pm\Settings.java
查看Settings.Settings方法:
Settings(File dataDir, PermissionSettings permission,
Object lock) {
......
mSystemDir = new File(dataDir, "system");
mSystemDir.mkdirs();
FileUtils.setPermissions(mSystemDir.toString(),
FileUtils.S_IRWXU|FileUtils.S_IRWXG
|FileUtils.S_IROTH|FileUtils.S_IXOTH,
-1, -1);
mSettingsFilename = new File(mSystemDir, "packages.xml");
mBackupSettingsFilename = new File(mSystemDir, "packages-backup.xml");
mPackageListFilename = new File(mSystemDir, "packages.list");
FileUtils.setPermissions(mPackageListFilename, 0640, SYSTEM_UID, PACKAGE_INFO_GID);
final File kernelDir = new File("/config/sdcardfs");
mKernelMappingFilename = kernelDir.exists() ? kernelDir : null;
// Deprecated: Needed for migration
mStoppedPackagesFilename = new File(mSystemDir, "packages-stopped.xml");
mBackupStoppedPackagesFilename = new File(mSystemDir, "packages-stopped-backup.xml");
}
我们大概看一下/data/system生成的文件信息:
packages.xml----主要是包括包的权限信息:
<package name="com.sohu.inputmethod.sogou.oem" codePath="/system/priv-app/SogouInput" nativeLibraryPath="/system/priv-app/SogouInput/lib" primaryCpuAbi="armeabi" publicFlags="945307205" privateFlags="8" ft="179aac28790" it="179aac28790" ut="179aac28790" version="1312" userId="10076" isOrphaned="true">
<sigs count="1" schemeVersion="1">
<cert index="0" key="30820248308201b102045a3eccafc07082c70bb30ef4" />
</sigs>
<perms>
<item name="android.permission.DOWNLOAD_WITHOUT_NOTIFICATION" granted="true" flags="0" />
<item name="android.permission.WRITE_SETTINGS" granted="true" flags="0" />
......
<item name="com.android.launcher.permission.INSTALL_SHORTCUT" granted="true" flags="0" />
<item name="android.permission.WAKE_LOCK" granted="true" flags="0" />
</perms>
<proper-signing-keyset identifier="8" />
</package>
packages-backup.xml
packages.list------------------应用列表
com.android.soundrecorder 10135 0 /data/user/0/com.android.soundrecorder platform:targetSdkVersion=29 1023,3003 0 63
packages-stopped.xml
packages-stopped-backup.xml
3.扫描各个系统目录下APP相关信息
PackageManagerService.PackageManagerService:
public PackageManagerService(Context context, Installer installer,
boolean factoryTest, boolean onlyCore) {
......
// Collect vendor/product/product_services overlay packages. (Do this before scanning
// any apps.)
// For security and version matching reason, only consider overlay packages if they
// reside in the right directory.
scanDirTracedLI(new File(VENDOR_OVERLAY_DIR),
mDefParseFlags
| PackageParser.PARSE_IS_SYSTEM_DIR,
scanFlags
| SCAN_AS_SYSTEM
| SCAN_AS_VENDOR,
0);
scanDirTracedLI(new File(PRODUCT_OVERLAY_DIR),
mDefParseFlags
| PackageParser.PARSE_IS_SYSTEM_DIR,
scanFlags
| SCAN_AS_SYSTEM
| SCAN_AS_PRODUCT,
0);
......
scanDirTracedLI(productServicesAppDir,
mDefParseFlags
| PackageParser.PARSE_IS_SYSTEM_DIR,
scanFlags
| SCAN_AS_SYSTEM
| SCAN_AS_PRODUCT_SERVICES,
0);
从Android 10,0的代码来看,扫描路径的顺序为:
/vendor/overlay
/product/overlay
/product_services/overlay
/odm/overlay
/oem/overlay
/system/framework
/system/priv-app
/system/app
/vendor/priv-app
/vendor/app
/odm/priv-app
/odm/app
/oem/app
/product/priv-app
/product/app
/product_services/priv-app
/product_services/app
PKMS安装APK
adb install命令 安装apk
我们使用adb install 命令来安装apk:
先来看PackageManagerService的消息定义:
static final int SEND_PENDING_BROADCAST = 1;
static final int INIT_COPY = 5; //此是在安装apk前,copy apk的消息
static final int POST_INSTALL = 9; //安装前的消息
static final int WRITE_SETTINGS = 13;
static final int WRITE_PACKAGE_RESTRICTIONS = 14;
static final int PACKAGE_VERIFIED = 15;
static final int CHECK_PENDING_VERIFICATION = 16;
static final int START_INTENT_FILTER_VERIFICATIONS = 17; //intent filter 的校验消息
static final int INTENT_FILTER_VERIFIED = 18;
static final int WRITE_PACKAGE_LIST = 19;
static final int INSTANT_APP_RESOLUTION_PHASE_TWO = 20;
static final int ENABLE_ROLLBACK_STATUS = 21;
static final int ENABLE_ROLLBACK_TIMEOUT = 22;
static final int DEFERRED_NO_KILL_POST_DELETE = 23;
static final int DEFERRED_NO_KILL_INSTALL_OBSERVER = 24;
static final int NEED_UPDATAE_APPLICATION = 25;
static final int NEED_UPDATAE_ACTIVITYINFO = 26;
我们先确认系统是如何发送消息MSG_COMMIT:
我们在PackageInstallerSession.commit添加日志信息:
public void commit(@NonNull IntentSender statusReceiver, boolean forTransfer) {
......
Slog.v(TAG, "commit " , new Throwable());
mHandler.obtainMessage(MSG_COMMIT).sendToTarget();
}
这个是日志信息输出:
com.android.server.pm.PackageInstallerSession.commit(PackageInstallerSession.java:920)
android.content.pm.PackageInstaller$Session.commit(PackageInstaller.java:1079)
com.android.server.pm.PackageManagerShellCommand.doCommitSession(PackageManagerShellCommand.java:2851)
com.android.server.pm.PackageManagerShellCommand.runInstall(PackageManagerShellCommand.java:1082)
com.android.server.pm.PackageManagerShellCommand.onCommand(PackageManagerShellCommand.java:169)
android.os.ShellCommand.exec(ShellCommand.java:104)
com.android.server.pm.PackageManagerService.onShellCommand(PackageManagerService.java:22266)
android.os.Binder.shellCommand(Binder.java:881)
android.os.Binder.onTransact(Binder.java:765)
android.content.pm.IPackageManager$Stub.onTransact(IPackageManager.java:4923)
com.android.server.pm.PackageManagerService.onTransact(PackageManagerService.java:4141)
android.os.Binder.execTransactInternal(Binder.java:1021)
android.os.Binder.execTransact(Binder.java:994)
查看PackageManagerShellCommand.onCommand:
public int onCommand(String cmd) {
......
switch(cmd) {
case "path":
return runPath();
case "dump":
return runDump();
case "list":
return runList();
case "resolve-activity":
return runResolveActivity();
case "query-activities":
return runQueryIntentActivities();
case "query-services":
return runQueryIntentServices();
case "query-receivers":
return runQueryIntentReceivers();
case "install":
return runInstall();//安装apk
......
可以看出adb shell pm command命令的入口就是在这个方法中添加,而我们执行adb install命令,后面就会来到此处的runInstall方法。
最后,就会来到PackageInstallerSession.commit:
public void commit(@NonNull IntentSender statusReceiver, boolean forTransfer) {
......
mHandler.obtainMessage(MSG_COMMIT).sendToTarget();//发送MSG_COMMIT消息
}
然后,我们在PackageManagerService$PackageHandler.doHandleMessage就可以接受到消息MSG_COMMIT:
void doHandleMessage(Message msg) {
......
switch (msg.what) {
case INIT_COPY: {
HandlerParams params = (HandlerParams) msg.obj;
if (params != null) {
if (DEBUG_INSTALL) Slog.i(TAG, "init_copy: " + params);
Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "queueInstall",
System.identityHashCode(params));
Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "startCopy");
params.startCopy();//执行copy操作
Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
}
break;
}
查看日志,我们就知道,会将此apk复现/data/app/vmdl2019169999.tmp:
PackageManager: init_copy: InstallParams{78e22b5 file=/data/app/vmdl2019169999.tmp}
PackageManager: startCopy UserHandle{0}: InstallParams{78e22b5 file=/data/app/vmdl2019169999.tmp}
PackageManagerService$HandlerParams.startCopy
final void startCopy() {
if (DEBUG_INSTALL) Slog.i(TAG, "startCopy " + mUser + ": " + this);
handleStartCopy();
handleReturnCode();
}
再查看日志:
PackageManager: Renaming /data/app/vmdl2019169999.tmp to /data/app/flipboard.cn-MArVEpS9MmEGIfVhBcSfbg==
我们发现有一个对复制过来的文件进行重命名的操作
再查看日志:
PackageManager: installNewPackageLI: Package{2dbf84 flipboard.cn}
在PackageManagerService.preparePackageLI添加日志信息:
private PrepareResult preparePackageLI(InstallArgs args, PackageInstalledInfo res)
throws PrepareFailure {
........
// Remember this for later, in case we need to rollback this install
String pkgName1 = pkg.packageName;
Slog.v(TAG, "preparePackageLI installNewPackageLI" , new Throwable());
if (DEBUG_INSTALL) Slog.d(TAG, "installNewPackageLI: " + pkg);
可以看到日志信息:
com.android.server.pm.PackageManagerService.preparePackageLI(PackageManagerService.java:18268)
com.android.server.pm.PackageManagerService.installPackagesLI(PackageManagerService.java:17328)
com.android.server.pm.PackageManagerService.installPackagesTracedLI(PackageManagerService.java:16675)
com.android.server.pm.PackageManagerService.lambda$processInstallRequestsAsync$13$PackageManagerService(PackageManagerService.java:14919)
再查看,发现日志信息:
PackageManager: Activities: flipboard.activities.LaunchActivity flipboard.activities.BriefingLaunchFlipboardAlias flipboard.activities.LaunchActivityAlias
PackageManager: Receivers: flipboard.receivers.FirstLaunchReminderReceiver flipboard.notifications.NotificationExpirationReceiver
PackageManager: Registered content provider: flipboard.remoteservice.feeds.china, className = flipboard.remoteservice.FLFeedItemContentProvider, isSyncable = false
也就是需要添加要安装的应用中四大组件activity,receiver,content provider,services信息:
我们在ComponentResolver.addProvidersLocked添加打印日志信息:
private void addProvidersLocked(PackageParser.Package pkg, boolean chatty) {
Slog.v(TAG, "addProvidersLocked" , new Throwable());
其打印日志为:
com.android.server.pm.ComponentResolver.addProvidersLocked(ComponentResolver.java:557)
com.android.server.pm.ComponentResolver.addAllComponents(ComponentResolver.java:375)
com.android.server.pm.PackageManagerService.commitPackageSettings(PackageManagerService.java:12483)
com.android.server.pm.PackageManagerService.commitReconciledScanResultLocked(PackageManagerService.java:11366)
com.android.server.pm.PackageManagerService.commitPackagesLocked(PackageManagerService.java:17263)
com.android.server.pm.PackageManagerService.installPackagesLI(PackageManagerService.java:17400)
com.android.server.pm.PackageManagerService.installPackagesTracedLI(PackageManagerService.java:16675)
com.android.server.pm.PackageManagerService.lambda$processInstallRequestsAsync$13$PackageManagerService(PackageManagerService.java:14919)
查看ComponentResolver.addAllComponents:
void addAllComponents(PackageParser.Package pkg, boolean chatty) {
final ArrayList<PackageParser.ActivityIntentInfo> newIntents = new ArrayList<>();
synchronized (mLock) {
addActivitiesLocked(pkg, newIntents, chatty);//添加activity
addReceiversLocked(pkg, chatty); //添加Receiver
addProvidersLocked(pkg, chatty); //添加Provider
addServicesLocked(pkg, chatty); //添加Service
}
其ComponentResolver类中定义四大组件的信息为:
/** All available activities, for your resolving pleasure. */
@GuardedBy("mLock")
private final ActivityIntentResolver mActivities = new ActivityIntentResolver();
/** All available providers, for your resolving pleasure. */
@GuardedBy("mLock")
private final ProviderIntentResolver mProviders = new ProviderIntentResolver();
/** All available receivers, for your resolving pleasure. */
@GuardedBy("mLock")
private final ActivityIntentResolver mReceivers = new ActivityIntentResolver();
/** All available services, for your resolving pleasure. */
@GuardedBy("mLock")
private final ServiceIntentResolver mServices = new ServiceIntentResolver();
再往下查看日志:
PackageManager: New package installed in /data/app/flipboard.cn-MArVEpS9MmEGIfVhBcSfbg==
我们在代码PackageManagerService.updateSettingsInternalLI中添加日志:
private void updateSettingsInternalLI(PackageParser.Package pkg,
String installerPackageName, int[] allUsers, int[] installedForUsers,
PackageInstalledInfo res, UserHandle user, int installReason) {
Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "updateSettings");
final String pkgName = pkg.packageName;
Slog.v(TAG, "updateSettingsInternalLI " , new Throwable());
if (DEBUG_INSTALL) Slog.d(TAG, "New package installed in " + pkg.codePath);
......
其输出日志信息为:
com.android.server.pm.PackageManagerService.updateSettingsInternalLI(PackageManagerService.java:16574)
com.android.server.pm.PackageManagerService.updateSettingsLI(PackageManagerService.java:16555)
com.android.server.pm.PackageManagerService.commitPackagesLocked(PackageManagerService.java:17264)
com.android.server.pm.PackageManagerService.installPackagesLI(PackageManagerService.java:17400)
com.android.server.pm.PackageManagerService.installPackagesTracedLI(PackageManagerService.java:16675)
com.android.server.pm.PackageManagerService.lambda$processInstallRequestsAsync$13$PackageManagerService(PackageManagerService.java:14919)
其理解为,我们更新上面说的settings数据信息。
我们在代码PackageManagerService$PackageHandler.doHandleMessage添加日志信息:
void doHandleMessage(Message msg) {
Slog.v(TAG, "PackageHandler doHandleMessage " , new Throwable());
Slog.v(TAG, "PackageHandler doHandleMessage " + msg.what);
可以看到,我们会先响应消息START_INTENT_FILTER_VERIFICATIONS:
PackageManager: PackageHandler doHandleMessage 17
PackageManagerService$PackageHandler.doHandleMessage:
case START_INTENT_FILTER_VERIFICATIONS: {
IFVerificationParams params = (IFVerificationParams) msg.obj;
verifyIntentFiltersIfNeeded(params.userId, params.verifierUid,
params.replacing, params.pkg);
break;
}
再响应消息POST_INSTALL:
PackageManager: PackageHandler doHandleMessage 9
PackageManagerService$PackageHandler.doHandleMessage
case POST_INSTALL: {
if (DEBUG_INSTALL) Log.v(TAG, "Handling post-install for " + msg.arg1);
PostInstallData data = mRunningInstalls.get(msg.arg1);
final boolean didRestore = (msg.arg2 != 0);
mRunningInstalls.delete(msg.arg1);//删除数据
if (data != null && data.mPostInstallRunnable != null) {
data.mPostInstallRunnable.run();
} else if (data != null) {
InstallArgs args = data.args;
PackageInstalledInfo parentRes = data.res;
final boolean grantPermissions = (args.installFlags
& PackageManager.INSTALL_GRANT_RUNTIME_PERMISSIONS) != 0;
final boolean killApp = (args.installFlags
& PackageManager.INSTALL_DONT_KILL_APP) == 0;
final boolean virtualPreload = ((args.installFlags
& PackageManager.INSTALL_VIRTUAL_PRELOAD) != 0);
final String[] grantedPermissions = args.installGrantPermissions;
final List<String> whitelistedRestrictedPermissions = ((args.installFlags
& PackageManager.INSTALL_ALL_WHITELIST_RESTRICTED_PERMISSIONS) != 0
&& parentRes.pkg != null)
? parentRes.pkg.requestedPermissions
: args.whitelistedRestrictedPermissions;
// Handle the parent package
handlePackagePostInstall(parentRes, grantPermissions,
killApp, virtualPreload, grantedPermissions,
whitelistedRestrictedPermissions, didRestore,
args.installerPackageName, args.observer);//handlePackagePostInstall
// Handle the child packages
final int childCount = (parentRes.addedChildPackages != null)
? parentRes.addedChildPackages.size() : 0;
for (int i = 0; i < childCount; i++) {
PackageInstalledInfo childRes = parentRes.addedChildPackages.valueAt(i);
handlePackagePostInstall(childRes, grantPermissions,
killApp, virtualPreload, grantedPermissions,
whitelistedRestrictedPermissions, false /*didRestore*/,
args.installerPackageName, args.observer);
}
// Log tracing if needed
if (args.traceMethod != null) {
Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, args.traceMethod,
args.traceCookie);
}
} else if (DEBUG_INSTALL) {
// No post-install when we run restore from installExistingPackageForUser
Slog.i(TAG, "Nothing to do for post-install token " + msg.arg1);
}
Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "postInstall", msg.arg1);
} break;
那么我们最后安装好apk,什么时候发送广播android.intent.action.PACKAGE_ADDED呢?
在PackageManagerService.sendPackageBroadcast源码中添加日志信息:
public void sendPackageBroadcast(final String action, final String pkg, final Bundle extras,
final int flags, final String targetPkg, final IIntentReceiver finishedReceiver,
final int[] userIds, int[] instantUserIds) {
Slog.v(TAG, "sendPackageBroadcast " , new Throwable());
输出的日志信息:
com.android.server.pm.PackageManagerService.sendPackageBroadcast(PackageManagerService.java:13221)
com.android.server.pm.PackageManagerService.sendPackageAddedForNewUsers(PackageManagerService.java:13513)
com.android.server.pm.PackageManagerService.handlePackagePostInstall(PackageManagerService.java:1984)
com.android.server.pm.PackageManagerService.access$400(PackageManagerService.java:424)
com.android.server.pm.PackageManagerService$PackageHandler.doHandleMessage(PackageManagerService.java:1532)
com.android.server.pm.PackageManagerService$PackageHandler.handleMessage(PackageManagerService.java:1440)
查看:
public void sendPackageAddedForNewUsers(String packageName, boolean sendBootCompleted,
boolean includeStopped, int appId, int[] userIds, int[] instantUserIds) {
......
Bundle extras = new Bundle(1);
// Set to UID of the first user, EXTRA_UID is automatically updated in sendPackageBroadcast
final int uid = UserHandle.getUid(
(ArrayUtils.isEmpty(userIds) ? instantUserIds[0] : userIds[0]), appId);
extras.putInt(Intent.EXTRA_UID, uid);
sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED,
packageName, extras, 0, null, null, userIds, instantUserIds);//发送ACTION_PACKAGE_ADDED广播
其安装UML类图:
安装UML类图(1)----处理消息MSG_COMMIT
安装UML类图(2)----处理消息START_INTENT_FILTER_VERIFICATIONS和POST_INSTALL
2.在我们应用商店中下载应用后台静默安装
在PackageInstaller.execInstallCommand中添加日志信息:
private boolean execInstallCommand(Context context, int sessionId, String packageName) {
Slog.v(TAG, "execInstallCommand " , new Throwable());
.......
输出日志信息:
android.content.pm.PackageInstaller.execInstallCommand(PackageInstaller.java:2513)
android.content.pm.PackageInstaller.silentInstallApk(PackageInstaller.java:2487)
android.content.pm.PackageInstaller.silentInstallApk(PackageInstaller.java:2423)
java.lang.reflect.Method.invoke(Native Method)
com.xxxx.webappstore.f.q.o(AppUtils.java:7)
com.xxxx.webappstore.f.q.p(AppUtils.java:1)
com.xxxx.webappstore.e.b.c.a.h(BaseDownloadTask.java:3)
com.xxxx.webappstore.e.b.c.b.B(DownloadTask.java:13)
com.xxxx.webappstore.e.b.c.b.run(DownloadTask.java:18)
从这就可以看出这是一个调用PackageInstaller的后台静默安装接口来实现的。
其PackageInstaller.execInstallCommand中实现方式为:
private boolean execInstallCommand(Context context, int sessionId, String packageName) {
PackageInstaller.Session session = null;
try {
session = openSession(sessionId);
Intent intent = new Intent();
intent.setAction(ACTION_SILENT_INSTALL_APK);
intent.putExtra(EXTRA_PACKAGE_NAME, packageName);
PendingIntent pendingIntent = PendingIntent.getBroadcast(context, sessionId, intent, PendingIntent.FLAG_UPDATE_CURRENT);
session.commit(pendingIntent.getIntentSender());//调用session.commit接口
return true;
} catch (Throwable e) {
Log.e(TAG, e.getMessage(), e);
}
return false;
}
public void commit(@NonNull IntentSender statusReceiver) {
try {
mSession.commit(statusReceiver, false);这个同上面的逻辑,最后就是调用PackageInstallerSession.commit接口
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
}
后面的逻辑,就会执行adb install命令来实现安装完全一样了。
PKMS卸载APK
我们在桌面长按一个应用,选择卸载:
其响应的UninstallUninstalling.onCreate逻辑是:
com.android.packageinstaller.UninstallUninstalling.onCreate(UninstallUninstalling.java:109)
protected void onCreate(@Nullable Bundle savedInstanceState) {
......
try {
ActivityThread.getPackageManager().getPackageInstaller().uninstall(
new VersionedPackage(mAppInfo.packageName,
PackageManager.VERSION_CODE_HIGHEST),
getPackageName(), flags, pendingIntent.getIntentSender(),
user.getIdentifier());//调用uninstall接口
} catch (RemoteException e) {
e.rethrowFromSystemServer();
}
其调用的是PackageInstallerService.uninstall:
com.android.server.pm.PackageInstallerService.uninstall(PackageInstallerService.java:823)
调用PackageInstallerService.uninstall:
public void uninstall(VersionedPackage versionedPackage, String callerPackageName, int flags,
IntentSender statusReceiver, int userId) {
......
if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DELETE_PACKAGES)
== PackageManager.PERMISSION_GRANTED) {
// Sweet, call straight through!
mPm.deletePackageVersioned(versionedPackage, adapter.getBinder(), userId, flags);//调用此接口
PackageManagerService.deletePackageVersioned
public void deletePackageVersioned(VersionedPackage versionedPackage,
final IPackageDeleteObserver2 observer, final int userId, final int deleteFlags) {
deletePackageVersionedOri(versionedPackage, observer, userId, deleteFlags);
}
PackageManagerService.deletePackageVersionedOri
private void deletePackageVersionedOri(VersionedPackage versionedPackage,
final IPackageDeleteObserver2 observer, final int userId, final int deleteFlags) {
......
returnCode = deletePackageX(internalPackageName, versionCode,
userId, deleteFlags);
PackageManagerService.deletePackageX
int deletePackageX(String packageName, long versionCode, int userId, int deleteFlags) {
......
if (DEBUG_REMOVE) Slog.d(TAG, "deletePackageX: pkg=" + packageName + " user=" + userId);
try (PackageFreezer freezer = freezePackageForDelete(packageName, freezeUser,
deleteFlags, "deletePackageX")) {
res = deletePackageLIF(packageName, UserHandle.of(removeUser), true, allUsers,
deleteFlags | PackageManager.DELETE_CHATTY, info, true, null);
}
......
if (res) {
final boolean killApp = (deleteFlags & PackageManager.DELETE_DONT_KILL_APP) == 0;
info.sendPackageRemovedBroadcasts(killApp);
info.sendSystemPackageUpdatedBroadcasts();
info.sendSystemPackageAppearedBroadcasts();
}
PackageManagerService$PackageRemovedInfo.sendPackageRemovedBroadcasts
void sendPackageRemovedBroadcasts(boolean killApp) {
sendPackageRemovedBroadcastInternal(killApp);
PackageManagerService$PackageRemovedInfo.sendPackageRemovedBroadcastInternal
private void sendPackageRemovedBroadcastInternal(boolean killApp) {
......
if (removedPackage != null) {
packageSender.sendPackageBroadcast(Intent.ACTION_PACKAGE_REMOVED,
removedPackage, extras, 0, null /*targetPackage*/, null,
broadcastUsers, instantUserIds);发送ACTION_PACKAGE_REMOVED
if (installerPackageName != null) {
packageSender.sendPackageBroadcast(Intent.ACTION_PACKAGE_REMOVED,
removedPackage, extras, 0 /*flags*/,
installerPackageName, null, broadcastUsers, instantUserIds);
}
if (dataRemoved && !isRemovedPackageSystemUpdate) {
packageSender.sendPackageBroadcast(Intent.ACTION_PACKAGE_FULLY_REMOVED,
removedPackage, extras,
Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND,
null, null, broadcastUsers, instantUserIds);//发送ACTION_PACKAGE_FULLY_REMOVED
packageSender.notifyPackageRemoved(removedPackage, removedUid);
}
}
......
packageSender.sendPackageBroadcast(Intent.ACTION_UID_REMOVED,
null, extras, Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND,
null, null, broadcastUsers, instantUserIds);//发送ACTION_UID_REMOVED
删除应用的UML图:
PackageManagerService 类图
参考资料
1.Android PMS相关流程
https://blog.csdn.net/qq_31429205/article/details/105232472
2.Android PMS(二)-Apk安装流程
https://www.jianshu.com/p/3c2ed166e829