Telephony: Create and use UiccController

UiccController creates and disposes IccCard
IccRecords and IccFileHandler is part of IccCard

Change-Id: I3dfb476c76162bbe8443271927a06743bb5e39c4
This commit is contained in:
Wink Saville
2012-03-06 17:11:49 -08:00
parent d1f0023ddf
commit 22c1700378
12 changed files with 166 additions and 43 deletions

View File

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

View File

@@ -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() {

View File

@@ -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);
}
}

View File

@@ -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();

View File

@@ -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);
}

View File

@@ -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;

View File

@@ -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);
}

View File

@@ -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
*/

View File

@@ -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();

View File

@@ -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() {

View File

@@ -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
*/

View File

@@ -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);
}
}