Android7.0 数据业务基础类的创建

版本
Android 7.0

我们知道,数据业务是依赖于PhoneApp的,因此它的基础类应该是在PhoneApp被加载后创建。
在PhoneApp的onCreate函数中:

@Override
public void onCreate() {
    //根据进程号判断用户,每个用户分配的可用进程号为100000
    //小于100000为主用户
    if (UserHandle.myUserId() == 0) {
    // We are running as the primary user, so should bring up the global phone state.
        mPhoneGlobals = new PhoneGlobals(this);
        //这里是我们关注的,数据和语音所需的基础类在这里创建
        mPhoneGlobals.onCreate();

        //这个具体的用处没研究过,网上的参考信息是处理PSTN呼叫
        mTelephonyGlobals = new TelephonyGlobals(this);
        mTelephonyGlobals.onCreate();
    }
}

我们看看PhoneGlobals的onCreate函数,目前我们只关注数据业务会用到的类:

public void onCreate() {
    ............
    //CallManager通话先关,初始时为null
    if (mCM == null) {
        // Initialize the telephony framework
        PhoneFactory.makeDefaultPhones(this);
        ..........
        //Phone进程对外的服务端,其它进程通过Binder调用PhoneInterfaceManager的接口
        phoneMgr = PhoneInterfaceManager.init(this, PhoneFactory.getDefaultPhone());
        ..........
    }
    ............
}

接下来我们看看PhoneFactory.makeDefaultPhones的内容。

public static void makeDefaultPhones(Context context) {
    makeDefaultPhone(context);
}

public static void makeDefaultPhone(Context context) {
        synchronized (sLockProxyPhones) {
            //确保只调用一次
            if (!sMadeDefaults) {
                sContext = context;

                //管理硬件资源用的
                TelephonyDevController.create();
                ..........
                //用于对外通知phone进程的一些状态
                sPhoneNotifier = new DefaultPhoneNotifier();

                //判断是单卡手机还是双卡,现在一般都是双卡了
                int numPhones =  TelephonyManager.getDefault().getPhoneCount();
                int[] networkModes = new int[numPhones];
                sPhones = new Phone[numPhones];
                sCommandsInterfaces = new RIL[numPhones];
                sTelephonyNetworkFactories = new TelephonyNetworkFactory[numPhones];

                for (int i = 0; i < numPhones; i++) {
                    networkModes[i] = RILConstants.PREFERRED_NETWORK_MODE;
                    ..........
                    //一个phone对象,有一个对应RIL(无线电接口层)
                    sCommandsInterfaces[i] = new RIL(context, networkModes[i],
                            cdmaSubscription, i);
                }

                //管理卡相关的信息,个人认为偏向于管理抽象化的卡信息,例如subId之类的
                SubscriptionController.init(context, sCommandsInterfaces);

                //管理卡相关的信息,个人认为偏向于管理实际的卡信息,例如卡中具体的内容
                sUiccController = UiccController.make(context, sCommandsInterfaces);

                //这里是android 7.0比较大的一个改进
                //在android 6.0及以前,对于不同的通信类型分别存在GsmPhone和CdmaPhone
                //在之前的版本中,插cdma卡的phone,在cdma网络和gsm网络间迁移(4g与2g迁移)时,将会发生phone切换
                //例如4g迁移到2g时,必须销毁cdmaphone,然后新建gsmphone;对象的开销和新建引入开销,还可能有隐藏的内存泄露
                for (int i = 0; i < numPhones; i++) {
                    //创建实际Phone对象的过程
                    Phone phone = null;
                    int phoneType = TelephonyManager.getPhoneType(networkModes[i]);
                    if (phoneType == PhoneConstants.PHONE_TYPE_GSM) {
                        phone = new GsmCdmaPhone(context,
                                sCommandsInterfaces[i], sPhoneNotifier, i,
                                PhoneConstants.PHONE_TYPE_GSM,
                                TelephonyComponentFactory.getInstance());
                    } else if (phoneType == PhoneConstants.PHONE_TYPE_CDMA) {
                        phone = new GsmCdmaPhone(context,
                                sCommandsInterfaces[i], sPhoneNotifier, i,
                                PhoneConstants.PHONE_TYPE_CDMA_LTE,
                                TelephonyComponentFactory.getInstance());
                    }
                    ........
                    sPhones[i] = phone;
                }

                //预定义的默认phone,为phone0
                sPhone = sPhones[0];
                sCommandsInterface = sCommandsInterfaces[0];
                //sms相关的,暂不关注
                ............
                //用于更新卡信息的类
                sSubInfoRecordUpdater = new SubscriptionInfoUpdater(context,
                        sPhones, sCommandsInterfaces);
                //仅让SubscriptionController获取到新创建的phone
                SubscriptionController.getInstance().updatePhonesAvailability(sPhones);

                //开始监听IMS服务
                for (int i = 0; i < numPhones; i++) {
                    sPhones[i].startMonitoringImsService();
                }

                //获取TelephonyRegistry的binder通信代理, TelephonyRegistry按观察者模式为其观察者提供phone的信息
                ITelephonyRegistry tr = ITelephonyRegistry.Stub.asInterface(
                        ServiceManager.getService("telephony.registry"));
                SubscriptionController sc = SubscriptionController.getInstance();

                //新增类,专注于监听卡的变化,然后通知给观察者
                sSubscriptionMonitor = new SubscriptionMonitor(tr, sContext, sc, numPhones);
                //新增类,在Android7.0中, 管理DDS(动态数据卡切换)的DctController被移除了
                //原来DctController中的内部类TelephonyFactory被单独抽成了一个文件
                //管理DDS逻辑的内容,被抽取成了PhoneSwitcher类
                sPhoneSwitcher = new PhoneSwitcher(MAX_ACTIVE_PHONES, numPhones,
                        sContext, sc, Looper.myLooper(), tr, sCommandsInterfaces,
                        sPhones);

                //在android7.0中,PhoneProxy类已经被移除了
                //此处ProxyController的定位不是很清晰,看接口多与RadioCapability有关
                sProxyController = ProxyController.getInstance(context, sPhones,
                        sUiccController, sCommandsInterfaces, sPhoneSwitcher);

                //原来作为DctController的子类,在android7.0中,终于独挡一面,成为一个独立的类
                //TelephonyNetworkFactory用于将数据业务纳入到整个android的网络管理框架中
                //通过NetworkFactory,数据业务和ConnectivityService衔接起来了
                sTelephonyNetworkFactories = new TelephonyNetworkFactory[numPhones];
                for (int i = 0; i < numPhones; i++) {
                    sTelephonyNetworkFactories[i] = new TelephonyNetworkFactory(
                            sPhoneSwitcher, sc, sSubscriptionMonitor, Looper.myLooper(),
                            sContext, i, sPhones[i].mDcTracker);
                }
        }
    }
}

这里我们暂时不继续分析每个对象的内部如何初始化,等后续分析具体的流程涉及到时,再作分析。

最后介绍一些前面提到的PhoneInterfaceManager的初始化。

static PhoneInterfaceManager init(PhoneGlobals app, Phone phone) {
    synchronized (PhoneInterfaceManager.class) {
        if (sInstance == null) {
            sInstance = new PhoneInterfaceManager(app, phone);
        } else {
            Log.wtf(LOG_TAG, "init() called multiple times! sInstance = " + sInstance);
        }
        return sInstance;
    }
}

private PhoneInterfaceManager(PhoneGlobals app, Phone phone) {
    //初始化内部变量
    ........
    publish();
}

private void publish() {
    if (DBG) log("publish: " + this);

    ServiceManager.addService("phone", this);
}

其实上面代码最值得关注的就是publish函数了,由于PhoneInterfaceManager继承了ITelephony.Stub(PhoneApp定义了ITelephony.aidl),因此上面的代码相当于将PhoneApp的Binder服务注册到ServiceManager中。于是,其它进程可以通过Binder通信,调用PhoneInterfaceManager提供的接口(当然是由权限检查的)。

结束语
这一篇blog实际上并没有太多深入的内容,其目的在于为之后介绍数据业务作一个铺垫。整个数据业务涉及的类非常多,从UI跨越了整个框架,并通过RIL及芯片商提供的库,最终与modem通信。因此,这里先简单描述一下,一些类初始化的情况。

你可能感兴趣的:(android)