Android O Phone进程启动流程
2018-03-01 00:00
274 查看
我们这里所说的Phone进程指的是"com.android.phone"进程,代码位于:
Phone进程是开机启动的,其AndroidManifest.xml中的以下代码决定了其将在DBM下就会启动,且异常退出后会自动重启。
directBootAware:设备开机后在用户解锁前会先进入一个Direct Boot Mode,这时系统会发送ACTION_LOCKED_BOOT_COMPLETED 广播,等到用户解锁后,系统才会发送ACTION_BOOT_COMPLETED广播。
PhoneApp继承了Application,所以PhoneApp.onCreate()在Telephony启动时就会首先被调用,且比当前进程中的其他任何Activity、Service、Receiver(不含ContentProvider)都要早。
接下来看看PhoneGlobals,需要重点关注的是PhoneFactory.makeDefaultPhones()。此外还做了很多初始化操作,下面仅仅列出了CallManager及PhoneInterfaceManager。
接下来就是在PhoneFactory中创建Phone对象了。GsmCdmaPhone、RIL、UiccController等对象都会在这里进行初始化,同时还会初始化ImsManager并监听ImsService。
我们主要来分析GsmCdmaPhone,UiccController的初始化可参考UICC开机初始化。
首先是initOnce(),主要是创建GsmCdmaCallTracker、IccPhoneBookInterfaceManager、IccCardProxy等对象,以及向RIL注册监听一些事件。
然后是initRatSpecific(),内容不多,就是设置一些初始值。
再往后就是ServiceStateTracker、DcTracker等对象的创建。
最后,简单总结以下,
PhoneApp开机启动
-> PhoneGlobals.onCreate()
-> PhoneFactory.makeDefaultPhones()
-> RIL、UiccController、ImsManager等
-> GsmCdmaPhone
-> GsmCdmaCallTracker、ServiceStateTracker、DcTracker等
-> 创建CallManager及PhoneInterfaceManager等
G
M
T
Text-to-speech function is limited to 200 characters
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 |
Options : History : Feedback : Donate | Close |
相关文章推荐
- Android系统启动流程——init进程
- Android 应用进程启动流程
- (OK) Android应用进程启动流程(Zygote进程与SystemServer进程)
- Android O: init进程启动流程分析(阶段一)
- Android源码解析之(八)-->Zygote进程启动流程
- Android系统进程Zygote启动流程
- Android O: init进程启动流程分析(阶段二)
- android init进程启动的大致流程
- Android 儿子Activity在启动过程中的流程组件 && 儿子Activity在一个新的进程组件启动过程
- android源码解析之(九)-->SystemServer进程启动流程
- Android——从init进程启动流程
- Android O: init进程启动流程分析(阶段三)
- Android N Phone进程启动流程
- android源码解析之(八)-->Zygote进程启动流程
- Android 应用进程启动流程
- android N进程启动流程(一)(捕获输入事件、准备创建activity、焦点切换)
- Android源码解析之(九)-->SystemServer进程启动流程
- Android Framework学习(五)之应用进程启动流程
- android N进程启动流程(二)(上一个activity的暂停、进程启动、绑定进程与创建application)
- Android中bindService的细节之一:从进程的角度分析绑定Service的流程【Service所在进程首次启动】