AI手机网,短视频直播 硬改改机 一键新机 群控软件 刷机定制

 找回密码
 立即注册
搜索
查看: 2364|回复: 3

Android ADB工具 adb,adbd,client,server之间的关系

[复制链接]
发表于 2018-7-11 14:51:47 | 显示全部楼层 |阅读模式
adb和adbd分析

在adb中有三个模块,分别是adbd,adb server,adb client,如下表所示:

module name
process name
run as

adbd
adbd
device/emulator

adb server
windows: adb.exe linux: adb
client

adb client
such as eclipse, screencast,ddm app…and so on
client

adb server需要连接到adbd,这个连接叫adbconnect,这时候就可以通过客户端与设备端进行沟通,如下图:

具体的沟通交流层次如下图所示:

adbd是运行在设备端的一个守护进程,具体代码在adb.c中:

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); //adbd的入口#endif}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23

其中adb_main 函数是adbd进程的入口,执行“sevice adbd”时从这里开始调用。

在adbd中将会创建一对socket,一个用来控制连接,一个用来连接到adb client,adbd将会接收和发送信息与应用层的程序进行交流,如图所示:

数据结构

struct fdevent {    fdevent *next;    fdevent *prev;    int fd;    int force_eof;    unsigned short state;    unsigned short events;    fd_func func;    void *arg;};
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14

adb server将会扫描设备的5555到5585的奇数端口号,install_listener将会实施交互监听,如图所示:

adb server和adb client将会通过socket与设备端进行交流,端口号为5037,如下图:

adb使用PC机可以通过USB或网络与android设备通讯。
adb的源码位于system/core/adb目录下,先来看下编译脚本Android.mk:

# Copyright 2005 The Android Open Source Project## Android.mk for adb#LOCAL_PATH:= $(call my-dir)# adb host tool# =========================================================include $(CLEAR_VARS)# Default to a virtual (sockets) usb interfaceUSB_SRCS :=EXTRA_SRCS :=ifeq ($(HOST_OS),linux)  USB_SRCS := usb_linux.c  EXTRA_SRCS := get_my_path_linux.c  LOCAL_LDLIBS += -lrt -ldl -lpthread  LOCAL_CFLAGS += -DWORKAROUND_BUG6558362endififeq ($(HOST_OS),darwin)  USB_SRCS := usb_osx.c  EXTRA_SRCS := get_my_path_darwin.c  LOCAL_LDLIBS += -lpthread -framework CoreFoundation -framework IOKit -framework Carbonendififeq ($(HOST_OS),freebsd)  USB_SRCS := usb_libusb.c  EXTRA_SRCS := get_my_path_freebsd.c  LOCAL_LDLIBS += -lpthread -lusbendififeq ($(HOST_OS),windows)  USB_SRCS := usb_windows.c  EXTRA_SRCS := get_my_path_windows.c ../libcutils/list.c  EXTRA_STATIC_LIBS := AdbWinApi  ifneq ($(strip $(USE_CYGWIN)),)    # Pure cygwin case    LOCAL_LDLIBS += -lpthread -lgdi32    LOCAL_C_INCLUDES += /usr/include/w32api/ddk  endif  ifneq ($(strip $(USE_MINGW)),)    # MinGW under Linux case    LOCAL_LDLIBS += -lws2_32 -lgdi32    USE_SYSDEPS_WIN32 := 1    LOCAL_C_INCLUDES += /usr/i586-mingw32msvc/include/ddk  endif  LOCAL_C_INCLUDES += development/host/windows/usb/api/endifLOCAL_SRC_FILES := \    adb.c \    console.c \    transport.c \    transport_local.c \    transport_usb.c \    commandline.c \    adb_client.c \    adb_auth_host.c \    sockets.c \    services.c \    file_sync_client.c \    $(EXTRA_SRCS) \    $(USB_SRCS) \    utils.c \    usb_vendors.cLOCAL_C_INCLUDES += external/openssl/includeifneq ($(USE_SYSDEPS_WIN32),)  LOCAL_SRC_FILES += sysdeps_win32.celse  LOCAL_SRC_FILES += fdevent.cendifLOCAL_CFLAGS += -O2 -g -DADB_HOST=1  -Wall -Wno-unused-parameterLOCAL_CFLAGS += -D_XOPEN_SOURCE -D_GNU_SOURCELOCAL_MODULE := adbLOCAL_MODULE_TAGS := debugLOCAL_STATIC_LIBRARIES := libzipfile libunz libcrypto_static $(EXTRA_STATIC_LIBS)ifeq ($(USE_SYSDEPS_WIN32),)    LOCAL_STATIC_LIBRARIES += libcutilsendifinclude $(BUILD_HOST_EXECUTABLE)$(call dist-for-goals,dist_files sdk,$(LOCAL_BUILT_MODULE))ifeq ($(HOST_OS),windows)$(LOCAL_INSTALLED_MODULE): \    $(HOST_OUT_EXECUTABLES)/AdbWinApi.dll \    $(HOST_OUT_EXECUTABLES)/AdbWinUsbApi.dllendif# adbd device daemon# =========================================================include $(CLEAR_VARS)LOCAL_SRC_FILES := \    adb.c \    backup_service.c \    fdevent.c \    transport.c \    transport_local.c \    transport_usb.c \    adb_auth_client.c \    sockets.c \    services.c \    file_sync_service.c \    jdwp_service.c \    framebuffer_service.c \    remount_service.c \    usb_linux_client.c \    log_service.c \    utils.cLOCAL_CFLAGS := -O2 -g -DADB_HOST=0 -Wall -Wno-unused-parameterLOCAL_CFLAGS += -D_XOPEN_SOURCE -D_GNU_SOURCEifneq (,$(filter userdebug eng,$(TARGET_BUILD_VARIANT)))LOCAL_CFLAGS += -DALLOW_ADBD_ROOT=1endifLOCAL_MODULE := adbdLOCAL_FORCE_STATIC_EXECUTABLE := trueLOCAL_MODULE_PATH := $(TARGET_ROOT_OUT_SBIN)LOCAL_UNSTRIPPED_PATH := $(TARGET_ROOT_OUT_SBIN_UNSTRIPPED)LOCAL_STATIC_LIBRARIES := libcutils libc libmincryptinclude $(BUILD_EXECUTABLE)# adb host tool for device-as-host# =========================================================ifneq ($(SDK_ONLY),true)include $(CLEAR_VARS)LOCAL_LDLIBS := -lrt -ldl -lpthreadLOCAL_SRC_FILES := \    adb.c \    console.c \    transport.c \    transport_local.c \    transport_usb.c \    commandline.c \    adb_client.c \    adb_auth_host.c \    sockets.c \    services.c \    file_sync_client.c \    get_my_path_linux.c \    usb_linux.c \    utils.c \    usb_vendors.c \    fdevent.cLOCAL_CFLAGS := \    -O2 \    -g \    -DADB_HOST=1 \    -DADB_HOST_ON_TARGET=1 \    -Wall \    -Wno-unused-parameter \    -D_XOPEN_SOURCE \    -D_GNU_SOURCELOCAL_C_INCLUDES += external/openssl/includeLOCAL_MODULE := adbLOCAL_STATIC_LIBRARIES := libzipfile libunz libcutilsLOCAL_SHARED_LIBRARIES := libcryptoinclude $(BUILD_EXECUTABLE)endif
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
  • 128
  • 129
  • 130
  • 131
  • 132
  • 133
  • 134
  • 135
  • 136
  • 137
  • 138
  • 139
  • 140
  • 141
  • 142
  • 143
  • 144
  • 145
  • 146
  • 147
  • 148
  • 149
  • 150
  • 151
  • 152
  • 153
  • 154
  • 155
  • 156
  • 157
  • 158
  • 159
  • 160
  • 161
  • 162
  • 163
  • 164
  • 165
  • 166
  • 167
  • 168
  • 169
  • 170
  • 171
  • 172
  • 173
  • 174
  • 175
  • 176
  • 177
  • 178
  • 179
  • 180
  • 181
  • 182
  • 183
  • 184

通过编译,最终会有3个执行文件被生成,adbd和两个adb程序。
adbd是设备终端的守护进程;
adb一个是windows、linux、darwin或freebsd运行的程序,另一个是目标机上运行的程序。
其中宏ADB_HOST用于区分是PC端程序还是目标机端的程序。宏ADB_HOST_ON_TARGET用于区分adb程序是否是在目标机上运行。 这3个程序使用的是同一份源码,在内部,使用这些宏来区别不同的程序。

先来看adbd程序,此时宏的设置是ADB_HOST=0。在main函数代码中start_device_log()是log的初始化操作,可以重定向输出的log信息,接着进入adb_main()函数。
先来看下它的参数DEFAULT_ADB_PORT:

#if ADB_HOST_ON_TARGET/* adb and adbd are coexisting on the target, so use 5038 for adb * to avoid conflicting with adbd's usage of 5037 */#  define DEFAULT_ADB_PORT 5038#else#  define DEFAULT_ADB_PORT 5037#endif
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

如果是目标机程序,它的值是5038,否则它的值是5037。
这里没有定义ADB_HOST_ON_TARGET, 所以它是5037。
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();//初始化fevent transport_registration_fde#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");//判断系统属性ro.adb.secure,目标板没有设置这个宏    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) {  //没有定义环境变量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 */     /*根据android编译环境should_drop_privileges返回不同的值,如果它的值是userdebug或eng,宏ALLOW_ADBD_ROOT的值被定义为1,执行install_listener(),否则不会定义,这种情况下,由于adbd运行在root下,为保证它的安全性,它需要降级运行*/    if (should_drop_privileges()) {        struct __user_cap_header_struct header;        struct __user_cap_data_struct cap[2];        if (prctl(PR_SET_KEEPCAPS, 1, 0, 0, 0) != 0) {            exit(1);        }        drop_capabilities_bounding_set_if_needed();        memset(&header, 0, sizeof(header));        memset(cap, 0, sizeof(cap));        /* set CAP_SYS_BOOT capability, so "adb reboot" will succeed */        header.version = _LINUX_CAPABILITY_VERSION_3;        header.pid = 0;        cap[CAP_TO_INDEX(CAP_SYS_BOOT)].effective |= CAP_TO_MASK(CAP_SYS_BOOT);        cap[CAP_TO_INDEX(CAP_SYS_BOOT)].permitted |= CAP_TO_MASK(CAP_SYS_BOOT);        capset(&header, cap);        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);        }    }    //判断是否存在设备文件USB_ADB_PATH或USB_FFS_ADB_EP0,存在则执行usb_init()    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.     //读取属性service.adb.tcp.port或persist.adb.tcp.port,执行local_init(),它内部会创建adb thread    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 {        // listen on default port        local_init(DEFAULT_ADB_LOCAL_TRANSPORT_PORT);    }    D("adb_main(): pre init_jdwp()\n");    init_jdwp();//执行init_jdwp(),jdwp是Java调试体系中的一种    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();//调用fdevent_loop()监听fdevent并处理    usb_cleanup();    return 0;}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
  • 128
  • 129
  • 130
  • 131
  • 132
  • 133
  • 134

再来看adb程序的执行:
在main()中调用return adb_commandline(argc - 1, argv + 1):

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;}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
  • 128
  • 129
  • 130
  • 131
  • 132
  • 133
  • 134
  • 135
  • 136
  • 137
  • 138
  • 139
  • 140
  • 141
  • 142
  • 143
  • 144
  • 145
  • 146
  • 147
  • 148
  • 149
  • 150
  • 151
  • 152
  • 153
  • 154
  • 155
  • 156
  • 157
  • 158
  • 159
  • 160
  • 161
  • 162
  • 163
  • 164
  • 165
  • 166
  • 167
  • 168
  • 169
  • 170
  • 171
  • 172
  • 173
  • 174
  • 175
  • 176
  • 177
  • 178
  • 179
  • 180
  • 181
  • 182
  • 183
  • 184
  • 185
  • 186
  • 187
  • 188
  • 189
  • 190
  • 191
  • 192
  • 193
  • 194
  • 195
  • 196
  • 197
  • 198
  • 199
  • 200
  • 201
  • 202
  • 203
  • 204
  • 205
  • 206
  • 207
  • 208
  • 209
  • 210
  • 211
  • 212
  • 213
  • 214
  • 215
  • 216
  • 217
  • 218
  • 219
  • 220
  • 221
  • 222
  • 223
  • 224
  • 225
  • 226
  • 227
  • 228
  • 229
  • 230
  • 231
  • 232
  • 233
  • 234
  • 235
  • 236
  • 237
  • 238
  • 239
  • 240
  • 241
  • 242
  • 243
  • 244
  • 245
  • 246
  • 247
  • 248
  • 249
  • 250
  • 251
  • 252
  • 253
  • 254
  • 255
  • 256
  • 257
  • 258
  • 259
  • 260
  • 261
  • 262
  • 263
  • 264
  • 265
  • 266
  • 267
  • 268
  • 269
  • 270
  • 271
  • 272
  • 273
  • 274
  • 275
  • 276
  • 277
  • 278
  • 279
  • 280
  • 281
  • 282
  • 283
  • 284
  • 285
  • 286
  • 287
  • 288
  • 289
  • 290
  • 291
  • 292
  • 293
  • 294
  • 295
  • 296
  • 297
  • 298
  • 299
  • 300
  • 301
  • 302
  • 303
  • 304
  • 305
  • 306
  • 307
  • 308
  • 309
  • 310
  • 311
  • 312
  • 313
  • 314
  • 315
  • 316
  • 317
  • 318
  • 319
  • 320
  • 321
  • 322
  • 323
  • 324
  • 325
  • 326
  • 327
  • 328
  • 329
  • 330
  • 331
  • 332
  • 333
  • 334
  • 335
  • 336
  • 337
  • 338
  • 339
  • 340
  • 341
  • 342
  • 343
  • 344
  • 345
  • 346
  • 347
  • 348
  • 349
  • 350
  • 351
  • 352
  • 353
  • 354
  • 355
  • 356
  • 357
  • 358
  • 359
  • 360
  • 361
  • 362
  • 363
  • 364
  • 365
  • 366
  • 367
  • 368
  • 369
  • 370
  • 371
  • 372
  • 373
  • 374
  • 375
  • 376
  • 377
  • 378
  • 379
  • 380
  • 381
  • 382
  • 383
  • 384
  • 385
  • 386
  • 387
  • 388
  • 389
  • 390
  • 391
  • 392
  • 393
  • 394
  • 395
  • 396
  • 397
  • 398
  • 399
  • 400
  • 401
  • 402
  • 403
  • 404
  • 405
  • 406
  • 407
  • 408
  • 409
  • 410
  • 411
  • 412
  • 413
  • 414
  • 415
  • 416
  • 417
  • 418
  • 419
  • 420
  • 421
  • 422
  • 423
  • 424
  • 425
  • 426
  • 427
  • 428
  • 429
  • 430
  • 431
  • 432
  • 433
  • 434
  • 435
  • 436
  • 437
  • 438
  • 439
  • 440
  • 441
  • 442
  • 443
  • 444
  • 445
  • 446
  • 447
  • 448
  • 449
  • 450
  • 451
  • 452
  • 453
  • 454
  • 455
  • 456
  • 457
  • 458
  • 459
  • 460
  • 461
  • 462
  • 463
  • 464
  • 465
  • 466
  • 467
  • 468
  • 469
  • 470
  • 471
  • 472
  • 473
  • 474
  • 475
  • 476
  • 477
  • 478
  • 479
  • 480
  • 481
  • 482
  • 483
  • 484
  • 485
  • 486
  • 487
  • 488
  • 489
  • 490
  • 491
  • 492
  • 493
  • 494
  • 495
  • 496
  • 497
  • 498
  • 499
  • 500
  • 501
  • 502
  • 503
  • 504
  • 505
  • 506
  • 507
  • 508
  • 509
  • 510
  • 511
  • 512
  • 513
  • 514
  • 515
  • 516
  • 517
  • 518
  • 519
  • 520
  • 521
  • 522
  • 523
  • 524
  • 525
  • 526
  • 527
  • 528
  • 529
  • 530
  • 531
  • 532
  • 533
  • 534
  • 535
  • 536
  • 537
  • 538
  • 539
  • 540
  • 541
  • 542
  • 543
  • 544
  • 545
  • 546
  • 547
  • 548
  • 549
  • 550
  • 551
  • 552
  • 553
  • 554
  • 555
  • 556
  • 557
  • 558
  • 559
  • 560
  • 561
  • 562
  • 563
  • 564
  • 565
  • 566
  • 567
  • 568
  • 569
  • 570
  • 571
  • 572
  • 573
  • 574
  • 575
  • 576
  • 577
  • 578

adb_commandline 函数根据命令的参数执行不同的功能。adb程序可能以服务的方式或命令行客户端的方式运行。

使用usb进行调试,则执行usb_init(),它的代码在usb_linux_client.c 中,如下:

void usb_init(){    if (access(USB_FFS_ADB_EP0, F_OK) == 0)        usb_ffs_init();    else        usb_adb_init();}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

调用usb_adb_init():

static void usb_adb_init(){    usb_handle *h;    adb_thread_t tid;    int fd;    h = calloc(1, sizeof(usb_handle));    h->write = usb_adb_write;    h->read = usb_adb_read;    h->kick = usb_adb_kick;    h->fd = -1;    adb_cond_init(&h->notify, 0);    adb_mutex_init(&h->lock, 0);    // Open the file /dev/android_adb_enable to trigger     // the enabling of the adb USB function in the kernel.    // We never touch this file again - just leave it open    // indefinitely so the kernel will know when we are running    // and when we are not.    fd = unix_open("/dev/android_adb_enable", O_RDWR);    if (fd < 0) {       D("failed to open /dev/android_adb_enable\n");    } else {        close_on_exec(fd);    }    D("[ usb_init - starting thread ]\n");    if(adb_thread_create(&tid, usb_adb_open_thread, h)){        fatal_errno("cannot create usb thread");    }}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34

它初始化了usb_handle,并把它作为参数创建usb_adb_open_thread()线程。这里不能打开/dev/android_adb_enable。h->fd的值会在线程usb_adb_open_thread中赋值,并把它做为h->write(), h->read(), h->kick()的文件句柄,h->kick()函数功能是把h->fd置为-1。
usb_adb_open_thread的代码如下:

static void *usb_adb_open_thread(void *x){    struct usb_handle *usb = (struct usb_handle *)x;    int fd;    while (1) {        // wait until the USB device needs opening        adb_mutex_lock(&usb->lock);        while (usb->fd != -1)            adb_cond_wait(&usb->notify, &usb->lock);        adb_mutex_unlock(&usb->lock);        D("[ usb_thread - opening device ]\n");        do {            /* XXX use inotify? */            fd = unix_open("/dev/android_adb", O_RDWR);            if (fd < 0) {                // to support older kernels                fd = unix_open("/dev/android", O_RDWR);            }            if (fd < 0) {                adb_sleep_ms(1000);            }        } while (fd < 0);        D("[ opening device succeeded ]\n");        close_on_exec(fd);        usb->fd = fd;        D("[ usb_thread - registering device ]\n");        register_usb_transport(usb, 0, 0, 1);    }    // never gets here    return 0;}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36

这个线程的作用是一进入立即打开/dev/android_adb或/dev/Android,如果成功,则调用register_usb_transport()后再次循环,并阻塞在以下代码处

while(usb->fd != -1)   adb_cond_wait(&usb->notify, &usb->lock);
  • 1
  • 2
  • 3

当usb->kick()调用后fd的值被赋为-1,并发送cond唤醒上面的代码。

adb源码fdevent.c文件中定义了工作时创建、监听和处理读写事件。

static fdevent **fd_table = 0; //fd_table保存的是以fdevent->fd为索引保存的fdevent指针static int fd_table_max = 0;
  • 1
  • 2

the_fdevent的值等于fd_table[the_fdevent->fd]

static void fdevent_register(fdevent *fde){    if(fde->fd < 0) {        FATAL("bogus negative fd (%d)\n", fde->fd);    }    if(fde->fd >= fd_table_max) {  //初始化或自动增长fd_table         int oldmax = fd_table_max;        if(fde->fd > 32000) {            FATAL("bogus huuuuge fd (%d)\n", fde->fd);        }        if(fd_table_max == 0) {            fdevent_init();            fd_table_max = 256;        }        while(fd_table_max <= fde->fd) {            fd_table_max *= 2;        }        fd_table = realloc(fd_table, sizeof(fdevent*) * fd_table_max);        if(fd_table == 0) {            FATAL("could not expand fd_table to %d entries\n", fd_table_max);        }        memset(fd_table + oldmax, 0, sizeof(int) * (fd_table_max - oldmax));    }    fd_table[fde->fd] = fde; //将fde添加到fd_table}static void fdevent_unregister(fdevent *fde)  //这个函数即将fde从fd_table中删除  {    if((fde->fd < 0) || (fde->fd >= fd_table_max)) {        FATAL("fd out of range (%d)\n", fde->fd);    }    if(fd_table[fde->fd] != fde) {        FATAL("fd_table out of sync [%d]\n", fde->fd);    }    fd_table[fde->fd] = 0;    if(!(fde->state & FDE_DONT_CLOSE)) { //如果fde->fd打开了并没有关闭,需要执行关闭操作          dump_fde(fde, "close");        adb_close(fde->fd);    }}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46

其中fdevent是代码处理事件的载体,结构体定义如下

struct fdevent {    fdevent *next;    fdevent *prev; //表明是循环链表      int fd;    int force_eof;    unsigned short state; //低8位表示事件,高8位表示状态     unsigned short events;  //需要处理的事件    fd_func func; //事件处理回调函数    void *arg; //参数 };
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15

其中事件可以是:

/* events that may be observed */#define FDE_READ              0x0001#define FDE_WRITE             0x0002#define FDE_ERROR             0x0004#define FDE_TIMEOUT           0x0008/* features that may be set (via the events set/add/del interface) */#define FDE_DONT_CLOSE        0x0080
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

状态可以是:

#define FDE_ACTIVE     0x0100#define FDE_PENDING    0x0200#define FDE_CREATED    0x0400
  • 1
  • 2
  • 3

时间和状态的掩码分别为:

#define FDE_EVENTMASK  0x00ff#define FDE_STATEMASK  0xff00
  • 1
  • 2
  • 3

注意,这些状态是可以同时存在的。
当调用fdevent_create()后,FDE_CREATED标志被设置,当调用fdevent_install()后, FDE_CREATED标志被设置,但在fdevent_create()内部调用了fdevent_install(),所以调用fdevent_create()都被设置了。
当有事件在调用select发生后,相应的事件state会设置为FDE_PENDING,当事件处理完后这个标志又被删除。相应的代码是:

void fdevent_loop(){    fdevent *fde;    fdevent_subproc_setup();    for(;;) {        D("--- ---- waiting for events\n");        fdevent_process();///在这个函数中调用select,当有事件发生时,state被设置为FDE_PENDING,event也会被设置。所有的pending事件都会被保存在全局变量list_pending中。          while((fde = fdevent_plist_dequeue())) { //处理list_pending变量的事件            fdevent_call_fdfunc(fde);        }    }}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17

其中list_pending的相关代码:

//变量定义和初始化 static fdevent list_pending = {    .next = &list_pending,    .prev = &list_pending,};//添加一个元素 static void fdevent_plist_enqueue(fdevent *node){    fdevent *list = &list_pending;    node->next = list;    node->prev = list->prev;    node->prev->next = node;    list->prev = node;}//删除一个指定元素  static void fdevent_plist_remove(fdevent *node){    node->prev->next = node->next;    node->next->prev = node->prev;    node->next = 0;    node->prev = 0;}//从list中取出一个元素 static fdevent *fdevent_plist_dequeue(void){    fdevent *list = &list_pending;    fdevent *node = list->next;    if(node == list) return 0;    list->next = node->next;    list->next->prev = list;    node->next = 0;    node->prev = 0;    return node;}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42

事件的处理是阻塞方式的,可以有两种代码实现方法。定义宏CRAPTASTIC表示使用epoll的方式,否则使用select方式。这里只列举select的处理方式:

static fd_set read_fds;        //读事件集合  static fd_set write_fds;       //写事件集合  static fd_set error_fds;       //发生错误事件集合  static int select_n = 0;  static void fdevent_init(void)  //初始化  {      FD_ZERO(&read_fds);      FD_ZERO(&write_fds);      FD_ZERO(&error_fds);  }  static void fdevent_connect(fdevent *fde)   //添加  {      if(fde->fd >= select_n) {          select_n = fde->fd + 1;      }  }  static void fdevent_disconnect(fdevent *fde)  //从所有事件集合删除fde  {      int i, n;      FD_CLR(fde->fd, &read_fds);      FD_CLR(fde->fd, &write_fds);      FD_CLR(fde->fd, &error_fds);      for(n = 0, i = 0; i < select_n; i++) {          if(fd_table != 0) n = i;      }      select_n = n + 1;  }  static void fdevent_update(fdevent *fde, unsigned events)//根据events设置事件集合  {      if(events & FDE_READ) {          FD_SET(fde->fd, &read_fds);      } else {          FD_CLR(fde->fd, &read_fds);      }      if(events & FDE_WRITE) {          FD_SET(fde->fd, &write_fds);      } else {          FD_CLR(fde->fd, &write_fds);      }      if(events & FDE_ERROR) {          FD_SET(fde->fd, &error_fds);      } else {          FD_CLR(fde->fd, &error_fds);      }      fde->state = (fde->state & FDE_STATEMASK) | events;  }  /* Looks at fd_table[] for bad FDs and sets bit in fds. ** Returns the number of bad FDs. */  static int fdevent_fd_check(fd_set *fds) //通过调用fcntl来判断是否是一个有效的fdevent  {      int i, n = 0;      fdevent *fde;      for(i = 0; i < select_n; i++) {          fde = fd_table;          if(fde == 0) continue;          if(fcntl(i, F_GETFL, NULL) < 0) {              FD_SET(i, fds);              n++;              // fde->state |= FDE_DONT_CLOSE;          }      }      return n;  }  
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75

transport的原理是使用了fevent机制进行数据传输,atransport结构体的定义如下

struct atransport{    atransport *next;    atransport *prev;    int (*read_from_remote)(apacket *p, atransport *t);    int (*write_to_remote)(apacket *p, atransport *t);    void (*close)(atransport *t);    void (*kick)(atransport *t);    int fd;    int transport_socket;    fdevent transport_fde;    int ref_count;    unsigned sync_token;    int connection_state;    int online;    transport_type type;        /* usb handle or socket fd as needed */    usb_handle *usb;    int sfd;        /* used to identify transports for clients */    char *serial;    char *product;    char *model;    char *device;    char *devpath;    int adb_port; // Use for emulators (local transport)        /* a list of adisconnect callbacks called when the transport is kicked */    int          kicked;    adisconnect  disconnects;    void *key;    unsigned char token[TOKEN_SIZE];    fdevent auth_fde;    unsigned failed_auth_attempts;};
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42

它是一个双向链表,所有的实体都保存在全局数据transport_list中:

static atransport transport_list = {    .next = &transport_list,    .prev = &transport_list,};
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

atransport的数据传输的两个函数是:

static intread_packet(int  fd, const char* name, apacket** ppacket){    char *p = (char*)ppacket;  /* really read a packet address */    int   r;    int   len = sizeof(*ppacket);    char  buff[8];    if (!name) {        snprintf(buff, sizeof buff, "fd=%d", fd);        name = buff;    }    while(len > 0) {        r = adb_read(fd, p, len);        if(r > 0) {            len -= r;            p   += r;        } else {            D("%s: read_packet (fd=%d), error ret=%d errno=%d: %s\n", name, fd, r, errno, strerror(errno));            if((r < 0) && (errno == EINTR)) continue;            return -1;        }    }#if ADB_TRACE    if (ADB_TRACING) {        dump_packet(name, "from remote", *ppacket);    }#endif    return 0;}static intwrite_packet(int  fd, const char* name, apacket** ppacket){    char *p = (char*) ppacket;  /* we really write the packet address */    int r, len = sizeof(ppacket);    char buff[8];    if (!name) {        snprintf(buff, sizeof buff, "fd=%d", fd);        name = buff;    }#if ADB_TRACE    if (ADB_TRACING) {        dump_packet(name, "to remote", *ppacket);    }#endif    len = sizeof(ppacket);    while(len > 0) {        r = adb_write(fd, p, len);        if(r > 0) {            len -= r;            p += r;        } else {            D("%s: write_packet (fd=%d) error ret=%d errno=%d: %s\n", name, fd, r, errno, strerror(errno));            if((r < 0) && (errno == EINTR)) continue;            return -1;        }    }    return 0;}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63

这是它的内部传输接口,注意传输的是apacket的数据内部。
外部接口的数据传输接口是:

static void transport_socket_events(int fd, unsigned events, void *_t){    atransport *t = _t;    D("transport_socket_events(fd=%d, events=%04x,...)\n", fd, events);    if(events & FDE_READ){        apacket *p = 0;        if(read_packet(fd, t->serial, &p)){            D("%s: failed to read packet from transport socket on fd %d\n", t->serial, fd);        } else {            handle_packet(p, (atransport *) _t);        }    }} void send_packet(apacket *p, atransport *t){    unsigned char *x;    unsigned sum;    unsigned count;    p->msg.magic = p->msg.command ^ 0xffffffff;    count = p->msg.data_length;    x = (unsigned char *) p->data;    sum = 0;    while(count-- > 0){        sum += *x++;    }    p->msg.data_check = sum;    print_packet("send", p);    if (t == NULL) {        D("Transport is null \n");        // Zap errno because print_packet() and other stuff have errno effect.        errno = 0;        fatal_errno("Transport is null");    }    if(write_packet(t->transport_socket, t->serial, &p)){        fatal_errno("cannot enqueue packet on transport socket");    }}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45

物理接口到atransport的接口是:

/* The transport is opened by transport_register_func before** the input and output threads are started.**** The output thread issues a SYNC(1, token) message to let** the input thread know to start things up.  In the event** of transport IO failure, the output thread will post a** SYNC(0,0) message to ensure shutdown.**** The transport will not actually be closed until both** threads exit, but the input thread will kick the transport** on its way out to disconnect the underlying device.*/static void *output_thread(void *_t){    atransport *t = _t;    apacket *p;    D("%s: starting transport output thread on fd %d, SYNC online (%d)\n",       t->serial, t->fd, t->sync_token + 1);    p = get_apacket();    p->msg.command = A_SYNC;    p->msg.arg0 = 1;    p->msg.arg1 = ++(t->sync_token);    p->msg.magic = A_SYNC ^ 0xffffffff;    if(write_packet(t->fd, t->serial, &p)) {        put_apacket(p);        D("%s: failed to write SYNC packet\n", t->serial);        goto oops;    }    D("%s: data pump started\n", t->serial);    for(;;) {        p = get_apacket();        if(t->read_from_remote(p, t) == 0){            D("%s: received remote packet, sending to transport\n",              t->serial);            if(write_packet(t->fd, t->serial, &p)){                put_apacket(p);                D("%s: failed to write apacket to transport\n", t->serial);                goto oops;            }        } else {            D("%s: remote read failed for transport\n", t->serial);            put_apacket(p);            break;        }    }    D("%s: SYNC offline for transport\n", t->serial);    p = get_apacket();    p->msg.command = A_SYNC;    p->msg.arg0 = 0;    p->msg.arg1 = 0;    p->msg.magic = A_SYNC ^ 0xffffffff;    if(write_packet(t->fd, t->serial, &p)) {        put_apacket(p);        D("%s: failed to write SYNC apacket to transport", t->serial);    }oops:    D("%s: transport output thread is exiting\n", t->serial);    kick_transport(t);    transport_unref(t);    return 0;}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69

这里做了一个物理到抽象的转换。最上层还有一层是tmsg的传输 , tmsg的作用是用于atransport的管理

void init_transport_registration(void){    int s[2];    if(adb_socketpair(s)){        fatal_errno("cannot open transport registration socketpair");    }    transport_registration_send = s[0];    transport_registration_recv = s[1];    fdevent_install(&transport_registration_fde,                    transport_registration_recv,                    transport_registration_func,                    0);    fdevent_set(&transport_registration_fde, FDE_READ);}/* the fdevent select pump is single threaded */static void register_transport(atransport *transport){    tmsg m;    m.transport = transport;    m.action = 1;    D("transport: %s registered\n", transport->serial);    if(transport_write_action(transport_registration_send, &m)) {        fatal_errno("cannot write transport registration socket\n");    }}static void remove_transport(atransport *transport){    tmsg m;    m.transport = transport;    m.action = 0;    D("transport: %s removed\n", transport->serial);    if(transport_write_action(transport_registration_send, &m)) {        fatal_errno("cannot write transport registration socket\n");    }}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42

未完待续。。。



 楼主| 发表于 2018-7-11 14:52:45 | 显示全部楼层
Android ADB工具 adb,adbd,client,server之间的关系

不多说我放一张图 可以看出他们之间的大致关系
adb 是在用户HOST端,adbd是在设备端(emulator/real device)

adb

大致流程是这样的
1、client调用某个adb命令
2、adb进程fork出一个子进程作为server
3、server查找当前连接的emulator/device
4、server接收到来自client请求
5、server处理请求,将本地处理不了的请求发给emulator/device
6、位于emulator/device的adbd拿到请求后交给对应的java虚拟机进程。
7、adbd将结果发回给server
8、server将结果发回给client
发表于 2018-7-31 16:35:04 | 显示全部楼层

就算花钱可以下载我也不带水的
发表于 2018-9-2 21:06:34 | 显示全部楼层
学习学习,谢谢分享………………
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

技术交流售后群

QQ|小黑屋|手机版|站点找错-建议|AI手机网 |Sitemap



GMT+8, 2024-4-20 19:51 , Processed in 0.187382 second(s), 27 queries .

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表