守护进程框架简单分析 (基于NetD)

守护进程框架简单分析 (基于NetD)

Main.cpp

  1. CommandListener对象,用于接收Framework层通过socket传下来的指令。
  2. NetlinkManager对象,创建与底层通信的Netlink Socket。
  3. MDnsSDListener对象

CommandListener.cpp

  1. 继承自FrameworkListener–SocketListener
    传进Netd字符串,作为将要监听的socket的name.
    FrameworkListener中新建mCommands list用来将要register的cmd.

    typedef android::sysutils::List<FrameworkCommand *> FrameworkCommandCollection;
    
  2. CommandListener中registerCmd注册各种自定义的Command。其父类FrameworkListener中将其将入到mCommands中去。
    自定义的Command继承自NetdCommand,其祖父类为FrameworkCommand.其构造参数为Command名字。
    自定义的Command必须重写runCommand函数,该函数为Command的具体处理函数。
    自定义control类,协助处理对应Command的runCommand函数。
  3. SocketListener中间听到客户端的消息后,回调FrameworkListener的onDataVailable函数,参数cli为客户端信息,然后根据命令信息,回调对应命令的runCommand函数。cli可用于向客户端反馈信息。
  4. SocketListener中sendBroadcast可以广播通知所有客户端。

NetlinkManager.cpp

  1. NetlinkManager的start函数中,调用setupSocekt创建Netlink Socket,并创建一个NetlinkHandler监听Netlink。
  2. NetlinkHandler继承自NetlinkListener。因此,如果Netlink Socket接收到消息,同样回调onDataVailable函数。
    onDataVailable函数中会新建一个NetlinkEvent对象,并调用该对象的decode函数解析Netlink Socket接收到的数据。decode函数中会根据NetlinkListener的format确定解析方法,以二进制解析还是ascii解析。解析完成后回调Netlink Handler的onEvent,将解析数据传递出来。
    Netd中的Netlink Handler的onEvent函数中会将结果通过CommandListener的sendBroadcast功能notify给framework层。

MDnsSDListener.cpp

原理与CommandListener类似,不展开介绍。

Framework层

NativeDaemonConnector类为Framework与守护进程通讯的工具类,会在NetworkManagermentService中被使用到。NativeDaemonConnector主要做两件事:1、接收底层反馈,2、向守护进程发送命令。
1. NativeDaemonConnector继承自Runnable,因此start后调用run函数,即可开始监听守护进程的socket。

    interface INativeDaemonConnectorCallbacks {
        void onDaemonConnected();
        boolean onCheckHoldWakeLock(int code);
        boolean onEvent(int code, String raw, String[] cooked);
    }  

NativeDaemonConnector构造函数第一个参数即为回调函数,该回调函数必须继承上面这个接口,并实现其函数
NativeDaemonConnector在start后即开始监听,监听到消息后封装成NativeDaemonEvent交由本身的handleMessage处理,handleMessage会回调用户回调函数的onEvent函数。
NativeDaemonEvent的parse函数可知,守护进程上传的数据格式为“CmdNumber Code Message”
2. NativeDaemonConnector的execute函数,向守护进程发命令。
不需要回复的命令直接写入socket即可
需要回复的命令:

makeCommand(rawBuilder, logBuilder, sequenceNumber, cmd, args);

自加一个sequenceNumber作为codeNumber拼接成命令,linsen socket的时候接收到消息后

    if (event.isClassUnsolicited()) {
    } else {
        //将回复消息加入回复队列
        mResponseQueue.add(event.getCmdNumber(), event);
    }  

execute延迟后读取mResponseQueue队列,根据之前设置的sequenceNumber

    do {
        //延迟读取sequenceNumber命令
        event = mResponseQueue.remove(sequenceNumber, timeout, logCmd);
        if (event == null) {
        loge("timed-out waiting for response to " + logCmd);
        throw new NativeDaemonFailureException(logCmd, event);
    }
    events.add(event);
    //代表接收到的event是否只是其中一段
    } while (event.isClassContinue());  

关于event的codeNumber类型:

/**
 * Test if event represents a partial response which is continued in
 * additional subsequent events.
 */
mCode >= 100 && mCode < 200;

/**
 * Test if event represents a command success.
 */
mCode >= 200 && mCode < 300;

/**
 * Test if event represents a remote native daemon error.
 */
pmCode >= 400 && mCode < 500;

/**
 * Test if event represents a command syntax or argument error.
 */
 mCode >= 500 && mCode < 600;

/**
 * Test if event represents an unsolicited event from native daemon.
 */
code >= 600 && code < 700;
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值