Android O Phone process startup process

The Phone process we are talking about here refers to the "com.android.phone" process, and the code is located at:

packages/services/Telephony

The Phone process is started at boot, and the following code in its AndroidManifest.xml determines that it will be started under DBM, and will restart automatically after an abnormal exit.

    <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 : After the device is powered on, it will enter a Direct Boot Mode before the user unlocks it. At this time, the system will send the ACTION_ LOCKED _BOOT_COMPLETED broadcast, and the system will not send the ACTION_BOOT_COMPLETED broadcast until the user unlocks it.

PhoneApp inherits Application, so PhoneApp.onCreate() will be called first when Telephony starts, and earlier than any other Activity, Service, Receiver (excluding ContentProvider) in the current process.

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相关的
        }
    }
}

Looking at PhoneGlobals next, the main thing to focus on is PhoneFactory.makeDefaultPhones(). In addition, a lot of initialization operations have been done, and only CallManager and PhoneInterfaceManager are listed below.

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());
        ......
    }
    ......
}

The next step is to create a Phone object in the PhoneFactory. Objects such as GsmCdmaPhone, RIL, UiccController will be initialized here, and ImsManager will also be initialized and listen to 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();
            }
            ......
        }
    }
}

We mainly analyze GsmCdmaPhone, the initialization of UiccController can refer to UICC boot initialization .

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);
}

The first is initOnce(), which mainly creates objects such as GsmCdmaCallTracker, IccPhoneBookInterfaceManager, IccCardProxy, etc., and registers and listens to some events with 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);
}

Then there is initRatSpecific(), which is not much, but sets some initial values.


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);
    }
}

Next is the creation of objects such as ServiceStateTracker and DcTracker.

 

Finally, a brief summary is as follows,

PhoneApp starts up

    -> PhoneGlobals.onCreate()

        -> PhoneFactory.makeDefaultPhones()

            -> RIL、UiccController、ImsManager等

            -> GsmCdmaPhone

                -> GsmCdmaCallTracker、ServiceStateTracker、DcTracker等

        -> Create CallManager and PhoneInterfaceManager, etc.

 

 

 

 

 

 

 
 
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

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=324928552&siteId=291194637