NetD初探
来源:互联网 发布:淘宝实名认证在哪里看 编辑:程序博客网 时间:2024/04/30 04:10
framework层定义了系统服务NetworkManagementService来提供netd相关处理的接口,再通过NativeDaemonConnector实现与Netd交互。
下面先分析下JAVA层入口:
NetworkManagementService是AIDL接口的实现类,属于System进程并由watchdog守护。
public class NetworkManagementService extends INetworkManagementService.Stub implements Watchdog.Monitor
2.NetworkManagementService的启动
开机后由SystemServer初始化:
</pre><pre>
try {Slog.i(TAG, "NetworkManagement Service"); networkManagement = NetworkManagementService.create(context); ServiceManager.addService(Context.NETWORKMANAGEMENT_SERVICE, networkManagement);} catch (Throwable e) { <span style="font-family: Arial, Helvetica, sans-serif;">reportWtf("starting NetworkManagement Service", e);}</span>
NetworkManagementService::create方法会创建实例,并执行一个子线程。
static NetworkManagementService create(Context context, String socket) throws InterruptedException { final NetworkManagementService service = new NetworkManagementService(context, socket); final CountDownLatch connectedSignal = service.mConnectedSignal; service.mThread.start();<span style="color:#ff0000;">//子线程中执行操作</span> connectedSignal.await(); return service; }
</pre><pre name="code" class="java"> public static NetworkManagementService create(Context context) throws InterruptedException { return create(context, NETD_SOCKET_NAME);<span style="color:#ff0000;">//指定netd socket的名字</span> }
NetworkManagementService::create中所启动的线程就是用来执行NativeDaemonConnector::run()的,即用于对netd socket的监听,具体请看4. NativeDaemonConnector初始化
NativeDaemonConnector类实现了Runnable,Handler.Callback和watchdog monitor
final class NativeDaemonConnector implements Runnable, Handler.Callback, Watchdog.Monitor
其run方法循环监听netd上报的消息,listenToSocket收到消息后发送给mCallbackHandler处理:
public void run() { mCallbackHandler = new Handler(mLooper, this); while (true) { try { listenToSocket();<span style="font-family: Arial, Helvetica, sans-serif;">//监听来自netd Socket的消息</span> } catch (Exception e) { loge("Error in NativeDaemonConnector: " + e); SystemClock.sleep(5000); } } }
4. NativeDaemonConnector初始化
NativeDaemonConnector在NetworkManagementService构造函数中初始化:
private NetworkManagementService(Context context, String socket) {... <span style="color:#ff0000;">//NetdCallbackReceiver接收NativeDaemonConnector回发的消息</span> mConnector = new NativeDaemonConnector(new NetdCallbackReceiver(), socket, 10, NETD_TAG, 160, wl, FgThread.get().getLooper()); mThread = new Thread(mConnector, NETD_TAG); <span style="color:#ff0000;">//新建线程</span>...}
新建的线程用于执行NativeDaemonConnector::run(),及调用listenToSocket()循环监听socket。
5. 监听来自netd消息:
监听消息处理在NativeDaemonConnector::listenToSocket中执行,接收到之后发送到Handler处理,并回调NetworkManagementService内部的NetdCallbackReceiver::onEvent()
6. 向netd发送执行命令:
NetworkManagementService提供了大量netd支持的接口, 都会通过NativeDaemonConnector发送至netd:
NativeDaemonConnector::execute接口用于接受具体命令,以NetworkManagementService::setDefaultNetId为例,传入命令参数是"network" + "default" + "set" + netId:
public void setDefaultNetId(int netId) { mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG); try { mConnector.execute("network", "default", "set", netId); } catch (NativeDaemonConnectorException e) { throw e.rethrowAsParcelableException(); } }
最后NativeDaemonConnector::executeForList 通过socket outstream向netd发送命令:
public NativeDaemonEvent[] executeForList(long timeoutMs, String cmd, Object... args) throws NativeDaemonConnectorException {... makeCommand(rawBuilder, logBuilder, sequenceNumber, cmd, args); log("SND -> {" + logCmd + "}"); synchronized (mDaemonLock) { if (mOutputStream == null) { throw new NativeDaemonConnectorException("missing output stream"); } else { try { mOutputStream.write(rawCmd.getBytes(StandardCharsets.UTF_8)); } catch (IOException e) { throw new NativeDaemonConnectorException("problem sending command", e); } } }...}
7. netd
netd作为linux服务,在init.rc中定义:
service netd /system/bin/netdclass mainsocket netd stream 0660 root systemsocket dnsproxyd stream 0660 root inetsocket mdns stream 0660 root systemsocket fwmarkd stream 0660 root inet
netd代码在/system/netd目录下,按照每个功能定义了处理模块,如Tethering相关功能由TetherController.cpp处理:
CommandListener.cpp是处理命令的入口,分解命令后指定对应的模块函数来处理。
以setDefaultNetId为例:
int CommandListener::NetworkCommand::runCommand(SocketClient* client, int argc, char** argv) {...if (!strcmp(argv[1], "<span style="background-color: rgb(255, 102, 102);">default</span>")) { if (argc < 3) { return syntaxError(client, "Missing argument"); } unsigned netId = NETID_UNSET; if (!strcmp(argv[2], "set")) { if (argc < 4) { return syntaxError(client, "Missing netId"); } netId = stringToNetId(argv[3]); } else if (strcmp(argv[2], "clear")) { return syntaxError(client, "Unknown argument"); } if (int ret = sNetCtrl->setDefaultNetwork(netId)) { return operationError(client, "setDefaultNetwork() failed", ret); } return success(client); }...}
这个只是netd的入口,具体实现涉及到linux网络模块各方面,后面有时间再深入分析。
- NetD初探
- netd
- Android Netd
- netd 框图
- android netd守护进程机制 --- netd分析
- Netd学习笔记
- netd的分析
- asp.netd点滴
- Android Netd介绍
- Netd工作流程
- android netd 笔记
- Netd工作流程
- Android - NETD解读
- Netd测试工具ndc
- Android5.0网络之netd
- [Android4.4]netd启动流程
- 超级服务netd和xinetd
- wifi详解-2(netd)
- C++外部排序(选择置换+败者树)
- 文件I/O和标准I/O区别
- [LeetCode] 264. Ugly Number II
- she's the one
- 51nod 1022 石子归并 V2
- NetD初探
- (1)spring boot起步之Hello World【从零开始学Spring Boot】
- 【坐在马桶上看算法】算法6:只有五行的Floyd最短路算法
- 父元素与子元素之间的margin-top问题(css hack)
- 51nod 1024 矩阵中不重复的元素
- Equal Sum Sets (DFS)
- 一天一条Linux指令-join
- 编写一个简易的 HTTP 服务器程序
- 51nod 1027 大数乘法