Android(安卓)4.1 Netd详细分析(三)代码分析1
16lz
2021-01-26
个人邮箱:xiaokeweng@gmail.com
接下来开始从代码分析,按照从下至上的顺序来分析,从native层向framework层过渡,Android的各个层之间严格按照软件工程原理的低耦合要求.#include <stdio.h>#include <stdlib.h>#include <signal.h>#include <errno.h>#include <string.h>#include <sys/stat.h>#include <sys/types.h>#include <sys/wait.h>#include <fcntl.h>#include <dirent.h>#define LOG_TAG "Netd"#include "cutils/log.h"#include "CommandListener.h"#include "NetlinkManager.h"#include "DnsProxyListener.h"#include "MDnsSdListener.h"static void coldboot(const char *path);static void sigchld_handler(int sig);static void blockSigpipe();int main() {/*********************************************************以下两个为函数主要使用的类*CommandListener :监听 framework 层的命令,并调用本类中注册的处理函数,并将处理结果返回*NetLinkManager :管理 kernel 层相关的 event,将收到收到的信息提交给 framework 层********************************************************/ CommandListener *cl; NetlinkManager *nm;/********************************************************* 这两个可以各自理解为单独的工作模块,相对上面的类更加简单。* DnsProxyListener :DNS 解析,通过系统库函数 getaddrinfo,并将解析结果反馈给 framework 层* MDnsSdListener :Muliticast-DNS Server Descript 利用局域网其他对象解析********************************************************/ DnsProxyListener *dpl; MDnsSdListener *mdnsl; ALOGI("Netd 1.0 starting");// signal(SIGCHLD, sigchld_handler); blockSigpipe();//禁用Sigpipe if (!(nm = NetlinkManager::Instance())) {//实例化nm ALOGE("Unable to create NetlinkManager"); exit(1); };/******************************************************** nm->setBroadcaster((SocketListener *) cl)* setBroadcaster函数将NetlinkManager的成员变量mBroadcaster设置成cl,这两个变量都是* ScoketListener的指针类型,命令执行广播函数,就会调用这个SocketListener的指针来调用* SocketListener类的广播函数* 因为:继承关系:* CommandListener(子类)-->FrameworkListener()-->SocketListener(父类)*******************************************************/ cl = new CommandListener();//实例化cl nm->setBroadcaster((SocketListener *) cl);//关联nm和cl这样nm就可以通过方法//广播消息来回复给framework/*************************************************** 使用了 Netlink socket 是用于实现用户进程与内核进程通信的 IPC,* 下面的 start()就是开启监听内核的线程。*************************************************/ if (nm->start()) { ALOGE("Unable to start NetlinkManager (%s)", strerror(errno)); exit(1); }/*************************************************** 关于DnsProxyListener/MdnsSdListener会在后面单独详细* 各自的原理同CommandListener+NetlinkManager两个组成的系统**************************************************/ // Set local DNS mode, to prevent bionic from proxying(自动代理) // back to this service, recursively.(递归) // DnsProxyListener -> FrameworkListrner -> SocketListener setenv("ANDROID_DNS_MODE", "local", 1); //设置为本地模式,是一个全局变量 //DNS dpl = new DnsProxyListener(); if (dpl->startListener()) { ALOGE("Unable to start DnsProxyListener (%s)", strerror(errno)); exit(1); } //multicast_DNS_server_descript_listener//多播DNS守护进程//内网没有DNS服务器时,出现此组播 mdnsl = new MDnsSdListener(); if (mdnsl->startListener()) { ALOGE("Unable to start MDnsSdListener (%s)", strerror(errno)); exit(1); }/************************************************* cl 开启线程,监听 framework 层下发的命令,并调用相关函数处理*********************************************** */ if (cl->startListener()) { ALOGE("Unable to start CommandListener (%s)", strerror(errno)); exit(1); } // 成为守护进程 while(1) { sleep(1000); } ALOGI("Netd exiting"); exit(0);} ///*********打杂函数**************//// 实际还真没看到打杂的意义/作用是什么……static void do_coldboot(DIR *d, int lvl){ struct dirent *de; int dfd, fd; dfd = dirfd(d); fd = openat(dfd, "uevent", O_WRONLY); if(fd >= 0) { write(fd, "add\n", 4); close(fd); } while((de = readdir(d))) { DIR *d2; if (de->d_name[0] == '.') continue; if (de->d_type != DT_DIR && lvl > 0) continue; fd = openat(dfd, de->d_name, O_RDONLY | O_DIRECTORY); if(fd < 0) continue; d2 = fdopendir(fd); if(d2 == 0) close(fd); else { do_coldboot(d2, lvl + 1); closedir(d2); } }}static void coldboot(const char *path){ DIR *d = opendir(path); if(d) { do_coldboot(d, 0); closedir(d); }}static void sigchld_handler(int sig) { pid_t pid = wait(NULL); ALOGD("Child process %d exited", pid);}static void blockSigpipe(){ sigset_t mask; sigemptyset(&mask); sigaddset(&mask, SIGPIPE); if (sigprocmask(SIG_BLOCK, &mask, NULL) != 0) ALOGW("WARNING: SIGPIPE not blocked\n");}
至此,按照 main 函数的流程进行分析。首先如上图,系统的部分主干关系图,系统可以按照功能和相关性分为三大部分,DnsProxyLis-
tener,MDnsSdListener,和 CommandListener + NetlinkManager 三大部分,每个部分都能够利用内
部 socket 和独立线程,接收到 Framework 层的命令,系统调用操作 Kernel 层,并回复 Framework 反
馈,可是说 Netd 充当了 Framework 与 kernel 的桥梁。
更多相关文章
- TabActivity子类中处理返回键事件
- android showSoftInput方法调用软键盘不显示
- Android(安卓)webView与JavaScript的交互
- Android函数响应式编程——必学的RxJava组合操作符startWith、me
- Android,一个函数实现指南针
- android-market-api
- android用户界面-组件Widget-网络视图WebView
- Android(安卓)进阶——Framework 核心四大组件之跨进程共享组件C
- Android(安卓)双开沙箱 VirtualApp 源码分析(四)启动插件 Service