• GSMPhone与CDMAPhone切换过程


    GSMPhone与CDMAPhone切换过程

     

    Phone创建过程

      Phone APP开机启动,会去创建Phone:

    public static void makeDefaultPhone(Context context) 
    {
        // Get preferred network mode 根据网络设置,
        // 否则默认PREFERRED_NETWORK_MODE 为= NETWORK_MODE_WCDMA_PREF;
        int preferredNetworkMode = RILConstants.PREFERRED_NETWORK_MODE;
        if (BaseCommands.getLteOnCdmaModeStatic() == Phone.LTE_ON_CDMA_TRUE) {
            preferredNetworkMode = Phone.NT_MODE_GLOBAL;
        }
        
        //从数据库中查询设置preferred network mode
        int networkMode = Settings.Secure.getInt(context.getContentResolver(),
                Settings.Secure.PREFERRED_NETWORK_MODE, preferredNetworkMode);
    
        //创建RIL,将会设置Modem的preferred network mode
      sCommandsInterface = new RIL(context, networkMode, cdmaSubscription);
    
        //若没有设置preferred network mode 或者设置pref WCDMA 则create GSMPhone     
        int phoneType = getPhoneType(networkMode);
        if (phoneType == Phone.PHONE_TYPE_GSM) {
            //create GSMPhone
            sProxyPhone = new PhoneProxy(new GSMPhone(context,
                    sCommandsInterface, sPhoneNotifier));
        } else if (phoneType == Phone.PHONE_TYPE_CDMA) {
            //create CDMAPhone Or CDMALTEPhone
        }
        
        ……
    }

      Phone是在开机就启动的,创建具体Phone是GSMPhone还是CDMAPhone,

    这个创建过程,跟插入的卡类型无关,跟设置preferred network mode有关;

    但是在具体使用中,假如插入UIM卡,显然是不行,肯定存在着GSMPhone向CDMAPhone切换的过程;或者相反的切换过程,看看此过程是如何进行的。

    PhoneProxy状态处理

    创建的Phone使用PhoneProxy代理的,PhoneProxy是个handler,实现Phone接口

    PhoneProxy构造过程

      

    public PhoneProxy(PhoneBase phone) {
        mActivePhone = phone;
        mCommandsInterface = ((PhoneBase)mActivePhone).mCM;
            
            //监听modem传递过来的一些消息
        mCommandsInterface.registerForRilConnected(this, EVENT_RIL_CONNECTED, null);
        mCommandsInterface.registerForOn(this, EVENT_RADIO_ON, null);
        mCommandsInterface.registerForVoiceRadioTechChanged(
                             this, EVENT_VOICE_RADIO_TECH_CHANGED, null);
        ……
    }

    PhoneProxy里面监听了modem传递过来的一些,看看这些消息都具体干了些什么。

    public void handleMessage(Message msg) {
        AsyncResult ar = (AsyncResult) msg.obj;
        logd(" msg.what = " + msg.what);
        switch(msg.what) {
          case EVENT_RADIO_ON:
              mVoiceTechQueryContext++;
              mCommandsInterface.getVoiceRadioTechnology(
                  obtainMessage(EVENT_REQUEST_VOICE_RADIO_TECH_DONE,
            mVoiceTechQueryContext));
              break;
          case EVENT_VOICE_RADIO_TECH_CHANGED:
              mVoiceTechQueryContext++;
              mCommandsInterface.getVoiceRadioTechnology(
            obtainMessage(EVENT_REQUEST_VOICE_RADIO_TECH_DONE,
            mVoiceTechQueryContext));
              break;
          case EVENT_REQUEST_VOICE_RADIO_TECH_DONE:
                  updatePhoneObject(newVoiceTech);
                  break;
            ……
        }
    }

      注册了EVENT_RADIO_ON与EVENT_VOICE_RADIO_TECH_CHANGED
    当收到这两个消息的时候,都调用了RIL的getVoiceRadioTechnology,获取当前注册网络使用技术;

    具体是哪一个消息新创建Phone,通过Log看到是Modem传递过来的EVENT_VOICE_RADIO_TECH_CHANGED消息;
    完了之后会将消息EVENT_REQUEST_VOICE_RADIO_TECH_DONE传递给PhoneProxy,
    调用updatePhoneObject,更新Phone.

    GSM 与CDMA切换过程

    public void updatePhoneObject(int newVoiceRadioTech) {
            //一堆判断是否当前Phone与当前网络技术相匹配
            
            //当前创建的Phone与网络技术不匹配,重新创建Phone
            deleteAndCreatePhone(newVoiceRadioTech);
    }
    
    private void deleteAndCreatePhone(int newVoiceRadioTech) {
            String outgoingPhoneName = "Unknown";
            Phone oldPhone = mActivePhone;
            
            //打印从GSM——》CDMA Or CDMA——》GSM
            outgoingPhoneName = ((PhoneBase) oldPhone).getPhoneName();
            logd("Switching Voice Phone : " + outgoingPhoneName + " >>> "
                  + (ServiceState.isGsm(newVoiceRadioTech) ? "GSM" : "CDMA"));
            
            //oldPhone Unregister      
            oldPhone.dispose();    
              
            //创建新Phone
            createNewPhone(newVoiceRadioTech);
    }
    
    protected void createNewPhone(int newVoiceRadioTech) {
        if (ServiceState.isCdma(newVoiceRadioTech)) {
            mActivePhone = PhoneFactory.getCdmaPhone();
        } else if (ServiceState.isGsm(newVoiceRadioTech)) {
            mActivePhone = PhoneFactory.getGsmPhone();
        }
    }

    通过当前设置Modem的preferred network mode与当前注册网络技术,进行比较,不匹配通知上层,进行查询更新。

  • 相关阅读:
    maven配置成功,但显示'cmd' 不是内部或外部命令,也不是可运行的程序 或批处理文件。
    java ee 4周
    java 3周
    XML
    web后台过程
    【转】Maven详细
    HDFS 客户端读写操作详情
    HDFS DataNode详解
    HDFS NameNode详解
    CSS的四种样式
  • 原文地址:https://www.cnblogs.com/bastard/p/2923539.html
Copyright © 2020-2023  润新知