前言

前文

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_seclabeladb_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()函数代码梳理相关推荐

  1. 响应式编程笔记(二):代码编写

    2019独角兽企业重金招聘Python工程师标准>>> 响应式编程笔记(二):代码编写 博客分类: 架构 原文:Notes on Reactive Programming Part ...

  2. js6的未来(二)函数增强

    js6的未来(二)函数增强 函数声明中的解构 JavaScript 的新解构赋值得名于数组或对象可以 "解构" 并提取出组成部分的概念.在 第 1 部分 中,学习了如何在局部变量中 ...

  3. 【Groovy】闭包 Closure ( 闭包参数绑定 | curry 函数 | rcurry 函数 | ncurry 函数 | 代码示例 )

    文章目录 一.闭包参数绑定 1.闭包参数绑定 curry 函数 2.闭包参数绑定 rcurry 函数 3.闭包参数绑定 ncurry 函数 二.完整代码示例 一.闭包参数绑定 闭包 Closure 提 ...

  4. 深入浅出javascript(二)函数和this对象

    一.函数对象的属性和方法 函数是一种数据类型,也是对象,这一点很明确.因此,函数对象也可以添加属性和方法,但是这里的属性和方法是静态的,之所以这样说,就是为了区别构造函数. 示例如下: ①创建一个空的 ...

  5. 2.函数(代码的整洁之道)

    2.函数(代码的整洁之道) 目录 短小 只做一件事 每个函数一个抽象层次 switch语句 使用描述性的名称 函数参数 无副作用 分隔指令与询问 使用异常代替返回的错误码 别重复自己 结构化编程 如何 ...

  6. 开源项目Hopsan代码梳理、流程分析

    Hosan开源项目是液压.电力等行业的仿真开源软件,由瑞典林平大学开发,可以仿真电力.液压等.更具体的了解,请参考:<Hopsan -- 液压.电力等行业的仿真开源软件>. Hosan开源 ...

  7. 吴恩达《机器学习》学习笔记七——逻辑回归(二分类)代码

    吴恩达<机器学习>学习笔记七--逻辑回归(二分类)代码 一.无正则项的逻辑回归 1.问题描述 2.导入模块 3.准备数据 4.假设函数 5.代价函数 6.梯度下降 7.拟合参数 8.用训练 ...

  8. 十二、Python第十二课——函数

    (请先看置顶博文)https://blog.csdn.net/GenuineMonster/article/details/104495419 目录 (请先看置顶博文)https://blog.csd ...

  9. php函数内的循环,PHP 循环列出目录内容的函数代码

    PHP 循环列出目录内容的函数代码 复制代码 代码如下: function list_files($dir) { if(is_dir($dir)) { if($handle = opendir($di ...

最新文章

  1. GPU服务器选购指南-思腾合力篇
  2. python深浅拷贝 面试_python基础-深浅拷贝
  3. .NET(C#)时间日期字符串(String)格式化转换成Datetime异常报错问题
  4. Accent-Insensitive, Accent Sensitive, a ã, e é 模糊查询
  5. 645. Set Mismatch(python)
  6. IT十八掌作业_java基础第十六天_GUI/socket
  7. poj2464扫描线好题,树状数组解法
  8. 黑马训练营自学笔记(03)
  9. 为防范“手机低头族”出交通事故 韩国开发行人警示系统
  10. 帮你深度探寻Spring循环依赖源码实现!面经解析
  11. python == 字符编码
  12. 【Python+OpenCV】Windows+Python3.6.0(Anaconda3)+OpenCV3.2.0安装配置
  13. 小米蓝牙音响驱动_小米手机绝佳配件,20W无线闪充,支持唤醒小爱,只卖149
  14. C# 简单的ZEBRA标签打印程序
  15. 宽度学习详解(Broad Learning System)
  16. 如何利用信息差赚钱?分享二个案例给你!
  17. 马赛克效果,通过PS把迪丽热巴制作成马赛克效果
  18. PB控件属性之Tab
  19. MIT 18.01 Single Variable Calculus(单变量微积分)课堂笔记【6】——近似和求最值
  20. 一个困扰程序员很多年的问题:微服务领域SpringCloud这么火,为何还要学习SpringCloud Alibaba?

热门文章

  1. 啥叫集成电路?(IC)
  2. 【LeetCode】91. Decode Ways 解题报告(Python)
  3. 使用Quartus II 18.1软件创建PLL IP核
  4. 莹石摄像头加密及H265设备播放
  5. [Python][PyQt5]WARNING: The scripts pylupdate5.exe, pyrcc5.exe and pyuic5.exe are installed in
  6. Cat.1究竟是如何崛起的?中速率到底有什么用?
  7. 计算机毕设(附源码)JAVA-SSM基于Web学术会议投稿管理系统
  8. 云贝餐饮小程序-V2可线传独立版【更新序列至2.5.6】独家修复商家登录/区域代理/分销商/会员卡/积分商城/文章/DIY
  9. 为什么说Security+认证是入行首选?
  10. web前端入门到实战:HTML5 VideoAPI,打造自己的Web视频播放器