NetD初探

来源:互联网 发布:淘宝实名认证在哪里看 编辑:程序博客网 时间:2024/04/30 04:10
netd是Android与Linux网络模块之间的接口,类似于RILD和Modem的关系。JAVA层的通过socket与netd交互。

framework层定义了系统服务NetworkManagementService来提供netd相关处理的接口,再通过NativeDaemonConnector实现与Netd交互。

下面先分析下JAVA层入口:


1.NetworkManagementService
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初始化


3. 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网络模块各方面,后面有时间再深入分析。


0 0
原创粉丝点击