安卓dialer Phone进程【Telephony框架、TeleService】启动过程
1. 相關(guān)源碼
phone進程是開機自啟的?,其進程是com.android.phone
packages/services/Telephony
? - src/com/android/phone/PhoneApp.java
? - AndroidManifest.xml
frameworks/base/services/core/java/com/android/server/
? - am/ActivityManagerService.java
frameworks/base/services/java/com/android/server/
? - SystemServer.java
frameworks/base/core/java/android/os/
? - Process.java
?2. Phone進程啟動流程
在packages/services/Telephony/AndroidManifest.xml中,/packages/services/Telephony/AndroidManifest.xml
<manifest xmlns:android="http://schemas.android.com/apk/res/android"xmlns:androidprv="http://schemas.android.com/apk/prv/res/android"package="com.android.phone"coreApp="true"android:sharedUserId="android.uid.phone"android:sharedUserLabel="@string/phoneAppLabel" ><!--: to pass lint --><uses-sdk android:minSdkVersion="24"/><!--: @}--><original-package android:name="com.android.phone" /> <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">?PhoneApp的屬性android:persistent="true",
android:persistent=true屬性。
系統(tǒng)啟動后,會通過ActivityManagerService的systemReady,加載persistent是true的應用。
擁有此屬性的app將不能被kill或kill后會自動重啟。
不過此apk是想做到不被kill,還是要在system/app下
ActivityManagerService在啟動后會去遍歷所有android:persistent="true"的應用,而后交由Process通過socket通知zygote fork一個新的進程,phone進程啟動具體過程如下:
1)startBootstrapServices?
- /frameworks/base/services/java/com/android/server/SystemServer.java
SystemServer執(zhí)行main方法,接著執(zhí)行run,run 方法主要是下列3 種方法
private void run() {startBootstrapServices();startCoreServices();startOtherServices(); }其中的startBootstrapServices方法去調(diào)用startService啟動ActivityManagerService
private void startBootstrapServices() {// Activity manager runs the show.traceBeginAndSlog("StartActivityManager");// TODO: Might need to move after migration to WM.ActivityTaskManagerService atm = mSystemServiceManager.startService(ActivityTaskManagerService.Lifecycle.class).getService();mActivityManagerService = ActivityManagerService.Lifecycle.startService(mSystemServiceManager, atm);mActivityManagerService.setSystemServiceManager(mSystemServiceManager);mActivityManagerService.setInstaller(installer);mWindowManagerGlobalLock = atm.getGlobalLock();traceEnd();// Set up the Application instance for the system process and get started.traceBeginAndSlog("SetSystemProcess");mActivityManagerService.setSystemProcess();traceEnd();?startService會回調(diào)Lifecycle.onStart(),這時已經(jīng)創(chuàng)建好ActivityManagerService對象mActivityManagerService,然后在SystemServer的startBootstrapServices中繼續(xù)調(diào)用ActivityManagerService的setSystemProcess,在ServiceManager中完成注冊ActivityManagerService。
- /frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java
至此ActivityManagerService完成了初始化。?
2067 public void setSystemProcess() { 2068 try { 2069 ServiceManager.addService(Context.ACTIVITY_SERVICE, this, /* allowIsolated= */ true, 2070 DUMP_FLAG_PRIORITY_CRITICAL | DUMP_FLAG_PRIORITY_NORMAL | DUMP_FLAG_PROTO); 2071 ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats);2)startOtherServices
- /frameworks/base/services/java/com/android/server/SystemServer.java
- /frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java
---------------
最終:?Zygote fork phone進程
- /packages/services/Telephony/src/com/android/phone/PhoneApp.java
Phone實體是Telephony框架對象,可以向該對象發(fā)起各種通訊相關(guān)的請求,Phone對象是Telephony整個框架的核心,他負責與RIL層的交互。
Phone對象是在PhoneApp這個application初始化過程中被創(chuàng)建的
public class PhoneApp extends Application {PhoneGlobals mPhoneGlobals;TelephonyGlobals mTelephonyGlobals;public PhoneApp() {}@Overridepublic void onCreate() {if (UserHandle.myUserId() == 0) {// We are running as the primary user, so should bring up the// global phone state.// 創(chuàng)建PhoneGlobals,即Phone的全局狀態(tài)mPhoneGlobals = new PhoneGlobals(this);mPhoneGlobals.onCreate();- /packages/services/Telephony/src/com/android/phone/PhoneGlobals.java
PhoneGlobals.onCreate()主要做了以下工作:
1.初始化 telephony framework
2.實例化各種管理類CallManager,NotificationMgr,PowerManager,KeyguardManager,CallGatewayManager,PhoneInterfaceManager
3.設(shè)置Phone的一些初始化配置,注冊相關(guān)廣播,初始化SimProvider,配置音頻硬件等
其中,各大管理類和各種配置可根據(jù)注釋以及源碼自己查看,這里繼續(xù)解析Phone,即Telephony framework (PhoneFactory.makeDefaultPhones(this));
初始化 telephony 框架
Telephony應用框架層啟動流程
// Initialize the telephony framework 297 PhoneFactory.makeDefaultPhones(this);- /frameworks/opt/telephony/src/java/com/android/internal/telephony/PhoneFactory.java
?1. 創(chuàng)建了 RIL 對象;2. 初始化了?SubscriptionController; 3. 檢查是否是多 SIM 卡
public static void makeDefaultPhone(Context context) {synchronized (sLockProxyPhones) {if (!sMadeDefaults) {sContext = context;// 實例化telephony硬件資源控制接口,這里的硬件資源包括SIM/MODEM/RILTelephonyDevController.create();int retryCount = 0;// 通過嘗試創(chuàng)建地址為"com.android.internal.telephony"的LocalServerSocket來中斷循環(huán)for(;;) {boolean hasException = false;retryCount ++;try {// 使用UNIX域套接字來防止后續(xù)初始化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) {}}}// Phone的狀態(tài)通知器,對外發(fā)出通知,包括通話狀態(tài)/網(wǎng)絡服務狀態(tài)/信號強度/SS(運營商補充服務--呼叫轉(zhuǎn)移等)/網(wǎng)絡小區(qū)信息/數(shù)據(jù)連接等等,// DefaultPhoneNotifier其實就是個中轉(zhuǎn)站,本質(zhì)上各接口都是通過ITelephonyRegistry代理來訪問"telephony.registry"服務sPhoneNotifier = new DefaultPhoneNotifier();// CDMA subscription狀態(tài)管理int cdmaSubscription = CdmaSubscriptionSourceManager.getDefault(context);// 在多SIM模式的情況下,創(chuàng)建兩個Phone,RIL實例,isMultiSimEnabled()函數(shù)檢查它是單SIM還是多SIM模式int numPhones = TelephonyManager.getDefault().getPhoneCount();// 返回設(shè)備是否應使用動態(tài)綁定或靜態(tài)實現(xiàn)(不建議使用)boolean isDynamicBinding = sContext.getResources().getBoolean(com.android.internal.R.bool.config_dynamic_bind_ims);// 獲取默認IMS實現(xiàn)的包名稱String defaultImsPackage = sContext.getResources().getString(com.android.internal.R.string.config_ims_package);// 啟動ImsResolver并綁定到ImsServicessImsResolver = new ImsResolver(sContext, defaultImsPackage, numPhones,isDynamicBinding);sImsResolver.initPopulateCacheAndStartBind();int[] networkModes = new int[numPhones];// 創(chuàng)建Phones數(shù)組,用來存儲Phone實例sPhones = new Phone[numPhones];// 創(chuàng)建RIL數(shù)組,用來存儲RIL實例sCommandsInterfaces = new RIL[numPhones];// TelephonyNetworkFactory是創(chuàng)建網(wǎng)絡代理的工廠,默認網(wǎng)絡代理的評判根據(jù)分數(shù)和能力來進行,也可以通過重載來實現(xiàn)更復雜的計算來評判sTelephonyNetworkFactories = new TelephonyNetworkFactory[numPhones];for (int i = 0; i < numPhones; i++) {// 讀取系統(tǒng)屬性并生成命令接口獲取首選網(wǎng)絡類型。// 初始化網(wǎng)絡模式和RIL,支持幾張卡就初始化幾個RILnetworkModes[i] = RILConstants.PREFERRED_NETWORK_MODE;sCommandsInterfaces[i] = new RIL(context, networkModes[i],cdmaSubscription, i);}// SubscriptionController提供訪問SubscriptionInfo的IPC接口,SubscriptionInfo是framework層對sim卡信息的抽象表示,// 數(shù)據(jù)都存儲在數(shù)據(jù)庫中,比如設(shè)置SIM卡的icon/名稱/號碼,讀取plmn/mccmnc等等SubscriptionController.init(context, sCommandsInterfaces);// 實例化UiccController/assets/images/android/tele/用于訪問UICC卡的相關(guān)信息,通過在RIL中注冊事件監(jiān)聽來實現(xiàn)sUiccController = UiccController.make(context, sCommandsInterfaces);if (context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_TELEPHONY_EUICC)) {sEuiccController = EuiccController.init(context);sEuiccCardController = EuiccCardController.init(context);}// 根據(jù)SIM卡數(shù)量創(chuàng)建Phone實例,Phone實例分為兩種類型GSM和CDMA// 7.0開始沒有CDMAPhone類,把之前的GSMPhone和CDMAPhone合并成了GsmCdmaPhone// 同樣的就有了GsmCdmaCallTracker/GsmCdmaConnectionfor (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());}sPhones[i] = phone;}// 在基類中設(shè)置默認PhonesPhone = sPhones[0];sCommandsInterface = sCommandsInterfaces[0];// 確保我們有一個默認的短信應用程序。 請求將updateIfNeeded設(shè)置為true的應用程序足以配置默認的SMS應用程序。ComponentName componentName =SmsApplication.getDefaultSmsApplication(context, true /* updateIfNeeded */);String packageName = "NONE";if (componentName != null) {packageName = componentName.getPackageName();}// 設(shè)置監(jiān)視器以監(jiān)視SMS程序包的更改SmsApplication.initSmsPackageMonitor(context);sMadeDefaults = true;// SubscriptionInfoUpdater主要監(jiān)聽sim卡的插入/拔出/上鎖/加載等情況sSubInfoRecordUpdater = new SubscriptionInfoUpdater(BackgroundThread.get().getLooper(), context, sPhones, sCommandsInterfaces);SubscriptionController.getInstance().updatePhonesAvailability(sPhones);// 在默認設(shè)置完成后開始監(jiān)控。 在創(chuàng)建ImsPhone之前,必須準備好默認Phone,因為ImsService在打開時可能需要它// 這應該為ImsService的ImsResolver實現(xiàn)初始化多個ImsPhones。for (int i = 0; i < numPhones; i++) {sPhones[i].startMonitoringImsService();}// ITelephonyRegistry提供了訪問通話狀態(tài)/網(wǎng)絡服務狀態(tài)/信號強度/SS(運營商補充服務--呼叫轉(zhuǎn)移等)/網(wǎng)絡小區(qū)信息/數(shù)據(jù)連接等等的接口ITelephonyRegistry tr = ITelephonyRegistry.Stub.asInterface(ServiceManager.getService("telephony.registry"));SubscriptionController sc = SubscriptionController.getInstance();sSubscriptionMonitor = new SubscriptionMonitor(tr, sContext, sc, numPhones);//PhoneSwitcher監(jiān)聽subscription的變化和網(wǎng)絡請求來決定啟用哪個phonesPhoneSwitcher = new PhoneSwitcher(MAX_ACTIVE_PHONES, numPhones,sContext, sc, Looper.myLooper(), tr, sCommandsInterfaces,sPhones);// ProxyController類用于get/set radio相關(guān)的操作sProxyController = ProxyController.getInstance(context, sPhones,sUiccController, sCommandsInterfaces, sPhoneSwitcher);sIntentBroadcaster = IntentBroadcaster.getInstance(context);sNotificationChannelController = new NotificationChannelController(context);// 網(wǎng)絡數(shù)據(jù)連接輔助類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);}}}}總結(jié)一下上面對makeDefaultPhone()方法的分析:
1.初始化各種控制接口SubscriptionController,UiccController,主要負責SIM卡狀態(tài)信息的控制監(jiān)聽
2.根據(jù)SIM卡數(shù)量創(chuàng)建Phone和RIL實例,并且設(shè)置默認Phone和RIL,Phone分為GSM和CDMA兩大種類
3.啟動ImsResolver并綁定到ImsServices
Android中有三種PhoneFactory
1.PhoneFactory.java ——–>用于創(chuàng)建GsmCdmaPhone對象
2.ImsPhoneFactory.java ——–>用于創(chuàng)建ImsPhone對象
3.SipPhoneFactory.java ——–>用于創(chuàng)建SipPhone對象
鏈接
3. Telephony phone?
其中:
其中在 GsmCdmaPhone 構(gòu)造方法會 makeXXXTreacker () 方法
3. 1 GsmCdmaPhone?
GsmCdmaPhone 對象作為Telephony 業(yè)務模型中的關(guān)鍵對象、中心對象,其Java 類的定義和繼承關(guān)系
public abstract class Phone extends Handler implements PhoneInternalInterface {------- 1 ------ public class GsmCdmaPhone extends Phone {------- 2 ------- abstract class ImsPhoneBase extends Phone { public class ImsPhone extends ImsPhoneBase {Phone 抽象類的三個子類
Sip Phone 負責Sip 網(wǎng)絡電話業(yè)務
GsmCdmaPhone 承載CS ( Circuit Switch ,電路交換)域的電信業(yè)務
Ims Phone 承載高清語音通話業(yè)務
關(guān)鍵屬性對象
mCi 是RILJ 對象引用, mDcTracker 是DcTracker 對象引用, mCT 是GsmCdmaCallTracker 對象引用, mSST 是ServiceStateTracker 對象引用
GsmCdmaPhone 關(guān)鍵屬性
GsmCdmaPhone 關(guān)鍵方法
3. 2?GsmCdmaPhone 的Handler 消息處理機制
GsmCdmaPhone 類中的Handler 消息處理機制可分成以下三個大類:
? 基本Handler 消息注冊和響應機制。
? Registrantlist 封裝的Handler 消息運行機制。
? 創(chuàng)建的Message 對象作為RILJ 對象回調(diào)入口。
1.?基本Handler 消息注冊和響應機制
GsmCdmaPhone 類中基本的Handler 消息注冊和響應機制包括兩方面的內(nèi)容:
? 調(diào)用mCi.registerForxxx 方法,向RILJ 對象注冊單個的Handler消息【在 GsmCdmaPhone 的構(gòu)造方法會初始化】
? Handler 對象handleMessage 接收并響應Message 消息
在GsmCdmaPhone 類的構(gòu)造方法的調(diào)用過程中,即加載Telephony 業(yè)務模型的過程中,以調(diào)用mCi.registerForxxx(this, what, null) 的方式向RILJ 對象發(fā)起消息注冊。在GsmCdmaPhone 和Phone類中均重寫了父類的handleMessage 方法,從而響應RILJ 對象發(fā)出的Handler 消息回調(diào)通知。
2.?Registrantlist 封裝的Handler 消息運行機制
在Phone 抽象類中,一共定義了14 個Registrantlist 對象。針對這14 個Registrantlist 對象,分別實現(xiàn)了 RegisterFor×××和unregisterForXXX 方法來完成多個Handler 消息的注冊和取消注冊
3.?創(chuàng)建的Message 對象作為RILJ 對象回調(diào)入口
GsmCdmaPhone 對象在與RILJ 對象的交互過程中創(chuàng)建Message 對象,作為R ILJ 對象的回調(diào)入口。使用這種方式不需要向R ILJ 注冊HanIder 消息,其生命周期很短,僅在一次交互過程中有效,決定了這種交互方式的靈活性。GsmCdmaPhone 對象提供的方法中有一些處理邏輯。首先,創(chuàng)建基于GsmCdmaPhone 對象的Message 對象,然后將此對象作為參數(shù)調(diào)用mCi 對象的方法;其次, RILJ 對象處理完成后,通過Message 對象進行回調(diào);最后,在GsmCdmaPhone 對象的handleMessage 方法中接收和響應Message 對象發(fā)出的Handler 消息。這種Handler 消息處理方式的代碼邏輯詳情如下
?
?
?
總結(jié)
以上是生活随笔為你收集整理的安卓dialer Phone进程【Telephony框架、TeleService】启动过程的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Web Of Science检索页面错误
- 下一篇: 2.4gwifi最高下载速度_2.4gw