接下来开始从代码分析,按照从下至上的顺序来分析,从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 的桥梁。