Android4.0(Phone)拨号启动过程分析(三)与Framework层通信

本文深入探讨Android 4.0中PhoneApp的初始化过程,特别是如何与Framework层进行通信。通过分析源码,展示了如何根据不同网络类型创建Phone对象,以及使用向上转型确保安全。同时,通过一个简单的GsmCallTracker线程示例,模拟电话状态变化,以帮助读者理解事件通知流程。核心涉及的技术包括RIL、CommandsInterface和IncallScreen。
摘要由CSDN通过智能技术生成

        由于Android几乎所有的代码都是公开的,如果要对Framework层分析就必需先拿到Framework层的代码,我在前面已经搭建好了ubuntu14.04的环境,下载好了Android4.0的源码,其中也包括了Framework层和Package的代码,导出到宿主机Windows XP中用Source Insight 3.5工具来查看源码,Package中的代码可以导入到Eclipse下查看,我是把frameworks\base整个目录都导入到Source Insight 3.5工程中,可以选择我们需要的目录导入,如frameworks\base\media\tests\contents\media_api目录下有很多音、视频文件,可以只导入frameworks\base\core、frameworks\base\telephony、frameworks\base\services、frameworks\base\include等目录。需要代码的可以到这下载:http://pan.baidu.com/s/1i3KczeX在PhoneApp初始化时,有以下代码

@Override
public void onCreate() {
	//...........
	if (phone == null) {
		// 初始化phone frameworks层
			PhoneFactory.makeDefaultPhones(this);

			// 获取默认的phone对象
			phone = PhoneFactory.getDefaultPhone();

			mCM = CallManager.getInstance();
			mCM.registerPhone(phone);
		//.............
	}
	//...............
}
在应用层的PhoneApp中调用PhoneFactory的静态方法makeDefaultPhones创建一个默认的Phone对象,而framework中采用的是代理模式和工厂模式实现,在makedefaultPhone中
 //***** Class Methods

    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(Phone.class) {
            if (!sMadeDefaults) {
                sLooper = Looper.myLooper();
                sContext = context;

                if (sLooper == null) {
                    throw new RuntimeException(
                        "PhoneFactory.makeDefaultPhone must be called from Looper thread");
                }

                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) {
                        }
                    }
                }

                sPhoneNotifier = new DefaultPhoneNotifier();

                // Get preferred network mode
                int preferredNetworkMode = RILConstants.PREFERRED_NETWORK_MODE;
                if (BaseCommands.getLteOnCdmaModeStatic() == Phone.LTE_ON_CDMA_TRUE) {
                    preferredNetworkMode = Phone.NT_MODE_GLOBAL;
                }
                int networkMode = Settings.Secure.getInt(context.getContentResolver(),
                        Settings.Secure.PREFERRED_NETWORK_MODE, preferredNetworkMode);
                Log.i(LOG_TAG, "Network Mode set to " + Integer.toString(networkMode));

                // Get cdmaSubscription
                // TODO: Change when the ril will provides a way to know at runtime
                //       the configuration, bug 4202572. And the ril issues the
                //       RIL_UNSOL_CDMA_SUBSCRIPTION_SOURCE_CHANGED, bug 4295439.
                int cdmaSubscription;
                int lteOnCdma = BaseCommands.getLteOnCdmaModeStatic();
                switch (lteOnCdma) {
                    case Phone.LTE_ON_CDMA_FALSE:
                        cdmaSubscription = RILConstants.SUBSCRIPTION_FROM_NV;
                        Log.i(LOG_TAG, "lteOnCdma is 0 use SUBSCRIPTION_FROM_NV");
                        break;
                    case Phone.LTE_ON_CDMA_TRUE:
                        cdmaSubscription = RILConstants.SUBSCRIPTION_FROM_RUIM;
                        Log.i(LOG_TAG, "lteOnCdma is 1 use SUBSCRIPTION_FROM_RUIM");
                        break;
                    case Phone.LTE_ON_CDMA_UNKNOWN:
                    default:
                        //Get cdmaSubscription mode from Settings.System
                        cdmaSubscription = Settings.Secure.getInt(context.getContentResolver(),
                                Settings.Secure.PREFERRED_CDMA_SUBSCRIPTION,
                                preferredCdmaSubscription);
               
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值