一、概述
- @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状态、数据连接业务等功能的查询或控制。
二、PhoneInterfaceManager的创建及注册过程
- 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();
- }
- private void publish() {
- //注册给ServiceManager,名字是“phone”
- ServiceManager.addService("phone", this);
- }
这里看到,PhoneInterfaceManager将自己注册为SystemServer,其他模块可以通过ServiceManager来获取他的服务。
三、PhoneInterfaceManager对客户端请求的处理
客户端通过ServiceManager获取到PhoneInterfaceManager的代理对象后,就可以对其发起各种请求,我们挑选几个比较重要的事务来简要分析。
3.1、拨号
- 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的形式发起拨号的任务。
3.2、挂断电话
- 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来处理结束通话的操作。
3.3、查询Pin码
- 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的查询。
3.4、数据连接业务
- public boolean disableDataConnectivity() {
- enforceModifyPermission();
- //通过ConnectivityManager来禁用数据连接
- ConnectivityManager cm = (ConnectivityManager)mApp.getSystemService(Context.CONNECTIVITY_SERVICE);
- cm.setMobileDataEnabled(false);
- return true;
- }
这里又通过ConnectivityManager来禁用数据连接业务。
3.5、小结
如图所示: