adb install 发生了什么-ADB篇
ADB是Android Debug Bridge ,简单就是给我们调试用的,adb install 首先就看下adb。adb分两个部分一个是android一个是客户端的,就是sdk里的adb工具。在host中启动的程序又分为service和client
//packages/modules/adb/Android.bp
cc_binary_host {
name: "adb",
stl: "libc++_static",
defaults: ["adb_defaults"],
...
shared_libs: [],
// Archive adb, adb.exe.
dist: {
targets: [
"dist_files",
"sdk",
"sdk-repo-platform-tools",
"sdk_repo",
"win_sdk",
],
},
target: {
darwin: {
cflags: [
"-Wno-sizeof-pointer-memaccess",
],
},
windows: {
enabled: true,
ldflags: ["-municode"],
shared_libs: ["AdbWinApi"],
required: [
"AdbWinUsbApi",
],
},
},
}
cc_binary {
name: "adbd",
defaults: ["adbd_defaults", "host_adbd_supported", "libadbd_binary_dependencies"],
recovery_available: true,
min_sdk_version: "30",
apex_available: ["com.android.adbd"],
srcs: [
"daemon/main.cpp",
],
cflags: [
"-D_GNU_SOURCE",
"-Wno-deprecated-declarations",
],
strip: {
keep_symbols: true,
},
...
}
...
cc_binary {
name: "abb",
defaults: ["adbd_defaults"],
stl: "libc++",
recovery_available: false,
srcs: [
"daemon/abb.cpp",
],
cflags: [
"-D_GNU_SOURCE",
"-Wno-deprecated-declarations",
],
strip: {
keep_symbols: true,
},
static_libs: [
"libadbd_core",
"libadbd_services",
"libcmd",
],
shared_libs: [
"libbase",
"libbinder",
"liblog",
"libutils",
"libselinux",
],
}
}
编译的时候根据host也就是各个平台生成了adb和abb,Android自己生成了adbd作为服务。下面看下adb在Android系统中的启动。adb在init.usb.rc中配置
//system/core/rootdir/init.usb.rc
# adbd is controlled via property triggers in init.<platform>.usb.rc
service adbd /system/bin/adbd --root_seclabel=u:r:su:s0
class core
socket adbd seqpacket 660 system system
disabled
updatable
seclabel u:r:adbd:s0
将adbd作为一个服务启动了起来,同时创建了一个socket。
adb install
在客户端的命令行执行adb install.
//packages/modules/adb/client/main.cpp
int main(int argc, char* argv[], char* envp[]) {
__adb_argv = const_cast<const char**>(argv);
__adb_envp = const_cast<const char**>(envp);
adb_trace_init(argv);
return adb_commandline(argc - 1, const_cast<const char**>(argv + 1));
}
处理直接交给adb_commandline了。
//packages/modules/adb/client/commandline.cpp
int adb_commandline(int argc, const char** argv) {
...
else if (!strcmp(argv[0], "install")) {
if (argc < 2) error_exit("install requires an argument");
return install_app(argc, argv);
}
...
}
通过字符串匹配输入的参数是install调用adb_sideload_install,还是在commandline中
//packages/modules/adb/client/adb_install.cpp
int install_app(int argc, const char** argv) {
InstallMode install_mode = INSTALL_DEFAULT;
auto incremental_request = CmdlineOption::None;
bool incremental_wait = false;
....
auto run_install_mode = [&](InstallMode install_mode, bool silent) {
switch (install_mode) {
case INSTALL_PUSH:
return install_app_legacy(passthrough_argv.size(), passthrough_argv.data(),
use_fastdeploy);
case INSTALL_STREAM:
return install_app_streamed(passthrough_argv.size(), passthrough_argv.data(),
use_fastdeploy);
case INSTALL_INCREMENTAL:
return install_app_incremental(passthrough_argv.size(), passthrough_argv.data(),
incremental_wait, silent);
case INSTALL_DEFAULT:
default:
error_exit("invalid install mode");
}
};
auto res = run_install_mode(primary_mode, fallback_mode.has_value());//执行安装
if (res && fallback_mode.value_or(primary_mode) != primary_mode) {
res = run_install_mode(*fallback_mode, false);
}
return res;
}
在老版本中apk会先到/data/local/tmp中,新版本直接使用piplines,所以这里使用install_app_streamed安装apk,安装时在命令行中显示的Performing Streamed Install也能证明这一点。
static int install_app_streamed(int argc, const char** argv, bool use_fastdeploy) {
printf("Performing Streamed Install\n");//果然在这
unique_fd local_fd(adb_open(file, O_RDONLY | O_CLOEXEC));//创建文件fd
if (local_fd < 0) {
fprintf(stderr, "adb: failed to open %s: %s\n", file, strerror(errno));
return 1;
}
#ifdef __linux__
posix_fadvise(local_fd.get(), 0, 0, POSIX_FADV_SEQUENTIAL | POSIX_FADV_NOREUSE);
#endif
...
const bool use_abb_exec = is_abb_exec_supported();
std::string error;
std::vector<std::string> cmd_args = {use_abb_exec ? "package" : "exec:cmd package"};//参数中增加"package"
cmd_args.reserve(argc + 3);
// don't copy the APK name, but, copy the rest of the arguments as-is
while (argc-- > 1) {
if (use_abb_exec) {
cmd_args.push_back(*argv++);
} else {
cmd_args.push_back(escape_arg(*argv++));
}
}
unique_fd remote_fd = send_command(cmd_args, &error);//拿到server的fd
if (remote_fd < 0) {
fprintf(stderr, "adb: connect error for write: %s\n", error.c_str());
return 1;
}
if (!copy_to_file(local_fd.get(), remote_fd.get())) {//将apk传输到server
fprintf(stderr, "adb: failed to install: copy_to_file: %s: %s", file, strerror(errno));
return 1;
}
char buf[BUFSIZ];
read_status_line(remote_fd.get(), buf, sizeof(buf));//获取结果
if (strncmp("Success", buf, 7) != 0) {
fprintf(stderr, "adb: failed to install %s: %s", file, buf);
return 1;
}
fputs(buf, stdout);
return 0;
}
这个方法内容很明了。
- 获取文件的fd
- 根据各种环境增加参数获得新的cmd_args,然后调用send_command将指令发送给server
- 将需要install的apk交给server
- 获得安装结果
//packages/modules/adb/client/adb_install.cpp
static unique_fd send_command(const std::vector<std::string>& cmd_args, std::string* error) {
if (is_abb_exec_supported()) {
return send_abb_exec_command(cmd_args, error);
} else {
return unique_fd(adb_connect(android::base::Join(cmd_args, " "), error));
}
}
//packages/modules/adb/client/commandline.h
unique_fd send_abb_exec_command(const ContainerT& command_args, std::string* error) {
std::string service_string = "abb_exec:" + android::base::Join(command_args, ABB_ARG_DELIMETER);
unique_fd fd(adb_connect(service_string, error));
if (fd < 0) {
fprintf(stderr, "adb: failed to run abb_exec. Error: %s\n", error->c_str());
return unique_fd{};
}
return fd;
}
//packages/modules/adb/client/adb_client.cpp
int adb_connect(std::string_view service, std::string* error) {
return adb_connect(nullptr, service, error);
}
层层调用下来最后会到adb_connect中。
int adb_connect(TransportId* transport, std::string_view service, std::string* error,
bool force_switch_device) {
LOG(DEBUG) << "adb_connect: service: " << service;
// Query the adb server's version.
if (!adb_check_server_version(error)) {
return -1;
}
// if the command is start-server, we are done.
if (service == "host:start-server") {
return 0;
}
unique_fd fd(_adb_connect(service, transport, error, force_switch_device));
if (fd == -1) {
D("_adb_connect error: %s", error->c_str());
} else if(fd == -2) {
fprintf(stderr, "* daemon still not running\n");
}
D("adb_connect: return fd %d", fd.get());
return fd.release();
}
就两步,现调用adb_check_server_version,然后调用_adb_connect返回连接的fd。
//packages/modules/adb/client/adb_client.cpp
bool adb_check_server_version(std::string* error) {
// Only check the version once per process, since this isn't atomic anyway.
static std::once_flag once;
static bool result;
static std::string* err;
std::call_once(once, []() {
err = new std::string();
result = __adb_check_server_version(err);
});
*error = *err;
return result;
}
static bool __adb_check_server_version(std::string* error) {
unique_fd fd(_adb_connect("host:version", nullptr, error));//先调用一次_adb_connect
bool local = is_local_socket_spec(__adb_server_socket_spec);
if (fd == -2 && !local) {
fprintf(stderr, "* cannot start server on remote host\n");
// error is the original network connection error
return false;
} else if (fd == -2) {
fprintf(stderr, "* daemon not running; starting now at %s\n", __adb_server_socket_spec);
start_server:
if (launch_server(__adb_server_socket_spec, __adb_client_one_device)) {//如果没启动调用launch_server启动服务
fprintf(stderr, "* failed to start daemon\n");
*error = "cannot connect to daemon";
return false;
} else {
fprintf(stderr, "* daemon started successfully\n");
}
// The server will wait until it detects all of its connected devices before acking.
// Fall through to _adb_connect.
} else {//如果版本不匹配会杀死进程,然后重新启动
...
adb_kill_server();
goto start_server;
}
}
return true;
}
adb_check_server_version调用了__adb_check_server_version,这个方法也分为两步
- 调用_adb_connect获得fd,由于是第一次启动所以肯定失败,返回的错误码是-2
- 如果没有获得fd,错误码是-2的话调用launch_server启动服务
这里根据客户端分为win32和其他系统,这里看下其他系统也就是linux,macos这些系统的代码。
//packages/modules/adb/adb.cpp
int launch_server(const std::string& socket_spec, const char* one_device) {
// set up a pipe so the child can tell us when it is ready.
unique_fd pipe_read, pipe_write;
if (!Pipe(&pipe_read, &pipe_write)) {//创建一个pipe
fprintf(stderr, "pipe failed in launch_server, errno: %d\n", errno);
return -1;
}
std::string path = android::base::GetExecutablePath();
pid_t pid = fork();//fork出一个子进程
if (pid < 0) return -1;
if (pid == 0) {//子进程
pipe_read.reset();
// android::base::Pipe unconditionally opens the pipe with O_CLOEXEC.
// Undo this manually.
fcntl(pipe_write.get(), F_SETFD, 0);
char reply_fd[30];
snprintf(reply_fd, sizeof(reply_fd), "%d", pipe_write.get());
// child process
std::vector<const char*> child_argv = {
"adb", "-L", socket_spec.c_str(), "fork-server", "server", "--reply-fd", reply_fd};//将pipe的fd作为返回的fd
....
child_argv.push_back(nullptr);
int result = execv(path.c_str(), const_cast<char* const*>(child_argv.data()));//执行命令
// this should not return
fprintf(stderr, "adb: execl returned %d: %s\n", result, strerror(errno));
} else {//父进程
char temp[3] = {};
// wait for the "OK\n" message
pipe_write.reset();
int ret = adb_read(pipe_read.get(), temp, 3);//3就是pipe的read fd,等待子进程执行的结果
int saved_errno = errno;
pipe_read.reset();
if (ret < 0) {
fprintf(stderr, "could not read ok from ADB Server, errno = %d\n", saved_errno);
return -1;
}
if (ret != 3 || temp[0] != 'O' || temp[1] != 'K' || temp[2] != '\n') {
ReportServerStartupFailure(pid);
return -1;
}
}
return 0;
}
这是一个标准的pipe流程
- 创建pipe,fork出子进程
- 子进程执行execv,默认端口是5037,这段指令就是"adb -L tcp:localhost:5037 fork-server server --reply-fd 4"
service启动
又到了commandline.cpp中,这次会根据参数执行adb_server_main方法,同样win32的部分就不看了。
//packages/modules/adb/client/main.cpp
int adb_server_main(int is_daemon, const std::string& socket_spec, const char* one_device,
int ack_reply_fd){
signal(SIGINT, [](int) { fdevent_run_on_looper([]() { exit(0); }); });//注册退出信号
....
if (is_daemon) {//这里启动的是service,传进来的参数是true,所以关闭标准输入
close_stdin();
setup_daemon_logging();
}
atexit(adb_server_cleanup);//注册清理函数
init_transport_registration();//初始化transport注册表
init_reconnect_handler();//处理重连的逻辑
adb_wifi_init();
if (!getenv("ADB_MDNS") || strcmp(getenv("ADB_MDNS"), "0") != 0) {
init_mdns_transport_discovery();//传输的域名解析服务的初始化
}
if (!getenv("ADB_USB") || strcmp(getenv("ADB_USB"), "0") != 0) {
if (should_use_libusb()) {//初始化usb连接相关的配置
libusb::usb_init();
} else {
usb_init();
}
} else {
adb_notify_device_scan_complete();
}
if (!getenv("ADB_EMU") || strcmp(getenv("ADB_EMU"), "0") != 0) {//如果连接模拟器相关配置的初始化
local_init(android::base::StringPrintf("tcp:%d", DEFAULT_ADB_LOCAL_TRANSPORT_PORT));
}
std::string error;
auto start = std::chrono::steady_clock::now();
// If we told a previous adb server to quit because of version mismatch, we can get to this
// point before it's finished exiting. Retry for a while to give it some time. Don't actually
// accept any connections until adb_wait_for_device_initialization finishes below.
while (install_listener(socket_spec, "*smartsocket*", nullptr, INSTALL_LISTENER_DISABLED,
nullptr, &error) != INSTALL_STATUS_OK) {//监听传进来的端口
if (std::chrono::steady_clock::now() - start > 0.5s) {
LOG(FATAL) << "could not install *smartsocket* listener: " << error;
}
std::this_thread::sleep_for(100ms);
}
adb_auth_init();//身份验证功能的初始化
std::thread notify_thread([ack_reply_fd]() {
adb_wait_for_device_initialization();//等待设备扫描结束
if (ack_reply_fd >= 0) {
//这里就是传进来的pipe的fd,这里服务就启动完成了会返回OK
if (!android::base::WriteStringToFd("OK\n", ack_reply_fd)) {
PLOG(FATAL) << "error writing ACK to fd " << ack_reply_fd;
}
unix_close(ack_reply_fd);
}
//服务启动好了允许连接
fdevent_run_on_looper([] { enable_server_sockets(); });
});
notify_thread.detach();
...
D("Event loop starting");
fdevent_loop();//开始循环获取连接事件
return 0;
}
先看下init_transport_registration
//packages/modules/adb/transport.cpp
void init_transport_registration(void) {
int s[2];
if (adb_socketpair(s)) {//创建了一对socket
PLOG(FATAL) << "cannot open transport registration socketpair";
}
D("socketpair: (%d,%d)", s[0], s[1]);
//将socket赋值给了两个变量
transport_registration_send = s[0];
transport_registration_recv = s[1];
//设置了收到事件时的处理函数transport_registration_func
transport_registration_fde =
fdevent_create(transport_registration_recv, transport_registration_func, nullptr);
fdevent_set(transport_registration_fde, FDE_READ);//开始监听读事件
}
init_transport_registration创建了一对socket,fdevent_create创建了transport_registration_fde,通过fdevent_set开始监听。
//packages/modules/adb/fdevent/fdevent.cpp
devent* fdevent_context::Create(unique_fd fd, std::variant<fd_func, fd_func2> func, void* arg) {
int fd_num = fd.get();
auto [it, inserted] = this->installed_fdevents_.emplace(fd_num, fdevent{});
CHECK(inserted);
fdevent* fde = &it->second;
fde->id = fdevent_id_++;
fde->state = 0;
fde->fd = std::move(fd);
fde->func = func;
fde->arg = arg;
...
this->Register(fde);
return fde;
}
//packages/modules/adb/fdevent/fdevent_epoll.cpp
void fdevent_context_epoll::Register(fdevent* fde) {
epoll_event ev = calculate_epoll_event(fde);
if (epoll_ctl(epoll_fd_.get(), EPOLL_CTL_ADD, fde->fd.get(), &ev) != 0) {
PLOG(FATAL) << "failed to register fd " << fde->fd.get() << " with epoll";
}
}
Create函数功能很简单,将参数封装成一个fdevent对象,主要就是一个fd,一个处理函数。Register将fd注册到epoll中来。
//packages/modules/adb/fdevent/fdevent_epoll.cpp
void fdevent_context_epoll::Set(fdevent* fde, unsigned events) {
unsigned previous_state = fde->state;
fde->state = events;
epoll_event ev = calculate_epoll_event(fde);
if (epoll_ctl(epoll_fd_.get(), EPOLL_CTL_MOD, fde->fd.get(), &ev) != 0) {
PLOG(FATAL) << "failed to modify fd " << fde->fd.get() << " with epoll";
}
}
fdevent_set最后会调用到fdevent_context_epoll::Set这里传进来的参数是FDE_READ,设置epoll监听fd的输入事件。下面看下install_listener是怎么监听端口的。
//packages/modules/adb/adb_listeners.cpp
InstallStatus install_listener(const std::string& local_name, const char* connect_to,
atransport* transport, int flags, int* resolved_tcp_port,
std::string* error) EXCLUDES(listener_list_mutex) {
....
auto listener = std::make_unique<alistener>(local_name, connect_to);//创建一个alistener对象
int resolved = 0;
listener->fd = socket_spec_listen(listener->local_name, error, &resolved);//创建socket,监听端口
if (listener->fd < 0) {
return INSTALL_STATUS_CANNOT_BIND;
}
// If the caller requested port 0, update the listener name with the resolved port.
if (resolved != 0) {
listener->local_name = android::base::StringPrintf("tcp:%d", resolved);
if (resolved_tcp_port) {
*resolved_tcp_port = resolved;
}
}
close_on_exec(listener->fd);
if (listener->connect_to == "*smartsocket*") {
#if ADB_HOST//同样使用epoll对listener->fd监听,回调方法为ss_listener_event_func
listener->fde = fdevent_create(listener->fd, ss_listener_event_func, listener.get());
#else
LOG(FATAL) << "attempted to connect to *smartsocket* in daemon";
#endif
} else {
listener->fde = fdevent_create(listener->fd, listener_event_func, listener.get());
}
if ((flags & INSTALL_LISTENER_DISABLED) == 0) {//这里是DISABLED所以不设置读取
fdevent_set(listener->fde, FDE_READ);
}
listener->transport = transport;
...
listener_list.push_back(std::move(listener));//添加到listener_list中
return INSTALL_STATUS_OK;
}
接着看下回调方法ss_listener_event_func
static void ss_listener_event_func(int _fd, unsigned ev, void *_l) {
if (ev & FDE_READ) {
unique_fd fd(adb_socket_accept(_fd, nullptr, nullptr));//获得连接的文件的fd
if (fd < 0) return;
int rcv_buf_size = CHUNK_SIZE;
adb_setsockopt(fd.get(), SOL_SOCKET, SO_RCVBUF, &rcv_buf_size, sizeof(rcv_buf_size));//设置了缓冲区
asocket* s = create_local_socket(std::move(fd));//创建一个local_asocket
if (s) {
connect_to_smartsocket(s);//就是将连接过来的fd和android端的socket关联起来
return;
}
}
}
static asocket* create_smart_socket(void) {
D("Creating smart socket");
asocket* s = new asocket();
s->enqueue = smart_socket_enqueue;
s->ready = smart_socket_ready;
s->shutdown = nullptr;
s->close = smart_socket_close;
D("SS(%d)", s->id);
return s;
}
void connect_to_smartsocket(asocket* s) {
D("Connecting to smart socket");
asocket* ss = create_smart_socket();
s->peer = ss;
ss->peer = s;
s->ready(s);
}
回到adb_server_main中调用notify_thread,在adb_wait_for_device_initialization();后设备连接成功,调用enable_server_sockets
void enable_server_sockets() EXCLUDES(listener_list_mutex) {
std::lock_guard<std::mutex> lock(listener_list_mutex);
for (auto& l : listener_list) {
if (l->connect_to == "*smartsocket*") {
fdevent_set(l->fde, FDE_READ);//install_listener中disable没开启读的功能在这开启。这样就能连接了。
}
}
}
最后通过loop来循环处理transport注册事件了。
//packages/modules/adb/fdevent/fdevent_epoll.cpp
void fdevent_context_epoll::Loop() {
...
while (true) {
int rc = -1;
while (rc == -1) {
...
rc = epoll_wait(epoll_fd_.get(), epoll_events.data(), epoll_events.size(), timeout_ms);
}
this->HandleEvents(fde_events);
fde_events.clear();
}
looper_thread_id_.reset();
}
void fdevent_context::HandleEvents(const std::vector<fdevent_event>& events) {
for (const auto& event : events) {
invoke_fde(event.fde, event.events);
}
FlushRunQueue();
}
主要流程就是通过epoll_wait来获取事件,然后调用注册的fde来处理事件,也就是前面注册epoll的时候的transport_registration_func。
//packages/modules/adb/transport.cpp
static void transport_registration_func(int _fd, unsigned ev, void*) {
tmsg m;
atransport* t;
if (!(ev & FDE_READ)) {
return;
}
if (transport_read_action(_fd, &m)) {//读取指令
PLOG(FATAL) << "cannot read transport registration socket";
}
t = m.transport;
if (m.action == tmsg::Action::UNREGISTER) {//如果指令是UNREGISTER就从transport_list中删除
D("transport: %s deleting", t->serial.c_str());
{
std::lock_guard<std::recursive_mutex> lock(transport_lock);
transport_list.remove(t);
}
delete t;
update_transports();
return;
}
/* don't create transport threads for inaccessible devices */
if (t->GetConnectionState() != kCsNoPerm) {
t->connection()->SetTransport(t);//为当前的连接设置transport
if (t->type == kTransportUsb && usb_devices_start_detached()) {
t->SetConnectionState(kCsDetached);
} else {
t->connection()->Start();//启动connection的io操作
#if ADB_HOST
send_connect(t);//发送连接消息
#endif
}
}
{
std::lock_guard<std::recursive_mutex> lock(transport_lock);
auto it = std::find(pending_list.begin(), pending_list.end(), t);
if (it != pending_list.end()) {
pending_list.remove(t);
transport_list.push_front(t);
}//将t添加到transport_list中的最前面
}
update_transports();//更新transport
}
这样在host上面的service启动完毕。中间有好几个socket可能有点晕。主要就是两部分:
- 初始化各种类型的连接方式,像usb,wifi这些,负责和设备的连接
- 在install_listener中监听5037端口,负责和client的连接。
回到connect。在启动之后第二次调用_adb_connect连接service,正常情况下连接成功会返回一个fd,创建连接。
static int _adb_connect(std::string_view service, TransportId* transport, std::string* error,
bool force_switch = false) {
LOG(DEBUG) << "_adb_connect: " << service;
if (service.empty() || service.size() > MAX_PAYLOAD) {
*error = android::base::StringPrintf("bad service name length (%zd)", service.size());
return -1;
}
std::string reason;
unique_fd fd;
if (!socket_spec_connect(&fd, __adb_server_socket_spec, nullptr, nullptr, &reason)) {
*error = android::base::StringPrintf("cannot connect to daemon at %s: %s",
__adb_server_socket_spec, reason.c_str());
return -2;
}
if (!service.starts_with("host") || force_switch) {
std::optional<TransportId> transport_result = switch_socket_transport(fd.get(), error);//设置transport
if (transport) {
*transport = *transport_result;
}
}
if (!SendProtocolString(fd.get(), service)) {
*error = perror_str("write failure during connection");
return -1;
}
if (!adb_status(fd.get(), error)) {
return -1;
}
D("_adb_connect: return fd %d", fd.get());
return fd.release();
}
先通过socket_spec_connect来建立连接
//packages/modules/adb/socket_spec.cpp
bool socket_spec_connect(unique_fd* fd, std::string_view address, int* port, std::string* serial,
std::string* error) {
if (address.starts_with("tcp:")) {
std::string hostname;
int port_value = port ? *port : 0;
if (!parse_tcp_socket_spec(address, &hostname, &port_value, serial, error)) {//将 tcp:localhost:5037转为真实的地址
return false;
}
if (tcp_host_is_local(hostname)) {//判断是不是本地的地址,几乎都是本地调试所以这里只看这一个分支
fd->reset(network_loopback_client(port_value, SOCK_STREAM, error));//创建一个socket连接到目标port,本地就不需要ip了
} else {
....
}
...
}
这里也看下linux的
static int _network_loopback_client(bool ipv6, int port, int type, std::string* error) {
unique_fd s(socket(ipv6 ? AF_INET6 : AF_INET, type, 0));
if (s == -1) {
set_error(error);
return -1;
}
struct sockaddr_storage addr_storage = {};
socklen_t addrlen = sizeof(addr_storage);
sockaddr* addr = (ipv6 ? loopback_addr6 : loopback_addr4)(&addr_storage, &addrlen, 0);
if (bind(s.get(), addr, addrlen) != 0) {
set_error(error);
return -1;
}
addr = (ipv6 ? loopback_addr6 : loopback_addr4)(&addr_storage, &addrlen, port);
if (connect(s.get(), addr, addrlen) != 0) {
set_error(error);
return -1;
}
return s.release();
}
就是创建了一个socket然后调用系统服务connect连接了port,返回了fd。这里就会触发前面监听端口的ss_listener_event_func。在ss_listener_event_func中将client和android设备的socket互相连接了起来。
Android adbd服务
在adbd_main很多代码和adb_server_main是很相似的。
//packages/modules/adb/daemon/main.cpp
int main(int argc, char** argv) {
#if defined(__BIONIC__)
...
D("Handling main()");
return adbd_main(DEFAULT_ADB_PORT);
}
int adbd_main(int server_port) {
umask(0);//修改了文件权限,为最大权限
...
init_transport_registration();// 和host中的初始化一样,创建一对socket注册处理函数
...
#if defined(__ANDROID__)
drop_privileges(server_port);//将权限从root降低为shell
#endif
#if defined(__ANDROID__)
watchdog::Initialize();
#endif
// adbd_auth_init will spawn a thread, so we need to defer it until after selinux transitions.
adbd_auth_init();//授权行为的初始化
bool is_usb = false;
#if defined(__ANDROID__)
if (access(USB_FFS_ADB_EP0, F_OK) == 0) {
// Listen on USB.
usb_init();//初始化usb连接的监听
is_usb = true;
}
#endif
// If one of these properties is set, also listen on that port.
// If one of the properties isn't set and we couldn't listen on usb, listen
// on the default port.
std::vector<std::string> addrs;
std::string prop_addr = android::base::GetProperty("service.adb.listen_addrs", "");
if (prop_addr.empty()) {
std::string prop_port = android::base::GetProperty("service.adb.tcp.port", "");
if (prop_port.empty()) {
prop_port = android::base::GetProperty("persist.adb.tcp.port", "");
}
#if !defined(__ANDROID__)
if (prop_port.empty() && getenv("ADBD_PORT")) {
prop_port = getenv("ADBD_PORT");
}
#endif
int port;
if (sscanf(prop_port.c_str(), "%d", &port) == 1 && port > 0) {
D("using tcp port=%d", port);
// Listen on TCP and VSOCK port specified by service.adb.tcp.port property.
addrs.push_back(android::base::StringPrintf("tcp:%d", port));
addrs.push_back(android::base::StringPrintf("vsock:%d", port));
setup_adb(addrs);//设置port处理tcp连接
} else if (!is_usb) {
// Listen on default port.
addrs.push_back(
android::base::StringPrintf("tcp:%d", DEFAULT_ADB_LOCAL_TRANSPORT_PORT));
addrs.push_back(
android::base::StringPrintf("vsock:%d", DEFAULT_ADB_LOCAL_TRANSPORT_PORT));
setup_adb(addrs);
}
} else {
addrs = android::base::Split(prop_addr, ",");
setup_adb(addrs);
}
LOG(INFO) << "adbd started";
D("adbd_main(): pre init_jdwp()");
init_jdwp();//初始化 java 调试框架和host中一样
D("adbd_main(): post init_jdwp()");
D("Event loop starting");
fdevent_loop();//循环接受事件并处理,也和host中的一样
return 0;
}
重点就看下setup_adb,adb连接有很多种方式,通过tcp就是setup_adb中初始化的。
static void setup_adb(const std::vector<std::string>& addrs) {
#if defined(__ANDROID__)
// Get the first valid port from addrs and setup mDNS.
int port = -1;
std::string error;
for (const auto& addr : addrs) {
port = get_host_socket_spec_port(addr, &error);//获取port
if (port != -1) {
break;
}
}
if (port == -1) {
port = DEFAULT_ADB_LOCAL_TRANSPORT_PORT;
}
LOG(INFO) << "Setup mdns on port= " << port;
setup_mdns(port);//和host一样的设计mdns
#endif
for (const auto& addr : addrs) {
LOG(INFO) << "adbd listening on " << addr;
local_init(addr);
}
}
//packages/modules/adb/daemon/transport_local.cpp
void local_init(const std::string& addr) {
D("transport: local server init");
std::thread(server_socket_thread, adb_listen, addr).detach();//创建了一个线程监听这个地址
}
setup_adb中调用local_init,local_init中启动了一个线程,执行server_socket_thread,server_socket_thread中通过adb_listen监听传入的addr。
//packages/modules/adb/daemon/transport_local.cpp
unique_fd adb_listen(std::string_view addr, std::string* error) {
return unique_fd{socket_spec_listen(addr, error, nullptr)};//也是创建一个监听的socket
}
void server_socket_thread(std::function<unique_fd(std::string_view, std::string*)> listen_func,
std::string_view addr) {
adb_thread_setname("server socket");
unique_fd serverfd;
std::string error;
while (serverfd == -1) {
errno = 0;
serverfd = listen_func(addr, &error);//这里调用传进来adb_listen
...
close_on_exec(serverfd.get());
}
while (true) {//这里就是标准的服务端代码了
D("server: trying to get new connection from fd %d", serverfd.get());
unique_fd fd(adb_socket_accept(serverfd, nullptr, nullptr));//监听客户端请求
if (fd >= 0) {
D("server: new connection on fd %d", fd.get());
close_on_exec(fd.get());
disable_tcp_nagle(fd.get());
std::string serial = android::base::StringPrintf("host-%d", fd.get());
register_socket_transport(
std::move(fd), std::move(serial), 0, 1,
[](atransport*) { return ReconnectResult::Abort; }, false);//将连接的socket注册保存起来
}
}
D("transport: server_socket_thread() exiting");
}
server_socket_thread作用就是监听传进来的地址,当有客户端连接就创建一个新链接,然后通过register_socket_transport将传输连接保存起来。
//packages/modules/adb/transport.cpp
bool register_socket_transport(unique_fd s, std::string serial, int port, int local,
atransport::ReconnectCallback reconnect, bool use_tls, int* error) {
atransport* t = new atransport(std::move(reconnect), kCsOffline);//对连接的抽象
t->use_tls = use_tls;
t->serial = std::move(serial);
D("transport: %s init'ing for socket %d, on port %d", t->serial.c_str(), s.get(), port);
if (init_socket_transport(t, std::move(s), port, local) < 0) {
delete t;
if (error) *error = errno;
return false;
}
std::unique_lock<std::recursive_mutex> lock(transport_lock);
pending_list.push_front(t);
lock.unlock();
register_transport(t);
if (local == 1) {
// Do not wait for emulator transports.
return true;
}
return true;
}
int init_socket_transport(atransport* t, unique_fd fd, int adb_port, int local) {//将连接保存起来
t->type = kTransportLocal;
auto fd_connection = std::make_unique<FdConnection>(std::move(fd));
t->SetConnection(std::make_unique<BlockingConnectionAdapter>(std::move(fd_connection)));
return 0;
}
void register_transport(atransport* transport) {
tmsg m;
m.transport = transport;
m.action = tmsg::Action::REGISTER;
D("transport: %s registered", transport->serial.c_str());
if (transport_write_action(transport_registration_send, &m)) {//将注册成功的消息发送给transport_registration_send
PLOG(FATAL) << "cannot write transport registration socket";
}
}
transport_registration_send的消息会进入transport_registration_func,这个方法前面讲过主要就是将自己注册到transport_list中,然后调用connect的start方法,最后通过update_transports更新。由于这不是ADB_HOST环境,所以update_transports是个空实现。
在init_socket_transport中创建的是一个BlockingConnectionAdapter类型的transport,所以Start就是BlockingConnectionAdapter::Start。
void BlockingConnectionAdapter::Start() {
std::lock_guard<std::mutex> lock(mutex_);
if (started_) {
LOG(FATAL) << "BlockingConnectionAdapter(" << Serial() << "): started multiple times";
}
StartReadThread();//启动Read线程
write_thread_ = std::thread([this]() {//创建写线程
LOG(INFO) << Serial() << ": write thread spawning";
while (true) {
std::unique_lock<std::mutex> lock(mutex_);
ScopedLockAssertion assume_locked(mutex_);
cv_.wait(lock, [this]() REQUIRES(mutex_) {
return this->stopped_ || !this->write_queue_.empty();
});//在没有写的数据并且没有退出的时候wait
if (this->stopped_) {
return;
}
std::unique_ptr<apacket> packet = std::move(this->write_queue_.front());//获取队列中最前面的包
this->write_queue_.pop_front();
lock.unlock();
if (!this->underlying_->Write(packet.get())) {//写入
break;
}
}
//跳出循环就是写入出错了报错
std::call_once(this->error_flag_, [this]() { transport_->HandleError("write failed"); });
});
started_ = true;
}
读取数据都是通过StartReadThread().
//packages/modules/adb/transport.cpp
void BlockingConnectionAdapter::StartReadThread() {
read_thread_ = std::thread([this]() {
LOG(INFO) << Serial() << ": read thread spawning";
while (true) {//也是创建一个线程然后一个死循环一直读取
auto packet = std::make_unique<apacket>();
if (!underlying_->Read(packet.get())) {//读取数据
PLOG(INFO) << Serial() << ": read failed";
break;
}
bool got_stls_cmd = false;
if (packet->msg.command == A_STLS) {
got_stls_cmd = true;
}
transport_->HandleRead(std::move(packet));//处理数据
// If we received the STLS packet, we are about to perform the TLS
// handshake. So this read thread must stop and resume after the
// handshake completes otherwise this will interfere in the process.
if (got_stls_cmd) {
LOG(INFO) << Serial() << ": Received STLS packet. Stopping read thread.";
return;
}
}
std::call_once(this->error_flag_, [this]() { transport_->HandleError("read failed"); });
});
}
终于拿到了数据在HandleRead处理。
//packages/modules/adb/transport.cpp
bool atransport::HandleRead(std::unique_ptr<apacket> p) {
if (!check_header(p.get(), this)) {
D("%s: remote read: bad header", serial.c_str());
return false;
}
VLOG(TRANSPORT) << dump_packet(serial.c_str(), "from remote", p.get());
apacket* packet = p.release();
// This needs to run on the looper thread since the associated fdevent
// message pump exists in that context.
fdevent_run_on_looper([packet, this]() { handle_packet(packet, this); });
return true;
}
这里逻辑就很简单了,拿到apacket,切换到主线程,执行handle_packet。创建连接部分的握手消息这次不是重点就不看了,这么久之后还记得最初发送到设备上的是什么吗,是 "abb_exec:"+上我们命令行里的参数,在handle_packet会打开abb服务。
case A_OPEN: {
uint32_t send_bytes = static_cast<uint32_t>(p->msg.arg1);//获取消息
if (t->SupportsDelayedAck() != static_cast<bool>(send_bytes)) {
LOG(ERROR) << "unexpected value of A_OPEN arg1: " << send_bytes
<< " (delayed acks = " << t->SupportsDelayedAck() << ")";
send_close(0, p->msg.arg0, t);
break;
}
std::string_view address(p->payload.begin(), p->payload.size());
address = StripTrailingNulls(address);
asocket* s = create_local_service_socket(address, t);//创建本地服务
s->peer = create_remote_socket(p->msg.arg0, t);
s->peer->peer = s;//将打开的服务的peer设置为客户端的socket
....
break;
}
//packages/modules/adb/sockets.cpp
asocket* create_local_service_socket(std::string_view name, atransport* transport) {
if (asocket* s = daemon_service_to_socket(name, transport); s) {//创建本地服务,返回fd
return s;
}
...
return s;
}
//packages/modules/adb/daemon/services.cpp
unique_fd daemon_service_to_fd(std::string_view name, atransport* transport) {
if (name.starts_with("abb:") || name.starts_with("abb_exec:")) {
return execute_abb_command(name);
}
.....
}
终于来到了abb_service中,execute_abb_command肯定是根据参数启动了服务
//packages/modules/adb/daemon/abb_service.cpp
unique_fd execute_abb_command(std::string_view command) {
return abbp->sendCommand(command);
}
unique_fd AbbProcess::sendCommand(std::string_view command) {
std::unique_lock lock{locker_};
for (int i = 0; i < kRetries; ++i) {//循环两次,失败就报错返回
unique_fd error_fd;
if (socket_fd_ == -1) {
socket_fd_ = startAbbProcess(&error_fd);//启动abb进程
}
if (!SendProtocolString(socket_fd_, command)) {//发送指令
PLOG(ERROR) << "failed to send command to abb";
socket_fd_.reset();
continue;
}
unique_fd fd;
char buf;
if (android::base::ReceiveFileDescriptors(socket_fd_, &buf, 1, &fd) != 1) {//接受abb的fd
PLOG(ERROR) << "failed to receive FD from abb";
socket_fd_.reset();
continue;
}
return fd;
}
LOG(ERROR) << "abb is unavailable";
socket_fd_.reset();
return ReportError(kErrorProtocol, "abb is unavailable");
}
三步
- 创建服务
- 发送指令
- 获取fd并返回
//packages/modules/adb/daemon/abb_service.cpp
unique_fd AbbProcess::startAbbProcess(unique_fd* error_fd) {
constexpr auto abb_process_type = SubprocessType::kRaw;
constexpr auto abb_protocol = SubprocessProtocol::kNone;
constexpr auto make_pty_raw = false;
return StartSubprocess("abb", "dumb", abb_process_type, abb_protocol, make_pty_raw,
kErrorProtocol, error_fd);
}
unique_fd StartSubprocess(std::string name, const char* terminal_type, SubprocessType type,
SubprocessProtocol protocol, bool make_pty_raw,
SubprocessProtocol error_protocol, unique_fd* error_fd) {
D("starting %s subprocess (protocol=%s, TERM=%s): '%s'",
type == SubprocessType::kRaw ? "raw" : "PTY",
protocol == SubprocessProtocol::kNone ? "none" : "shell", terminal_type, name.c_str());
auto subprocess = std::make_unique<Subprocess>(std::move(name), terminal_type, type, protocol,
make_pty_raw);//创建一个Subprocess
...
std::string error;
if (!subprocess->ForkAndExec(&error)) {//执行fork,根据服务名字启动服务,在startAbbProcess中传进来的abb,就会启动abb
LOG(ERROR) << "failed to start subprocess: " << error;
*error_fd = ReportError(error_protocol, error);
return {};
}
unique_fd local_socket(subprocess->ReleaseLocalSocket());//获取子进程的fd
if (!Subprocess::StartThread(std::move(subprocess), &error)) {//启动线程
LOG(ERROR) << "failed to start subprocess management thread: " << error;
*error_fd = ReportError(error_protocol, error);
return {};
}
return local_socket;
}
这里看下ForkAndExec开启子进程。
bool Subprocess::ForkAndExec(std::string* error) {
unique_fd child_stdinout_sfd, child_stderr_sfd;
unique_fd parent_error_sfd, child_error_sfd;
const char* pts_name = nullptr;
if (!CreateSocketpair(&parent_error_sfd, &child_error_sfd)) {//创建socket用于父子进程通讯
*error = android::base::StringPrintf(
"failed to create pipe for subprocess error reporting: %s", strerror(errno));
return false;
}
// Construct the environment for the child before we fork.
passwd* pw = getpwuid(getuid());
std::unordered_map<std::string, std::string> env;
if (environ) {//设置环境
char** current = environ;
while (char* env_cstr = *current++) {
std::string env_string = env_cstr;
char* delimiter = strchr(&env_string[0], '=');
// Drop any values that don't contain '='.
if (delimiter) {
*delimiter++ = '\0';
env[env_string.c_str()] = delimiter;
}
}
}
.....
if (command_.empty()) {//关于启动就是根据command_在shell中执行
// Spawn a login shell if we don't have a command.
execle(_PATH_BSHELL, "-" _PATH_BSHELL, nullptr, cenv.data());
} else {
execle(_PATH_BSHELL, _PATH_BSHELL, "-c", command_.c_str(), nullptr, cenv.data());
}
....
return true;
}
通过abb启动了abb服务,接下来就看下abb的实现。
//packages/modules/adb/daemon/abb.cpp
int main(int argc, char* const argv[]) {
signal(SIGPIPE, SIG_IGN);
int fd = STDIN_FILENO;
std::string data;
while (true) {
std::string error;
...
std::string_view name = data;
auto protocol = SubprocessProtocol::kShell;
if (android::base::ConsumePrefix(&name, "abb:")) {
protocol = SubprocessProtocol::kShell;
} else if (android::base::ConsumePrefix(&name, "abb_exec:")) {//这就是从clinet中传过来的
protocol = SubprocessProtocol::kNone;//将协议设置成SubprocessProtocol::kNone
} else {
LOG(FATAL) << "Unknown command prefix for abb: " << data;
}
unique_fd result = StartCommandInProcess(std::string(name), &execCmd, protocol);//名字可以知道是在当前进程执行指令。
int max_buf = LINUX_MAX_SOCKET_SIZE;
adb_setsockopt(result, SOL_SOCKET, SO_SNDBUF, &max_buf, sizeof(max_buf));
}
}
//packages/modules/adb/daemon/shell_service.cpp
bool Subprocess::ExecInProcess(Command command, std::string* _Nonnull error) {
unique_fd child_stdinout_sfd, child_stderr_sfd;
CHECK(type_ == SubprocessType::kRaw);
__android_log_security_bswrite(SEC_TAG_ADB_SHELL_CMD, command_.c_str());
if (!CreateSocketpair(&stdinout_sfd_, &child_stdinout_sfd)) {//有创建了Socketpair
*error = android::base::StringPrintf("failed to create socketpair for stdin/out: %s",
strerror(errno));
return false;
}
if (protocol_ == SubprocessProtocol::kShell) {//协议是SubprocessProtocol::kNone
// Shell protocol allows for splitting stderr.
if (!CreateSocketpair(&stderr_sfd_, &child_stderr_sfd)) {
*error = android::base::StringPrintf("failed to create socketpair for stderr: %s",
strerror(errno));
return false;
}
} else {
// Raw protocol doesn't support multiple output streams, so combine stdout and stderr.
child_stderr_sfd.reset(dup(child_stdinout_sfd.get()));
}
D("execinprocess: stdin/stdout FD = %d, stderr FD = %d", stdinout_sfd_.get(),
stderr_sfd_.get());
if (!ConnectProtocolEndpoints(error)) {//因为是NONE,所以没影响
return false;
}
std::thread([inout_sfd = std::move(child_stdinout_sfd), err_sfd = std::move(child_stderr_sfd),
command = std::move(command),
args = command_]() { command(args, inout_sfd, inout_sfd, err_sfd); })
.detach();//这次不是子进程了,启动了一个线程。 终于要执行命令了,command是从abb_main中传进来的&execCmd
D("execinprocess: completed");
return true;
}
最终是调用execCmd执行了命令。回到abb中看下实现。
//packages/modules/adb/daemon/abb.cpp
static int execCmd(std::string_view args, borrowed_fd in, borrowed_fd out, borrowed_fd err) {
int max_buf = LINUX_MAX_SOCKET_SIZE;
adb_setsockopt(in, SOL_SOCKET, SO_SNDBUF, &max_buf, sizeof(max_buf));
adb_setsockopt(out, SOL_SOCKET, SO_SNDBUF, &max_buf, sizeof(max_buf));
adb_setsockopt(err, SOL_SOCKET, SO_SNDBUF, &max_buf, sizeof(max_buf));
AdbFdTextOutput oin(out);
AdbFdTextOutput oerr(err);
return cmdMain(parseCmdArgs(args), oin, oerr, in.get(), out.get(), err.get(),
RunMode::kLibrary);//通过cmdMain执行
}
int cmdMain(const std::vector<std::string_view>& argv, TextOutput& outputLog, TextOutput& errorLog,
int in, int out, int err, RunMode runMode) {
sp<ProcessState> proc = ProcessState::self();//使用binder的一套流程
proc->startThreadPool();
#if DEBUG
ALOGD("cmd: starting");
#endif
sp<IServiceManager> sm = defaultServiceManager();
if (runMode == RunMode::kStandalone) {
fflush(stdout);
}
if (sm == nullptr) {
ALOGW("Unable to get default service manager!");
errorLog << "cmd: Unable to get default service manager!" << endl;
return 20;
}
int argc = argv.size();
...
bool waitForService = ((argc > 1) && (argv[0] == "-w"));
int serviceIdx = (waitForService) ? 1 : 0;
const auto cmd = argv[serviceIdx];
Vector<String16> args;
String16 serviceName = String16(cmd.data(), cmd.size());
for (int i = serviceIdx + 1; i < argc; i++) {
args.add(String16(argv[i].data(), argv[i].size()));
}
sp<IBinder> service;
if(waitForService) {
service = sm->waitForService(serviceName);
} else {
service = sm->checkService(serviceName);
}
if (service == nullptr) {
if (runMode == RunMode::kStandalone) {
ALOGW("Can't find service %.*s", static_cast<int>(cmd.size()), cmd.data());
}
errorLog << "cmd: Can't find service: " << cmd << endl;
return 20;
}
sp<MyShellCallback> cb = new MyShellCallback(errorLog);
sp<MyResultReceiver> result = new MyResultReceiver();
// TODO: block until a result is returned to MyResultReceiver.
status_t error = IBinder::shellCommand(service, in, out, err, args, cb, result);//又是一个binder调用执行,然后返回结果
....
cb->mActive = false;
status_t res = result->waitForResult();
return res;
}
到这里就是一个正常的binder调用了,在install_app_streamed中系统自动增加了一个参数"package",这就是packagemanager在android中的名字,servicemanager通过这个名字找到PMS,通过binder调用PMS的安装。
adb的功能在一次安装中的功能到这里也就结束了。