呼叫转移流程(二)

下面为RIL工作框图:

 

 

呼叫转移中对RIL层返回的response,具体流程图如下

 

1. GsmCdmaPhone

一般向RIL请求request的类中含有对应的handleMessage方法会对RIL返回的response做出回应


       case EVENT_GET_CALL_FORWARD_DONE:
                ar = (AsyncResult)msg.obj;
                if (ar.exception == null) {
                    handleCfuQueryResult((CallForwardInfo[])ar.result);
                }
                onComplete = (Message) ar.userObj;
                if (onComplete != null) {
                    AsyncResult.forMessage(onComplete, ar.result, ar.exception);
                    onComplete.sendToTarget();
                }
                break;

 

GsmCdmaPhone.handleMessage中如果消息为EVENT_GET_CALL_FORWARD_DONE则表示返回得到返回的消息,得到了呼叫转移的状态,

如果onComplete不为空,则发送消息,发送到3.GsmUmtsCallForwardOptionhandler中,进行消息处理;

同时调用

GsmCdmaPhone.handleCfuqueryresult(CallForwardInfo[] infos)通知已经得到了呼叫转移的结果

 

2. SIMrecords

Phone.setVoiceCallForwardingFlag(int line, boolean enable)

 

RIccRecords的实例,但IccRecords中的setVoiceCallForwardingFlag函数具体实现是在子类SIMrecords中。

 

SIMrecordsIccrecords的子类,实际调用SIMRecords中的setVoiceCallForwardingFlag方法

 @Override
    public void setVoiceCallForwardingFlag(int line, boolean enable, String dialNumber) {

        if (line != 1) return; // only line 1 is supported

        mCallForwardingStatus = enable ? CALL_FORWARDING_STATUS_ENABLED :
                CALL_FORWARDING_STATUS_DISABLED;

        mRecordsEventsRegistrants.notifyResult(EVENT_CFI);

        try {
            if (validEfCfis(mEfCfis)) {
                // lsb is of byte f1 is voice status
                if (enable) {
                    mEfCfis[1] |= 1;
                } else {
                    mEfCfis[1] &= 0xfe;
                }

                log("setVoiceCallForwardingFlag: enable=" + enable
                        + " mEfCfis=" + IccUtils.bytesToHexString(mEfCfis));

                // Update dialNumber if not empty and CFU is enabled.
                // Spec reference for EF_CFIS contents, TS 51.011 section 10.3.46.
                if (enable && !TextUtils.isEmpty(dialNumber)) {
                    logv("EF_CFIS: updating cf number, " + Rlog.pii(LOG_TAG, dialNumber));
                    byte[] bcdNumber = PhoneNumberUtils.numberToCalledPartyBCD(dialNumber);

                    System.arraycopy(bcdNumber, 0, mEfCfis, CFIS_TON_NPI_OFFSET, bcdNumber.length);

                    mEfCfis[CFIS_BCD_NUMBER_LENGTH_OFFSET] = (byte) (bcdNumber.length);
                    mEfCfis[CFIS_ADN_CAPABILITY_ID_OFFSET] = (byte) 0xFF;
                    mEfCfis[CFIS_ADN_EXTENSION_ID_OFFSET] = (byte) 0xFF;
                }

                mFh.updateEFLinearFixed(
                        EF_CFIS, 1, mEfCfis, null,
                        obtainMessage (EVENT_UPDATE_DONE, EF_CFIS));
            } else {
                log("setVoiceCallForwardingFlag: ignoring enable=" + enable
                        + " invalid mEfCfis=" + IccUtils.bytesToHexString(mEfCfis));
            }

            if (mEfCff != null) {
                if (enable) {
                    mEfCff[0] = (byte) ((mEfCff[0] & CFF_LINE1_RESET)
                            | CFF_UNCONDITIONAL_ACTIVE);
                } else {
                    mEfCff[0] = (byte) ((mEfCff[0] & CFF_LINE1_RESET)
                            | CFF_UNCONDITIONAL_DEACTIVE);
                }

                mFh.updateEFTransparent(
                        EF_CFF_CPHS, mEfCff,
                        obtainMessage (EVENT_UPDATE_DONE, EF_CFF_CPHS));
            }
        } catch (ArrayIndexOutOfBoundsException ex) {
            logw("Error saving call forwarding flag to SIM. "
                            + "Probably malformed SIM record", ex);

        }
    }

 

3. RegistrantList消息机制

下面为消息的发送需要参考RegistrantList的消息处理机制

消息不断传递,最后在Registrant.java中的internalNotifyRegistrant方法中发送消息

代码中使用了RegistrantList,如何快速分析下一步流程走到哪里?

这是一个回调的过程,所以核心就是在哪里注册就在哪里处理,我们要找到调用register方法的地方。 我们看到在SIMRecords类中的

mRecordsEventRegistrants.notifyResult(EVENT_CFI);

先搜索mRecordsEventRegistrants,找到registerForRecordsEvent的方法;

 

 

再找到调用registerForRecordsEvent方法的地方,注册了事件EVENT_ICC_RECORD_EVENTS

 

最后搜索”EVENT_ICC_RECORD_EVENTS,找到handleMessage()方法对消息的处理,所以下一步代码流程就应该是走这里了。

4. GamCdmaPhone.hangdleMessage

GamCdmaPhonehangdleMessage中有对以下消息的处理语句,可以看到会调用processIccRecordEvents方法

           case EVENT_ICC_RECORD_EVENTS:
                ar = (AsyncResult)msg.obj;
                processIccRecordEvents((Integer)ar.result);
                break;

GsmCdmaPhone.javaprocessIccRecordEvents

    private void processIccRecordEvents(int eventCode) {
        switch (eventCode) {
            case IccRecords.EVENT_CFI:
                notifyCallForwardingIndicator();
                break;
        }
    }

 

 

5. DefaultPhoneNotifier

notifyCallForwardingChanged方法为PhoneNotify接口的函数,具体实现在DefaultPhoneNotifier.java类中


    @Override
    public void notifyCallForwardingChanged(Phone sender) {
        int subId = sender.getSubId();
        try {
            if (mRegistry != null) {
                mRegistry.notifyCallForwardingChangedForSubscriber(subId,
                        sender.getCallForwardingIndicator());
            }
        } catch (RemoteException ex) {
            // system process is dead
        }
    }

6. TelephonyRegistry

调用TelephonyRegistry.javanotifyCallForwardingChangedForSubscriber

    public void notifyCallForwardingChangedForSubscriber(int subId, boolean cfi) {
        if (!checkNotifyPermission("notifyCallForwardingChanged()")) {
            return;
        }
        if (VDBG) {
            log("notifyCallForwardingChangedForSubscriber: subId=" + subId
                + " cfi=" + cfi);
        }
        synchronized (mRecords) {
            int phoneId = SubscriptionManager.getPhoneId(subId);
            if (validatePhoneId(phoneId)) {
                mCallForwarding[phoneId] = cfi;
                for (Record r : mRecords) {
                    if (r.matchPhoneStateListenerEvent(
                            PhoneStateListener.LISTEN_CALL_FORWARDING_INDICATOR) &&
                            idMatch(r.subId, subId, phoneId)) {
                        try {
                            r.callback.onCallForwardingIndicatorChanged(cfi);
                        } catch (RemoteException ex) {
                            mRemoveList.add(r.binder);
                        }
                    }
                }
            }
            handleRemoveListLocked();
        }
    }

CallbackIPhoneStateListener,onCallForwardingIndicatorChanged函数实现要在phoneStateListener中

621        public void onCallForwardingIndicatorChanged(boolean cfi) {
622            send(LISTEN_CALL_FORWARDING_INDICATOR, cfi ? 1 : 0, 0, null);
623        }

send

     private void send(int what, int arg1, int arg2, Object obj) {
603            PhoneStateListener listener = mPhoneStateListenerWeakRef.get();
604            if (listener != null) {
605                Message.obtain(listener.mHandler, what, arg1, arg2, obj).sendToTarget();
606            }
607        }

 

Handle传递消息LISTEN_CALL_FORWARDING_INDICATOR,处理消息在

PhoneStateListener中。

317                    case LISTEN_CALL_FORWARDING_INDICATOR:
318                        PhoneStateListener.this.onCallForwardingIndicatorChanged(msg.arg1 != 0);
319                        break;

调用函数具体的实现代码,具体的实现过程要去看他的子类CallNotifierPhoneStateListener

7. CallNotifier

598        for (int i = 0; i < subInfos.size(); i++) {
599            int subId = subInfos.get(i).getSubscriptionId();
600            if (!mPhoneStateListeners.containsKey(subId)) {
601                CallNotifierPhoneStateListener listener = new CallNotifierPhoneStateListener(subId);
602                mTelephonyManager.listen(listener,
603                        PhoneStateListener.LISTEN_MESSAGE_WAITING_INDICATOR
604                        | PhoneStateListener.LISTEN_CALL_FORWARDING_INDICATOR);
605                mPhoneStateListeners.put(subId, listener);
606            }
607        }
608    }

CallNotifierPhoneStateListener继承自PhoneStateListener,重写oncallForwardingIndicatorChanged方法;会调用updataPhoneStateListeners函数updataPhoneStateListeners函数中注册到Phone进程中

 

8.NotificationMgr

并且会调用函数updataCfi,此方法是用来发送通知 ,设置呼叫转移成功

763        @Override
764        public void onCallForwardingIndicatorChanged(boolean visible) {
765            Log.i(LOG_TAG, "onCallForwardingIndicatorChanged(): subId=" + this.mSubId
766                    + ", visible=" + (visible ? "Y" : "N"));
767            mApplication.notificationMgr.updateCfi(this.mSubId, visible);
768        }
769    };

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值