经常在使用中的am & pm 命令,现在来看看里面到底是什么东西,以pm 为例:
在Android 6.0 中
cat /system/bin/pm
base=/system
export CLASSPATH=$base/framework/pm.jar
exec app_process $base/bin com.android.commands.pm.Pm "$@"
首先我们需要知道/system/bin/pm是一个可执行的shell 文件 在Android6.0中,这个shell 脚本文件实际上执行的是源文件是 frameworks/base/cmds/pm/src/com/android/commands/pm/Pm.java Pm->main->new Pm().run(args)->
public int run(String[] args) throws IOException, RemoteException {
......
这里省略了部分代码,只看关键部分
......
if ("list".equals(op)) {
return runList();
}
if ("path".equals(op)) {
return runPath();
}
if ("dump".equals(op)) {
return runDump();
}
if ("install".equals(op)) {
return runInstall();
}
if ("uninstall".equals(op)) {
return runUninstall();
}
if ("clear".equals(op)) {
return runClear();
}
...
这里省略了部分代码,只看关键部分
......
}
看到这里逻辑就很清楚了,根据参数做不同的处理。最后通过IPackageManager mPm = IPackageManager.Stub.asInterface(ServiceManager.getService(“package”)); 调用到PackageManagerService 里面去。
在Android 9.0 中
cat /system/bin/pm
#!/system/bin/sh
cmd package "$@"
cmd 是什么呢, which cmd 查看一下:
/system/bin/cmd
cmd 是一个二进制文件 frameworks/native/cmds/cmd/cmd.cpp
int main(int argc, char* const argv[])
{
....
sp<IServiceManager> sm = defaultServiceManager();
...
sp<IBinder> service = sm->checkService(cmd);
...
status_t err = IBinder::shellCommand(service, STDIN_FILENO, STDOUT_FILENO, STDERR_FILENO,
...
}
frameworks/base/services/core/java/com/android/server/pm/PackageManagerService.java
@Override
public void onShellCommand() {
(new PackageManagerShellCommand(this)).exec(
this, in, out, err, args, callback, resultReceiver);
}
frameworks/base/services/core/java/com/android/server/pm/PackageManagerShellCommand.java
public int onCommand(String cmd) {
...
try {
switch(cmd) {
case "path":
return runPath();
case "dump":
return runDump();
case "list":
return runList();
case "uninstall":
return runUninstall();
case "clear":
return runClear();
case "enable":
return runSetEnabledSetting(PackageManager.COMPONENT_ENABLED_STATE_ENABLED);
case "disable":
return runSetEnabledSetting(PackageManager.COMPONENT_ENABLED_STATE_DISABLED);
case "disable-user":
return runSetEnabledSetting(
PackageManager.COMPONENT_ENABLED_STATE_DISABLED_USER);
return uninstallSystemUpdates();
...
}
} catch (RemoteException e) {
pw.println("Remote exception: " + e);
}
return -1;
}
看到这里整体的脉络应该是比较清晰了.
|