adb源码分析 androidadblinux
相关基础信息:
adb | 5038 | ADB_HOST=1 ADB_HOST_ON_TARGET=1 |
adb_sysdeps_init适用于linux和windows的版本 adb_trace_init adb_commandline |
adb client | 提供HOST端运行的命令 | ||
adb service | HOST端上的一个后台进程 | ||
adb daemon | 5037 设备开机启动 |
ADB_HOST=0 ALLOW_ADBD_ROOT=1 |
adb_qemu_trace_init start_device_log adb_main |
Android中adb源码路径:system/core/adb,核心源码列表:
adb BUILD_EXECUTABLE | adbd BUILD_EXECUTABLE | |
adb.c \ | √ | √ |
adb_auth_client.c \ | √ | |
adb_auth_host.c \ | √ | |
adb_client.c \ | √ | |
backup_service.c \ | √ | |
commandline.c \ | √ | |
console.c \ | √ | |
fdevent.c \ | √ | √ |
file_sync_client.c \ | √ | √ |
framebuffer_service.c \ | √ | |
get_my_path_linux.c \ | √ | |
jdwp_service.c \ | √ | |
log_service.c \ | √ | |
remount_service.c \ | √ | |
services.c \ | √ | √ |
sockets.c \ | √ | √ |
transport.c \ | √ | √ |
transport_local.c \ | √ | √ |
transport_usb.c \ | √ | √ |
usb_linux.c \ | √ | |
usb_linux_client.c \ | √ | |
usb_vendors.c | √ | |
utils.c \ | √ | √ |
$(EXTRA_SRCS) \ | ||
$(USB_SRCS) \ |
Android启动过程adb相关服务及系统属性信息:
1 | # create basic filesystem structure |
公私钥认证机制,只允许授权主机使用USB调试接口。保存路径/data/misc/adb/adb_keys | |
mkdir /data/misc/adb 02750 system shell | |
2 | # Enable adb security for JB4.2.2 |
设置是否启用adb公私钥认证机制,0禁用1启用 | |
setprop ro.adb.secure 0 | |
3 | # adbd is controlled via property triggers in init.<platform>.usb.rc |
service adbd /sbin/adbd | |
class core | |
socket adbd stream 660 system system | |
disabled | |
seclabel u:r:adbd:s0 | |
4 | # adbd on at boot in emulator |
on property:ro.kernel.qemu=1 | |
start adbd |
以下为linux版adb工具执行过程分析(实用环境可能在机顶盒或车载机上):
1、命令行执行adb devices,主程序入口,main -> adb_commandline
system/core/ktadb/adb.c::main():Handling commandline() system/core/ktadb/commandline.c::adb_commandline():getenv ANDROID_SERIAL=(null) ANDROID_ADB_SERVER_PORT=(null) server_port=5038 system/core/ktadb/commandline.c::adb_commandline():adb_commandline() para[0]=devices system/core/ktadb/commandline.c::adb_commandline():is_server=0 no_daemon=0 is_daemon=0
2、执行函数adb_query()
system/core/ktadb/adb_client.c::adb_query():adb_query: host:devices
a. 验证版本
a.1 验证成功
system/core/ktadb/adb_client.c::_adb_connect():_adb_connect: host:version 30303063 000c 686f73743a76657273696f6e host:version system/core/ktadb/transport.c::writex():writex: fd=3 len=4: system/core/ktadb/transport.c::writex():writex: fd=3 len=12: system/core/ktadb/transport.c::readx():readx: fd=3 wanted=4 system/core/ktadb/transport.c::readx():readx: fd=3 wanted=4 got=4 4f4b4159 OKAY system/core/ktadb/adb_client.c::_adb_connect():_adb_connect: return fd 3 system/core/ktadb/transport.c::readx():readx: fd=3 wanted=4 system/core/ktadb/transport.c::readx():readx: fd=3 wanted=4 got=4 30303034 0004 system/core/ktadb/transport.c::readx():readx: fd=3 wanted=4 system/core/ktadb/transport.c::readx():readx: fd=3 wanted=4 got=4 30303166 001f 版本号31
发送4字节+host:version指令,读取OKAY返回结果,读取结果长度及结果内容。
a.2 验证失败
system/core/ktadb/adb_client.c::_adb_connect():_adb_connect: host:version adb_server_name=(null) system/core/ktadb/adb_client.c::_adb_connect():_adb_connect: socket_loopback_client system/core/ktadb/adb_client.c::_adb_connect():_adb_connect: return fd -2 system/core/ktadb/adb_client.c::_adb_connect():_adb_connect: error message cannot connect to daemon system/core/ktadb/adb_client.c::adb_connect():adb_connect: service host:devices, _adb_connect_ret=-2
a.2.launch_server fork()
* daemon not running. starting it now on port 5038 * system/core/ktadb/adb_client.c::adb_connect():fd == -2 adb_connect:launch_server() launch_server():fork() system/core/ktadb/adb.c::main():Handling commandline() system/core/ktadb/commandline.c::adb_commandline():getenv ANDROID_SERIAL=(null) ANDROID_ADB_SERVER_PORT=(null) server_port=5038 system/core/ktadb/commandline.c::adb_commandline():adb_commandline() para[0]=-P system/core/ktadb/commandline.c::adb_commandline():adb_commandline() para[1]=5038 system/core/ktadb/commandline.c::adb_commandline():is_server=1 no_daemon=0 is_daemon=1 system/core/ktadb/commandline.c::adb_commandline():adb_commandline::adb_main system/core/ktadb/adb.c::adb_main():adb.c::adb_main()
a.2.launch_server usb_vendors_init()
每个设备厂家都会定义一个VID(vender id)来标识自己的usb 设备,ADB service端只会连接已知的VID,这个函数的作用就是初始化一个VID的数组,初始化后这个数组中将包含adb代码中内建的一些厂家的ID以及HOST端的android配置文件中定义的ID。
a.2.launch_server usb_init()
创建一个线程,线程处理函数device_poll_thread,进入一个循环,每隔1s执行一次find_usb_device和kick_disconnected_devices,find_usb_device搜索所有的usb设备,判断VID是否在上面初始化的列表中,如果是,则将该usb设备注册到一个handle_list中。调用register_usb_transport基于这个fd构造一个atransport类型的对象,再基于这个atransport对象调用register_transport构造一个tmsg类型的对象。
最后,将这个tmsg对象写到transport_registration_send这个fd,将触发相应的socket监控。kick_disconnected_devices函数判断adb设备是否还正常,不正常的话从handle_list中去掉。
a.2.launch_server local_init(DEFAULT_ADB_LOCAL_TRANSPORT_PORT);
system/core/ktadb/usb_linux.c::device_poll_thread():Created device thread system/core/ktadb/transport_local.c::local_init():transport: local client init on port 5555
创建一个线程,尝试连接HOST端5555-5585端口,如果连接成功,则返回一个fd,register_socket_transport基于这个fd构造一个atransport类型的对象,再基于这个atransport对象调用register_transport构造一个tmsg类型的对象。最后,将这个tmsg对象写 transport_registration_send这个fd,将触发相应的socket监控。
a.2.launch_server adb_auth_init();
ystem/core/ktadb/adb_auth_host.c::adb_auth_init():adb_auth_init system/core/ktadb/adb_auth_host.c::get_user_keyfilepath():home '/data' system/core/ktadb/transport_local.c::client_socket_thread():transport: client_socket_thread() starting system/core/ktadb/adb_auth_host.c::get_user_key():user key '/data/.android/adbkey' system/core/ktadb/adb_auth_host.c::read_key():read_key '/data/.android/adbkey'
adbkey.pub文件内容
QAAAAOcgswwpDbwD9nP4IsrHRVTPBcHn3g6cIIoK9+OBBRoll6C7ASYw7+tRV3QisHhR+fWToXocEeSJeZrevInAI5wlqKBVIqa9RiHafVGcWEWXXZ0T7t2zmVT5Yrkvw1OegeHICaZpzZieI7ii5SDHFrXxMejZsU+vVkxEy6tnRldywTxcKSpQ11fLyeDqR8fmr/R06uK3Tjet/98zGStWdsvDcN95ZxpGjfkj9Sv83+NXBWYZWQzBqTTJiWRQWbe9mi3RpqgKpLXHQDzYTQbJRWvTOt4QR50rt0kQf1SUdilO0ap1eGf/KXQALx72ivk/9fhU5L+IDKUyP/EsspUqc01KD8GzkPvUMdUbXdStc4uEjzoHNERB+PD5EioRoeYwXzqIRJGycP1+Xvn1ek9CnoTU8Fqno8KkiMtbeB8T0I0cpQv0J52IoL/yN3tST+RZzAFspOv2CAhY7bvNAZ035+amfkI6O9sF7Mq+cLsHXKX3elcydpVnLAabBPAD/pnX46p44UZT4L9OY7+3JkMwu0yolKvO8ku0fqckitkE1p0DBLzZByjKqD6VqSTpzMQi63GSDBdV6d9MWt4BuuhwLuTO1UMolJv0h+lTKA40GzeNuNF9xw9AH2GJIESjxtJaKe8dUOcpxpbJ1Su74TnjdubBRgvkeYId1/VdUySrbviBnghOpwEAAQA= unknown@localhost
a.2.launch_server build_local_name(local_name, sizeof(local_name), server_port)
a.2.launch_server install_listener(local_name, "*smartsocket*", NULL, 0)
system/core/ktadb/usb_linux.c::register_device():[ usb located new device /dev/bus/usb/002/025 (131/3/1) ] system/core/ktadb/usb_linux.c::register_device():[ usb open /dev/bus/usb/002/025fd = 12]
监听"tcp:5037",adb client与adb service之间的通讯端口。
a.2.launch_server start_logging()
将stdin重写向到/dev/null,将stdout、stderr重定向/tmp/adb.log,然后输出"adb starting"到stderr。
a.2.launch_server fdevent_loop()
前面通过fdinstall()注册了几个fde,这里就通过一个无限循环epoll相应的fd,有相应的事件则调用fdinstall时注册的处理函数。
a.2.launch_server usb_cleanup()
usb相关的清理工作,对应linux平台的实现目前为空。
* daemon started successfully *
b.获取列表
b.1 设备正常
system/core/ktadb/adb_client.c::_adb_connect():_adb_connect: host:devices 30303063 000c 686f73743a64657669636573 host:devices system/core/ktadb/transport.c::writex():writex: fd=3 len=4: system/core/ktadb/transport.c::writex():writex: fd=3 len=12: system/core/ktadb/transport.c::readx():readx: fd=3 wanted=4 system/core/ktadb/transport.c::readx():readx: fd=3 wanted=4 got=4 4f4b4159 OKAY system/core/ktadb/adb_client.c::_adb_connect():_adb_connect: return fd 3 system/core/ktadb/adb_client.c::adb_connect():adb_connect: return fd 3 system/core/ktadb/transport.c::readx():readx: fd=3 wanted=4 system/core/ktadb/transport.c::readx():readx: fd=3 wanted=4 got=4 30303230 0020 结果长度32 system/core/ktadb/transport.c::readx():readx: fd=3 wanted=32 system/core/ktadb/transport.c::readx():readx: fd=3 wanted=32 got=32 31343833453130303531334644303130 1483E100513FD010 List of devices attached 1483E100513FD0100_MTPADB device
发送4字节+host:devices指令,读取OKAY返回结果,读取结果长度及结果内容。
b.2 设备未授权
system/core/ktadb/adb_client.c::_adb_connect():_adb_connect: host:devices (null) 30303063 000c 686f73743a64657669636573 host:devices system/core/ktadb/transport.c::writex():writex: fd=3 len=4: system/core/ktadb/transport.c::writex():writex: fd=3 len=12: system/core/ktadb/transport.c::readx():readx: fd=3 wanted=4 system/core/ktadb/transport.c::readx():readx: fd=3 wanted=4 got=4 4f4b4159 OKAY system/core/ktadb/adb_client.c::_adb_connect():_adb_connect: return fd 3 system/core/ktadb/adb_client.c::adb_connect():adb_connect: return fd 3 system/core/ktadb/transport.c::readx():readx: fd=3 wanted=4 system/core/ktadb/transport.c::readx():readx: fd=3 wanted=4 got=4 30303136 0016 system/core/ktadb/transport.c::readx():readx: fd=3 wanted=22 system/core/ktadb/transport.c::readx():readx: fd=3 wanted=22 got=22 373964373561656309756e617574686f 79d75aec.unautho List of devices attached 79d75aec unauthorized
b.3 无设备
system/core/ktadb/adb_client.c::_adb_connect():_adb_connect: host:devices adb_server_name=(null) system/core/ktadb/adb_client.c::_adb_connect():_adb_connect: socket_loopback_client 30303063 000c 686f73743a64657669636573 host:devices system/core/ktadb/transport.c::writex():writex: fd=3 len=4: system/core/ktadb/transport.c::writex():writex: fd=3 len=12: system/core/ktadb/transport.c::readx():readx: fd=3 wanted=4 system/core/ktadb/transport.c::readx():readx: fd=3 wanted=4 got=4 4f4b4159 OKAY system/core/ktadb/adb_client.c::_adb_connect():_adb_connect: return fd 3 system/core/ktadb/adb_client.c::adb_connect():adb_connect: return fd 3 system/core/ktadb/transport.c::readx():readx: fd=3 wanted=4 system/core/ktadb/transport.c::readx():readx: fd=3 wanted=4 got=4 30303030 0000 system/core/ktadb/transport.c::readx():readx: fd=3 wanted=0 system/core/ktadb/transport.c::readx():readx: fd=3 wanted=0 got=0 List of devices attached
主机端 | ||
平台 | Win 7 | Linux |
公钥 | %USERPROFILE%\.android\adbkey.pub | /data/.android/adbkey.pub |
私钥 | %USERPROFILE%\.android\adbkey | /data/.android/adbkey |
手机 | 手机弹出主机公钥的指纹(MD5),询问是否允许 | |
已验证通过的主机保存在 /data/misc/adb/adb_keys |
生成主机公钥指纹:
$ awk "{print $1}" < adbkey.pub | openssl base64 -A -d -a | openssl md5 -c | awk "{print $2}" | tr "[:lower:]" "[:upper:]"
23:B2:47:E1:08:DE:5A:3B:58:5A:A5:A6:FA:98:E0:50
linux平台adb公私钥相关文件夹授权
mkdir /data/.android 0777 system system export HOME /data
查看已保存主机秘钥信息:
ls -l /data/misc/adb/adb_keys
-rw-r----- system shell
备注:重启手机端adbd会重读/data/misc/adb/adb_keys,或重启手机
在移动设备上打开终端
1、stop adbd;
2、将主机公钥文件放入/mnt/sdcard/文件夹下,新增授权设备(需root权限),:
cat adbkey.pub >> /data/misc/adb/adb_keys;
3、start adbd.
执行adb kill-server、adb start-server、adb devices查看是否已经连接成功
adb devices
emulator-5554 unauthorized
设置网络调试端口为偶数端口(如:5566),即不会出现此问题,原因:http://blog.csdn.net/span76/article/details/9293937
1) adb 启动就连接5555端口
启动 adb 的时候, adb 通过 "adb fork-server server" 启动 adb deamon
而后deamon 就会去找本地的 5555 端口, 直到 5555+32
ref: jellybean/system/core/adb/transport_local.c#140
为何连接上就叫 emulator, 这是因为 adb 期望自动为用户连接本机的emulator ( 每个emu两个端口, 可以多达16个)
如果你不用service.adb.tcp.port=5566 而用 5565 就是出现 emulator-5564, 因为连接只测试奇数端口
2) 为何连接叫 emulator-5554 而不是 emulator-5555
这是因为缺省emulator的 console 端口是 5554 ( 应该可以用 telnet 连接与 emulator 交互(还没有试验)) , 而adb 的端口是console端口 +1 就是 5555
当使用 adb emu <command> 可能就是把 <command> 发到5554端口
adb log开关
adb.h line 385
fdevent.c line 40
下一篇: TODO:一不顺眼就换字体Go之应用篇