Android ADB实现解析

来源:互联网 发布:java pagecache 不释放 编辑:程序博客网 时间:2024/06/08 09:13
        ADB是Android系统提供的调试工具,整个ADB工具由三部分组成:adb client、adb service、adb daemon。
 1、ADB client
       提供HOST端运行的命令
 2、ADB service
       HOST端上的一个后台进程
 3、ADB daemom
       DEVICE端(真实的机器或者模拟器)的守护进程
       ADB代码位于/system/core/adb目录下,通过查看Android.mk,可以知道,该目录下的代码生成了两个MODULE,分别是adb和adbd,  adb client和adb service都是由adb这个可执行文件实现, adb daemon由adbd实现。adb和adbd的一些源代码文件是用同一个的,编译时通过LOCAL_CFLAGS的参数ADB_HOST来区分,这种你中有我我中有你的关系,对于初次接触的朋友们,多少增加了些困扰。理清了ADB几部分的关系,以及源代码的结构,对ADB的认识已经有一个飞越了。
 
        一、main函数
 
        adb.c的main函数是adb client、adb service、adb daemon的共同入口,
int main(int argc, char **argv){#if ADB_HOST    adb_sysdeps_init();    adb_trace_init();    D("Handling commandline()\n");    return adb_commandline(argc - 1, argv + 1);#else    /* If adbd runs inside the emulator this will enable adb tracing via     * adb-debug qemud service in the emulator. */    adb_qemu_trace_init();    if((argc > 1) && (!strcmp(argv[1],"recovery"))) {        adb_device_banner = "recovery";        recovery_mode = 1;    }    start_device_log();    D("Handling main()\n");    return adb_main(0, DEFAULT_ADB_PORT);#endif}
 
        根据Android.mk中传的ADB_HOST确定编译的是adb client\adb service, 或者是adb daemon, ADB_HOST为1时编译adb client\adb service的代码, ADB_HOST为0时编译adb daemon的代码。
 
        以上代码中,adb client\adb service端代码如,
    adb_sysdeps_init();    adb_trace_init();    D("Handling commandline()\n");    return adb_commandline(argc - 1, argv + 1);

       1、adb_sysdeps_init():  adb client\adb service适用于linux和windows版本,所以代码中有平台相关的部分。

       2、adb_trace_init():   初始化log输出配置,初始化后在HOST上设置ADB_TRACE这个环境变量,可以控制client\service端的log输出等级,

             配置为1或者all的话,将输出所有 的log。

       3、adb_commandline():  关键函数,代码如下。

 
int adb_commandline(int argc, char **argv){    char buf[4096];    int no_daemon = 0;    int is_daemon = 0;    int is_server = 0;    int persist = 0;    int r;    int quote;    transport_type ttype = kTransportAny;    char* serial = NULL;    char* server_port_str = NULL;        /* If defined, this should be an absolute path to         * the directory containing all of the various system images         * for a particular product.  If not defined, and the adb         * command requires this information, then the user must         * specify the path using "-p".         */    gProductOutPath = getenv("ANDROID_PRODUCT_OUT");    if (gProductOutPath == NULL || gProductOutPath[0] == '\0') {        gProductOutPath = NULL;    }    // TODO: also try TARGET_PRODUCT/TARGET_DEVICE as a hint    serial = getenv("ANDROID_SERIAL");    /* Validate and assign the server port */    server_port_str = getenv("ANDROID_ADB_SERVER_PORT");    int server_port = DEFAULT_ADB_PORT;    if (server_port_str && strlen(server_port_str) > 0) {        server_port = (int) strtol(server_port_str, NULL, 0);        if (server_port <= 0 || server_port > 65535) {            fprintf(stderr,                    "adb: Env var ANDROID_ADB_SERVER_PORT must be a positive number less than 65535. Got \"%s\"\n",                    server_port_str);            return usage();        }    }    /* modifiers and flags */    while(argc > 0) {        if(!strcmp(argv[0],"server")) {            is_server = 1;        } else if(!strcmp(argv[0],"nodaemon")) {            no_daemon = 1;        } else if (!strcmp(argv[0], "fork-server")) {            /* this is a special flag used only when the ADB client launches the ADB Server */            is_daemon = 1;        } else if(!strcmp(argv[0],"persist")) {            persist = 1;        } else if(!strncmp(argv[0], "-p", 2)) {            const char *product = NULL;            if (argv[0][2] == '\0') {                if (argc < 2) return usage();                product = argv[1];                argc--;                argv++;            } else {                product = argv[0] + 2;            }            gProductOutPath = find_product_out_path(product);            if (gProductOutPath == NULL) {                fprintf(stderr, "adb: could not resolve \"-p %s\"\n",                        product);                return usage();            }        } else if (argv[0][0]=='-' && argv[0][1]=='s') {            if (isdigit(argv[0][2])) {                serial = argv[0] + 2;            } else {                if(argc < 2 || argv[0][2] != '\0') return usage();                serial = argv[1];                argc--;                argv++;            }        } else if (!strcmp(argv[0],"-d")) {            ttype = kTransportUsb;        } else if (!strcmp(argv[0],"-e")) {            ttype = kTransportLocal;        } else if (!strcmp(argv[0],"-a")) {            gListenAll = 1;        } else if(!strncmp(argv[0], "-H", 2)) {            const char *hostname = NULL;            if (argv[0][2] == '\0') {                if (argc < 2) return usage();                hostname = argv[1];                argc--;                argv++;            } else {                hostname = argv[0] + 2;            }            adb_set_tcp_name(hostname);        } else if(!strncmp(argv[0], "-P", 2)) {            if (argv[0][2] == '\0') {                if (argc < 2) return usage();                server_port_str = argv[1];                argc--;                argv++;            } else {                server_port_str = argv[0] + 2;            }            if (strlen(server_port_str) > 0) {                server_port = (int) strtol(server_port_str, NULL, 0);                if (server_port <= 0 || server_port > 65535) {                    fprintf(stderr,                            "adb: port number must be a positive number less than 65536. Got \"%s\"\n",                            server_port_str);                    return usage();                }            } else {                fprintf(stderr,                "adb: port number must be a positive number less than 65536. Got empty string.\n");                return usage();            }        } else {                /* out of recognized modifiers and flags */            break;        }        argc--;        argv++;    }    adb_set_transport(ttype, serial);    adb_set_tcp_specifics(server_port);    if (is_server) {        if (no_daemon || is_daemon) {            r = adb_main(is_daemon, server_port);        } else {            r = launch_server(server_port);        }        if(r) {            fprintf(stderr,"* could not start server *\n");        }        return r;    }top:    if(argc == 0) {        return usage();    }    /* adb_connect() commands */    if(!strcmp(argv[0], "devices")) {        char *tmp;        char *listopt;        if (argc < 2)            listopt = "";        else if (argc == 2 && !strcmp(argv[1], "-l"))            listopt = argv[1];        else {            fprintf(stderr, "Usage: adb devices [-l]\n");            return 1;        }        snprintf(buf, sizeof buf, "host:%s%s", argv[0], listopt);        tmp = adb_query(buf);        if(tmp) {            printf("List of devices attached \n");            printf("%s\n", tmp);            return 0;        } else {            return 1;        }    }    if(!strcmp(argv[0], "connect")) {        char *tmp;        if (argc != 2) {            fprintf(stderr, "Usage: adb connect <host>[:<port>]\n");            return 1;        }        snprintf(buf, sizeof buf, "host:connect:%s", argv[1]);        tmp = adb_query(buf);        if(tmp) {            printf("%s\n", tmp);            return 0;        } else {            return 1;        }    }    if(!strcmp(argv[0], "disconnect")) {        char *tmp;        if (argc > 2) {            fprintf(stderr, "Usage: adb disconnect [<host>[:<port>]]\n");            return 1;        }        if (argc == 2) {            snprintf(buf, sizeof buf, "host:disconnect:%s", argv[1]);        } else {            snprintf(buf, sizeof buf, "host:disconnect:");        }        tmp = adb_query(buf);        if(tmp) {            printf("%s\n", tmp);            return 0;        } else {            return 1;        }    }    if (!strcmp(argv[0], "emu")) {        return adb_send_emulator_command(argc, argv);    }    if(!strcmp(argv[0], "shell") || !strcmp(argv[0], "hell")) {        int r;        int fd;        char h = (argv[0][0] == 'h');        if (h) {            printf("\x1b[41;33m");            fflush(stdout);        }        if(argc < 2) {            D("starting interactive shell\n");            r = interactive_shell();            if (h) {                printf("\x1b[0m");                fflush(stdout);            }            return r;        }        snprintf(buf, sizeof buf, "shell:%s", argv[1]);        argc -= 2;        argv += 2;        while(argc-- > 0) {            strcat(buf, " ");            /* quote empty strings and strings with spaces */            quote = (**argv == 0 || strchr(*argv, ' '));            if (quote)                strcat(buf, "\"");            strcat(buf, *argv++);            if (quote)                strcat(buf, "\"");        }        for(;;) {            D("interactive shell loop. buff=%s\n", buf);            fd = adb_connect(buf);            if(fd >= 0) {                D("about to read_and_dump(fd=%d)\n", fd);                read_and_dump(fd);                D("read_and_dump() done.\n");                adb_close(fd);                r = 0;            } else {                fprintf(stderr,"error: %s\n", adb_error());                r = -1;            }            if(persist) {                fprintf(stderr,"\n- waiting for device -\n");                adb_sleep_ms(1000);                do_cmd(ttype, serial, "wait-for-device", 0);            } else {                if (h) {                    printf("\x1b[0m");                    fflush(stdout);                }                D("interactive shell loop. return r=%d\n", r);                return r;            }        }    }    if(!strcmp(argv[0], "kill-server")) {        int fd;        fd = _adb_connect("host:kill");        if(fd == -1) {            fprintf(stderr,"* server not running *\n");            return 1;        }        return 0;    }    if(!strcmp(argv[0], "sideload")) {        if(argc != 2) return usage();        if(adb_download("sideload", argv[1], 1)) {            return 1;        } else {            return 0;        }    }    if(!strcmp(argv[0], "remount") || !strcmp(argv[0], "reboot")            || !strcmp(argv[0], "reboot-bootloader")            || !strcmp(argv[0], "tcpip") || !strcmp(argv[0], "usb")            || !strcmp(argv[0], "root")) {        char command[100];        if (!strcmp(argv[0], "reboot-bootloader"))            snprintf(command, sizeof(command), "reboot:bootloader");        else if (argc > 1)            snprintf(command, sizeof(command), "%s:%s", argv[0], argv[1]);        else            snprintf(command, sizeof(command), "%s:", argv[0]);        int fd = adb_connect(command);        if(fd >= 0) {            read_and_dump(fd);            adb_close(fd);            return 0;        }        fprintf(stderr,"error: %s\n", adb_error());        return 1;    }    if(!strcmp(argv[0], "bugreport")) {        if (argc != 1) return usage();        do_cmd(ttype, serial, "shell", "bugreport", 0);        return 0;    }    /* adb_command() wrapper commands */    if(!strncmp(argv[0], "wait-for-", strlen("wait-for-"))) {        char* service = argv[0];        if (!strncmp(service, "wait-for-device", strlen("wait-for-device"))) {            if (ttype == kTransportUsb) {                service = "wait-for-usb";            } else if (ttype == kTransportLocal) {                service = "wait-for-local";            } else {                service = "wait-for-any";            }        }        format_host_command(buf, sizeof buf, service, ttype, serial);        if (adb_command(buf)) {            D("failure: %s *\n",adb_error());            fprintf(stderr,"error: %s\n", adb_error());            return 1;        }        /* Allow a command to be run after wait-for-device,            * e.g. 'adb wait-for-device shell'.            */        if(argc > 1) {            argc--;            argv++;            goto top;        }        return 0;    }    if(!strcmp(argv[0], "forward")) {        char host_prefix[64];        char remove = 0;        char remove_all = 0;        char list = 0;        char no_rebind = 0;        // Parse options here.        while (argc > 1 && argv[1][0] == '-') {            if (!strcmp(argv[1], "--list"))                list = 1;            else if (!strcmp(argv[1], "--remove"))                remove = 1;            else if (!strcmp(argv[1], "--remove-all"))                remove_all = 1;            else if (!strcmp(argv[1], "--no-rebind"))                no_rebind = 1;            else {                return usage();            }            argc--;            argv++;        }        // Ensure we can only use one option at a time.        if (list + remove + remove_all + no_rebind > 1) {            return usage();        }        // Determine the <host-prefix> for this command.        if (serial) {            snprintf(host_prefix, sizeof host_prefix, "host-serial:%s",                    serial);        } else if (ttype == kTransportUsb) {            snprintf(host_prefix, sizeof host_prefix, "host-usb");        } else if (ttype == kTransportLocal) {            snprintf(host_prefix, sizeof host_prefix, "host-local");        } else {            snprintf(host_prefix, sizeof host_prefix, "host");        }        // Implement forward --list        if (list) {            if (argc != 1)                return usage();            snprintf(buf, sizeof buf, "%s:list-forward", host_prefix);            char* forwards = adb_query(buf);            if (forwards == NULL) {                fprintf(stderr, "error: %s\n", adb_error());                return 1;            }            printf("%s", forwards);            free(forwards);            return 0;        }        // Implement forward --remove-all        else if (remove_all) {            if (argc != 1)                return usage();            snprintf(buf, sizeof buf, "%s:killforward-all", host_prefix);        }        // Implement forward --remove <local>        else if (remove) {            if (argc != 2)                return usage();            snprintf(buf, sizeof buf, "%s:killforward:%s", host_prefix, argv[1]);        }        // Or implement one of:        //    forward <local> <remote>        //    forward --no-rebind <local> <remote>        else        {          if (argc != 3)            return usage();          const char* command = no_rebind ? "forward:norebind:" : "forward";          snprintf(buf, sizeof buf, "%s:%s:%s;%s", host_prefix, command, argv[1], argv[2]);        }        if(adb_command(buf)) {            fprintf(stderr,"error: %s\n", adb_error());            return 1;        }        return 0;    }    /* do_sync_*() commands */    if(!strcmp(argv[0], "ls")) {        if(argc != 2) return usage();        return do_sync_ls(argv[1]);    }    if(!strcmp(argv[0], "push")) {        if(argc != 3) return usage();        return do_sync_push(argv[1], argv[2], 0 /* no verify APK */);    }    if(!strcmp(argv[0], "pull")) {        if (argc == 2) {            return do_sync_pull(argv[1], ".");        } else if (argc == 3) {            return do_sync_pull(argv[1], argv[2]);        } else {            return usage();        }    }    if(!strcmp(argv[0], "install")) {        if (argc < 2) return usage();        return install_app(ttype, serial, argc, argv);    }    if(!strcmp(argv[0], "uninstall")) {        if (argc < 2) return usage();        return uninstall_app(ttype, serial, argc, argv);    }    if(!strcmp(argv[0], "sync")) {        char *srcarg, *android_srcpath, *data_srcpath;        int listonly = 0;        int ret;        if(argc < 2) {            /* No local path was specified. */            srcarg = NULL;        } else if (argc >= 2 && strcmp(argv[1], "-l") == 0) {            listonly = 1;            if (argc == 3) {                srcarg = argv[2];            } else {                srcarg = NULL;            }        } else if(argc == 2) {            /* A local path or "android"/"data" arg was specified. */            srcarg = argv[1];        } else {            return usage();        }        ret = find_sync_dirs(srcarg, &android_srcpath, &data_srcpath);        if(ret != 0) return usage();        if(android_srcpath != NULL)            ret = do_sync_sync(android_srcpath, "/system", listonly);        if(ret == 0 && data_srcpath != NULL)            ret = do_sync_sync(data_srcpath, "/data", listonly);        free(android_srcpath);        free(data_srcpath);        return ret;    }    /* passthrough commands */    if(!strcmp(argv[0],"get-state") ||        !strcmp(argv[0],"get-serialno") ||        !strcmp(argv[0],"get-devpath"))    {        char *tmp;        format_host_command(buf, sizeof buf, argv[0], ttype, serial);        tmp = adb_query(buf);        if(tmp) {            printf("%s\n", tmp);            return 0;        } else {            return 1;        }    }    /* other commands */    if(!strcmp(argv[0],"status-window")) {        status_window(ttype, serial);        return 0;    }    if(!strcmp(argv[0],"logcat") || !strcmp(argv[0],"lolcat") || !strcmp(argv[0],"longcat")) {        return logcat(ttype, serial, argc, argv);    }    if(!strcmp(argv[0],"ppp")) {        return ppp(argc, argv);    }    if (!strcmp(argv[0], "start-server")) {        return adb_connect("host:start-server");    }    if (!strcmp(argv[0], "backup")) {        return backup(argc, argv);    }    if (!strcmp(argv[0], "restore")) {        return restore(argc, argv);    }    if (!strcmp(argv[0], "jdwp")) {        int  fd = adb_connect("jdwp");        if (fd >= 0) {            read_and_dump(fd);            adb_close(fd);            return 0;        } else {            fprintf(stderr, "error: %s\n", adb_error());            return -1;        }    }    /* "adb /?" is a common idiom under Windows */    if(!strcmp(argv[0], "help") || !strcmp(argv[0], "/?")) {        help();        return 0;    }    if(!strcmp(argv[0], "version")) {        version(stdout);        return 0;    }    usage();    return 1;}
   adb_commandline解析adb命令,如adb devices,  关于某个命令具体执行过程,后面专门针对某个命令进行解析。
 
   main()中, adbd端代码如下,
   /* If adbd runs inside the emulator this will enable adb tracing via     * adb-debug qemud service in the emulator. */    adb_qemu_trace_init();    if((argc > 1) && (!strcmp(argv[1],"recovery"))) {        adb_device_banner = "recovery";        recovery_mode = 1;    }    start_device_log();    D("Handling main()\n");    return adb_main(0, DEFAULT_ADB_PORT);
  1、adb_qemu_trace_init():  建立和模拟器中的adb-debug qemud service的连接。
  2、if((argc > 1) && (!strcmp(argv[1],"recovery"))) {
            adb_device_banner = "recovery";
            recovery_mode = 1;
        }
     启动adbd的时候,可以加参数, 例如,在recovery模式中init.rc文件中的adbd service是带recovery参数的,如果带
     recovery参数就设置这两个标志,但目前没有看到哪里用到了这两个标志。
  3、start_device_log(): 配置adb daemon的log输出, 前面说了adb client和service端的log输出可以通过ADB_TRACE这个环境
     变量来控制,adb daemon端的log可以通过persist.adb.trace_mask控制, start_device_log()中判persist.adb.trace_mask
     的值,如果有值,就会将log输出到/data/adb/目录下。
  4、adb_main():如下
 
int adb_main(int is_daemon, int server_port){#if !ADB_HOST    int port;    char value[PROPERTY_VALUE_MAX];    umask(000);#endif    atexit(adb_cleanup);#ifdef HAVE_WIN32_PROC    SetConsoleCtrlHandler( ctrlc_handler, TRUE );#elif defined(HAVE_FORKEXEC)    // No SIGCHLD. Let the service subproc handle its children.    signal(SIGPIPE, SIG_IGN);#endif    init_transport_registration();#if ADB_HOST    HOST = 1;#ifdef WORKAROUND_BUG6558362    if(is_daemon) adb_set_affinity();#endif    usb_vendors_init();    usb_init();    local_init(DEFAULT_ADB_LOCAL_TRANSPORT_PORT);    adb_auth_init();    char local_name[30];    build_local_name(local_name, sizeof(local_name), server_port);    if(install_listener(local_name, "*smartsocket*", NULL, 0)) {        exit(1);    }#else    property_get("ro.adb.secure", value, "0");    auth_enabled = !strcmp(value, "1");    if (auth_enabled)        adb_auth_init();    // Our external storage path may be different than apps, since    // we aren't able to bind mount after dropping root.    const char* adb_external_storage = getenv("ADB_EXTERNAL_STORAGE");    if (NULL != adb_external_storage) {        setenv("EXTERNAL_STORAGE", adb_external_storage, 1);    } else {        D("Warning: ADB_EXTERNAL_STORAGE is not set.  Leaving EXTERNAL_STORAGE"          " unchanged.\n");    }    /* don't listen on a port (default 5037) if running in secure mode */    /* don't run as root if we are running in secure mode */    if (should_drop_privileges()) {        drop_capabilities_bounding_set_if_needed();        /* add extra groups:        ** AID_ADB to access the USB driver        ** AID_LOG to read system logs (adb logcat)        ** AID_INPUT to diagnose input issues (getevent)        ** AID_INET to diagnose network issues (netcfg, ping)        ** AID_GRAPHICS to access the frame buffer        ** AID_NET_BT and AID_NET_BT_ADMIN to diagnose bluetooth (hcidump)        ** AID_SDCARD_R to allow reading from the SD card        ** AID_SDCARD_RW to allow writing to the SD card        ** AID_MOUNT to allow unmounting the SD card before rebooting        ** AID_NET_BW_STATS to read out qtaguid statistics        */        gid_t groups[] = { AID_ADB, AID_LOG, AID_INPUT, AID_INET, AID_GRAPHICS,                           AID_NET_BT, AID_NET_BT_ADMIN, AID_SDCARD_R, AID_SDCARD_RW,                           AID_MOUNT, AID_NET_BW_STATS };        if (setgroups(sizeof(groups)/sizeof(groups[0]), groups) != 0) {            exit(1);        }        /* then switch user and group to "shell" */        if (setgid(AID_SHELL) != 0) {            exit(1);        }        if (setuid(AID_SHELL) != 0) {            exit(1);        }        D("Local port disabled\n");    } else {        char local_name[30];        build_local_name(local_name, sizeof(local_name), server_port);        if(install_listener(local_name, "*smartsocket*", NULL, 0)) {            exit(1);        }    }    int usb = 0;    if (access(USB_ADB_PATH, F_OK) == 0 || access(USB_FFS_ADB_EP0, F_OK) == 0) {        // listen on USB        usb_init();        usb = 1;    }    // If one of these properties is set, also listen on that port    // If one of the properties isn't set and we couldn't listen on usb,    // listen on the default port.    property_get("service.adb.tcp.port", value, "");    if (!value[0]) {        property_get("persist.adb.tcp.port", value, "");    }    if (sscanf(value, "%d", &port) == 1 && port > 0) {        printf("using port=%d\n", port);        // listen on TCP port specified by service.adb.tcp.port property        local_init(port);    } else if (!usb) {        // listen on default port        local_init(DEFAULT_ADB_LOCAL_TRANSPORT_PORT);    }    D("adb_main(): pre init_jdwp()\n");    init_jdwp();    D("adb_main(): post init_jdwp()\n");#endif    if (is_daemon)    {        // inform our parent that we are up and running.#ifdef HAVE_WIN32_PROC        DWORD  count;        WriteFile( GetStdHandle( STD_OUTPUT_HANDLE ), "OK\n", 3, &count, NULL );#elif defined(HAVE_FORKEXEC)        fprintf(stderr, "OK\n");#endif        start_logging();    }    D("Event loop starting\n");    fdevent_loop();    usb_cleanup();    return 0;}

        二、adb_main()函数
 
        上一节中已经附上adb_main()函数代码, 其中,adb service端的代码如下,
    usb_vendors_init();    usb_init();    local_init(DEFAULT_ADB_LOCAL_TRANSPORT_PORT);    adb_auth_init();    char local_name[30];    build_local_name(local_name, sizeof(local_name), server_port);    if(install_listener(local_name, "*smartsocket*", NULL, 0)) {        exit(1);    }          .........        start_logging();    }    D("Event loop starting\n");    fdevent_loop();    usb_cleanup();

    1、usb_vendors_init(): 每个设备产家都会定义一个vender id来标识自己的usb 设备,ADB service端只会连接已知的vender
     id,这个函数的作用就是初始化一个vender id的数组,初始化后这个数组中将包含adb代码中内建的一些产家的id以及HOST
     端的android配置文件中定义的id。
  2、usb_init(): 创建一个线程,线程处理函数device_poll_thread, 进入一个循环,每隔1s执行一次find_usb_device和 
     kick_disconnected_devices,find_usb_device搜索所有的usb设备,判断vender id是否在上面初始化的列表中,如果是,则
     将该usb设备注册到一个handle_list中。调用register_usb_transport基于这个fd 构造一个atransport类型的对象,再基于
     这atransport对象调用register_transport构造一个tmsg类型的对象。
     最后,将这个tmsg对象写到transport_registration_send个fd,  将触发相应的socket监控。kick_disconnected_devices
     判断adb设备是否还正常,不正常的话从handle_list中支掉。
  3、local_init(): 创建一个线程,尝试连接HOST端5555-5585端口,如果连接成功,则返回一个fd, register_socket_transport
     基于这个fd 构造一个atransport类型的对象,再基于这个atransport对象调用register_transport构造一个tmsg类型的
     对象。后,将这个tmsg对象写 transport_registration_send这个fd,  将触发相应的socket监控。
  4、install_listener():  监听"tcp:5037" ,  adb client与adb service之间通讯用这个端口。
  5、start_logging():  将stdin重写向到/dev/null, 将stdout、stderr重定向/tmp/adb.log, 然后输出"adb starting"到
     stderr。
  6、fdevent_loop():  前面通过fdinstall()注册了几个fde, 这里就通过一个无限循环epoll相应的fd,  有相应的事件则调用
     fdinstall时注册的处理函数。
  7、usb_cleanup(): usb相关的清理工作,对应linux平台的实现目前为空。

     其中,adb daemon端代码如下, 
    property_get("ro.adb.secure", value, "0");    auth_enabled = !strcmp(value, "1");    if (auth_enabled)        adb_auth_init();    // Our external storage path may be different than apps, since    // we aren't able to bind mount after dropping root.    const char* adb_external_storage = getenv("ADB_EXTERNAL_STORAGE");    if (NULL != adb_external_storage) {        setenv("EXTERNAL_STORAGE", adb_external_storage, 1);    } else {        D("Warning: ADB_EXTERNAL_STORAGE is not set.  Leaving EXTERNAL_STORAGE"          " unchanged.\n");    }    /* don't listen on a port (default 5037) if running in secure mode */    /* don't run as root if we are running in secure mode */    if (should_drop_privileges()) {        drop_capabilities_bounding_set_if_needed();        /* add extra groups:        ** AID_ADB to access the USB driver        ** AID_LOG to read system logs (adb logcat)        ** AID_INPUT to diagnose input issues (getevent)        ** AID_INET to diagnose network issues (netcfg, ping)        ** AID_GRAPHICS to access the frame buffer        ** AID_NET_BT and AID_NET_BT_ADMIN to diagnose bluetooth (hcidump)        ** AID_SDCARD_R to allow reading from the SD card        ** AID_SDCARD_RW to allow writing to the SD card        ** AID_MOUNT to allow unmounting the SD card before rebooting        ** AID_NET_BW_STATS to read out qtaguid statistics        */        gid_t groups[] = { AID_ADB, AID_LOG, AID_INPUT, AID_INET, AID_GRAPHICS,                           AID_NET_BT, AID_NET_BT_ADMIN, AID_SDCARD_R, AID_SDCARD_RW,                           AID_MOUNT, AID_NET_BW_STATS };        if (setgroups(sizeof(groups)/sizeof(groups[0]), groups) != 0) {            exit(1);        }        /* then switch user and group to "shell" */        if (setgid(AID_SHELL) != 0) {            exit(1);        }        if (setuid(AID_SHELL) != 0) {            exit(1);        }        D("Local port disabled\n");    } else {        char local_name[30];        build_local_name(local_name, sizeof(local_name), server_port);        if(install_listener(local_name, "*smartsocket*", NULL, 0)) {            exit(1);        }    }    int usb = 0;    if (access(USB_ADB_PATH, F_OK) == 0 || access(USB_FFS_ADB_EP0, F_OK) == 0) {        // listen on USB        usb_init();        usb = 1;    }    // If one of these properties is set, also listen on that port    // If one of the properties isn't set and we couldn't listen on usb,    // listen on the default port.    property_get("service.adb.tcp.port", value, "");    if (!value[0]) {        property_get("persist.adb.tcp.port", value, "");    }    if (sscanf(value, "%d", &port) == 1 && port > 0) {        printf("using port=%d\n", port);        // listen on TCP port specified by service.adb.tcp.port property        local_init(port);    } else if (!usb) {        // listen on default port        local_init(DEFAULT_ADB_LOCAL_TRANSPORT_PORT);    }    D("adb_main(): pre init_jdwp()\n");    init_jdwp();    D("adb_main(): post init_jdwp()\n");

   1、local_init():  adb daemon的这个函数与adb service端的有所不同,adb service端的local_init只在adb service初始化
      的时候扫描一下5555-5585端口,而adb daemon端的local_init会在线程中运行一个无限循环,不停尝试连接5555端口或者由
      service.adb.tcp.port\persist.adb.tcp.port设置的端口,因为作为daemon随时要准备为他人服务。  
   2、init_jdwp():  jdwp全称为java debug wire protocol, 每dalvik VM都会创建一个jdwp, 可以建立在adb或者tcp基础上,
      与DDMS或debugger进行通信, 这个函数就是初始化了监听socket描述符"\0jdwp-control"动作。
   
   adb daemon其它部分的代码与adb service都比较类似,可能参考adb service部分。

0 1
原创粉丝点击