首页 > 学院 > 开发设计 > 正文

Telephony之PhoneInterfaceManager

2019-11-07 23:52:20
字体:
来源:转载
供稿:网友

一、概述

        PhoneInterfaceManager是一个Service,在被创建时通过ServiceManager注册自己,他作为Telephony对外的接口,可以接受其他进程向Telephony的请求,我们通过该Service所继承的AIDL文件就能看到他所提供的具体功能:[java] view plain copy 在CODE上查看代码片@ITelephony.aidl  interface ITelephony {      //发起通话      void dial(String number);      void call(String callingPackage, String number);      boolean showCallScreen();      boolean showCallScreenWithDialpad(boolean showDialpad);      //挂断通话      boolean endCall();      //接听通话      void answerRingingCall();      void silenceRinger();      //通话状态判断      boolean isOffhook();      boolean isRinging();      boolean isIdle();      boolean isRadioOn();      boolean isSimPinEnabled();      void cancelMissedCallsNotification();      //Pin/Puk码查询      boolean supplyPin(String pin);      int getIccPin1RetryCount();      boolean supplyPuk(String puk, String pin);      int[] supplyPinReportResult(String pin);      int[] supplyPukReportResult(String puk, String pin);      boolean handlePinMmi(String dialString);      void toggleRadioOnOff();      boolean setRadio(boolean turnOn);      boolean setRadioPower(boolean turnOn);      void updateServiceLocation();      void enableLocationUpdates();      void disableLocationUpdates();      //数据连接业务      int enableApnType(String type);      int disableApnType(String type);      boolean enableDataConnectivity();      boolean disableDataConnectivity();      boolean isDataConnectivityPossible();      Bundle getCellLocation();      List<NeighboringCellInfo> getNeighboringCellInfo(String callingPkg);      //通话状态获取      int getCallState();      int getDataActivity();      int getDataState();      int getActivePhoneType();      int getCdmaEriIconIndex();      int getCdmaEriIconMode();      String getCdmaEriText();      boolean needsOtaServicePRovisioning();      int getVoiceMessageCount();      //网络、数据类型      int getNetworkType();      int getDataNetworkType();      int getVoiceNetworkType();      boolean hasIccCard();      int getLteOnCdmaMode();      List<CellInfo> getAllCellInfo();      void setCellInfoListRate(int rateInMillis);      String transmitIccLogicalChannel(int cla, int command, int channel, int p1, int p2, int p3, String data);      String transmitIccBasicChannel(int cla, int command, int p1, int p2, int p3, String data);      int openIccLogicalChannel(String AID);      boolean closeIccLogicalChannel(int channel);      int getLastError();      byte[] transmitIccSimIO(int fileID, int command, int p1, int p2, int p3, String filePath);      byte[] getATR();      //通话中合并、切换、静音、Dtmf处理      void toggleHold();      void merge();      void swap();      void mute(boolean mute);      void playDtmfTone(char digit, boolean timedShortCode);      void stopDtmfTone();      //添加、删除监听器      void addListener(ITelephonyListener listener);      void removeListener(ITelephonyListener listener);  }  

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

二、PhoneInterfaceManager的创建及注册过程

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

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

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

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

3.1、拨号

 %20 %20 %20 %20当通过PhoneInterfaceManager拨号时,会进入以下流程:[java]%20view%20plain%20copy%20public void dial(String number) {      String url = createTelUrl(number);      if (url == null) {          return;      }      PhoneConstants.State state = mCM.getState();      if (state != PhoneConstants.State.OFFHOOK && state != PhoneConstants.State.RINGING) {          //发送Intent实现拨号          Intent  intent = new Intent(Intent.ACTION_DIAL, Uri.parse(url));          intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);          mApp.startActivity(intent);      }  }  

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

3.2、挂断电话

 %20 %20 %20 %20现在来看挂断电话的操作:[java]%20view%20plain%20copy%20public boolean endCall() {      //权限检查      enforceCallPermission();      //发送CMD_END_CALL的Message      return (Boolean) sendRequest(CMD_END_CALL, null);  }  private final class MainThreadHandler extends Handler {      @Override      public void handleMessage(Message msg) {          switch (msg.what) {              case CMD_END_CALL:                  request = (MainThreadRequest) msg.obj;                  boolean hungUp = false;                  int phoneType = mPhone.getPhoneType();                  if (phoneType == PhoneConstants.PHONE_TYPE_CDMA) {                      //通过PhoneUtils挂断电话                      hungUp = PhoneUtils.hangupRingingAndActive(mPhone);                  } else if (phoneType == PhoneConstants.PHONE_TYPE_GSM) {                      //通过PhoneUtils挂断电话                      hungUp = PhoneUtils.hangup(mCM);                  } else {                      throw new IllegalStateException("Unexpected phone type: " + phoneType);                  }                  request.result = hungUp;                  synchronized (request) {                      request.notifyAll();                  }                  break;              default:                  break;          }      }  }  

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

3.3、查询Pin码

 %20 %20 %20 %20下面看Pin码的操作:[java]%20view%20plain%20copy%20public boolean supplyPin(String pin) {      //权限检查      enforceModifyPermission();      //通过IccCard来操作      final UnlockSim checkSimPin = new UnlockSim(mPhone.getIccCard());      //启用查询线程      checkSimPin.start();      return checkSimPin.unlockSim(null, pin);  }   %20 %20 %20 %20看以下线程内部的操作:[java]%20view%20plain%20copy%20synchronized boolean unlockSim(String puk, String pin) {      Message callback = Message.obtain(mHandler, SUPPLY_PIN_COMPLETE);      //通过IccCard来查询Pin、Puk      if (puk == null) {          mSimCard.supplyPin(pin, callback);      } else {          mSimCard.supplyPuk(puk, pin, callback);      }      return mResult;  }  

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

3.4、数据连接业务

 %20 %20 %20 %20数据连接的开启:[java]%20view%20plain%20copy%20public boolean disableDataConnectivity() {      enforceModifyPermission();      //通过ConnectivityManager来禁用数据连接      ConnectivityManager cm = (ConnectivityManager)mApp.getSystemService(Context.CONNECTIVITY_SERVICE);      cm.setMobileDataEnabled(false);      return true;  }  

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

3.5、小结

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

 %20 %20 %20 %20如图所示:

 %20 %20 %20  


发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表