Telephony之PhoneInterfaceManager

一、概述


        PhoneInterfaceManager是一个Service,在被创建时通过ServiceManager注册自己,他作为Telephony对外的接口,可以接受其他进程向Telephony的请求,我们通过该Service所继承的AIDL文件就能看到他所提供的具体功能:
  1. @ITelephony.aidl  
  2. interface ITelephony {  
  3.     //发起通话  
  4.     void dial(String number);  
  5.     void call(String callingPackage, String number);  
  6.     boolean showCallScreen();  
  7.     boolean showCallScreenWithDialpad(boolean showDialpad);  
  8.     //挂断通话  
  9.     boolean endCall();  
  10.     //接听通话  
  11.     void answerRingingCall();  
  12.     void silenceRinger();  
  13.     //通话状态判断  
  14.     boolean isOffhook();  
  15.     boolean isRinging();  
  16.     boolean isIdle();  
  17.     boolean isRadioOn();  
  18.     boolean isSimPinEnabled();  
  19.     void cancelMissedCallsNotification();  
  20.     //Pin/Puk码查询  
  21.     boolean supplyPin(String pin);  
  22.     int getIccPin1RetryCount();  
  23.     boolean supplyPuk(String puk, String pin);  
  24.     int[] supplyPinReportResult(String pin);  
  25.     int[] supplyPukReportResult(String puk, String pin);  
  26.     boolean handlePinMmi(String dialString);  
  27.     void toggleRadioOnOff();  
  28.     boolean setRadio(boolean turnOn);  
  29.     boolean setRadioPower(boolean turnOn);  
  30.     void updateServiceLocation();  
  31.     void enableLocationUpdates();  
  32.     void disableLocationUpdates();  
  33.     //数据连接业务  
  34.     int enableApnType(String type);  
  35.     int disableApnType(String type);  
  36.     boolean enableDataConnectivity();  
  37.     boolean disableDataConnectivity();  
  38.     boolean isDataConnectivityPossible();  
  39.     Bundle getCellLocation();  
  40.     List<NeighboringCellInfo> getNeighboringCellInfo(String callingPkg);  
  41.     //通话状态获取  
  42.     int getCallState();  
  43.     int getDataActivity();  
  44.     int getDataState();  
  45.     int getActivePhoneType();  
  46.     int getCdmaEriIconIndex();  
  47.     int getCdmaEriIconMode();  
  48.     String getCdmaEriText();  
  49.     boolean needsOtaServiceProvisioning();  
  50.     int getVoiceMessageCount();  
  51.     //网络、数据类型  
  52.     int getNetworkType();  
  53.     int getDataNetworkType();  
  54.     int getVoiceNetworkType();  
  55.     boolean hasIccCard();  
  56.     int getLteOnCdmaMode();  
  57.     List<CellInfo> getAllCellInfo();  
  58.     void setCellInfoListRate(int rateInMillis);  
  59.     String transmitIccLogicalChannel(int cla, int command, int channel, int p1, int p2, int p3, String data);  
  60.     String transmitIccBasicChannel(int cla, int command, int p1, int p2, int p3, String data);  
  61.     int openIccLogicalChannel(String AID);  
  62.     boolean closeIccLogicalChannel(int channel);  
  63.     int getLastError();  
  64.     byte[] transmitIccSimIO(int fileID, int command, int p1, int p2, int p3, String filePath);  
  65.     byte[] getATR();  
  66.     //通话中合并、切换、静音、Dtmf处理  
  67.     void toggleHold();  
  68.     void merge();  
  69.     void swap();  
  70.     void mute(boolean mute);  
  71.     void playDtmfTone(char digit, boolean timedShortCode);  
  72.     void stopDtmfTone();  
  73.     //添加、删除监听器  
  74.     void addListener(ITelephonyListener listener);  
  75.     void removeListener(ITelephonyListener listener);  
  76. }  

        从他所提供的接口来看,其提供了Telephony比较全面的功能,包括:通话、Pin/Puk、Radio状态、数据连接业务等功能的查询或控制


二、PhoneInterfaceManager的创建及注册过程


        PhoneInterfaceManager是在PhoneGlobals的onCreate()中被创建的:
  1. phoneMgr = PhoneInterfaceManager.init(this, phone, callHandlerServiceProxy);  
        我们来看具体的创建过程:
  1. @PhoneInterfaceManager.java  
  2. static PhoneInterfaceManager init(PhoneGlobals app, Phone phone, CallHandlerServiceProxy callHandlerService) {  
  3.     synchronized (PhoneInterfaceManager.class) {  
  4.         if (sInstance == null) {  
  5.             //创建对象  
  6.             sInstance = new PhoneInterfaceManager(app, phone, callHandlerService);  
  7.         } else {  
  8.             Log.wtf(LOG_TAG, "init() called multiple times!  sInstance = " + sInstance);  
  9.         }  
  10.         return sInstance;  
  11.     }  
  12. }  
        继续看构造方法:
  1. private PhoneInterfaceManager(PhoneGlobals app, Phone phone, CallHandlerServiceProxy callHandlerService) {  
  2.     mApp = app;  
  3.     mPhone = phone;  
  4.     mCM = PhoneGlobals.getInstance().mCM;  
  5.     mAppOps = (AppOpsManager)app.getSystemService(Context.APP_OPS_SERVICE);  
  6.     mMainThreadHandler = new MainThreadHandler();  
  7.     mCallHandlerService = callHandlerService;  
  8.     publish();  
  9. }  
        在构造方法中除了将PhoneGlobals中初始化的Phone、CallManager等信息传递给PhoneInterfaceManager外,还将PhoneInterfaceManager通过publish()注册给ServiceManager:
  1. private void publish() {  
  2.     //注册给ServiceManager,名字是“phone”  
  3.     ServiceManager.addService("phone"this);  
  4. }  

        这里看到,PhoneInterfaceManager将自己注册为SystemServer,其他模块可以通过ServiceManager来获取他的服务


三、PhoneInterfaceManager对客户端请求的处理


        客户端通过ServiceManager获取到PhoneInterfaceManager的代理对象后,就可以对其发起各种请求,我们挑选几个比较重要的事务来简要分析。


3.1、拨号


        当通过PhoneInterfaceManager拨号时,会进入以下流程:
  1. public void dial(String number) {  
  2.     String url = createTelUrl(number);  
  3.     if (url == null) {  
  4.         return;  
  5.     }  
  6.     PhoneConstants.State state = mCM.getState();  
  7.     if (state != PhoneConstants.State.OFFHOOK && state != PhoneConstants.State.RINGING) {  
  8.         //发送Intent实现拨号  
  9.         Intent  intent = new Intent(Intent.ACTION_DIAL, Uri.parse(url));  
  10.         intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);  
  11.         mApp.startActivity(intent);  
  12.     }  
  13. }  

        这里可以看到,PhoneInterfaceManager会通过Intent的形式发起拨号的任务


3.2、挂断电话


        现在来看挂断电话的操作:
  1. public boolean endCall() {  
  2.     //权限检查  
  3.     enforceCallPermission();  
  4.     //发送CMD_END_CALL的Message  
  5.     return (Boolean) sendRequest(CMD_END_CALL, null);  
  6. }  
  7. private final class MainThreadHandler extends Handler {  
  8.     @Override  
  9.     public void handleMessage(Message msg) {  
  10.         switch (msg.what) {  
  11.             case CMD_END_CALL:  
  12.                 request = (MainThreadRequest) msg.obj;  
  13.                 boolean hungUp = false;  
  14.                 int phoneType = mPhone.getPhoneType();  
  15.                 if (phoneType == PhoneConstants.PHONE_TYPE_CDMA) {  
  16.                     //通过PhoneUtils挂断电话  
  17.                     hungUp = PhoneUtils.hangupRingingAndActive(mPhone);  
  18.                 } else if (phoneType == PhoneConstants.PHONE_TYPE_GSM) {  
  19.                     //通过PhoneUtils挂断电话  
  20.                     hungUp = PhoneUtils.hangup(mCM);  
  21.                 } else {  
  22.                     throw new IllegalStateException("Unexpected phone type: " + phoneType);  
  23.                 }  
  24.                 request.result = hungUp;  
  25.                 synchronized (request) {  
  26.                     request.notifyAll();  
  27.                 }  
  28.                 break;  
  29.             default:  
  30.                 break;  
  31.         }  
  32.     }  
  33. }  

        在这里,PhoneInterfaceManager又将请求传给了PhoneUtils来处理结束通话的操作


3.3、查询Pin码


        下面看Pin码的操作:
  1. public boolean supplyPin(String pin) {  
  2.     //权限检查  
  3.     enforceModifyPermission();  
  4.     //通过IccCard来操作  
  5.     final UnlockSim checkSimPin = new UnlockSim(mPhone.getIccCard());  
  6.     //启用查询线程  
  7.     checkSimPin.start();  
  8.     return checkSimPin.unlockSim(null, pin);  
  9. }  
        看以下线程内部的操作:
  1. synchronized boolean unlockSim(String puk, String pin) {  
  2.     Message callback = Message.obtain(mHandler, SUPPLY_PIN_COMPLETE);  
  3.     //通过IccCard来查询Pin、Puk  
  4.     if (puk == null) {  
  5.         mSimCard.supplyPin(pin, callback);  
  6.     } else {  
  7.         mSimCard.supplyPuk(puk, pin, callback);  
  8.     }  
  9.     return mResult;  
  10. }  

        可以看到,最终是通过IccCard来实现Pin、Puk的查询


3.4、数据连接业务


        数据连接的开启:
  1. public boolean disableDataConnectivity() {  
  2.     enforceModifyPermission();  
  3.     //通过ConnectivityManager来禁用数据连接  
  4.     ConnectivityManager cm = (ConnectivityManager)mApp.getSystemService(Context.CONNECTIVITY_SERVICE);  
  5.     cm.setMobileDataEnabled(false);  
  6.     return true;  
  7. }  

        这里又通过ConnectivityManager来禁用数据连接业务


3.5、小结


        经过以上几个请求的解析,我们发现,PhoneInterfaceManager自身并没有完成请求的功能,而是把客户端的请求分配给相应领域的管理者,也可以这样理解,PhoneInterfaceManager作为Telephony框架对外的“接口人”,接收客户的请求后,将请求发送给真正的“主人”去实现。

        如图所示:

        

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值