loadSetting(stmt, Settings.Secure.CDMA_CELL_BROADCAST_SMS,
RILConstants.CDMA_CELL_BROADCAST_SMS_DISABLED);
- // Set the preferred cdma subscription to 0 = Subscription from RUIM, when available
- loadSetting(stmt, Settings.Secure.PREFERRED_CDMA_SUBSCRIPTION,
- RILConstants.PREFERRED_CDMA_SUBSCRIPTION);
-
// Don't do this. The SystemServer will initialize ADB_ENABLED from a
// persistent system property instead.
//loadSetting(stmt, Settings.Secure.ADB_ENABLED, 0);
public static final int RADIO_TECHNOLOGY_LTE = 14;
/** @hide */
public static final int RADIO_TECHNOLOGY_HSPAP = 15;
+ /**
+ * GSM radio technology only supports voice. It does not support data.
+ * @hide
+ */
+ public static final int RADIO_TECHNOLOGY_GSM = 16;
/**
* Available registration states for GSM, UMTS and CDMA.
case 15:
rtString = "HSPAP";
break;
+ case 16:
+ rtString = "GSM";
+ break;
default:
rtString = "Unexpected";
Log.w(LOG_TAG, "Unexpected radioTechnology=" + rt);
public int getSystemId() {
return this.mSystemId;
}
+
+ /** @hide */
+ public static boolean isGsm(int radioTechnology) {
+ return radioTechnology == RADIO_TECHNOLOGY_GPRS
+ || radioTechnology == RADIO_TECHNOLOGY_EDGE
+ || radioTechnology == RADIO_TECHNOLOGY_UMTS
+ || radioTechnology == RADIO_TECHNOLOGY_HSDPA
+ || radioTechnology == RADIO_TECHNOLOGY_HSUPA
+ || radioTechnology == RADIO_TECHNOLOGY_HSPA
+ || radioTechnology == RADIO_TECHNOLOGY_LTE
+ || radioTechnology == RADIO_TECHNOLOGY_HSPAP
+ || radioTechnology == RADIO_TECHNOLOGY_GSM;
+ }
+
+ /** @hide */
+ public static boolean isCdma(int radioTechnology) {
+ return radioTechnology == RADIO_TECHNOLOGY_IS95A
+ || radioTechnology == RADIO_TECHNOLOGY_IS95B
+ || radioTechnology == RADIO_TECHNOLOGY_1xRTT
+ || radioTechnology == RADIO_TECHNOLOGY_EVDO_0
+ || radioTechnology == RADIO_TECHNOLOGY_EVDO_A
+ || radioTechnology == RADIO_TECHNOLOGY_EVDO_B
+ || radioTechnology == RADIO_TECHNOLOGY_EHRPD;
+ }
}
//***** Instance Variables
protected Context mContext;
protected RadioState mState = RadioState.RADIO_UNAVAILABLE;
- protected RadioState mSimState = RadioState.RADIO_UNAVAILABLE;
- protected RadioState mRuimState = RadioState.RADIO_UNAVAILABLE;
- protected RadioState mNvState = RadioState.RADIO_UNAVAILABLE;
protected Object mStateMonitor = new Object();
protected RegistrantList mRadioStateChangedRegistrants = new RegistrantList();
protected RegistrantList mAvailRegistrants = new RegistrantList();
protected RegistrantList mOffOrNotAvailRegistrants = new RegistrantList();
protected RegistrantList mNotAvailRegistrants = new RegistrantList();
- protected RegistrantList mSIMReadyRegistrants = new RegistrantList();
- protected RegistrantList mSIMLockedRegistrants = new RegistrantList();
- protected RegistrantList mRUIMReadyRegistrants = new RegistrantList();
- protected RegistrantList mRUIMLockedRegistrants = new RegistrantList();
- protected RegistrantList mNVReadyRegistrants = new RegistrantList();
protected RegistrantList mCallStateRegistrants = new RegistrantList();
protected RegistrantList mVoiceNetworkStateRegistrants = new RegistrantList();
protected RegistrantList mDataNetworkStateRegistrants = new RegistrantList();
- protected RegistrantList mRadioTechnologyChangedRegistrants = new RegistrantList();
+ protected RegistrantList mVoiceRadioTechChangedRegistrants = new RegistrantList();
protected RegistrantList mIccStatusChangedRegistrants = new RegistrantList();
protected RegistrantList mVoicePrivacyOnRegistrants = new RegistrantList();
protected RegistrantList mVoicePrivacyOffRegistrants = new RegistrantList();
return mState;
}
- public RadioState getSimState() {
- return mSimState;
- }
-
- public RadioState getRuimState() {
- return mRuimState;
- }
-
- public RadioState getNvState() {
- return mNvState;
- }
-
-
public void registerForRadioStateChanged(Handler h, int what, Object obj) {
Registrant r = new Registrant (h, what, obj);
}
}
-
- /** Any transition into SIM_READY */
- public void registerForSIMReady(Handler h, int what, Object obj) {
- Registrant r = new Registrant (h, what, obj);
-
- synchronized (mStateMonitor) {
- mSIMReadyRegistrants.add(r);
-
- if (mSimState.isSIMReady()) {
- r.notifyRegistrant(new AsyncResult(null, null, null));
- }
- }
- }
-
- public void unregisterForSIMReady(Handler h) {
- synchronized (mStateMonitor) {
- mSIMReadyRegistrants.remove(h);
- }
- }
-
- /** Any transition into RUIM_READY */
- public void registerForRUIMReady(Handler h, int what, Object obj) {
- Registrant r = new Registrant (h, what, obj);
-
- synchronized (mStateMonitor) {
- mRUIMReadyRegistrants.add(r);
-
- if (mRuimState.isRUIMReady()) {
- r.notifyRegistrant(new AsyncResult(null, null, null));
- }
- }
- }
-
- public void unregisterForRUIMReady(Handler h) {
- synchronized(mStateMonitor) {
- mRUIMReadyRegistrants.remove(h);
- }
- }
-
- /** Any transition into NV_READY */
- public void registerForNVReady(Handler h, int what, Object obj) {
- Registrant r = new Registrant (h, what, obj);
-
- synchronized (mStateMonitor) {
- mNVReadyRegistrants.add(r);
-
- if (mNvState.isNVReady()) {
- r.notifyRegistrant(new AsyncResult(null, null, null));
- }
- }
- }
-
- public void unregisterForNVReady(Handler h) {
- synchronized (mStateMonitor) {
- mNVReadyRegistrants.remove(h);
- }
- }
-
- public void registerForSIMLockedOrAbsent(Handler h, int what, Object obj) {
- Registrant r = new Registrant (h, what, obj);
-
- synchronized (mStateMonitor) {
- mSIMLockedRegistrants.add(r);
-
- if (mSimState == RadioState.SIM_LOCKED_OR_ABSENT) {
- r.notifyRegistrant(new AsyncResult(null, null, null));
- }
- }
- }
-
- public void unregisterForSIMLockedOrAbsent(Handler h) {
- synchronized (mStateMonitor) {
- mSIMLockedRegistrants.remove(h);
- }
- }
-
- public void registerForRUIMLockedOrAbsent(Handler h, int what, Object obj) {
- Registrant r = new Registrant (h, what, obj);
-
- synchronized (mStateMonitor) {
- mRUIMLockedRegistrants.add(r);
-
- if (mRuimState == RadioState.RUIM_LOCKED_OR_ABSENT) {
- r.notifyRegistrant(new AsyncResult(null, null, null));
- }
- }
- }
-
- public void unregisterForRUIMLockedOrAbsent(Handler h) {
- synchronized (mStateMonitor) {
- mRUIMLockedRegistrants.remove(h);
- }
- }
-
public void registerForCallStateChanged(Handler h, int what, Object obj) {
Registrant r = new Registrant (h, what, obj);
mDataNetworkStateRegistrants.remove(h);
}
- public void registerForRadioTechnologyChanged(Handler h, int what, Object obj) {
+ public void registerForVoiceRadioTechChanged(Handler h, int what, Object obj) {
Registrant r = new Registrant (h, what, obj);
- mRadioTechnologyChangedRegistrants.add(r);
+ mVoiceRadioTechChangedRegistrants.add(r);
}
- public void unregisterForRadioTechnologyChanged(Handler h) {
- mRadioTechnologyChangedRegistrants.remove(h);
+ public void unregisterForVoiceRadioTechChanged(Handler h) {
+ mVoiceRadioTechChangedRegistrants.remove(h);
}
public void registerForIccStatusChanged(Handler h, int what, Object obj) {
* This function is called only by RIL.java when receiving unsolicited
* RIL_UNSOL_RESPONSE_RADIO_STATE_CHANGED
*
- * RadioState has 5 values : RADIO_OFF, RADIO_UNAVAILABLE, SIM_NOT_READY,
- * SIM_LOCKED_OR_ABSENT, and SIM_READY.
+ * RadioState has 3 values : RADIO_OFF, RADIO_UNAVAILABLE, RADIO_ON.
*
* @param newState new RadioState decoded from RIL_UNSOL_RADIO_STATE_CHANGED
*/
return;
}
- // FIXME: Use Constants or Enums
- if(mState.getType() == 0) {
- mSimState = mState;
- mRuimState = mState;
- mNvState = mState;
- }
- else if (mState.getType() == 1) {
- mSimState = mState;
- }
- else if (mState.getType() == 2) {
- mRuimState = mState;
- }
- else if (mState.getType() == 3) {
- mNvState = mState;
- }
-
mRadioStateChangedRegistrants.notifyRegistrants();
if (mState.isAvailable() && !oldState.isAvailable()) {
mNotAvailRegistrants.notifyRegistrants();
}
- if (mState.isSIMReady() && !oldState.isSIMReady()) {
- Log.d(LOG_TAG,"Notifying: SIM ready");
- mSIMReadyRegistrants.notifyRegistrants();
- }
-
- if (mState == RadioState.SIM_LOCKED_OR_ABSENT) {
- Log.d(LOG_TAG,"Notifying: SIM locked or absent");
- mSIMLockedRegistrants.notifyRegistrants();
- }
-
- if (mState.isRUIMReady() && !oldState.isRUIMReady()) {
- Log.d(LOG_TAG,"Notifying: RUIM ready");
- mRUIMReadyRegistrants.notifyRegistrants();
- }
-
- if (mState == RadioState.RUIM_LOCKED_OR_ABSENT) {
- Log.d(LOG_TAG,"Notifying: RUIM locked or absent");
- mRUIMLockedRegistrants.notifyRegistrants();
- }
- if (mState.isNVReady() && !oldState.isNVReady()) {
- Log.d(LOG_TAG,"Notifying: NV ready");
- mNVReadyRegistrants.notifyRegistrants();
- }
-
if (mState.isOn() && !oldState.isOn()) {
Log.d(LOG_TAG,"Notifying: Radio On");
mOnRegistrants.notifyRegistrants();
Log.d(LOG_TAG,"Notifying: radio off or not available");
mOffOrNotAvailRegistrants.notifyRegistrants();
}
-
- /* Radio Technology Change events
- * NOTE: isGsm and isCdma have no common states in RADIO_OFF or RADIO_UNAVAILABLE; the
- * current phone is determined by mPhoneType
- * NOTE: at startup no phone have been created and the RIL determines the mPhoneType
- * looking based on the networkMode set by the PhoneFactory in the constructor
- */
-
- if (mState.isGsm() && oldState.isCdma()) {
- Log.d(LOG_TAG,"Notifying: radio technology change CDMA to GSM");
- mRadioTechnologyChangedRegistrants.notifyRegistrants();
- }
-
- if (mState.isGsm() && !oldState.isOn() && (mPhoneType == Phone.PHONE_TYPE_CDMA)) {
- Log.d(LOG_TAG,"Notifying: radio technology change CDMA OFF to GSM");
- mRadioTechnologyChangedRegistrants.notifyRegistrants();
- }
-
- if (mState.isCdma() && oldState.isGsm()) {
- Log.d(LOG_TAG,"Notifying: radio technology change GSM to CDMA");
- mRadioTechnologyChangedRegistrants.notifyRegistrants();
- }
-
- if (mState.isCdma() && !oldState.isOn() && (mPhoneType == Phone.PHONE_TYPE_GSM)) {
- Log.d(LOG_TAG,"Notifying: radio technology change GSM OFF to CDMA");
- mRadioTechnologyChangedRegistrants.notifyRegistrants();
- }
}
}
import android.os.Message;
import android.os.Handler;
+import android.util.Log;
/**
* {@hide}
*/
public interface CommandsInterface {
enum RadioState {
- RADIO_OFF(0), /* Radio explictly powered off (eg CFUN=0) */
- RADIO_UNAVAILABLE(0), /* Radio unavailable (eg, resetting or not booted) */
- SIM_NOT_READY(1), /* Radio is on, but the SIM interface is not ready */
- SIM_LOCKED_OR_ABSENT(1), /* SIM PIN locked, PUK required, network
- personalization, or SIM absent */
- SIM_READY(1), /* Radio is on and SIM interface is available */
- RUIM_NOT_READY(2), /* Radio is on, but the RUIM interface is not ready */
- RUIM_READY(2), /* Radio is on and the RUIM interface is available */
- RUIM_LOCKED_OR_ABSENT(2), /* RUIM PIN locked, PUK required, network
- personalization locked, or RUIM absent */
- NV_NOT_READY(3), /* Radio is on, but the NV interface is not available */
- NV_READY(3); /* Radio is on and the NV interface is available */
+ RADIO_OFF, /* Radio explicitly powered off (eg CFUN=0) */
+ RADIO_UNAVAILABLE, /* Radio unavailable (eg, resetting or not booted) */
+ RADIO_ON; /* Radio is on */
public boolean isOn() /* and available...*/ {
- return this == SIM_NOT_READY
- || this == SIM_LOCKED_OR_ABSENT
- || this == SIM_READY
- || this == RUIM_NOT_READY
- || this == RUIM_READY
- || this == RUIM_LOCKED_OR_ABSENT
- || this == NV_NOT_READY
- || this == NV_READY;
- }
- private int stateType;
- private RadioState (int type) {
- stateType = type;
- }
-
- public int getType() {
- return stateType;
+ return this == RADIO_ON;
}
public boolean isAvailable() {
return this != RADIO_UNAVAILABLE;
}
-
- public boolean isSIMReady() {
- return this == SIM_READY;
- }
-
- public boolean isRUIMReady() {
- return this == RUIM_READY;
- }
-
- public boolean isNVReady() {
- return this == NV_READY;
- }
-
- public boolean isGsm() {
- if (BaseCommands.getLteOnCdmaModeStatic() == Phone.LTE_ON_CDMA_TRUE) {
- return false;
- } else {
- return this == SIM_NOT_READY
- || this == SIM_LOCKED_OR_ABSENT
- || this == SIM_READY;
- }
- }
-
- public boolean isCdma() {
- if (BaseCommands.getLteOnCdmaModeStatic() == Phone.LTE_ON_CDMA_TRUE) {
- return true;
- } else {
- return this == RUIM_NOT_READY
- || this == RUIM_READY
- || this == RUIM_LOCKED_OR_ABSENT
- || this == NV_NOT_READY
- || this == NV_READY;
- }
- }
}
//***** Constants
static final int CDMA_SMS_FAIL_CAUSE_ENCODING_PROBLEM = 96;
//***** Methods
-
RadioState getRadioState();
- RadioState getSimState();
- RadioState getRuimState();
- RadioState getNvState();
+
+ void getVoiceRadioTechnology(Message result);
/**
* Fires on any RadioState transition
void registerForRadioStateChanged(Handler h, int what, Object obj);
void unregisterForRadioStateChanged(Handler h);
+ void registerForVoiceRadioTechChanged(Handler h, int what, Object obj);
+ void unregisterForVoiceRadioTechChanged(Handler h);
+
/**
* Fires on any transition into RadioState.isOn()
* Fires immediately if currently in that state
void unregisterForOffOrNotAvailable(Handler h);
/**
- * Fires on any transition into SIM_READY
- * Fires immediately if if currently in that state
- * In general, actions should be idempotent. State may change
- * before event is received.
+ * Fires on any change in ICC status
*/
- void registerForSIMReady(Handler h, int what, Object obj);
- void unregisterForSIMReady(Handler h);
-
- /** Any transition into SIM_LOCKED_OR_ABSENT */
- void registerForSIMLockedOrAbsent(Handler h, int what, Object obj);
- void unregisterForSIMLockedOrAbsent(Handler h);
-
void registerForIccStatusChanged(Handler h, int what, Object obj);
void unregisterForIccStatusChanged(Handler h);
void registerForDataNetworkStateChanged(Handler h, int what, Object obj);
void unregisterForDataNetworkStateChanged(Handler h);
- void registerForRadioTechnologyChanged(Handler h, int what, Object obj);
- void unregisterForRadioTechnologyChanged(Handler h);
- void registerForNVReady(Handler h, int what, Object obj);
- void unregisterForNVReady(Handler h);
- void registerForRUIMLockedOrAbsent(Handler h, int what, Object obj);
- void unregisterForRUIMLockedOrAbsent(Handler h);
-
/** InCall voice privacy notifications */
void registerForInCallVoicePrivacyOn(Handler h, int what, Object obj);
void unregisterForInCallVoicePrivacyOn(Handler h);
void unregisterForInCallVoicePrivacyOff(Handler h);
/**
- * Fires on any transition into RUIM_READY
- * Fires immediately if if currently in that state
- * In general, actions should be idempotent. State may change
- * before event is received.
- */
- void registerForRUIMReady(Handler h, int what, Object obj);
- void unregisterForRUIMReady(Handler h);
-
- /**
* unlike the register* methods, there's only one new 3GPP format SMS handler.
* if you need to unregister, you should also tell the radio to stop
* sending SMS's to you (via AT+CNMI)
protected static final int EVENT_DO_RECOVERY = BASE + 18;
protected static final int EVENT_APN_CHANGED = BASE + 19;
protected static final int EVENT_CDMA_DATA_DETACHED = BASE + 20;
- protected static final int EVENT_NV_READY = BASE + 21;
+ protected static final int EVENT_CDMA_SUBSCRIPTION_SOURCE_CHANGED = BASE + 21;
protected static final int EVENT_PS_RESTRICT_ENABLED = BASE + 22;
protected static final int EVENT_PS_RESTRICT_DISABLED = BASE + 23;
public static final int EVENT_CLEAN_UP_CONNECTION = BASE + 24;
import com.android.internal.telephony.PhoneBase;
import com.android.internal.telephony.CommandsInterface.RadioState;
import com.android.internal.telephony.gsm.SIMRecords;
-
+import com.android.internal.telephony.cdma.CdmaSubscriptionSourceManager;
import android.os.SystemProperties;
import com.android.internal.R;
private IccCardStatus mIccCardStatus = null;
protected State mState = null;
+ private final Object mStateMonitor = new Object();
+
+ protected boolean is3gpp = true;
+ protected boolean isSubscriptionFromIccCard = true;
+ protected CdmaSubscriptionSourceManager mCdmaSSM = null;
protected PhoneBase mPhone;
private RegistrantList mAbsentRegistrants = new RegistrantList();
private RegistrantList mPinLockedRegistrants = new RegistrantList();
private RegistrantList mNetworkLockedRegistrants = new RegistrantList();
+ protected RegistrantList mReadyRegistrants = new RegistrantList();
+ protected RegistrantList mRuimReadyRegistrants = new RegistrantList();
private boolean mDesiredPinLocked;
private boolean mDesiredFdnEnabled;
static public final String INTENT_VALUE_ABSENT_ON_PERM_DISABLED = "PERM_DISABLED";
- protected static final int EVENT_ICC_LOCKED_OR_ABSENT = 1;
+ protected static final int EVENT_ICC_LOCKED = 1;
private static final int EVENT_GET_ICC_STATUS_DONE = 2;
protected static final int EVENT_RADIO_OFF_OR_NOT_AVAILABLE = 3;
private static final int EVENT_PINPUK_DONE = 4;
private static final int EVENT_ICC_STATUS_CHANGED = 12;
private static final int EVENT_CARD_REMOVED = 13;
private static final int EVENT_CARD_ADDED = 14;
+ protected static final int EVENT_CDMA_SUBSCRIPTION_SOURCE_CHANGED = 15;
+ protected static final int EVENT_RADIO_ON = 16;
/*
UNKNOWN is a transient state, for example, after uesr inputs ICC pin under
*/
case RADIO_OFF:
case RADIO_UNAVAILABLE:
- case SIM_NOT_READY:
- case RUIM_NOT_READY:
return State.UNKNOWN;
- case SIM_LOCKED_OR_ABSENT:
- case RUIM_LOCKED_OR_ABSENT:
- //this should be transient-only
- return State.UNKNOWN;
- case SIM_READY:
- case RUIM_READY:
- case NV_READY:
- return State.READY;
- case NV_NOT_READY:
- return State.ABSENT;
+ default:
+ if (!is3gpp && !isSubscriptionFromIccCard) {
+ // CDMA can get subscription from NV. In that case,
+ // subscription is ready as soon as Radio is ON.
+ return State.READY;
+ }
}
} else {
return mState;
}
- Log.e(mLogTag, "IccCard.getState(): case should never be reached");
return State.UNKNOWN;
}
public IccCard(PhoneBase phone, String logTag, Boolean dbg) {
mPhone = phone;
+ mPhone.mCM.registerForOffOrNotAvailable(mHandler, EVENT_RADIO_OFF_OR_NOT_AVAILABLE, null);
+ mPhone.mCM.registerForOn(mHandler, EVENT_RADIO_ON, null);
mPhone.mCM.registerForIccStatusChanged(mHandler, EVENT_ICC_STATUS_CHANGED, null);
mLogTag = logTag;
mDbg = dbg;
public void dispose() {
mPhone.mCM.unregisterForIccStatusChanged(mHandler);
+ mPhone.mCM.unregisterForOffOrNotAvailable(mHandler);
+ mPhone.mCM.unregisterForOn(mHandler);
}
protected void finalize() {
mPinLockedRegistrants.remove(h);
}
+ public void registerForReady(Handler h, int what, Object obj) {
+ Registrant r = new Registrant (h, what, obj);
+
+ synchronized (mStateMonitor) {
+ mReadyRegistrants.add(r);
+
+ if (getState() == State.READY) {
+ r.notifyRegistrant(new AsyncResult(null, null, null));
+ }
+ }
+ }
+
+ public void unregisterForReady(Handler h) {
+ synchronized (mStateMonitor) {
+ mReadyRegistrants.remove(h);
+ }
+ }
+
+ public State getRuimState() {
+ if(mIccCardStatus != null) {
+ return getAppState(mIccCardStatus.getCdmaSubscriptionAppIndex());
+ } else {
+ return State.UNKNOWN;
+ }
+ }
+
+ public void registerForRuimReady(Handler h, int what, Object obj) {
+ Registrant r = new Registrant (h, what, obj);
+
+ synchronized (mStateMonitor) {
+ mRuimReadyRegistrants.add(r);
+
+ if (getState() == State.READY && getRuimState() == State.READY ) {
+ r.notifyRegistrant(new AsyncResult(null, null, null));
+ }
+ }
+ }
+
+ public void unregisterForRuimReady(Handler h) {
+ synchronized (mStateMonitor) {
+ mRuimReadyRegistrants.remove(h);
+ }
+ }
/**
* Supply the ICC PIN to the ICC
boolean isIccCardAdded;
State oldState, newState;
+ State oldRuimState = getRuimState();
oldState = mState;
mIccCardStatus = newCardStatus;
newState = getIccCardState();
- mState = newState;
- updateStateProperty();
+ synchronized (mStateMonitor) {
+ mState = newState;
+ updateStateProperty();
+ if (oldState != State.READY && newState == State.READY) {
+ mHandler.sendMessage(mHandler.obtainMessage(EVENT_ICC_READY));
+ mReadyRegistrants.notifyRegistrants();
+ } else if (newState.isPinLocked()) {
+ mHandler.sendMessage(mHandler.obtainMessage(EVENT_ICC_LOCKED));
+ }
+ if (oldRuimState != State.READY && getRuimState() == State.READY) {
+ mRuimReadyRegistrants.notifyRegistrants();
+ }
+ }
transitionedIntoPinLocked = (
(oldState != State.PIN_REQUIRED && newState == State.PIN_REQUIRED)
updateStateProperty();
broadcastIccStateChangedIntent(INTENT_VALUE_ICC_NOT_READY, null);
break;
- case EVENT_ICC_READY:
- //TODO: put facility read in SIM_READY now, maybe in REG_NW
+ case EVENT_RADIO_ON:
+ if (!is3gpp) {
+ handleCdmaSubscriptionSource();
+ }
mPhone.mCM.getIccCardStatus(obtainMessage(EVENT_GET_ICC_STATUS_DONE));
- mPhone.mCM.queryFacilityLock (
- CommandsInterface.CB_FACILITY_BA_SIM, "", serviceClassX,
- obtainMessage(EVENT_QUERY_FACILITY_LOCK_DONE));
- mPhone.mCM.queryFacilityLock (
- CommandsInterface.CB_FACILITY_BA_FD, "", serviceClassX,
- obtainMessage(EVENT_QUERY_FACILITY_FDN_DONE));
break;
- case EVENT_ICC_LOCKED_OR_ABSENT:
- mPhone.mCM.getIccCardStatus(obtainMessage(EVENT_GET_ICC_STATUS_DONE));
- mPhone.mCM.queryFacilityLock (
- CommandsInterface.CB_FACILITY_BA_SIM, "", serviceClassX,
- obtainMessage(EVENT_QUERY_FACILITY_LOCK_DONE));
+ case EVENT_CDMA_SUBSCRIPTION_SOURCE_CHANGED:
+ handleCdmaSubscriptionSource();
+ break;
+ case EVENT_ICC_READY:
+ if(isSubscriptionFromIccCard) {
+ mPhone.mCM.queryFacilityLock (
+ CommandsInterface.CB_FACILITY_BA_SIM, "", serviceClassX,
+ obtainMessage(EVENT_QUERY_FACILITY_LOCK_DONE));
+ mPhone.mCM.queryFacilityLock (
+ CommandsInterface.CB_FACILITY_BA_FD, "", serviceClassX,
+ obtainMessage(EVENT_QUERY_FACILITY_FDN_DONE));
+ }
break;
+ case EVENT_ICC_LOCKED:
+ mPhone.mCM.queryFacilityLock (
+ CommandsInterface.CB_FACILITY_BA_SIM, "", serviceClassX,
+ obtainMessage(EVENT_QUERY_FACILITY_LOCK_DONE));
+ break;
case EVENT_GET_ICC_STATUS_DONE:
ar = (AsyncResult)msg.obj;
}
};
+ private void handleCdmaSubscriptionSource() {
+ if(mCdmaSSM != null) {
+ int newSubscriptionSource = mCdmaSSM.getCdmaSubscriptionSource();
+
+ Log.d(mLogTag, "Received Cdma subscription source: " + newSubscriptionSource);
+
+ boolean isNewSubFromRuim =
+ (newSubscriptionSource == CdmaSubscriptionSourceManager.SUBSCRIPTION_FROM_RUIM);
+
+ if (isNewSubFromRuim != isSubscriptionFromIccCard) {
+ isSubscriptionFromIccCard = isNewSubFromRuim;
+ // Parse the Stored IccCardStatus Message to set mState correctly.
+ handleIccCardStatus(mIccCardStatus);
+ }
+ }
+ }
+
public State getIccCardState() {
+ if(!is3gpp && !isSubscriptionFromIccCard) {
+ // CDMA can get subscription from NV. In that case,
+ // subscription is ready as soon as Radio is ON.
+ return State.READY;
+ }
+
if (mIccCardStatus == null) {
Log.e(mLogTag, "[IccCard] IccCardStatus is null");
return IccCard.State.ABSENT;
RadioState currentRadioState = mPhone.mCM.getRadioState();
// check radio technology
if( currentRadioState == RadioState.RADIO_OFF ||
- currentRadioState == RadioState.RADIO_UNAVAILABLE ||
- currentRadioState == RadioState.SIM_NOT_READY ||
- currentRadioState == RadioState.RUIM_NOT_READY ||
- currentRadioState == RadioState.NV_NOT_READY ||
- currentRadioState == RadioState.NV_READY) {
+ currentRadioState == RadioState.RADIO_UNAVAILABLE) {
return IccCard.State.NOT_READY;
}
- if( currentRadioState == RadioState.SIM_LOCKED_OR_ABSENT ||
- currentRadioState == RadioState.SIM_READY ||
- currentRadioState == RadioState.RUIM_LOCKED_OR_ABSENT ||
- currentRadioState == RadioState.RUIM_READY) {
-
+ if( currentRadioState == RadioState.RADIO_ON ) {
State csimState =
getAppState(mIccCardStatus.getCdmaSubscriptionAppIndex());
State usimState =
}
// check for CDMA radio technology
- if (currentRadioState == RadioState.RUIM_LOCKED_OR_ABSENT ||
- currentRadioState == RadioState.RUIM_READY) {
+ if (!is3gpp) {
return csimState;
}
return usimState;
* @return an interface to the UsimServiceTable record, or null if not available
*/
UsimServiceTable getUsimServiceTable();
+
+ /**
+ * Unregister from all events it registered for and dispose objects
+ * created by this object.
+ */
+ void dispose();
+
+ /**
+ * Remove references to external object stored in this object.
+ */
+ void removeReferences();
}
protected static final int EVENT_SET_ENHANCED_VP = 24;
protected static final int EVENT_EMERGENCY_CALLBACK_MODE_ENTER = 25;
protected static final int EVENT_EXIT_EMERGENCY_CALLBACK_RESPONSE = 26;
+ protected static final int EVENT_CDMA_SUBSCRIPTION_SOURCE_CHANGED = 27;
// Key used to read/write current CLIR setting
public static final String CLIR_KEY = "clir_key";
public void removeReferences() {
mSmsStorageMonitor = null;
mSmsUsageMonitor = null;
+ mSMS = null;
+ mIccRecords = null;
+ mIccCard = null;
+ mDataConnectionTracker = null;
}
/**
import com.android.internal.telephony.cdma.CDMAPhone;
import com.android.internal.telephony.cdma.CDMALTEPhone;
+import com.android.internal.telephony.cdma.CdmaSubscriptionSourceManager;
import com.android.internal.telephony.gsm.GSMPhone;
import com.android.internal.telephony.sip.SipPhone;
import com.android.internal.telephony.sip.SipPhoneFactory;
static private Looper sLooper;
static private Context sContext;
- static final int preferredCdmaSubscription = RILConstants.PREFERRED_CDMA_SUBSCRIPTION;
+ static final int preferredCdmaSubscription =
+ CdmaSubscriptionSourceManager.PREFERRED_CDMA_SUBSCRIPTION;
//***** Class Methods
int lteOnCdma = BaseCommands.getLteOnCdmaModeStatic();
switch (lteOnCdma) {
case Phone.LTE_ON_CDMA_FALSE:
- cdmaSubscription = RILConstants.SUBSCRIPTION_FROM_NV;
+ cdmaSubscription = CdmaSubscriptionSourceManager.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;
+ cdmaSubscription = CdmaSubscriptionSourceManager.SUBSCRIPTION_FROM_RUIM;
Log.i(LOG_TAG, "lteOnCdma is 1 use SUBSCRIPTION_FROM_RUIM");
break;
case Phone.LTE_ON_CDMA_UNKNOWN:
import android.content.Intent;
import android.net.LinkCapabilities;
import android.net.LinkProperties;
+import android.os.AsyncResult;
import android.os.Handler;
import android.os.Message;
import android.os.SystemProperties;
import com.android.internal.telephony.gsm.UsimServiceTable;
import com.android.internal.telephony.ims.IsimRecords;
import com.android.internal.telephony.test.SimulatedRadioControl;
+import com.android.internal.telephony.CallManager;
import java.util.List;
public final static Object lockForRadioTechnologyChange = new Object();
private Phone mActivePhone;
- private String mOutgoingPhone;
private CommandsInterface mCommandsInterface;
private IccSmsInterfaceManagerProxy mIccSmsInterfaceManagerProxy;
private IccPhoneBookInterfaceManagerProxy mIccPhoneBookInterfaceManagerProxy;
private boolean mResetModemOnRadioTechnologyChange = false;
- private static final int EVENT_RADIO_TECHNOLOGY_CHANGED = 1;
+ private int mRilVersion;
+
+ private static final int EVENT_VOICE_RADIO_TECH_CHANGED = 1;
+ private static final int EVENT_RADIO_ON = 2;
+ private static final int EVENT_REQUEST_VOICE_RADIO_TECH_DONE = 3;
+ private static final int EVENT_RIL_CONNECTED = 4;
+
private static final String LOG_TAG = "PHONE";
//***** Class Methods
phone.getIccPhoneBookInterfaceManager());
mPhoneSubInfoProxy = new PhoneSubInfoProxy(phone.getPhoneSubInfo());
mCommandsInterface = ((PhoneBase)mActivePhone).mCM;
- mCommandsInterface.registerForRadioTechnologyChanged(
- this, EVENT_RADIO_TECHNOLOGY_CHANGED, null);
+
+ mCommandsInterface.registerForRilConnected(this, EVENT_RIL_CONNECTED, null);
+ mCommandsInterface.registerForOn(this, EVENT_RADIO_ON, null);
+ mCommandsInterface.registerForVoiceRadioTechChanged(
+ this, EVENT_VOICE_RADIO_TECH_CHANGED, null);
}
@Override
public void handleMessage(Message msg) {
+ AsyncResult ar = (AsyncResult) msg.obj;
switch(msg.what) {
- case EVENT_RADIO_TECHNOLOGY_CHANGED:
- //switch Phone from CDMA to GSM or vice versa
- mOutgoingPhone = mActivePhone.getPhoneName();
- logd("Switching phone from " + mOutgoingPhone + "Phone to " +
- (mOutgoingPhone.equals("GSM") ? "CDMAPhone" : "GSMPhone") );
- boolean oldPowerState = false; // old power state to off
- if (mResetModemOnRadioTechnologyChange) {
- if (mCommandsInterface.getRadioState().isOn()) {
- oldPowerState = true;
- logd("Setting Radio Power to Off");
- mCommandsInterface.setRadioPower(false, null);
- }
+ case EVENT_RADIO_ON:
+ /* Proactively query voice radio technologies */
+ mCommandsInterface.getVoiceRadioTechnology(
+ this.obtainMessage(EVENT_REQUEST_VOICE_RADIO_TECH_DONE));
+ break;
+
+ case EVENT_RIL_CONNECTED:
+ if (ar.exception == null && ar.result != null) {
+ mRilVersion = (Integer) ar.result;
+ } else {
+ logd("Unexpected exception on EVENT_RIL_CONNECTED");
+ mRilVersion = -1;
}
+ break;
- if(mOutgoingPhone.equals("GSM")) {
- logd("Make a new CDMAPhone and destroy the old GSMPhone.");
+ case EVENT_VOICE_RADIO_TECH_CHANGED:
+ case EVENT_REQUEST_VOICE_RADIO_TECH_DONE:
- ((GSMPhone)mActivePhone).dispose();
- Phone oldPhone = mActivePhone;
+ if (ar.exception == null) {
+ if ((ar.result != null) && (((int[]) ar.result).length != 0)) {
+ int newVoiceTech = ((int[]) ar.result)[0];
+ updatePhoneObject(newVoiceTech);
+ } else {
+ loge("Voice Radio Technology event " + msg.what + " has no tech!");
+ }
+ } else {
+ loge("Voice Radio Technology event " + msg.what + " exception!" + ar.exception);
+ }
+ break;
- //Give the garbage collector a hint to start the garbage collection asap
- // NOTE this has been disabled since radio technology change could happen during
- // e.g. a multimedia playing and could slow the system. Tests needs to be done
- // to see the effects of the GC call here when system is busy.
- //System.gc();
+ default:
+ loge("Error! This handler was not registered for this message type. Message: "
+ + msg.what);
+ break;
+ }
+ super.handleMessage(msg);
+ }
- mActivePhone = PhoneFactory.getCdmaPhone();
- ((GSMPhone)oldPhone).removeReferences();
- oldPhone = null;
- } else {
- logd("Make a new GSMPhone and destroy the old CDMAPhone.");
+ private static void logd(String msg) {
+ Log.d(LOG_TAG, "[PhoneProxy] " + msg);
+ }
- ((CDMAPhone)mActivePhone).dispose();
- //mActivePhone = null;
- Phone oldPhone = mActivePhone;
+ private void logw(String msg) {
+ Log.w(LOG_TAG, "[PhoneProxy] " + msg);
+ }
- // Give the GC a hint to start the garbage collection asap
- // NOTE this has been disabled since radio technology change could happen during
- // e.g. a multimedia playing and could slow the system. Tests needs to be done
- // to see the effects of the GC call here when system is busy.
- //System.gc();
+ private void loge(String msg) {
+ Log.e(LOG_TAG, "[PhoneProxy] " + msg);
+ }
- mActivePhone = PhoneFactory.getGsmPhone();
- ((CDMAPhone)oldPhone).removeReferences();
- oldPhone = null;
+ private void updatePhoneObject(int newVoiceRadioTech) {
+
+ if (mActivePhone != null) {
+ if(mRilVersion == 6 && getLteOnCdmaMode() == Phone.LTE_ON_CDMA_TRUE) {
+ /*
+ * On v6 RIL, when LTE_ON_CDMA is TRUE, always create CDMALTEPhone
+ * irrespective of the voice radio tech reported.
+ */
+ if (mActivePhone.getPhoneType() == PHONE_TYPE_CDMA) {
+ logd("LTE ON CDMA property is set. Use CDMA Phone" +
+ " newVoiceRadioTech = " + newVoiceRadioTech +
+ " Active Phone = " + mActivePhone.getPhoneName());
+ return;
+ } else {
+ logd("LTE ON CDMA property is set. Switch to CDMALTEPhone" +
+ " newVoiceRadioTech = " + newVoiceRadioTech +
+ " Active Phone = " + mActivePhone.getPhoneName());
+ newVoiceRadioTech = ServiceState.RADIO_TECHNOLOGY_1xRTT;
+ }
+ } else {
+ if ((ServiceState.isCdma(newVoiceRadioTech) &&
+ mActivePhone.getPhoneType() == PHONE_TYPE_CDMA) ||
+ (ServiceState.isGsm(newVoiceRadioTech) &&
+ mActivePhone.getPhoneType() == PHONE_TYPE_GSM)) {
+ // Nothing changed. Keep phone as it is.
+ logd("Ignoring voice radio technology changed message." +
+ " newVoiceRadioTech = " + newVoiceRadioTech +
+ " Active Phone = " + mActivePhone.getPhoneName());
+ return;
+ }
}
+ }
+
+ if (newVoiceRadioTech == ServiceState.RADIO_TECHNOLOGY_UNKNOWN) {
+ // We need some voice phone object to be active always, so never
+ // delete the phone without anything to replace it with!
+ logd("Ignoring voice radio technology changed message. newVoiceRadioTech = Unknown."
+ + " Active Phone = " + mActivePhone.getPhoneName());
+ return;
+ }
- if (mResetModemOnRadioTechnologyChange) {
- logd("Resetting Radio");
- mCommandsInterface.setRadioPower(oldPowerState, null);
+ boolean oldPowerState = false; // old power state to off
+ if (mResetModemOnRadioTechnologyChange) {
+ if (mCommandsInterface.getRadioState().isOn()) {
+ oldPowerState = true;
+ logd("Setting Radio Power to Off");
+ mCommandsInterface.setRadioPower(false, null);
}
+ }
- //Set the new interfaces in the proxy's
- mIccSmsInterfaceManagerProxy.setmIccSmsInterfaceManager(
- mActivePhone.getIccSmsInterfaceManager());
- mIccPhoneBookInterfaceManagerProxy.setmIccPhoneBookInterfaceManager(
- mActivePhone.getIccPhoneBookInterfaceManager());
- mPhoneSubInfoProxy.setmPhoneSubInfo(this.mActivePhone.getPhoneSubInfo());
- mCommandsInterface = ((PhoneBase)mActivePhone).mCM;
-
- //Send an Intent to the PhoneApp that we had a radio technology change
- Intent intent = new Intent(TelephonyIntents.ACTION_RADIO_TECHNOLOGY_CHANGED);
- intent.addFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING);
- intent.putExtra(Phone.PHONE_NAME_KEY, mActivePhone.getPhoneName());
- ActivityManagerNative.broadcastStickyIntent(intent, null);
- break;
- default:
- Log.e(LOG_TAG,"Error! This handler was not registered for this message type. Message: "
- + msg.what);
- break;
+ deleteAndCreatePhone(newVoiceRadioTech);
+
+ if (mResetModemOnRadioTechnologyChange && oldPowerState) { // restore power state
+ logd("Resetting Radio");
+ mCommandsInterface.setRadioPower(oldPowerState, null);
}
- super.handleMessage(msg);
+
+ // Set the new interfaces in the proxy's
+ mIccSmsInterfaceManagerProxy.setmIccSmsInterfaceManager(
+ mActivePhone.getIccSmsInterfaceManager());
+ mIccPhoneBookInterfaceManagerProxy.setmIccPhoneBookInterfaceManager(mActivePhone
+ .getIccPhoneBookInterfaceManager());
+ mPhoneSubInfoProxy.setmPhoneSubInfo(this.mActivePhone.getPhoneSubInfo());
+
+ mCommandsInterface = ((PhoneBase)mActivePhone).mCM;
+
+ // Send an Intent to the PhoneApp that we had a radio technology change
+ Intent intent = new Intent(TelephonyIntents.ACTION_RADIO_TECHNOLOGY_CHANGED);
+ intent.addFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING);
+ intent.putExtra(Phone.PHONE_NAME_KEY, mActivePhone.getPhoneName());
+ ActivityManagerNative.broadcastStickyIntent(intent, null);
+
}
- private static void logd(String msg) {
- Log.d(LOG_TAG, "[PhoneProxy] " + msg);
+ private void deleteAndCreatePhone(int newVoiceRadioTech) {
+
+ String outgoingPhoneName = "Unknown";
+ Phone oldPhone = mActivePhone;
+
+ if (oldPhone != null) {
+ outgoingPhoneName = ((PhoneBase) oldPhone).getPhoneName();
+ }
+
+ logd("Switching Voice Phone : " + outgoingPhoneName + " >>> "
+ + (ServiceState.isGsm(newVoiceRadioTech) ? "GSM" : "CDMA"));
+
+ if (oldPhone != null) {
+ CallManager.getInstance().unregisterPhone(oldPhone);
+ logd("Disposing old phone..");
+ oldPhone.dispose();
+ }
+
+ // Give the garbage collector a hint to start the garbage collection
+ // asap NOTE this has been disabled since radio technology change could
+ // happen during e.g. a multimedia playing and could slow the system.
+ // Tests needs to be done to see the effects of the GC call here when
+ // system is busy.
+ // System.gc();
+
+ if (ServiceState.isCdma(newVoiceRadioTech)) {
+ mActivePhone = PhoneFactory.getCdmaPhone();
+ } else if (ServiceState.isGsm(newVoiceRadioTech)) {
+ mActivePhone = PhoneFactory.getGsmPhone();
+ }
+
+ if (oldPhone != null) {
+ oldPhone.removeReferences();
+ }
+
+ if(mActivePhone != null) {
+ CallManager.getInstance().registerPhone(mActivePhone);
+ }
+
+ oldPhone = null;
}
public ServiceState getServiceState() {
public UsimServiceTable getUsimServiceTable() {
return mActivePhone.getUsimServiceTable();
}
+
+ public void dispose() {
+ mCommandsInterface.unregisterForOn(this);
+ mCommandsInterface.unregisterForVoiceRadioTechChanged(this);
+ mCommandsInterface.unregisterForRilConnected(this);
+ }
+
+ public void removeReferences() {
+ mActivePhone = null;
+ mCommandsInterface = null;
+ }
}
//***** CommandsInterface implementation
+ public void getVoiceRadioTechnology(Message result) {
+ RILRequest rr = RILRequest.obtain(RIL_REQUEST_VOICE_RADIO_TECH, result);
+
+ if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
+
+ send(rr);
+ }
+
+
@Override public void
setOnNITZTime(Handler h, int what, Object obj) {
super.setOnNITZTime(h, what, obj);
switch(stateInt) {
case 0: state = RadioState.RADIO_OFF; break;
case 1: state = RadioState.RADIO_UNAVAILABLE; break;
- case 2: state = RadioState.SIM_NOT_READY; break;
- case 3: state = RadioState.SIM_LOCKED_OR_ABSENT; break;
- case 4: state = RadioState.SIM_READY; break;
- case 5: state = RadioState.RUIM_NOT_READY; break;
- case 6: state = RadioState.RUIM_READY; break;
- case 7: state = RadioState.RUIM_LOCKED_OR_ABSENT; break;
- case 8: state = RadioState.NV_NOT_READY; break;
- case 9: state = RadioState.NV_READY; break;
+ case 10: state = RadioState.RADIO_ON; break;
default:
throw new RuntimeException(
case RIL_REQUEST_ISIM_AUTHENTICATION: ret = responseString(p); break;
case RIL_REQUEST_ACKNOWLEDGE_INCOMING_GSM_SMS_WITH_PDU: ret = responseVoid(p); break;
case RIL_REQUEST_STK_SEND_ENVELOPE_WITH_STATUS: ret = responseICC_IO(p); break;
+ case RIL_REQUEST_VOICE_RADIO_TECH: ret = responseInts(p); break;
default:
throw new RuntimeException("Unrecognized solicited response: " + rr.mRequest);
//break;
case RIL_UNSOl_CDMA_PRL_CHANGED: ret = responseInts(p); break;
case RIL_UNSOL_EXIT_EMERGENCY_CALLBACK_MODE: ret = responseVoid(p); break;
case RIL_UNSOL_RIL_CONNECTED: ret = responseInts(p); break;
+ case RIL_UNSOL_VOICE_RADIO_TECH_CHANGED: ret = responseInts(p); break;
default:
throw new RuntimeException("Unrecognized unsol response: " + response);
}
break;
+ case RIL_UNSOL_VOICE_RADIO_TECH_CHANGED:
+ if (RILJ_LOGD) unsljLogRet(response, ret);
+
+ if (mVoiceRadioTechChangedRegistrants != null) {
+ mVoiceRadioTechChangedRegistrants.notifyRegistrants(
+ new AsyncResult(null, ret, null));
+ }
+ break;
+
case RIL_UNSOL_CDMA_SUBSCRIPTION_SOURCE_CHANGED:
if (RILJ_LOGD) unsljLogRet(response, ret);
case RIL_REQUEST_ISIM_AUTHENTICATION: return "RIL_REQUEST_ISIM_AUTHENTICATION";
case RIL_REQUEST_ACKNOWLEDGE_INCOMING_GSM_SMS_WITH_PDU: return "RIL_REQUEST_ACKNOWLEDGE_INCOMING_GSM_SMS_WITH_PDU";
case RIL_REQUEST_STK_SEND_ENVELOPE_WITH_STATUS: return "RIL_REQUEST_STK_SEND_ENVELOPE_WITH_STATUS";
+ case RIL_REQUEST_VOICE_RADIO_TECH: return "RIL_REQUEST_VOICE_RADIO_TECH";
default: return "<unknown request>";
}
}
case RIL_UNSOl_CDMA_PRL_CHANGED: return "UNSOL_CDMA_PRL_CHANGED";
case RIL_UNSOL_EXIT_EMERGENCY_CALLBACK_MODE: return "UNSOL_EXIT_EMERGENCY_CALLBACK_MODE";
case RIL_UNSOL_RIL_CONNECTED: return "UNSOL_RIL_CONNECTED";
+ case RIL_UNSOL_VOICE_RADIO_TECH_CHANGED: return "UNSOL_VOICE_RADIO_TECH_CHANGED";
default: return "<unknown reponse>";
}
}
int PREFERRED_NETWORK_MODE = NETWORK_MODE_WCDMA_PREF;
- /* CDMA subscription source. See ril.h RIL_REQUEST_CDMA_SET_SUBSCRIPTION */
- int SUBSCRIPTION_FROM_RUIM = 0; /* CDMA subscription from RUIM when available */
- int SUBSCRIPTION_FROM_NV = 1; /* CDMA subscription from NV */
- int PREFERRED_CDMA_SUBSCRIPTION = SUBSCRIPTION_FROM_NV;
-
int CDMA_CELL_BROADCAST_SMS_DISABLED = 1;
int CDMA_CELL_BROADCAST_SMS_ENABLED = 0;
int RIL_REQUEST_ISIM_AUTHENTICATION = 105;
int RIL_REQUEST_ACKNOWLEDGE_INCOMING_GSM_SMS_WITH_PDU = 106;
int RIL_REQUEST_STK_SEND_ENVELOPE_WITH_STATUS = 107;
+ int RIL_REQUEST_VOICE_RADIO_TECH = 108;
int RIL_UNSOL_RESPONSE_BASE = 1000;
int RIL_UNSOL_RESPONSE_RADIO_STATE_CHANGED = 1000;
int RIL_UNSOL_RESPONSE_CALL_STATE_CHANGED = 1001;
int RIL_UNSOl_CDMA_PRL_CHANGED = 1032;
int RIL_UNSOL_EXIT_EMERGENCY_CALLBACK_MODE = 1033;
int RIL_UNSOL_RIL_CONNECTED = 1034;
+ int RIL_UNSOL_VOICE_RADIO_TECH_CHANGED = 1035;
}
protected static final int EVENT_ERI_FILE_LOADED = 36;
protected static final int EVENT_OTA_PROVISION_STATUS_CHANGE = 37;
protected static final int EVENT_SET_RADIO_POWER_OFF = 38;
+ protected static final int EVENT_CDMA_SUBSCRIPTION_SOURCE_CHANGED = 39;
+ protected static final int EVENT_CDMA_PRL_VERSION_CHANGED = 40;
+ protected static final int EVENT_RADIO_ON = 41;
+
protected static final String TIMEZONE_PROPERTY = "persist.sys.timezone";
mIccRecords = ir;
// Register for SIM ready event.
- mCmdIf.registerForSIMReady(this, MSG_ID_SIM_READY, null);
- mCmdIf.registerForRUIMReady(this, MSG_ID_SIM_READY, null);
- mCmdIf.registerForNVReady(this, MSG_ID_SIM_READY, null);
+ ic.registerForReady(this, MSG_ID_SIM_READY, null);
mIccRecords.registerForRecordsLoaded(this, MSG_ID_ICC_RECORDS_LOADED, null);
CatLog.d(this, "Is running");
@Override
protected void initSstIcc() {
- mSST = new CdmaLteServiceStateTracker(this);
- mIccRecords = new CdmaLteUiccRecords(this);
mIccCard = new SimCard(this, LOG_TAG, DBG);
+ mIccRecords = new CdmaLteUiccRecords(this);
mIccFileHandler = new CdmaLteUiccFileHandler(this);
+ // CdmaLteServiceStateTracker registers with IccCard to know
+ // when the card is ready. So create mIccCard before the ServiceStateTracker
+ mSST = new CdmaLteServiceStateTracker(this);
}
@Override
// Instance Variables
CdmaCallTracker mCT;
CdmaServiceStateTracker mSST;
+ CdmaSubscriptionSourceManager mCdmaSSM;
ArrayList <CdmaMmiCode> mPendingMmis = new ArrayList<CdmaMmiCode>();
RuimPhoneBookInterfaceManager mRuimPhoneBookInterfaceManager;
RuimSmsInterfaceManager mRuimSmsInterfaceManager;
+ int mCdmaSubscriptionSource = CdmaSubscriptionSourceManager.SUBSCRIPTION_SOURCE_UNKNOWN;
PhoneSubInfo mSubInfo;
EriManager mEriManager;
WakeLock mWakeLock;
CatService mCcatService;
- // mNvLoadedRegistrants are informed after the EVENT_NV_READY
- private final RegistrantList mNvLoadedRegistrants = new RegistrantList();
-
// mEriFileLoadedRegistrants are informed after the ERI text has been loaded
private final RegistrantList mEriFileLoadedRegistrants = new RegistrantList();
}
protected void initSstIcc() {
- mSST = new CdmaServiceStateTracker(this);
- mIccRecords = new RuimRecords(this);
mIccCard = new RuimCard(this, LOG_TAG, DBG);
+ mIccRecords = new RuimRecords(this);
mIccFileHandler = new RuimFileHandler(this);
+ // CdmaServiceStateTracker registers with IccCard to know
+ // when the Ruim card is ready. So create mIccCard before the ServiceStateTracker
+ mSST = new CdmaServiceStateTracker(this);
}
protected void init(Context context, PhoneNotifier notifier) {
mCM.setPhoneType(Phone.PHONE_TYPE_CDMA);
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);
mCM.registerForOn(this, EVENT_RADIO_ON, null);
mCM.setOnSuppServiceNotification(this, EVENT_SSN, null);
mSST.registerForNetworkAttached(this, EVENT_REGISTERED_TO_NETWORK, null);
- mCM.registerForNVReady(this, EVENT_NV_READY, null);
mCM.setEmergencyCallbackMode(this, EVENT_EMERGENCY_CALLBACK_MODE_ENTER, null);
PowerManager pm
mCM.unregisterForAvailable(this); //EVENT_RADIO_AVAILABLE
mCM.unregisterForOffOrNotAvailable(this); //EVENT_RADIO_OFF_OR_NOT_AVAILABLE
mCM.unregisterForOn(this); //EVENT_RADIO_ON
- mCM.unregisterForNVReady(this); //EVENT_NV_READY
mSST.unregisterForNetworkAttached(this); //EVENT_REGISTERED_TO_NETWORK
mCM.unSetOnSuppServiceNotification(this);
removeCallbacks(mExitEcmRunnable);
mCT.dispose();
mDataConnectionTracker.dispose();
mSST.dispose();
+ mCdmaSSM.dispose(this);
mSMS.dispose();
mIccFileHandler.dispose(); // instance of RuimFileHandler
mIccRecords.dispose();
super.removeReferences();
mRuimPhoneBookInterfaceManager = null;
mRuimSmsInterfaceManager = null;
- mSMS = null;
mSubInfo = null;
- mIccRecords = null;
mIccFileHandler = null;
- mIccCard = null;
- mDataConnectionTracker = null;
mCT = null;
mSST = null;
mEriManager = null;
case EVENT_RADIO_ON:{
Log.d(LOG_TAG, "Event EVENT_RADIO_ON Received");
+ handleCdmaSubscriptionSource(mCdmaSSM.getCdmaSubscriptionSource());
+ }
+ break;
+
+ case EVENT_CDMA_SUBSCRIPTION_SOURCE_CHANGED:{
+ Log.d(LOG_TAG, "EVENT_CDMA_SUBSCRIPTION_SOURCE_CHANGED");
+ handleCdmaSubscriptionSource(mCdmaSSM.getCdmaSubscriptionSource());
}
break;
case EVENT_NV_READY:{
Log.d(LOG_TAG, "Event EVENT_NV_READY Received");
- //Inform the Service State Tracker
- mNvLoadedRegistrants.notifyRegistrants();
prepareEri();
}
break;
}
/**
+ * Handles the call to get the subscription source
+ *
+ * @param holds the new CDMA subscription source value
+ */
+ private void handleCdmaSubscriptionSource(int newSubscriptionSource) {
+ if (newSubscriptionSource != mCdmaSubscriptionSource) {
+ mCdmaSubscriptionSource = newSubscriptionSource;
+ if (newSubscriptionSource == CDMA_SUBSCRIPTION_NV) {
+ // NV is ready when subscription source is NV
+ sendMessage(obtainMessage(EVENT_NV_READY));
+ }
+ }
+ }
+
+ /**
* Retrieves the PhoneSubInfo of the CDMAPhone
*/
public PhoneSubInfo getPhoneSubInfo() {
return mRuimPhoneBookInterfaceManager;
}
- public void registerForNvLoaded(Handler h, int what, Object obj) {
- Registrant r = new Registrant (h, what, obj);
- mNvLoadedRegistrants.add(r);
- }
-
- public void unregisterForNvLoaded(Handler h) {
- mNvLoadedRegistrants.remove(h);
- }
-
public void registerForEriFileLoaded(Handler h, int what, Object obj) {
Registrant r = new Registrant (h, what, obj);
mEriFileLoadedRegistrants.add(r);
import android.telephony.PhoneNumberUtils;
import android.telephony.ServiceState;
import com.android.internal.telephony.TelephonyProperties;
+import com.android.internal.telephony.RILConstants;
/**
* {@hide}
} else if (serviceState == ServiceState.STATE_OUT_OF_SERVICE
|| serviceState == ServiceState.STATE_EMERGENCY_ONLY) {
return DisconnectCause.OUT_OF_SERVICE;
- } else if (phone.mCM.getNvState() != CommandsInterface.RadioState.NV_READY
- && phone.getIccCard().getState() != RuimCard.State.READY) {
+ } else if (phone.mCdmaSubscriptionSource ==
+ CdmaSubscriptionSourceManager.SUBSCRIPTION_FROM_RUIM
+ && phone.getIccCard().getState() != RuimCard.State.READY) {
return DisconnectCause.ICC_ERROR;
} else if (causeCode==CallFailCause.NORMAL_CLEARING) {
return DisconnectCause.NORMAL;
import com.android.internal.telephony.RetryManager;
import com.android.internal.telephony.Phone;
import com.android.internal.util.AsyncChannel;
+import com.android.internal.telephony.RILConstants;
import java.util.ArrayList;
protected final String LOG_TAG = "CDMA";
private CDMAPhone mCdmaPhone;
+ private CdmaSubscriptionSourceManager mCdmaSSM;
/** The DataConnection being setup */
private CdmaDataConnection mPendingDataConnection;
p.mCM.registerForAvailable (this, EVENT_RADIO_AVAILABLE, null);
p.mCM.registerForOffOrNotAvailable(this, EVENT_RADIO_OFF_OR_NOT_AVAILABLE, null);
p.mIccRecords.registerForRecordsLoaded(this, EVENT_RECORDS_LOADED, null);
- p.mCM.registerForNVReady(this, EVENT_NV_READY, null);
p.mCM.registerForDataNetworkStateChanged (this, EVENT_DATA_STATE_CHANGED, null);
p.mCT.registerForVoiceCallEnded (this, EVENT_VOICE_CALL_ENDED, null);
p.mCT.registerForVoiceCallStarted (this, EVENT_VOICE_CALL_STARTED, null);
p.mSST.registerForRoamingOn(this, EVENT_ROAMING_ON, null);
p.mSST.registerForRoamingOff(this, EVENT_ROAMING_OFF, null);
p.mCM.registerForCdmaOtaProvision(this, EVENT_CDMA_OTA_PROVISION, null);
+ mCdmaSSM = CdmaSubscriptionSourceManager.getInstance (p.getContext(), p.mCM, this,
+ EVENT_CDMA_SUBSCRIPTION_SOURCE_CHANGED, null);
mDataConnectionTracker = this;
mPhone.mCM.unregisterForAvailable(this);
mPhone.mCM.unregisterForOffOrNotAvailable(this);
mCdmaPhone.mIccRecords.unregisterForRecordsLoaded(this);
- mPhone.mCM.unregisterForNVReady(this);
mPhone.mCM.unregisterForDataNetworkStateChanged(this);
mCdmaPhone.mCT.unregisterForVoiceCallEnded(this);
mCdmaPhone.mCT.unregisterForVoiceCallStarted(this);
mCdmaPhone.mSST.unregisterForDataConnectionDetached(this);
mCdmaPhone.mSST.unregisterForRoamingOn(this);
mCdmaPhone.mSST.unregisterForRoamingOff(this);
+ mCdmaSSM.dispose(this);
mPhone.mCM.unregisterForCdmaOtaProvision(this);
destroyAllDataConnectionList();
int psState = mCdmaPhone.mSST.getCurrentDataConnectionState();
boolean roaming = (mPhone.getServiceState().getRoaming() && !getDataOnRoamingEnabled());
boolean desiredPowerState = mCdmaPhone.mSST.getDesiredPowerState();
+ boolean subscriptionFromNv = (mCdmaSSM.getCdmaSubscriptionSource()
+ == CdmaSubscriptionSourceManager.SUBSCRIPTION_FROM_NV);
boolean allowed =
(psState == ServiceState.STATE_IN_SERVICE ||
mAutoAttachOnCreation) &&
- (mPhone.mCM.getNvState() == CommandsInterface.RadioState.NV_READY ||
+ (subscriptionFromNv ||
mCdmaPhone.mIccRecords.getRecordsLoaded()) &&
(mCdmaPhone.mSST.isConcurrentVoiceAndDataAllowed() ||
mPhone.getState() == Phone.State.IDLE) &&
if (!((psState == ServiceState.STATE_IN_SERVICE) || mAutoAttachOnCreation)) {
reason += " - psState= " + psState;
}
- if (!(mPhone.mCM.getNvState() == CommandsInterface.RadioState.NV_READY ||
- mCdmaPhone.mIccRecords.getRecordsLoaded())) {
- reason += " - radioState= " + mPhone.mCM.getNvState() + " - RUIM not loaded";
+ if (!subscriptionFromNv &&
+ !mCdmaPhone.mIccRecords.getRecordsLoaded()) {
+ reason += " - RUIM not loaded";
}
if (!(mCdmaPhone.mSST.isConcurrentVoiceAndDataAllowed() ||
mPhone.getState() == Phone.State.IDLE)) {
onRecordsLoaded();
break;
- case EVENT_NV_READY:
- onNVReady();
+ case EVENT_CDMA_SUBSCRIPTION_SOURCE_CHANGED:
+ if(mCdmaSSM.getCdmaSubscriptionSource() ==
+ CdmaSubscriptionSourceManager.SUBSCRIPTION_FROM_NV) {
+ onNVReady();
+ }
break;
case EVENT_CDMA_DATA_DETACHED:
import com.android.internal.telephony.MccTable;
import com.android.internal.telephony.EventLogTags;
import com.android.internal.telephony.RILConstants;
+import com.android.internal.telephony.IccCard;
import android.content.Intent;
import android.telephony.SignalStrength;
CDMALTEPhone mCdmaLtePhone;
private ServiceState mLteSS; // The last LTE state from Voice Registration
- private boolean mNeedToRegForSimLoaded = true;
public CdmaLteServiceStateTracker(CDMALTEPhone phone) {
super(phone);
- cm.registerForSIMReady(this, EVENT_SIM_READY, null);
mCdmaLtePhone = phone;
mLteSS = new ServiceState();
}
@Override
- public void dispose() {
- cm.unregisterForSIMReady(this);
- super.dispose();
- }
-
- @Override
public void handleMessage(Message msg) {
AsyncResult ar;
int[] ints;
ar = (AsyncResult)msg.obj;
handlePollStateResult(msg.what, ar);
break;
- case EVENT_SIM_READY:
- if (DBG) log("handleMessage EVENT_SIM_READY");
- isSubscriptionFromRuim = false;
- // Register SIM_RECORDS_LOADED dynamically.
- // This is to avoid confilct with RUIM_READY scenario)
- if (mNeedToRegForSimLoaded) {
- phone.mIccRecords.registerForRecordsLoaded(this, EVENT_SIM_RECORDS_LOADED, null);
- mNeedToRegForSimLoaded = false;
- }
- pollState();
- // Signal strength polling stops when radio is off.
- queueNextSignalStrengthPoll();
-
- // load ERI file
- phone.prepareEri();
- break;
- case EVENT_SIM_RECORDS_LOADED:
+ case EVENT_RUIM_RECORDS_LOADED:
CdmaLteUiccRecords sim = (CdmaLteUiccRecords)phone.mIccRecords;
if ((sim != null) && sim.isProvisioned()) {
mMdn = sim.getMdn();
ss.setOperatorAlphaLong(eriText);
}
- if (cm.getSimState().isSIMReady()) {
- // SIM is found on the device. If ERI roaming is OFF and SID/NID matches
- // one configfured in SIM, use operator name from CSIM record.
+ if (phone.mIccCard.getState() == IccCard.State.READY) {
+ // SIM is found on the device. If ERI roaming is OFF, and SID/NID matches
+ // one configfured in SIM, use operator name from CSIM record.
boolean showSpn =
((CdmaLteUiccRecords)phone.mIccRecords).getCsimSpnDisplayCondition();
int iconIndex = ss.getCdmaEriIconIndex();
import com.android.internal.telephony.EventLogTags;
import com.android.internal.telephony.IccCard;
import com.android.internal.telephony.MccTable;
+import com.android.internal.telephony.RILConstants;
import com.android.internal.telephony.Phone;
import com.android.internal.telephony.ServiceStateTracker;
import com.android.internal.telephony.TelephonyIntents;
import com.android.internal.telephony.TelephonyProperties;
+import com.android.internal.telephony.CommandsInterface.RadioState;
import android.app.AlarmManager;
import android.content.ContentResolver;
import android.os.SystemClock;
import android.os.SystemProperties;
import android.provider.Settings;
+import android.provider.Settings.Secure;
import android.provider.Settings.SettingNotFoundException;
import android.provider.Telephony.Intents;
import android.telephony.ServiceState;
private boolean isEriTextLoaded = false;
protected boolean isSubscriptionFromRuim = false;
+ private CdmaSubscriptionSourceManager mCdmaSSM;
/* Used only for debugging purposes. */
private String mRegistrationDeniedReason;
newCellLoc = new CdmaCellLocation();
mSignalStrength = new SignalStrength();
+ mCdmaSSM = CdmaSubscriptionSourceManager.getInstance(phone.getContext(), cm, this,
+ EVENT_CDMA_SUBSCRIPTION_SOURCE_CHANGED, null);
+ isSubscriptionFromRuim = (mCdmaSSM.getCdmaSubscriptionSource() ==
+ CdmaSubscriptionSourceManager.SUBSCRIPTION_FROM_RUIM);
+
PowerManager powerManager =
(PowerManager)phone.getContext().getSystemService(Context.POWER_SERVICE);
mWakeLock = powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, WAKELOCK_TAG);
- cm.registerForAvailable(this, EVENT_RADIO_AVAILABLE, null);
cm.registerForRadioStateChanged(this, EVENT_RADIO_STATE_CHANGED, null);
cm.registerForVoiceNetworkStateChanged(this, EVENT_NETWORK_STATE_CHANGED_CDMA, null);
cm.setOnNITZTime(this, EVENT_NITZ_TIME, null);
cm.setOnSignalStrengthUpdate(this, EVENT_SIGNAL_STRENGTH_UPDATE, null);
- cm.registerForRUIMReady(this, EVENT_RUIM_READY, null);
-
- cm.registerForNVReady(this, EVENT_NV_READY, null);
+ cm.registerForCdmaPrlChanged(this, EVENT_CDMA_PRL_VERSION_CHANGED, null);
phone.registerForEriFileLoaded(this, EVENT_ERI_FILE_LOADED, null);
cm.registerForCdmaOtaProvision(this,EVENT_OTA_PROVISION_STATUS_CHANGE, null);
public void dispose() {
// Unregister for all events.
- cm.unregisterForAvailable(this);
cm.unregisterForRadioStateChanged(this);
cm.unregisterForVoiceNetworkStateChanged(this);
- cm.unregisterForRUIMReady(this);
- cm.unregisterForNVReady(this);
+ phone.mIccCard.unregisterForReady(this);
+
cm.unregisterForCdmaOtaProvision(this);
phone.unregisterForEriFileLoaded(this);
phone.mIccRecords.unregisterForRecordsLoaded(this);
cm.unSetOnNITZTime(this);
cr.unregisterContentObserver(mAutoTimeObserver);
cr.unregisterContentObserver(mAutoTimeZoneObserver);
+ mCdmaSSM.dispose(this);
+ cm.unregisterForCdmaPrlChanged(this);
}
@Override
cdmaForSubscriptionInfoReadyRegistrants.remove(h);
}
+ /**
+ * Save current source of cdma subscription
+ * @param source - 1 for NV, 0 for RUIM
+ */
+ private void saveCdmaSubscriptionSource(int source) {
+ log("Storing cdma subscription source: " + source);
+ Secure.putInt(phone.getContext().getContentResolver(),
+ Secure.CDMA_SUBSCRIPTION_MODE,
+ source );
+ }
+
+ private void getSubscriptionInfoAndStartPollingThreads() {
+ cm.getCDMASubscription(obtainMessage(EVENT_POLL_STATE_CDMA_SUBSCRIPTION));
+
+ // Get Registration Information
+ pollState();
+ }
+
@Override
public void handleMessage (Message msg) {
AsyncResult ar;
int[] ints;
String[] strings;
+ if (!phone.mIsTheCurrentActivePhone) {
+ loge("Received message " + msg + "[" + msg.what + "]" +
+ " while being destroyed. Ignoring.");
+ return;
+ }
+
switch (msg.what) {
- case EVENT_RADIO_AVAILABLE:
- if (DBG) log("handleMessage: EVENT_RADIO_AVAILABLE");
+ case EVENT_CDMA_SUBSCRIPTION_SOURCE_CHANGED:
+ handleCdmaSubscriptionSource(mCdmaSSM.getCdmaSubscriptionSource());
break;
case EVENT_RUIM_READY:
// The RUIM is now ready i.e if it was locked it has been
// unlocked. At this stage, the radio is already powered on.
- isSubscriptionFromRuim = true;
if (mNeedToRegForRuimLoaded) {
phone.mIccRecords.registerForRecordsLoaded(this,
EVENT_RUIM_RECORDS_LOADED, null);
mNeedToRegForRuimLoaded = false;
}
-
- cm.getCDMASubscription(obtainMessage(EVENT_POLL_STATE_CDMA_SUBSCRIPTION));
- if (DBG) log("handleMessage: EVENT_RUIM_READY, Send Request getCDMASubscription.");
-
- // Restore the previous network selection.
- pollState();
-
- // Signal strength polling stops when radio is off.
- queueNextSignalStrengthPoll();
+ if (DBG) log("Receive EVENT_RUIM_READY and Send Request getCDMASubscription.");
+ getSubscriptionInfoAndStartPollingThreads();
+ phone.prepareEri();
break;
case EVENT_NV_READY:
- // TODO: Consider calling setCurrentPreferredNetworkType as we do in GsmSST.
- // cm.setCurrentPreferredNetworkType();
-
- isSubscriptionFromRuim = false;
// For Non-RUIM phones, the subscription information is stored in
// Non Volatile. Here when Non-Volatile is ready, we can poll the CDMA
// subscription info.
- if (DBG) log("handleMessage: EVENT_NV_READY, Send Request getCDMASubscription.");
- cm.getCDMASubscription( obtainMessage(EVENT_POLL_STATE_CDMA_SUBSCRIPTION));
- pollState();
- // Signal strength polling stops when radio is off.
- queueNextSignalStrengthPoll();
+ getSubscriptionInfoAndStartPollingThreads();
break;
case EVENT_RADIO_STATE_CHANGED:
+ if(cm.getRadioState() == RadioState.RADIO_ON) {
+ handleCdmaSubscriptionSource(mCdmaSSM.getCdmaSubscriptionSource());
+
+ // Signal strength polling stops when radio is off.
+ queueNextSignalStrengthPoll();
+ }
// This will do nothing in the 'radio not available' case.
setPowerStateToDesired();
pollState();
// This callback is called when signal strength is polled
// all by itself.
- if (!(cm.getRadioState().isOn()) || (cm.getRadioState().isGsm())) {
+ if (!(cm.getRadioState().isOn())) {
// Polling will continue when radio turns back on.
return;
}
}
break;
+ case EVENT_CDMA_PRL_VERSION_CHANGED:
+ ar = (AsyncResult)msg.obj;
+ if (ar.exception == null) {
+ ints = (int[]) ar.result;
+ mPrlVersion = Integer.toString(ints[0]);
+ }
+ break;
+
default:
super.handleMessage(msg);
break;
//***** Private Instance Methods
+ private void handleCdmaSubscriptionSource(int newSubscriptionSource) {
+ log("Subscription Source : " + newSubscriptionSource);
+ isSubscriptionFromRuim =
+ (newSubscriptionSource == CdmaSubscriptionSourceManager.SUBSCRIPTION_FROM_RUIM);
+ saveCdmaSubscriptionSource(newSubscriptionSource);
+ if (!isSubscriptionFromRuim) {
+ // NV is ready when subscription source is NV
+ sendMessage(obtainMessage(EVENT_NV_READY));
+ } else {
+ phone.mIccCard.registerForReady(this, EVENT_RUIM_READY, null);
+ }
+ }
+
@Override
protected void setPowerStateToDesired() {
// If we want it on and it's off, turn it on
@Override
protected void updateSpnDisplay() {
- // TODO RUIM SPN is not implemented, EF_SPN has to be read and Display Condition
- // Character Encoding, Language Indicator and SPN has to be set, something like below:
- // if (cm.getRadioState().isRUIMReady()) {
- // rule = phone.mRuimRecords.getDisplayRule(ss.getOperatorNumeric());
- // spn = phone.mSIMRecords.getServiceProvideName();
- // }
-
// mOperatorAlphaLong contains the ERI text
String plmn = ss.getOperatorAlphaLong();
if (!TextUtils.equals(plmn, mCurPlmn)) {
"'= " + opNames[2]);
}
}
- if (cm.getNvState().isNVReady()) {
+
+ if (!isSubscriptionFromRuim) {
// In CDMA in case on NV, the ss.mOperatorAlphaLong is set later with the
// ERI text, so here it is ignored what is coming from the modem.
newSS.setOperatorName(null, opNames[1], opNames[2]);
pollStateDone();
break;
- case SIM_NOT_READY:
- case SIM_LOCKED_OR_ABSENT:
- case SIM_READY:
- if (DBG) log("Radio Technology Change ongoing, setting SS to off");
- newSS.setStateOff();
- newCellLoc.setStateInvalid();
- setSignalStrengthDefaultValues();
- mGotCountryCode = false;
-
- // NOTE: pollStateDone() is not needed in this case
- break;
-
default:
// Issue all poll-related commands at once, then count
// down the responses which are allowed to arrive
}
if (hasChanged) {
- if (cm.getRadioState().isNVReady()) {
+ if ((cm.getRadioState().isOn()) && (!isSubscriptionFromRuim)) {
String eriText;
// Now the CDMAPhone sees the new ServiceState so it can get the new ERI text
if (ss.getState() == ServiceState.STATE_IN_SERVICE) {
* This code should probably be hoisted to the base class so
* the fix, when added, works for both.
*/
- protected void
+ private void
queueNextSignalStrengthPoll() {
- if (dontPollSignalStrength || (cm.getRadioState().isGsm())) {
+ if (dontPollSignalStrength) {
// The radio is telling us about signal strength changes
// we don't have to ask it
return;
--- /dev/null
+/*
+ * Copyright (c) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.internal.telephony.cdma;
+
+import java.util.concurrent.atomic.AtomicInteger;
+
+import com.android.internal.telephony.CommandsInterface;
+import com.android.internal.telephony.RILConstants;
+
+import android.content.Context;
+import android.os.AsyncResult;
+import android.os.Handler;
+import android.os.Message;
+import android.os.Registrant;
+import android.os.RegistrantList;
+import android.provider.Settings;
+import android.util.Log;
+
+/**
+ * Class that handles the CDMA subscription source changed events from RIL
+ */
+public class CdmaSubscriptionSourceManager extends Handler {
+ static final String LOG_TAG = "CDMA";
+ private static final int EVENT_CDMA_SUBSCRIPTION_SOURCE_CHANGED = 1;
+ private static final int EVENT_GET_CDMA_SUBSCRIPTION_SOURCE = 2;
+ private static final int EVENT_RADIO_ON = 3;
+
+ public static final int SUBSCRIPTION_SOURCE_UNKNOWN = -1;
+ public static final int SUBSCRIPTION_FROM_RUIM = 0; /* CDMA subscription from RUIM */
+ public static final int SUBSCRIPTION_FROM_NV = 1; /* CDMA subscription from NV */
+ public static final int PREFERRED_CDMA_SUBSCRIPTION = SUBSCRIPTION_FROM_NV;
+
+ private static CdmaSubscriptionSourceManager sInstance;
+ private static final Object sReferenceCountMonitor = new Object();
+ private static int sReferenceCount = 0;
+
+ // ***** Instance Variables
+ private CommandsInterface mCM;
+ private Context mContext;
+ private RegistrantList mCdmaSubscriptionSourceChangedRegistrants = new RegistrantList();
+
+ // Type of CDMA subscription source
+ private AtomicInteger mCdmaSubscriptionSource = new AtomicInteger(SUBSCRIPTION_FROM_NV);
+
+ // Constructor
+ private CdmaSubscriptionSourceManager(Context context, CommandsInterface ci) {
+ mContext = context;
+ mCM = ci;
+ mCM.registerForCdmaSubscriptionChanged(this, EVENT_CDMA_SUBSCRIPTION_SOURCE_CHANGED, null);
+ mCM.registerForOn(this, EVENT_RADIO_ON, null);
+ int subscriptionSource = getDefaultCdmaSubscriptionSource();
+ mCdmaSubscriptionSource.set(subscriptionSource);
+ }
+
+ /**
+ * This function creates a single instance of this class
+ *
+ * @return object of type CdmaSubscriptionSourceManager
+ */
+ public static CdmaSubscriptionSourceManager getInstance(Context context,
+ CommandsInterface ci, Handler h, int what, Object obj) {
+ synchronized (sReferenceCountMonitor) {
+ if (null == sInstance) {
+ sInstance = new CdmaSubscriptionSourceManager(context, ci);
+ }
+ sInstance.sReferenceCount++;
+ }
+ sInstance.registerForCdmaSubscriptionSourceChanged(h, what, obj);
+ return sInstance;
+ }
+
+ /**
+ * Unregisters for the registered event with RIL
+ */
+ public void dispose(Handler h) {
+ mCdmaSubscriptionSourceChangedRegistrants.remove(h);
+ synchronized (sReferenceCountMonitor) {
+ sReferenceCount--;
+ if (sReferenceCount <= 0) {
+ mCM.unregisterForCdmaSubscriptionChanged(this);
+ mCM.unregisterForOn(this);
+ sInstance = null;
+ }
+ }
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see android.os.Handler#handleMessage(android.os.Message)
+ */
+ @Override
+ public void handleMessage(Message msg) {
+ AsyncResult ar;
+ switch (msg.what) {
+ case EVENT_CDMA_SUBSCRIPTION_SOURCE_CHANGED:
+ case EVENT_GET_CDMA_SUBSCRIPTION_SOURCE:
+ {
+ log("CDMA_SUBSCRIPTION_SOURCE event = " + msg.what);
+ ar = (AsyncResult) msg.obj;
+ handleGetCdmaSubscriptionSource(ar);
+ }
+ break;
+ case EVENT_RADIO_ON: {
+ mCM.getCdmaSubscriptionSource(obtainMessage(EVENT_GET_CDMA_SUBSCRIPTION_SOURCE));
+ }
+ break;
+ default:
+ super.handleMessage(msg);
+ }
+ }
+
+ /**
+ * Returns the current CDMA subscription source value
+ * @return CDMA subscription source value
+ */
+ public int getCdmaSubscriptionSource() {
+ return mCdmaSubscriptionSource.get();
+ }
+
+ /**
+ * Gets the default CDMA subscription source
+ *
+ * @return Default CDMA subscription source from Settings DB if present.
+ */
+ private int getDefaultCdmaSubscriptionSource() {
+ // Get the default value from the Settings
+ int subscriptionSource = Settings.Secure.getInt(mContext.getContentResolver(),
+ Settings.Secure.CDMA_SUBSCRIPTION_MODE, PREFERRED_CDMA_SUBSCRIPTION);
+ return subscriptionSource;
+ }
+
+ /**
+ * Clients automatically register for CDMA subscription source changed event
+ * when they get an instance of this object.
+ */
+ private void registerForCdmaSubscriptionSourceChanged(Handler h, int what, Object obj) {
+ Registrant r = new Registrant (h, what, obj);
+ mCdmaSubscriptionSourceChangedRegistrants.add(r);
+ }
+
+ /**
+ * Handles the call to get the subscription source
+ *
+ * @param ar AsyncResult object that contains the result of get CDMA
+ * subscription source call
+ */
+ private void handleGetCdmaSubscriptionSource(AsyncResult ar) {
+ if ((ar.exception == null) && (ar.result != null)) {
+ int newSubscriptionSource = ((int[]) ar.result)[0];
+
+ if (newSubscriptionSource != mCdmaSubscriptionSource.get()) {
+ log("Subscription Source Changed : " + mCdmaSubscriptionSource + " >> "
+ + newSubscriptionSource);
+ mCdmaSubscriptionSource.set(newSubscriptionSource);
+
+ // Notify registrants of the new CDMA subscription source
+ mCdmaSubscriptionSourceChangedRegistrants.notifyRegistrants(new AsyncResult(null,
+ null, null));
+ }
+ } else {
+ // GET_CDMA_SUBSCRIPTION is returning Failure. Probably
+ // because modem created GSM Phone. If modem created
+ // GSMPhone, then PhoneProxy will trigger a change in
+ // Phone objects and this object will be destroyed.
+ logw("Unable to get CDMA Subscription Source, Exception: " + ar.exception
+ + ", result: " + ar.result);
+ }
+ }
+
+ private void log(String s) {
+ Log.d(LOG_TAG, "[CdmaSSM] " + s);
+ }
+
+ private void loge(String s) {
+ Log.e(LOG_TAG, "[CdmaSSM] " + s);
+ }
+
+ private void logw(String s) {
+ Log.w(LOG_TAG, "[CdmaSSM] " + s);
+ }
+
+}
RuimCard(CDMAPhone phone, String LOG_TAG, boolean dbg) {
super(phone, LOG_TAG, dbg);
- mPhone.mCM.registerForRUIMLockedOrAbsent(mHandler, EVENT_ICC_LOCKED_OR_ABSENT, null);
- mPhone.mCM.registerForOffOrNotAvailable(mHandler, EVENT_RADIO_OFF_OR_NOT_AVAILABLE, null);
- mPhone.mCM.registerForRUIMReady(mHandler, EVENT_ICC_READY, null);
+ is3gpp = false;
+ mCdmaSSM = CdmaSubscriptionSourceManager.getInstance(mPhone.getContext(),
+ mPhone.mCM, mHandler, EVENT_CDMA_SUBSCRIPTION_SOURCE_CHANGED, null);
+
updateStateProperty();
}
@Override
public void dispose() {
super.dispose();
- //Unregister for all events
- mPhone.mCM.unregisterForRUIMLockedOrAbsent(mHandler);
- mPhone.mCM.unregisterForOffOrNotAvailable(mHandler);
- mPhone.mCM.unregisterForRUIMReady(mHandler);
+ mCdmaSSM.dispose(mHandler);
}
@Override
recordsToLoad = 0;
- p.mCM.registerForRUIMReady(this, EVENT_RUIM_READY, null);
+ p.mIccCard.registerForRuimReady(this, EVENT_RUIM_READY, null);
p.mCM.registerForOffOrNotAvailable(this, EVENT_RADIO_OFF_OR_NOT_AVAILABLE, null);
// NOTE the EVENT_SMS_ON_RUIM is not registered
p.mCM.registerForIccRefresh(this, EVENT_RUIM_REFRESH, null);
@Override
public void dispose() {
//Unregister for all events
- phone.mCM.unregisterForRUIMReady(this);
+ phone.mIccCard.unregisterForRuimReady(this);
phone.mCM.unregisterForOffOrNotAvailable( this);
phone.mCM.unregisterForIccRefresh(this);
}
@Override
protected void finalize() {
- if(DBG) Log.d(LOG_TAG, "RuimRecords finalized");
+ if(DBG) log("RuimRecords finalized");
}
@Override
AsyncResult.forMessage((onComplete)).exception =
new IccException("setVoiceMailNumber not implemented");
onComplete.sendToTarget();
- Log.e(LOG_TAG, "method setVoiceMailNumber is not implemented");
+ loge("method setVoiceMailNumber is not implemented");
}
/**
boolean isRecordLoadResponse = false;
+ if (!phone.mIsTheCurrentActivePhone) {
+ loge("Received message " + msg +
+ "[" + msg.what + "] while being destroyed. Ignoring.");
+ return;
+ }
+
try { switch (msg.what) {
case EVENT_RUIM_READY:
onRuimReady();
break;
case EVENT_GET_DEVICE_IDENTITY_DONE:
- Log.d(LOG_TAG, "Event EVENT_GET_DEVICE_IDENTITY_DONE Received");
+ log("Event EVENT_GET_DEVICE_IDENTITY_DONE Received");
break;
/* IO events */
ar = (AsyncResult)msg.obj;
if (ar.exception != null) {
- Log.e(LOG_TAG, "Exception querying IMSI, Exception:" + ar.exception);
+ loge("Exception querying IMSI, Exception:" + ar.exception);
break;
}
// IMSI (MCC+MNC+MSIN) is at least 6 digits, but not more
// than 15 (and usually 15).
if (mImsi != null && (mImsi.length() < 6 || mImsi.length() > 15)) {
- Log.e(LOG_TAG, "invalid IMSI " + mImsi);
+ loge("invalid IMSI " + mImsi);
mImsi = null;
}
- Log.d(LOG_TAG, "IMSI: " + mImsi.substring(0, 6) + "xxxxxxxxx");
+ log("IMSI: " + mImsi.substring(0, 6) + "xxxxxxxxx");
String operatorNumeric = getRUIMOperatorNumeric();
if (operatorNumeric != null) {
mMin2Min1 = localTemp[3];
mPrlVersion = localTemp[4];
- Log.d(LOG_TAG, "MDN: " + mMyMobileNumber + " MIN: " + mMin2Min1);
+ log("MDN: " + mMyMobileNumber + " MIN: " + mMin2Min1);
break;
iccid = IccUtils.bcdToString(data, 0, data.length);
- Log.d(LOG_TAG, "iccid: " + iccid);
+ log("iccid: " + iccid);
break;
// TODO: probably EF_CST should be read instead
case EVENT_GET_SST_DONE:
- Log.d(LOG_TAG, "Event EVENT_GET_SST_DONE Received");
+ log("Event EVENT_GET_SST_DONE Received");
break;
case EVENT_RUIM_REFRESH:
if (recordsToLoad == 0 && recordsRequested == true) {
onAllRecordsLoaded();
} else if (recordsToLoad < 0) {
- Log.e(LOG_TAG, "RuimRecords: recordsToLoad <0, programmer error suspected");
+ loge("RuimRecords: recordsToLoad <0, programmer error suspected");
recordsToLoad = 0;
}
}
@Override
protected void onAllRecordsLoaded() {
- Log.d(LOG_TAG, "RuimRecords: record load complete");
+ log("RuimRecords: record load complete");
// Further records that can be inserted are Operator/OEM dependent
}
mCM.setPhoneType(Phone.PHONE_TYPE_GSM);
+ mIccCard = new SimCard(this, LOG_TAG, true);
mCT = new GsmCallTracker(this);
mSST = new GsmServiceStateTracker (this);
mSMS = new GsmSMSDispatcher(this, mSmsStorageMonitor, mSmsUsageMonitor);
mIccFileHandler = new SIMFileHandler(this);
mIccRecords = new SIMRecords(this);
mDataConnectionTracker = new GsmDataConnectionTracker (this);
- mIccCard = new SimCard(this);
if (!unitTestMode) {
mSimPhoneBookIntManager = new SimPhoneBookInterfaceManager(this);
mSimSmsIntManager = new SimSmsInterfaceManager(this, mSMS);
mStkService = null;
mSimPhoneBookIntManager = null;
mSimSmsIntManager = null;
- mSMS = null;
mSubInfo = null;
- mIccRecords = null;
mIccFileHandler = null;
- mIccCard = null;
- mDataConnectionTracker = null;
mCT = null;
mSST = null;
}
cm.setOnNITZTime(this, EVENT_NITZ_TIME, null);
cm.setOnSignalStrengthUpdate(this, EVENT_SIGNAL_STRENGTH_UPDATE, null);
cm.setOnRestrictedStateChanged(this, EVENT_RESTRICTED_STATE_CHANGED, null);
- cm.registerForSIMReady(this, EVENT_SIM_READY, null);
+ phone.mIccCard.registerForReady(this, EVENT_SIM_READY, null);
// system setting property AIRPLANE_MODE_ON is set in Settings.
int airplaneMode = Settings.System.getInt(
cm.unregisterForAvailable(this);
cm.unregisterForRadioStateChanged(this);
cm.unregisterForVoiceNetworkStateChanged(this);
- cm.unregisterForSIMReady(this);
-
+ phone.mIccCard.unregisterForReady(this);
phone.mIccRecords.unregisterForRecordsLoaded(this);
cm.unSetOnSignalStrengthUpdate(this);
cm.unSetOnRestrictedStateChanged(this);
String[] strings;
Message message;
+ if (!phone.mIsTheCurrentActivePhone) {
+ Log.e(LOG_TAG, "Received message " + msg +
+ "[" + msg.what + "] while being destroyed. Ignoring.");
+ return;
+ }
switch (msg.what) {
case EVENT_RADIO_AVAILABLE:
//this is unnecessary
// This callback is called when signal strength is polled
// all by itself
- if (!(cm.getRadioState().isOn()) || (cm.getRadioState().isCdma())) {
- // Polling will continue when radio turns back on and not CDMA
+ if (!(cm.getRadioState().isOn())) {
+ // Polling will continue when radio turns back on
return;
}
ar = (AsyncResult) msg.obj;
pollStateDone();
break;
- case RUIM_NOT_READY:
- case RUIM_READY:
- case RUIM_LOCKED_OR_ABSENT:
- case NV_NOT_READY:
- case NV_READY:
- if (DBG) log("Radio Technology Change ongoing, setting SS to off");
- newSS.setStateOff();
- newCellLoc.setStateInvalid();
- setSignalStrengthDefaultValues();
- mGotCountryCode = false;
-
- //NOTE: pollStateDone() is not needed in this case
- break;
-
default:
// Issue all poll-related commands at once
// then count down the responses, which
}
private void queueNextSignalStrengthPoll() {
- if (dontPollSignalStrength || (cm.getRadioState().isCdma())) {
+ if (dontPollSignalStrength) {
// The radio is telling us about signal strength changes
// we don't have to ask it
return;
// recordsToLoad is set to 0 because no requests are made yet
recordsToLoad = 0;
- p.mCM.registerForSIMReady(this, EVENT_SIM_READY, null);
+ p.mIccCard.registerForReady(this, EVENT_SIM_READY, null);
p.mCM.registerForOffOrNotAvailable(
this, EVENT_RADIO_OFF_OR_NOT_AVAILABLE, null);
p.mCM.setOnSmsOnSim(this, EVENT_SMS_ON_SIM, null);
@Override
public void dispose() {
//Unregister for all events
- phone.mCM.unregisterForSIMReady(this);
+ phone.mIccCard.unregisterForReady(this);
phone.mCM.unregisterForOffOrNotAvailable( this);
phone.mCM.unregisterForIccRefresh(this);
}
protected void finalize() {
- if(DBG) Log.d(LOG_TAG, "SIMRecords finalized");
+ if(DBG) log("finalized");
}
protected void onRadioOffOrNotAvailable() {
obtainMessage (EVENT_UPDATE_DONE, EF_VOICE_MAIL_INDICATOR_CPHS));
}
} catch (ArrayIndexOutOfBoundsException ex) {
- Log.w(LOG_TAG,
- "Error saving voice mail state to SIM. Probably malformed SIM record", ex);
+ logw("Error saving voice mail state to SIM. Probably malformed SIM record", ex);
}
}
obtainMessage (EVENT_UPDATE_DONE, EF_CFF_CPHS));
}
} catch (ArrayIndexOutOfBoundsException ex) {
- Log.w(LOG_TAG,
- "Error saving call fowarding flag to SIM. "
+ logw("Error saving call fowarding flag to SIM. "
+ "Probably malformed SIM record", ex);
}
@Override
public String getOperatorNumeric() {
if (imsi == null) {
- Log.d(LOG_TAG, "getOperatorNumeric: IMSI == null");
+ log("getOperatorNumeric: IMSI == null");
return null;
}
if (mncLength == UNINITIALIZED || mncLength == UNKNOWN) {
- Log.d(LOG_TAG, "getSIMOperatorNumeric: bad mncLength");
+ log("getSIMOperatorNumeric: bad mncLength");
return null;
}
boolean isRecordLoadResponse = false;
+ if (!phone.mIsTheCurrentActivePhone) {
+ loge("Received message " + msg + "[" + msg.what + "] " +
+ " while being destroyed. Ignoring.");
+ return;
+ }
+
try { switch (msg.what) {
case EVENT_SIM_READY:
onSimReady();
ar = (AsyncResult)msg.obj;
if (ar.exception != null) {
- Log.e(LOG_TAG, "Exception querying IMSI, Exception:" + ar.exception);
+ loge("Exception querying IMSI, Exception:" + ar.exception);
break;
}
// IMSI (MCC+MNC+MSIN) is at least 6 digits, but not more
// than 15 (and usually 15).
if (imsi != null && (imsi.length() < 6 || imsi.length() > 15)) {
- Log.e(LOG_TAG, "invalid IMSI " + imsi);
+ loge("invalid IMSI " + imsi);
imsi = null;
}
- Log.d(LOG_TAG, "IMSI: " + /* imsi.substring(0, 6) +*/ "xxxxxxx");
+ log("IMSI: " + /* imsi.substring(0, 6) +*/ "xxxxxxx");
if (((mncLength == UNKNOWN) || (mncLength == 2)) &&
((imsi != null) && (imsi.length() >= 6))) {
mncLength = MccTable.smallestDigitsMccForMnc(mcc);
} catch (NumberFormatException e) {
mncLength = UNKNOWN;
- Log.e(LOG_TAG, "SIMRecords: Corrupt IMSI!");
+ loge("Corrupt IMSI!");
}
}
isValidMbdn = false;
if (ar.exception == null) {
// Refer TS 51.011 Section 10.3.44 for content details
- Log.d(LOG_TAG, "EF_MBI: " +
- IccUtils.bytesToHexString(data));
+ log("EF_MBI: " + IccUtils.bytesToHexString(data));
// Voice mail record number stored first
mailboxIndex = (int)data[0] & 0xff;
// check if dailing numbe id valid
if (mailboxIndex != 0 && mailboxIndex != 0xff) {
- Log.d(LOG_TAG, "Got valid mailbox number for MBDN");
+ log("Got valid mailbox number for MBDN");
isValidMbdn = true;
}
}
if (ar.exception != null) {
- Log.d(LOG_TAG, "Invalid or missing EF"
+ log("Invalid or missing EF"
+ ((msg.what == EVENT_GET_CPHS_MAILBOX_DONE) ? "[MAILBOX]" : "[MBDN]"));
// Bug #645770 fall back to CPHS
adn = (AdnRecord)ar.result;
- Log.d(LOG_TAG, "VM: " + adn +
+ log("VM: " + adn +
((msg.what == EVENT_GET_CPHS_MAILBOX_DONE) ? " EF[MAILBOX]" : " EF[MBDN]"));
if (adn.isEmpty() && msg.what == EVENT_GET_MBDN_DONE) {
ar = (AsyncResult)msg.obj;
if (ar.exception != null) {
- Log.d(LOG_TAG, "Invalid or missing EF[MSISDN]");
+ log("Invalid or missing EF[MSISDN]");
break;
}
msisdn = adn.getNumber();
msisdnTag = adn.getAlphaTag();
- Log.d(LOG_TAG, "MSISDN: " + /*msisdn*/ "xxxxxxx");
+ log("MSISDN: " + /*msisdn*/ "xxxxxxx");
break;
case EVENT_SET_MSISDN_DONE:
break;
}
- Log.d(LOG_TAG, "EF_MWIS: " +
- IccUtils.bytesToHexString(data));
+ log("EF_MWIS: " + IccUtils.bytesToHexString(data));
efMWIS = data;
if ((data[0] & 0xff) == 0xff) {
- Log.d(LOG_TAG, "SIMRecords: Uninitialized record MWIS");
+ log("Uninitialized record MWIS");
break;
}
iccid = IccUtils.bcdToString(data, 0, data.length);
- Log.d(LOG_TAG, "iccid: " + iccid);
+ log("iccid: " + iccid);
break;
break;
}
- Log.d(LOG_TAG, "EF_AD: " +
- IccUtils.bytesToHexString(data));
+ log("EF_AD: " + IccUtils.bytesToHexString(data));
if (data.length < 3) {
- Log.d(LOG_TAG, "SIMRecords: Corrupt AD data on SIM");
+ log("Corrupt AD data on SIM");
break;
}
if (data.length == 3) {
- Log.d(LOG_TAG, "SIMRecords: MNC length not present in EF_AD");
+ log("MNC length not present in EF_AD");
break;
}
mncLength = MccTable.smallestDigitsMccForMnc(mcc);
} catch (NumberFormatException e) {
mncLength = UNKNOWN;
- Log.e(LOG_TAG, "SIMRecords: Corrupt IMSI!");
+ loge("Corrupt IMSI!");
}
} else {
// Indicate we got this info, but it didn't contain the length.
mncLength = UNKNOWN;
- Log.d(LOG_TAG, "SIMRecords: MNC length not present in EF_AD");
+ log("MNC length not present in EF_AD");
}
}
if (imsi != null && mncLength != UNKNOWN) {
break;
}
- Log.d(LOG_TAG, "EF_CFF_CPHS: " +
- IccUtils.bytesToHexString(data));
+ log("EF_CFF_CPHS: " + IccUtils.bytesToHexString(data));
mEfCff = data;
if (mEfCfis == null) {
case EVENT_UPDATE_DONE:
ar = (AsyncResult)msg.obj;
if (ar.exception != null) {
- Log.i(LOG_TAG, "SIMRecords update failed", ar.exception);
+ logw("update failed. ", ar.exception);
}
break;
int[] index = (int[])ar.result;
if (ar.exception != null || index.length != 1) {
- Log.e(LOG_TAG, "[SIMRecords] Error on SMS_ON_SIM with exp "
+ loge("Error on SMS_ON_SIM with exp "
+ ar.exception + " length " + index.length);
} else {
- Log.d(LOG_TAG, "READ EF_SMS RECORD index=" + index[0]);
+ log("READ EF_SMS RECORD index=" + index[0]);
phone.getIccFileHandler().loadEFLinearFixed(EF_SMS,index[0],
obtainMessage(EVENT_GET_SMS_DONE));
}
if (ar.exception == null) {
handleSms((byte[])ar.result);
} else {
- Log.e(LOG_TAG, "[SIMRecords] Error on GET_SMS with exp "
- + ar.exception);
+ loge("Error on GET_SMS with exp " + ar.exception);
}
break;
case EVENT_GET_SST_DONE:
case EVENT_SIM_REFRESH:
isRecordLoadResponse = false;
ar = (AsyncResult)msg.obj;
- if (DBG) log("Sim REFRESH with exception: " + ar.exception);
+ if (DBG) log("Sim REFRESH with exception: " + ar.exception);
if (ar.exception == null) {
handleSimRefresh((int[])(ar.result));
}
break;
}
- Log.d(LOG_TAG, "EF_CFIS: " +
- IccUtils.bytesToHexString(data));
+ log("EF_CFIS: " + IccUtils.bytesToHexString(data));
mEfCfis = data;
ar = (AsyncResult)msg.obj;
if (ar.exception != null) {
- Log.e(LOG_TAG,"Exception in fetching EF_CSP data " + ar.exception);
+ loge("Exception in fetching EF_CSP data " + ar.exception);
break;
}
data = (byte[])ar.result;
- Log.i(LOG_TAG,"EF_CSP: " + IccUtils.bytesToHexString(data));
+ log("EF_CSP: " + IccUtils.bytesToHexString(data));
handleEfCspData(data);
break;
}}catch (RuntimeException exc) {
// I don't want these exceptions to be fatal
- Log.w(LOG_TAG, "Exception parsing SIM record", exc);
+ logw("Exception parsing SIM record", exc);
} finally {
// Count up record load responses even if they are fails
if (isRecordLoadResponse) {
break;
case EF_CSP_CPHS:
recordsToLoad++;
- Log.i(LOG_TAG, "[CSP] SIM Refresh for EF_CSP_CPHS");
+ log("[CSP] SIM Refresh for EF_CSP_CPHS");
phone.getIccFileHandler().loadEFTransparent(EF_CSP_CPHS,
obtainMessage(EVENT_GET_CSP_CPHS_DONE));
break;
if (recordsToLoad == 0 && recordsRequested == true) {
onAllRecordsLoaded();
} else if (recordsToLoad < 0) {
- Log.e(LOG_TAG, "SIMRecords: recordsToLoad <0, programmer error suspected");
+ loge("recordsToLoad <0, programmer error suspected");
recordsToLoad = 0;
}
}
protected void onAllRecordsLoaded() {
- Log.d(LOG_TAG, "SIMRecords: record load complete");
+ log("record load complete");
String operator = getOperatorNumeric();
MccTable.countryCodeForMcc(Integer.parseInt(imsi.substring(0,3))));
}
else {
- Log.e("SIM", "[SIMRecords] onAllRecordsLoaded: imsi is NULL!");
+ loge("onAllRecordsLoaded: imsi is NULL!");
}
setVoiceMailByCountry(operator);
recordsRequested = true;
IccFileHandler iccFh = phone.getIccFileHandler();
- Log.v(LOG_TAG, "SIMRecords:fetchSimRecords " + recordsToLoad);
+ logv("fetchSimRecords " + recordsToLoad);
phone.mCM.getIMSI(obtainMessage(EVENT_GET_IMSI_DONE));
recordsToLoad++;
Log.e(LOG_TAG, "[SIMRecords] " + s);
}
+ protected void logw(String s, Throwable tr) {
+ Log.w(LOG_TAG, "[SIMRecords] " + s, tr);
+ }
+
+ protected void logv(String s) {
+ Log.v(LOG_TAG, "[SIMRecords] " + s);
+ }
+
/**
* Return true if "Restriction of menu options for manual PLMN selection"
* bit is set or EF_CSP data is unavailable, return false otherwise.
mCspPlmnEnabled = true;
for (int i = 0; i < usedCspGroups; i++) {
if (data[2 * i] == valueAddedServicesGroup) {
- Log.i(LOG_TAG, "[CSP] found ValueAddedServicesGroup, value "
- + data[(2 * i) + 1]);
+ log("[CSP] found ValueAddedServicesGroup, value " + data[(2 * i) + 1]);
if ((data[(2 * i) + 1] & 0x80) == 0x80) {
// Bit 8 is for
// "Restriction of menu options for manual PLMN selection".
mCspPlmnEnabled = false;
// Operator Selection menu should be disabled.
// Operator Selection Mode should be set to Automatic.
- Log.i(LOG_TAG,"[CSP] Set Automatic Network Selection");
+ log("[CSP] Set Automatic Network Selection");
phone.setNetworkSelectionModeAutomatic(null);
}
return;
}
}
- Log.w(LOG_TAG, "[CSP] Value Added Service Group (0xC0), not found!");
+ log("[CSP] Value Added Service Group (0xC0), not found!");
}
}
*/
public final class SimCard extends IccCard {
- SimCard(GSMPhone phone) {
- super(phone, "GSM", true);
-
- mPhone.mCM.registerForSIMLockedOrAbsent(mHandler, EVENT_ICC_LOCKED_OR_ABSENT, null);
- mPhone.mCM.registerForOffOrNotAvailable(mHandler, EVENT_RADIO_OFF_OR_NOT_AVAILABLE, null);
- mPhone.mCM.registerForSIMReady(mHandler, EVENT_ICC_READY, null);
- updateStateProperty();
- }
-
- /**
- * We have the Sim card for LTE on CDMA phone
- */
public SimCard(PhoneBase phone, String logTag, Boolean dbg) {
super(phone, logTag, dbg);
- mPhone.mCM.registerForSIMLockedOrAbsent(mHandler, EVENT_ICC_LOCKED_OR_ABSENT, null);
- mPhone.mCM.registerForOffOrNotAvailable(mHandler, EVENT_RADIO_OFF_OR_NOT_AVAILABLE, null);
- mPhone.mCM.registerForSIMReady(mHandler, EVENT_ICC_READY, null);
updateStateProperty();
-
- if(mPhone.getLteOnCdmaMode() == Phone.LTE_ON_CDMA_TRUE) {
- mPhone.mCM.registerForIccStatusChanged(mHandler, EVENT_ICC_LOCKED_OR_ABSENT, null);
- }
- }
-
- @Override
- public void dispose() {
- super.dispose();
- //Unregister for all events
- mPhone.mCM.unregisterForSIMLockedOrAbsent(mHandler);
- mPhone.mCM.unregisterForOffOrNotAvailable(mHandler);
- mPhone.mCM.unregisterForSIMReady(mHandler);
-
- if(mPhone.getLteOnCdmaMode() == Phone.LTE_ON_CDMA_TRUE) {
- mPhone.mCM.unregisterForIccStatusChanged(mHandler);
- }
}
@Override
public void requestIsimAuthentication(String nonce, Message response) {
}
+
+ public void getVoiceRadioTechnology(Message result) {
+ }
}
if (pin != null && pin.equals(mPinCode)) {
Log.i(LOG_TAG, "[SimCmd] supplyIccPin: success!");
- setRadioState(RadioState.SIM_READY);
mPinUnlockAttempts = 0;
mSimLockedState = SimLockState.NONE;
+ mIccStatusChangedRegistrants.notifyRegistrants();
if (result != null) {
AsyncResult.forMessage(result, null, null);
if (puk != null && puk.equals(SIM_PUK_CODE)) {
Log.i(LOG_TAG, "[SimCmd] supplyIccPuk: success!");
- setRadioState(RadioState.SIM_READY);
mSimLockedState = SimLockState.NONE;
mPukUnlockAttempts = 0;
+ mIccStatusChangedRegistrants.notifyRegistrants();
if (result != null) {
AsyncResult.forMessage(result, null, null);
* The ar.result List is sorted by DriverCall.index
*/
public void getCurrentCalls (Message result) {
- if (mState == RadioState.SIM_READY) {
+ if ((mState == RadioState.RADIO_ON) && !isSimLocked()) {
//Log.i("GSM", "[SimCmds] getCurrentCalls");
resultSuccess(result, simulatedCallState.getDriverCalls());
} else {
- //Log.i("GSM", "[SimCmds] getCurrentCalls: SIM not ready!");
+ //Log.i("GSM", "[SimCmds] getCurrentCalls: RADIO_OFF or SIM not ready!");
resultFail(result,
new CommandException(
CommandException.Error.RADIO_NOT_AVAILABLE));
public void setRadioPower(boolean on, Message result) {
if(on) {
- if (isSimLocked()) {
- Log.i("SIM", "[SimCmd] setRadioPower: SIM locked! state=" +
- mSimLockedState);
- setRadioState(RadioState.SIM_LOCKED_OR_ABSENT);
- }
- else {
- setRadioState(RadioState.SIM_READY);
- }
+ setRadioState(RadioState.RADIO_ON);
} else {
setRadioState(RadioState.RADIO_OFF);
}
public void requestIsimAuthentication(String nonce, Message response) {
unimplemented(response);
}
+
+ public void getVoiceRadioTechnology(Message response) {
+ unimplemented(response);
+ }
}
@Override
public void requestIsimAuthentication(String nonce, Message response) {
}
+
+ @Override
+ public void getVoiceRadioTechnology(Message response) {
+ }
}