android2.3-adb源码分析
ADB是android debug bridge的缩写,负责计算机与Android设备的几乎所有通信和协作,可以认为是连接两者的桥梁。
其完整源代码路径:system\core\adb
1、首先查看其Android.mk文件,确认会生成哪此文件。
可执行进程由两部分组成:
LOCAL_MODULE := adb
include $(BUILD_HOST_EXECUTABLE)adb或adb.exe,运行于PC端,包括Linux、Windows、Mac OS等系统之中,通常是x86架构上LOCAL_MODULE := adbdifeq ($(TARGET_SIMULATOR),true)include $(BUILD_HOST_EXECUTABLE)elseinclude $(BUILD_EXECUTABLE)endifadbd,运行于Android设备的底层Linux平台上,或者运行于虚拟机平台上盒子上如此运行:init.rc 脚本添加:service adbd /sbin/adbd disabled利用ADB_HOST宏定义编译不同的代码2、主体介绍一下现在分析一下整个adb通讯由哪些模块或组件构成呢?一、adb server 服务端:这是一个守护进程长期运行于后台(runs on the host machine),没有控制台界面.其主要工作有两部分:1):管理PC中的Android模拟器,以及通过USB线连接到PC的Android设备,负责维持运行于其中的 adbd进程与自身的数据通道;2):实现PC与设备/模拟器之间的数据拷贝。主要代码文件:二、adb client 客户端:提供给用户的命令行工具,对用户暴露了上述install、push、shell等接口,与用户交互其主要工作是解析这些命令的参数,做必要预处理,然后转移为指令或数据,发送给adb服务端。adb服务端再将指令数据转发到模拟器或设备中,由adbd处理,产生结果,再通过adb服务端接收回来。三、adb service 服务:由此服务给adbd提供功能,即由这个模块完成,主要分为Host Services及 Local Services两类四、ADB daemon (adbd) 守护进程作为后台进程运行于Android device or emulated system,提供连接 ADB server的功能(through USB for devices, through TCP for emulators)其通讯典型结构如下:3、以常用命令为实例常用的指令如下:adb push <local> <remote> - copy file/dir to deviceadb pull <remote> [<local>] - copy file/dir from deviceadb shell - run remote shell interactivelyadb install [-l] [-r] [-s] <file> - push this package file to the device and install itadb kill-server - kill the server if it is runningconnect <host>[:<port>] - connect to a device via TCP/IP Port 5555 is used by default if no port number is specified.所有这些cmd处理函数都在:\system\core\adb\Commandline.c 中:int adb_commandline(int argc, char **argv)为了更好的理解这些命令,有必须找到代码理解一下这些命令的处理主要函数:函数启动点: adb.c 中的main函数,根据ADB_HOST决定执行哪些代码:int main(int argc, char **argv){...adb_trace_init();#if ADB_HOST adb_sysdeps_init(); return adb_commandline(argc - 1, argv + 1); //这里运行PC端,用于命令发送#else start_device_log(); return adb_main(0, DEFAULT_ADB_PORT); //运行于android系统的盒子或设备上,用于命令接收及反馈#endif}先分析PC端这边:a、首先建立adb server: 有两种方式,手工建立:adb fork-server server 调用:adb_main(is_daemon, server_port);默认5037端口,也可以设置:service.adb.tcp.port 这个属性获取自动建立:调用 launch_server(server_port),利用 CreateProcess 或者fork建立后台进程进行运行// child process int result = execl(path, "adb", "fork-server", "server", NULL);这个进程利用fdevent_loop();处理所有数据及消息 b、ADB command-line client即发送命令界面:主要处理函数:int adb_commandline(int argc, char **argv)主要利用如下几个函数:adb_query 查询adb_connect 连接adb_status 获取状态命令发送格式:1. A 4-byte hexadecimal string giving the length of the payload2. Followed by the payload itself.
服务端收到后回复:1. For success, the 4-byte "OKAY" string2. For failure, the 4-byte "FAIL" string, followed by a 4-byte hex length, followed by a string giving the reason for failure.3. As a special exception, for 'host:version', a 4-byte hex string corresponding to the server's internal version number以上两者通讯利用socket进行数据传递然后分析设备服务端:主要集中在函数:fdevent_loop();主要分析一下数据transport这块,文件Transport.cvoid init_transport_registration(void){adb_socketpair(s) //创建socket pair用于处理异步注册事件 transport_registration_send = s[0]; transport_registration_recv = s[1];// 在transport_registration_recv上安装一个transport_registration_func异步事情回调函数 fdevent_install(&transport_registration_fde, transport_registration_recv, transport_registration_func, 0); ...
}异步如何触发的呢?register_transport-->transport_write_action(transport_registration_send, &m)remove_transport-->transport_write_action(transport_registration_send, &m)此时会将事件写入socket pair的写入端,而接收端:void fdevent_loop(){...for(;;) {while((fde = fdevent_plist_dequeue())) { unsigned events = fde->events; fde->events = 0; fde->state &= (~FDE_PENDING); dump_fde(fde, "callback"); //这个回调函数是在:fdevent_install 函数中注册的:fde->func = func; fde->func(fde->fd, events, fde->arg);}}}然后利用transport_read_action读取异步事情,那么数据处理在哪里呢?transport_registration_func-->/* don't create transport threads for inaccessible devices */ if (t->connection_state != CS_NOPERM) { if(adb_thread_create(&input_thread_ptr, input_thread, t)){ fatal_errno("cannot create input thread"); } if(adb_thread_create(&output_thread_ptr, output_thread, t)){ fatal_errno("cannot create output thread"); } } 在这里会创建两个线程 output thread和 input thread用于做异步 IO, =============================================================================根据 adb的文档说明, output线程和 input线程的引人主要是为了解决 USB endpoint不支持非阻塞读写,所以就专门为 usb读操作开一个output线程,为usb写操作创建一个input线程。所以,数据流方向是远程连接->output线程->主线程->input线程->远程连接。刚开始时,output线程会发一个 SYNC消息给input线程,启动这个transport。static void *input_thread(void *_t){D("to_remote: starting input_thread for %p, reading from fd %d\n",t,
t->fd);for(;;){read_packet(t->fd, &p);t->write_to_remote(p, t);}}static void *output_thread(void *_t){D("from_remote: data pump for transport %p\n", t); for(;;) { p = get_apacket();t->read_from_remote(p, t);write_packet(t->fd, &p);}}=============================================================================说一下我开始疑惑的问题解决:adb shell 命令处理:if(!strcmp(argv[0], "shell")) {if(argc < 2) {
return interactive_shell(); }
}int interactive_shell(void){fd = adb_connect("shell:");adb_thread_create(&thr, stdin_read_thread, fds);}而服务端处理:#if ADB_HOST#define SHELL_COMMAND "/bin/sh"#else#define SHELL_COMMAND "/system/bin/sh"#endifint service_to_fd(const char *name){if(!HOST && !strncmp(name, "shell:", 6)) {if(name[6]) { ret = create_subprocess(SHELL_COMMAND, "-c", name + 6);} else { ret = create_subprocess(SHELL_COMMAND, "-", 0);}}...}单独创建出一个进程进行处理shell命令static int create_subprocess(const char *cmd, const char *arg0, const char *arg1){pid = fork();if(pid == 0){execl(cmd, cmd, arg0, arg1, NULL);}else...}adb install xxx.apk 处理方式: if(!strcmp(argv[0], "install")) { if (argc < 2) return usage(); return install_app(ttype, serial, argc, argv); } if(!strcmp(argv[0], "uninstall")) { if (argc < 2) return usage(); return uninstall_app(ttype, serial, argc, argv); } 安装apk:int install_app(transport_type transport, char* serial, int argc, char** argv){//下载路径 const char *const DATA_DEST = "/data/local/tmp/%s"; const char *const SD_DEST = "/sdcard/tmp/%s"; const char* where = DATA_DEST;//将apk文件写入到to目录下 if (!(err = do_sync_push(filename, to, 1 /* verify APK */))) { /* file in place; tell the Package Manager to install it */ argv[argc - 1] = to; /* destination name, not source location */ pm_command(transport, serial, argc, argv); delete_file(transport, serial, to); }...}通知android系统进行安装apk包static int pm_command(transport_type transport, char* serial, int argc, char** argv){snprintf(buf, sizeof(buf), "shell:pm");//通知包管理器安装apk应用,即使用pm命令安装应用send_shellcommand(transport, serial, buf);return 0;}usage: pm [list|path|install|uninstall] pm list packages [-f] pm list permission-groups pm list permissions [-g] [-f] [-d] [-u] [GROUP] pm list instrumentation [-f] [TARGET-PACKAGE] pm list features pm path PACKAGE pm install [-l] [-r] [-t] [-i INSTALLER_PACKAGE_NAME] [-s] [-f] PATH pm uninstall [-k] PACKAGE pm enable PACKAGE_OR_COMPONENT pm disable PACKAGE_OR_COMPONENT pm setInstallLocation [0/auto] [1/internal] [2/external]最后:
源码的OVERVIEW.txt文件中对它们的关系进行了描述。而protocol.txt描述了各模块之间通信协作的协议格式。
分享到:
相关推荐
Android 2.3引入了新的开发者工具,如Android Debug Bridge (ADB)、DDMS(Dalvik Debug Monitor Service),以及改进的Eclipse集成开发环境,便于开发者调试和测试应用。 7. **第三方库支持**: `org`目录可能...
10. **性能优化**:源码分析有助于理解系统性能瓶颈,如内存管理、CPU调度等,从而进行针对性的优化。 总之,分析“TD2.3”这样的Android源码压缩包,不仅可以提升开发者对系统的深入理解,还能提供无尽的创新机会...
This project provides reverse tethering over adb for Android: it allows devices to use the internet connection of the computer they are plugged on. It does not require any root access (neither on the ...
- **2-1-1 编译ANDROID2.3形成文件系统** 在Ubuntu 10.10环境下编译Android 2.3的源码,是构建Android开发环境的基础步骤之一。这一步骤主要包括下载源码、配置编译环境、执行编译命令等环节。成功完成这一步后,...
- Ubuntu10.10系统上编译Android源码的过程,包括生成Android 2.3的文件系统和SDK开发包。 - 提供了Ubunt9.10(32位)和Ubuntu10.10(64位)两个版本的源代码,方便开发者根据自己的Linux开发环境选择合适的版本。...
**2.3 ADB命令使用技巧** - **基础**:ADB(Android Debug Bridge)是一个命令行工具,用于与Android设备通信。 - **常用命令**:如adb install、adb shell、adb logcat等。 **2.4 模拟器使用和配置** - **功能**...
##### 2.3 编译Android中的Linux内核 - **获取.config文件**: 可以从模拟器中获取.config文件。 1. **启动模拟器**,打开SDK的Tools目录。 2. **使用adb命令**: `> adb pull /proc/config.gz d:\`,将文件保存到`...
1.3.4 Android Debug Bridge(ADB) 的用法 16 1.3.5 使用DX编译Android应用 18 1.3.6 使用Android Asset Packaging Tool(AAPT)打包资源 19 1.3.7 使用mksdcard管理虚拟SD卡 19 1.4 开始第一个...
2.3 Android开发模拟器 11 2.3.1 创建模拟器 11 2.3.2 启动模拟器 13 2.3.3 键盘映射与模拟器控制 13 2.3.4 横屏与竖屏切换 14 第3章 第一个Android程序 15 3.1 HelloAndroid 15 3.1.1 在Eclipse中创建项目 ...
2.3 分析并编译Android源代码 35 2.3.1 Android源代码的结构 35 2.3.2 编译Android源代码 40 2.3.3 运行Android源代码 42 2.3.4 实践演练——演示编译Android程序的两种方法 43 2.4 编译...
4.4.1 adb install分析 4.4.2 pm分析 4.4.3 installPackageWithVerification函数分析 4.4.4 APK 安装流程总结 4.4.5 Verification介绍 4.5 queryIntentActivities分析 4.5.1 Intent及IntentFilter介绍 4.5.2...
根据提供的文档信息,我们可以总结出以下关键知识点,主要聚焦于X3399 Android平台的开发环境搭建、工具使用、源码管理与编译、以及最终的映像文件烧录等几个方面。 ### 1. 开发平台的搭建 #### 1.1 使用U盘安装...
2.3 分析并编译Android源代码 35 2.3.1 Android源代码的结构 35 2.3.2 编译Android源代码 40 2.3.3 运行Android源代码 42 2.3.4 实践演练——演示编译Android程序的两种方法 43 2.4 编译...
2.3 分析并编译Android源代码 35 2.3.1 Android源代码的结构 35 2.3.2 编译Android源代码 40 2.3.3 运行Android源代码 42 2.3.4 实践演练——演示编译Android程序的两种方法 43 2.4 编译...
4.1 Android Studio中的Logcat工具可以帮助你查看应用程序的日志输出,这对于跟踪问题和分析行为非常有用。 4.2 在运行时,通过输出特定标签或关键字的Log信息,可以了解程序的状态和运行情况。 **步骤5:特殊调试...