Android L Phone 启动流程
来源:互联网 发布:知彼而知己 打不开 编辑:程序博客网 时间:2024/05/01 15:28
1、在ActivityManagerService 的SystemReady中启动所有persist属性的应用 ,其中就包含TeleService,且在Launcher前启动!
synchronized (this) { if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) { try { List apps = AppGlobals.getPackageManager(). getPersistentApplications(STOCK_PM_FLAGS); if (apps != null) { int N = apps.size(); int i; for (i=0; i<N; i++) { ApplicationInfo info = (ApplicationInfo)apps.get(i); if (info != null && !info.packageName.equals("android")) { addAppLocked(info, false, null /* ABI override */); } } } } catch (RemoteException ex) { // pm is in same process, this will never happen. } } // Start up initial activity. mBooting = true; startHomeActivityLocked(mCurrentUserId); try { if (AppGlobals.getPackageManager().hasSystemUidErrors()) { Message msg = Message.obtain(); msg.what = SHOW_UID_ERROR_MSG; mHandler.sendMessage(msg); } } catch (RemoteException e) { }
@Override public void onCreate() { 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(); mTelephonyGlobals = new TelephonyGlobals(this); mTelephonyGlobals.onCreate(); } }
它的主要工作便是启动PhoneGlobals,这是一个非常重要的类:
在这里初始化了Phone的framework层的东西,是的,就是这样上上下下来回调,起到承上启下的作用。
而且PhoneGlobals还采用了单例模式!来看重要的onCreate方法:
public void onCreate() { if (VDBG) Log.v(LOG_TAG, "onCreate()..."); ContentResolver resolver = getContentResolver(); // Cache the "voice capable" flag. // This flag currently comes from a resource (which is // overrideable on a per-product basis): sVoiceCapable = getResources().getBoolean(com.android.internal.R.bool.config_voice_capable); // ...but this might eventually become a PackageManager "system // feature" instead, in which case we'd do something like: // sVoiceCapable = // getPackageManager().hasSystemFeature(PackageManager.FEATURE_TELEPHONY_VOICE_CALLS); if (phone == null) { // Initialize the telephony framework <span style="background-color: rgb(255, 255, 102);">PhoneFactory.makeDefaultPhones(this);</span> int numPhones = TelephonyManager.getDefault().getPhoneCount(); if(numPhones > 1) PrimarySubSelectionController.init(this); // Get the default phone <span style="background-color: rgb(255, 255, 51);"> phone = PhoneFactory.getDefaultPhone();</span> // Start TelephonyDebugService After the default phone is created. Intent intent = new Intent(this, TelephonyDebugService.class); startService(intent); mPhones = new PhoneProxy[numPhones]; mPhones = PhoneFactory.getPhones(); <span style="background-color: rgb(255, 255, 102);">mCM = CallManager.getInstance();</span> for (Phone ph : mPhones) { <span style="background-color: rgb(255, 255, 51);">mCM.registerPhone(ph);</span> } // Create the NotificationMgr singleton, which is used to display // status bar icons and control other status bar behavior. notificationMgr = NotificationMgr.init(this); mHandler.sendEmptyMessage(EVENT_START_SIP_SERVICE); int phoneType = phone.getPhoneType(); if (phoneType == PhoneConstants.PHONE_TYPE_CDMA) { // Create an instance of CdmaPhoneCallState and initialize it to IDLE cdmaPhoneCallState = new CdmaPhoneCallState(); cdmaPhoneCallState.CdmaPhoneCallStateInit(); } // before registering for phone state changes mPowerManager = (PowerManager) getSystemService(Context.POWER_SERVICE); mWakeLock = mPowerManager.newWakeLock(PowerManager.FULL_WAKE_LOCK, LOG_TAG); // lock used to keep the processor awake, when we don't care for the display. mPartialWakeLock = mPowerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK | PowerManager.ON_AFTER_RELEASE, LOG_TAG); mKeyguardManager = (KeyguardManager) getSystemService(Context.KEYGUARD_SERVICE); // get a handle to the service so that we can use it later when we // want to set the poke lock. mPowerManagerService = IPowerManager.Stub.asInterface( ServiceManager.getService("power")); // Get UpdateLock to suppress system-update related events (e.g. dialog show-up) // during phone calls. mUpdateLock = new UpdateLock("phone"); if (DBG) Log.d(LOG_TAG, "onCreate: mUpdateLock: " + mUpdateLock); CallLogger callLogger = new CallLogger(this, new CallLogAsync()); callGatewayManager = CallGatewayManager.getInstance(); // Create the CallController singleton, which is the interface // to the telephony layer for user-initiated telephony functionality // (like making outgoing calls.) <span style="background-color: rgb(255, 255, 102);">callController = CallController.init(this, callLogger, callGatewayManager);</span> // Create the CallerInfoCache singleton, which remembers custom ring tone and // send-to-voicemail settings. // // The asynchronous caching will start just after this call. callerInfoCache = CallerInfoCache.init(this); // Monitors call activity from the telephony layer callStateMonitor = new CallStateMonitor(mCM); // Bluetooth manager bluetoothManager = new BluetoothManager(); phoneMgr = PhoneInterfaceManager.init(this, phone); // Create the CallNotifer singleton, which handles // asynchronous events from the telephony layer (like // launching the incoming-call UI when an incoming call comes // in.) <span style="background-color: rgb(255, 255, 102);"> notifier = CallNotifier.init(this, phone, callLogger, callStateMonitor, bluetoothManager);</span> // register for ICC status IccCard sim = phone.getIccCard(); if (sim != null) { if (VDBG) Log.v(LOG_TAG, "register for ICC status"); sim.registerForPersoLocked(mHandler, EVENT_PERSO_LOCKED, null); } // register for MMI/USSD mCM.registerForMmiComplete(mHandler, MMI_COMPLETE, null); // register connection tracking to PhoneUtils PhoneUtils.initializeConnectionHandler(mCM); // Register for misc other intent broadcasts. IntentFilter intentFilter = new IntentFilter(Intent.ACTION_AIRPLANE_MODE_CHANGED); intentFilter.addAction(TelephonyIntents.ACTION_ANY_DATA_CONNECTION_STATE_CHANGED); intentFilter.addAction(Intent.ACTION_DOCK_EVENT); intentFilter.addAction(TelephonyIntents.ACTION_SIM_STATE_CHANGED); intentFilter.addAction(TelephonyIntents.ACTION_RADIO_TECHNOLOGY_CHANGED); intentFilter.addAction(TelephonyIntents.ACTION_SERVICE_STATE_CHANGED); intentFilter.addAction(TelephonyIntents.ACTION_EMERGENCY_CALLBACK_MODE_CHANGED); intentFilter.addAction(TelephonyIntents.ACTION_MANAGED_ROAMING_IND); <span style="background-color: rgb(255, 255, 102);">registerReceiver(mReceiver, intentFilter);</span> //set the default values for the preferences in the phone. PreferenceManager.setDefaultValues(this, R.xml.network_setting, false); PreferenceManager.setDefaultValues(this, R.xml.call_feature_setting, false); // Make sure the audio mode (along with some // audio-mode-related state of our own) is initialized // correctly, given the current state of the phone. PhoneUtils.setAudioMode(mCM); } cdmaOtaProvisionData = new OtaUtils.CdmaOtaProvisionData(); cdmaOtaConfigData = new OtaUtils.CdmaOtaConfigData(); cdmaOtaScreenState = new OtaUtils.CdmaOtaScreenState(); cdmaOtaInCallScreenUiState = new OtaUtils.CdmaOtaInCallScreenUiState(); // XXX pre-load the SimProvider so that it's ready resolver.getType(Uri.parse("content://icc/adn")); // start with the default value to set the mute state. mShouldRestoreMuteOnInCallResume = false; // TODO: Register for Cdma Information Records // phone.registerCdmaInformationRecord(mHandler, EVENT_UNSOL_CDMA_INFO_RECORD, null); // Read HAC settings and configure audio hardware if (getResources().getBoolean(R.bool.hac_enabled)) { int hac = android.provider.Settings.System.getInt(phone.getContext().getContentResolver(), android.provider.Settings.System.HEARING_AID, 0); AudioManager audioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE); audioManager.setParameter(CallFeaturesSetting.HAC_KEY, hac != 0 ? CallFeaturesSetting.HAC_VAL_ON : CallFeaturesSetting.HAC_VAL_OFF); } }
PhoneFactory.makeDefaultPhones(this); 对framework进行初始化,在frameworks/opt下
public static void makeDefaultPhone(Context context) { synchronized (sLockProxyPhones) { if (!sMadeDefaults) { sContext = context; // create the telephony device controller. TelephonyDevController.create(); int retryCount = 0; for(;;) { boolean hasException = false; retryCount ++; try { // use UNIX domain socket to // prevent subsequent initialization new LocalServerSocket("com.android.internal.telephony"); } catch (java.io.IOException ex) { hasException = true; } if ( !hasException ) { break; } else if (retryCount > SOCKET_OPEN_MAX_RETRY) { throw new RuntimeException("PhoneFactory probably already running"); } else { try { Thread.sleep(SOCKET_OPEN_RETRY_MILLIS); } catch (InterruptedException er) { } } } sPhoneNotifier = new DefaultPhoneNotifier(); // Get preferred network mode int preferredNetworkMode = RILConstants.PREFERRED_NETWORK_MODE; if (TelephonyManager.getLteOnCdmaModeStatic() == PhoneConstants.LTE_ON_CDMA_TRUE) { preferredNetworkMode = Phone.NT_MODE_GLOBAL; } int cdmaSubscription = CdmaSubscriptionSourceManager.getDefault(context); Rlog.i(LOG_TAG, "Cdma Subscription set to " + cdmaSubscription); /* In case of multi SIM mode two instances of PhoneProxy, RIL are created, where as in single SIM mode only instance. isMultiSimEnabled() function checks whether it is single SIM or multi SIM mode */ int numPhones = TelephonyManager.getDefault().getPhoneCount(); int[] networkModes = new int[numPhones]; sProxyPhones = new PhoneProxy[numPhones]; sCommandsInterfaces = new RIL[numPhones]; for (int i = 0; i < numPhones; i++) { //reads the system properties and makes commandsinterface try {// // Get preferred network type.// TODO: Sishir added this code to but we need a new technique for MSim// int networkType = calculatePreferredNetworkType(context);// Rlog.i(LOG_TAG, "Network Type set to " + Integer.toString(networkType)); networkModes[i] = TelephonyManager.getIntAtIndex( context.getContentResolver(), Settings.Global.PREFERRED_NETWORK_MODE, i); } catch (SettingNotFoundException snfe) { Rlog.e(LOG_TAG, "Settings Exception Reading Value At Index for"+ " Settings.Global.PREFERRED_NETWORK_MODE"); networkModes[i] = preferredNetworkMode; } if (sContext.getResources().getBoolean( com.android.internal.R.bool.config_global_phone_enabled) && i == PhoneConstants.PHONE_ID1) { networkModes[i] = Phone.NT_MODE_LTE_CDMA_EVDO_GSM_WCDMA; TelephonyManager.putIntAtIndex( context.getContentResolver(), Settings.Global.PREFERRED_NETWORK_MODE, i, networkModes[i]); } Rlog.i(LOG_TAG, "Network Mode set to " + Integer.toString(networkModes[i])); sCommandsInterfaces[i] = new RIL(context, networkModes[i], cdmaSubscription, i); } Rlog.i(LOG_TAG, "Creating SubscriptionController"); SubscriptionController.init(context, sCommandsInterfaces); // Instantiate UiccController so that all other classes can just // call getInstance() mUiccController = UiccController.make(context, sCommandsInterfaces); sModemStackController = ModemStackController.make(context, mUiccController, sCommandsInterfaces); sModemBindingPolicyHandler = ModemBindingPolicyHandler.make(context, mUiccController, sCommandsInterfaces); for (int i = 0; i < numPhones; i++) { PhoneBase phone = null; <span style="background-color: rgb(255, 255, 102);">int phoneType = TelephonyManager.getPhoneType(networkModes[i]);</span> if (phoneType == PhoneConstants.PHONE_TYPE_GSM) { phone = new GSMPhone(context, sCommandsInterfaces[i], sPhoneNotifier, i); } else if (phoneType == PhoneConstants.PHONE_TYPE_CDMA) { phone = new CDMALTEPhone(context, sCommandsInterfaces[i], sPhoneNotifier, i); } Rlog.i(LOG_TAG, "Creating Phone with type = " + phoneType + " sub = " + i); <span style="background-color: rgb(255, 255, 102);"> sProxyPhones[i] = new PhoneProxy(phone)</span>; } mProxyController = ProxyController.getInstance(context, sProxyPhones, mUiccController, sCommandsInterfaces); // Set the default phone in base class. // FIXME: This is a first best guess at what the defaults will be. It // FIXME: needs to be done in a more controlled manner in the future. sProxyPhone = sProxyPhones[0]; sCommandsInterface = sCommandsInterfaces[0]; // Ensure that we have a default SMS app. Requesting the app with // updateIfNeeded set to true is enough to configure a default SMS app. ComponentName componentName = SmsApplication.getDefaultSmsApplication(context, true /* updateIfNeeded */); String packageName = "NONE"; if (componentName != null) { packageName = componentName.getPackageName(); } Rlog.i(LOG_TAG, "defaultSmsApplication: " + packageName); // Set up monitor to watch for changes to SMS packages SmsApplication.initSmsPackageMonitor(context); sMadeDefaults = true; Rlog.i(LOG_TAG, "Creating SubInfoRecordUpdater "); sSubInfoRecordUpdater = new SubInfoRecordUpdater(context, sProxyPhones, sCommandsInterfaces); SubscriptionController.getInstance().updatePhonesAvailability(sProxyPhones); } } }
这是一个非常重要的方法,创建套接字 通过socket与底层交互,获得卡类型例如当前为GSM,则创建GSMPhone对象
并生成代理对象.存入数组,此方法内对Phone的framework层初始化完毕
3.
<span style="background-color: rgb(255, 255, 51);">phone = PhoneFactory.getDefaultPhone();</span>
<span style="background-color: rgb(255, 255, 51);"></span>
<span style="background-color: rgb(255, 255, 51);"></span><pre name="code" class="java"> public static Phone getDefaultPhone() { synchronized (sLockProxyPhones) { if (!sMadeDefaults) { throw new IllegalStateException("Default phones haven't been made yet!"); } return sProxyPhone; } }
sProxyPhone为Phone对象数组中的第0个元素。
4、初始化CallManager (在frameworks/opt下),上下层交互的通道,采用单例模式,非常重要的一个类。
<pre name="code" class="html"> mCM = CallManager.getInstance(); for (Phone ph : mPhones) { mCM.registerPhone(ph); }
CallManager的registerPhone是一个非常重要的方法:
/** * Register phone to CallManager * @param phone to be registered * @return true if register successfully */ public boolean registerPhone(Phone phone) { Phone basePhone = getPhoneBase(phone); if (basePhone != null && !mPhones.contains(basePhone)) { if (DBG) { Rlog.d(LOG_TAG, "registerPhone(" + phone.getPhoneName() + " " + phone + ")"); } if (mPhones.isEmpty()) { mDefaultPhone = basePhone; } mPhones.add(basePhone); mRingingCalls.add(basePhone.getRingingCall()); mBackgroundCalls.add(basePhone.getBackgroundCall()); mForegroundCalls.add(basePhone.getForegroundCall()); registerForPhoneStates(basePhone); return true; } return false;
将当前Phone对应的三个Call对象保存到CallManager的三个对应的数组结构中,并调用私有方法
registerForPhoneStates(basePhone),来注册监听Phone的状态。注意此处传入的是真Phone
<pre name="code" class="java"> private void registerForPhoneStates(Phone phone) { // We need to keep a mapping of handler to Phone for proper unregistration. // TODO: Clean up this solution as it is just a work around for each Phone instance // using the same Handler to register with the RIL. When time permits, we should consider // moving the handler (or the reference ot the handler) into the Phone object. // See b/17414427. CallManagerHandler handler = mHandlerMap.get(phone); if (handler != null) { Rlog.d(LOG_TAG, "This phone has already been registered."); return; } // New registration, create a new handler instance and register the phone. handler = new CallManagerHandler(); mHandlerMap.put(phone, handler); // for common events supported by all phones phone.registerForPreciseCallStateChanged(handler, EVENT_PRECISE_CALL_STATE_CHANGED, null); phone.registerForDisconnect(handler, EVENT_DISCONNECT, null); phone.registerForNewRingingConnection(handler, EVENT_NEW_RINGING_CONNECTION, null); phone.registerForUnknownConnection(handler, EVENT_UNKNOWN_CONNECTION, null); phone.registerForIncomingRing(handler, EVENT_INCOMING_RING, null); phone.registerForRingbackTone(handler, EVENT_RINGBACK_TONE, null); phone.registerForInCallVoicePrivacyOn(handler, EVENT_IN_CALL_VOICE_PRIVACY_ON, null); phone.registerForInCallVoicePrivacyOff(handler, EVENT_IN_CALL_VOICE_PRIVACY_OFF, null); phone.registerForDisplayInfo(handler, EVENT_DISPLAY_INFO, null); phone.registerForSignalInfo(handler, EVENT_SIGNAL_INFO, null); phone.registerForResendIncallMute(handler, EVENT_RESEND_INCALL_MUTE, null); phone.registerForMmiInitiate(handler, EVENT_MMI_INITIATE, null); phone.registerForMmiComplete(handler, EVENT_MMI_COMPLETE, null); phone.registerForSuppServiceFailed(handler, EVENT_SUPP_SERVICE_FAILED, null); phone.registerForServiceStateChanged(handler, EVENT_SERVICE_STATE_CHANGED, null); // for events supported only by GSM, CDMA and IMS phone if (phone.getPhoneType() == PhoneConstants.PHONE_TYPE_GSM || phone.getPhoneType() == PhoneConstants.PHONE_TYPE_CDMA || phone.getPhoneType() == PhoneConstants.PHONE_TYPE_IMS) { phone.setOnPostDialCharacter(handler, EVENT_POST_DIAL_CHARACTER, null); } // for events supported only by CDMA phone if (phone.getPhoneType() == PhoneConstants.PHONE_TYPE_CDMA ){ phone.registerForCdmaOtaStatusChange(handler, EVENT_CDMA_OTA_STATUS_CHANGE, null); phone.registerForSubscriptionInfoReady(handler, EVENT_SUBSCRIPTION_INFO_READY, null); phone.registerForCallWaiting(handler, EVENT_CALL_WAITING, null); phone.registerForEcmTimerReset(handler, EVENT_ECM_TIMER_RESET, null); } // for events supported only by IMS phone if (phone.getPhoneType() == PhoneConstants.PHONE_TYPE_IMS) { phone.registerForOnHoldTone(handler, EVENT_ONHOLD_TONE, null); } }
剩下的就是初始化一些非常重要的类,和注册广播接收器,就没什么特别的了。
未完待续
0 0
- Android L Phone 启动流程
- android L 启动流程
- android L 启动流程
- android L 启动流程
- android L 启动流程
- android L 启动流程
- android L 启动流程
- Android L launcher3启动流程
- com.android.phone进程启动流程
- Android N Phone进程启动流程
- Android N Phone进程启动流程
- Phone的启动流程
- android phone模块流程
- Android L Phone进程初始化_01
- Android L Phone进程初始化_02
- android L 关机流程分析
- android phone电话调用流程
- android phone电话调用流程
- PythonChallenge第10题
- Linux帮助命令
- c++_sqrt实现判断素数函数
- svn客户端--TortoiseSVN的安装
- 软考复习专题十---算法设计
- Android L Phone 启动流程
- 使用浮动div元素来实现橡皮筋式截取选取框(鼠标监听事件)
- 【C语言总结】宏定义,预处理
- android 持久化保存cookie
- 方向导数和梯度
- String与InputStream相互转换
- Android ListView 一
- hznu 1464: ST Task(算角度,注意精度)
- Unique Paths