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

查看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);
                    }
                }
            }
        }
    }

    
        
        "0,modem,0,0,0,1,1,1"
        
        "1,sim,0,modem"
    
/**
     * hardware configuration update or insert.
     */
    private static void updateOrInsert(HardwareConfig hw, ArrayList 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的方法,在此不一一看了。



你可能感兴趣的:(SIM卡开机流程分析)