summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlex Yakavenka <ayakav@codeaurora.org>2012-07-26 15:34:10 -0700
committerWink Saville <wink@google.com>2012-08-08 20:48:20 -0700
commite0e2ebb5a50e580cbe6957dcafb3495a2d0a27f2 (patch)
tree4eed1415126fb7bb5caf178a3d1c119e09ae13f3
parentf7c060b9ded0613109c1cec05c537c4e846fecd4 (diff)
downloadframeworks_opt_telephony-e0e2ebb5a50e580cbe6957dcafb3495a2d0a27f2.zip
frameworks_opt_telephony-e0e2ebb5a50e580cbe6957dcafb3495a2d0a27f2.tar.gz
frameworks_opt_telephony-e0e2ebb5a50e580cbe6957dcafb3495a2d0a27f2.tar.bz2
Telephony: Dynamically instantiate IccCard
Instantiate when get_sim_status request returns Change-Id: I9c9333d23f1e0b23256731b245577d1a25721647
-rw-r--r--src/java/com/android/internal/telephony/DataConnectionTracker.java13
-rw-r--r--src/java/com/android/internal/telephony/IccCard.java131
-rw-r--r--src/java/com/android/internal/telephony/IccPhoneBookInterfaceManager.java12
-rw-r--r--src/java/com/android/internal/telephony/IccRecords.java18
-rw-r--r--src/java/com/android/internal/telephony/PhoneBase.java40
-rw-r--r--src/java/com/android/internal/telephony/ServiceStateTracker.java33
-rw-r--r--src/java/com/android/internal/telephony/cdma/CDMALTEPhone.java41
-rwxr-xr-xsrc/java/com/android/internal/telephony/cdma/CDMAPhone.java67
-rw-r--r--src/java/com/android/internal/telephony/cdma/CdmaDataConnectionTracker.java39
-rw-r--r--src/java/com/android/internal/telephony/cdma/CdmaLteServiceStateTracker.java14
-rwxr-xr-xsrc/java/com/android/internal/telephony/cdma/CdmaServiceStateTracker.java74
-rw-r--r--src/java/com/android/internal/telephony/cdma/RuimPhoneBookInterfaceManager.java10
-rwxr-xr-xsrc/java/com/android/internal/telephony/cdma/RuimRecords.java19
-rw-r--r--src/java/com/android/internal/telephony/gsm/GSMPhone.java130
-rw-r--r--src/java/com/android/internal/telephony/gsm/GsmDataConnectionTracker.java49
-rw-r--r--src/java/com/android/internal/telephony/gsm/GsmMmiCode.java15
-rw-r--r--src/java/com/android/internal/telephony/gsm/GsmServiceStateTracker.java64
-rwxr-xr-xsrc/java/com/android/internal/telephony/gsm/SIMRecords.java8
-rw-r--r--src/java/com/android/internal/telephony/gsm/SimPhoneBookInterfaceManager.java9
-rwxr-xr-xsrc/java/com/android/internal/telephony/sip/SipPhoneBase.java4
-rw-r--r--src/java/com/android/internal/telephony/uicc/UiccController.java131
21 files changed, 643 insertions, 278 deletions
diff --git a/src/java/com/android/internal/telephony/DataConnectionTracker.java b/src/java/com/android/internal/telephony/DataConnectionTracker.java
index ef50b91..fdaf0a3 100644
--- a/src/java/com/android/internal/telephony/DataConnectionTracker.java
+++ b/src/java/com/android/internal/telephony/DataConnectionTracker.java
@@ -47,6 +47,7 @@ import android.util.Log;
import com.android.internal.R;
import com.android.internal.telephony.DataConnection.FailCause;
import com.android.internal.telephony.DctConstants;
+import com.android.internal.telephony.uicc.UiccController;
import com.android.internal.util.AsyncChannel;
import java.io.FileDescriptor;
@@ -57,6 +58,7 @@ import java.util.Map.Entry;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicInteger;
+import java.util.concurrent.atomic.AtomicReference;
/**
* {@hide}
@@ -166,11 +168,12 @@ public abstract class DataConnectionTracker extends Handler {
// member variables
protected PhoneBase mPhone;
+ protected UiccController mUiccController;
+ protected AtomicReference<IccRecords> mIccRecords = new AtomicReference<IccRecords>();
protected DctConstants.Activity mActivity = DctConstants.Activity.NONE;
protected DctConstants.State mState = DctConstants.State.IDLE;
protected Handler mDataConnectionTracker = null;
-
protected long mTxPkts;
protected long mRxPkts;
protected int mNetStatPollPeriod;
@@ -419,6 +422,8 @@ public abstract class DataConnectionTracker extends Handler {
super();
if (DBG) log("DCT.constructor");
mPhone = phone;
+ mUiccController = UiccController.getInstance();
+ mUiccController.registerForIccChanged(this, DctConstants.EVENT_ICC_CHANGED, null);
IntentFilter filter = new IntentFilter();
filter.addAction(getActionIntentReconnectAlarm());
@@ -461,6 +466,7 @@ public abstract class DataConnectionTracker extends Handler {
mIsDisposed = true;
mPhone.getContext().unregisterReceiver(this.mIntentReceiver);
mDataRoamingSettingObserver.unregister(mPhone.getContext());
+ mUiccController.unregisterForIccChanged(this);
}
protected void broadcastMessenger() {
@@ -583,6 +589,7 @@ public abstract class DataConnectionTracker extends Handler {
protected abstract void onCleanUpConnection(boolean tearDown, int apnId, String reason);
protected abstract void onCleanUpAllConnections(String cause);
protected abstract boolean isDataPossible(String apnType);
+ protected abstract void onUpdateIcc();
protected void onDataStallAlarm(int tag) {
loge("onDataStallAlarm: not impleted tag=" + tag);
@@ -693,6 +700,10 @@ public abstract class DataConnectionTracker extends Handler {
onSetPolicyDataEnabled(enabled);
break;
}
+ case DctConstants.EVENT_ICC_CHANGED:
+ onUpdateIcc();
+ break;
+
default:
Log.e("DATA", "Unidentified event msg=" + msg);
break;
diff --git a/src/java/com/android/internal/telephony/IccCard.java b/src/java/com/android/internal/telephony/IccCard.java
index 740292c..b093ef7 100644
--- a/src/java/com/android/internal/telephony/IccCard.java
+++ b/src/java/com/android/internal/telephony/IccCard.java
@@ -34,10 +34,13 @@ import android.view.WindowManager;
import com.android.internal.telephony.PhoneBase;
import com.android.internal.telephony.CommandsInterface.RadioState;
+import com.android.internal.telephony.gsm.GSMPhone;
import com.android.internal.telephony.gsm.SIMFileHandler;
import com.android.internal.telephony.gsm.SIMRecords;
+import com.android.internal.telephony.sip.SipPhone;
import com.android.internal.telephony.cat.CatService;
import com.android.internal.telephony.cdma.CDMALTEPhone;
+import com.android.internal.telephony.cdma.CDMAPhone;
import com.android.internal.telephony.cdma.CdmaLteUiccFileHandler;
import com.android.internal.telephony.cdma.CdmaLteUiccRecords;
import com.android.internal.telephony.cdma.CdmaSubscriptionSourceManager;
@@ -84,8 +87,6 @@ public class IccCard {
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_REPOLL_STATUS_DONE = 5;
protected static final int EVENT_ICC_READY = 6;
private static final int EVENT_QUERY_FACILITY_LOCK_DONE = 7;
private static final int EVENT_CHANGE_FACILITY_LOCK_DONE = 8;
@@ -122,34 +123,19 @@ public class IccCard {
return IccCardConstants.State.UNKNOWN;
}
- public IccCard(PhoneBase phone, String logTag, Boolean is3gpp, Boolean dbg) {
+ public IccCard(PhoneBase phone, IccCardStatus ics, String logTag, boolean dbg) {
mLogTag = logTag;
mDbg = dbg;
- if (mDbg) log("[IccCard] Creating card type " + (is3gpp ? "3gpp" : "3gpp2"));
- mPhone = phone;
- this.is3gpp = is3gpp;
+ if (mDbg) log("Creating");
+ update(phone, ics);
mCdmaSSM = CdmaSubscriptionSourceManager.getInstance(mPhone.getContext(),
mPhone.mCM, mHandler, EVENT_CDMA_SUBSCRIPTION_SOURCE_CHANGED, null);
- if (phone.mCM.getLteOnCdmaMode() == PhoneConstants.LTE_ON_CDMA_TRUE
- && phone instanceof CDMALTEPhone) {
- mIccFileHandler = new CdmaLteUiccFileHandler(this, "", mPhone.mCM);
- mIccRecords = new CdmaLteUiccRecords(this, mPhone.mContext, mPhone.mCM);
- } else {
- // Correct aid will be set later (when GET_SIM_STATUS returns)
- mIccFileHandler = is3gpp ? new SIMFileHandler(this, "", mPhone.mCM) :
- new RuimFileHandler(this, "", mPhone.mCM);
- mIccRecords = is3gpp ? new SIMRecords(this, mPhone.mContext, mPhone.mCM) :
- new RuimRecords(this, mPhone.mContext, mPhone.mCM);
- }
- mCatService = CatService.getInstance(mPhone.mCM, mIccRecords,
- mPhone.mContext, mIccFileHandler, this);
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);
}
public void dispose() {
- if (mDbg) log("[IccCard] Disposing card type " + (is3gpp ? "3gpp" : "3gpp2"));
+ if (mDbg) log("Disposing card type " + (is3gpp ? "3gpp" : "3gpp2"));
mPhone.mCM.unregisterForIccStatusChanged(mHandler);
mPhone.mCM.unregisterForOffOrNotAvailable(mHandler);
mPhone.mCM.unregisterForOn(mHandler);
@@ -159,6 +145,42 @@ public class IccCard {
mIccFileHandler.dispose();
}
+ public void update(PhoneBase phone, IccCardStatus ics) {
+ if (phone != mPhone) {
+ PhoneBase oldPhone = mPhone;
+ mPhone = phone;
+ log("Update");
+ if (phone instanceof GSMPhone) {
+ is3gpp = true;
+ } else if (phone instanceof CDMALTEPhone){
+ is3gpp = true;
+ } else if (phone instanceof CDMAPhone){
+ is3gpp = false;
+ } else if (phone instanceof SipPhone){
+ is3gpp = true;
+ } else {
+ throw new RuntimeException("Update: Unhandled phone type. Critical error!" +
+ phone.getPhoneName());
+ }
+
+
+ if (phone.mCM.getLteOnCdmaMode() == PhoneConstants.LTE_ON_CDMA_TRUE
+ && phone instanceof CDMALTEPhone) {
+ mIccFileHandler = new CdmaLteUiccFileHandler(this, "", mPhone.mCM);
+ mIccRecords = new CdmaLteUiccRecords(this, mPhone.mContext, mPhone.mCM);
+ } else {
+ // Correct aid will be set later (when GET_SIM_STATUS returns)
+ mIccFileHandler = is3gpp ? new SIMFileHandler(this, "", mPhone.mCM) :
+ new RuimFileHandler(this, "", mPhone.mCM);
+ mIccRecords = is3gpp ? new SIMRecords(this, mPhone.mContext, mPhone.mCM) :
+ new RuimRecords(this, mPhone.mContext, mPhone.mCM);
+ }
+ mCatService = CatService.getInstance(mPhone.mCM, mIccRecords, mPhone.mContext,
+ mIccFileHandler, this);
+ }
+ mHandler.sendMessage(mHandler.obtainMessage(EVENT_GET_ICC_STATUS_DONE, ics));
+ }
+
protected void finalize() {
if (mDbg) log("[IccCard] Finalized card type " + (is3gpp ? "3gpp" : "3gpp2"));
}
@@ -289,27 +311,23 @@ public class IccCard {
*/
public void supplyPin (String pin, Message onComplete) {
- mPhone.mCM.supplyIccPin(pin, mHandler.obtainMessage(EVENT_PINPUK_DONE, onComplete));
+ mPhone.mCM.supplyIccPin(pin, onComplete);
}
public void supplyPuk (String puk, String newPin, Message onComplete) {
- mPhone.mCM.supplyIccPuk(puk, newPin,
- mHandler.obtainMessage(EVENT_PINPUK_DONE, onComplete));
+ mPhone.mCM.supplyIccPuk(puk, newPin, onComplete);
}
public void supplyPin2 (String pin2, Message onComplete) {
- mPhone.mCM.supplyIccPin2(pin2,
- mHandler.obtainMessage(EVENT_PINPUK_DONE, onComplete));
+ mPhone.mCM.supplyIccPin2(pin2, onComplete);
}
public void supplyPuk2 (String puk2, String newPin2, Message onComplete) {
- mPhone.mCM.supplyIccPuk2(puk2, newPin2,
- mHandler.obtainMessage(EVENT_PINPUK_DONE, onComplete));
+ mPhone.mCM.supplyIccPuk2(puk2, newPin2, onComplete);
}
public void supplyNetworkDepersonalization (String pin, Message onComplete) {
- mPhone.mCM.supplyNetworkDepersonalization(pin,
- mHandler.obtainMessage(EVENT_PINPUK_DONE, onComplete));
+ mPhone.mCM.supplyNetworkDepersonalization(pin, onComplete);
}
/**
@@ -439,21 +457,15 @@ public class IccCard {
*
*/
public String getServiceProviderName () {
- return mPhone.mIccRecords.getServiceProviderName();
+ return mIccRecords.getServiceProviderName();
}
protected void updateStateProperty() {
mPhone.setSystemProperty(TelephonyProperties.PROPERTY_SIM_STATE, getState().toString());
}
- private void getIccCardStatusDone(AsyncResult ar) {
- if (ar.exception != null) {
- Log.e(mLogTag,"Error getting ICC status. "
- + "RIL_REQUEST_GET_ICC_STATUS should "
- + "never return an error", ar.exception);
- return;
- }
- handleIccCardStatus((IccCardStatus) ar.result);
+ private void getIccCardStatusDone(IccCardStatus ics) {
+ handleIccCardStatus(ics);
}
private void handleIccCardStatus(IccCardStatus newCardStatus) {
@@ -534,11 +546,8 @@ public class IccCard {
// Call onReady Record(s) on the IccCard becomes ready (not NV)
if (oldState != IccCardConstants.State.READY && newState == IccCardConstants.State.READY &&
(is3gpp || isSubscriptionFromIccCard)) {
- if (!(mIccFileHandler instanceof CdmaLteUiccFileHandler)) {
- // CdmaLteUicc File Handler deals with both USIM and CSIM.
- // Do not lock onto one AID for now.
- mIccFileHandler.setAid(getAid());
- }
+ mIccFileHandler.setAid(getAid());
+ broadcastIccStateChangedIntent(IccCardConstants.INTENT_VALUE_ICC_READY, null);
mIccRecords.onReady();
}
}
@@ -660,7 +669,6 @@ public class IccCard {
if (!is3gpp) {
handleCdmaSubscriptionSource();
}
- mPhone.mCM.getIccCardStatus(obtainMessage(EVENT_GET_ICC_STATUS_DONE));
break;
case EVENT_CDMA_SUBSCRIPTION_SOURCE_CHANGED:
handleCdmaSubscriptionSource();
@@ -681,30 +689,9 @@ public class IccCard {
obtainMessage(EVENT_QUERY_FACILITY_LOCK_DONE));
break;
case EVENT_GET_ICC_STATUS_DONE:
- ar = (AsyncResult)msg.obj;
-
- getIccCardStatusDone(ar);
- break;
- case EVENT_PINPUK_DONE:
- // a PIN/PUK/PIN2/PUK2/Network Personalization
- // request has completed. ar.userObj is the response Message
- // Repoll before returning
- ar = (AsyncResult)msg.obj;
- // TODO should abstract these exceptions
- AsyncResult.forMessage(((Message)ar.userObj)).exception
- = ar.exception;
- mPhone.mCM.getIccCardStatus(
- obtainMessage(EVENT_REPOLL_STATUS_DONE, ar.userObj));
- break;
- case EVENT_REPOLL_STATUS_DONE:
- // Finished repolling status after PIN operation
- // ar.userObj is the response messaeg
- // ar.userObj.obj is already an AsyncResult with an
- // appropriate exception filled in if applicable
+ IccCardStatus cs = (IccCardStatus)msg.obj;
- ar = (AsyncResult)msg.obj;
- getIccCardStatusDone(ar);
- ((Message)ar.userObj).sendToTarget();
+ getIccCardStatusDone(cs);
break;
case EVENT_QUERY_FACILITY_LOCK_DONE:
ar = (AsyncResult)msg.obj;
@@ -753,10 +740,6 @@ public class IccCard {
= ar.exception;
((Message)ar.userObj).sendToTarget();
break;
- case EVENT_ICC_STATUS_CHANGED:
- Log.d(mLogTag, "Received Event EVENT_ICC_STATUS_CHANGED");
- mPhone.mCM.getIccCardStatus(obtainMessage(EVENT_GET_ICC_STATUS_DONE));
- break;
case EVENT_CARD_REMOVED:
onIccSwap(false);
break;
@@ -926,6 +909,10 @@ public class IccCard {
Log.d(mLogTag, "[IccCard] " + msg);
}
+ private void loge(String msg) {
+ Log.e(mLogTag, "[IccCard] " + msg);
+ }
+
protected int getCurrentApplicationIndex() {
if (is3gpp) {
return mIccCardStatus.getGsmUmtsSubscriptionAppIndex();
diff --git a/src/java/com/android/internal/telephony/IccPhoneBookInterfaceManager.java b/src/java/com/android/internal/telephony/IccPhoneBookInterfaceManager.java
index 45562ca..0e5f2da 100644
--- a/src/java/com/android/internal/telephony/IccPhoneBookInterfaceManager.java
+++ b/src/java/com/android/internal/telephony/IccPhoneBookInterfaceManager.java
@@ -103,11 +103,23 @@ public abstract class IccPhoneBookInterfaceManager extends IIccPhoneBook.Stub {
public IccPhoneBookInterfaceManager(PhoneBase phone) {
this.phone = phone;
+ IccRecords r = phone.mIccRecords.get();
+ if (r != null) {
+ adnCache = r.getAdnCache();
+ }
}
public void dispose() {
}
+ public void updateIccRecords(IccRecords iccRecords) {
+ if (iccRecords != null) {
+ adnCache = iccRecords.getAdnCache();
+ } else {
+ adnCache = null;
+ }
+ }
+
protected void publish() {
//NOTE service "simphonebook" added by IccSmsInterfaceManagerProxy
ServiceManager.addService("simphonebook", this);
diff --git a/src/java/com/android/internal/telephony/IccRecords.java b/src/java/com/android/internal/telephony/IccRecords.java
index 41c9d5a..3c90647 100644
--- a/src/java/com/android/internal/telephony/IccRecords.java
+++ b/src/java/com/android/internal/telephony/IccRecords.java
@@ -26,6 +26,8 @@ import android.os.RegistrantList;
import com.android.internal.telephony.gsm.UsimServiceTable;
import com.android.internal.telephony.ims.IsimRecords;
+import java.util.concurrent.atomic.AtomicBoolean;
+
/**
* {@hide}
*/
@@ -33,7 +35,7 @@ public abstract class IccRecords extends Handler implements IccConstants {
protected static final boolean DBG = true;
// ***** Instance Variables
- protected boolean mDestroyed = false; // set to true once this object needs to be disposed of
+ protected AtomicBoolean mDestroyed = new AtomicBoolean(false);
protected Context mContext;
protected CommandsInterface mCi;
protected IccFileHandler mFh;
@@ -79,9 +81,9 @@ public abstract class IccRecords extends Handler implements IccConstants {
// ***** Event Constants
protected static final int EVENT_SET_MSISDN_DONE = 30;
- public static final int EVENT_MWI = 0;
- public static final int EVENT_CFI = 1;
- public static final int EVENT_SPN = 2;
+ public static final int EVENT_MWI = 0; // Message Waiting indication
+ public static final int EVENT_CFI = 1; // Call Forwarding indication
+ public static final int EVENT_SPN = 2; // Service Provider Name
public static final int EVENT_GET_ICC_RECORD_DONE = 100;
@@ -113,7 +115,7 @@ public abstract class IccRecords extends Handler implements IccConstants {
* Call when the IccRecords object is no longer going to be used.
*/
public void dispose() {
- mDestroyed = true;
+ mDestroyed.set(true);
mParentCard = null;
mFh = null;
mCi = null;
@@ -128,12 +130,8 @@ public abstract class IccRecords extends Handler implements IccConstants {
return adnCache;
}
- public IccCard getIccCard() {
- return mParentCard;
- }
-
public void registerForRecordsLoaded(Handler h, int what, Object obj) {
- if (mDestroyed) {
+ if (mDestroyed.get()) {
return;
}
diff --git a/src/java/com/android/internal/telephony/PhoneBase.java b/src/java/com/android/internal/telephony/PhoneBase.java
index b55240a..866628b 100644
--- a/src/java/com/android/internal/telephony/PhoneBase.java
+++ b/src/java/com/android/internal/telephony/PhoneBase.java
@@ -40,6 +40,7 @@ import com.android.internal.R;
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.uicc.UiccController;
import com.android.internal.telephony.gsm.SIMRecords;
import java.io.FileDescriptor;
@@ -110,6 +111,7 @@ public abstract class PhoneBase extends Handler implements Phone {
protected static final int EVENT_SET_NETWORK_AUTOMATIC = 28;
protected static final int EVENT_NEW_ICC_SMS = 29;
protected static final int EVENT_ICC_RECORD_EVENTS = 30;
+ protected static final int EVENT_ICC_CHANGED = 31;
// Key used to read/write current CLIR setting
public static final String CLIR_KEY = "clir_key";
@@ -126,7 +128,8 @@ public abstract class PhoneBase extends Handler implements Phone {
int mCallRingDelay;
public boolean mIsTheCurrentActivePhone = true;
boolean mIsVoiceCapable = true;
- public IccRecords mIccRecords;
+ protected UiccController mUiccController = null;
+ public AtomicReference<IccRecords> mIccRecords = new AtomicReference<IccRecords>();
protected AtomicReference<IccCard> mIccCard = new AtomicReference<IccCard>();
public SmsStorageMonitor mSmsStorageMonitor;
public SmsUsageMonitor mSmsUsageMonitor;
@@ -251,6 +254,8 @@ public abstract class PhoneBase extends Handler implements Phone {
// Initialize device storage and outgoing SMS usage monitors for SMSDispatchers.
mSmsStorageMonitor = new SmsStorageMonitor(this);
mSmsUsageMonitor = new SmsUsageMonitor(context);
+ mUiccController = UiccController.getInstance(this);
+ mUiccController.registerForIccChanged(this, EVENT_ICC_CHANGED, null);
}
public void dispose() {
@@ -262,6 +267,7 @@ public abstract class PhoneBase extends Handler implements Phone {
// Dispose the SMS usage and storage monitors
mSmsStorageMonitor.dispose();
mSmsUsageMonitor.dispose();
+ mUiccController.unregisterForIccChanged(this);
}
}
@@ -269,9 +275,10 @@ public abstract class PhoneBase extends Handler implements Phone {
mSmsStorageMonitor = null;
mSmsUsageMonitor = null;
mSMS = null;
- mIccRecords = null;
+ mIccRecords.set(null);
mIccCard.set(null);
mDataConnectionTracker = null;
+ mUiccController = null;
}
/**
@@ -309,6 +316,10 @@ public abstract class PhoneBase extends Handler implements Phone {
}
break;
+ case EVENT_ICC_CHANGED:
+ onUpdateIccAvailability();
+ break;
+
default:
throw new RuntimeException("unexpected event not handled");
}
@@ -319,6 +330,9 @@ public abstract class PhoneBase extends Handler implements Phone {
return mContext;
}
+ // Will be called when icc changed
+ protected abstract void onUpdateIccAvailability();
+
/**
* Disables the DNS check (i.e., allows "0.0.0.0").
* Useful for lab testing environment.
@@ -667,22 +681,26 @@ public abstract class PhoneBase extends Handler implements Phone {
@Override
public String getIccSerialNumber() {
- return mIccRecords.iccid;
+ IccRecords r = mIccRecords.get();
+ return (r != null) ? r.iccid : "";
}
@Override
public boolean getIccRecordsLoaded() {
- return mIccRecords.getRecordsLoaded();
+ IccRecords r = mIccRecords.get();
+ return (r != null) ? r.getRecordsLoaded() : false;
}
@Override
public boolean getMessageWaitingIndicator() {
- return mIccRecords.getVoiceMessageWaiting();
+ IccRecords r = mIccRecords.get();
+ return (r != null) ? r.getVoiceMessageWaiting() : false;
}
@Override
public boolean getCallForwardingIndicator() {
- return mIccRecords.getVoiceCallForwardingFlag();
+ IccRecords r = mIccRecords.get();
+ return (r != null) ? r.getVoiceCallForwardingFlag() : false;
}
/**
@@ -1136,7 +1154,10 @@ public abstract class PhoneBase extends Handler implements Phone {
*/
@Override
public void setVoiceMessageWaiting(int line, int countWaiting) {
- mIccRecords.setVoiceMessageWaiting(line, countWaiting);
+ IccRecords r = mIccRecords.get();
+ if (r != null) {
+ r.setVoiceMessageWaiting(line, countWaiting);
+ }
}
/**
@@ -1145,7 +1166,8 @@ public abstract class PhoneBase extends Handler implements Phone {
*/
@Override
public UsimServiceTable getUsimServiceTable() {
- return mIccRecords.getUsimServiceTable();
+ IccRecords r = mIccRecords.get();
+ return (r != null) ? r.getUsimServiceTable() : null;
}
public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
@@ -1158,7 +1180,7 @@ public abstract class PhoneBase extends Handler implements Phone {
pw.println(" mCallRingDelay=" + mCallRingDelay);
pw.println(" mIsTheCurrentActivePhone=" + mIsTheCurrentActivePhone);
pw.println(" mIsVoiceCapable=" + mIsVoiceCapable);
- pw.println(" mIccRecords=" + mIccRecords);
+ pw.println(" mIccRecords=" + mIccRecords.get());
pw.println(" mIccCard=" + mIccCard.get());
pw.println(" mSmsStorageMonitor=" + mSmsStorageMonitor);
pw.println(" mSmsUsageMonitor=" + mSmsUsageMonitor);
diff --git a/src/java/com/android/internal/telephony/ServiceStateTracker.java b/src/java/com/android/internal/telephony/ServiceStateTracker.java
index e4cfb23..178addd 100644
--- a/src/java/com/android/internal/telephony/ServiceStateTracker.java
+++ b/src/java/com/android/internal/telephony/ServiceStateTracker.java
@@ -18,6 +18,7 @@ package com.android.internal.telephony;
import android.os.AsyncResult;
import android.os.Handler;
+import android.os.Looper;
import android.os.Message;
import android.os.Registrant;
import android.os.RegistrantList;
@@ -28,12 +29,17 @@ import android.util.TimeUtils;
import java.io.FileDescriptor;
import java.io.PrintWriter;
+import com.android.internal.telephony.uicc.UiccController;
+
/**
* {@hide}
*/
public abstract class ServiceStateTracker extends Handler {
protected CommandsInterface cm;
+ protected UiccController mUiccController = null;
+ protected IccCard mIccCard = null;
+ protected IccRecords mIccRecords = null;
public ServiceState ss;
protected ServiceState newSS;
@@ -131,7 +137,7 @@ public abstract class ServiceStateTracker extends Handler {
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 int EVENT_ICC_CHANGED = 42;
protected static final String TIMEZONE_PROPERTY = "persist.sys.timezone";
@@ -168,7 +174,10 @@ public abstract class ServiceStateTracker extends Handler {
protected static final String REGISTRATION_DENIED_GEN = "General";
protected static final String REGISTRATION_DENIED_AUTH = "Authentication Failure";
- public ServiceStateTracker() {
+ public ServiceStateTracker(PhoneBase p, CommandsInterface ci) {
+ cm = ci;
+ mUiccController = UiccController.getInstance();
+ mUiccController.registerForIccChanged(this, EVENT_ICC_CHANGED, null);
}
public boolean getDesiredPowerState() {
@@ -295,6 +304,10 @@ public abstract class ServiceStateTracker extends Handler {
}
break;
+ case EVENT_ICC_CHANGED:
+ onUpdateIccAvailability();
+ break;
+
default:
log("Unhandled message with number: " + msg.what);
break;
@@ -305,6 +318,7 @@ public abstract class ServiceStateTracker extends Handler {
protected abstract void handlePollStateResult(int what, AsyncResult ar);
protected abstract void updateSpnDisplay();
protected abstract void setPowerStateToDesired();
+ protected abstract void onUpdateIccAvailability();
protected abstract void log(String s);
protected abstract void loge(String s);
@@ -535,4 +549,19 @@ public abstract class ServiceStateTracker extends Handler {
pw.println(" mPendingRadioPowerOffAfterDataOff=" + mPendingRadioPowerOffAfterDataOff);
pw.println(" mPendingRadioPowerOffAfterDataOffTag=" + mPendingRadioPowerOffAfterDataOffTag);
}
+
+ /**
+ * Verifies the current thread is the same as the thread originally
+ * used in the initialization of this instance. Throws RuntimeException
+ * if not.
+ *
+ * @exception RuntimeException if the current thread is not
+ * the thread that originally obtained this PhoneBase instance.
+ */
+ protected void checkCorrectThread() {
+ if (Thread.currentThread() != getLooper().getThread()) {
+ throw new RuntimeException(
+ "ServiceStateTracker must be used from within one thread");
+ }
+ }
}
diff --git a/src/java/com/android/internal/telephony/cdma/CDMALTEPhone.java b/src/java/com/android/internal/telephony/cdma/CDMALTEPhone.java
index df42515..f125484 100644
--- a/src/java/com/android/internal/telephony/cdma/CDMALTEPhone.java
+++ b/src/java/com/android/internal/telephony/cdma/CDMALTEPhone.java
@@ -29,6 +29,7 @@ import android.util.Log;
import com.android.internal.telephony.CommandsInterface;
import com.android.internal.telephony.IccCard;
+import com.android.internal.telephony.IccRecords;
import com.android.internal.telephony.OperatorInfo;
import com.android.internal.telephony.Phone;
import com.android.internal.telephony.PhoneConstants;
@@ -67,7 +68,6 @@ public class CDMALTEPhone extends CDMAPhone {
public CDMALTEPhone(Context context, CommandsInterface ci, PhoneNotifier notifier) {
super(context, ci, notifier, false);
m3gppSMS = new GsmSMSDispatcher(this, mSmsStorageMonitor, mSmsUsageMonitor);
- mIccRecords.registerForNewSms(this, EVENT_NEW_ICC_SMS, null);
}
@Override
@@ -89,10 +89,6 @@ public class CDMALTEPhone extends CDMAPhone {
@Override
protected void initSstIcc() {
- mIccCard.set(UiccController.getInstance(this).getIccCard());
- mIccRecords = mIccCard.get().getIccRecords();
- // CdmaLteServiceStateTracker registers with IccCard to know
- // when the card is ready. So create mIccCard before the ServiceStateTracker
mSST = new CdmaLteServiceStateTracker(this);
}
@@ -101,7 +97,6 @@ public class CDMALTEPhone extends CDMAPhone {
synchronized(PhoneProxy.lockForRadioTechnologyChange) {
super.dispose();
m3gppSMS.dispose();
- mIccRecords.unregisterForNewSms(this);
}
}
@@ -205,11 +200,12 @@ public class CDMALTEPhone extends CDMAPhone {
@Override
public boolean updateCurrentCarrierInProvider() {
- if (mIccRecords != null) {
+ IccRecords r = mIccRecords.get();
+ if (r != null) {
try {
Uri uri = Uri.withAppendedPath(Telephony.Carriers.CONTENT_URI, "current");
ContentValues map = new ContentValues();
- String operatorNumeric = mIccRecords.getOperatorNumeric();
+ String operatorNumeric = r.getOperatorNumeric();
map.put(Telephony.Carriers.NUMERIC, operatorNumeric);
if (DBG) log("updateCurrentCarrierInProvider from UICC: numeric=" +
operatorNumeric);
@@ -227,7 +223,8 @@ public class CDMALTEPhone extends CDMAPhone {
// return IMSI from USIM as subscriber ID.
@Override
public String getSubscriberId() {
- return mIccRecords.getIMSI();
+ IccRecords r = mIccRecords.get();
+ return (r != null) ? r.getIMSI() : "";
}
@Override
@@ -242,12 +239,14 @@ public class CDMALTEPhone extends CDMAPhone {
@Override
public IsimRecords getIsimRecords() {
- return mIccRecords.getIsimRecords();
+ IccRecords r = mIccRecords.get();
+ return (r != null) ? r.getIsimRecords() : null;
}
@Override
public String getMsisdn() {
- return mIccRecords.getMsisdnNumber();
+ IccRecords r = mIccRecords.get();
+ return (r != null) ? r.getMsisdnNumber() : null;
}
@Override
@@ -261,6 +260,26 @@ public class CDMALTEPhone extends CDMAPhone {
}
@Override
+ protected void registerForRuimRecordEvents() {
+ IccRecords r = mIccRecords.get();
+ if (r == null) {
+ return;
+ }
+ r.registerForNewSms(this, EVENT_NEW_ICC_SMS, null);
+ super.registerForRuimRecordEvents();
+ }
+
+ @Override
+ protected void unregisterForRuimRecordEvents() {
+ IccRecords r = mIccRecords.get();
+ if (r == null) {
+ return;
+ }
+ r.unregisterForNewSms(this);
+ super.unregisterForRuimRecordEvents();
+ }
+
+ @Override
protected void log(String s) {
Log.d(LOG_TAG, "[CDMALTEPhone] " + s);
}
diff --git a/src/java/com/android/internal/telephony/cdma/CDMAPhone.java b/src/java/com/android/internal/telephony/cdma/CDMAPhone.java
index 26ef9dc..f88fa9c 100755
--- a/src/java/com/android/internal/telephony/cdma/CDMAPhone.java
+++ b/src/java/com/android/internal/telephony/cdma/CDMAPhone.java
@@ -50,6 +50,7 @@ import com.android.internal.telephony.IccCard;
import com.android.internal.telephony.IccException;
import com.android.internal.telephony.IccFileHandler;
import com.android.internal.telephony.IccPhoneBookInterfaceManager;
+import com.android.internal.telephony.IccRecords;
import com.android.internal.telephony.IccSmsInterfaceManager;
import com.android.internal.telephony.MccTable;
import com.android.internal.telephony.MmiCode;
@@ -153,10 +154,6 @@ public class CDMAPhone extends PhoneBase {
}
protected void initSstIcc() {
- mIccCard.set(UiccController.getInstance(this).getIccCard());
- mIccRecords = mIccCard.get().getIccRecords();
- // CdmaServiceStateTracker registers with IccCard to know
- // when the Ruim card is ready. So create mIccCard before the ServiceStateTracker
mSST = new CdmaServiceStateTracker(this);
}
@@ -173,7 +170,6 @@ public class CDMAPhone extends PhoneBase {
mEriManager = new EriManager(this, context, EriManager.ERI_FROM_XML);
mCM.registerForAvailable(this, EVENT_RADIO_AVAILABLE, null);
- registerForRuimRecordEvents();
mCM.registerForOffOrNotAvailable(this, EVENT_RADIO_OFF_OR_NOT_AVAILABLE, null);
mCM.registerForOn(this, EVENT_RADIO_ON, null);
mCM.setOnSuppServiceNotification(this, EVENT_SSN, null);
@@ -728,7 +724,10 @@ public class CDMAPhone extends PhoneBase {
Message resp;
mVmNumber = voiceMailNumber;
resp = obtainMessage(EVENT_SET_VM_NUMBER_DONE, 0, 0, onComplete);
- mIccRecords.setVoiceMailNumber(alphaTag, mVmNumber, resp);
+ IccRecords r = mIccRecords.get();
+ if (r != null) {
+ r.setVoiceMailNumber(alphaTag, mVmNumber, resp);
+ }
}
public String getVoiceMailNumber() {
@@ -750,7 +749,8 @@ public class CDMAPhone extends PhoneBase {
* @hide
*/
public int getVoiceMessageCount() {
- int voicemailCount = mIccRecords.getVoiceMessageCount();
+ IccRecords r = mIccRecords.get();
+ int voicemailCount = (r != null) ? r.getVoiceMessageCount() : 0;
// If mRuimRecords.getVoiceMessageCount returns zero, then there is possibility
// that phone was power cycled and would have lost the voicemail count.
// So get the count from preferences.
@@ -1065,6 +1065,39 @@ public class CDMAPhone extends PhoneBase {
}
}
+ @Override
+ protected void onUpdateIccAvailability() {
+ if (mUiccController == null ) {
+ return;
+ }
+
+ IccCard newIccCard = mUiccController.getIccCard();
+
+ IccCard c = mIccCard.get();
+ if (c != newIccCard) {
+ if (c != null) {
+ log("Removing stale icc objects.");
+ if (mIccRecords.get() != null) {
+ unregisterForRuimRecordEvents();
+ if (mRuimPhoneBookInterfaceManager != null) {
+ mRuimPhoneBookInterfaceManager.updateIccRecords(null);
+ }
+ }
+ mIccRecords.set(null);
+ mIccCard.set(null);
+ }
+ if (newIccCard != null) {
+ log("New card found");
+ mIccCard.set(newIccCard);
+ mIccRecords.set(newIccCard.getIccRecords());
+ registerForRuimRecordEvents();
+ if (mRuimPhoneBookInterfaceManager != null) {
+ mRuimPhoneBookInterfaceManager.updateIccRecords(mIccRecords.get());
+ }
+ }
+ }
+ }
+
private void processIccRecordEvents(int eventCode) {
switch (eventCode) {
case RuimRecords.EVENT_MWI:
@@ -1463,14 +1496,22 @@ public class CDMAPhone extends PhoneBase {
return mEriManager.isEriFileLoaded();
}
- private void registerForRuimRecordEvents() {
- mIccRecords.registerForRecordsEvents(this, EVENT_ICC_RECORD_EVENTS, null);
- mIccRecords.registerForRecordsLoaded(this, EVENT_RUIM_RECORDS_LOADED, null);
+ protected void registerForRuimRecordEvents() {
+ IccRecords r = mIccRecords.get();
+ if (r == null) {
+ return;
+ }
+ r.registerForRecordsEvents(this, EVENT_ICC_RECORD_EVENTS, null);
+ r.registerForRecordsLoaded(this, EVENT_RUIM_RECORDS_LOADED, null);
}
- private void unregisterForRuimRecordEvents() {
- mIccRecords.unregisterForRecordsEvents(this);
- mIccRecords.unregisterForRecordsLoaded(this);
+ protected void unregisterForRuimRecordEvents() {
+ IccRecords r = mIccRecords.get();
+ if (r == null) {
+ return;
+ }
+ r.unregisterForRecordsEvents(this);
+ r.unregisterForRecordsLoaded(this);
}
protected void log(String s) {
diff --git a/src/java/com/android/internal/telephony/cdma/CdmaDataConnectionTracker.java b/src/java/com/android/internal/telephony/cdma/CdmaDataConnectionTracker.java
index 20f1d08..51b4a4c 100644
--- a/src/java/com/android/internal/telephony/cdma/CdmaDataConnectionTracker.java
+++ b/src/java/com/android/internal/telephony/cdma/CdmaDataConnectionTracker.java
@@ -42,6 +42,8 @@ import com.android.internal.telephony.DataConnectionTracker;
import com.android.internal.telephony.DctConstants;
import com.android.internal.telephony.EventLogTags;
import com.android.internal.telephony.PhoneConstants;
+import com.android.internal.telephony.IccCard;
+import com.android.internal.telephony.IccRecords;
import com.android.internal.telephony.RetryManager;
import com.android.internal.telephony.RILConstants;
import com.android.internal.telephony.Phone;
@@ -104,7 +106,6 @@ public final class CdmaDataConnectionTracker extends DataConnectionTracker {
p.mCM.registerForAvailable (this, DctConstants.EVENT_RADIO_AVAILABLE, null);
p.mCM.registerForOffOrNotAvailable(this, DctConstants.EVENT_RADIO_OFF_OR_NOT_AVAILABLE, null);
- p.mIccRecords.registerForRecordsLoaded(this, DctConstants.EVENT_RECORDS_LOADED, null);
p.mCM.registerForDataNetworkStateChanged (this, DctConstants.EVENT_DATA_STATE_CHANGED, null);
p.mCT.registerForVoiceCallEnded (this, DctConstants.EVENT_VOICE_CALL_ENDED, null);
p.mCT.registerForVoiceCallStarted (this, DctConstants.EVENT_VOICE_CALL_STARTED, null);
@@ -146,7 +147,8 @@ public final class CdmaDataConnectionTracker extends DataConnectionTracker {
// Unregister from all events
mPhone.mCM.unregisterForAvailable(this);
mPhone.mCM.unregisterForOffOrNotAvailable(this);
- mCdmaPhone.mIccRecords.unregisterForRecordsLoaded(this);
+ IccRecords r = mIccRecords.get();
+ if (r != null) { r.unregisterForRecordsLoaded(this);}
mPhone.mCM.unregisterForDataNetworkStateChanged(this);
mCdmaPhone.mCT.unregisterForVoiceCallEnded(this);
mCdmaPhone.mCT.unregisterForVoiceCallStarted(this);
@@ -216,11 +218,12 @@ public final class CdmaDataConnectionTracker extends DataConnectionTracker {
boolean subscriptionFromNv = (mCdmaSSM.getCdmaSubscriptionSource()
== CdmaSubscriptionSourceManager.SUBSCRIPTION_FROM_NV);
+ IccRecords r = mIccRecords.get();
boolean allowed =
(psState == ServiceState.STATE_IN_SERVICE ||
mAutoAttachOnCreation) &&
(subscriptionFromNv ||
- mCdmaPhone.mIccRecords.getRecordsLoaded()) &&
+ (r != null && r.getRecordsLoaded())) &&
(mCdmaPhone.mSST.isConcurrentVoiceAndDataAllowed() ||
mPhone.getState() ==PhoneConstants.State.IDLE) &&
!roaming &&
@@ -235,7 +238,7 @@ public final class CdmaDataConnectionTracker extends DataConnectionTracker {
reason += " - psState= " + psState;
}
if (!subscriptionFromNv &&
- !mCdmaPhone.mIccRecords.getRecordsLoaded()) {
+ !(r != null && r.getRecordsLoaded())) {
reason += " - RUIM not loaded";
}
if (!(mCdmaPhone.mSST.isConcurrentVoiceAndDataAllowed() ||
@@ -1007,6 +1010,34 @@ public final class CdmaDataConnectionTracker extends DataConnectionTracker {
}
@Override
+ protected void onUpdateIcc() {
+ if (mUiccController == null ) {
+ return;
+ }
+
+ IccCard newIccCard = mUiccController.getIccCard();
+ IccRecords newIccRecords = null;
+ if (newIccCard != null) {
+ newIccRecords = newIccCard.getIccRecords();
+ }
+
+ IccRecords r = mIccRecords.get();
+ if (r != newIccRecords) {
+ if (r != null) {
+ log("Removing stale icc objects.");
+ r.unregisterForRecordsLoaded(this);
+ mIccRecords.set(null);
+ }
+ if (newIccRecords != null) {
+ log("New card found");
+ mIccRecords.set(newIccRecords);
+ newIccRecords.registerForRecordsLoaded(
+ this, DctConstants.EVENT_RECORDS_LOADED, null);
+ }
+ }
+ }
+
+ @Override
public boolean isDisconnected() {
return ((mState == DctConstants.State.IDLE) || (mState == DctConstants.State.FAILED));
}
diff --git a/src/java/com/android/internal/telephony/cdma/CdmaLteServiceStateTracker.java b/src/java/com/android/internal/telephony/cdma/CdmaLteServiceStateTracker.java
index 0c5c342..43db046 100644
--- a/src/java/com/android/internal/telephony/cdma/CdmaLteServiceStateTracker.java
+++ b/src/java/com/android/internal/telephony/cdma/CdmaLteServiceStateTracker.java
@@ -65,7 +65,7 @@ public class CdmaLteServiceStateTracker extends CdmaServiceStateTracker {
handlePollStateResult(msg.what, ar);
break;
case EVENT_RUIM_RECORDS_LOADED:
- CdmaLteUiccRecords sim = (CdmaLteUiccRecords)phone.mIccRecords;
+ CdmaLteUiccRecords sim = (CdmaLteUiccRecords)mIccRecords;
if ((sim != null) && sim.isProvisioned()) {
mMdn = sim.getMdn();
mMin = sim.getMin();
@@ -344,7 +344,7 @@ public class CdmaLteServiceStateTracker extends CdmaServiceStateTracker {
if (ss.getState() == ServiceState.STATE_IN_SERVICE) {
eriText = phone.getCdmaEriText();
} else if (ss.getState() == ServiceState.STATE_POWER_OFF) {
- eriText = phone.mIccRecords.getServiceProviderName();
+ eriText = (mIccRecords != null) ? mIccRecords.getServiceProviderName() : null;
if (TextUtils.isEmpty(eriText)) {
// Sets operator alpha property by retrieving from
// build-time system property
@@ -359,16 +359,18 @@ public class CdmaLteServiceStateTracker extends CdmaServiceStateTracker {
ss.setOperatorAlphaLong(eriText);
}
- if (phone.getIccCard().getState() == IccCardConstants.State.READY) {
+ if (mIccCard != null && mIccCard.getState() == IccCardConstants.State.READY &&
+ mIccRecords != null) {
// 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();
+ ((CdmaLteUiccRecords)mIccRecords).getCsimSpnDisplayCondition();
int iconIndex = ss.getCdmaEriIconIndex();
if (showSpn && (iconIndex == EriInfo.ROAMING_INDICATOR_OFF) &&
- isInHomeSidNid(ss.getSystemId(), ss.getNetworkId())) {
- ss.setOperatorAlphaLong(phone.mIccRecords.getServiceProviderName());
+ isInHomeSidNid(ss.getSystemId(), ss.getNetworkId()) &&
+ mIccRecords != null) {
+ ss.setOperatorAlphaLong(mIccRecords.getServiceProviderName());
}
}
diff --git a/src/java/com/android/internal/telephony/cdma/CdmaServiceStateTracker.java b/src/java/com/android/internal/telephony/cdma/CdmaServiceStateTracker.java
index 5a4af7a..8247d54 100755
--- a/src/java/com/android/internal/telephony/cdma/CdmaServiceStateTracker.java
+++ b/src/java/com/android/internal/telephony/cdma/CdmaServiceStateTracker.java
@@ -116,12 +116,6 @@ public class CdmaServiceStateTracker extends ServiceStateTracker {
long mSavedTime;
long mSavedAtTime;
- /**
- * We can't register for SIM_RECORDS_LOADED immediately because the
- * SIMRecords object may not be instantiated yet.
- */
- private boolean mNeedToRegForRuimLoaded = false;
-
/** Wake lock used while setting time of day. */
private PowerManager.WakeLock mWakeLock;
private static final String WAKELOCK_TAG = "ServiceStateTracker";
@@ -163,11 +157,10 @@ public class CdmaServiceStateTracker extends ServiceStateTracker {
};
public CdmaServiceStateTracker(CDMAPhone phone) {
- super();
+ super(phone, phone.mCM);
this.phone = phone;
cr = phone.getContext().getContentResolver();
- cm = phone.mCM;
ss = new ServiceState();
newSS = new ServiceState();
cellLoc = new CdmaCellLocation();
@@ -204,18 +197,17 @@ public class CdmaServiceStateTracker extends ServiceStateTracker {
Settings.System.getUriFor(Settings.System.AUTO_TIME_ZONE), true,
mAutoTimeZoneObserver);
setSignalStrengthDefaultValues();
-
- mNeedToRegForRuimLoaded = true;
}
public void dispose() {
+ checkCorrectThread();
// Unregister for all events.
cm.unregisterForRadioStateChanged(this);
cm.unregisterForVoiceNetworkStateChanged(this);
- phone.getIccCard().unregisterForReady(this);
cm.unregisterForCdmaOtaProvision(this);
phone.unregisterForEriFileLoaded(this);
- phone.mIccRecords.unregisterForRecordsLoaded(this);
+ if (mIccCard != null) {mIccCard.unregisterForReady(this);}
+ if (mIccRecords != null) {mIccRecords.unregisterForRecordsLoaded(this);}
cm.unSetOnSignalStrengthUpdate(this);
cm.unSetOnNITZTime(this);
cr.unregisterContentObserver(mAutoTimeObserver);
@@ -287,14 +279,6 @@ public class CdmaServiceStateTracker extends ServiceStateTracker {
// TODO: Consider calling setCurrentPreferredNetworkType as we do in GsmSST.
// cm.setCurrentPreferredNetworkType();
- // The RUIM is now ready i.e if it was locked it has been
- // unlocked. At this stage, the radio is already powered on.
- if (mNeedToRegForRuimLoaded) {
- phone.mIccRecords.registerForRecordsLoaded(this,
- EVENT_RUIM_RECORDS_LOADED, null);
- mNeedToRegForRuimLoaded = false;
- }
-
if (phone.getLteOnCdmaMode() == PhoneConstants.LTE_ON_CDMA_TRUE) {
// Subscription will be read from SIM I/O
if (DBG) log("Receive EVENT_RUIM_READY");
@@ -413,8 +397,19 @@ public class CdmaServiceStateTracker extends ServiceStateTracker {
mIsMinInfoReady = true;
updateOtaspState();
- phone.getIccCard().broadcastIccStateChangedIntent(
- IccCardConstants.INTENT_VALUE_ICC_IMSI, null);
+ if (mIccCard != null) {
+ if (DBG) {
+ log("GET_CDMA_SUBSCRIPTION broadcast Icc state changed");
+ }
+ mIccCard.broadcastIccStateChangedIntent(
+ IccCardConstants.INTENT_VALUE_ICC_IMSI,
+ null);
+ } else {
+ if (DBG) {
+ log("GET_CDMA_SUBSCRIPTION mIccCard is null (probably NV type device)" +
+ " can't broadcast Icc state changed");
+ }
+ }
} else {
if (DBG) {
log("GET_CDMA_SUBSCRIPTION: error parsing cdmaSubscription params num="
@@ -506,8 +501,6 @@ public class CdmaServiceStateTracker extends ServiceStateTracker {
if (!isSubscriptionFromRuim) {
// NV is ready when subscription source is NV
sendMessage(obtainMessage(EVENT_NV_READY));
- } else {
- phone.getIccCard().registerForReady(this, EVENT_RUIM_READY, null);
}
}
@@ -1702,6 +1695,38 @@ public class CdmaServiceStateTracker extends ServiceStateTracker {
}
@Override
+ protected void onUpdateIccAvailability() {
+ if (mUiccController == null ) {
+ return;
+ }
+
+ IccCard newIccCard = mUiccController.getIccCard();
+
+ if (mIccCard != newIccCard) {
+ if (mIccCard != null) {
+ log("Removing stale icc objects.");
+ mIccCard.unregisterForReady(this);
+ if (mIccRecords != null) {
+ mIccRecords.unregisterForRecordsLoaded(this);
+ }
+ mIccRecords = null;
+ mIccCard = null;
+ }
+ if (newIccCard != null) {
+ log("New card found");
+ mIccCard = newIccCard;
+ mIccRecords = mIccCard.getIccRecords();
+ if (isSubscriptionFromRuim) {
+ mIccCard.registerForReady(this, EVENT_RUIM_READY, null);
+ if (mIccRecords != null) {
+ mIccRecords.registerForRecordsLoaded(this, EVENT_RUIM_RECORDS_LOADED, null);
+ }
+ }
+ }
+ }
+ }
+
+ @Override
protected void log(String s) {
Log.d(LOG_TAG, "[CdmaSST] " + s);
}
@@ -1734,7 +1759,6 @@ public class CdmaServiceStateTracker extends ServiceStateTracker {
pw.println(" mSavedTimeZone=" + mSavedTimeZone);
pw.println(" mSavedTime=" + mSavedTime);
pw.println(" mSavedAtTime=" + mSavedAtTime);
- pw.println(" mNeedToRegForRuimLoaded=" + mNeedToRegForRuimLoaded);
pw.println(" mWakeLock=" + mWakeLock);
pw.println(" mCurPlmn=" + mCurPlmn);
pw.println(" mMdn=" + mMdn);
diff --git a/src/java/com/android/internal/telephony/cdma/RuimPhoneBookInterfaceManager.java b/src/java/com/android/internal/telephony/cdma/RuimPhoneBookInterfaceManager.java
index 04ee2dd..e919245 100644
--- a/src/java/com/android/internal/telephony/cdma/RuimPhoneBookInterfaceManager.java
+++ b/src/java/com/android/internal/telephony/cdma/RuimPhoneBookInterfaceManager.java
@@ -21,6 +21,7 @@ import java.util.concurrent.atomic.AtomicBoolean;
import android.os.Message;
import android.util.Log;
+import com.android.internal.telephony.IccFileHandler;
import com.android.internal.telephony.IccPhoneBookInterfaceManager;
/**
@@ -34,7 +35,6 @@ public class RuimPhoneBookInterfaceManager extends IccPhoneBookInterfaceManager
public RuimPhoneBookInterfaceManager(CDMAPhone phone) {
super(phone);
- adnCache = phone.mIccRecords.getAdnCache();
//NOTE service "simphonebook" added by IccSmsInterfaceManagerProxy
}
@@ -61,8 +61,12 @@ public class RuimPhoneBookInterfaceManager extends IccPhoneBookInterfaceManager
AtomicBoolean status = new AtomicBoolean(false);
Message response = mBaseHandler.obtainMessage(EVENT_GET_SIZE_DONE, status);
- phone.getIccFileHandler().getEFLinearRecordSize(efid, response);
- waitForResult(status);
+ IccFileHandler fh = phone.getIccFileHandler();
+ //IccFileHandler can be null if there is no icc card present.
+ if (fh != null) {
+ fh.getEFLinearRecordSize(efid, response);
+ waitForResult(status);
+ }
}
return recordSize;
diff --git a/src/java/com/android/internal/telephony/cdma/RuimRecords.java b/src/java/com/android/internal/telephony/cdma/RuimRecords.java
index e257fb6..d3e04bd 100755
--- a/src/java/com/android/internal/telephony/cdma/RuimRecords.java
+++ b/src/java/com/android/internal/telephony/cdma/RuimRecords.java
@@ -200,7 +200,7 @@ public final class RuimRecords extends IccRecords {
boolean isRecordLoadResponse = false;
- if (mDestroyed) {
+ if (mDestroyed.get()) {
loge("Received message " + msg +
"[" + msg.what + "] while being destroyed. Ignoring.");
return;
@@ -318,18 +318,20 @@ public final class RuimRecords extends IccRecords {
// One record loaded successfully or failed, In either case
// we need to update the recordsToLoad count
recordsToLoad -= 1;
- if (DBG) log("RuimRecords:onRecordLoaded " + recordsToLoad + " requested: " + recordsRequested);
+ if (DBG) log("onRecordLoaded " + recordsToLoad + " requested: " + recordsRequested);
if (recordsToLoad == 0 && recordsRequested == true) {
onAllRecordsLoaded();
} else if (recordsToLoad < 0) {
- loge("RuimRecords: recordsToLoad <0, programmer error suspected");
+ loge("recordsToLoad <0, programmer error suspected");
recordsToLoad = 0;
}
}
@Override
protected void onAllRecordsLoaded() {
+ if (DBG) log("record load complete");
+
// Further records that can be inserted are Operator/OEM dependent
String operator = getRUIMOperatorNumeric();
@@ -349,13 +351,6 @@ public final class RuimRecords extends IccRecords {
@Override
public void onReady() {
- /* broadcast intent ICC_READY here so that we can make sure
- READY is sent before IMSI ready
- */
-
- mParentCard.broadcastIccStateChangedIntent(
- IccCardConstants.INTENT_VALUE_ICC_READY, null);
-
fetchRuimRecords();
mCi.getCDMASubscription(obtainMessage(EVENT_GET_CDMA_SUBSCRIPTION_DONE));
@@ -365,7 +360,7 @@ public final class RuimRecords extends IccRecords {
private void fetchRuimRecords() {
recordsRequested = true;
- Log.v(LOG_TAG, "RuimRecords:fetchRuimRecords " + recordsToLoad);
+ if (DBG) log("fetchRuimRecords " + recordsToLoad);
mCi.getIMSI(obtainMessage(EVENT_GET_IMSI_DONE));
recordsToLoad++;
@@ -374,7 +369,7 @@ public final class RuimRecords extends IccRecords {
obtainMessage(EVENT_GET_ICCID_DONE));
recordsToLoad++;
- log("RuimRecords:fetchRuimRecords " + recordsToLoad + " requested: " + recordsRequested);
+ if (DBG) log("fetchRuimRecords " + recordsToLoad + " requested: " + recordsRequested);
// Further records that can be inserted are Operator/OEM dependent
}
diff --git a/src/java/com/android/internal/telephony/gsm/GSMPhone.java b/src/java/com/android/internal/telephony/gsm/GSMPhone.java
index 34ee647..bc8aa0f 100644
--- a/src/java/com/android/internal/telephony/gsm/GSMPhone.java
+++ b/src/java/com/android/internal/telephony/gsm/GSMPhone.java
@@ -59,6 +59,7 @@ import com.android.internal.telephony.Connection;
import com.android.internal.telephony.IccCard;
import com.android.internal.telephony.IccFileHandler;
import com.android.internal.telephony.IccPhoneBookInterfaceManager;
+import com.android.internal.telephony.IccRecords;
import com.android.internal.telephony.IccSmsInterfaceManager;
import com.android.internal.telephony.MmiCode;
import com.android.internal.telephony.OperatorInfo;
@@ -140,11 +141,10 @@ public class GSMPhone extends PhoneBase {
}
mCM.setPhoneType(PhoneConstants.PHONE_TYPE_GSM);
- mIccCard.set(UiccController.getInstance(this).getIccCard());
- mIccRecords = mIccCard.get().getIccRecords();
mCT = new GsmCallTracker(this);
mSST = new GsmServiceStateTracker (this);
mSMS = new GsmSMSDispatcher(this, mSmsStorageMonitor, mSmsUsageMonitor);
+
mDataConnectionTracker = new GsmDataConnectionTracker (this);
if (!unitTestMode) {
mSimPhoneBookIntManager = new SimPhoneBookInterfaceManager(this);
@@ -153,7 +153,6 @@ public class GSMPhone extends PhoneBase {
}
mCM.registerForAvailable(this, EVENT_RADIO_AVAILABLE, null);
- registerForSimRecordEvents();
mCM.registerForOffOrNotAvailable(this, EVENT_RADIO_OFF_OR_NOT_AVAILABLE, null);
mCM.registerForOn(this, EVENT_RADIO_ON, null);
mCM.setOnUSSD(this, EVENT_USSD, null);
@@ -801,7 +800,8 @@ public class GSMPhone extends PhoneBase {
public String getVoiceMailNumber() {
// Read from the SIM. If its null, try reading from the shared preference area.
- String number = mIccRecords.getVoiceMailNumber();
+ IccRecords r = mIccRecords.get();
+ String number = (r != null) ? r.getVoiceMailNumber() : "";
if (TextUtils.isEmpty(number)) {
SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(getContext());
number = sp.getString(VM_NUMBER, null);
@@ -823,8 +823,9 @@ public class GSMPhone extends PhoneBase {
public String getVoiceMailAlphaTag() {
String ret;
+ IccRecords r = mIccRecords.get();
- ret = mIccRecords.getVoiceMailAlphaTag();
+ ret = (r != null) ? r.getVoiceMailAlphaTag() : "";
if (ret == null || ret.length() == 0) {
return mContext.getText(
@@ -857,24 +858,31 @@ public class GSMPhone extends PhoneBase {
}
public String getSubscriberId() {
- return mIccRecords.getIMSI();
+ IccRecords r = mIccRecords.get();
+ return (r != null) ? r.getIMSI() : "";
}
public String getLine1Number() {
- return mIccRecords.getMsisdnNumber();
+ IccRecords r = mIccRecords.get();
+ return (r != null) ? r.getMsisdnNumber() : "";
}
@Override
public String getMsisdn() {
- return mIccRecords.getMsisdnNumber();
+ IccRecords r = mIccRecords.get();
+ return (r != null) ? r.getMsisdnNumber() : "";
}
public String getLine1AlphaTag() {
- return mIccRecords.getMsisdnAlphaTag();
+ IccRecords r = mIccRecords.get();
+ return (r != null) ? r.getMsisdnAlphaTag() : "";
}
public void setLine1Number(String alphaTag, String number, Message onComplete) {
- mIccRecords.setMsisdnNumber(alphaTag, number, onComplete);
+ IccRecords r = mIccRecords.get();
+ if (r != null) {
+ r.setMsisdnNumber(alphaTag, number, onComplete);
+ }
}
public void setVoiceMailNumber(String alphaTag,
@@ -884,7 +892,10 @@ public class GSMPhone extends PhoneBase {
Message resp;
mVmNumber = voiceMailNumber;
resp = obtainMessage(EVENT_SET_VM_NUMBER_DONE, 0, 0, onComplete);
- mIccRecords.setVoiceMailNumber(alphaTag, mVmNumber, resp);
+ IccRecords r = mIccRecords.get();
+ if (r != null) {
+ r.setVoiceMailNumber(alphaTag, mVmNumber, resp);
+ }
}
private boolean isValidCommandInterfaceCFReason (int commandInterfaceCFReason) {
@@ -1252,8 +1263,9 @@ public class GSMPhone extends PhoneBase {
case EVENT_SET_CALL_FORWARD_DONE:
ar = (AsyncResult)msg.obj;
- if (ar.exception == null) {
- mIccRecords.setVoiceCallForwardingFlag(1, msg.arg1 == 1);
+ IccRecords r = mIccRecords.get();
+ if (ar.exception == null && r != null) {
+ r.setVoiceCallForwardingFlag(1, msg.arg1 == 1);
}
onComplete = (Message) ar.userObj;
if (onComplete != null) {
@@ -1326,12 +1338,41 @@ public class GSMPhone extends PhoneBase {
}
}
+ @Override
+ protected void onUpdateIccAvailability() {
+ if (mUiccController == null ) {
+ return;
+ }
+
+ IccCard newIccCard = mUiccController.getIccCard();
+
+ IccCard c = mIccCard.get();
+ if (c != newIccCard) {
+ if (c != null) {
+ if (LOCAL_DEBUG) log("Removing stale icc objects.");
+ if (mIccRecords.get() != null) {
+ unregisterForSimRecordEvents();
+ mSimPhoneBookIntManager.updateIccRecords(null);
+ }
+ mIccRecords.set(null);
+ mIccCard.set(null);
+ }
+ if (newIccCard != null) {
+ if (LOCAL_DEBUG) log("New card found");
+ mIccCard.set(newIccCard);
+ mIccRecords.set(newIccCard.getIccRecords());
+ registerForSimRecordEvents();
+ mSimPhoneBookIntManager.updateIccRecords(mIccRecords.get());
+ }
+ }
+ }
+
private void processIccRecordEvents(int eventCode) {
switch (eventCode) {
- case SIMRecords.EVENT_CFI:
+ case IccRecords.EVENT_CFI:
notifyCallForwardingIndicator();
break;
- case SIMRecords.EVENT_MWI:
+ case IccRecords.EVENT_MWI:
notifyMessageWaitingIndicator();
break;
}
@@ -1343,11 +1384,12 @@ public class GSMPhone extends PhoneBase {
* @return true for success; false otherwise.
*/
boolean updateCurrentCarrierInProvider() {
- if (mIccRecords != null) {
+ IccRecords r = mIccRecords.get();
+ if (r != null) {
try {
Uri uri = Uri.withAppendedPath(Telephony.Carriers.CONTENT_URI, "current");
ContentValues map = new ContentValues();
- map.put(Telephony.Carriers.NUMERIC, mIccRecords.getOperatorNumeric());
+ map.put(Telephony.Carriers.NUMERIC, r.getOperatorNumeric());
mContext.getContentResolver().insert(uri, map);
return true;
} catch (SQLException e) {
@@ -1409,16 +1451,19 @@ public class GSMPhone extends PhoneBase {
}
private void handleCfuQueryResult(CallForwardInfo[] infos) {
- if (infos == null || infos.length == 0) {
- // Assume the default is not active
- // Set unconditional CFF in SIM to false
- mIccRecords.setVoiceCallForwardingFlag(1, false);
- } else {
- for (int i = 0, s = infos.length; i < s; i++) {
- if ((infos[i].serviceClass & SERVICE_CLASS_VOICE) != 0) {
- mIccRecords.setVoiceCallForwardingFlag(1, (infos[i].status == 1));
- // should only have the one
- break;
+ IccRecords r = mIccRecords.get();
+ if (r != null) {
+ if (infos == null || infos.length == 0) {
+ // Assume the default is not active
+ // Set unconditional CFF in SIM to false
+ r.setVoiceCallForwardingFlag(1, false);
+ } else {
+ for (int i = 0, s = infos.length; i < s; i++) {
+ if ((infos[i].serviceClass & SERVICE_CLASS_VOICE) != 0) {
+ r.setVoiceCallForwardingFlag(1, (infos[i].status == 1));
+ // should only have the one
+ break;
+ }
}
}
}
@@ -1477,22 +1522,31 @@ public class GSMPhone extends PhoneBase {
}
public boolean isCspPlmnEnabled() {
- return mIccRecords.isCspPlmnEnabled();
+ IccRecords r = mIccRecords.get();
+ return (r != null) ? r.isCspPlmnEnabled() : false;
}
private void registerForSimRecordEvents() {
- mIccRecords.registerForNetworkSelectionModeAutomatic(
+ IccRecords r = mIccRecords.get();
+ if (r == null) {
+ return;
+ }
+ r.registerForNetworkSelectionModeAutomatic(
this, EVENT_SET_NETWORK_AUTOMATIC, null);
- mIccRecords.registerForNewSms(this, EVENT_NEW_ICC_SMS, null);
- mIccRecords.registerForRecordsEvents(this, EVENT_ICC_RECORD_EVENTS, null);
- mIccRecords.registerForRecordsLoaded(this, EVENT_SIM_RECORDS_LOADED, null);
+ r.registerForNewSms(this, EVENT_NEW_ICC_SMS, null);
+ r.registerForRecordsEvents(this, EVENT_ICC_RECORD_EVENTS, null);
+ r.registerForRecordsLoaded(this, EVENT_SIM_RECORDS_LOADED, null);
}
private void unregisterForSimRecordEvents() {
- mIccRecords.unregisterForNetworkSelectionModeAutomatic(this);
- mIccRecords.unregisterForNewSms(this);
- mIccRecords.unregisterForRecordsEvents(this);
- mIccRecords.unregisterForRecordsLoaded(this);
+ IccRecords r = mIccRecords.get();
+ if (r == null) {
+ return;
+ }
+ r.unregisterForNetworkSelectionModeAutomatic(this);
+ r.unregisterForNewSms(this);
+ r.unregisterForRecordsEvents(this);
+ r.unregisterForRecordsLoaded(this);
}
@Override
@@ -1509,4 +1563,8 @@ public class GSMPhone extends PhoneBase {
if (VDBG) pw.println(" mImeiSv=" + mImeiSv);
pw.println(" mVmNumber=" + mVmNumber);
}
+
+ protected void log(String s) {
+ Log.d(LOG_TAG, "[GSMPhone] " + s);
+ }
}
diff --git a/src/java/com/android/internal/telephony/gsm/GsmDataConnectionTracker.java b/src/java/com/android/internal/telephony/gsm/GsmDataConnectionTracker.java
index 324841e..bcc2908 100644
--- a/src/java/com/android/internal/telephony/gsm/GsmDataConnectionTracker.java
+++ b/src/java/com/android/internal/telephony/gsm/GsmDataConnectionTracker.java
@@ -60,6 +60,8 @@ import com.android.internal.telephony.DataConnectionAc;
import com.android.internal.telephony.DataConnectionTracker;
import com.android.internal.telephony.DctConstants;
import com.android.internal.telephony.EventLogTags;
+import com.android.internal.telephony.IccCard;
+import com.android.internal.telephony.IccRecords;
import com.android.internal.telephony.Phone;
import com.android.internal.telephony.PhoneBase;
import com.android.internal.telephony.PhoneConstants;
@@ -190,7 +192,6 @@ public final class GsmDataConnectionTracker extends DataConnectionTracker {
p.mCM.registerForAvailable (this, DctConstants.EVENT_RADIO_AVAILABLE, null);
p.mCM.registerForOffOrNotAvailable(this, DctConstants.EVENT_RADIO_OFF_OR_NOT_AVAILABLE,
null);
- p.mIccRecords.registerForRecordsLoaded(this, DctConstants.EVENT_RECORDS_LOADED, null);
p.mCM.registerForDataNetworkStateChanged (this, DctConstants.EVENT_DATA_STATE_CHANGED,
null);
p.getCallTracker().registerForVoiceCallEnded (this, DctConstants.EVENT_VOICE_CALL_ENDED,
@@ -235,7 +236,8 @@ public final class GsmDataConnectionTracker extends DataConnectionTracker {
//Unregister for all events
mPhone.mCM.unregisterForAvailable(this);
mPhone.mCM.unregisterForOffOrNotAvailable(this);
- mPhone.mIccRecords.unregisterForRecordsLoaded(this);
+ IccRecords r = mIccRecords.get();
+ if (r != null) { r.unregisterForRecordsLoaded(this);}
mPhone.mCM.unregisterForDataNetworkStateChanged(this);
mPhone.getCallTracker().unregisterForVoiceCallEnded(this);
mPhone.getCallTracker().unregisterForVoiceCallStarted(this);
@@ -637,10 +639,12 @@ public final class GsmDataConnectionTracker extends DataConnectionTracker {
int gprsState = mPhone.getServiceStateTracker().getCurrentDataConnectionState();
boolean desiredPowerState = mPhone.getServiceStateTracker().getDesiredPowerState();
+ IccRecords r = mIccRecords.get();
+ boolean recordsLoaded = (r != null) ? r.getRecordsLoaded() : false;
boolean allowed =
(gprsState == ServiceState.STATE_IN_SERVICE || mAutoAttachOnCreation) &&
- mPhone.mIccRecords.getRecordsLoaded() &&
+ recordsLoaded &&
(mPhone.getState() == PhoneConstants.State.IDLE ||
mPhone.getServiceStateTracker().isConcurrentVoiceAndDataAllowed()) &&
internalDataEnabled &&
@@ -652,7 +656,7 @@ public final class GsmDataConnectionTracker extends DataConnectionTracker {
if (!((gprsState == ServiceState.STATE_IN_SERVICE) || mAutoAttachOnCreation)) {
reason += " - gprs= " + gprsState;
}
- if (!mPhone.mIccRecords.getRecordsLoaded()) reason += " - SIM not loaded";
+ if (!recordsLoaded) reason += " - SIM not loaded";
if (mPhone.getState() != PhoneConstants.State.IDLE &&
!mPhone.getServiceStateTracker().isConcurrentVoiceAndDataAllowed()) {
reason += " - PhoneState= " + mPhone.getState();
@@ -2000,7 +2004,8 @@ public final class GsmDataConnectionTracker extends DataConnectionTracker {
log("onRadioAvailable: We're on the simulator; assuming data is connected");
}
- if (mPhone.mIccRecords.getRecordsLoaded()) {
+ IccRecords r = mIccRecords.get();
+ if (r != null && r.getRecordsLoaded()) {
notifyOffApnsOfAvailability(null);
}
@@ -2296,7 +2301,8 @@ public final class GsmDataConnectionTracker extends DataConnectionTracker {
*/
private void createAllApnList() {
mAllApns = new ArrayList<ApnSetting>();
- String operator = mPhone.mIccRecords.getOperatorNumeric();
+ IccRecords r = mIccRecords.get();
+ String operator = (r != null) ? r.getOperatorNumeric() : "";
if (operator != null) {
String selection = "numeric = '" + operator + "'";
// query only enabled apn.
@@ -2412,7 +2418,8 @@ public final class GsmDataConnectionTracker extends DataConnectionTracker {
}
}
- String operator = mPhone.mIccRecords.getOperatorNumeric();
+ IccRecords r = mIccRecords.get();
+ String operator = (r != null) ? r.getOperatorNumeric() : "";
int radioTech = mPhone.getServiceState().getRilRadioTechnology();
if (canSetPreferApn && mPreferredApn != null &&
@@ -2648,6 +2655,34 @@ public final class GsmDataConnectionTracker extends DataConnectionTracker {
}
@Override
+ protected void onUpdateIcc() {
+ if (mUiccController == null ) {
+ return;
+ }
+
+ IccCard newIccCard = mUiccController.getIccCard();
+ IccRecords newIccRecords = null;
+ if (newIccCard != null) {
+ newIccRecords = newIccCard.getIccRecords();
+ }
+
+ IccRecords r = mIccRecords.get();
+ if (r != newIccRecords) {
+ if (r != null) {
+ log("Removing stale icc objects.");
+ r.unregisterForRecordsLoaded(this);
+ mIccRecords.set(null);
+ }
+ if (newIccRecords != null) {
+ log("New card found");
+ mIccRecords.set(newIccRecords);
+ newIccRecords.registerForRecordsLoaded(
+ this, DctConstants.EVENT_RECORDS_LOADED, null);
+ }
+ }
+ }
+
+ @Override
protected void log(String s) {
Log.d(LOG_TAG, "[GsmDCT] "+ s);
}
diff --git a/src/java/com/android/internal/telephony/gsm/GsmMmiCode.java b/src/java/com/android/internal/telephony/gsm/GsmMmiCode.java
index 15e6a22..1f7836e 100644
--- a/src/java/com/android/internal/telephony/gsm/GsmMmiCode.java
+++ b/src/java/com/android/internal/telephony/gsm/GsmMmiCode.java
@@ -885,7 +885,10 @@ public final class GsmMmiCode extends Handler implements MmiCode {
*/
if ((ar.exception == null) && (msg.arg1 == 1)) {
boolean cffEnabled = (msg.arg2 == 1);
- phone.mIccRecords.setVoiceCallForwardingFlag(1, cffEnabled);
+ IccRecords r = phone.mIccRecords.get();
+ if (r != null) {
+ r.setVoiceCallForwardingFlag(1, cffEnabled);
+ }
}
onSetComplete(ar);
@@ -1203,7 +1206,10 @@ public final class GsmMmiCode extends Handler implements MmiCode {
(info.serviceClass & serviceClassMask)
== CommandsInterface.SERVICE_CLASS_VOICE) {
boolean cffEnabled = (info.status == 1);
- phone.mIccRecords.setVoiceCallForwardingFlag(1, cffEnabled);
+ IccRecords r = phone.mIccRecords.get();
+ if (r != null) {
+ r.setVoiceCallForwardingFlag(1, cffEnabled);
+ }
}
return TextUtils.replace(template, sources, destinations);
@@ -1228,7 +1234,10 @@ public final class GsmMmiCode extends Handler implements MmiCode {
sb.append(context.getText(com.android.internal.R.string.serviceDisabled));
// Set unconditional CFF in SIM to false
- phone.mIccRecords.setVoiceCallForwardingFlag(1, false);
+ IccRecords r = phone.mIccRecords.get();
+ if (r != null) {
+ r.setVoiceCallForwardingFlag(1, false);
+ }
} else {
SpannableStringBuilder tb = new SpannableStringBuilder();
diff --git a/src/java/com/android/internal/telephony/gsm/GsmServiceStateTracker.java b/src/java/com/android/internal/telephony/gsm/GsmServiceStateTracker.java
index 808ec2b..046d220 100644
--- a/src/java/com/android/internal/telephony/gsm/GsmServiceStateTracker.java
+++ b/src/java/com/android/internal/telephony/gsm/GsmServiceStateTracker.java
@@ -125,12 +125,6 @@ final class GsmServiceStateTracker extends ServiceStateTracker {
long mSavedTime;
long mSavedAtTime;
- /**
- * We can't register for SIM_RECORDS_LOADED immediately because the
- * SIMRecords object may not be instantiated yet.
- */
- private boolean mNeedToRegForSimLoaded;
-
/** Started the recheck process after finding gprs should registered but not. */
private boolean mStartedGprsRegCheck = false;
@@ -193,10 +187,9 @@ final class GsmServiceStateTracker extends ServiceStateTracker {
};
public GsmServiceStateTracker(GSMPhone phone) {
- super();
+ super(phone, phone.mCM);
this.phone = phone;
- cm = phone.mCM;
ss = new ServiceState();
newSS = new ServiceState();
cellLoc = new GsmCellLocation();
@@ -214,7 +207,6 @@ final class GsmServiceStateTracker extends ServiceStateTracker {
cm.setOnNITZTime(this, EVENT_NITZ_TIME, null);
cm.setOnSignalStrengthUpdate(this, EVENT_SIGNAL_STRENGTH_UPDATE, null);
cm.setOnRestrictedStateChanged(this, EVENT_RESTRICTED_STATE_CHANGED, null);
- phone.getIccCard().registerForReady(this, EVENT_SIM_READY, null);
// system setting property AIRPLANE_MODE_ON is set in Settings.
int airplaneMode = Settings.System.getInt(
@@ -231,7 +223,6 @@ final class GsmServiceStateTracker extends ServiceStateTracker {
mAutoTimeZoneObserver);
setSignalStrengthDefaultValues();
- mNeedToRegForSimLoaded = true;
// Monitor locale change
IntentFilter filter = new IntentFilter();
@@ -243,12 +234,13 @@ final class GsmServiceStateTracker extends ServiceStateTracker {
}
public void dispose() {
+ checkCorrectThread();
// Unregister for all events.
cm.unregisterForAvailable(this);
cm.unregisterForRadioStateChanged(this);
cm.unregisterForVoiceNetworkStateChanged(this);
- phone.getIccCard().unregisterForReady(this);
- phone.mIccRecords.unregisterForRecordsLoaded(this);
+ if (mIccCard != null) {mIccCard.unregisterForReady(this);}
+ if (mIccRecords != null) {mIccRecords.unregisterForRecordsLoaded(this);}
cm.unSetOnSignalStrengthUpdate(this);
cm.unSetOnRestrictedStateChanged(this);
cm.unSetOnNITZTime(this);
@@ -286,15 +278,6 @@ final class GsmServiceStateTracker extends ServiceStateTracker {
// Set the network type, in case the radio does not restore it.
cm.setCurrentPreferredNetworkType();
- // The SIM is now ready i.e if it was locked
- // it has been unlocked. At this stage, the radio is already
- // powered on.
- if (mNeedToRegForSimLoaded) {
- phone.mIccRecords.registerForRecordsLoaded(this,
- EVENT_SIM_RECORDS_LOADED, null);
- mNeedToRegForSimLoaded = false;
- }
-
boolean skipRestoringSelection = phone.getContext().getResources().getBoolean(
com.android.internal.R.bool.skip_restoring_network_selection);
@@ -496,8 +479,11 @@ final class GsmServiceStateTracker extends ServiceStateTracker {
}
protected void updateSpnDisplay() {
- int rule = phone.mIccRecords.getDisplayRule(ss.getOperatorNumeric());
- String spn = phone.mIccRecords.getServiceProviderName();
+ if (mIccRecords == null) {
+ return;
+ }
+ int rule = mIccRecords.getDisplayRule(ss.getOperatorNumeric());
+ String spn = mIccRecords.getServiceProviderName();
String plmn = ss.getOperatorAlphaLong();
// For emergency calls only, pass the EmergencyCallsOnly string via EXTRA_PLMN
@@ -1150,7 +1136,7 @@ final class GsmServiceStateTracker extends ServiceStateTracker {
((state & RILConstants.RIL_RESTRICTED_STATE_CS_EMERGENCY) != 0) ||
((state & RILConstants.RIL_RESTRICTED_STATE_CS_ALL) != 0) );
//ignore the normal call and data restricted state before SIM READY
- if (phone.getIccCard().getState() == IccCardConstants.State.READY) {
+ if (mIccCard.getState() == IccCardConstants.State.READY) {
newRs.setCsNormalRestricted(
((state & RILConstants.RIL_RESTRICTED_STATE_CS_NORMAL) != 0) ||
((state & RILConstants.RIL_RESTRICTED_STATE_CS_ALL) != 0) );
@@ -1677,6 +1663,35 @@ final class GsmServiceStateTracker extends ServiceStateTracker {
}
@Override
+ protected void onUpdateIccAvailability() {
+ if (mUiccController == null ) {
+ return;
+ }
+
+ IccCard newIccCard = mUiccController.getIccCard();
+
+ if (mIccCard != newIccCard) {
+ if (mIccCard != null) {
+ log("Removing stale icc objects.");
+ mIccCard.unregisterForReady(this);
+ if (mIccRecords != null) {
+ mIccRecords.unregisterForRecordsLoaded(this);
+ }
+ mIccRecords = null;
+ mIccCard = null;
+ }
+ if (newIccCard != null) {
+ log("New card found");
+ mIccCard = newIccCard;
+ mIccRecords = mIccCard.getIccRecords();
+ mIccCard.registerForReady(this, EVENT_SIM_READY, null);
+ if (mIccRecords != null) {
+ mIccRecords.registerForRecordsLoaded(this, EVENT_SIM_RECORDS_LOADED, null);
+ }
+ }
+ }
+ }
+ @Override
protected void log(String s) {
Log.d(LOG_TAG, "[GsmSST] " + s);
}
@@ -1716,7 +1731,6 @@ final class GsmServiceStateTracker extends ServiceStateTracker {
pw.println(" mSavedTimeZone=" + mSavedTimeZone);
pw.println(" mSavedTime=" + mSavedTime);
pw.println(" mSavedAtTime=" + mSavedAtTime);
- pw.println(" mNeedToRegForSimLoaded=" + mNeedToRegForSimLoaded);
pw.println(" mStartedGprsRegCheck=" + mStartedGprsRegCheck);
pw.println(" mReportedGprsNoReg=" + mReportedGprsNoReg);
pw.println(" mNotification=" + mNotification);
diff --git a/src/java/com/android/internal/telephony/gsm/SIMRecords.java b/src/java/com/android/internal/telephony/gsm/SIMRecords.java
index 1ec3ea7..d5099f7 100755
--- a/src/java/com/android/internal/telephony/gsm/SIMRecords.java
+++ b/src/java/com/android/internal/telephony/gsm/SIMRecords.java
@@ -522,7 +522,7 @@ public class SIMRecords extends IccRecords {
boolean isRecordLoadResponse = false;
- if (mDestroyed) {
+ if (mDestroyed.get()) {
loge("Received message " + msg + "[" + msg.what + "] " +
" while being destroyed. Ignoring.");
return;
@@ -1300,12 +1300,6 @@ public class SIMRecords extends IccRecords {
@Override
public void onReady() {
- /* broadcast intent SIM_READY here so that we can make sure
- READY is sent before IMSI ready
- */
- mParentCard.broadcastIccStateChangedIntent(
- IccCardConstants.INTENT_VALUE_ICC_READY, null);
-
fetchSimRecords();
}
diff --git a/src/java/com/android/internal/telephony/gsm/SimPhoneBookInterfaceManager.java b/src/java/com/android/internal/telephony/gsm/SimPhoneBookInterfaceManager.java
index 35ba0d1..37f9a4f 100644
--- a/src/java/com/android/internal/telephony/gsm/SimPhoneBookInterfaceManager.java
+++ b/src/java/com/android/internal/telephony/gsm/SimPhoneBookInterfaceManager.java
@@ -21,6 +21,7 @@ import java.util.concurrent.atomic.AtomicBoolean;
import android.os.Message;
import android.util.Log;
+import com.android.internal.telephony.IccFileHandler;
import com.android.internal.telephony.IccPhoneBookInterfaceManager;
/**
@@ -34,7 +35,6 @@ public class SimPhoneBookInterfaceManager extends IccPhoneBookInterfaceManager {
public SimPhoneBookInterfaceManager(GSMPhone phone) {
super(phone);
- adnCache = phone.mIccRecords.getAdnCache();
//NOTE service "simphonebook" added by IccSmsInterfaceManagerProxy
}
@@ -61,8 +61,11 @@ public class SimPhoneBookInterfaceManager extends IccPhoneBookInterfaceManager {
AtomicBoolean status = new AtomicBoolean(false);
Message response = mBaseHandler.obtainMessage(EVENT_GET_SIZE_DONE, status);
- phone.getIccFileHandler().getEFLinearRecordSize(efid, response);
- waitForResult(status);
+ IccFileHandler fh = phone.getIccFileHandler();
+ if (fh != null) {
+ fh.getEFLinearRecordSize(efid, response);
+ waitForResult(status);
+ }
}
return recordSize;
diff --git a/src/java/com/android/internal/telephony/sip/SipPhoneBase.java b/src/java/com/android/internal/telephony/sip/SipPhoneBase.java
index ff64486..b0a6080 100755
--- a/src/java/com/android/internal/telephony/sip/SipPhoneBase.java
+++ b/src/java/com/android/internal/telephony/sip/SipPhoneBase.java
@@ -462,4 +462,8 @@ abstract class SipPhoneBase extends PhoneBase {
notifyPhoneStateChanged();
}
}
+
+ @Override
+ protected void onUpdateIccAvailability() {
+ }
}
diff --git a/src/java/com/android/internal/telephony/uicc/UiccController.java b/src/java/com/android/internal/telephony/uicc/UiccController.java
index 5961efd..ab7d561 100644
--- a/src/java/com/android/internal/telephony/uicc/UiccController.java
+++ b/src/java/com/android/internal/telephony/uicc/UiccController.java
@@ -16,78 +16,151 @@
package com.android.internal.telephony.uicc;
+import com.android.internal.telephony.CommandsInterface;
import com.android.internal.telephony.IccCard;
+import com.android.internal.telephony.IccCardStatus;
+import com.android.internal.telephony.IccCardStatus.CardState;
import com.android.internal.telephony.PhoneBase;
-import com.android.internal.telephony.cdma.CDMALTEPhone;
-import com.android.internal.telephony.cdma.CDMAPhone;
-import com.android.internal.telephony.gsm.GSMPhone;
+import android.os.AsyncResult;
+import android.os.Handler;
+import android.os.Message;
+import android.os.Registrant;
+import android.os.RegistrantList;
import android.util.Log;
/* This class is responsible for keeping all knowledge about
* ICCs in the system. It is also used as API to get appropriate
* applications to pass them to phone and service trackers.
*/
-public class UiccController {
+public class UiccController extends Handler {
private static final boolean DBG = true;
private static final String LOG_TAG = "RIL_UiccController";
+ private static final int EVENT_ICC_STATUS_CHANGED = 1;
+ private static final int EVENT_GET_ICC_STATUS_DONE = 2;
+
private static UiccController mInstance;
private PhoneBase mCurrentPhone;
- private boolean mIsCurrentCard3gpp;
+ private CommandsInterface mCi;
private IccCard mIccCard;
+ private boolean mRegisteredWithCi = false;
+
+ private RegistrantList mIccChangedRegistrants = new RegistrantList();
public static synchronized UiccController getInstance(PhoneBase phone) {
if (mInstance == null) {
mInstance = new UiccController(phone);
- } else {
+ } else if (phone != null) {
mInstance.setNewPhone(phone);
}
return mInstance;
}
- public IccCard getIccCard() {
+ // This method is not synchronized as getInstance(PhoneBase) is.
+ public static UiccController getInstance() {
+ return getInstance(null);
+ }
+
+ public synchronized IccCard getIccCard() {
return mIccCard;
}
+ //Notifies when card status changes
+ public void registerForIccChanged(Handler h, int what, Object obj) {
+ Registrant r = new Registrant (h, what, obj);
+ mIccChangedRegistrants.add(r);
+ //Notify registrant right after registering, so that it will get the latest ICC status,
+ //otherwise which may not happen until there is an actual change in ICC status.
+ r.notifyRegistrant();
+ }
+ public void unregisterForIccChanged(Handler h) {
+ mIccChangedRegistrants.remove(h);
+ }
+
+ @Override
+ public void handleMessage (Message msg) {
+ switch (msg.what) {
+ case EVENT_ICC_STATUS_CHANGED:
+ if (DBG) log("Received EVENT_ICC_STATUS_CHANGED, calling getIccCardStatus");
+ mCi.getIccCardStatus(obtainMessage(EVENT_GET_ICC_STATUS_DONE));
+ break;
+ case EVENT_GET_ICC_STATUS_DONE:
+ if (DBG) log("Received EVENT_GET_ICC_STATUS_DONE");
+ AsyncResult ar = (AsyncResult)msg.obj;
+ onGetIccCardStatusDone(ar);
+ break;
+ default:
+ Log.e(LOG_TAG, " Unknown Event " + msg.what);
+ }
+ }
+
private UiccController(PhoneBase phone) {
if (DBG) log("Creating UiccController");
setNewPhone(phone);
}
- private void setNewPhone(PhoneBase phone) {
- mCurrentPhone = phone;
- if (phone instanceof GSMPhone) {
- if (DBG) log("New phone is GSMPhone");
- updateCurrentCard(IccCard.CARD_IS_3GPP);
- } else if (phone instanceof CDMALTEPhone){
- if (DBG) log("New phone type is CDMALTEPhone");
- updateCurrentCard(IccCard.CARD_IS_3GPP);
- } else if (phone instanceof CDMAPhone){
- if (DBG) log("New phone type is CDMAPhone");
- updateCurrentCard(IccCard.CARD_IS_NOT_3GPP);
- } else {
- Log.e(LOG_TAG, "Unhandled phone type. Critical error!");
+ private synchronized void onGetIccCardStatusDone(AsyncResult ar) {
+ if (ar.exception != null) {
+ Log.e(LOG_TAG,"Error getting ICC status. "
+ + "RIL_REQUEST_GET_ICC_STATUS should "
+ + "never return an error", ar.exception);
+ return;
}
- }
- private void updateCurrentCard(boolean isNewCard3gpp) {
- if (mIsCurrentCard3gpp == isNewCard3gpp && mIccCard != null) {
- return;
+ IccCardStatus status = (IccCardStatus)ar.result;
+
+ //Update already existing card
+ if (mIccCard != null && status.getCardState() == CardState.CARDSTATE_PRESENT) {
+ mIccCard.update(mCurrentPhone, status);
}
- if (mIccCard != null) {
+ //Dispose of removed card
+ if (mIccCard != null && status.getCardState() != CardState.CARDSTATE_PRESENT) {
mIccCard.dispose();
mIccCard = null;
}
- mIsCurrentCard3gpp = isNewCard3gpp;
- mIccCard = new IccCard(mCurrentPhone, mCurrentPhone.getPhoneName(),
- isNewCard3gpp, DBG);
+ //Create new card
+ if (mIccCard == null && status.getCardState() == CardState.CARDSTATE_PRESENT) {
+ mIccCard = new IccCard(mCurrentPhone, status, mCurrentPhone.getPhoneName(), true);
+ }
+
+ if (DBG) log("Notifying IccChangedRegistrants");
+ mIccChangedRegistrants.notifyRegistrants();
+ }
+
+ private void setNewPhone(PhoneBase phone) {
+ if (phone == null) {
+ throw new RuntimeException("Phone can't be null in UiccController");
+ //return;
+ }
+
+ if (DBG) log("setNewPhone");
+ if (mCurrentPhone != phone) {
+ if (mIccCard != null) {
+ // Refresh card if phone changed
+ // TODO: Remove once card is simplified
+ if (DBG) log("Disposing card since phone object changed");
+ mIccCard.dispose();
+ mIccCard = null;
+ }
+ sendMessage(obtainMessage(EVENT_ICC_STATUS_CHANGED));
+ mCurrentPhone = phone;
+
+ if (!mRegisteredWithCi) {
+ // This needs to be done only once after we have valid phone object
+ mCi = mCurrentPhone.mCM;
+ mCi.registerForIccStatusChanged(this, EVENT_ICC_STATUS_CHANGED, null);
+ // TODO remove this once modem correctly notifies the unsols
+ mCi.registerForOn(this, EVENT_ICC_STATUS_CHANGED, null);
+ mRegisteredWithCi = true;
+ }
+ }
}
private void log(String string) {
Log.d(LOG_TAG, string);
}
-} \ No newline at end of file
+}