ADB(二)_ADBD_main()函数代码梳理
前言
前文
ADB(一)_概况了解
前面我们对ADB从整体上进行了简单的概括梳理,我们对adb的了解应该比日常开发了解的更多了。现在就需要从局部对adb进行分析,了解它组成部分的具体工作原理是怎么样的,相互之间又是怎么进行交互的。
ADBD (ADB daemon)
在上一篇内容里我们知道adbd主要作用是连接ADB Server 和android device或者仿真器并为在开发者主机上的client提供一些服务.那我们就先从运行在Android device、Emulator上面的adbd程序入手。
1. ADBD代码说明
由于程序是由C++在底层编写的。那我们就从它的main()函数入口来了解adbd的启动流程是怎样的。
这里还是先摆出Android.mk文件中adbd的编译部分。也为接下来的代码追踪提供线索。
# adbd device daemon
# =========================================================
include $(CLEAR_VARS)LOCAL_SRC_FILES := \daemon/main.cpp \daemon/mdns.cpp \services.cpp \file_sync_service.cpp \framebuffer_service.cpp \remount_service.cpp \set_verity_enable_state_service.cpp \shell_service.cpp \shell_service_protocol.cpp \LOCAL_CFLAGS := \$(ADB_COMMON_CFLAGS) \$(ADB_COMMON_linux_CFLAGS) \-DADB_HOST=0 \-D_GNU_SOURCE \-Wno-deprecated-declarations \LOCAL_CFLAGS += -DALLOW_ADBD_NO_AUTH=$(if $(filter userdebug eng,$(TARGET_BUILD_VARIANT)),1,0)ifneq (,$(filter userdebug eng,$(TARGET_BUILD_VARIANT)))
LOCAL_CFLAGS += -DALLOW_ADBD_DISABLE_VERITY=1
LOCAL_CFLAGS += -DALLOW_ADBD_ROOT=1
endifLOCAL_MODULE := adbdLOCAL_FORCE_STATIC_EXECUTABLE := trueLOCAL_SANITIZE := $(adb_target_sanitize)
LOCAL_STRIP_MODULE := keep_symbols
LOCAL_STATIC_LIBRARIES := \libadbd \libasyncio \libavb_user \...
include $(BUILD_EXECUTABLE)
虽然有Android.mk明确了adb和adbd分别编译的代码文件。但是有一些文件是adb和adbd共同使用的,也就是说在同一份代码既需要在adb中使用,也需要在adbd中使用,这时候,C++就使出了它常用的宏定义的方法了。利用ADB_HOST
标志【ADB_HOST说明是在主机端运行,不在Android devices运行】来选择了,我们在源码中也常会看见以下这样的宏定义:
...
#if ADB_HOST
...//代码块①
#endif
...
如果ADB_HOST为真,那么接下来要走的就是代码块①,否则就不走代码块①。
2. adbd初始化说明
在main()函数的一开始,就出现一个getopt_long()函数,这是一个解析命令行的函数,然后就会调用close_stdin(),用来关闭标准输入;
int main(int argc, char** argv) {...int c = getopt_long(argc, argv, "", opts, &option_index);...close_stdin();debuggerd_init(nullptr);adb_trace_init(argv);D("Handling main()");return adbd_main(DEFAULT_ADB_PORT);
}
如上图所示,就是adbd的main()函数的调用流程;下面就上述的函数调用来梳理一下adbd启动时做了哪些事:
2.1 getopt_long
首先这个getopt_long()函数是系统提供的,主要作用就是用来解析命令行参数,主要是根据命令行参数给root_seclabel
和adb_device_banner
这两个变量赋值,root_seclabel是可以理解为安全标签的意思,是adbd的权限说明,adb_device_banner可以理解为是说明设备是android设备还是主机。
...
case 's':root_seclabel = optarg;break;
case 'b':adb_device_banner = optarg;break;
...
2.2 close_stdin
close_stdin()函数内部的实现如下代码所示,
...
constexpr char kNullFileName[] = "/dev/null";
#endif
void close_stdin() {int fd = unix_open(kNullFileName, O_RDONLY);if (fd == -1) {fatal_errno("failed to open %s", kNullFileName);}if (TEMP_FAILURE_RETRY(dup2(fd, STDIN_FILENO)) == -1) {fatal_errno("failed to redirect stdin to %s", kNullFileName);}unix_close(fd);
}
...
在这里,我们主要关注一下这个dup2()函数;这个dup2()函数原型是int dup2(int oldfd, int newfd);
/* Standard file descriptors. */
#define STDIN_FILENO 0 /* Standard input. */
#define STDOUT_FILENO 1 /* Standard output. */
#define STDERR_FILENO 2 /* Standard error output. */
在这里dup2(fd, STDIN_FILENO)的意思是,newfd指向oldfd句柄指向的文件描述符结构,即原本是指向标准输出文件描述结构体的STDIN_FILENO
指向标准输出文件指向了"/dev/null",这样一来,原本从显示器终端输入文件输入的数据从改从/dev/null
文件输入了;
2.3 debuggerd_init
Android 提供了一个程序异常退出的诊断daemon debuggerd。此进程可以侦测到程序崩溃,并将崩溃时的进程状态信息输出到文件和串口中,以供开发人员分析调试使用。具体的工作原理此处就不深入,知道这是用于分析调试的就行。
2.4 adb_trace_init
adbd的adb_trace_init()函数的内部实现如下所示(这里我已经剔除了非adbd的代码部分):
std::string get_trace_setting() {return android::base::GetProperty("persist.adb.trace_mask", "");
}
....
void adb_trace_init(char** argv) {...// Don't open log file if no tracing, since this will block// the crypto unmount of /dataif (!get_trace_setting().empty()) {if (unix_isatty(STDOUT_FILENO) == 0) {start_device_log();}}...android::base::InitLogging(argv, &AdbLogger);setup_trace_mask();VLOG(ADB) << adb_version();
}
在adbd的adb_trace_init(0函数中,首先通过获取系统设置来决定时候开始设备的log。然后调用setup_trace_mask()设置trace掩码;adb的trace设置来自adb_trace环境变量,而adbd来自系统属性persist.adb.trace_mask。就是说通过获取Android系统属性来设置trace。
2.5 adbd_main(DEFAULT_ADB_PORT);
#define DEFAULT_ADB_PORT 5037
adbd的默认通信端口是5037,adb_main()函数是main()函数最后调用,综合main()函数之前的调用,我们可以判断adbd的绝大部分工作应该都在adbd的adb_main()函数中。
如需进一步了解,请继续阅读:
ADB(三)_ADBD_adbd_main()函数代码梳理
ADB(二)_ADBD_main()函数代码梳理相关推荐
- 响应式编程笔记(二):代码编写
2019独角兽企业重金招聘Python工程师标准>>> 响应式编程笔记(二):代码编写 博客分类: 架构 原文:Notes on Reactive Programming Part ...
- js6的未来(二)函数增强
js6的未来(二)函数增强 函数声明中的解构 JavaScript 的新解构赋值得名于数组或对象可以 "解构" 并提取出组成部分的概念.在 第 1 部分 中,学习了如何在局部变量中 ...
- 【Groovy】闭包 Closure ( 闭包参数绑定 | curry 函数 | rcurry 函数 | ncurry 函数 | 代码示例 )
文章目录 一.闭包参数绑定 1.闭包参数绑定 curry 函数 2.闭包参数绑定 rcurry 函数 3.闭包参数绑定 ncurry 函数 二.完整代码示例 一.闭包参数绑定 闭包 Closure 提 ...
- 深入浅出javascript(二)函数和this对象
一.函数对象的属性和方法 函数是一种数据类型,也是对象,这一点很明确.因此,函数对象也可以添加属性和方法,但是这里的属性和方法是静态的,之所以这样说,就是为了区别构造函数. 示例如下: ①创建一个空的 ...
- 2.函数(代码的整洁之道)
2.函数(代码的整洁之道) 目录 短小 只做一件事 每个函数一个抽象层次 switch语句 使用描述性的名称 函数参数 无副作用 分隔指令与询问 使用异常代替返回的错误码 别重复自己 结构化编程 如何 ...
- 开源项目Hopsan代码梳理、流程分析
Hosan开源项目是液压.电力等行业的仿真开源软件,由瑞典林平大学开发,可以仿真电力.液压等.更具体的了解,请参考:<Hopsan -- 液压.电力等行业的仿真开源软件>. Hosan开源 ...
- 吴恩达《机器学习》学习笔记七——逻辑回归(二分类)代码
吴恩达<机器学习>学习笔记七--逻辑回归(二分类)代码 一.无正则项的逻辑回归 1.问题描述 2.导入模块 3.准备数据 4.假设函数 5.代价函数 6.梯度下降 7.拟合参数 8.用训练 ...
- 十二、Python第十二课——函数
(请先看置顶博文)https://blog.csdn.net/GenuineMonster/article/details/104495419 目录 (请先看置顶博文)https://blog.csd ...
- php函数内的循环,PHP 循环列出目录内容的函数代码
PHP 循环列出目录内容的函数代码 复制代码 代码如下: function list_files($dir) { if(is_dir($dir)) { if($handle = opendir($di ...
最新文章
- GPU服务器选购指南-思腾合力篇
- python深浅拷贝 面试_python基础-深浅拷贝
- .NET(C#)时间日期字符串(String)格式化转换成Datetime异常报错问题
- Accent-Insensitive, Accent Sensitive, a ã, e é 模糊查询
- 645. Set Mismatch(python)
- IT十八掌作业_java基础第十六天_GUI/socket
- poj2464扫描线好题,树状数组解法
- 黑马训练营自学笔记(03)
- 为防范“手机低头族”出交通事故 韩国开发行人警示系统
- 帮你深度探寻Spring循环依赖源码实现!面经解析
- python == 字符编码
- 【Python+OpenCV】Windows+Python3.6.0(Anaconda3)+OpenCV3.2.0安装配置
- 小米蓝牙音响驱动_小米手机绝佳配件,20W无线闪充,支持唤醒小爱,只卖149
- C# 简单的ZEBRA标签打印程序
- 宽度学习详解(Broad Learning System)
- 如何利用信息差赚钱?分享二个案例给你!
- 马赛克效果,通过PS把迪丽热巴制作成马赛克效果
- PB控件属性之Tab
- MIT 18.01 Single Variable Calculus(单变量微积分)课堂笔记【6】——近似和求最值
- 一个困扰程序员很多年的问题:微服务领域SpringCloud这么火,为何还要学习SpringCloud Alibaba?
热门文章
- 啥叫集成电路?(IC)
- 【LeetCode】91. Decode Ways 解题报告(Python)
- 使用Quartus II 18.1软件创建PLL IP核
- 莹石摄像头加密及H265设备播放
- [Python][PyQt5]WARNING: The scripts pylupdate5.exe, pyrcc5.exe and pyuic5.exe are installed in
- Cat.1究竟是如何崛起的?中速率到底有什么用?
- 计算机毕设(附源码)JAVA-SSM基于Web学术会议投稿管理系统
- 云贝餐饮小程序-V2可线传独立版【更新序列至2.5.6】独家修复商家登录/区域代理/分销商/会员卡/积分商城/文章/DIY
- 为什么说Security+认证是入行首选?
- web前端入门到实战:HTML5 VideoAPI,打造自己的Web视频播放器