本文共 3991 字,大约阅读时间需要 13 分钟。
本文尝试列举客户端能够发送给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”。因为这个服务相当复杂,需要专门的文章来解释说明,如果有朋友感兴趣,我们以后专门讨论。
转载地址:http://wokci.baihongyu.com/