Android的通讯框架从上往下可以分为4个部分:
Modem 这是整个通讯的硬件基础,需要Modem芯片,不同制式需要采用不同的Modem;
RIL 为了适配不同的Modem芯片而抽象出来的中间层,用于将Modem指令转换为Java可用的数据流;
Telephony 这是在Framework层搭建的通讯框架,面向开发者提供操作通讯事务的能力;
Application 这是最上层的应用,直接面向用户,提供拨号、上网、发短信的界面;
Phone进程是通话最主要的进程,通话框架的主体,全称是: package=”com.android.phone”
在packages\services\Telephony的AndroidManifest.xml中,我们可以看到它的定义,它有一个名为“PhoneApp”的application,persistent属性为true,保证了AMS在开机后会自动启动它,即使被杀死也会立即启动。
PhoneApp启动后,会调用onCreate方法,并创建PhoneGlobals,调用它的onCreate方法。
<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">
PhoneGlobals.java packages\services\Telephony\src\com\android\phone
public void onCreate(){
// Initialize the telephony framework
PhoneFactory.makeDefaultPhones(this);
.....
// Create the NotificationMgr singleton, which is used to display
// status bar icons and control other status bar behavior.
notificationMgr = NotificationMgr.init(this);
......
phoneMgr = PhoneInterfaceManager.init(this, PhoneFactory.getDefaultPhone());
// Create the CallNotifier singleton, which handles
// asynchronous events from the telephony layer (like
// launching the incoming-call UI when an incoming call comes
// in.)
notifier = CallNotifier.init(this);
......
}
PhoneFactory.java frameworks\opt\telephony\src\java\com\android\internal\telephony
public static void makeDefaultPhone(Context context) {
//1、创建硬件控制接口,包括modem、sim
TelephonyDevController.create();
// 2、创建Phone状态通知器,通知电话、网络、数据等业务的状态
sPhoneNotifier = telephonyComponentFactory.makeDefaultPhoneNotifier();
int cdmaSubscription = CdmaSubscriptionSourceManager.getDefault(context);
Rlog.i(LOG_TAG, "Cdma Subscription set to " + cdmaSubscription);
//3、获取单卡还是多卡,初始化网络模式、phone和RIL
int numPhones = TelephonyManager.getDefault().getPhoneCount();
// Return whether or not the device should use dynamic binding or the static
// implementation (deprecated)
boolean isDynamicBinding = sContext.getResources().getBoolean(
com.android.internal.R.bool.config_dynamic_bind_ims);
// Get the package name of the default IMS implementation.
String defaultImsPackage = sContext.getResources().getString(
com.android.internal.R.string.config_ims_package);
// Start ImsResolver and bind to ImsServices.
Rlog.i(LOG_TAG, "ImsResolver: defaultImsPackage: " + defaultImsPackage);
sImsResolver = new ImsResolver(sContext, defaultImsPackage, numPhones,
isDynamicBinding);
sImsResolver.initPopulateCacheAndStartBind();
int[] networkModes = new int[numPhones];
sPhones = new Phone[numPhones];
sCommandsInterfaces = new RIL[numPhones];
sTelephonyNetworkFactories = new TelephonyNetworkFactory[numPhones];
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]));
// 4、创建RIL
sCommandsInterfaces[i] =
telephonyComponentFactory.makeRil(context, networkModes[i],
cdmaSubscription, i);
}
Rlog.i(LOG_TAG, "Creating SubscriptionController");
// 5、获取和设置SIM卡相关的信息
SubscriptionController.init(context, sCommandsInterfaces);
telephonyComponentFactory.initRadioManager(context, numPhones, sCommandsInterfaces);
/// M: eMBMS feature
telephonyComponentFactory.initEmbmsAdaptor(context, sCommandsInterfaces);
/// M: eMBMS end
// 6、实例化UiccController,用于访问UICC卡相关信息,通过在RIL中注册事件监听来实现
sUiccController = UiccController.make(context, sCommandsInterfaces);
if (context.getPackageManager().hasSystemFeature(
PackageManager.FEATURE_TELEPHONY_EUICC)) {
sEuiccController = EuiccController.init(context);
sEuiccCardController = EuiccCardController.init(context);
}
for (int i = 0; i < numPhones; i++) {
// 7、根据支持卡的数量和对应网络模式创建phone对象
Phone phone = null;
int phoneType = TelephonyManager.getPhoneType(networkModes[i]);
if (phoneType == PhoneConstants.PHONE_TYPE_GSM) {
phone = telephonyComponentFactory.makePhone(context,
sCommandsInterfaces[i], sPhoneNotifier, i,
PhoneConstants.PHONE_TYPE_GSM,
telephonyComponentFactory.getInstance());
} else if (phoneType == PhoneConstants.PHONE_TYPE_CDMA) {
phone = telephonyComponentFactory.makePhone(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;
}
// 8、监听IMS服务状态
for (int i = 0; i < numPhones; i++) {
sPhones[i].startMonitoringImsService();
}
}
GsmCdmaPhone.java frameworks\opt\telephony\src\java\com\android\internal\telephony
Phone对象创建相关的Tracker
GsmCdmaPhone中有大量和通话有关的方法,如拨号、挂断、接听、拒接等,应用层通过Phone对象,调用这些命令,然后GsmCdmaPhone再把这些命令委派给GsmCdmaCallTracker,GsmCdmaCallTracker进行相应的逻辑判断,进行相应的处理,在将命令下发给RIL对象,RIL对象通过rild进程,发送给modem侧。
public GsmCdmaPhone(Context context, CommandsInterface ci, PhoneNotifier notifier,
boolean unitTestMode, int phoneId, int precisePhoneType,
TelephonyComponentFactory telephonyComponentFactory) {
super(precisePhoneType == PhoneConstants.PHONE_TYPE_GSM ? "GSM" : "CDMA",
notifier, context, ci, unitTestMode, phoneId, telephonyComponentFactory);
// phone type needs to be set before other initialization as other objects rely on it
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);
// 为对应phone创建网络、数据、电话和Tracker,管理相应的业务
mSST = mTelephonyComponentFactory.makeServiceStateTracker(this, this.mCi);
// DcTracker uses SST so needs to be created after it is instantiated
mDcTracker = mTelephonyComponentFactory.makeDcTracker(this);
mCarrerIdentifier = mTelephonyComponentFactory.makeCarrierIdentifier(this);
mSST.registerForNetworkAttached(this, EVENT_REGISTERED_TO_NETWORK, null);
mDeviceStateMonitor = mTelephonyComponentFactory.makeDeviceStateMonitor(this);
}
在initOnce中还在RIL中注册了许多消息,对modem上报的消息进行监听。
protected 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);
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);
mCIM = new CarrierInfoManager();
}
因此,Phone实例就间接地拥有了跟modem交互的能力和上报消息的能力,再加上Phone实例自身就有监听事件的能力,所以Phone的作用就是:
1.注册监听事件,及时上报消息(Call状态变化、Service状态变化、新来电等等)
2.间接地为其他类提供跟modem交互的服务。
其实总结起来phone中比较重要的就是以下三类对象
1.RIL接口
2.Tracker相关类
3.Notifiy相关类