【安卓12源码】adb 的dumpsys和cmd实现原理

 主要分析下列 2 个流程:

// dump activity 的一些信息

adb shell dumpsys activity > D:\dumpsys\activity2.txt


// a11 打开 ActivityManagerDebugConfig 的开关
adb shell cmd activity log_switch enable DEBUG_ALL

1. 分析 adb shell dumpsys 实现过程

还可以使用下列命令dump 具体的组件

adb shell dumpsys activity -a a // -a 是dump全部,a 是 activities

/frameworks/native/cmds/dumpsys/main.cpp

int main(int argc, char* const argv[]) {
    signal(SIGPIPE, SIG_IGN);
    sp sm = defaultServiceManager();
    fflush(stdout);
    if (sm == nullptr) {
        ALOGE("Unable to get default service manager!");
        std::cerr << "dumpsys: Unable to get default service manager!" << std::endl;
        return 20;
    }

    Dumpsys dumpsys(sm.get());

// 执行 dumpsys 的 main 方法
    return dumpsys.main(argc, argv);
}

// 执行 dumpsys 的 main 方法

/frameworks/native/cmds/dumpsys/dumpsys.cpp

int Dumpsys::main(int argc, char* const argv[]) {
    Vector services;
    Vector args;
    String16 priorityType;
    Vector skippedServices;
    Vector protoServices;
    Type type = Type::DUMP;
。。。
    optind = 1;
。。。
    for (int i = optind; i < argc; i++) {
        if (skipServices) {
            skippedServices.add(String16(argv[i]));
        } else {

// 将输入的servicename 保存到 services 中,如adb shell dumpsys activity -a a
// 则将 activity 保存到 services 中
            if (i == optind) {
                services.add(String16(argv[i]));
            } else {
                const String16 arg(argv[i]);
// args 保存其他参数 -a a
                args.add(arg);

    const size_t N = services.size();
。。。。
    for (size_t i = 0; i < N; i++) {
        const String16& serviceName = services[i];
        if (IsSkipped(skippedServices, serviceName)) continue;

// 调用startDumpThread 方法  type 类型为 DUMP
        if (startDumpThread(type, serviceName, args) == OK) {
            bool addSeparator = (N > 1);
            if (addSeparator) {
                writeDumpHeader(STDOUT_FILENO, serviceName, priorityFlags);
            }
            std::chrono::duration elapsedDuration;
            size_t bytesWritten = 0;
// 输出结果
            status_t status =
                writeDump(STDOUT_FILENO, serviceName, std::chrono::milliseconds(timeoutArgMs),
                          asProto, elapsedDuration, bytesWritten);

==========
// 调用startDumpThread 方法  type 类型为 DUMP

status_t Dumpsys::startDumpThread(Type type, const String16& serviceName,
                                  const Vector& args) {

// 找到对应服务的客户端
    sp service = sm_->checkService(serviceName);
    if (service == nullptr) {
        std::cerr << "Can't find service: " << serviceName << std::endl;
        return NAME_NOT_FOUND;
    }

    int sfd[2];
// 管道通信
    if (pipe(sfd) != 0) {
        std::cerr << "Failed to create pipe to dump service info for " << serviceName << ": "
             << strerror(errno) << std::endl;
        return -errno;
    }

    redirectFd_ = unique_fd(sfd[0]);
    unique_fd remote_end(sfd[1]);
    sfd[0] = sfd[1] = -1;

    // dump blocks until completion, so spawn a thread..
    activeThread_ = std::thread([=, remote_end{std::move(remote_end)}]() mutable {
        status_t err = 0;

        switch (type) {
        case Type::DUMP:
// binder 通信调用dump 方法
            err = service->dump(remote_end.get(), args);
            break;

// binder 通信调用dump 方法

/frameworks/native/libs/binder/BpBinder.cpp

status_t BpBinder::dump(int fd, const Vector& args)
{
    Parcel send;
    Parcel reply;
// send 封装了文件描述符
    send.writeFileDescriptor(fd);
    const size_t numArgs = args.size();
    send.writeInt32(numArgs);
    for (size_t i = 0; i < numArgs; i++) {
// 保存了 args 参数
        send.writeString16(args[i]);
    }
    status_t err = transact(DUMP_TRANSACTION, send, &reply);
    return err;
}

=========
status_t BpBinder::transact(
    uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
{
    // Once a binder has died, it will never come back to life.
    if (mAlive) {
        bool privateVendor = flags & FLAG_PRIVATE_VENDOR;
        // don't send userspace flags to the kernel
        flags = flags & ~FLAG_PRIVATE_VENDOR;

        // user transactions require a given stability level
        if (code >= FIRST_CALL_TRANSACTION && code <= LAST_CALL_TRANSACTION) {
            using android::internal::Stability;

            auto stability = Stability::get(this);
            auto required = privateVendor ? Stability::VENDOR : Stability::kLocalStability;

            if (CC_UNLIKELY(!Stability::check(stability, required))) {
                ALOGE("Cannot do a user transaction on a %s binder in a %s context.",
                    Stability::stabilityString(stability).c_str(),
                    Stability::stabilityString(required).c_str());
                return BAD_TYPE;
            }
        }
/// 通过binder 驱动去找到对端服务器端
        status_t status = IPCThreadState::self()->transact(
            mHandle, code, data, reply, flags);

===========服务端执行流程===========

走到服务器端的 BBinder

/frameworks/base/core/jni/android_util_Binder.cpp

// javabinder 继承了 BBinder
class JavaBBinder : public BBinder
{
public:
    JavaBBinder(JNIEnv* env, jobject /* Java Binder */ object)
        : mVM(jnienv_to_javavm(env)), mObject(env->NewGlobalRef(object))
    {

。。。
    status_t onTransact(
        uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags = 0) override
    {
        JNIEnv* env = javavm_to_jnienv(mVM);

        ALOGV("onTransact() on %p calling object %p in env %p vm %p\n", this, mObject, env, mVM);

        IPCThreadState* thread_state = IPCThreadState::self();
        const int32_t strict_policy_before = thread_state->getStrictModePolicy();

        //printf("Transact from %p to Java code sending: ", this);
        //data.print();
        //printf("\n");

// 调用java 层的execTransact 方法
        jboolean res = env->CallBooleanMethod(mObject, gBinderOffsets.mExecTransact,
            code, reinterpret_cast(&data), reinterpret_cast(reply), flags);

// mExecTransact 为java 层的 execTransact 方法
    gBinderOffsets.mExecTransact = GetMethodIDOrDie(env, clazz, "execTransact", "(IJJI)Z");

// 调用java 层的execTransact 方法

/frameworks/base/core/java/android/os/Binder.java

    @UnsupportedAppUsage
    private boolean execTransact(int code, long dataObj, long replyObj,
            int flags) {
        // At that point, the parcel request headers haven't been parsed so we do not know what
        // WorkSource the caller has set. Use calling uid as the default.
        final int callingUid = Binder.getCallingUid();
        final long origWorkSource = ThreadLocalWorkSource.setUid(callingUid);
        try {
            return execTransactInternal(code, dataObj, replyObj, flags, callingUid);

===========

    private boolean execTransactInternal(int code, long dataObj, long replyObj, int flags,
            int callingUid) {
        final BinderInternal.Observer observer = sObserver;
        final CallSession callSession =
                observer != null ? observer.callStarted(this, code, UNSET_WORKSOURCE) : null;
        Parcel data = Parcel.obtain(dataObj);
        Parcel reply = Parcel.obtain(replyObj);
        boolean res;
        // Log any exceptions as warnings, don't silently suppress them.
        // If the call was FLAG_ONEWAY then these exceptions disappear into the ether.
        final boolean tracingEnabled = Binder.isTracingEnabled();
        try {

            if ((flags & FLAG_COLLECT_NOTED_APP_OPS) != 0) {
                AppOpsManager.startNotedAppOpsCollection(callingUid);
                try {
                    res = onTransact(code, data, reply, flags);
                } finally {
                    AppOpsManager.finishNotedAppOpsCollection();
                }
            } else {
// 调用 onTransact 方法
                res = onTransact(code, data, reply, flags);
            }

=============
    protected boolean onTransact(int code, @NonNull Parcel data, @Nullable Parcel reply,
            int flags) throws RemoteException {

// 如果是dump 命令,则执行 dump 方法
        } else if (code == DUMP_TRANSACTION) {
            ParcelFileDescriptor fd = data.readFileDescriptor();
            String[] args = data.readStringArray();
            if (fd != null) {
                try {
                    dump(fd.getFileDescriptor(), args);

// 如果是 adb shell cmd,则调用 shellCommand 方法
        } else if (code == SHELL_COMMAND_TRANSACTION) {
            ParcelFileDescriptor in = data.readFileDescriptor();
            ParcelFileDescriptor out = data.readFileDescriptor();
            ParcelFileDescriptor err = data.readFileDescriptor();
            String[] args = data.readStringArray();
            ShellCallback shellCallback = ShellCallback.CREATOR.createFromParcel(data);
            ResultReceiver resultReceiver = ResultReceiver.CREATOR.createFromParcel(data);
            try {
                if (out != null) {
                    shellCommand(in != null ? in.getFileDescriptor() : null,
                            out.getFileDescriptor(),
                            err != null ? err.getFileDescriptor() : out.getFileDescriptor(),
                            args, shellCallback, resultReceiver);
                }

=========
    public void dump(@NonNull FileDescriptor fd, @Nullable String[] args) {
        FileOutputStream fout = new FileOutputStream(fd);
        PrintWriter pw = new FastPrintWriter(fout);
        try {
            doDump(fd, pw, args);

=========
    void doDump(FileDescriptor fd, PrintWriter pw, String[] args) {
        final String disabled = sDumpDisabled;
        if (disabled == null) {
            try {
                dump(fd, pw, args);

 由 aidl 自动生成的  IActivityManager.Stub 是继承于Binder 对象的


public IActivityManager IRemoteService extends android.os.IInterface {

public static abstract class Stub extends android.os.Binder implements xxx

而 ActivityManagerService 是继承了 IActivityManager.Stub,所以走到其 dump(fd, pw, args) 方法

/frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java

10510      @Override
10511      protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
// 传入参数是 mPriorityDumper
10512          PriorityDump.dump(mPriorityDumper, fd, pw, args);
10513      }

=============

调用 PriorityDump 工具类的dump 方法

/frameworks/base/services/core/java/com/android/server/utils/PriorityDump.java 

    public static void dump(PriorityDumper dumper, FileDescriptor fd, PrintWriter pw,
            String[] args) {
        boolean asProto = false;
        @PriorityType int priority = PRIORITY_TYPE_INVALID;
...

        String[] strippedArgs = new String[args.length];
        int strippedCount = 0;
        for (int argIndex = 0; argIndex < args.length; argIndex++) {
            if (args[argIndex].equals(PROTO_ARG)) {
                asProto = true;
            } else if (args[argIndex].equals(PRIORITY_ARG)) {
                if (argIndex + 1 < args.length) {
                    argIndex++;
                    priority = getPriorityType(args[argIndex]);
                }
            } else {
// 分离出命令args 来
                strippedArgs[strippedCount++] = args[argIndex];
            }
        }

        if (strippedCount < args.length) {
            strippedArgs = Arrays.copyOf(strippedArgs, strippedCount);
        }

        switch (priority) {
...
            default: {
// 调用 PriorityDumper  去dump
                dumper.dump(fd, pw, strippedArgs, asProto);
                return;
            }
        }

// 调用 PriorityDumper  去dump

/frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java

674      private final PriorityDump.PriorityDumper mPriorityDumper = new PriorityDump.PriorityDumper() {
675          @Override
676          public void dumpCritical(FileDescriptor fd, PrintWriter pw, String[] args,
677                  boolean asProto) {
678              if (asProto) return;
679              doDump(fd, pw, new String[]{"activities"}, asProto);
680              doDump(fd, pw, new String[]{"service", "all-platform-critical"}, asProto);
681          }

。。。。。
687  
688          @Override
689          public void dump(FileDescriptor fd, PrintWriter pw, String[] args, boolean asProto) {

// dump 方法
690              doDump(fd, pw, args, asProto);
691          }
692      };

========

// dump 方法

10666      private void doDump(FileDescriptor fd, PrintWriter pw, String[] args, boolean useProto) {
10667          if (!DumpUtils.checkDumpAndUsageStatsPermission(mContext, TAG, pw)) return;
10668  
10669          boolean dumpAll = false;
10670          boolean dumpClient = false;
10671          boolean dumpCheckin = false;
10672          boolean dumpCheckinFormat = false;
10673          boolean dumpNormalPriority = false;
10674          boolean dumpVisibleStacksOnly = false;
10675          boolean dumpFocusedStackOnly = false;
10676          String dumpPackage = null;
10677  
10678          int opti = 0;
10679          while (opti < args.length) {
10680              String opt = args[opti];
10681              if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
10682                  break;
10683              }
10684              opti++;

// 先判断输入命令是否有 -a ,如果有则dump全部信息
10685              if ("-a".equals(opt)) {
10686                  dumpAll = true;

。。。

// useProto 为false
10718          if (useProto) {
10719              final ProtoOutputStream proto = new ProtoOutputStream(fd);
10720              String cmd = opti < args.length ? args[opti] : "";
10721              opti++;
。。。
10786          int dumpAppId = getAppId(dumpPackage);
10787          boolean more = false;
10788          // Is the caller requesting to dump a particular piece of data?
10789          if (opti < args.length) {
10790              String cmd = args[opti];
10791              opti++;

// DUMP_ACTIVITIES_CMD 为 activities,DUMP_ACTIVITIES_SHORT_CMD 为a
10792              if (DUMP_ACTIVITIES_CMD.equals(cmd) || DUMP_ACTIVITIES_SHORT_CMD.equals(cmd)
10793                      || DUMP_LASTANR_CMD.equals(cmd) || DUMP_LASTANR_TRACES_CMD.equals(cmd)
10794                      || DUMP_STARTER_CMD.equals(cmd) || DUMP_CONTAINERS_CMD.equals(cmd)
10795                      || DUMP_RECENTS_CMD.equals(cmd) || DUMP_RECENTS_SHORT_CMD.equals(cmd)) {
10796                  mAtmInternal.dump(
10797                          cmd, fd, pw, args, opti, true /* dumpAll */, dumpClient, dumpPackage);

调用 ActivityTaskManagerService 的方法

6979          @Override
6980          public void dump(String cmd, FileDescriptor fd, PrintWriter pw, String[] args, int opti,
6981                  boolean dumpAll, boolean dumpClient, String dumpPackage) {
6982              synchronized (mGlobalLock) {
6983                  if (DUMP_ACTIVITIES_CMD.equals(cmd) || DUMP_ACTIVITIES_SHORT_CMD.equals(cmd)) {
6984                      dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);

2. 分析 adb shell cmd 实现过程

adb shell cmd activity -h

/frameworks/native/cmds/cmd/main.cpp

int main(int argc, char* const argv[]) {
    signal(SIGPIPE, SIG_IGN);

    std::vector arguments;
    arguments.reserve(argc - 1);
    // 0th argument is a program name, skipping.
    for (int i = 1; i < argc; ++i) {
        arguments.emplace_back(argv[i]);
    }

// 调用 cmdMain 方法
    return cmdMain(arguments, android::aout, android::aerr, STDIN_FILENO, STDOUT_FILENO,
                   STDERR_FILENO, RunMode::kStandalone);

// 调用 cmdMain 方法

/frameworks/native/cmds/cmd/cmd.cpp

int cmdMain(const std::vector& argv, TextOutput& outputLog, TextOutput& errorLog,
            int in, int out, int err, RunMode runMode) {
    sp proc = ProcessState::self();
    proc->startThreadPool();

#if DEBUG
    ALOGD("cmd: starting");
#endif
    sp sm = defaultServiceManager();

    int argc = argv.size();

// 如果命令是:adb shell cmd -l 则列出所有的service 的名字
    if ((argc == 1) && (argv[0] == "-l")) {
        Vector services = sm->listServices();
        services.sort(sort_func);
// 会打印出下列string 值
        outputLog << "Currently running services:" << endl;

        for (size_t i=0; i service = sm->checkService(services[i]);
            if (service != nullptr) {
                outputLog << "  " << services[i] << endl;
            }
        }
        return 0;
    }

// 这里是 false 的
    bool waitForService = ((argc > 1) && (argv[0] == "-w"));
// index 的值为 0
    int serviceIdx = (waitForService) ? 1 : 0;
// cmd 为第一个参数为 servicename
    const auto cmd = argv[serviceIdx];

    Vector args;
// 通过cmd 获取到 servicename
    String16 serviceName = String16(cmd.data(), cmd.size());

// 遍历service 后面的参数,保存到 args 中
    for (int i = serviceIdx + 1; i < argc; i++) {
        args.add(String16(argv[i].data(), argv[i].size()));
    }
    sp service;
    if(waitForService) {
        service = sm->waitForService(serviceName);
    } else {

// 获取到对应的service
        service = sm->checkService(serviceName);
    }

。。。
    // TODO: block until a result is returned to MyResultReceiver.
// 调用 shellCommand 方法
    status_t error = IBinder::shellCommand(service, in, out, err, args, cb, result);
    if (error < 0) {

// 调用 shellCommand 方法

 /frameworks/native/libs/binder/Binder.cpp

status_t IBinder::shellCommand(const sp& target, int in, int out, int err,
    Vector& args, const sp& callback,
    const sp& resultReceiver)
{
    Parcel send;
    Parcel reply;
// 将传入的参数封装为 Parcel 
    send.writeFileDescriptor(in);
    send.writeFileDescriptor(out);
    send.writeFileDescriptor(err);
    const size_t numArgs = args.size();
    send.writeInt32(numArgs);
    for (size_t i = 0; i < numArgs; i++) {
        send.writeString16(args[i]);
    }
    send.writeStrongBinder(callback != nullptr ? IInterface::asBinder(callback) : nullptr);
    send.writeStrongBinder(resultReceiver != nullptr ? IInterface::asBinder(resultReceiver) : nullptr);

// 调用对应的service 的客户端去binder 通信
    return target->transact(SHELL_COMMAND_TRANSACTION, send, &reply);
}

如前面的分析也会调用 java 层的execTransact 方法

/frameworks/base/core/java/android/os/Binder.java

    private boolean execTransactInternal(int code, long dataObj, long replyObj, int flags,
            int callingUid) {
        final BinderInternal.Observer observer = sObserver;
        final CallSession callSession =
                observer != null ? observer.callStarted(this, code, UNSET_WORKSOURCE) : null;
        Parcel data = Parcel.obtain(dataObj);
        Parcel reply = Parcel.obtain(replyObj);
        boolean res;
        // Log any exceptions as warnings, don't silently suppress them.
        // If the call was FLAG_ONEWAY then these exceptions disappear into the ether.
        final boolean tracingEnabled = Binder.isTracingEnabled();
        try {

            if ((flags & FLAG_COLLECT_NOTED_APP_OPS) != 0) {
                AppOpsManager.startNotedAppOpsCollection(callingUid);
                try {
                    res = onTransact(code, data, reply, flags);
                } finally {
                    AppOpsManager.finishNotedAppOpsCollection();
                }
            } else {
// 调用 onTransact 方法
                res = onTransact(code, data, reply, flags);
            }

=============
    protected boolean onTransact(int code, @NonNull Parcel data, @Nullable Parcel reply,
            int flags) throws RemoteException {

// 如果是dump 命令,则执行 dump 方法
        } else if (code == DUMP_TRANSACTION) {
            ParcelFileDescriptor fd = data.readFileDescriptor();
            String[] args = data.readStringArray();
            if (fd != null) {
                try {
                    dump(fd.getFileDescriptor(), args);

// 如果是 adb shell cmd,则调用 shellCommand 方法
        } else if (code == SHELL_COMMAND_TRANSACTION) {
            ParcelFileDescriptor in = data.readFileDescriptor();
            ParcelFileDescriptor out = data.readFileDescriptor();
            ParcelFileDescriptor err = data.readFileDescriptor();
            String[] args = data.readStringArray();
            ShellCallback shellCallback = ShellCallback.CREATOR.createFromParcel(data);
            ResultReceiver resultReceiver = ResultReceiver.CREATOR.createFromParcel(data);
            try {
                if (out != null) {
                    shellCommand(in != null ? in.getFileDescriptor() : null,
                            out.getFileDescriptor(),
                            err != null ? err.getFileDescriptor() : out.getFileDescriptor(),
                            args, shellCallback, resultReceiver);
                }

================
// shellCommand 方法的实现
    public void shellCommand(@Nullable FileDescriptor in, @Nullable FileDescriptor out,
            @Nullable FileDescriptor err,
            @NonNull String[] args, @Nullable ShellCallback callback,
            @NonNull ResultReceiver resultReceiver) throws RemoteException {

// 同样去调用 ams 的 onShellCommand 方法
        onShellCommand(in, out, err, args, callback, resultReceiver);
    }

// 同样去调用 ams 的 onShellCommand 方法

/frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java

10502      @Override
10503      public void onShellCommand(FileDescriptor in, FileDescriptor out,
10504              FileDescriptor err, String[] args, ShellCallback callback,
10505              ResultReceiver resultReceiver) {

// 创建 ActivityManagerShellCommand 对象去执行 exec
10506          (new ActivityManagerShellCommand(this, false)).exec(
10507                  this, in, out, err, args, callback, resultReceiver);
10508      }

// 创建 ActivityManagerShellCommand 对象去执行 exec

/frameworks/base/services/core/java/com/android/server/am/ActivityManagerShellCommand.java

// 继承了 ShellCommand  方法
124  final class ActivityManagerShellCommand extends ShellCommand {
125      public static final String NO_CLASS_ERROR_CODE = "Error type 3";

/frameworks/base/core/java/android/os/ShellCommand.java

// ShellCommand 又继承了 BasicShellCommandHandler 
36  public abstract class ShellCommand extends BasicShellCommandHandler {
37      private ShellCallback mShellCallback;
38      private ResultReceiver mResultReceiver;
39  

// 执行 exec 方法
40      public int exec(Binder target, FileDescriptor in, FileDescriptor out, FileDescriptor err,
41              String[] args, ShellCallback callback, ResultReceiver resultReceiver) {
42          mShellCallback = callback;
43          mResultReceiver = resultReceiver;

// 调用父类BasicShellCommandHandler 的 exec 方法
44          final int result = super.exec(target, in, out, err, args);
45  

// 发送结果给cmd 进程
46          if (mResultReceiver != null) {
47              mResultReceiver.send(result, null);
48          }
49  
50          return result;
51      }

// 调用父类BasicShellCommandHandler 的 exec 方法

 /frameworks/base/core/java/android/os/BasicShellCommandHandler.java

75      public int exec(Binder target, FileDescriptor in, FileDescriptor out, FileDescriptor err,
76              String[] args) {
77          String cmd;
78          int start;
79          if (args != null && args.length > 0) {

// 获取adb shell cmd activity 后面的第一个参数 
80              cmd = args[0];
81              start = 1;
82          } else {
83              cmd = null;
84              start = 0;
85          }
86          init(target, in, out, err, args, start);
87          mCmd = cmd;
88  
89          if (DEBUG) {
90              RuntimeException here = new RuntimeException("here");
91              here.fillInStackTrace();
92              Log.d(TAG, "Starting command " + mCmd + " on " + mTarget, here);
93              Log.d(TAG, "Calling uid=" + Binder.getCallingUid()
94                      + " pid=" + Binder.getCallingPid());
95          }
96          int res = -1;
97          try {

// 回调子类ActivityManagerShellCommand.java的方法 onCommand
98              res = onCommand(mCmd);
99              if (DEBUG) Log.d(TAG, "Executed command " + mCmd + " on " + mTarget);

// 回调子类ActivityManagerShellCommand.java的方法 onCommand

/frameworks/base/services/core/java/com/android/server/am/ActivityManagerShellCommand.java

    @Override
    public int onCommand(String cmd) {
        if (cmd == null) {
            return handleDefaultCommands(cmd);
        }
        final PrintWriter pw = getOutPrintWriter();
        try {
            switch (cmd) {

// 启动activity 命令
                case "start":
                case "start-activity":
                    return runStartActivity(pw);

// 启动service 的命令
                case "startservice":
                case "start-service":
                    return runStartService(pw, false);

//如果都不满足上述情形,则执行 
                default:
                    return handleDefaultCommands(cmd);
            }

/frameworks/base/core/java/android/os/BasicShellCommandHandler.java

// 调用到 父类的方法
289      public int handleDefaultCommands(String cmd) {
290          if (cmd == null || "help".equals(cmd) || "-h".equals(cmd)) {
291              onHelp();

又调用到子类的方法

/frameworks/base/services/core/java/com/android/server/am/ActivityManagerShellCommand.java

    @Override
    public void onHelp() {
        PrintWriter pw = getOutPrintWriter();
// mDumping 为false
        dumpHelp(pw, mDumping);
    }

============
    static void dumpHelp(PrintWriter pw, boolean dumping) {
        if (dumping) {
。。。。。
        } else {
            pw.println("Activity manager (activity) commands:");
            pw.println("  help");
            pw.println("      Print this help text.");
            pw.println("  start-activity [-D] [-N] [-W] [-P ] [--start-profiler ]");

总结:

adb shell cmd 命令:

1. 对应命令会调用到service 的  onCommand

2. 帮助命令会调用到  onHelp

adb shell dumpsys 命令:

对应命令调用到 service 的 dump方法

你可能感兴趣的:(安卓源码解析,安卓源码,binder机制,adb,shell,dumpsys,cmd)