Android adb 代码分析

adb 常用命令

adb devices
adb connect 192.168.43.xx
adb kill-server
adb push xx /sdcard/
adb pull /sdcard/xx
adb shell logcat

adb 代码分析

当输入adb devices的时候,发生了什么?
adb.c
int main(int argc, char **argv)
{
//ADB_HOST表示是运行 HOST端的,比如PC的commandline
#if ADB_HOST
    adb_sysdeps_init();
    adb_trace_init();
    D("Handling commandline()\n");
    return adb_commandline(argc - 1, argv + 1);
#else
}
int adb_commandline(int argc, char **argv)
{

#  define DEFAULT_ADB_PORT 5037
    int server_port = DEFAULT_ADB_PORT;
    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);
        //执行例如host:devices的命令
        tmp = adb_query(buf);
}
char *adb_query(const char *service)
{
    int fd = adb_connect(service);
    if(readx(fd, tmp, n) == 0) {
        tmp[n] = 0;
        adb_close(fd);
        return tmp;
    }
这里有几个比较重要的函数,adb_connect和readx以及adb_close,其中
adb_connect是与adb server建立一个socket连接,并且将service这个命令字符串通过socket的writex函数写到server端,并等待回应
readx从socket当中读取server的回应
adb_close就是关闭adb_connect和server建立的socket连接。
}
先看下adb_connect函数
int adb_connect(const char *service)
{
    int fd = _adb_connect("host:version");
    D("adb_connect: service %s\n", service);
    if(fd == -2 && __adb_server_name) {
        fprintf(stderr,"** Cannot start server on remote host\n");
        return fd;
    } else if(fd == -2) {
    //第一次敲adb命令时候,常见的输出log,表示server并没有启动,我们的命令执行前要先把adb server启动起来。
        fprintf(stdout,"* daemon not running. starting it now on port %d *\n",
                __adb_server_port);
    start_server:
        if(launch_server(__adb_server_port)) {
            fprintf(stderr,"* failed to start daemon *\n");
            return -1;
        } else {
            fprintf(stdout,"* daemon started successfully *\n");
        }
        /* give the server some time to start properly and detect devices */
        adb_sleep_ms(3000);
        // fall through to _adb_connect
    }
    //执行真正的命令,也就是我们的host:devices
    fd = _adb_connect(service);
}
中间插一下,这个adb server又是什么?
//以windows的代码为例:
int launch_server(int server_port)
{
#ifdef HAVE_WIN32_PROC
其中build/core/combo/include/arch/windows/AndroidConfig.h 里面有HAVE_WIN32_PROC的定义
#ifdef __CYGWIN__
#  define HAVE_FORKEXEC
#else
#  define HAVE_WIN32_PROC
#endif

    ret = CreateProcess(
            program_path,                              /* program path  */
            "adb fork-server server",
                                    /* the fork-server argument will set the
                                       debug = 2 in the child           */
            NULL,                   /* process handle is not inheritable */
            NULL,                    /* thread handle is not inheritable */
            TRUE,                          /* yes, inherit some handles */
            DETACHED_PROCESS, /* the new process doesn't have a console */
            NULL,                     /* use parent's environment block */
            NULL,                    /* use parent's starting directory */
            &startup,                 /* startup info, i.e. std handles */
            &pinfo );
        ret = ReadFile( pipe_read, temp, 3, &count, NULL );
        CloseHandle( pipe_read );
        if ( !ret ) {
            fprintf(stderr, "could not read ok from ADB Server, error = %ld\n", GetLastError() );
            return -1;
        }
        if (count != 3 || temp[0] != 'O' || temp[1] != 'K' || temp[2] != '\n') {
            fprintf(stderr, "ADB server didn't ACK\n" );
            return -1;
        }
}
以上函数创建了一个pipe,然后调用adb fork-server server,实际上是后台又重新run了一下adb 的命令,然后等待pipe回应OK的信息,表明server已经ready。

要再退回到
int adb_commandline(int argc, char **argv)
函数
         if(!strcmp(argv[0],"server")) {
            is_server = 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;
        }
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;
    }

int adb_main(int is_daemon/*1*/, int server_port /*5037*/)
{
//创建一对socket,有一个USB设备探测的线程,检测到USB设备变化,会往socket里面写内容,static void register_transport(atransport *transport)/remove_transport,另外read 的scoekt会接收到变化的信息transport_registration_func,这样devices就能遍历出设备
    init_transport_registration();
    usb_vendors_init();
    usb_init();  => 创建线程device_poll_thread,不停的遍历usb设备的变化。
    void* device_poll_thread(void* unused) {
  while(1) {
    find_devices();
    adb_sleep_ms(1000);
  }
}

//listen在server_port上,等待其他adb命令的client连接过来
    build_local_name(local_name, sizeof(local_name), server_port);  //tcp:
    if(install_listener(local_name, "*smartsocket*", NULL, 0)) {
        exit(1);
    }
    //有client连接上来的话,ss_listener_event_func负责处理
          =>  fdevent_install(&l->fde, l->fd, ss_listener_event_func, l);

//通知adb devices,server已经OK了
        WriteFile( GetStdHandle( STD_OUTPUT_HANDLE ), "OK\n", 3, &count, NULL );

//等待socket的变化,进行处理
    fdevent_loop();
}

所以adb server,实际上
1 遍历USB设备,监听USB设备的变化
2 创建了一个本地的:5037 TCP端口,等待其他adb命令的client连接过来,需要通过USB写下去的,就在这个sever当中处理。

继续分析adb devices剩下的几个函数
int _adb_connect(const char *service)
{
        fd = socket_loopback_client(__adb_server_port, SOCK_STREAM);
    if(writex(fd, tmp, 4) || writex(fd, service, len)) {
        strcpy(__adb_error, "write failure during connection");
        adb_close(fd);
        return -1;
    }
}
_adb_connect会连到上一章节adb server的socket 5037上,同时将service字符串通过write接口写下去,我们的字符串是host:devices
writex->adb_write->write
再调用readx得到adb server返回的结果
readx->adb_read->read

说明adb devices,命令做了:
1 启动adb server
2 通过socket将host:devices写给adb server
3 等待server的回应

继续看下server的处理函数
//前面提到 adb server负责处理client过来的socket连接,那么adb devices过来的host:devices是怎么样处理的呢?
static void ss_listener_event_func(int _fd, unsigned ev, void *_l)
{
    asocket *s;

    if(ev & FDE_READ) {
        struct sockaddr addr;
        socklen_t alen;
        int fd;

        alen = sizeof(addr);
//accept一个client的socket连接
        fd = adb_socket_accept(_fd, &addr, &alen);
        if(fd < 0) return;

        if(syc_size_enabled == 1) {
            adb_socket_setbufsize(fd, CHUNK_SIZE_CUSTOMIZE);
        } else {
            adb_socket_setbufsize(fd, CHUNK_SIZE);
        }
//构造一个asocket,插入到local_socket_list当中,并且由local_socket_event_func来处理这个socket的event,比如读写
        s = create_local_socket(fd);
        if(s) {
            connect_to_smartsocket(s);
            return;
        }

        XLOGD("ss_listener_event_func adb_close \n");
        adb_close(fd);
    }
}

static void local_socket_event_func(int fd, unsigned ev, void *_s)
            r = s->peer->enqueue(s->peer, p);
    s->enqueue = smart_socket_enqueue;
static int smart_socket_enqueue(asocket *s, apacket *p)
int handle_host_request(char *service, transport_type ttype, char* serial, int reply_fd, asocket *s)

这里真正处理了client过来的消息,比如host:devices
    // return a list of all connected devices
    if (!strncmp(service, "devices", 7)) {
        char buffer[4096];
        int use_long = !strcmp(service+7, "-l");
        if (use_long || service[7] == 0) {
            memset(buffer, 0, sizeof(buffer));
            D("Getting device list \n");
            list_transports(buffer, sizeof(buffer), use_long);
            D("Wrote device list \n");
            send_msg_with_okay(reply_fd, buffer, strlen(buffer));
            return 0;
        }
    }

通过adb连接设备的某个TCP服务

adb forward的功能是建立一个转发
adb forward tcp:11111 tcp:22222
的意思是,将PC端的11111端口收到的数据,转发给到手机中22222端口。但是光执行这个命令还不能转发数据,还需要完成两个步骤才能传数据。这两个步骤是:
(a)在手机端,建立一个端口为22222的server,并打开server到监听状态。
(b)在PC端,建立一个socket client端,连接到端口为11111的server上。

参考

https://blog.csdn.net/viewsky11/article/details/53889143
https://blog.csdn.net/u013553529/article/details/80036227

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值