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/netd class main socket netd stream 0660 root system socket dnsproxyd stream 0660 root inet socket mdns stream 0660 root system socket 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网络模块各方面,后面有时间再深入分析。