diff --git a/telephony/java/com/android/internal/telephony/IccCard.java b/telephony/java/com/android/internal/telephony/IccCard.java index 530a8dcb3e486..fe80fdf2ad565 100644 --- a/telephony/java/com/android/internal/telephony/IccCard.java +++ b/telephony/java/com/android/internal/telephony/IccCard.java @@ -35,8 +35,15 @@ import android.view.WindowManager; import com.android.internal.telephony.PhoneBase; import com.android.internal.telephony.CommandsInterface.RadioState; +import com.android.internal.telephony.gsm.SIMFileHandler; import com.android.internal.telephony.gsm.SIMRecords; +import com.android.internal.telephony.cdma.CDMALTEPhone; +import com.android.internal.telephony.cdma.CdmaLteUiccFileHandler; +import com.android.internal.telephony.cdma.CdmaLteUiccRecords; import com.android.internal.telephony.cdma.CdmaSubscriptionSourceManager; +import com.android.internal.telephony.cdma.RuimFileHandler; +import com.android.internal.telephony.cdma.RuimRecords; + import android.os.SystemProperties; import com.android.internal.R; @@ -56,6 +63,8 @@ public class IccCard { protected boolean isSubscriptionFromIccCard = true; protected CdmaSubscriptionSourceManager mCdmaSSM = null; protected PhoneBase mPhone; + private IccRecords mIccRecords; + private IccFileHandler mIccFileHandler; private RegistrantList mAbsentRegistrants = new RegistrantList(); private RegistrantList mPinLockedRegistrants = new RegistrantList(); private RegistrantList mNetworkLockedRegistrants = new RegistrantList(); @@ -167,26 +176,46 @@ public class IccCard { } public IccCard(PhoneBase phone, String logTag, Boolean is3gpp, Boolean dbg) { + mLogTag = logTag; + mDbg = dbg; + if (mDbg) log("[IccCard] Creating card type " + (is3gpp ? "3gpp" : "3gpp2")); mPhone = phone; this.is3gpp = is3gpp; mCdmaSSM = CdmaSubscriptionSourceManager.getInstance(mPhone.getContext(), mPhone.mCM, mHandler, EVENT_CDMA_SUBSCRIPTION_SOURCE_CHANGED, null); + if (phone.mCM.getLteOnCdmaMode() == Phone.LTE_ON_CDMA_TRUE + && phone instanceof CDMALTEPhone) { + mIccRecords = new CdmaLteUiccRecords(phone); + mIccFileHandler = new CdmaLteUiccFileHandler((CDMALTEPhone)phone); + } else { + mIccRecords = is3gpp ? new SIMRecords(phone) : new RuimRecords(phone); + mIccFileHandler = is3gpp ? new SIMFileHandler(phone) : new RuimFileHandler(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() { + if (mDbg) log("[IccCard] Disposing card type " + (is3gpp ? "3gpp" : "3gpp2")); mPhone.mCM.unregisterForIccStatusChanged(mHandler); mPhone.mCM.unregisterForOffOrNotAvailable(mHandler); mPhone.mCM.unregisterForOn(mHandler); mCdmaSSM.dispose(mHandler); + mIccRecords.dispose(); + mIccFileHandler.dispose(); } protected void finalize() { - if(mDbg) Log.d(mLogTag, "IccCard finalized"); + if (mDbg) log("[IccCard] Finalized card type " + (is3gpp ? "3gpp" : "3gpp2")); + } + + public IccRecords getIccRecords() { + return mIccRecords; + } + + public IccFileHandler getIccFileHandler() { + return mIccFileHandler; } /** @@ -541,6 +570,10 @@ public class IccCard { } else if (isIccCardAdded) { mHandler.sendMessage(mHandler.obtainMessage(EVENT_CARD_ADDED, null)); } + + if (oldState != State.READY && newState == State.READY) { + mIccRecords.onReady(); + } } private void onIccSwap(boolean isAdded) { @@ -932,6 +965,10 @@ public class IccCard { public String getAid() { String aid = ""; + if (mIccCardStatus == null) { + return aid; + } + int appIndex = getCurrentApplicationIndex(); if (appIndex >= 0 && appIndex < IccCardStatus.CARD_MAX_APPS) { diff --git a/telephony/java/com/android/internal/telephony/IccRecords.java b/telephony/java/com/android/internal/telephony/IccRecords.java index fc011c0b86686..6e82903bac554 100644 --- a/telephony/java/com/android/internal/telephony/IccRecords.java +++ b/telephony/java/com/android/internal/telephony/IccRecords.java @@ -102,6 +102,7 @@ public abstract class IccRecords extends Handler implements IccConstants { public abstract void dispose(); protected abstract void onRadioOffOrNotAvailable(); + public abstract void onReady(); //***** Public Methods public AdnRecordCache getAdnCache() { diff --git a/telephony/java/com/android/internal/telephony/cdma/CDMALTEPhone.java b/telephony/java/com/android/internal/telephony/cdma/CDMALTEPhone.java index 3084c146370f9..14a4b46b3d8dd 100644 --- a/telephony/java/com/android/internal/telephony/cdma/CDMALTEPhone.java +++ b/telephony/java/com/android/internal/telephony/cdma/CDMALTEPhone.java @@ -36,6 +36,7 @@ import com.android.internal.telephony.PhoneProxy; import com.android.internal.telephony.SMSDispatcher; import com.android.internal.telephony.gsm.GsmSMSDispatcher; import com.android.internal.telephony.ims.IsimRecords; +import com.android.internal.telephony.uicc.UiccController; public class CDMALTEPhone extends CDMAPhone { static final String LOG_TAG = "CDMA"; @@ -79,9 +80,9 @@ public class CDMALTEPhone extends CDMAPhone { @Override protected void initSstIcc() { - mIccCard = new IccCard(this, LOG_TAG, IccCard.CARD_IS_3GPP, DBG); - mIccRecords = new CdmaLteUiccRecords(this); - mIccFileHandler = new CdmaLteUiccFileHandler(this); + mIccCard = UiccController.getInstance(this).getIccCard(); + mIccRecords = mIccCard.getIccRecords(); + mIccFileHandler = mIccCard.getIccFileHandler(); // CdmaLteServiceStateTracker registers with IccCard to know // when the card is ready. So create mIccCard before the ServiceStateTracker mSST = new CdmaLteServiceStateTracker(this); @@ -164,7 +165,7 @@ public class CDMALTEPhone extends CDMAPhone { // look for our wrapper within the asyncresult, skip the rest if it // is null. if (!(ar.userObj instanceof NetworkSelectMessage)) { - if (DBG) Log.d(LOG_TAG, "unexpected result from user object."); + Log.e(LOG_TAG, "unexpected result from user object."); return; } @@ -173,7 +174,7 @@ public class CDMALTEPhone extends CDMAPhone { // found the object, now we send off the message we had originally // attached to the request. if (nsm.message != null) { - if (DBG) Log.d(LOG_TAG, "sending original message to recipient"); + if (DBG) log("sending original message to recipient"); AsyncResult.forMessage(nsm.message, ar.result, ar.exception); nsm.message.sendToTarget(); } @@ -200,14 +201,15 @@ public class CDMALTEPhone extends CDMAPhone { ContentValues map = new ContentValues(); String operatorNumeric = mIccRecords.getOperatorNumeric(); map.put(Telephony.Carriers.NUMERIC, operatorNumeric); - log("updateCurrentCarrierInProvider from UICC: numeric=" + operatorNumeric); + if (DBG) log("updateCurrentCarrierInProvider from UICC: numeric=" + + operatorNumeric); mContext.getContentResolver().insert(uri, map); return true; } catch (SQLException e) { Log.e(LOG_TAG, "[CDMALTEPhone] Can't store current operator ret false", e); } } else { - log("updateCurrentCarrierInProvider mIccRecords == null ret false"); + if (DBG) log("updateCurrentCarrierInProvider mIccRecords == null ret false"); } return false; } @@ -259,7 +261,6 @@ public class CDMALTEPhone extends CDMAPhone { @Override protected void log(String s) { - if (DBG) Log.d(LOG_TAG, "[CDMALTEPhone] " + s); } } diff --git a/telephony/java/com/android/internal/telephony/cdma/CDMAPhone.java b/telephony/java/com/android/internal/telephony/cdma/CDMAPhone.java index b5dca65462242..e86e441934904 100755 --- a/telephony/java/com/android/internal/telephony/cdma/CDMAPhone.java +++ b/telephony/java/com/android/internal/telephony/cdma/CDMAPhone.java @@ -64,6 +64,7 @@ import com.android.internal.telephony.TelephonyIntents; import com.android.internal.telephony.TelephonyProperties; import com.android.internal.telephony.UUSInfo; import com.android.internal.telephony.cat.CatService; +import com.android.internal.telephony.uicc.UiccController; import java.util.ArrayList; import java.util.List; @@ -149,9 +150,9 @@ public class CDMAPhone extends PhoneBase { } protected void initSstIcc() { - mIccCard = new IccCard(this, LOG_TAG, IccCard.CARD_IS_NOT_3GPP, DBG); - mIccRecords = new RuimRecords(this); - mIccFileHandler = new RuimFileHandler(this); + mIccCard = UiccController.getInstance(this).getIccCard(); + mIccRecords = mIccCard.getIccRecords(); + mIccFileHandler = mIccCard.getIccFileHandler(); // CdmaServiceStateTracker registers with IccCard to know // when the Ruim card is ready. So create mIccCard before the ServiceStateTracker mSST = new CdmaServiceStateTracker(this); @@ -242,7 +243,6 @@ public class CDMAPhone extends PhoneBase { mSMS.dispose(); mIccFileHandler.dispose(); // instance of RuimFileHandler mIccRecords.dispose(); - mIccCard.dispose(); mRuimPhoneBookInterfaceManager.dispose(); mRuimSmsInterfaceManager.dispose(); mSubInfo.dispose(); diff --git a/telephony/java/com/android/internal/telephony/cdma/CdmaLteUiccFileHandler.java b/telephony/java/com/android/internal/telephony/cdma/CdmaLteUiccFileHandler.java index 8375fd04b67fe..e195ff2ec00ea 100644 --- a/telephony/java/com/android/internal/telephony/cdma/CdmaLteUiccFileHandler.java +++ b/telephony/java/com/android/internal/telephony/cdma/CdmaLteUiccFileHandler.java @@ -27,7 +27,7 @@ import android.os.Message; public final class CdmaLteUiccFileHandler extends IccFileHandler { static final String LOG_TAG = "CDMA"; - CdmaLteUiccFileHandler(CDMALTEPhone phone) { + public CdmaLteUiccFileHandler(CDMALTEPhone phone) { super(phone); } diff --git a/telephony/java/com/android/internal/telephony/cdma/CdmaLteUiccRecords.java b/telephony/java/com/android/internal/telephony/cdma/CdmaLteUiccRecords.java index 0a285b904dfed..ca1e96d6f7657 100755 --- a/telephony/java/com/android/internal/telephony/cdma/CdmaLteUiccRecords.java +++ b/telephony/java/com/android/internal/telephony/cdma/CdmaLteUiccRecords.java @@ -436,6 +436,10 @@ public final class CdmaLteUiccRecords extends SIMRecords { return true; } + if (phone == null || phone.mIccCard == null) { + return false; + } + if (phone.mIccCard.isApplicationOnIcc(AppType.APPTYPE_CSIM) && ((mMdn == null) || (mMin == null))) { return false; diff --git a/telephony/java/com/android/internal/telephony/cdma/RuimFileHandler.java b/telephony/java/com/android/internal/telephony/cdma/RuimFileHandler.java index 375cc0763eef2..e854d7f8ae4ba 100644 --- a/telephony/java/com/android/internal/telephony/cdma/RuimFileHandler.java +++ b/telephony/java/com/android/internal/telephony/cdma/RuimFileHandler.java @@ -25,6 +25,7 @@ import com.android.internal.telephony.IccFileHandler; import com.android.internal.telephony.IccFileTypeMismatch; import com.android.internal.telephony.IccIoResult; import com.android.internal.telephony.IccUtils; +import com.android.internal.telephony.PhoneBase; import com.android.internal.telephony.PhoneProxy; import java.util.ArrayList; @@ -38,7 +39,7 @@ public final class RuimFileHandler extends IccFileHandler { //***** Instance Variables //***** Constructor - RuimFileHandler(CDMAPhone phone) { + public RuimFileHandler(PhoneBase phone) { super(phone); } diff --git a/telephony/java/com/android/internal/telephony/cdma/RuimRecords.java b/telephony/java/com/android/internal/telephony/cdma/RuimRecords.java index e518c4c744b0c..265dff703affb 100755 --- a/telephony/java/com/android/internal/telephony/cdma/RuimRecords.java +++ b/telephony/java/com/android/internal/telephony/cdma/RuimRecords.java @@ -31,6 +31,7 @@ import com.android.internal.telephony.AdnRecordLoader; import com.android.internal.telephony.CommandsInterface; import com.android.internal.telephony.IccRefreshResponse; import com.android.internal.telephony.IccCard; +import com.android.internal.telephony.PhoneBase; import com.android.internal.telephony.TelephonyProperties; import com.android.internal.telephony.MccTable; @@ -61,7 +62,6 @@ public final class RuimRecords extends IccRecords { // ***** Event Constants - private static final int EVENT_RUIM_READY = 1; private static final int EVENT_RADIO_OFF_OR_NOT_AVAILABLE = 2; private static final int EVENT_GET_IMSI_DONE = 3; private static final int EVENT_GET_DEVICE_IDENTITY_DONE = 4; @@ -78,7 +78,7 @@ public final class RuimRecords extends IccRecords { private static final int EVENT_RUIM_REFRESH = 31; - RuimRecords(CDMAPhone p) { + public RuimRecords(PhoneBase p) { super(p); adnCache = new AdnRecordCache(phone); @@ -88,8 +88,6 @@ public final class RuimRecords extends IccRecords { // recordsToLoad is set to 0 because no requests are made yet recordsToLoad = 0; - - 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); @@ -102,7 +100,6 @@ public final class RuimRecords extends IccRecords { @Override public void dispose() { //Unregister for all events - phone.mIccCard.unregisterForRuimReady(this); phone.mCM.unregisterForOffOrNotAvailable( this); phone.mCM.unregisterForIccRefresh(this); } @@ -206,10 +203,6 @@ public final class RuimRecords extends IccRecords { } try { switch (msg.what) { - case EVENT_RUIM_READY: - onRuimReady(); - break; - case EVENT_RADIO_OFF_OR_NOT_AVAILABLE: onRadioOffOrNotAvailable(); break; @@ -349,7 +342,8 @@ public final class RuimRecords extends IccRecords { IccCard.INTENT_VALUE_ICC_LOADED, null); } - private void onRuimReady() { + @Override + public void onReady() { /* broadcast intent ICC_READY here so that we can make sure READY is sent before IMSI ready */ diff --git a/telephony/java/com/android/internal/telephony/gsm/GSMPhone.java b/telephony/java/com/android/internal/telephony/gsm/GSMPhone.java index 4c846f1136b1e..5e9a4f29279ab 100644 --- a/telephony/java/com/android/internal/telephony/gsm/GSMPhone.java +++ b/telephony/java/com/android/internal/telephony/gsm/GSMPhone.java @@ -70,6 +70,7 @@ import com.android.internal.telephony.PhoneSubInfo; import com.android.internal.telephony.TelephonyProperties; import com.android.internal.telephony.UUSInfo; import com.android.internal.telephony.test.SimulatedRadioControl; +import com.android.internal.telephony.uicc.UiccController; import com.android.internal.telephony.IccVmNotSupportedException; import com.android.internal.telephony.ServiceStateTracker; @@ -136,12 +137,12 @@ public class GSMPhone extends PhoneBase { } mCM.setPhoneType(Phone.PHONE_TYPE_GSM); - mIccCard = new IccCard(this, LOG_TAG, IccCard.CARD_IS_3GPP, true); + mIccCard = UiccController.getInstance(this).getIccCard(); mCT = new GsmCallTracker(this); mSST = new GsmServiceStateTracker (this); mSMS = new GsmSMSDispatcher(this, mSmsStorageMonitor, mSmsUsageMonitor); - mIccFileHandler = new SIMFileHandler(this); - mIccRecords = new SIMRecords(this); + mIccFileHandler = mIccCard.getIccFileHandler(); + mIccRecords = mIccCard.getIccRecords(); mDataConnectionTracker = new GsmDataConnectionTracker (this); if (!unitTestMode) { mSimPhoneBookIntManager = new SimPhoneBookInterfaceManager(this); @@ -220,7 +221,6 @@ public class GSMPhone extends PhoneBase { mSST.dispose(); mIccFileHandler.dispose(); // instance of SimFileHandler mIccRecords.dispose(); - mIccCard.dispose(); mSimPhoneBookIntManager.dispose(); mSimSmsIntManager.dispose(); mSubInfo.dispose(); diff --git a/telephony/java/com/android/internal/telephony/gsm/SIMFileHandler.java b/telephony/java/com/android/internal/telephony/gsm/SIMFileHandler.java index e8d10f9172180..8c3bc0e48d356 100644 --- a/telephony/java/com/android/internal/telephony/gsm/SIMFileHandler.java +++ b/telephony/java/com/android/internal/telephony/gsm/SIMFileHandler.java @@ -23,22 +23,20 @@ import com.android.internal.telephony.IccCard; import com.android.internal.telephony.IccCardApplication; import com.android.internal.telephony.IccConstants; import com.android.internal.telephony.IccFileHandler; -import com.android.internal.telephony.Phone; +import com.android.internal.telephony.PhoneBase; /** * {@hide} */ public final class SIMFileHandler extends IccFileHandler implements IccConstants { static final String LOG_TAG = "GSM"; - private Phone mPhone; //***** Instance Variables //***** Constructor - SIMFileHandler(GSMPhone phone) { + public SIMFileHandler(PhoneBase phone) { super(phone); - mPhone = phone; } public void dispose() { diff --git a/telephony/java/com/android/internal/telephony/gsm/SIMRecords.java b/telephony/java/com/android/internal/telephony/gsm/SIMRecords.java index 1fb99e332eb0f..68d3b2ac60098 100755 --- a/telephony/java/com/android/internal/telephony/gsm/SIMRecords.java +++ b/telephony/java/com/android/internal/telephony/gsm/SIMRecords.java @@ -123,7 +123,6 @@ public class SIMRecords extends IccRecords { // ***** Event Constants - private static final int EVENT_SIM_READY = 1; private static final int EVENT_RADIO_OFF_OR_NOT_AVAILABLE = 2; protected static final int EVENT_GET_IMSI_DONE = 3; protected static final int EVENT_GET_ICCID_DONE = 4; @@ -188,7 +187,6 @@ public class SIMRecords extends IccRecords { // recordsToLoad is set to 0 because no requests are made yet recordsToLoad = 0; - 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); @@ -202,7 +200,6 @@ public class SIMRecords extends IccRecords { @Override public void dispose() { //Unregister for all events - phone.mIccCard.unregisterForReady(this); phone.mCM.unregisterForOffOrNotAvailable( this); phone.mCM.unregisterForIccRefresh(this); } @@ -526,10 +523,6 @@ public class SIMRecords extends IccRecords { } try { switch (msg.what) { - case EVENT_SIM_READY: - onSimReady(); - break; - case EVENT_RADIO_OFF_OR_NOT_AVAILABLE: onRadioOffOrNotAvailable(); break; @@ -1296,7 +1289,8 @@ public class SIMRecords extends IccRecords { } } - public void onSimReady() { + @Override + public void onReady() { /* broadcast intent SIM_READY here so that we can make sure READY is sent before IMSI ready */ diff --git a/telephony/java/com/android/internal/telephony/uicc/UiccController.java b/telephony/java/com/android/internal/telephony/uicc/UiccController.java new file mode 100644 index 0000000000000..5961efd35b530 --- /dev/null +++ b/telephony/java/com/android/internal/telephony/uicc/UiccController.java @@ -0,0 +1,93 @@ +/* + * 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.uicc; + +import com.android.internal.telephony.IccCard; +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.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 { + private static final boolean DBG = true; + private static final String LOG_TAG = "RIL_UiccController"; + + private static UiccController mInstance; + + private PhoneBase mCurrentPhone; + private boolean mIsCurrentCard3gpp; + private IccCard mIccCard; + + public static synchronized UiccController getInstance(PhoneBase phone) { + if (mInstance == null) { + mInstance = new UiccController(phone); + } else { + mInstance.setNewPhone(phone); + } + return mInstance; + } + + public IccCard getIccCard() { + return mIccCard; + } + + 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 void updateCurrentCard(boolean isNewCard3gpp) { + if (mIsCurrentCard3gpp == isNewCard3gpp && mIccCard != null) { + return; + } + + if (mIccCard != null) { + mIccCard.dispose(); + mIccCard = null; + } + + mIsCurrentCard3gpp = isNewCard3gpp; + mIccCard = new IccCard(mCurrentPhone, mCurrentPhone.getPhoneName(), + isNewCard3gpp, DBG); + } + + private void log(String string) { + Log.d(LOG_TAG, string); + } +} \ No newline at end of file