android adb源码分析(5)【转】
本文转载自:http://blog.csdn.net/xgbing/article/details/52096880
本篇以“adb devices"命令为例,跟踪代码的执行流程。
(1) main()->
(2)adb_commandline()->
adb_commandline()中的相关源码:
- 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); //传递的buf=”host:devices”
- if(tmp) { //命令执行成功,打印出信息
- printf("List of devices attached \n");
- printf("%s\n", tmp);
- return 0;
- } else {///失败
- return 1;
- }
- }
(3) adb_query():adb_query: host:devices ->
- char *adb_query(const char *service) //函数返回设备信息字符串
- {
- char buf[5];
- unsigned n;
- char *tmp;
- D("adb_query: %s\n", service);
- int fd = adb_connect(service); //连接adbserver,返回fd
- if(fd < 0) {
- fprintf(stderr,"error: %s\n", __adb_error);
- return 0;
- }
- if(readx(fd, buf, 4)) goto oops; //读取数据长度,如果失败则返回错误
- buf[4] = 0;
- n = strtoul(buf, 0, 16); //转换成数值
- if(n > 1024) goto oops;
- tmp = malloc(n + 1); //申请空间
- if(tmp == 0) goto oops;
- if(readx(fd, tmp, n) == 0) { //读取信息并返回
- tmp[n] = 0;
- adb_close(fd);
- return tmp;
- }
- free(tmp);
- oops:
- adb_close(fd);
- return 0;
- }
(4) adb_connect()->
这个函数的作用是连接adb server,如果adb server没有启动则先启动它。
- int adb_connect(const char *service)
- {
- // first query the adb server's version
- int fd = _adb_connect("host:version"); //查询adb server的版本信息,用来判断它是否启动。
- D("adb_connect: service %s\n", service);
- if(fd == -2) { //查询不到adb server
- fprintf(stdout,"* daemon not running. starting it now on port %d *\n",
- __adb_server_port);
- start_server: //启动adb server
- if(launch_server(__adb_server_port)) { //启动adb server失败
- 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
- } else {//查询到adb server版本信息,说明adb server 已经启动
- // if server was running, check its version to make sure it is not out of date
- char buf[100];
- int n;
- int version = ADB_SERVER_VERSION - 1;
- // if we have a file descriptor, then parse version result
- if(fd >= 0) {
- if(readx(fd, buf, 4)) goto error; //读取版本信息的长度
- buf[4] = 0;
- n = strtoul(buf, 0, 16);
- if(n > (int)sizeof(buf)) goto error;
- if(readx(fd, buf, n)) goto error;//读取版本信息
- adb_close(fd);
- if (sscanf(buf, "%04x", &version) != 1) goto error;//转换字符串的版本为数值型
- } else { //fd返回的值表示adb server可能不支持读取版本信息
- // if fd is -1, then check for "unknown host service",
- // which would indicate a version of adb that does not support the version command
- if (strcmp(__adb_error, "unknown host service") != 0)
- return fd; //返回错误。
- }
- if(version != ADB_SERVER_VERSION) {
- printf("adb server is out of date. killing...\n");
- fd = _adb_connect("host:kill");
- adb_close(fd);
- /* XXX can we better detect its death? */
- adb_sleep_ms(2000);
- goto start_server; //版本信息过期则关闭adb server并重新启动。
- }
- }
- // if the command is start-server, we are done.
- if (!strcmp(service, "host:start-server")) //如果命令是start-server,执行到这就可以了
- return 0;
- //下面的代码连接adb server并返回fd。
- fd = _adb_connect(service); //连接adb server 并返回fd。
- if(fd == -2) {
- fprintf(stderr,"** daemon still not running");
- }
- D("adb_connect: return fd %d\n", fd);
- return fd;
- error:
- adb_close(fd);
- return -1;
- }
(5) launch_server()
- #if ADB_HOST
- int launch_server(int server_port)
- {
- #ifdef HAVE_WIN32_PROC
- /* we need to start the server in the background */
- /* we create a PIPE that will be used to wait for the server's "OK" */
- /* message since the pipe handles must be inheritable, we use a */
- /* security attribute */
- HANDLE pipe_read, pipe_write;
- SECURITY_ATTRIBUTES sa;
- STARTUPINFO startup;
- PROCESS_INFORMATION pinfo;
- char program_path[ MAX_PATH ];
- int ret;
- sa.nLength = sizeof(sa);
- sa.lpSecurityDescriptor = NULL;
- sa.bInheritHandle = TRUE;
- /* create pipe, and ensure its read handle isn't inheritable */
- ret = CreatePipe( &pipe_read, &pipe_write, &sa, 0 );
- if (!ret) {
- fprintf(stderr, "CreatePipe() failure, error %ld\n", GetLastError() );
- return -1;
- }
- SetHandleInformation( pipe_read, HANDLE_FLAG_INHERIT, 0 );
- ZeroMemory( &startup, sizeof(startup) );
- startup.cb = sizeof(startup);
- startup.hStdInput = GetStdHandle( STD_INPUT_HANDLE );
- startup.hStdOutput = pipe_write;
- startup.hStdError = GetStdHandle( STD_ERROR_HANDLE );
- startup.dwFlags = STARTF_USESTDHANDLES;
- ZeroMemory( &pinfo, sizeof(pinfo) );
- /* get path of current program */
- GetModuleFileName( NULL, program_path, sizeof(program_path) );
- //创建进程“adb fork-server server”,并把startup信息传给新进程。
- 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 );
- CloseHandle( pipe_write );
- if (!ret) {
- fprintf(stderr, "CreateProcess failure, error %ld\n", GetLastError() );
- CloseHandle( pipe_read );
- return -1;
- }
- CloseHandle( pinfo.hProcess );
- CloseHandle( pinfo.hThread );
- /* wait for the "OK\n" message */
- {
- char temp[3];
- DWORD count;
- //等待新进程发送“OK”到pipe_read管道。
- 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;
- }
- }
- #elif defined(HAVE_FORKEXEC)
- char path[PATH_MAX];
- int fd[2];
- // set up a pipe so the child can tell us when it is ready.
- // fd[0] will be parent's end, and fd[1] will get mapped to stderr in the child.
- if (pipe(fd)) {
- fprintf(stderr, "pipe failed in launch_server, errno: %d\n", errno);
- return -1;
- }
- get_my_path(path, PATH_MAX);
- pid_t pid = fork();
- if(pid < 0) return -1;
- if (pid == 0) { //下面的代码在子进程中运行
- // child side of the fork
- // redirect stderr to the pipe
- // we use stderr instead of stdout due to stdout's buffering behavior.
- adb_close(fd[0]);
- dup2(fd[1], STDERR_FILENO); //重定向新进程的错误信息给fd[1]
- adb_close(fd[1]);
- // child process 运行”adb fok-server server”程序。
- int result = execl(path, "adb", "fork-server", "server", NULL);
- // this should not return
- fprintf(stderr, "OOPS! execl returned %d, errno: %d\n", result, errno);
- } else {//下面的代码还是在这个进程中执行
- // parent side of the fork
- char temp[3];
- temp[0] = 'A'; temp[1] = 'B'; temp[2] = 'C';
- // wait for the "OK\n" message
- adb_close(fd[1]);
- int ret = adb_read(fd[0], temp, 3); //等待新进程发送“OK”字符串。
- int saved_errno = errno;
- adb_close(fd[0]);
- if (ret < 0) {
- fprintf(stderr, "could not read ok from ADB Server, errno = %d\n", saved_errno);
- return -1;
- }
- if (ret != 3 || temp[0] != 'O' || temp[1] != 'K' || temp[2] != '\n') {//接收字符错误。
- fprintf(stderr, "ADB server didn't ACK\n" );
- return -1;
- }
- setsid();
- }
- #else
- #error "cannot implement background server start on this platform"
- #endif
- return 0;
- }
- #endif
再来看看”adb fork-server server”的运行。
(1) main()->adb_commandline();
- /* 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 {
- /* 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;
- }
这里将is_daemon和is_server都置为1,并调用adb_main(1, 5037);
(2) adb_main()
- int adb_main(int is_daemon, int server_port)
- {
- #if ADB_HOST
- HOST = 1;
- usb_vendors_init();
- usb_init(); //监听USB端口数据
- local_init(DEFAULT_ADB_LOCAL_TRANSPORT_PORT); //初始化建立5555网口信道
- adb_auth_init();
- char local_name[30];
- build_local_name(local_name, sizeof(local_name), server_port); //监听5037端口
- if(install_listener(local_name, "*smartsocket*", NULL)) {
- exit(1);
- }
- #else
- …
- #endif
- if (is_daemon)
- {
- // inform our parent that we are up and running.
- //发送“OK”给父进程
- #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;
- }
(3) usb_linux.c中的usb_init()
- void usb_init()
- {
- adb_thread_t tid;
- struct sigaction actions;
- memset(&actions, 0, sizeof(actions));
- sigemptyset(&actions.sa_mask);
- actions.sa_flags = 0;
- actions.sa_handler = sigalrm_handler;
- sigaction(SIGALRM,& actions, NULL);
- if(adb_thread_create(&tid, device_poll_thread, NULL)){
- fatal_errno("cannot create input thread");
- }
- }
- void* device_poll_thread(void* unused)
- {
- D("Created device thread\n");
- for(;;) {
- /* XXX use inotify */
- find_usb_device("/dev/bus/usb", register_device);
- kick_disconnected_devices();
- sleep(1);
- }
- return NULL;
- }
在register_device()函数中最终会调用register_usb_transport()。
(4) install_listener(local_name, "*smartsocket*", NULL)
- if(!strcmp(l->connect_to, "*smartsocket*")) {
- fdevent_install(&l->fde, l->fd, ss_listener_event_func, l);
- } else {
- fdevent_install(&l->fde, l->fd, listener_event_func, l);
- }
- fdevent_set(&l->fde, FDE_READ);
(5) ss_listener_event_func分析
- 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);
- fd = adb_socket_accept(_fd, &addr, &alen); //接受客户端的连接
- if(fd < 0) return;
- adb_socket_setbufsize(fd, CHUNK_SIZE);
- s = create_local_socket(fd);
- if(s) {
- connect_to_smartsocket(s);
- return;
- }
- adb_close(fd);
- }
- }
(6) 执行connect_to_smartsocket(s)
- void connect_to_smartsocket(asocket *s)
- {
- D("Connecting to smart socket \n");
- asocket *ss = create_smart_socket(smart_socket_action);
- s->peer = ss;
- ss->peer = s;
- s->ready(s);
- }
(7) 执行create_smart_socket
- static int smart_socket_enqueue(asocket *s, apacket *p)
- {
- unsigned len;
- #if ADB_HOST
- char *service = NULL;
- char* serial = NULL;
- transport_type ttype = kTransportAny;
- #endif
- D("SS(%d): enqueue %d\n", s->id, p->len);
- if(s->pkt_first == 0) {
- s->pkt_first = p;
- s->pkt_last = p;
- } else {
- if((s->pkt_first->len + p->len) > MAX_PAYLOAD) {
- D("SS(%d): overflow\n", s->id);
- put_apacket(p);
- goto fail;
- }
- memcpy(s->pkt_first->data + s->pkt_first->len,
- p->data, p->len);
- s->pkt_first->len += p->len;
- put_apacket(p);
- p = s->pkt_first;
- }
- /* don't bother if we can't decode the length */
- if(p->len < 4) return 0;
- len = unhex(p->data, 4);
- if((len < 1) || (len > 1024)) {
- D("SS(%d): bad size (%d)\n", s->id, len);
- goto fail;
- }
- D("SS(%d): len is %d\n", s->id, len );
- /* can't do anything until we have the full header */
- if((len + 4) > p->len) {
- D("SS(%d): waiting for %d more bytes\n", s->id, len+4 - p->len);
- return 0;
- }
- p->data[len + 4] = 0;
- D("SS(%d): '%s'\n", s->id, (char*) (p->data + 4));
- #if ADB_HOST
- service = (char *)p->data + 4;
- if(!strncmp(service, "host-serial:", strlen("host-serial:"))) {
- char* serial_end;
- service += strlen("host-serial:");
- // serial number should follow "host:" and could be a host:port string.
- serial_end = skip_host_serial(service);
- if (serial_end) {
- *serial_end = 0; // terminate string
- serial = service;
- service = serial_end + 1;
- }
- } else if (!strncmp(service, "host-usb:", strlen("host-usb:"))) {
- ttype = kTransportUsb;
- service += strlen("host-usb:");
- } else if (!strncmp(service, "host-local:", strlen("host-local:"))) {
- ttype = kTransportLocal;
- service += strlen("host-local:");
- } else if (!strncmp(service, "host:", strlen("host:"))) {
- ttype = kTransportAny;
- service += strlen("host:");
- } else {
- service = NULL;
- }
- if (service) {
- asocket *s2;
- /* some requests are handled immediately -- in that
- ** case the handle_host_request() routine has sent
- ** the OKAY or FAIL message and all we have to do
- ** is clean up.
- */
- if(handle_host_request(service, ttype, serial, s->peer->fd, s) == 0) {
- /* XXX fail message? */
- D( "SS(%d): handled host service '%s'\n", s->id, service );
- goto fail;
- }
- if (!strncmp(service, "transport", strlen("transport"))) {
- D( "SS(%d): okay transport\n", s->id );
- p->len = 0;
- return 0;
- }
- /* try to find a local service with this name.
- ** if no such service exists, we'll fail out
- ** and tear down here.
- */
- s2 = create_host_service_socket(service, serial);
- if(s2 == 0) {
- D( "SS(%d): couldn't create host service '%s'\n", s->id, service );
- sendfailmsg(s->peer->fd, "unknown host service");
- goto fail;
- }
- /* we've connected to a local host service,
- ** so we make our peer back into a regular
- ** local socket and bind it to the new local
- ** service socket, acknowledge the successful
- ** connection, and close this smart socket now
- ** that its work is done.
- */
- adb_write(s->peer->fd, "OKAY", 4);
- s->peer->ready = local_socket_ready;
- s->peer->close = local_socket_close;
- s->peer->peer = s2;
- s2->peer = s->peer;
- s->peer = 0;
- D( "SS(%d): okay\n", s->id );
- s->close(s);
- /* initial state is "ready" */
- s2->ready(s2);
- return 0;
- }
- #else /* !ADB_HOST */
- if (s->transport == NULL) {
- char* error_string = "unknown failure";
- s->transport = acquire_one_transport (CS_ANY,
- kTransportAny, NULL, &error_string);
- if (s->transport == NULL) {
- sendfailmsg(s->peer->fd, error_string);
- goto fail;
- }
- }
- #endif
- if(!(s->transport) || (s->transport->connection_state == CS_OFFLINE)) {
- /* if there's no remote we fail the connection
- ** right here and terminate it
- */
- sendfailmsg(s->peer->fd, "device offline (x)");
- goto fail;
- }
- /* instrument our peer to pass the success or fail
- ** message back once it connects or closes, then
- ** detach from it, request the connection, and
- ** tear down
- */
- s->peer->ready = local_socket_ready_notify;
- s->peer->close = local_socket_close_notify;
- s->peer->peer = 0;
- /* give him our transport and upref it */
- s->peer->transport = s->transport;
- connect_to_remote(s->peer, (char*) (p->data + 4));
- s->peer = 0;
- s->close(s);
- return 1;
- fail:
- /* we're going to close our peer as a side-effect, so
- ** return -1 to signal that state to the local socket
- ** who is enqueueing against us
- */
- s->close(s);
- return -1;
- }
(8) 执行handle_host_request
- int handle_host_request(char *service, transport_type ttype, char* serial, int reply_fd, asocket *s)
- {
- // return a list of all connected devices
- if (!strncmp(service, "devices", 7)) { //执行adb devices,返回结果
- char buffer[4096];
- int use_long = !strcmp(service+7, "-l");
- if (use_long || service[7] == 0) {
- memset(buf, 0, sizeof(buf));
- memset(buffer, 0, sizeof(buffer));
- D("Getting device list \n");
- list_transports(buffer, sizeof(buffer), use_long);
- snprintf(buf, sizeof(buf), "OKAY%04x%s",(unsigned)strlen(buffer),buffer);
- D("Wrote device list \n");
- writex(reply_fd, buf, strlen(buf));
- return 0;
- }
- }
- }