赞
踩
无论手机如何改变,功能如何丰富,它最核心最关键的功能依旧是通讯,通讯按现在的情况来说主要就是打电话发短信和上网,Android的通讯框架从上往下可以分为4个部分:
这篇文章主要对Telephony框架做一个小小的概述与总结
整个Framework层的Telephony框架运行在一个叫做Phone(com.android.phone)的进程中。而这个进程是在packages\services\Telephony模块中被创建的(Android 8.0.0平台)。并且该模块在AndroidManifest.xml中有如下关键的声明:
<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"
//从 Android N 开始,在首次开机时,在用户尚未来得及解锁设备之前,设备可直接启动到一种名为 Direct Boot(直接启动)的新模式中。在此模式下,操作系统可以全功能运行,但不允许访问私有应用数据,只能运行经过更新、可支持直接启动功能的应用。
//该属性使得用户在加密状态(未解锁)下能够正常使用一些手机功能,如闹钟,接电话等
>
这个声明创建了一个名叫“PhoneApp”的application,并且确定了他的name、label、icon等信息,而且将该application的persistent属性置为true。那么这个persistent属性的作用是什么呢?这里的persistent属性具备两个关键作用:
+ 该模块会在开机时被系统自动初始化;
+ 该模块所在的进程(com.android.phone)由于任何原因被kill掉之后,都会自动重启(这种情况只针对系统内置app,第三方安装的app不会被重启);
以上两点是十分必要的,他保证/导致了两个效果:
前面介绍了Telephony的框架和进程,那么当发生具体的某个通讯请求,比如打电话、发短信时,该如何操作呢?
这里要引入一个非常重要的对象:Phone对象。该对象可以看做是Telephony框架的实体,可以向该对象发起各种通讯相关的请求,可以说,Phone对象是Telephony整个框架的核心,他负责与RIL层的交互。
而这个Phone对象就是在PhoneApp这个application初始化过程中被创建的。我们就从入口开始,来查看Phone进程的创建过程:
在PhoneApp的onCreate()方法中,会new出PhoneGlobals的对象,并接着调用该对象的onCreate方法:
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的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 (mCM == null) {
// Initialize the telephony framework
// 创建Phone对象
PhoneFactory.makeDefaultPhones(this);
// Start TelephonyDebugService After the default phone is created.
Intent intent = new Intent(this, TelephonyDebugService.class);
startService(intent);
// 初始化CallManager
mCM = CallManager.getInstance();
for (Phone phone : PhoneFactory.getPhones()) {
mCM.registerPhone(phone);
}
// Create the NotificationMgr singleton, which is used to display
// status bar icons and control other status bar behavior.
// 初始化NotificationMgr,用于状态栏通知
notificationMgr = NotificationMgr.init(this);
// If PhoneGlobals has crashed and is being restarted, then restart.
mHandler.sendEmptyMessage(EVENT_RESTART_SIP);
// 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 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.)
// 初始化CallController
callController = CallController.init(this, callLogger, callGatewayManager);
// 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);
// 初始化PhoneInterfaceManager
phoneMgr = PhoneInterfaceManager.init(this, PhoneFactory.getDefaultPhone());
configLoader = CarrierConfigLoader.init(this);
// Create the CallNotifer singleton, which handles
// asynchronous events from the telephony layer (like
// launching the incoming-call UI when an incoming call comes
// in.)
// 初始化CallNotifer, 响铃等动作在这里面完成
notifier = CallNotifier.init(this);
PhoneUtils.registerIccStatus(mHandler, EVENT_SIM_NETWORK_LOCKED);
// 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(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);
registerReceiver(mReceiver, intentFilter);
mCarrierVvmPackageInstalledReceiver.register(this);
//set the default values for the preferences in the phone.
PreferenceManager.setDefaultValues(this, R.xml.network_setting_fragment, 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);
}
// XXX pre-load the SimProvider so that it's ready
resolver.getType(Uri.parse("content://icc/adn"));
// 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(
getContentResolver(),
android.provider.Settings.System.HEARING_AID,
0);
AudioManager audioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
audioManager.setParameter(SettingsConstants.HAC_KEY,
hac == SettingsConstants.HAC_ENABLED
? SettingsConstants.HAC_VAL_ON : SettingsConstants.HAC_VAL_OFF);
}
}
从以上代码可以看出,PhoneGlobals的初始化过程中要先通过PhoneFactory的makeDefaultPhones()方法创建Phone对象,接着完成了一系列与Telephony相关的重要服务的初始化,比如CallManager、NotificationMgr、CallCommandService、PhoneInterfaceManager、CallNotifier等。
我们现在只关心Phone对象的创建过程,也就是PhoneFactory的makeDefaultPhones过程:
public static void makeDefaultPhones(Context context) {
makeDefaultPhone(context);
}
/**
* FIXME replace this with some other way of making these
* instances
*/
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) {
}
}
}
// 创建DefaultPhoneNotifier,负责通知Phone的状态
sPhoneNotifier = new DefaultPhoneNotifier();
int cdmaSubscription = CdmaSubscriptionSourceManager.getDefault(context);
Rlog.i(LOG_TAG, "Cdma Subscription set to " + cdmaSubscription);
/* In case of multi SIM mode two instances of Phone, 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();
// Start ImsResolver and bind to ImsServices.
String defaultImsPackage = sContext.getResources().getString(
com.android.internal.R.string.config_ims_package);
Rlog.i(LOG_TAG, "ImsResolver: defaultImsPackage: " + defaultImsPackage);
sImsResolver = new ImsResolver(sContext, defaultImsPackage, numPhones);
sImsResolver.populateCacheAndStartBind();
// 获取当前网络类型
int[] networkModes = new int[numPhones];
sPhones = new Phone[numPhones];
// 根据网络类型创建RILJ,负责Framework与RIL层的交互
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]));
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()
// 创建UiccController,间接创建UiccCard、UiccCardApplication、IccFileHandler、IccRecords、CatService服务
// (手机中使用的卡SIM,USIM,UIM等统称为:UICC)
sUiccController = UiccController.make(context, sCommandsInterfaces);
// 根据当前Phone类型创建不同的PhoneProxy
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 +
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。