本文尝试列举客户端能够发送给ADB服务器的所有请求。关于adb客户端、adb服务器、adbd守护进程、adb服务的概念,以及这些组件如何相互配合完成ADB工作的细节,请参考之前发的文章《Android Debug Bridge 技术实现》。
==============================
主机服务
==============================
host:version
请求ADB服务器的内部版本号。作为一个特殊的例外,服务器将用4字节的十六进制字符串回应,返回服务器内部版本号,回应中没有“OKAY”和“FAIL”。
host:kill
请求ADB服务器立即退出。用于ADB客户端检测到在升级之后有废弃的ADB服务器仍在运行的情况。
host:devices
请求返回可用的Android设备及其状态的列表。在“OKAY”之后是4个字节的长度定义,然后是指定长度的表明当前设备状况的字符串,返回之后连接关闭。
host:track-devices
“host:devices”的一个变种,它不关闭连接;相反,每次添加或移除设备或者指定设备的状态发生变化,一个新的设备列表描述被发送。这就使得像DDMS这样的工具能够实时跟踪连接设备的状态,而不用重复轮训服务器。
host:emulator:<port>
这是一个特殊的请求,当启动一个新的模拟器时,该请求被发送到ADB服务器。<port>是一个十进制数字代表模拟器的ADB协议端口号,比如:模拟器将自动转发到adbd守护进程的TCP端口号。这个机制使得ADB服务器能够知道新的模拟器实例启动。
host:transport:<serial-number>
请求切换连接到<serial-number>指示的设备或模拟器。接到“OKAY”回应之后,所有的客户端请求将被直接发送给运行在指定设备上的adbd守护进程。(用来实现-s)
host:transport-usb
请求切换连接到通过USB连接到主机的设备上。如果存在多个这样的设备,请求将失败。(用来实现-d)
host:transport-local
请求切换连接到通过TCP连接的模拟器。如果有多个这样的模拟器实例在运行,请求将失败。(用来实现-e)
host:transport-any
另一个“host:transport”变种。请求切换连接到已连接的设备或正在运行的模拟器。如果可用的设备或模拟器多于一个,请求将失败。(用在-s、-d、-e都不被提供时)
host-serial:<serial-number>:<request>
这是一个特殊形式的请求,前缀“host-serial:<serial-number>:”表明客户端正在请求ADB服务器获得指定设备的信息。<request>可以是下述格式的一种。
host-usb:<request>
host-serial的一个变种,用于将连接到主机的唯一USB设备作为目标。如果没有这样的设备或有多个这样的设备,请求将失败。
host-local:<request>
host-serial的一个变种,用于将运行在主机上唯一的模拟器实例作为目标。如果没有这样的模拟器或有多个这样的模拟器,请求将失败。
host:<request>
当请求设备相关的信息时,“host:”也能被解释为“任何连接到主机的唯一设备或运行在主机上的唯一模拟器”。
<host-prefix>:get-product
暂无解释。
<host-prefix>:get-serialno
返回对应设备或模拟器的序列号。注意模拟器序列号是“emulator-5544”的形式。
<host-prefix>:get-state
返回指定设备的状态字符串。
<host-prefix>:forward:<local>;<remote>
请求ADB服务器将本地连接从<local>转移到指定设备上的<remote>地址。
这里的<host-prefix>可以是上面描述的host-serial、host-usb、host-local、host的任意一个,它表明目标是哪个设备或模拟器。
<local>的格式有以下几种:
tcp:<port> -> 在localhost:<port>上的TCP连接
local:<path> -> 在<path>上的Unix本地域套接字(Unix domain socket)
<remote>的格式有以下几种:
tcp:<port> -> 在设备上localhost:<port>的TCP连接
local:<path> -> 在设备上的Unix本地域套接字
jdwp:<pid> -> 在虚拟机进程<pid>中的JDWP线程
或者下面所描述的本地服务的任何一种。
==============================
本地服务
==============================
下面所有的请求都假设你已经切换传输到实际的设备,或者你使用上面所描述的请求前缀。
shell:command arg1 arg2 ...
在设备的shell中运行“command arg1 arg2 ...”,返回输出流及错误流。注意命令参数必须用空格分隔。如果一个参数包含空格,应该对它使用双引号。参数不能包含双引号和其他会导致错误的符号。
这是“adb shell”的非交互版本。
shell:
在设备上启动一个交互的shell会话。恰当的重定向标准输入、标准输出和标准错误输出。ADB服务器使用这个服务来实现“adb shell”,但是在输入被发送到设备之前,ADB服务器也会对输入做加工。(参考commandline.c中的interactive_shell()函数)
remount:
请求adbd守护进程重新挂载设备的文件系统到读/写模式下,而不是只读模式。在执行“adb sync”或者“adb push”之前,通常都需要这个服务。
在不允许该操作的特定的系统中,这个请求可能不成功。
dev:<path>
打开一个设备文件,直接将客户端连接到这个文件去执行读写。该服务对于调试除错很有用,但是需要特殊的权限,不能在所有的设备上运行。<path>是从文件系统根目录开始的全路径。
tcp:<port>
尝试连接到loclhost的tcp端口<port>上。
tcp:<port>:<server-name>
尝试从设备连接到<server-name>所指定机器的tcp端口<port>上。这个服务对调试只能在设备上显示的网络或代理问题很有用。
local:<path>
尝试连接到设备上的Unix域套接字<path>。
localreserved:<path>
localabstract:<path>
localfilesystem:<path>
几个local:<path>的变种,用来访问其他Android套接字命名空间。
log:<name>
打开一个系统日志(/dev/log/<name>),允许客户端直接读取。用来实现“adb logcat”。数据流对客户端是只读的。
framebuffer:
这个服务用来向客户端发送framebuffer的快照。它需要足够的权限,工作原理如下:
在“OKAY”之后,服务发送包含下列字段的16字节的二进制结构(低位优先格式):
depth: uint32_t: framebuffer深度
size: uint32_t: framebuffer大小(单位:字节)
width: uint32_t: framebuffer宽度(单位:像素)
height: uint32_t: framebuffer高度(单位:像素)
在当前的实现中,framebuffer深度总是16,大小总是:宽度*高度*2。
每当客户端想要一个快照时,它应该通过通道发送一个字节,触发服务将framebuffer数据按framebuffer大小指定的字节数发送给它。
如果adbd守护进程没有足够的权限打开framebuffer设备,那么连接会立即关闭。
dns:<server-name>
这个服务是个例外,因为它仅仅运行在ADB服务器中。它被用来实现USB联网,比如:通过主机为设备提供一个网络连接。
它用来在主机上执行gethostbyname(<address>),IP地址以4个字节的字符串返回。
recover:<size>
这个服务上传一个recovery影像到设备中。<size>必须与recovery影像文件大小一样。工作原理如下:
- 创建一个命名为/tmp/update的文件;
- 从客户端读取<size>大小的字节数,将它们写入到/tmp/update;
- 当影像文件成功读取之后,创建一个命名为/tmp/update.start的文件。
只有当设备处于recovery模式时,这个服务才能工作。此外,如果/tmp目录不存在,连接会立即关闭。
jdwp:<pid>
连接到运行在虚拟机进程<pid>中的JDWP线程。
track-jdwp
用于周期性的向客户端发送JDWP pids列表。返回数据格式如下:
<hex4>: 4个字符的十六进制字符串指定所有内容的长度
<content>: 一连串的格式为<pid> "/n"的ASCII行
DDMS使用这个服务知道设备或模拟器上正在运行哪些可以调试的进程。
注意没有仅获取一次列表的单步服务。
sync:
这个请求启动文件系统同步服务,用来实现“adb push”和“adb pull”。因为这个服务相当复杂,需要专门的文章来解释说明,如果有朋友感兴趣,我们以后专门讨论。
来源:https://www.cnblogs.com/armlinux/archive/2011/02/16/2396844.html