Android O Phone进程启动流程

我们这里所说的Phone进程指的是"com.android.phone"进程,代码位于:

packages/services/Telephony

Phone进程是开机启动的,其AndroidManifest.xml中的以下代码决定了其将在DBM下就会启动,且异常退出后会自动重启。

    <application android:name="PhoneApp"
            android:persistent="true" // 开机启动,异常自动重启
            android:label="@string/phoneAppLabel"
            android:icon="@mipmap/ic_launcher_phone"
            android:allowBackup="false"
            android:supportsRtl="true"
            android:usesCleartextTraffic="true"
            android:defaultToDeviceProtectedStorage="true"
            android:directBootAware="true"> // DBM下启动

directBootAware:设备开机后在用户解锁前会先进入一个Direct Boot Mode,这时系统会发送ACTION_LOCKED_BOOT_COMPLETED 广播,等到用户解锁后,系统才会发送ACTION_BOOT_COMPLETED广播。

PhoneApp继承了Application,所以PhoneApp.onCreate()在Telephony启动时就会首先被调用,且比当前进程中的其他任何Activity、Service、Receiver(不含ContentProvider)都要早。

public class PhoneApp extends Application {
    ......
    public void onCreate() {
        if (UserHandle.myUserId() == 0) {
            ......
            mPhoneGlobals = new PhoneGlobals(this);
            mPhoneGlobals.onCreate(); // 初始化Phone相关的内容

            mTelephonyGlobals = new TelephonyGlobals(this);
            mTelephonyGlobals.onCreate(); // TTY相关的
        }
    }
}

接下来看看PhoneGlobals,需要重点关注的是PhoneFactory.makeDefaultPhones()。此外还做了很多初始化操作,下面仅仅列出了CallManager及PhoneInterfaceManager。

public PhoneGlobals(Context context) {
    super(context);
    sMe = this;
    mSettingsObserver = new SettingsObserver(context, mHandler);
}

public void onCreate() {
    ......
    if (mCM == null) {
        // Initialize the telephony framework
        PhoneFactory.makeDefaultPhones(this); // 创建Phone对象
        ......
        // 创建CallManager,其会注册监听Phone的一些事件
        mCM = CallManager.getInstance();
        for (Phone phone : PhoneFactory.getPhones()) {
            mCM.registerPhone(phone);
        }
        ......
         // ITelephony的实现,是Phone提供给外部的IPC接口,使用时尽量通过TelephonyManager来调用
        phoneMgr = PhoneInterfaceManager.init(this, PhoneFactory.getDefaultPhone());
        ......
    }
    ......
}

接下来就是在PhoneFactory中创建Phone对象了。GsmCdmaPhone、RIL、UiccController等对象都会在这里进行初始化,同时还会初始化ImsManager并监听ImsService。


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

public static void makeDefaultPhone(Context context) {
    synchronized (sLockProxyPhones) {
        if (!sMadeDefaults) {
            ......
            // 每张SIM卡都要建立一个Phone和一个RIL对象
            int[] networkModes = new int[numPhones];
            sPhones = new Phone[numPhones];
            sCommandsInterfaces = new RIL[numPhones];
            sTelephonyNetworkFactories = new TelephonyNetworkFactory[numPhones];

            // 根据"ro.telephony.default_network"获取默认网络模式,并创建RIL对象
            for (int i = 0; i < numPhones; i++) {
                // reads the system properties and makes commandsinterface
                // Get preferred network type.
                networkModes[i] = RILConstants.PREFERRED_NETWORK_MODE;

                Rlog.i(LOG_TAG, "Network Mode set to " + Integer.toString(networkModes[i]));
                sCommandsInterfaces[i] = new RIL(context, networkModes[i],
                        cdmaSubscription, i);
            }
            ......
            // UiccController初始化
            sUiccController = UiccController.make(context, sCommandsInterfaces);

            // 根据网络模式创建对应的Phone对象
            for (int i = 0; i < numPhones; i++) {
                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());
                }
                Rlog.i(LOG_TAG, "Creating Phone with type = " + phoneType + " sub = " + i);

                sPhones[i] = phone;
            }
            ......
            // 监听ImsService的启动、关闭及IMS配置改变,并处理
            for (int i = 0; i < numPhones; i++) {
                sPhones[i].startMonitoringImsService();
            }
            ......
        }
    }
}

我们主要来分析GsmCdmaPhone,UiccController的初始化可参考UICC开机初始化

public GsmCdmaPhone(Context context, CommandsInterface ci, PhoneNotifier notifier,
                    boolean unitTestMode, int phoneId, int precisePhoneType,
                    TelephonyComponentFactory telephonyComponentFactory) {
    // 父类中会获取并保存UiccController
    super(precisePhoneType == PhoneConstants.PHONE_TYPE_GSM ? "GSM" : "CDMA",
            notifier, context, ci, unitTestMode, phoneId, telephonyComponentFactory);

    mPrecisePhoneType = precisePhoneType;
    initOnce(ci);
    initRatSpecific(precisePhoneType);
    // CarrierSignalAgent uses CarrierActionAgent in construction so it needs to be created
    // after CarrierActionAgent.
    mCarrierActionAgent = mTelephonyComponentFactory.makeCarrierActionAgent(this);
    mCarrierSignalAgent = mTelephonyComponentFactory.makeCarrierSignalAgent(this);
    mSST = mTelephonyComponentFactory.makeServiceStateTracker(this, this.mCi);
    // DcTracker uses SST so needs to be created after it is instantiated
    mDcTracker = mTelephonyComponentFactory.makeDcTracker(this);
    mSST.registerForNetworkAttached(this, EVENT_REGISTERED_TO_NETWORK, null);
    mDeviceStateMonitor = mTelephonyComponentFactory.makeDeviceStateMonitor(this);
    logd("GsmCdmaPhone: constructor: sub = " + mPhoneId);
}

首先是initOnce(),主要是创建GsmCdmaCallTracker、IccPhoneBookInterfaceManager、IccCardProxy等对象,以及向RIL注册监听一些事件。

private void initOnce(CommandsInterface ci) {
    if (ci instanceof SimulatedRadioControl) {
        mSimulatedRadioControl = (SimulatedRadioControl) ci;
    }

    mCT = mTelephonyComponentFactory.makeGsmCdmaCallTracker(this);
    mIccPhoneBookIntManager = mTelephonyComponentFactory.makeIccPhoneBookInterfaceManager(this);
    PowerManager pm
            = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE);
    mWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, LOG_TAG);
    mIccSmsInterfaceManager = mTelephonyComponentFactory.makeIccSmsInterfaceManager(this);
    mIccCardProxy = mTelephonyComponentFactory.makeIccCardProxy(mContext, mCi, mPhoneId);

    mCi.registerForAvailable(this, EVENT_RADIO_AVAILABLE, null);
    mCi.registerForOffOrNotAvailable(this, EVENT_RADIO_OFF_OR_NOT_AVAILABLE, null);
    mCi.registerForOn(this, EVENT_RADIO_ON, null);
    mCi.setOnSuppServiceNotification(this, EVENT_SSN, null);

    //GSM
    mCi.setOnUSSD(this, EVENT_USSD, null);
    mCi.setOnSs(this, EVENT_SS, null);

    //CDMA
    mCdmaSSM = mTelephonyComponentFactory.getCdmaSubscriptionSourceManagerInstance(mContext,
            mCi, this, EVENT_CDMA_SUBSCRIPTION_SOURCE_CHANGED, null);
    mEriManager = mTelephonyComponentFactory.makeEriManager(this, mContext,
            EriManager.ERI_FROM_XML);
    mCi.setEmergencyCallbackMode(this, EVENT_EMERGENCY_CALLBACK_MODE_ENTER, null);
    mCi.registerForExitEmergencyCallbackMode(this, EVENT_EXIT_EMERGENCY_CALLBACK_RESPONSE,
            null);
    mCi.registerForModemReset(this, EVENT_MODEM_RESET, null);
    // get the string that specifies the carrier OTA Sp number
    mCarrierOtaSpNumSchema = TelephonyManager.from(mContext).getOtaSpNumberSchemaForPhone(
            getPhoneId(), "");

    mResetModemOnRadioTechnologyChange = SystemProperties.getBoolean(
            TelephonyProperties.PROPERTY_RESET_ON_RADIO_TECH_CHANGE, false);

    mCi.registerForRilConnected(this, EVENT_RIL_CONNECTED, null);
    mCi.registerForVoiceRadioTechChanged(this, EVENT_VOICE_RADIO_TECH_CHANGED, null);
    mContext.registerReceiver(mBroadcastReceiver, new IntentFilter(
            CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED));
    mCDM = new CarrierKeyDownloadManager(this);
}

然后是initRatSpecific(),内容不多,就是设置一些初始值。


private void initRatSpecific(int precisePhoneType) {
    mPendingMMIs.clear();
    mIccPhoneBookIntManager.updateIccRecords(null);
    mEsn = null;
    mMeid = null;

    mPrecisePhoneType = precisePhoneType;

    TelephonyManager tm = TelephonyManager.from(mContext);
    if (isPhoneTypeGsm()) {
        mCi.setPhoneType(PhoneConstants.PHONE_TYPE_GSM);
        tm.setPhoneType(getPhoneId(), PhoneConstants.PHONE_TYPE_GSM);
        mIccCardProxy.setVoiceRadioTech(ServiceState.RIL_RADIO_TECHNOLOGY_UMTS);
    } else {
        mCdmaSubscriptionSource = CdmaSubscriptionSourceManager.SUBSCRIPTION_SOURCE_UNKNOWN;
        // This is needed to handle phone process crashes
        mIsPhoneInEcmState = getInEcmMode();
        if (mIsPhoneInEcmState) {
            // Send a message which will invoke handleExitEmergencyCallbackMode
            mCi.exitEmergencyCallbackMode(
                    obtainMessage(EVENT_EXIT_EMERGENCY_CALLBACK_RESPONSE));
        }

        mCi.setPhoneType(PhoneConstants.PHONE_TYPE_CDMA);
        tm.setPhoneType(getPhoneId(), PhoneConstants.PHONE_TYPE_CDMA);
        mIccCardProxy.setVoiceRadioTech(ServiceState.RIL_RADIO_TECHNOLOGY_1xRTT);
        // Sets operator properties by retrieving from build-time system property
        String operatorAlpha = SystemProperties.get("ro.cdma.home.operator.alpha");
        String operatorNumeric = SystemProperties.get(PROPERTY_CDMA_HOME_OPERATOR_NUMERIC);
        logd("init: operatorAlpha='" + operatorAlpha
                + "' operatorNumeric='" + operatorNumeric + "'");
        if (mUiccController.getUiccCardApplication(mPhoneId, UiccController.APP_FAM_3GPP) ==
                null || isPhoneTypeCdmaLte()) {
            if (!TextUtils.isEmpty(operatorAlpha)) {
                logd("init: set 'gsm.sim.operator.alpha' to operator='" + operatorAlpha + "'");
                tm.setSimOperatorNameForPhone(mPhoneId, operatorAlpha);
            }
            if (!TextUtils.isEmpty(operatorNumeric)) {
                logd("init: set 'gsm.sim.operator.numeric' to operator='" + operatorNumeric +
                        "'");
                logd("update icc_operator_numeric=" + operatorNumeric);
                tm.setSimOperatorNumericForPhone(mPhoneId, operatorNumeric);

                SubscriptionController.getInstance().setMccMnc(operatorNumeric, getSubId());
                // Sets iso country property by retrieving from build-time system property
                setIsoCountryProperty(operatorNumeric);
                // Updates MCC MNC device configuration information
                logd("update mccmnc=" + operatorNumeric);
                MccTable.updateMccMncConfiguration(mContext, operatorNumeric, false);
            }
        }

        // Sets current entry in the telephony carrier table
        updateCurrentCarrierInProvider(operatorNumeric);
    }
}

再往后就是ServiceStateTracker、DcTracker等对象的创建。

最后,简单总结以下,

PhoneApp开机启动

    -> PhoneGlobals.onCreate()

        -> PhoneFactory.makeDefaultPhones()

            -> RIL、UiccController、ImsManager等

            -> GsmCdmaPhone

                -> GsmCdmaCallTracker、ServiceStateTracker、DcTracker等

        -> 创建CallManager及PhoneInterfaceManager等

 
 
G
M
T
 
 
Detect languageAfrikaansAlbanianArabicArmenianAzerbaijaniBasqueBelarusianBengaliBosnianBulgarianCatalanCebuanoChichewaChinese (Simplified)Chinese (Traditional)CroatianCzechDanishDutchEnglishEsperantoEstonianFilipinoFinnishFrenchGalicianGeorgianGermanGreekGujaratiHaitian CreoleHausaHebrewHindiHmongHungarianIcelandicIgboIndonesianIrishItalianJapaneseJavaneseKannadaKazakhKhmerKoreanLaoLatinLatvianLithuanianMacedonianMalagasyMalayMalayalamMalteseMaoriMarathiMongolianMyanmar (Burmese)NepaliNorwegianPersianPolishPortuguesePunjabiRomanianRussianSerbianSesothoSinhalaSlovakSlovenianSomaliSpanishSundaneseSwahiliSwedishTajikTamilTeluguThaiTurkishUkrainianUrduUzbekVietnameseWelshYiddishYorubaZulu
 
AfrikaansAlbanianArabicArmenianAzerbaijaniBasqueBelarusianBengaliBosnianBulgarianCatalanCebuanoChichewaChinese (Simplified)Chinese (Traditional)CroatianCzechDanishDutchEnglishEsperantoEstonianFilipinoFinnishFrenchGalicianGeorgianGermanGreekGujaratiHaitian CreoleHausaHebrewHindiHmongHungarianIcelandicIgboIndonesianIrishItalianJapaneseJavaneseKannadaKazakhKhmerKoreanLaoLatinLatvianLithuanianMacedonianMalagasyMalayMalayalamMalteseMaoriMarathiMongolianMyanmar (Burmese)NepaliNorwegianPersianPolishPortuguesePunjabiRomanianRussianSerbianSesothoSinhalaSlovakSlovenianSomaliSpanishSundaneseSwahiliSwedishTajikTamilTeluguThaiTurkishUkrainianUrduUzbekVietnameseWelshYiddishYorubaZulu
 
 
 
 
 
 
 
 
 
Text-to-speech function is limited to 200 characters
 
 
Options : History : Feedback : Donate Close

猜你喜欢

转载自my.oschina.net/igiantpanda/blog/1627462