博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Framework层Ril控制流程分析
阅读量:4985 次
发布时间:2019-06-12

本文共 7264 字,大约阅读时间需要 24 分钟。

     Framework层Ril控制流程分析

RIL Native层分析:

一 RIL整体框架

看一下整个RIL部分框架图:

    

  实际上Framework部分比较复杂的,包含了很多类;但其核心的两个类是GSMPhone/,RIL.Java.

还包括围绕这两个类构成的状态管理,命令交互的类。

二 PhoneApp 启动过程

在AndroidManifest.xml文件中:

  <application android:name="PhoneApp"

     android:persistent="true"

     …… 

         在开机启动时到ActivityManagerService的systemReady时,会将带有这个属性的App启动。

调用应用的Application——PhoneApp

public class PhoneApp extends Application{    @Override    public void onCreate() {         //初始化framework层telephony相关         PhoneFactory.makeDefaultPhones(this);     Phone phone = PhoneFactory.getDefaultPhone();                  CallManager mCM = CallManager.getInstance();         mCM.registerPhone(phone);    }}

PhoneFactory初始化Framework层相关对象:  

public static void makeDefaultPhone(Context context) {    sPhoneNotifier = new DefaultPhoneNotifier();        //创建CommandsInterface实例RIL    sCommandsInterface = new RIL(context, networkMode, cdmaSubscription);        // Instantiate UiccController so that all other classes can just call getInstance()    UiccController.make(context, sCommandsInterface);        //根据类型创建Phone实例    int phoneType = getPhoneType(networkMode);    //创建Phone实例GSMPhone 以及代理对象ProxyPhone    sProxyPhone = new PhoneProxy(new GSMPhone(context,                        sCommandsInterface, sPhoneNotifier));}

  这个sCommandsInterface很关键 是连接GSMPhone与RIL。

  整个Framewrok Telephony中很关键的就是Phone和CommandInterface两个接口:

核心就是围绕这两个接口派生的类;还有各种对Phone进行了包装的类。

  Phone:Internal interface used to control the phone;

  CommandInterface:提供跟native层Ril交互的接口发送命令和接受命令,注册状态传递回调接口,向上层传递状态变化。

下面是这几个核心类的结构图:

    

三 命令控制流程

         命令从Phone开始,在传递到RIL,在通过Socket传递给Rild。下面看一下framework中RIL类工作流程。

与Native端交互过程:

    

  RIL提供了call和connection过程命令接口,状态变化回调,unsolicited事件通知。

类结构图:

    

 

  其中关键的两个线程:sender和receiver ,运行单独的线程中处理向下和向上的请求。

RIL构造函数:

public RIL(Context context, ……) {        //创建sender运行线程     mSenderThread = new HandlerThread("RILSender");    mSenderThread.start();    //send消息处理循环    Looper looper = mSenderThread.getLooper();    mSender = new RILSender(looper);        //建立receiver运行的线程    mReceiver = new RILReceiver();    mReceiverThread = new Thread(mReceiver, "RILReceiver");    mReceiverThread.start();}

1 send事件流程

dial拨号流程:

 

public void dial(String address, int clirMode,                 UUSInfo uusInfo, Message result) {                                        //获取一个RILRequest对象 请求对象类型    RILRequest rr = RILRequest.obtain(RIL_REQUEST_DIAL, result);    //将数据打包成parcel    rr.mp.writeString(address);    rr.mp.writeInt(clirMode);    rr.mp.writeInt(0); // UUS information is absent    ……    //将数据发送到send线程中处理 内部公共接口send    send(rr);}    private void send(RILRequest rr) {    //Handler异步处理消息    msg = mSender.obtainMessage(EVENT_SEND, rr);    msg.sendToTarget();} 

Send消息处理过程:

class RILSender extends Handler implements Runnable {  public RILSender(Looper looper) {      super(looper); }  // Only allocated once  byte[] dataLength = new byte[4];  public void run() {      //setup if needed  }  handleMessage(Message msg) {      RILRequest rr = (RILRequest)(msg.obj);      RILRequest req = null;      switch (msg.what) {        case EVENT_SEND:          //与rild通信socket          LocalSocket s;          s = mSocket;          //加入请求队列          synchronized (mRequestsList) {              mRequestsList.add(rr);              mRequestMessagesWaiting++;          }          byte[] data;          data = rr.mp.marshall();          //将将数据通过socket传入到rild进程中          s.getOutputStream().write(dataLength);          s.getOutputStream().write(data);            break;    }  }}

         在send线程中将数据通过socket传递给rild进程处理。

2 receive事件流程

Receiver接收rild发送来的事件以及send事件的response事件:

 

class RILReceiver implements Runnable {  byte[] buffer;  RILReceiver() {      buffer = new byte[RIL_MAX_COMMAND_BYTES];  }    public void run() {        String rilSocket = "rild";        //循环处理rild传递来的事件        for (;;) {            //创建于rild通信的socket 建立连接            s = new LocalSocket();            l = new LocalSocketAddress(rilSocket,                            LocalSocketAddress.Namespace.RESERVED);            s.connect(l);              mSocket = s;              //读取socket数据            InputStream is = mSocket.getInputStream();                  for (;;) {              //解析数据              Parcel p;              length = readRilMessage(is, buffer);              p = Parcel.obtain();              p.unmarshall(buffer, 0, length);              p.setDataPosition(0);                            //处理rild传递来的消息              processResponse(p);          }                  setRadioState (RadioState.RADIO_UNAVAILABLE);          mSocket.close();          // Clear request list on close          clearRequestsList(RADIO_NOT_AVAILABLE, false);      }    }}    private void processResponse (Parcel p) {  type = p.readInt();    //新事件Or send事件response  if (type == RESPONSE_UNSOLICITED) {      processUnsolicited (p);  } else if (type == RESPONSE_SOLICITED) {      processSolicited (p);  }}

网络端事件处理流程:

 

private void processUnsolicited (Parcel p) {    Object ret;    int response = p.readInt();    switch(response) {        //来电        case RIL_UNSOL_CALL_RING:             ret =  responseCallRing(p); break;        ……    }        switch(response) {        case RIL_UNSOL_CALL_RING:            //通知注册来电事件的register            if (mRingRegistrant != null) {                mRingRegistrant.notifyRegistrant(                    new AsyncResult (null, ret, null));            }            break;        ……    }} 

3 receiver事件通知register机制

对事件状态的注册是在RIL的父类BaseCommands完成的。

BaseCommands类注册事件的实现:

 

public abstract class BaseCommands implements CommandsInterface {    //注册到列表中    protected RegistrantList mRadioStateChangedRegistrants = new RegistrantList();    protected RegistrantList mCallStateRegistrants = new RegistrantList();    protected RegistrantList mDataNetworkStateRegistrants = new RegistrantList();    ……        //注册某一事件发生    protected Registrant mRingRegistrant;    protected Registrant mSmsStatusRegistrant;    protected Registrant mRestrictedStateRegistrant;    ……        //注册接口    public void registerForRadioStateChanged(Handler h, int what, Object obj) {        Registrant r = new Registrant (h, what, obj);                synchronized (mStateMonitor) {            mRadioStateChangedRegistrants.add(r);            r.notifyRegistrant();        }    }    //注册回调    public void setOnCallRing(Handler h, int what, Object obj) {        mRingRegistrant = new Registrant (h, what, obj);    }} 

这里有RegistrantList与Registrant类,注册事件以Registrant对象存储;

下面是Registrant类得主要成员:

 

public class Registrant{    WeakReference   refH;    int             what;    Object          userObj;    public Registrant(Handler h, int what, Object obj){        refH = new WeakReference(h);        this.what = what;        userObj = obj;    }        public void notifyRegistrant(){        internalNotifyRegistrant (null, null);    }        void internalNotifyRegistrant (Object result, Throwable exception){      //通过Handler传递消息    Handler h = getHandler();    Message msg = Message.obtain();    msg.what = what;    msg.obj = new AsyncResult(userObj, result, exception);    h.sendMessage(msg);    }} 

  这里说直接使用Handler,来实现了一个Observer模式,但是Handler是处理线程的框架类,实现异步的处理消息,具有更强的功能。

所以看到Telephony中很多类都是从Handler继承下来的,就是为了监听事件发生,状态变化等消息。

转载于:https://www.cnblogs.com/bastard/archive/2012/11/22/2783229.html

你可能感兴趣的文章
线性判别函数-Fisher 线性判别
查看>>
面试小题
查看>>
My latest news
查看>>
VisualStudio 2015 开启IIS Express可以调试X64项目
查看>>
关于block 用法
查看>>
layui学习
查看>>
zepto源码--整体框架--学习笔记
查看>>
ZeroMQ研究与应用分析
查看>>
纯windows下制作变色龙引导安装U盘教程
查看>>
输出一个数组里最大子数组的和(文件)
查看>>
复杂sql书写方法
查看>>
路由器安置(Routing)
查看>>
4.24—010—周三
查看>>
误移动根目录导致系统异常的解决办法
查看>>
n层满k叉树总共有多少个节点
查看>>
对于JSONObject,我只是临时抱佛脚
查看>>
springboot与dubbo整合入门(三种方式)
查看>>
KVC KVO KVB
查看>>
vue element传的值报_self.$scopedSlots.default is not a function
查看>>
CodeForces - 405C
查看>>