必威体育Betway必威体育官网
当前位置:首页 > IT技术

呼叫转移流程分析(一)

时间:2019-10-11 18:14:32来源:IT技术作者:seo实验室小编阅读:81次「手机版」
 

呼叫转移设置

Android5.0之后的版本,手机的CallSetting设置一般在package/APPs/service/Telephony中

下面为呼叫转移流程图,包括应用层与RIL的request

 1.CallFeartureSettingActivity.java为通话设置入口

//在谷歌的源码中没有这个类,可以直接看2、CallFeatureSetting

在onResume方法中判断手机是单卡还是双卡

单卡直接通过CallFeatureSetting进入补充业务的设置界面,双卡先进入PhoneAccountSettingActivity的双卡选择界面,再通过PhoneAccountSettingFragmentNew选择某个sim卡,以intent进入CallFeatureSetting的activity

2.CallFeatureSetting设置补充业务

CallFeatureSetting中的onResume中调用init,

       if (carrierConfig.getBoolean(CarrierConfigManager.KEY_WORLD_PHONE_BOOL)) {
            cdmaOptions.setIntent(mSubscriptionInfoHelper.getIntent(CdmaCallOptions.class));
            gsmOptions.setIntent(mSubscriptionInfoHelper.getIntent(GsmUmtsCallOptions.class));
        } else {
            prefSet.removePreference(cdmaOptions);
            prefSet.removePreference(gsmOptions);

            int phoneType = mPhone.getPhoneType();
            if (carrierConfig.getBoolean(CarrierConfigManager.KEY_HIDE_CARRIER_NETWORK_settings_BOOL)) {
                prefSet.removePreference(fdnButton);
            } else {
                if (phoneType == Phoneconstants.PHONE_TYPE_CDMA) {
                    prefSet.removePreference(fdnButton);//固定拨号

                    if (!carrierConfig.getBoolean(
                            CarrierConfigManager.KEY_VOICE_PRIVACY_disable_UI_BOOL)) {
                        addPreferencesFromResource(R.xml.cdma_call_privacy);
                    }
                } else if (phoneType == PhoneConstants.PHONE_TYPE_GSM) {

                    if (carrierConfig.getBoolean(
                            CarrierConfigManager.KEY_ADDITIONAL_CALL_SETTING_BOOL)) {
                        addPreferencesFromResource(R.xml.gsm_umts_call_options);
                        GsmUmtsCallOptions.init(prefSet, mSubscriptionInfoHelper);
                    }
                } else {
                    throw new IllegalStateException("unexpected phone type: " + phoneType);
                }
            }

GsmUmtsCallOption.init(preferencescreen,SubscriptionIfoHelper)为补充业务的preference建立对应的intent

63    public static void init(PreferenceScreen prefScreen, SubscriptionInfoHelper subInfoHelper) {
64        Preference callForwardingPref = prefScreen.findPreference(CALL_FORWARDING_KEY);
65        callForwardingPref.setIntent(subInfoHelper.getIntent(GsmUmtsCallForwardOptions.class));
66
67        Preference additionalGsmSettingsPref =
68                prefScreen.findPreference(ADDITIONAL_GSM_SETTINGS_KEY);
69        additionalGsmSettingsPref.setIntent(
70                subInfoHelper.getIntent(GsmUmtsAdditionalCallOptions.class));

不同的补充业务会转入不同的activity,呼叫转移业务对应的activity为GsmUmtsCallForwardOption。

3. GsmUmtsCallForwardOption呼叫转移的activity

在onResume中进行界面初始化,调用init函数

    @Override
    public void onResume() {
        super.onResume();

        if (mFirstResume) {
            if (mIcicle == null) {
                if (DBG) Log.d(LOG_TAG, "start to init ");
                mPreferences.get(MinitIndex).init(this, false, mPhone);
            } else {
                mInitIndex = mPreferences.size();

                for (CallForwardEditPreference pref : mPreferences) {
                    Bundle bundle = mIcicle.getParcelable(pref.getKey());
                    pref.setToggled(bundle.getBoolean(KEY_TOGGLE));
                    CallForwardInfo cf = new CallForwardInfo();
                    cf.number = bundle.getString(KEY_NUMBER);
                    cf.status = bundle.getInt(KEY_STATUS);
                    pref.handleCallForwardResult(cf);
                    pref.init(this, true, mPhone);
                }
            }
            mFirstResume = false;
            mIcicle = null;
        }
    }

在初次进入时会进行四种呼叫转移的初始化,因为四个呼叫转移都是CallForwardEditPreference类,所以具体每个Preference的点击动作应该看CallForwardEditPreference类;CallForwardEditPreference通过Myhandle的消息处理handlemessage,分别为handleGetCFresponse(设置新CF)与handleSetCFResponse (读取CF状态)。

CallForwardEditPreference分为始终转接,占线时转接,无人接听时转接和无法接听时转接四种情况,也就是四个CallForwardEditPreference,其中init函数是获取当前呼叫转移设置的代码

    void init(TimeConsumingPreferenceListener listener, boolean skipReading, Phone phone) {
        mPhone = phone;
        mTcpListener = listener;

        if (!skipReading) {
            mPhone.getCallForwardingOption(reason,
                    mhandler.obtainMessage(MyHandler.MESSAGE_GET_CF,
                            // unused in this case
                            commandsInterface.CF_ACTION_DISABLE,
                            MyHandler.MESSAGE_GET_CF, null));
            if (mTcpListener != null) {
                mTcpListener.onStarted(this, true);
            }
        }
    }

4. GsmCdmaPhone

其中函数getCallForwardingOption这是个phone的接口方法,继承自接口PhoneInternalInterface

作为父类,真正的实现代码在GsmCdmaPhone.java上

    @Override
    public void getCallForwardingOption(int commandInterfaceCFReason, Message onComplete) {
        if (isPhoneTypeGsm()) {
            Phone imsPhone = mImsPhone;
//判断是否为imsPhone,是的话走ImsPhone(PS)流程,不是的话走CS流程
            if ((imsPhone != null)
                    && ((imsPhone.getServiceState().getState() == ServiceState.STATE_IN_SERVICE)
                    || imsPhone.isUtEnabled())) {
                imsPhone.getCallForwardingOption(commandInterfaceCFReason, onComplete);
                return;
            }

            if (isvalidCommandInterfaceCFReason(commandInterfaceCFReason)) {
                if (DBG) logd("requesting call forwarding query.");
                Message resp;
                if (commandInterfaceCFReason == CF_REASON_UNconditional) {
                    resp = obtainMessage(EVENT_GET_CALL_FORWARD_DONE, onComplete);
                } else {
                    resp = onComplete;
                }
                mCi.queryCallforwardstatus(commandInterfaceCFReason, 0, null, resp);
            }
        } else {
            loge("getCallForwardingOption: not possible in CDMA");
        }
    }

首先分析走CS流程,mCi为Phone类中的CommandsInterface接口,而CommandsInterface的接口方法都在RIL类中实现

5.RIL

调用函数RIL.queryCallForwardStatus(int cfReason, int serviceClass, String number, Message response)


    @Override
    public void queryCallForwardStatus(int cfReason, int serviceClass,
                           String number, Message result) {
        IRadio radioProxy = getRadioProxy(result);
//将消息result包装为IRadio发送request到modem
        if (radioProxy != null) {
            RILRequest rr = obtainRequest(RIL_REQUEST_QUERY_CALL_FORWARD_STATUS, result,
                    mRILDefaultWorkSource);

            if (RILJ_LOGD) {
                riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)
                        + " cfreason = " + cfReason + " serviceClass = " + serviceClass);
            }

            android.hardware.radio.V1_0.CallForwardInfo cfInfo =
                    new android.hardware.radio.V1_0.CallForwardInfo();
            cfInfo.reason = cfReason;
            cfInfo.serviceClass = serviceClass;
            cfInfo.toa = PhoneNumberUtils.toaFromString(number);
            cfInfo.number = convertNullToemptyString(number);
            cfInfo.timeSeconds = 0;

            try {
                radioProxy.getCallForwardStatus(rr.mSerial, cfInfo);
            } catch (RemoteException | runtimeexception e) {
                handleRadioProxyExceptionForRR(rr, "queryCallForwardStatus", e);
            }
        }
    }

IRadio为c++程序,这是发送Requst的过程,下面就超出了本组的学习内容

 

相关阅读

系统分析与设计方法---用户界面设计的原则

用户界面设计   接口设计主要包括三个方面的内容:一是设计软件构件间的接口;二是设计模块和其他非人的信息生产者和消费者(如外部

从爬取豆瓣影评到基于朴素贝叶斯的电影评论情感分析(

一、爬取豆瓣影评 基本思路:先获取每个电影的评论区链接,然后依次进入其评论区爬取评论。选取10部电影,每部200条评论。 用到的包为

货拉拉APP产品分析:作为同城货运的APP,是如何在市场上占

在同城货运市场不断扩大趋势下,货拉拉作为一款同城货运的APP,如何在市场上占有一席之地的,又存在哪些交互细节的问题,我们一起进入产

2017移动互联网家庭育儿记录工具市场分析

2016年中国出生人口数量同比增长11.50%,家庭育儿市场迎来人口红利。同时,伴随着科学养育观念不断渗透,男性在家庭育儿过程中参与度越

竞品分析|唱吧如何赶超全民K歌?

唱吧需要怎么利用自己的目前积累的强大体量用户和明星资源,寻找差异化突破点来应对全民K歌?本文作者就此来分析,一起来瞧瞧~一、背景

分享到:

栏目导航

推荐阅读

热门阅读