欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

adb源码分析 androidadblinux

程序员文章站 2022-07-04 15:26:43
...

  相关基础信息:

 

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

相关标签: android adb linux