@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); }
从他所提供的接口来看,其提供了Telephony比较全面的功能,包括:通话、Pin/Puk、Radio状态、数据连接业务等功能的查询或控制。
phoneMgr = PhoneInterfaceManager.init(this, phone, callHandlerServiceProxy);我们来看具体的创建过程:
@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; } }继续看构造方法:
private 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(); }在构造方法中除了将PhoneGlobals中初始化的Phone、CallManager等信息传递给PhoneInterfaceManager外,还将PhoneInterfaceManager通过publish()注册给ServiceManager:
private void publish() { //注册给ServiceManager,名字是“phone” ServiceManager.addService("phone", this); }
这里看到,PhoneInterfaceManager将自己注册为SystemServer,其他模块可以通过ServiceManager来获取他的服务。
客户端通过ServiceManager获取到PhoneInterfaceManager的代理对象后,就可以对其发起各种请求,我们挑选几个比较重要的事务来简要分析。
public 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); } }
这里可以看到,PhoneInterfaceManager会通过Intent的形式发起拨号的任务。
public 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; } } }
在这里,PhoneInterfaceManager又将请求传给了PhoneUtils来处理结束通话的操作。
public boolean supplyPin(String pin) { //权限检查 enforceModifyPermission(); //通过IccCard来操作 final UnlockSim checkSimPin = new UnlockSim(mPhone.getIccCard()); //启用查询线程 checkSimPin.start(); return checkSimPin.unlockSim(null, pin); }看以下线程内部的操作:
synchronized 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; }
可以看到,最终是通过IccCard来实现Pin、Puk的查询。
public boolean disableDataConnectivity() { enforceModifyPermission(); //通过ConnectivityManager来禁用数据连接 ConnectivityManager cm = (ConnectivityManager)mApp.getSystemService(Context.CONNECTIVITY_SERVICE); cm.setMobileDataEnabled(false); return true; }
这里又通过ConnectivityManager来禁用数据连接业务。
如图所示: