这篇博客我们主要分析下adbd在usb线拔掉,然后再连接的代码流程。
一、log打印流程
我们先来看下自己调试的代码打印:
由于显示的问题,我把log的时间去除了,只显示了pid 和tid
//拔去usb线
185 188 I adbd : output_thread:(null): remote read failed for transport
185 188 I adbd : output_thread:(null) SYNC offline for transport
185 185 I adbd : handle_packet: A_SYNC
185 185 I adbd : handle_packet: A_SYNC CS_OFFLINE
185 187 I adbd : input_thread:(null): transport SYNC offline
185 187 I adbd : input_thread:(null): transport input thread is exiting, fd 13
185 186 I usb_adb_open_thread: adbd usb_thread - opening device
185 186 I usb_adb_open_thread: adbd opening device succeeded
185 185 I adbd : handle_packet: A_SYNC
185 185 I adbd : handle_packet: A_SYNC send_packet
185 2164 I adbd : input_thread:(null): transport SYNC online
//插上usb线
185 2165 I adbd : output_thread: read_from_remote after
185 185 I adbd : handle_packet: A_CNXN
185 185 I adbd : handle_packet: A_CNXN handle_online
185 185 I adbd : handle_packet: A_CNXN send_connect
185 2165 I adbd : output_thread: read_from_remote after
185 185 I adbd : adb command: 'shell:dumpsys iphonesubinfo'
185 2165 I adbd : output_thread: read_from_remote after
185 2165 I adbd : output_thread: read_from_remote after
185 185 I adbd : adb command: 'shell:dumpsys battery'
185 2165 I adbd : output_thread: read_from_remote after
185 2165 I adbd : output_thread: read_from_remote after
185 2165 I adbd : output_thread: read_from_remote after
185 185 I adbd : handle_packet: A_CNXN
185 185 I adbd : handle_packet: A_CNXN handle_offline
185 185 I adbd : handle_packet: A_CNXN handle_online
185 185 I adbd : handle_packet: A_CNXN send_connect
二、拔usb线流程
2.1 output_thread读取adb驱动的数据出错
我们按照log看,首先就是output_thread读取adb驱动的数据出错了
static void *output_thread(void *_t)
{
atransport *t = reinterpret_cast<atransport*>(_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);
LOG("%s:%s: failed to write apacket to transport\n", __FUNCTION__, t->serial);
goto oops;
}
} else {
D("%s: remote read failed for transport\n", t->serial);
LOG("%s:%s: remote read failed for transport\n", __FUNCTION__, t->serial);//读取adb驱动数据失败
put_apacket(p);
break;
}
}
D("%s: SYNC offline for transport\n", t->serial);
LOG("%s:%s SYNC offline for transport\n", __FUNCTION__, 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)) {//往sockpair另一侧写信息
put_apacket(p);
D("%s: failed to write SYNC apacket to transport", t->serial);
}
output_thread读取adb驱动的数据出错了,然后退出线程并发送sockpair的另一侧数据
另一侧的socketpair关联的函数是transport_socket_events函数
fdevent_install(&(t->transport_fde),
t->transport_socket,
transport_socket_events,
t);
transport_socket_events函数,接着调用了handle_packet函数
static void transport_socket_events(int fd, unsigned events, void *_t)
{
atransport *t = reinterpret_cast<atransport*>(_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);
}
}
}
2.2 handle_packet处理offline
handle_packet函数收到A_SYNC命令,然后处理o