您的位置:首页 > 移动开发 > Android开发

(M)SIM卡开机流程分析之TelephonyDevController类分析

2017-03-01 15:48 417 查看
查看PhoneFactory.java文件中的makeDefaultPhone方法中有如下代码
// create the telephony device controller.
TelephonyDevController.create();

查看TelephonyDevController.java文件,从google对于这个类的解释来看,

/**
* TelephonyDevController - provides a unified view of the
* telephony hardware resources on a device.
*
* manages the set of HardwareConfig for the framework.
*/这个类应该是一个处理HardwareConfig集合的类
查看其的create方法

public static TelephonyDevController create() {
synchronized (mLock) {
// Leo, 这样做的意思是,这个方法只能够调用一次,如果多次调用的话,就会抛出异常
if (sTelephonyDevController != null) {
throw new RuntimeException("TelephonyDevController already created!?!");
}
sTelephonyDevController = new TelephonyDevController();
return sTelephonyDevController;
}
}从上面这段代码来看,当这个方法第一次被调用的时候,会新建一个TelephonyDevController的对象,而当以后如果再调用的话,会抛出一个异常,因此此方法只能被调用一次
继续查看TelephonyDevController的构造函数

// Leo,构造函数
private TelephonyDevController() {
initFromResource();

// Leo,trimToSize方法的作用是去除ArrayList剩余申请空间
// ArrayList在创建对象的时候,会申请相对较多的空间
mModems.trimToSize();
mSims.trimToSize();
}从其构造函数中可看到,其最重要的方法是调用了initFromResource方法
private void initFromResource() {
Resources resource = Resources.getSystem();
// Leo
String[] hwStrings = resource.getStringArray(
com.android.internal.R.array.config_telephonyHardware);
if (hwStrings != null) {
for (String hwString : hwStrings) {
HardwareConfig hw = new HardwareConfig(hwString);
if (hw != null) {
if (hw.type == HardwareConfig.DEV_HARDWARE_TYPE_MODEM) {
// Leo, 将上述配置文件中的关于modem的数据,添加到mModems中
updateOrInsert(hw, mModems);
} else if (hw.type == HardwareConfig.DEV_HARDWARE_TYPE_SIM) {
// Leo,将上述配置文件中的关于sim的数据,添加到mSims中
updateOrInsert(hw, mSims);
}
}
}
}
}
<!-- an array of "[hardware type],[hardware-uuid],[state],[[hardware-type specific]]"
with, [[hardware-type specific]] in:
- "[[ril-model],[rat],[max-active-voice],[max-active-data],[max-active-standby]]"
for 'modem' hardware
- "[[associated-modem-uuid]]"
for 'sim' hardware.
refer to HardwareConfig in com.android.internal.telephony for specific details/values
those elements can carry.
-->
<string-array translatable="false" name="config_telephonyHardware">
<!-- modem -->
<item>"0,modem,0,0,0,1,1,1"</item>
<!-- sim -->
<item>"1,sim,0,modem"</item>
</string-array>
/**
* hardware configuration update or insert.
*/
private static void updateOrInsert(HardwareConfig hw, ArrayList<HardwareConfig> list) {
int size;
HardwareConfig item;
synchronized (mLock) {
size = list.size();
for (int i = 0 ; i < size ; i++) {
item = list.get(i);
if (item.uuid.compareTo(hw.uuid) == 0) {
if (DBG) logd("updateOrInsert: removing: " + item);
list.remove(i);
}
}
if (DBG) logd("updateOrInsert: inserting: " + hw);
list.add(hw);
}
}
可以看到,其实这个方法只是初始化了mModems和mSims
/**
* {@hide}
*
* hardware configuration information reported by the ril layer and for
* use by the telephone framework.
*
* the hardware configuration is managed by the TelephonyDevController
* (aka: the 'TDC').
*
* the hardware resources are:
* - modem: physical entity providing acces technology.
* - sim: physicaly entity providing a slot interface.
*/
public class HardwareConfig {
......
}也就是说,这个TelephonyDevController类中的create方法,只是初始化了一个TelephonyDevController对象,然后将默认的modem和sim的HardwareConfig对象加入到mModems和mSims中。
接下来看看TelephonyDevController类中还有些其他的方法,从上面我们可以看到TelephonyDevController的构造方法是private的,那么也就是说我们在其他地方无法再次创建其对象了,而只能通过getInstance方法才能获取到其对象

// 确认为单例模式,只能通过先调用create方法后,这个方法才能获取到TelephonyDevController对象
public static TelephonyDevController getInstance() {
synchronized (mLock) {
if (sTelephonyDevController == null) {
throw new RuntimeException("TelephonyDevController not yet created!?!");
}
return sTelephonyDevController;
}
}而从getInstance方法中看到,其只是返回了sTelephonyDevController,所以这个方法一定要在create方法调用后,才能调用,否则就会抛出异常
/**
* each RIL call this interface to register/unregister the unsolicited hardware
* configuration callback data it can provide.
*/
public static void registerRIL(CommandsInterface cmdsIf) {
/* get the current configuration from this ril... */
// Leo,获取当前RIL的HardwareConfig值
cmdsIf.getHardwareConfig(sRilHardwareConfig);
/* ... process it ... */
if (sRilHardwareConfig != null) {
AsyncResult ar = (AsyncResult) sRilHardwareConfig.obj;
if (ar.exception == null) {
// 处理sRilHardwareConfig消息携带的HardwareConfig数据
handleGetHardwareConfigChanged(ar);
}
}
/* and register for async device configuration change. */
cmdsIf.registerForHardwareConfigChanged(sTelephonyDevController, EVENT_HARDWARE_CONFIG_CHANGED, null);
}和RIL建立联系,该方法的参数cmdsIf就是RIL对象,调用了RIL.java类中的getHardwareConfig方法,对于sRilHardwareConfig进行赋值,这个方法到时候在RIL.java文件中分析,若获取到sRilHardwareConfig的值后,则调用handleGetHardwareConfigChanged方法
/**
* hardware configuration changed.
*/
private static void handleGetHardwareConfigChanged(AsyncResult ar) {
if ((ar.exception == null) && (ar.result != null)) {
List hwcfg = (List)ar.result;
for (int i = 0 ; i < hwcfg.size() ; i++) {
HardwareConfig hw = null;

hw = (HardwareConfig) hwcfg.get(i);
if (hw != null) {
if (hw.type == HardwareConfig.DEV_HARDWARE_TYPE_MODEM) {
// Leo,确认mModems中是否包含hw,若不包含,直接添加,若包含,直接跳过
updateOrInsert(hw, mModems);
} else if (hw.type == HardwareConfig.DEV_HARDWARE_TYPE_SIM) {
// Leo,同上述解释
updateOrInsert(hw, mSims);
}
}
}
} else {
/* error detected, ignore. are we missing some real time configutation
* at this point? what to do...
*/
loge("handleGetHardwareConfigChanged - returned an error.");
}
}即将RIL得到的HardwareConfig对象加入到mModems和/或mSims中
之后在RIL.java文件中调用了registerForHardwareConfigChanged方法,这个方法的具体分析,我们在RIL.java文件中再分析,结果是当RIL受到hardwareConfig改变的时候,会发出EVENT_HARDWARE_CONFIG_CHANGED消息,在TelephonyDevController.java文件中进行处理

/**
* handle callbacks from RIL.
*/
public void handleMessage(Message msg) {
AsyncResult ar;
switch (msg.what) {
case EVENT_HARDWARE_CONFIG_CHANGED:
if (DBG) logd("handleMessage: received EVENT_HARDWARE_CONFIG_CHANGED");
ar = (AsyncResult) msg.obj;
handleGetHardwareConfigChanged(ar);
break;
default:
loge("handleMessage: Unknown Event " + msg.what);
}
}

其他方法均是一些获取modem或者sim的方法,在此不一一看了。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  Android