Framework中的TelephonyRegistry

来源:互联网 发布:php培训机构哪家好 编辑:程序博客网 时间:2024/06/09 18:37

一、基础知识

(1)ITelephonyRegistry.aidl:frameworks/base/telephony/java/com/android/internal/telephony (接口)

(2)TelephonyRegistry.java: frameworks\base\services\core\java\com\android\server  (服务器端,继承ITelephonyRegistry.stub)

(3)ServiceManager.java:  frameworks\base\core\java\android\os         (系统服务)

(4)TelephonyManager.java:  frameworks\base\telephony\java\android\telephony  (封装服务,供上层使用)


(1)TelephonyRegistry.java是一个系统服务,因此需要通过方法ServiceManager.java中的方法addService加入到系统服务中。

         服务器端TelephonyRegistry.java向系统注册过程,在开机时通过SystemServer添加到ServiceManager中,如下:

         telephonyRegistry = new TelephonyRegistry(context);       ServiceManager.addService("telephony.registry", telephonyRegistry);

(2)获取服务方法:sRegistry = ITelephonyRegistry.Stub.asInterface(ServiceManager.getService( "telephony.registry"));

二、功能介绍

关于TelephonyRegistry功能,如下:

(1)客户端向服务器端注册,TelephonyRegistry监听phone状态,当phone状态发生改变时,通知注册的客户端。

        监听的功能如下(还有好多):

         notifyCallState:监听通话状态的改变

        notifyServiceStateForPhoneId:监听网络状态的改变

        notifyCallForwardingChanged :监听呼叫转移状态的改变

        notifyDataActivity:监听数据连接状态的改变

(2)监听phone状态的改变,当发生改变时,发送系统广播

         broadcastCallStateChanged 

         broadcastDataConnectionStateChanged        

         broadcastSignalStrengthChanged

三、客户端向服务器端注册的过程

       服务器端通过维护一服务mRecords的列表,当客户端加入到这个列表中,当phone状态发生改变时,就会遍历这个列表中的客户端,去调用他们当初注册的回调函数首先分析一下这列表的数据结构:

private static class Record {        String callingPackage;           调试用        IBinder binder;                  回调函数的binder对象
        IPhoneStateListener callback;    回调函数        int callerUserId;                客户端的uid,用于检查权限         int events;                      客户注册的是哪个监听器
       }
    (1)客户端注册服务器端,需要提供 IPhoneStateListener对象;
    (2)客户端注册服务器端,需要提供监听哪些事件;
    (3)并不是所有的监听者都有权限获取服务,这个由callerUserId决定。
IPhoneStateListener数据结构:定义了监听器的回调函数
    void onServiceStateChanged(in ServiceState serviceState);    void onSignalStrengthChanged(int asu);    void onCallForwardingIndicatorChanged(boolean cfi);    void onCallStateChanged(int state, String incomingNumber);    void onDataConnectionStateChanged(int state, int networkType);    void onOtaspChanged(in int otaspMode);    void onVoLteServiceStateChanged(in VoLteServiceState lteState);
PhoneStateListener.java :客户端可以监听哪些消息
  1. LISTEN_SIGNAL_STRENGTH  
  2. LISTEN_MESSAGE_WAITING_INDICATOR  
  3. LISTEN_CALL_FORWARDING_INDICATOR  
  4. LISTEN_CELL_LOCATION  
  5. LISTEN_CALL_STATE  
  6. LISTEN_DATA_CONNECTION_STATE  
  7. LISTEN_DATA_ACTIVITY  
  8. LISTEN_SIGNAL_STRENGTHS  
  9. LISTEN_OTASP_CHANGED  
  10. LISTEN_CELL_INFO 
即客户端可以指定监听的事件,同时指定监听的回调函数,当事件发生时,TelephonyRegistry.java会回调客户端的回调函数。因此下面要分析一下客户端监听的过程。
四、客户端注册服务器端流程

上篇文章介绍了TelephonyManager和ITelehony.aidl调用关系的实现,即上层可以通过TelephonyManager.java实现系统服务。这个和TelephonyRegistry是一样的,其他客户端对TelephonyRegistry的注册,可以通过TelephonyManager实现,获得系统服务如下:

   public TelephonyManager(Context context, int subId) {        if (sRegistry == null) {            sRegistry = ITelephonyRegistry.Stub.asInterface(ServiceManager.getService( "telephony.registry"));        }    }

客户端通过TelephonyManager.java的listen方法实现对服务器端的records的注册。

public void listen(PhoneStateListener listener, int events) {            sRegistry.listenForSubscriber(listener.mSubId, getOpPackageName(),listener.callback, events, notifyNow); }
换句话说,如果客户端向注册到服务器端,首先要获取TelephonyManager服务,其次调用TelephonyManager的listen方法,首先客户端对服务器端的注册。注册成功后,当phone状态发生改变时,再有TelephonyRegistry通知给客户端。
 接下来我们继续看在TelephonyManager中调用listen的结果:

  1. @TelephonyRegistry  
  2. public void listen(String pkgForDebug, IPhoneStateListener callback, int events, boolean notifyNow) {  
  3.     int callerUid = UserHandle.getCallingUserId();  
  4.     //得到客户端的UID  
  5.     int myUid = UserHandle.myUserId();  
  6.     //检测调用者是否有权限进行监听  
  7.     checkListenerPermission(events);  
  8.     IBinder b = callback.asBinder();  
  9.     //先去查找当前的申请者是否已经注册了监听  
  10.     final int N = mRecords.size();  
  11.     for (int i = 0; i < N; i++) {  
  12.         r = mRecords.get(i);  
  13.         if (b == r.binder) {  
  14.             break find_and_add;  
  15.         }  
  16.     }  
  17.     //构建一个Record对象  
  18.     r = new Record();  
  19.     r.binder = b;  
  20.     r.callback = callback;  
  21.     r.pkgForDebug = pkgForDebug;  
  22.     r.callerUid = callerUid;  
  23.     //把当前客户端信息写入mRecords列表中  
  24.     mRecords.add(r);  
  25.     //需要立刻发送通知  
  26.     if (notifyNow) {  
  27.         if ((events & PhoneStateListener.LISTEN_SERVICE_STATE) != 0) {  
  28.             r.callback.onServiceStateChanged(new ServiceState(mServiceState));  
  29.         }  
  30.         ........  
  31.     }  
  32. }  
 上面的代码说明在listen中主要完成3个任务:
        1、检查客户端是否有权限监听;

        2、构建客户端的Record并添加到mRecords列表中

       3、判断是否需要立刻发送通知

五、服务端通知客户端过程

服务器端TelephonyRegistry对客户端的通知消息,是由其他客户端获取的,

(1)首先,在DefaultPhoneNotifier.java的构造方法中,获取了TelephonyRegistry.java的服务。

(2)其次,DefaultPhoneNotifier.java中,又注册了RIL,当modem主动上报消息,会将消息上报给DefaultPhoneNotifier.java,DefaultPhoneNotifier收到消息后,会根据不同的消息

调用TelephonyRegistry.java相应的方法,最终将RIL层反馈的消息派发给各个客户端。

(3)

也就是说,TelephonyRegistry充当了中介的角色,由其中某个客户端通过TelephonyRegistry去向其他所有的客户端进行消息派发

现在以监听手机状态改变为例子:


 
原创粉丝点击