网友通过本文主要向大家介绍了android6.0 adbd深入分析(二)adb驱动数据的处理、写数据到adb驱动节点等相关知识,希望对您有所帮助,也希望大家支持linkedu.com www.linkedu.com
android6.0 adbd深入分析(二)adb驱动数据的处理、写数据到adb驱动节点
之前我们讲到在output_thread中,读取了adb驱动的数据后,就调用write_packet(t->fd, t->serial, &p)函数,把数据网socketpair的一侧写。</div>这会导致socketpair的另一侧有数据,另一侧有数据会调用transport_socket_events函数来处理数据。
一、处理驱动读取的数据
我们现在来看看transport_socket_events函数:
static void transport_socket_events(int fd, unsigned events, void *_t) { atransport *t = reinterpret_cast(_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); } } }
我们先把socketpair一端的数据读取出来,然后调用handle_packet来处理。
void handle_packet(apacket *p, atransport *t) { asocket *s; switch(p->msg.command){//根据从驱动读取内容msg的命令 ...... case A_OPEN: /* OPEN(local-id, 0, "destination") * if (t->online && p->msg.arg0 != 0 && p->msg.arg1 == 0) { char *name = (char*) p->data; name[p->msg.data_length > 0 ? p->msg.data_length - 1 : 0] = 0; s = create_local_service_socket(name);//创建一个本地的socket if(s == 0) { send_close(0, p->msg.arg0, t); } else { s->peer = create_remote_socket(p->msg.arg0, t); s->peer->peer = s; send_ready(s->id, s->peer->id, t); s->ready(s); } } break; ...... case A_WRTE: /* WRITE(local-id, remote-id, ) */ if (t->online && p->msg.arg0 != 0 && p->msg.arg1 != 0) { if((s = find_local_socket(p->msg.arg1, p->msg.arg0))) { unsigned rid = p->msg.arg0; p->len = p->msg.data_length; if(s->enqueue(s, p) == 0) { D("Enqueue the socket\n"); send_ready(s->id, rid, t); } return; } } break; default: printf("handle_packet: what is %08x?!\n", p->msg.command); } put_apacket(p); }
上面是处理驱动的数据,我们先来看下处理open命令中一个create_local_service_socket函数
asocket *create_local_service_socket(const char *name) { #if !ADB_HOST if (!strcmp(name,"jdwp")) { return create_jdwp_service_socket(); } if (!strcmp(name,"track-jdwp")) { return create_jdwp_tracker_service_socket(); } #endif int fd = service_to_fd(name);//获取fd if(fd < 0) return 0; asocket* s = create_local_socket(fd);//创建socket D("LS(%d): bound to '%s' via %d\n", s->id, name, fd); #if !ADB_HOST char debug[PROPERTY_VALUE_MAX]; if (!strncmp(name, "root:", 5)) property_get("ro.debuggable", debug, ""); if ((!strncmp(name, "root:", 5) && getuid() != 0 && strcmp(debug, "1") == 0) || (!strncmp(name, "unroot:", 7) && getuid() == 0) || !strncmp(name, "usb:", 4) || !strncmp(name, "tcpip:", 6)) { D("LS(%d): enabling exit_on_close\n", s->id); s->exit_on_close = 1; } #endif return s; }
我们先来看看service_to_fd函数:
int service_to_fd(const char *name) { int ret = -1; if(!strncmp(name, "tcp:", 4)) { int port = atoi(name + 4); name = strchr(name + 4, ':'); if(name == 0) { ret = socket_loopback_client(port, SOCK_STREAM); if (ret >= 0) disable_tcp_nagle(ret); } else { #if ADB_HOST ret = socket_network_client(name + 1, port, SOCK_STREAM); #else return -1; #endif } #ifndef HAVE_WINSOCK /* winsock doesn't implement unix domain sockets */ } else if(!strncmp(name, "local:", 6)) { ret = socket_local_client(name + 6, ANDROID_SOCKET_NAMESPACE_RESERVED, SOCK_STREAM); } else if(!strncmp(name, "localreserved:", 14)) { ret = socket_local_client(name + 14, ANDROID_SOCKET_NAMESPACE_RESERVED, SOCK_STREAM); } else if(!strncmp(name, "localabstract:", 14)) { ret = socket_local_client(name + 14, ANDROID_SOCKET_NAMESPACE_ABSTRACT, SOCK_STREAM); } else if(!strncmp(name, "localfilesystem:", 16)) { ret = socket_local_client(name + 16, ANDROID_SOCKET_NAMESPACE_FILESYSTEM, SOCK_STREAM); #endif #if !ADB_HOST } else if(!strncmp("dev:", name, 4)) { ret = unix_open(name + 4, O_RDWR | O_CLOEXEC); } else if(!strncmp(name, "framebuffer:", 12)) { ret = create_service_thread(framebuffer_service, 0); } else if (!strncmp(name, "jdwp:", 5)) { ret = create_jdwp_connection_fd(atoi(name+5)); } else if(!HOST && !strncmp(name, "shell:", 6)) {//adb shell ret = create_subproc_thread(name + 6, SUBPROC_PTY); } else if(!HOST && !strncmp(name, "exec:", 5)) { ret = create_subproc_thread(name + 5, SUBPROC_RAW); } else if(!strncmp(name, "sync:", 5)) { D("kangchen service_to_fd file_sync_service"); ret = create_service_thread(file_sync_service, NULL); } else if(!strncmp(name, "remount:", 8)) { ret = create_service_thread(remount_service, NULL); } else if(!strncmp(name, "reboot:", 7)) { void* arg = strdup(name + 7); if (arg == NULL) return -1; ret = create_service_thread(reboot_service, arg); } else if(!strncmp(name, "root:", 5)) {//adb root ret = create_service_thread(restart_root_service, NULL);这里我们主要看下adb root和adb shell,其他的以后自己慢慢研究:
1.2 adb root的处理过程
我们先来看下adb root的处理过程,serverice_to_fd函数先调用了create_service_thread函数:
static int create_service_thread(void (*func)(int, void *), void *cookie) { int s[2]; if (adb_socketpair(s)) {//建立一对socketpair printf("cannot create service socket pair\n"); return -1; } D("socketpair: (%d,%d)", s[0], s[1]); stinfo* sti = reinterpret_cast(malloc(sizeof(stinfo))); if (sti == nullptr) { fatal("cannot allocate stinfo"); } sti->func = func; sti->cookie = cookie; sti->fd = s[1]; adb_thread_t t; if (adb_thread_create(&t, service_bootstrap_func, sti)) { free(sti); adb_close(s[0]); adb_close(s[1]); printf("cannot create service thread\n"); return -1; } D("service thread started, %d:%d\n",s[0], s[1]); return s[0];//返回一端的socketpair }
我们再来看看service_bootstrap_func函数:
void *service_bootstrap_func(void *x) { stinfo* sti = reinterpret_cast(x); sti->func(sti->fd, sti->cookie); free(sti); return 0; }
最终还是调用了create_service_thread传进来的func函数
而adb root传入的是restart_root_service函数:
void restart_root_service(int fd, void *cookie) { if (getuid() == 0) {//已经root WriteFdExactly(fd, "