概括
在PhoneFactory 中当要创建的类型是LTE_ON_CDMA_TRUE时这个时候我们的PhoneProxy中要创建的phone将会是CDMALTEPhone。在这种情况下他充当PhoneProxy 所代理的对象,是这个手机的通话和数据链接等基本功能的抽象。
知识要点
构造Phone 对象,注册一些需要监听的事件和一些组件的构造,
//出发点
sProxyPhone = new PhoneProxy(new CDMALTEPhone(context,
sCommandsInterface, sPhoneNotifier)); // sCommandsInterface 是RIL java 和RIL C 通信的接口
// Constructors
public CDMALTEPhone(Context context, CommandsInterface ci, PhoneNotifier notifier) {
super(context, ci, notifier, false); //调用CDMAPhone 的构造函数
m3gppSMS = new GsmSMSDispatcher(this, mSmsStorageMonitor, mSmsUsageMonitor);
}
public CDMAPhone(Context context, CommandsInterface ci, PhoneNotifier notifier,
boolean unitTestMode) {
super(notifier, context, ci, unitTestMode); //调用PhoneBase 的构造函数
initSstIcc();
init(context, notifier);
}
protected void init(Context context, PhoneNotifier notifier) {
mCM.setPhoneType(PhoneConstants.PHONE_TYPE_CDMA); // 设置Phone Type
mCT = new CdmaCallTracker(this);
mCdmaSSM = CdmaSubscriptionSourceManager.getInstance(context, mCM, this,
EVENT_CDMA_SUBSCRIPTION_SOURCE_CHANGED, null);
mSMS = new CdmaSMSDispatcher(this, mSmsStorageMonitor, mSmsUsageMonitor);
mDataConnectionTracker = new CdmaDataConnectionTracker (this); // 构造数据链接的维护者
mRuimPhoneBookInterfaceManager = new RuimPhoneBookInterfaceManager(this);
mRuimSmsInterfaceManager = new RuimSmsInterfaceManager(this, mSMS);
mSubInfo = new PhoneSubInfo(this);
mEriManager = new EriManager(this, context, EriManager.ERI_FROM_XML);
mCM.registerForAvailable(this, EVENT_RADIO_AVAILABLE, null); //监听Radio Available 事件
mCM.registerForOffOrNotAvailable(this, EVENT_RADIO_OFF_OR_NOT_AVAILABLE, null);
mCM.registerForOn(this, EVENT_RADIO_ON, null); //监听 Radio On 事件
mCM.setOnSuppServiceNotification(this, EVENT_SSN, null);
mSST.registerForNetworkAttached(this, EVENT_REGISTERED_TO_NETWORK, null);
mCM.setEmergencyCallbackMode(this, EVENT_EMERGENCY_CALLBACK_MODE_ENTER, null);
PowerManager pm
= (PowerManager) context.getSystemService(Context.POWER_SERVICE);
mWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK,LOG_TAG);
//Change the system setting
SystemProperties.set(TelephonyProperties.CURRENT_ACTIVE_PHONE,
Integer.toString(PhoneConstants.PHONE_TYPE_CDMA));
// This is needed to handle phone process crashes
String inEcm=SystemProperties.get(TelephonyProperties.PROPERTY_INECM_MODE, "false");
mIsPhoneInEcmState = inEcm.equals("true");
if (mIsPhoneInEcmState) {
// Send a message which will invoke handleExitEmergencyCallbackMode
mCM.exitEmergencyCallbackMode(obtainMessage(EVENT_EXIT_EMERGENCY_CALLBACK_RESPONSE));
}
// get the string that specifies the carrier OTA Sp number
mCarrierOtaSpNumSchema = SystemProperties.get(
TelephonyProperties.PROPERTY_OTASP_NUM_SCHEMA,"");
// Sets operator alpha property by retrieving from build-time system property
String operatorAlpha = SystemProperties.get("ro.cdma.home.operator.alpha");
setSystemProperty(PROPERTY_ICC_OPERATOR_ALPHA, operatorAlpha);
// Sets operator numeric property by retrieving from build-time system property
String operatorNumeric = SystemProperties.get(PROPERTY_CDMA_HOME_OPERATOR_NUMERIC);
log("CDMAPhone: init set 'gsm.sim.operator.numeric' to operator='" +
operatorNumeric + "'");
setSystemProperty(PROPERTY_ICC_OPERATOR_NUMERIC, operatorNumeric);
// Sets iso country property by retrieving from build-time system property
setIsoCountryProperty(operatorNumeric);
// Sets current entry in the telephony carrier table
updateCurrentCarrierInProvider(operatorNumeric);
// Notify voicemails.
notifier.notifyMessageWaitingChanged(this);
}
/**
* Constructs a PhoneBase in normal (non-unit test) mode.
*
* @param notifier An instance of DefaultPhoneNotifier,
* @param context Context object from hosting application
* unless unit testing.
* @param ci is CommandsInterface
* @param unitTestMode when true, prevents notifications
* of state change events
*/
protected PhoneBase(PhoneNotifier notifier, Context context, CommandsInterface ci,
boolean unitTestMode) {
this.mNotifier = notifier;
this.mContext = context;
mLooper = Looper.myLooper();
mCM = ci;
setPropertiesByCarrier();
setUnitTestMode(unitTestMode);
SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(context);
mDnsCheckDisabled = sp.getBoolean(DNS_SERVER_CHECK_DISABLED_KEY, false);
mCM.setOnCallRing(this, EVENT_CALL_RING, null);
/* "Voice capable" means that this device supports circuit-switched
* (i.e. voice) phone calls over the telephony network, and is allowed
* to display the in-call UI while a cellular voice call is active.
* This will be false on "data only" devices which can't make voice
* calls and don't support any in-call UI.
*/
mIsVoiceCapable = mContext.getResources().getBoolean(
com.android.internal.R.bool.config_voice_capable);
/**
* Some RIL's don't always send RIL_UNSOL_CALL_RING so it needs
* to be generated locally. Ideally all ring tones should be loops
* and this wouldn't be necessary. But to minimize changes to upper
* layers it is requested that it be generated by lower layers.
*
* By default old phones won't have the property set but do generate
* the RIL_UNSOL_CALL_RING so the default if there is no property is
* true.
*/
mDoesRilSendMultipleCallRing = SystemProperties.getBoolean(
TelephonyProperties.PROPERTY_RIL_SENDS_MULTIPLE_CALL_RING, true);
Log.d(LOG_TAG, "mDoesRilSendMultipleCallRing=" + mDoesRilSendMultipleCallRing);
mCallRingDelay = SystemProperties.getInt(
TelephonyProperties.PROPERTY_CALL_RING_DELAY, 3000);
Log.d(LOG_TAG, "mCallRingDelay=" + mCallRingDelay);
// Initialize device storage and outgoing SMS usage monitors for SMSDispatchers.
mSmsStorageMonitor = new SmsStorageMonitor(this);
mSmsUsageMonitor = new SmsUsageMonitor(context);
mUiccController = UiccController.getInstance(); // 获取sim 卡的单例
mUiccController.registerForIccChanged(this, EVENT_ICC_CHANGED, null); //监听 mIccChangedRegistrants
}
CDMALTEPhone Handler 消息处理机制,CDMALTEPhone 实际上是Handler 的一个子类,和Registrant结合一起完成完成消息异步处理,回掉功能。处理流程比如说EVENT_RADIO_ON消息
protected void init(Context context, PhoneNotifier notifier) {
***********************************************************************
mCM.registerForOn(this, EVENT_RADIO_ON, null); //监听 Radio On 事件, this 代表当前的handler , 按照handler机制会调用该类的handleMessage(Message msg)
***********************************************************************
}
public void dispose() {
synchronized(PhoneProxy.lockForRadioTechnologyChange) {
***********************************************************************
mCM.unregisterForOn(this); //取消监听 Radio On 事件
***********************************************************************
}
}
public void handleMessage(Message msg) {
AsyncResult ar;
Message onComplete;
switch(msg.what) {
case EVENT_RADIO_ON:{ //处理该事件
Log.d(LOG_TAG, "Event EVENT_RADIO_ON Received");
handleCdmaSubscriptionSource(mCdmaSSM.getCdmaSubscriptionSource());
}
break;
}
}