Remove duplicate code in Sim/Ruim card, handle IccCardStatus.

a) Push code to IccCard.java base class.
b) Handle IccCardStatus.
c) Add some helper functions for USIM use.
This commit is contained in:
Jaikumar Ganesh
2009-07-02 10:49:08 -07:00
parent a0ad661fc9
commit cdadaad0e4
9 changed files with 675 additions and 1185 deletions

View File

@ -82,15 +82,6 @@ public interface CommandsInterface {
}
}
enum IccStatus {
ICC_ABSENT,
ICC_NOT_READY,
ICC_READY,
ICC_PIN,
ICC_PUK,
ICC_NETWORK_PERSONALIZATION
}
//***** Constants
// Used as parameter to dial() and setCLIR() below
@ -533,15 +524,6 @@ public interface CommandsInterface {
void registerForCdmaOtaProvision(Handler h,int what, Object obj);
void unregisterForCdmaOtaProvision(Handler h);
/**
* Returns current ICC status.
*
* AsyncResult.result is IccStatus
*
*/
void getIccStatus(Message result);
/**
* Supply the ICC PIN to the ICC card
*
@ -1366,4 +1348,12 @@ public interface CommandsInterface {
* @param response callback message
*/
public void exitEmergencyCallbackMode(Message response);
/**
* Request the status of the ICC and UICC cards.
*
* @param response
* Callback message containing {@link IccCardStatus} structure for the card.
*/
public void getIccCardStatus(Message result);
}

View File

@ -16,13 +16,40 @@
package com.android.internal.telephony;
import android.os.Message;
import static android.Manifest.permission.READ_PHONE_STATE;
import android.app.ActivityManagerNative;
import android.content.Intent;
import android.os.AsyncResult;
import android.os.Handler;
import android.os.Message;
import android.os.Registrant;
import android.os.RegistrantList;
import android.util.Log;
import com.android.internal.telephony.PhoneBase;
import com.android.internal.telephony.CommandsInterface.RadioState;
/**
* {@hide}
*/
public interface IccCard {
public abstract class IccCard {
protected String mLogTag;
protected boolean mDbg;
private IccCardStatus mIccCardStatus = null;
protected State mState = null;
protected PhoneBase mPhone;
private RegistrantList mAbsentRegistrants = new RegistrantList();
private RegistrantList mPinLockedRegistrants = new RegistrantList();
private RegistrantList mNetworkLockedRegistrants = new RegistrantList();
private boolean mDesiredPinLocked;
private boolean mDesiredFdnEnabled;
private boolean mIccPinLocked = true; // Default to locked
private boolean mIccFdnEnabled = false; // Default to disabled.
// Will be updated when SIM_READY.
/* The extra data for broacasting intent INTENT_ICC_STATE_CHANGE */
static public final String INTENT_KEY_ICC_STATE = "ss";
/* NOT_READY means the ICC interface is not ready (eg, radio is off or powering on) */
@ -46,6 +73,17 @@ public interface IccCard {
/* NETWORK means ICC is locked on NETWORK PERSONALIZATION */
static public final String INTENT_VALUE_LOCKED_NETWORK = "NETWORK";
protected static final int EVENT_ICC_LOCKED_OR_ABSENT = 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;
private static final int EVENT_CHANGE_ICC_PASSWORD_DONE = 9;
private static final int EVENT_QUERY_FACILITY_FDN_DONE = 10;
private static final int EVENT_CHANGE_FACILITY_FDN_DONE = 11;
/*
UNKNOWN is a transient state, for example, after uesr inputs ICC pin under
@ -58,33 +96,108 @@ public interface IccCard {
PIN_REQUIRED,
PUK_REQUIRED,
NETWORK_LOCKED,
READY;
READY,
NOT_READY;
public boolean isPinLocked() {
return ((this == PIN_REQUIRED) || (this == PUK_REQUIRED));
}
}
State getState();
public State getState() {
if (mState == null) {
switch(mPhone.mCM.getRadioState()) {
/* This switch block must not return anything in
* State.isLocked() or State.ABSENT.
* If it does, handleSimStatus() may break
*/
case RADIO_OFF:
case RADIO_UNAVAILABLE:
case SIM_NOT_READY:
case RUIM_NOT_READY:
return State.UNKNOWN;
case SIM_LOCKED_OR_ABSENT:
case RUIM_LOCKED_OR_ABSENT:
//this should be transient-only
return State.UNKNOWN;
case SIM_READY:
case RUIM_READY:
return State.READY;
case NV_READY:
case NV_NOT_READY:
return State.ABSENT;
}
} else {
return mState;
}
Log.e(mLogTag, "IccCard.getState(): case should never be reached");
return State.UNKNOWN;
}
public IccCard(PhoneBase phone, String logTag, Boolean dbg) {
mPhone = phone;
mLogTag = logTag;
mDbg = dbg;
}
abstract public void dispose();
protected void finalize() {
if(mDbg) Log.d(mLogTag, "IccCard finalized");
}
/**
* Notifies handler of any transition into State.ABSENT
*/
void registerForAbsent(Handler h, int what, Object obj);
void unregisterForAbsent(Handler h);
public void registerForAbsent(Handler h, int what, Object obj) {
Registrant r = new Registrant (h, what, obj);
/**
* Notifies handler of any transition into State.isPinLocked()
*/
void registerForLocked(Handler h, int what, Object obj);
void unregisterForLocked(Handler h);
mAbsentRegistrants.add(r);
if (getState() == State.ABSENT) {
r.notifyRegistrant();
}
}
public void unregisterForAbsent(Handler h) {
mAbsentRegistrants.remove(h);
}
/**
* Notifies handler of any transition into State.NETWORK_LOCKED
*/
void registerForNetworkLocked(Handler h, int what, Object obj);
void unregisterForNetworkLocked(Handler h);
public void registerForNetworkLocked(Handler h, int what, Object obj) {
Registrant r = new Registrant (h, what, obj);
mNetworkLockedRegistrants.add(r);
if (getState() == State.NETWORK_LOCKED) {
r.notifyRegistrant();
}
}
public void unregisterForNetworkLocked(Handler h) {
mNetworkLockedRegistrants.remove(h);
}
/**
* Notifies handler of any transition into State.isPinLocked()
*/
public void registerForLocked(Handler h, int what, Object obj) {
Registrant r = new Registrant (h, what, obj);
mPinLockedRegistrants.add(r);
if (getState().isPinLocked()) {
r.notifyRegistrant();
}
}
public void unregisterForLocked(Handler h) {
mPinLockedRegistrants.remove(h);
}
/**
* Supply the ICC PIN to the ICC
@ -107,10 +220,30 @@ public interface IccCard {
*
*/
void supplyPin (String pin, Message onComplete);
void supplyPuk (String puk, String newPin, Message onComplete);
void supplyPin2 (String pin2, Message onComplete);
void supplyPuk2 (String puk2, String newPin2, Message onComplete);
public void supplyPin (String pin, Message onComplete) {
mPhone.mCM.supplyIccPin(pin, mHandler.obtainMessage(EVENT_PINPUK_DONE, onComplete));
}
public void supplyPuk (String puk, String newPin, Message onComplete) {
mPhone.mCM.supplyIccPuk(puk, newPin,
mHandler.obtainMessage(EVENT_PINPUK_DONE, onComplete));
}
public void supplyPin2 (String pin2, Message onComplete) {
mPhone.mCM.supplyIccPin2(pin2,
mHandler.obtainMessage(EVENT_PINPUK_DONE, onComplete));
}
public void supplyPuk2 (String puk2, String newPin2, Message onComplete) {
mPhone.mCM.supplyIccPuk2(puk2, newPin2,
mHandler.obtainMessage(EVENT_PINPUK_DONE, onComplete));
}
public void supplyNetworkDepersonalization (String pin, Message onComplete) {
if(mDbg) log("Network Despersonalization: " + pin);
mPhone.mCM.supplyNetworkDepersonalization(pin,
mHandler.obtainMessage(EVENT_PINPUK_DONE, onComplete));
}
/**
* Check whether ICC pin lock is enabled
@ -119,35 +252,9 @@ public interface IccCard {
* @return true for ICC locked enabled
* false for ICC locked disabled
*/
boolean getIccLockEnabled ();
/**
* Set the ICC pin lock enabled or disabled
* When the operation is complete, onComplete will be sent to its handler
*
* @param enabled "true" for locked "false" for unlocked.
* @param password needed to change the ICC pin state, aka. Pin1
* @param onComplete
* onComplete.obj will be an AsyncResult
* ((AsyncResult)onComplete.obj).exception == null on success
* ((AsyncResult)onComplete.obj).exception != null on fail
*/
void setIccLockEnabled(boolean enabled, String password, Message onComplete);
/**
* Change the ICC password used in ICC pin lock
* When the operation is complete, onComplete will be sent to its handler
*
* @param oldPassword is the old password
* @param newPassword is the new password
* @param onComplete
* onComplete.obj will be an AsyncResult
* ((AsyncResult)onComplete.obj).exception == null on success
* ((AsyncResult)onComplete.obj).exception != null on fail
*/
void changeIccLockPassword(String oldPassword, String newPassword,
Message onComplete);
public boolean getIccLockEnabled() {
return mIccPinLocked;
}
/**
* Check whether ICC fdn (fixed dialing number) is enabled
@ -156,36 +263,99 @@ public interface IccCard {
* @return true for ICC fdn enabled
* false for ICC fdn disabled
*/
boolean getIccFdnEnabled ();
public boolean getIccFdnEnabled() {
return mIccFdnEnabled;
}
/**
* Set the ICC fdn enabled or disabled
* When the operation is complete, onComplete will be sent to its handler
*
* @param enabled "true" for locked "false" for unlocked.
* @param password needed to change the ICC fdn enable, aka Pin2
* @param onComplete
* onComplete.obj will be an AsyncResult
* ((AsyncResult)onComplete.obj).exception == null on success
* ((AsyncResult)onComplete.obj).exception != null on fail
*/
void setIccFdnEnabled(boolean enabled, String password, Message onComplete);
/**
* Set the ICC pin lock enabled or disabled
* When the operation is complete, onComplete will be sent to its handler
*
* @param enabled "true" for locked "false" for unlocked.
* @param password needed to change the ICC pin state, aka. Pin1
* @param onComplete
* onComplete.obj will be an AsyncResult
* ((AsyncResult)onComplete.obj).exception == null on success
* ((AsyncResult)onComplete.obj).exception != null on fail
*/
public void setIccLockEnabled (boolean enabled,
String password, Message onComplete) {
int serviceClassX;
serviceClassX = CommandsInterface.SERVICE_CLASS_VOICE +
CommandsInterface.SERVICE_CLASS_DATA +
CommandsInterface.SERVICE_CLASS_FAX;
/**
* Change the ICC password used in ICC fdn enable
* When the operation is complete, onComplete will be sent to its handler
*
* @param oldPassword is the old password
* @param newPassword is the new password
* @param onComplete
* onComplete.obj will be an AsyncResult
* ((AsyncResult)onComplete.obj).exception == null on success
* ((AsyncResult)onComplete.obj).exception != null on fail
*/
void changeIccFdnPassword(String oldPassword, String newPassword,
Message onComplete);
mDesiredPinLocked = enabled;
mPhone.mCM.setFacilityLock(CommandsInterface.CB_FACILITY_BA_SIM,
enabled, password, serviceClassX,
mHandler.obtainMessage(EVENT_CHANGE_FACILITY_LOCK_DONE, onComplete));
}
/**
* Set the ICC fdn enabled or disabled
* When the operation is complete, onComplete will be sent to its handler
*
* @param enabled "true" for locked "false" for unlocked.
* @param password needed to change the ICC fdn enable, aka Pin2
* @param onComplete
* onComplete.obj will be an AsyncResult
* ((AsyncResult)onComplete.obj).exception == null on success
* ((AsyncResult)onComplete.obj).exception != null on fail
*/
public void setIccFdnEnabled (boolean enabled,
String password, Message onComplete) {
int serviceClassX;
serviceClassX = CommandsInterface.SERVICE_CLASS_VOICE +
CommandsInterface.SERVICE_CLASS_DATA +
CommandsInterface.SERVICE_CLASS_FAX +
CommandsInterface.SERVICE_CLASS_SMS;
mDesiredFdnEnabled = enabled;
mPhone.mCM.setFacilityLock(CommandsInterface.CB_FACILITY_BA_FD,
enabled, password, serviceClassX,
mHandler.obtainMessage(EVENT_CHANGE_FACILITY_FDN_DONE, onComplete));
}
/**
* Change the ICC password used in ICC pin lock
* When the operation is complete, onComplete will be sent to its handler
*
* @param oldPassword is the old password
* @param newPassword is the new password
* @param onComplete
* onComplete.obj will be an AsyncResult
* ((AsyncResult)onComplete.obj).exception == null on success
* ((AsyncResult)onComplete.obj).exception != null on fail
*/
public void changeIccLockPassword(String oldPassword, String newPassword,
Message onComplete) {
if(mDbg) log("Change Pin1 old: " + oldPassword + " new: " + newPassword);
mPhone.mCM.changeIccPin(oldPassword, newPassword,
mHandler.obtainMessage(EVENT_CHANGE_ICC_PASSWORD_DONE, onComplete));
}
/**
* Change the ICC password used in ICC fdn enable
* When the operation is complete, onComplete will be sent to its handler
*
* @param oldPassword is the old password
* @param newPassword is the new password
* @param onComplete
* onComplete.obj will be an AsyncResult
* ((AsyncResult)onComplete.obj).exception == null on success
* ((AsyncResult)onComplete.obj).exception != null on fail
*/
public void changeIccFdnPassword(String oldPassword, String newPassword,
Message onComplete) {
if(mDbg) log("Change Pin2 old: " + oldPassword + " new: " + newPassword);
mPhone.mCM.changeIccPin2(oldPassword, newPassword,
mHandler.obtainMessage(EVENT_CHANGE_ICC_PASSWORD_DONE, onComplete));
}
void supplyNetworkDepersonalization (String pin, Message onComplete);
/**
* Returns service provider name stored in ICC card.
@ -203,5 +373,301 @@ public interface IccCard {
* yet available
*
*/
String getServiceProviderName();
public abstract String 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 handleIccCardStatus(IccCardStatus newCardStatus) {
boolean transitionedIntoPinLocked;
boolean transitionedIntoAbsent;
boolean transitionedIntoNetworkLocked;
State oldState, newState;
oldState = mState;
mIccCardStatus = newCardStatus;
newState = getIccCardState();
mState = newState;
updateStateProperty();
transitionedIntoPinLocked = (
(oldState != State.PIN_REQUIRED && newState == State.PIN_REQUIRED)
|| (oldState != State.PUK_REQUIRED && newState == State.PUK_REQUIRED));
transitionedIntoAbsent = (oldState != State.ABSENT && newState == State.ABSENT);
transitionedIntoNetworkLocked = (oldState != State.NETWORK_LOCKED
&& newState == State.NETWORK_LOCKED);
if (transitionedIntoPinLocked) {
if(mDbg) log("Notify SIM pin or puk locked.");
mPinLockedRegistrants.notifyRegistrants();
broadcastIccStateChangedIntent(INTENT_VALUE_ICC_LOCKED,
(newState == State.PIN_REQUIRED) ?
INTENT_VALUE_LOCKED_ON_PIN : INTENT_VALUE_LOCKED_ON_PUK);
} else if (transitionedIntoAbsent) {
if(mDbg) log("Notify SIM missing.");
mAbsentRegistrants.notifyRegistrants();
broadcastIccStateChangedIntent(INTENT_VALUE_ICC_ABSENT, null);
} else if (transitionedIntoNetworkLocked) {
if(mDbg) log("Notify SIM network locked.");
mNetworkLockedRegistrants.notifyRegistrants();
broadcastIccStateChangedIntent(INTENT_VALUE_ICC_LOCKED,
INTENT_VALUE_LOCKED_NETWORK);
}
}
/**
* Interperate EVENT_QUERY_FACILITY_LOCK_DONE
* @param ar is asyncResult of Query_Facility_Locked
*/
private void onQueryFdnEnabled(AsyncResult ar) {
if(ar.exception != null) {
if(mDbg) log("Error in querying facility lock:" + ar.exception);
return;
}
int[] ints = (int[])ar.result;
if(ints.length != 0) {
mIccFdnEnabled = (0!=ints[0]);
if(mDbg) log("Query facility lock : " + mIccFdnEnabled);
} else {
Log.e(mLogTag, "[IccCard] Bogus facility lock response");
}
}
/**
* Interperate EVENT_QUERY_FACILITY_LOCK_DONE
* @param ar is asyncResult of Query_Facility_Locked
*/
private void onQueryFacilityLock(AsyncResult ar) {
if(ar.exception != null) {
if (mDbg) log("Error in querying facility lock:" + ar.exception);
return;
}
int[] ints = (int[])ar.result;
if(ints.length != 0) {
mIccPinLocked = (0!=ints[0]);
if(mDbg) log("Query facility lock : " + mIccPinLocked);
} else {
Log.e(mLogTag, "[IccCard] Bogus facility lock response");
}
}
public void broadcastIccStateChangedIntent(String value, String reason) {
Intent intent = new Intent(TelephonyIntents.ACTION_SIM_STATE_CHANGED);
intent.putExtra(Phone.PHONE_NAME_KEY, mPhone.getPhoneName());
intent.putExtra(INTENT_KEY_ICC_STATE, value);
intent.putExtra(INTENT_KEY_LOCKED_REASON, reason);
if(mDbg) log("Broadcasting intent ACTION_SIM_STATE_CHANGED " + value
+ " reason " + reason);
ActivityManagerNative.broadcastStickyIntent(intent, READ_PHONE_STATE);
}
protected Handler mHandler = new Handler() {
@Override
public void handleMessage(Message msg){
AsyncResult ar;
int serviceClassX;
serviceClassX = CommandsInterface.SERVICE_CLASS_VOICE +
CommandsInterface.SERVICE_CLASS_DATA +
CommandsInterface.SERVICE_CLASS_FAX;
switch (msg.what) {
case EVENT_RADIO_OFF_OR_NOT_AVAILABLE:
mState = null;
updateStateProperty();
broadcastIccStateChangedIntent(INTENT_VALUE_ICC_NOT_READY, null);
break;
case EVENT_ICC_READY:
//TODO: put facility read in SIM_READY now, maybe in REG_NW
mPhone.mCM.getIccCardStatus(obtainMessage(EVENT_GET_ICC_STATUS_DONE));
mPhone.mCM.queryFacilityLock (
CommandsInterface.CB_FACILITY_BA_SIM, "", serviceClassX,
obtainMessage(EVENT_QUERY_FACILITY_LOCK_DONE));
mPhone.mCM.queryFacilityLock (
CommandsInterface.CB_FACILITY_BA_FD, "", serviceClassX,
obtainMessage(EVENT_QUERY_FACILITY_FDN_DONE));
break;
case EVENT_ICC_LOCKED_OR_ABSENT:
mPhone.mCM.getIccCardStatus(obtainMessage(EVENT_GET_ICC_STATUS_DONE));
mPhone.mCM.queryFacilityLock (
CommandsInterface.CB_FACILITY_BA_SIM, "", serviceClassX,
obtainMessage(EVENT_QUERY_FACILITY_LOCK_DONE));
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
ar = (AsyncResult)msg.obj;
getIccCardStatusDone(ar);
((Message)ar.userObj).sendToTarget();
break;
case EVENT_QUERY_FACILITY_LOCK_DONE:
ar = (AsyncResult)msg.obj;
onQueryFacilityLock(ar);
break;
case EVENT_QUERY_FACILITY_FDN_DONE:
ar = (AsyncResult)msg.obj;
onQueryFdnEnabled(ar);
break;
case EVENT_CHANGE_FACILITY_LOCK_DONE:
ar = (AsyncResult)msg.obj;
if (ar.exception == null) {
mIccPinLocked = mDesiredPinLocked;
if (mDbg) log( "EVENT_CHANGE_FACILITY_LOCK_DONE: " +
"mIccPinLocked= " + mIccPinLocked);
} else {
Log.e(mLogTag, "Error change facility lock with exception "
+ ar.exception);
}
AsyncResult.forMessage(((Message)ar.userObj)).exception
= ar.exception;
((Message)ar.userObj).sendToTarget();
break;
case EVENT_CHANGE_FACILITY_FDN_DONE:
ar = (AsyncResult)msg.obj;
if (ar.exception == null) {
mIccFdnEnabled = mDesiredFdnEnabled;
if (mDbg) log("EVENT_CHANGE_FACILITY_FDN_DONE: " +
"mIccFdnEnabled=" + mIccFdnEnabled);
} else {
Log.e(mLogTag, "Error change facility fdn with exception "
+ ar.exception);
}
AsyncResult.forMessage(((Message)ar.userObj)).exception
= ar.exception;
((Message)ar.userObj).sendToTarget();
break;
case EVENT_CHANGE_ICC_PASSWORD_DONE:
ar = (AsyncResult)msg.obj;
if(ar.exception != null) {
Log.e(mLogTag, "Error in change sim password with exception"
+ ar.exception);
}
AsyncResult.forMessage(((Message)ar.userObj)).exception
= ar.exception;
((Message)ar.userObj).sendToTarget();
break;
default:
Log.e(mLogTag, "[IccCard] Unknown Event " + msg.what);
}
}
};
public State getIccCardState() {
if (mIccCardStatus == null) {
Log.e(mLogTag, "[IccCard] IccCardStatus is null");
return IccCard.State.ABSENT;
}
// this is common for all radio technologies
if (!mIccCardStatus.getCardState().isCardPresent()) {
return IccCard.State.NOT_READY;
}
RadioState currentRadioState = mPhone.mCM.getRadioState();
// check radio technology
if( currentRadioState == RadioState.RADIO_OFF ||
currentRadioState == RadioState.RADIO_UNAVAILABLE ||
currentRadioState == RadioState.SIM_NOT_READY ||
currentRadioState == RadioState.RUIM_NOT_READY ||
currentRadioState == RadioState.NV_NOT_READY ||
currentRadioState == RadioState.NV_READY) {
return IccCard.State.NOT_READY;
}
if( currentRadioState == RadioState.SIM_LOCKED_OR_ABSENT ||
currentRadioState == RadioState.SIM_READY ||
currentRadioState == RadioState.RUIM_LOCKED_OR_ABSENT ||
currentRadioState == RadioState.RUIM_READY) {
int index;
// check for CDMA radio technology
if (currentRadioState == RadioState.RUIM_LOCKED_OR_ABSENT ||
currentRadioState == RadioState.RUIM_READY) {
index = mIccCardStatus.getCdmaSubscriptionAppIndex();
}
else {
index = mIccCardStatus.getGsmUmtsSubscriptionAppIndex();
}
IccCardApplication app = mIccCardStatus.getApplication(index);
if (app == null) {
Log.e(mLogTag, "[IccCard] Subscription Application in not present");
return IccCard.State.ABSENT;
}
// check if PIN required
if (app.app_state.isPinRequired()) {
return IccCard.State.PIN_REQUIRED;
}
if (app.app_state.isPukRequired()) {
return IccCard.State.PUK_REQUIRED;
}
if (app.app_state.isSubscriptionPersoEnabled()) {
return IccCard.State.NETWORK_LOCKED;
}
if (app.app_state.isAppReady()) {
return IccCard.State.READY;
}
if (app.app_state.isAppNotReady()) {
return IccCard.State.NOT_READY;
}
return IccCard.State.NOT_READY;
}
return IccCard.State.ABSENT;
}
public boolean hasApplicationType(IccCardApplication.AppType type) {
if (mIccCardStatus == null) return false;
for (int i = 0 ; i < mIccCardStatus.getNumApplications(); i++) {
IccCardApplication app = mIccCardStatus.getApplication(i);
if (app != null && app.app_type == type) {
return true;
}
}
return false;
}
private void log(String msg) {
Log.d(mLogTag, "[IccCard] " + msg);
}
}

View File

@ -45,42 +45,89 @@ public class IccCardStatus {
PINSTATE_ENABLED_PERM_BLOCKED
};
public CardState card_state;
public PinState universal_pin_state;
public int gsm_umts_subscription_app_index;
public int cdma_subscription_app_index;
public int num_applications;
private CardState mCardState;
private PinState mUniversalPinState;
private int mGsmUmtsSubscriptionAppIndex;
private int mCdmaSubscriptionAppIndex;
private int mNumApplications;
ArrayList<IccCardApplication> application = new ArrayList<IccCardApplication>(CARD_MAX_APPS);
private ArrayList<IccCardApplication> mApplications =
new ArrayList<IccCardApplication>(CARD_MAX_APPS);
CardState CardStateFromRILInt(int state) {
CardState newState;
/* RIL_CardState ril.h */
switch(state) {
case 0: newState = CardState.CARDSTATE_ABSENT; break;
case 1: newState = CardState.CARDSTATE_PRESENT; break;
case 2: newState = CardState.CARDSTATE_ERROR; break;
default:
throw new RuntimeException(
"Unrecognized RIL_CardState: " +state);
}
return newState;
public CardState getCardState() {
return mCardState;
}
PinState PinStateFromRILInt(int state) {
PinState newState;
/* RIL_PinState ril.h */
public void setCardState(int state) {
switch(state) {
case 0: newState = PinState.PINSTATE_UNKNOWN; break;
case 1: newState = PinState.PINSTATE_ENABLED_NOT_VERIFIED; break;
case 2: newState = PinState.PINSTATE_ENABLED_VERIFIED; break;
case 3: newState = PinState.PINSTATE_DISABLED; break;
case 4: newState = PinState.PINSTATE_ENABLED_BLOCKED; break;
case 5: newState = PinState.PINSTATE_ENABLED_PERM_BLOCKED; break;
default:
throw new RuntimeException(
"Unrecognized RIL_PinState: " +state);
case 0:
mCardState = CardState.CARDSTATE_ABSENT;
break;
case 1:
mCardState = CardState.CARDSTATE_PRESENT;
break;
case 2:
mCardState = CardState.CARDSTATE_ERROR;
break;
default:
throw new RuntimeException("Unrecognized RIL_CardState: " + state);
}
return newState;
}
public void setUniversalPinState(int state) {
switch(state) {
case 0:
mUniversalPinState = PinState.PINSTATE_UNKNOWN;
break;
case 1:
mUniversalPinState = PinState.PINSTATE_ENABLED_NOT_VERIFIED;
break;
case 2:
mUniversalPinState = PinState.PINSTATE_ENABLED_VERIFIED;
break;
case 3:
mUniversalPinState = PinState.PINSTATE_DISABLED;
break;
case 4:
mUniversalPinState = PinState.PINSTATE_ENABLED_BLOCKED;
break;
case 5:
mUniversalPinState = PinState.PINSTATE_ENABLED_PERM_BLOCKED;
break;
default:
throw new RuntimeException("Unrecognized RIL_PinState: " + state);
}
}
public int getGsmUmtsSubscriptionAppIndex() {
return mGsmUmtsSubscriptionAppIndex;
}
public void setGsmUmtsSubscriptionAppIndex(int gsmUmtsSubscriptionAppIndex) {
mGsmUmtsSubscriptionAppIndex = gsmUmtsSubscriptionAppIndex;
}
public int getCdmaSubscriptionAppIndex() {
return mCdmaSubscriptionAppIndex;
}
public void setCdmaSubscriptionAppIndex(int cdmaSubscriptionAppIndex) {
mCdmaSubscriptionAppIndex = cdmaSubscriptionAppIndex;
}
public int getNumApplications() {
return mNumApplications;
}
public void setNumApplications(int numApplications) {
mNumApplications = numApplications;
}
public void addApplication(IccCardApplication application) {
mApplications.add(application);
}
public IccCardApplication getApplication(int index) {
return mApplications.get(index);
}
}

View File

@ -630,7 +630,7 @@ public final class RIL extends BaseCommands implements CommandsInterface {
}
public void
getIccStatus(Message result) {
getIccCardStatus(Message result) {
//Note: This RIL request has not been renamed to ICC,
// but this request is also valid for SIM and RUIM
RILRequest rr = RILRequest.obtain(RIL_REQUEST_GET_SIM_STATUS, result);
@ -2732,24 +2732,22 @@ public final class RIL extends BaseCommands implements CommandsInterface {
private Object
responseIccCardStatus(Parcel p) {
RadioState currentRadioState;
IccCardApplication ca;
currentRadioState = getRadioState();
IccCardStatus status = new IccCardStatus();
status.card_state = status.CardStateFromRILInt(p.readInt());
status.universal_pin_state = status.PinStateFromRILInt(p.readInt());
status.gsm_umts_subscription_app_index = p.readInt();
status.cdma_subscription_app_index = p.readInt();
status.num_applications = p.readInt();
status.setCardState(p.readInt());
status.setUniversalPinState(p.readInt());
status.setGsmUmtsSubscriptionAppIndex(p.readInt());
status.setCdmaSubscriptionAppIndex(p.readInt());
int numApplications = p.readInt();
// limit to maximum allowed applications
if (status.num_applications > IccCardStatus.CARD_MAX_APPS) {
status.num_applications = IccCardStatus.CARD_MAX_APPS;
if (numApplications > IccCardStatus.CARD_MAX_APPS) {
numApplications = IccCardStatus.CARD_MAX_APPS;
}
status.setNumApplications(numApplications);
for (int i = 0 ; i < status.num_applications ; i++) {
for (int i = 0 ; i < numApplications ; i++) {
ca = new IccCardApplication();
ca.app_type = ca.AppTypeFromRILInt(p.readInt());
ca.app_state = ca.AppStateFromRILInt(p.readInt());
@ -2759,62 +2757,9 @@ public final class RIL extends BaseCommands implements CommandsInterface {
ca.pin1_replaced = p.readInt();
ca.pin1 = p.readInt();
ca.pin2 = p.readInt();
status.application.add(ca);
status.addApplication(ca);
}
// this is common for all radio technologies
if (!status.card_state.isCardPresent()) {
return IccStatus.ICC_ABSENT;
}
// check radio technology
if( currentRadioState == RadioState.RADIO_OFF ||
currentRadioState == RadioState.RADIO_UNAVAILABLE ||
currentRadioState == RadioState.SIM_NOT_READY ||
currentRadioState == RadioState.RUIM_NOT_READY ||
currentRadioState == RadioState.NV_NOT_READY ||
currentRadioState == RadioState.NV_READY ) {
return IccStatus.ICC_NOT_READY;
}
if( currentRadioState == RadioState.SIM_LOCKED_OR_ABSENT ||
currentRadioState == RadioState.SIM_READY ||
currentRadioState == RadioState.RUIM_LOCKED_OR_ABSENT ||
currentRadioState == RadioState.RUIM_READY) {
int index;
// check for CDMA radio technology
if (currentRadioState == RadioState.RUIM_LOCKED_OR_ABSENT ||
currentRadioState == RadioState.RUIM_READY) {
index = status.cdma_subscription_app_index;
}
else {
index = status.gsm_umts_subscription_app_index;
}
// check if PIN required
if (status.application.get(index).app_state.isPinRequired()) {
return IccStatus.ICC_PIN;
}
if (status.application.get(index).app_state.isPukRequired()) {
return IccStatus.ICC_PUK;
}
if (status.application.get(index).app_state.isSubscriptionPersoEnabled()) {
return IccStatus.ICC_NETWORK_PERSONALIZATION;
}
if (status.application.get(index).app_state.isAppReady()) {
return IccStatus.ICC_READY;
}
if (status.application.get(index).app_state.isAppNotReady()) {
return IccStatus.ICC_NOT_READY;
}
return IccStatus.ICC_NOT_READY;
}
// Unrecognized ICC status. Treat it like a missing ICC.
Log.e(LOG_TAG, "Unrecognized RIL_REQUEST_GET_SIM_STATUS result: " + status);
return IccStatus.ICC_ABSENT;
return status;
}
private Object

View File

@ -16,507 +16,34 @@
package com.android.internal.telephony.cdma;
import android.os.AsyncResult;
import android.os.Handler;
import android.os.Message;
import android.os.Registrant;
import android.os.RegistrantList;
import android.os.RemoteException;
import android.util.Log;
import com.android.internal.telephony.CommandsInterface;
import com.android.internal.telephony.IccCard;
import com.android.internal.telephony.Phone;
import com.android.internal.telephony.PhoneProxy;
import com.android.internal.telephony.TelephonyIntents;
import com.android.internal.telephony.TelephonyProperties;
import android.app.ActivityManagerNative;
import android.content.Intent;
import android.content.res.Configuration;
import static android.Manifest.permission.READ_PHONE_STATE;
/**
* Note: this class shares common code with SimCard, consider a base class to minimize code
* duplication.
* {@hide}
*/
public final class RuimCard extends Handler implements IccCard {
static final String LOG_TAG="CDMA";
//***** Instance Variables
private static final boolean DBG = true;
private CDMAPhone phone;
private CommandsInterface.IccStatus status = null;
private boolean mDesiredPinLocked;
private boolean mDesiredFdnEnabled;
private boolean mRuimPinLocked = true; // default to locked
private boolean mRuimFdnEnabled = false; // Default to disabled.
// Will be updated when RUIM_READY.
// //***** Constants
// // FIXME I hope this doesn't conflict with the Dialer's notifications
// Nobody is using this at the moment
// static final int NOTIFICATION_ID_ICC_STATUS = 33456;
//***** Event Constants
static final int EVENT_RUIM_LOCKED_OR_ABSENT = 1;
static final int EVENT_GET_RUIM_STATUS_DONE = 2;
static final int EVENT_RADIO_OFF_OR_NOT_AVAILABLE = 3;
static final int EVENT_PINPUK_DONE = 4;
static final int EVENT_REPOLL_STATUS_DONE = 5;
static final int EVENT_RUIM_READY = 6;
static final int EVENT_QUERY_FACILITY_LOCK_DONE = 7;
static final int EVENT_CHANGE_FACILITY_LOCK_DONE = 8;
static final int EVENT_CHANGE_RUIM_PASSWORD_DONE = 9;
static final int EVENT_QUERY_FACILITY_FDN_DONE = 10;
static final int EVENT_CHANGE_FACILITY_FDN_DONE = 11;
//***** Constructor
public final class RuimCard extends IccCard {
RuimCard(CDMAPhone phone) {
this.phone = phone;
phone.mCM.registerForRUIMLockedOrAbsent(
this, EVENT_RUIM_LOCKED_OR_ABSENT, null);
phone.mCM.registerForOffOrNotAvailable(
this, EVENT_RADIO_OFF_OR_NOT_AVAILABLE, null);
phone.mCM.registerForRUIMReady(
this, EVENT_RUIM_READY, null);
super(phone, "CDMA", true);
mPhone.mCM.registerForRUIMLockedOrAbsent(mHandler, EVENT_ICC_LOCKED_OR_ABSENT, null);
mPhone.mCM.registerForOffOrNotAvailable(mHandler, EVENT_RADIO_OFF_OR_NOT_AVAILABLE, null);
mPhone.mCM.registerForRUIMReady(mHandler, EVENT_ICC_READY, null);
updateStateProperty();
}
//***** RuimCard implementation
public State
getState() {
if (status == null) {
switch(phone.mCM.getRadioState()) {
/* This switch block must not return anything in
* State.isLocked() or State.ABSENT.
* If it does, handleSimStatus() may break
*/
case RADIO_OFF:
case RADIO_UNAVAILABLE:
case RUIM_NOT_READY:
return State.UNKNOWN;
case RUIM_LOCKED_OR_ABSENT:
//this should be transient-only
return State.UNKNOWN;
case RUIM_READY:
return State.READY;
case NV_READY:
case NV_NOT_READY:
return State.ABSENT;
}
} else {
switch (status) {
case ICC_ABSENT: return State.ABSENT;
case ICC_NOT_READY: return State.UNKNOWN;
case ICC_READY: return State.READY;
case ICC_PIN: return State.PIN_REQUIRED;
case ICC_PUK: return State.PUK_REQUIRED;
case ICC_NETWORK_PERSONALIZATION: return State.NETWORK_LOCKED;
}
}
Log.e(LOG_TAG, "RuimCard.getState(): case should never be reached");
return State.UNKNOWN;
}
@Override
public void dispose() {
//Unregister for all events
phone.mCM.unregisterForRUIMLockedOrAbsent(this);
phone.mCM.unregisterForOffOrNotAvailable(this);
phone.mCM.unregisterForRUIMReady(this);
mPhone.mCM.unregisterForRUIMLockedOrAbsent(mHandler);
mPhone.mCM.unregisterForOffOrNotAvailable(mHandler);
mPhone.mCM.unregisterForRUIMReady(mHandler);
}
protected void finalize() {
if(DBG) Log.d(LOG_TAG, "RuimCard finalized");
}
private RegistrantList absentRegistrants = new RegistrantList();
private RegistrantList pinLockedRegistrants = new RegistrantList();
private RegistrantList networkLockedRegistrants = new RegistrantList();
public void registerForAbsent(Handler h, int what, Object obj) {
Registrant r = new Registrant (h, what, obj);
absentRegistrants.add(r);
if (getState() == State.ABSENT) {
r.notifyRegistrant();
}
}
public void unregisterForAbsent(Handler h) {
absentRegistrants.remove(h);
}
public void registerForNetworkLocked(Handler h, int what, Object obj) {
Registrant r = new Registrant (h, what, obj);
networkLockedRegistrants.add(r);
if (getState() == State.NETWORK_LOCKED) {
r.notifyRegistrant();
}
}
public void unregisterForNetworkLocked(Handler h) {
networkLockedRegistrants.remove(h);
}
public void registerForLocked(Handler h, int what, Object obj) {
Registrant r = new Registrant (h, what, obj);
pinLockedRegistrants.add(r);
if (getState().isPinLocked()) {
r.notifyRegistrant();
}
}
public void unregisterForLocked(Handler h) {
pinLockedRegistrants.remove(h);
}
public void supplyPin (String pin, Message onComplete) {
phone.mCM.supplyIccPin(pin, obtainMessage(EVENT_PINPUK_DONE, onComplete));
}
public void supplyPuk (String puk, String newPin, Message onComplete) {
phone.mCM.supplyIccPuk(puk, newPin, obtainMessage(EVENT_PINPUK_DONE, onComplete));
}
public void supplyPin2 (String pin2, Message onComplete) {
phone.mCM.supplyIccPin2(pin2, obtainMessage(EVENT_PINPUK_DONE, onComplete));
}
public void supplyPuk2 (String puk2, String newPin2, Message onComplete) {
phone.mCM.supplyIccPuk2(puk2, newPin2, obtainMessage(EVENT_PINPUK_DONE, onComplete));
}
public void supplyNetworkDepersonalization (String pin, Message onComplete) {
if(DBG) log("Network Despersonalization: " + pin);
phone.mCM.supplyNetworkDepersonalization(pin,
obtainMessage(EVENT_PINPUK_DONE, onComplete));
}
public boolean getIccLockEnabled() {
return mRuimPinLocked;
}
public boolean getIccFdnEnabled() {
return mRuimFdnEnabled;
}
public void setIccLockEnabled (boolean enabled,
String password, Message onComplete) {
int serviceClassX;
serviceClassX = CommandsInterface.SERVICE_CLASS_VOICE +
CommandsInterface.SERVICE_CLASS_DATA +
CommandsInterface.SERVICE_CLASS_FAX;
mDesiredPinLocked = enabled;
phone.mCM.setFacilityLock(CommandsInterface.CB_FACILITY_BA_SIM,
enabled, password, serviceClassX,
obtainMessage(EVENT_CHANGE_FACILITY_LOCK_DONE, onComplete));
}
public void setIccFdnEnabled (boolean enabled,
String password, Message onComplete) {
int serviceClassX;
serviceClassX = CommandsInterface.SERVICE_CLASS_VOICE +
CommandsInterface.SERVICE_CLASS_DATA +
CommandsInterface.SERVICE_CLASS_FAX +
CommandsInterface.SERVICE_CLASS_SMS;
mDesiredFdnEnabled = enabled;
phone.mCM.setFacilityLock(CommandsInterface.CB_FACILITY_BA_FD,
enabled, password, serviceClassX,
obtainMessage(EVENT_CHANGE_FACILITY_FDN_DONE, onComplete));
}
public void changeIccLockPassword(String oldPassword, String newPassword,
Message onComplete) {
if(DBG) log("Change Pin1 old: " + oldPassword + " new: " + newPassword);
phone.mCM.changeIccPin(oldPassword, newPassword,
obtainMessage(EVENT_CHANGE_RUIM_PASSWORD_DONE, onComplete));
}
public void changeIccFdnPassword(String oldPassword, String newPassword,
Message onComplete) {
if(DBG) log("Change Pin2 old: " + oldPassword + " new: " + newPassword);
phone.mCM.changeIccPin2(oldPassword, newPassword,
obtainMessage(EVENT_CHANGE_RUIM_PASSWORD_DONE, onComplete));
}
public String getServiceProviderName() {
return phone.mRuimRecords.getServiceProviderName();
}
//***** Handler implementation
@Override
public void handleMessage(Message msg){
AsyncResult ar;
int serviceClassX;
serviceClassX = CommandsInterface.SERVICE_CLASS_VOICE +
CommandsInterface.SERVICE_CLASS_DATA +
CommandsInterface.SERVICE_CLASS_FAX;
switch (msg.what) {
case EVENT_RADIO_OFF_OR_NOT_AVAILABLE:
Log.d(LOG_TAG, "Event EVENT_RADIO_OFF_OR_NOT_AVAILABLE Received");
status = null;
updateStateProperty();
broadcastRuimStateChangedIntent(RuimCard.INTENT_VALUE_ICC_NOT_READY, null);
break;
case EVENT_RUIM_READY:
Log.d(LOG_TAG, "Event EVENT_RUIM_READY Received");
//TODO: put facility read in SIM_READY now, maybe in REG_NW
phone.mCM.getIccStatus(obtainMessage(EVENT_GET_RUIM_STATUS_DONE));
phone.mCM.queryFacilityLock (
CommandsInterface.CB_FACILITY_BA_SIM, "", serviceClassX,
obtainMessage(EVENT_QUERY_FACILITY_LOCK_DONE));
phone.mCM.queryFacilityLock (
CommandsInterface.CB_FACILITY_BA_FD, "", serviceClassX,
obtainMessage(EVENT_QUERY_FACILITY_FDN_DONE));
break;
case EVENT_RUIM_LOCKED_OR_ABSENT:
Log.d(LOG_TAG, "Event EVENT_RUIM_LOCKED_OR_ABSENT Received");
phone.mCM.getIccStatus(obtainMessage(EVENT_GET_RUIM_STATUS_DONE));
phone.mCM.queryFacilityLock (
CommandsInterface.CB_FACILITY_BA_SIM, "", serviceClassX,
obtainMessage(EVENT_QUERY_FACILITY_LOCK_DONE));
break;
case EVENT_GET_RUIM_STATUS_DONE:
Log.d(LOG_TAG, "Event EVENT_GET_RUIM_STATUS_DONE Received");
ar = (AsyncResult)msg.obj;
getRuimStatusDone(ar);
break;
case EVENT_PINPUK_DONE:
Log.d(LOG_TAG, "Event EVENT_PINPUK_DONE Received");
// 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;
phone.mCM.getIccStatus(
obtainMessage(EVENT_REPOLL_STATUS_DONE, ar.userObj));
break;
case EVENT_REPOLL_STATUS_DONE:
Log.d(LOG_TAG, "Event EVENT_REPOLL_STATUS_DONE Received");
// 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
ar = (AsyncResult)msg.obj;
getRuimStatusDone(ar);
((Message)ar.userObj).sendToTarget();
break;
case EVENT_QUERY_FACILITY_LOCK_DONE:
Log.d(LOG_TAG, "Event EVENT_QUERY_FACILITY_LOCK_DONE Received");
ar = (AsyncResult)msg.obj;
onQueryFacilityLock(ar);
break;
case EVENT_QUERY_FACILITY_FDN_DONE:
Log.d(LOG_TAG, "Event EVENT_QUERY_FACILITY_FDN_DONE Received");
ar = (AsyncResult)msg.obj;
onQueryFdnEnabled(ar);
break;
case EVENT_CHANGE_FACILITY_LOCK_DONE:
Log.d(LOG_TAG, "Event EVENT_CHANGE_FACILITY_LOCK_DONE Received");
ar = (AsyncResult)msg.obj;
if (ar.exception == null) {
mRuimPinLocked = mDesiredPinLocked;
if (DBG) log( "EVENT_CHANGE_FACILITY_LOCK_DONE: " +
"mRuimPinLocked= " + mRuimPinLocked);
} else {
Log.e(LOG_TAG, "Error change facility lock with exception "
+ ar.exception);
}
AsyncResult.forMessage(((Message)ar.userObj)).exception
= ar.exception;
((Message)ar.userObj).sendToTarget();
break;
case EVENT_CHANGE_FACILITY_FDN_DONE:
Log.d(LOG_TAG, "Event EVENT_CHANGE_FACILITY_FDN_DONE Received");
ar = (AsyncResult)msg.obj;
if (ar.exception == null) {
mRuimFdnEnabled = mDesiredFdnEnabled;
if (DBG) log("EVENT_CHANGE_FACILITY_FDN_DONE: " +
"mRuimFdnEnabled=" + mRuimFdnEnabled);
} else {
Log.e(LOG_TAG, "Error change facility fdn with exception "
+ ar.exception);
}
AsyncResult.forMessage(((Message)ar.userObj)).exception
= ar.exception;
((Message)ar.userObj).sendToTarget();
break;
case EVENT_CHANGE_RUIM_PASSWORD_DONE:
Log.d(LOG_TAG, "Event EVENT_CHANGE_RUIM_PASSWORD_DONE Received");
ar = (AsyncResult)msg.obj;
if(ar.exception != null) {
Log.e(LOG_TAG, "Error in change sim password with exception"
+ ar.exception);
}
AsyncResult.forMessage(((Message)ar.userObj)).exception
= ar.exception;
((Message)ar.userObj).sendToTarget();
break;
default:
Log.e(LOG_TAG, "[CdmaRuimCard] Unknown Event " + msg.what);
}
public String getServiceProviderName () {
return ((CDMAPhone)mPhone).mRuimRecords.getServiceProviderName();
}
//***** Private methods
/**
* Interpret EVENT_QUERY_FACILITY_LOCK_DONE
* @param ar is asyncResult of Query_Facility_Locked
*/
private void onQueryFacilityLock(AsyncResult ar) {
if(ar.exception != null) {
if (DBG) log("Error in querying facility lock:" + ar.exception);
return;
}
int[] ints = (int[])ar.result;
if(ints.length != 0) {
mRuimPinLocked = (0!=ints[0]);
if(DBG) log("Query facility lock : " + mRuimPinLocked);
} else {
Log.e(LOG_TAG, "[CdmaRuimCard] Bogus facility lock response");
}
}
/**
* Interpret EVENT_QUERY_FACILITY_LOCK_DONE
* @param ar is asyncResult of Query_Facility_Locked
*/
private void onQueryFdnEnabled(AsyncResult ar) {
if(ar.exception != null) {
if(DBG) log("Error in querying facility lock:" + ar.exception);
return;
}
int[] ints = (int[])ar.result;
if(ints.length != 0) {
mRuimFdnEnabled = (0!=ints[0]);
if(DBG) log("Query facility lock : " + mRuimFdnEnabled);
} else {
Log.e(LOG_TAG, "[CdmaRuimCard] Bogus facility lock response");
}
}
private void
getRuimStatusDone(AsyncResult ar) {
if (ar.exception != null) {
Log.e(LOG_TAG,"Error getting SIM status. "
+ "RIL_REQUEST_GET_SIM_STATUS should "
+ "never return an error", ar.exception);
return;
}
CommandsInterface.IccStatus newStatus
= (CommandsInterface.IccStatus) ar.result;
handleRuimStatus(newStatus);
}
private void
handleRuimStatus(CommandsInterface.IccStatus newStatus) {
boolean transitionedIntoPinLocked;
boolean transitionedIntoAbsent;
boolean transitionedIntoNetworkLocked;
RuimCard.State oldState, newState;
oldState = getState();
status = newStatus;
newState = getState();
updateStateProperty();
transitionedIntoPinLocked = (
(oldState != State.PIN_REQUIRED && newState == State.PIN_REQUIRED)
|| (oldState != State.PUK_REQUIRED && newState == State.PUK_REQUIRED));
transitionedIntoAbsent = (oldState != State.ABSENT && newState == State.ABSENT);
transitionedIntoNetworkLocked = (oldState != State.NETWORK_LOCKED
&& newState == State.NETWORK_LOCKED);
if (transitionedIntoPinLocked) {
if(DBG) log("Notify RUIM pin or puk locked.");
pinLockedRegistrants.notifyRegistrants();
broadcastRuimStateChangedIntent(RuimCard.INTENT_VALUE_ICC_LOCKED,
(newState == State.PIN_REQUIRED) ?
INTENT_VALUE_LOCKED_ON_PIN : INTENT_VALUE_LOCKED_ON_PUK);
} else if (transitionedIntoAbsent) {
if(DBG) log("Notify RUIM missing.");
absentRegistrants.notifyRegistrants();
broadcastRuimStateChangedIntent(RuimCard.INTENT_VALUE_ICC_ABSENT, null);
} else if (transitionedIntoNetworkLocked) {
if(DBG) log("Notify RUIM network locked.");
networkLockedRegistrants.notifyRegistrants();
broadcastRuimStateChangedIntent(RuimCard.INTENT_VALUE_ICC_LOCKED,
INTENT_VALUE_LOCKED_NETWORK);
}
}
public void broadcastRuimStateChangedIntent(String value, String reason) {
Intent intent = new Intent(TelephonyIntents.ACTION_SIM_STATE_CHANGED);
intent.putExtra(Phone.PHONE_NAME_KEY, phone.getPhoneName());
intent.putExtra(RuimCard.INTENT_KEY_ICC_STATE, value);
intent.putExtra(RuimCard.INTENT_KEY_LOCKED_REASON, reason);
if(DBG) log("Broadcasting intent SIM_STATE_CHANGED_ACTION " + value
+ " reason " + reason);
ActivityManagerNative.broadcastStickyIntent(intent, READ_PHONE_STATE);
}
public void updateImsiConfiguration(String imsi) {
if (imsi.length() >= 6) {
Configuration config = new Configuration();
config.mcc = ((imsi.charAt(0)-'0')*100)
+ ((imsi.charAt(1)-'0')*10)
+ (imsi.charAt(2)-'0');
config.mnc = ((imsi.charAt(3)-'0')*100)
+ ((imsi.charAt(4)-'0')*10)
+ (imsi.charAt(5)-'0');
try {
ActivityManagerNative.getDefault().updateConfiguration(config);
} catch (RemoteException e) {
}
}
}
private void
updateStateProperty() {
phone.setSystemProperty(
TelephonyProperties.PROPERTY_SIM_STATE,
getState().toString());
}
private void log(String msg) {
Log.d(LOG_TAG, "[RuimCard] " + msg);
}
}
}

View File

@ -342,7 +342,7 @@ public final class RuimRecords extends IccRecords {
recordsLoadedRegistrants.notifyRegistrants(
new AsyncResult(null, null, null));
((CDMAPhone) phone).mRuimCard.broadcastRuimStateChangedIntent(
((CDMAPhone) phone).mRuimCard.broadcastIccStateChangedIntent(
RuimCard.INTENT_VALUE_ICC_LOADED, null);
}
@ -351,7 +351,7 @@ public final class RuimRecords extends IccRecords {
READY is sent before IMSI ready
*/
((CDMAPhone) phone).mRuimCard.broadcastRuimStateChangedIntent(
((CDMAPhone) phone).mRuimCard.broadcastIccStateChangedIntent(
RuimCard.INTENT_VALUE_ICC_READY, null);
fetchRuimRecords();

View File

@ -16,41 +16,29 @@
package com.android.internal.telephony.gsm;
import android.app.ActivityManagerNative;
import static com.android.internal.telephony.TelephonyProperties.PROPERTY_ICC_OPERATOR_ALPHA;
import static com.android.internal.telephony.TelephonyProperties.PROPERTY_ICC_OPERATOR_ISO_COUNTRY;
import static com.android.internal.telephony.TelephonyProperties.PROPERTY_ICC_OPERATOR_NUMERIC;
import android.app.AlarmManager;
import android.app.IActivityManager;
import android.content.Context;
import android.content.res.Configuration;
import android.net.wifi.WifiManager;
import android.os.AsyncResult;
import android.os.Handler;
import android.os.Message;
import android.os.SystemProperties;
import android.os.Registrant;
import android.provider.Settings;
import android.util.Log;
import java.util.ArrayList;
import static com.android.internal.telephony.TelephonyProperties.*;
import com.android.internal.telephony.AdnRecord;
import com.android.internal.telephony.AdnRecordCache;
import com.android.internal.telephony.AdnRecordLoader;
import com.android.internal.telephony.CommandsInterface;
import com.android.internal.telephony.gsm.SimCard;
import com.android.internal.telephony.gsm.SmsMessage;
import com.android.internal.telephony.IccFileHandler;
import com.android.internal.telephony.IccRecords;
import com.android.internal.telephony.IccUtils;
import com.android.internal.telephony.IccVmFixedException;
import com.android.internal.telephony.IccVmNotSupportedException;
import com.android.internal.telephony.PhoneProxy;
import java.util.ArrayList;
/**
@ -577,7 +565,7 @@ public final class SIMRecords extends IccRecords {
Log.d(LOG_TAG, "IMSI: " + imsi.substring(0, 6) + "xxxxxxxxx");
((GSMPhone) phone).mSimCard.updateImsiConfiguration(imsi);
((GSMPhone) phone).mSimCard.broadcastSimStateChangedIntent(
((GSMPhone) phone).mSimCard.broadcastIccStateChangedIntent(
SimCard.INTENT_VALUE_ICC_IMSI, null);
int mcc = Integer.parseInt(imsi.substring(0, 3));
@ -1204,7 +1192,7 @@ public final class SIMRecords extends IccRecords {
recordsLoadedRegistrants.notifyRegistrants(
new AsyncResult(null, null, null));
((GSMPhone) phone).mSimCard.broadcastSimStateChangedIntent(
((GSMPhone) phone).mSimCard.broadcastIccStateChangedIntent(
SimCard.INTENT_VALUE_ICC_LOADED, null);
}
@ -1229,7 +1217,7 @@ public final class SIMRecords extends IccRecords {
/* broadcast intent SIM_READY here so that we can make sure
READY is sent before IMSI ready
*/
((GSMPhone) phone).mSimCard.broadcastSimStateChangedIntent(
((GSMPhone) phone).mSimCard.broadcastIccStateChangedIntent(
SimCard.INTENT_VALUE_ICC_READY, null);
fetchSimRecords();

View File

@ -17,469 +17,37 @@
package com.android.internal.telephony.gsm;
import android.app.ActivityManagerNative;
import android.content.Intent;
import android.content.res.Configuration;
import android.os.AsyncResult;
import android.os.RemoteException;
import android.os.Handler;
import android.os.Message;
import android.os.Registrant;
import android.os.RegistrantList;
import android.util.Log;
import com.android.internal.telephony.CommandsInterface;
import com.android.internal.telephony.IccCard;
import com.android.internal.telephony.Phone;
import com.android.internal.telephony.PhoneProxy;
import com.android.internal.telephony.TelephonyIntents;
import com.android.internal.telephony.TelephonyProperties;
import static android.Manifest.permission.READ_PHONE_STATE;
/**
* Note: this class shares common code with RuimCard, consider a base class to minimize code
* duplication.
* {@hide}
*/
public final class SimCard extends Handler implements IccCard {
static final String LOG_TAG="GSM";
//***** Instance Variables
private static final boolean DBG = true;
private GSMPhone phone;
private CommandsInterface.IccStatus status = null;
private boolean mDesiredPinLocked;
private boolean mDesiredFdnEnabled;
private boolean mSimPinLocked = true; // Default to locked
private boolean mSimFdnEnabled = false; // Default to disabled.
// Will be updated when SIM_READY.
//***** Constants
// FIXME I hope this doesn't conflict with the Dialer's notifications
static final int NOTIFICATION_ID_SIM_STATUS = 33456;
//***** Event Constants
static final int EVENT_SIM_LOCKED_OR_ABSENT = 1;
static final int EVENT_GET_SIM_STATUS_DONE = 2;
static final int EVENT_RADIO_OFF_OR_NOT_AVAILABLE = 3;
static final int EVENT_PINPUK_DONE = 4;
static final int EVENT_REPOLL_STATUS_DONE = 5;
static final int EVENT_SIM_READY = 6;
static final int EVENT_QUERY_FACILITY_LOCK_DONE = 7;
static final int EVENT_CHANGE_FACILITY_LOCK_DONE = 8;
static final int EVENT_CHANGE_SIM_PASSWORD_DONE = 9;
static final int EVENT_QUERY_FACILITY_FDN_DONE = 10;
static final int EVENT_CHANGE_FACILITY_FDN_DONE = 11;
//***** Constructor
public final class SimCard extends IccCard {
SimCard(GSMPhone phone) {
this.phone = phone;
phone.mCM.registerForSIMLockedOrAbsent(
this, EVENT_SIM_LOCKED_OR_ABSENT, null);
phone.mCM.registerForOffOrNotAvailable(
this, EVENT_RADIO_OFF_OR_NOT_AVAILABLE, null);
phone.mCM.registerForSIMReady(
this, EVENT_SIM_READY, null);
super(phone, "GSM", true);
mPhone.mCM.registerForSIMLockedOrAbsent(mHandler, EVENT_ICC_LOCKED_OR_ABSENT, null);
mPhone.mCM.registerForOffOrNotAvailable(mHandler, EVENT_RADIO_OFF_OR_NOT_AVAILABLE, null);
mPhone.mCM.registerForSIMReady(mHandler, EVENT_ICC_READY, null);
updateStateProperty();
}
@Override
public void dispose() {
//Unregister for all events
phone.mCM.unregisterForSIMLockedOrAbsent(this);
phone.mCM.unregisterForOffOrNotAvailable(this);
phone.mCM.unregisterForSIMReady(this);
mPhone.mCM.unregisterForSIMLockedOrAbsent(mHandler);
mPhone.mCM.unregisterForOffOrNotAvailable(mHandler);
mPhone.mCM.unregisterForSIMReady(mHandler);
}
protected void finalize() {
if(DBG) Log.d(LOG_TAG, "SimCard finalized");
}
//***** SimCard implementation
public State
getState() {
if (status == null) {
switch(phone.mCM.getRadioState()) {
/* This switch block must not return anything in
* State.isLocked() or State.ABSENT.
* If it does, handleSimStatus() may break
*/
case RADIO_OFF:
case RADIO_UNAVAILABLE:
case SIM_NOT_READY:
return State.UNKNOWN;
case SIM_LOCKED_OR_ABSENT:
//this should be transient-only
return State.UNKNOWN;
case SIM_READY:
return State.READY;
}
} else {
switch (status) {
case ICC_ABSENT: return State.ABSENT;
case ICC_NOT_READY: return State.UNKNOWN;
case ICC_READY: return State.READY;
case ICC_PIN: return State.PIN_REQUIRED;
case ICC_PUK: return State.PUK_REQUIRED;
case ICC_NETWORK_PERSONALIZATION: return State.NETWORK_LOCKED;
}
}
Log.e(LOG_TAG, "GsmSimCard.getState(): case should never be reached");
return State.UNKNOWN;
}
private RegistrantList absentRegistrants = new RegistrantList();
private RegistrantList pinLockedRegistrants = new RegistrantList();
private RegistrantList networkLockedRegistrants = new RegistrantList();
public void registerForAbsent(Handler h, int what, Object obj) {
Registrant r = new Registrant (h, what, obj);
absentRegistrants.add(r);
if (getState() == State.ABSENT) {
r.notifyRegistrant();
}
}
public void unregisterForAbsent(Handler h) {
absentRegistrants.remove(h);
}
public void registerForNetworkLocked(Handler h, int what, Object obj) {
Registrant r = new Registrant (h, what, obj);
networkLockedRegistrants.add(r);
if (getState() == State.NETWORK_LOCKED) {
r.notifyRegistrant();
}
}
public void unregisterForNetworkLocked(Handler h) {
networkLockedRegistrants.remove(h);
}
public void registerForLocked(Handler h, int what, Object obj) {
Registrant r = new Registrant (h, what, obj);
pinLockedRegistrants.add(r);
if (getState().isPinLocked()) {
r.notifyRegistrant();
}
}
public void unregisterForLocked(Handler h) {
pinLockedRegistrants.remove(h);
}
public void supplyPin (String pin, Message onComplete) {
phone.mCM.supplyIccPin(pin,
obtainMessage(EVENT_PINPUK_DONE, onComplete));
}
public void supplyPuk (String puk, String newPin, Message onComplete) {
phone.mCM.supplyIccPuk(puk, newPin,
obtainMessage(EVENT_PINPUK_DONE, onComplete));
}
public void supplyPin2 (String pin2, Message onComplete) {
phone.mCM.supplyIccPin2(pin2,
obtainMessage(EVENT_PINPUK_DONE, onComplete));
}
public void supplyPuk2 (String puk2, String newPin2, Message onComplete) {
phone.mCM.supplyIccPuk2(puk2, newPin2,
obtainMessage(EVENT_PINPUK_DONE, onComplete));
}
public void supplyNetworkDepersonalization (String pin, Message onComplete) {
if(DBG) log("Network Despersonalization: " + pin);
phone.mCM.supplyNetworkDepersonalization(pin,
obtainMessage(EVENT_PINPUK_DONE, onComplete));
}
public boolean getIccLockEnabled() {
return mSimPinLocked;
}
public boolean getIccFdnEnabled() {
return mSimFdnEnabled;
}
public void setIccLockEnabled (boolean enabled,
String password, Message onComplete) {
int serviceClassX;
serviceClassX = CommandsInterface.SERVICE_CLASS_VOICE +
CommandsInterface.SERVICE_CLASS_DATA +
CommandsInterface.SERVICE_CLASS_FAX;
mDesiredPinLocked = enabled;
phone.mCM.setFacilityLock(CommandsInterface.CB_FACILITY_BA_SIM,
enabled, password, serviceClassX,
obtainMessage(EVENT_CHANGE_FACILITY_LOCK_DONE, onComplete));
}
public void setIccFdnEnabled (boolean enabled,
String password, Message onComplete) {
int serviceClassX;
serviceClassX = CommandsInterface.SERVICE_CLASS_VOICE +
CommandsInterface.SERVICE_CLASS_DATA +
CommandsInterface.SERVICE_CLASS_FAX +
CommandsInterface.SERVICE_CLASS_SMS;
mDesiredFdnEnabled = enabled;
phone.mCM.setFacilityLock(CommandsInterface.CB_FACILITY_BA_FD,
enabled, password, serviceClassX,
obtainMessage(EVENT_CHANGE_FACILITY_FDN_DONE, onComplete));
}
public void changeIccLockPassword(String oldPassword, String newPassword,
Message onComplete) {
if(DBG) log("Change Pin1 old: " + oldPassword + " new: " + newPassword);
phone.mCM.changeIccPin(oldPassword, newPassword,
obtainMessage(EVENT_CHANGE_SIM_PASSWORD_DONE, onComplete));
}
public void changeIccFdnPassword(String oldPassword, String newPassword,
Message onComplete) {
if(DBG) log("Change Pin2 old: " + oldPassword + " new: " + newPassword);
phone.mCM.changeIccPin2(oldPassword, newPassword,
obtainMessage(EVENT_CHANGE_SIM_PASSWORD_DONE, onComplete));
}
public String getServiceProviderName () {
return phone.mSIMRecords.getServiceProviderName();
}
//***** Handler implementation
@Override
public void handleMessage(Message msg){
AsyncResult ar;
int serviceClassX;
serviceClassX = CommandsInterface.SERVICE_CLASS_VOICE +
CommandsInterface.SERVICE_CLASS_DATA +
CommandsInterface.SERVICE_CLASS_FAX;
switch (msg.what) {
case EVENT_RADIO_OFF_OR_NOT_AVAILABLE:
status = null;
updateStateProperty();
broadcastSimStateChangedIntent(SimCard.INTENT_VALUE_ICC_NOT_READY, null);
break;
case EVENT_SIM_READY:
//TODO: put facility read in SIM_READY now, maybe in REG_NW
phone.mCM.getIccStatus(obtainMessage(EVENT_GET_SIM_STATUS_DONE));
phone.mCM.queryFacilityLock (
CommandsInterface.CB_FACILITY_BA_SIM, "", serviceClassX,
obtainMessage(EVENT_QUERY_FACILITY_LOCK_DONE));
phone.mCM.queryFacilityLock (
CommandsInterface.CB_FACILITY_BA_FD, "", serviceClassX,
obtainMessage(EVENT_QUERY_FACILITY_FDN_DONE));
break;
case EVENT_SIM_LOCKED_OR_ABSENT:
phone.mCM.getIccStatus(obtainMessage(EVENT_GET_SIM_STATUS_DONE));
phone.mCM.queryFacilityLock (
CommandsInterface.CB_FACILITY_BA_SIM, "", serviceClassX,
obtainMessage(EVENT_QUERY_FACILITY_LOCK_DONE));
break;
case EVENT_GET_SIM_STATUS_DONE:
ar = (AsyncResult)msg.obj;
getSimStatusDone(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;
phone.mCM.getIccStatus(
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
ar = (AsyncResult)msg.obj;
getSimStatusDone(ar);
((Message)ar.userObj).sendToTarget();
break;
case EVENT_QUERY_FACILITY_LOCK_DONE:
ar = (AsyncResult)msg.obj;
onQueryFacilityLock(ar);
break;
case EVENT_QUERY_FACILITY_FDN_DONE:
ar = (AsyncResult)msg.obj;
onQueryFdnEnabled(ar);
break;
case EVENT_CHANGE_FACILITY_LOCK_DONE:
ar = (AsyncResult)msg.obj;
if (ar.exception == null) {
mSimPinLocked = mDesiredPinLocked;
if (DBG) log( "EVENT_CHANGE_FACILITY_LOCK_DONE: " +
"mSimPinLocked= " + mSimPinLocked);
} else {
Log.e(LOG_TAG, "Error change facility lock with exception "
+ ar.exception);
}
AsyncResult.forMessage(((Message)ar.userObj)).exception
= ar.exception;
((Message)ar.userObj).sendToTarget();
break;
case EVENT_CHANGE_FACILITY_FDN_DONE:
ar = (AsyncResult)msg.obj;
if (ar.exception == null) {
mSimFdnEnabled = mDesiredFdnEnabled;
if (DBG) log("EVENT_CHANGE_FACILITY_FDN_DONE: " +
"mSimFdnEnabled=" + mSimFdnEnabled);
} else {
Log.e(LOG_TAG, "Error change facility fdn with exception "
+ ar.exception);
}
AsyncResult.forMessage(((Message)ar.userObj)).exception
= ar.exception;
((Message)ar.userObj).sendToTarget();
break;
case EVENT_CHANGE_SIM_PASSWORD_DONE:
ar = (AsyncResult)msg.obj;
if(ar.exception != null) {
Log.e(LOG_TAG, "Error in change sim password with exception"
+ ar.exception);
}
AsyncResult.forMessage(((Message)ar.userObj)).exception
= ar.exception;
((Message)ar.userObj).sendToTarget();
break;
default:
Log.e(LOG_TAG, "[GsmSimCard] Unknown Event " + msg.what);
}
}
//***** Private methods
/**
* Interperate EVENT_QUERY_FACILITY_LOCK_DONE
* @param ar is asyncResult of Query_Facility_Locked
*/
private void onQueryFacilityLock(AsyncResult ar) {
if(ar.exception != null) {
if (DBG) log("Error in querying facility lock:" + ar.exception);
return;
}
int[] ints = (int[])ar.result;
if(ints.length != 0) {
mSimPinLocked = (0!=ints[0]);
if(DBG) log("Query facility lock : " + mSimPinLocked);
} else {
Log.e(LOG_TAG, "[GsmSimCard] Bogus facility lock response");
}
}
/**
* Interperate EVENT_QUERY_FACILITY_LOCK_DONE
* @param ar is asyncResult of Query_Facility_Locked
*/
private void onQueryFdnEnabled(AsyncResult ar) {
if(ar.exception != null) {
if(DBG) log("Error in querying facility lock:" + ar.exception);
return;
}
int[] ints = (int[])ar.result;
if(ints.length != 0) {
mSimFdnEnabled = (0!=ints[0]);
if(DBG) log("Query facility lock : " + mSimFdnEnabled);
} else {
Log.e(LOG_TAG, "[GsmSimCard] Bogus facility lock response");
}
}
private void
getSimStatusDone(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;
}
CommandsInterface.IccStatus newStatus
= (CommandsInterface.IccStatus) ar.result;
handleSimStatus(newStatus);
}
private void
handleSimStatus(CommandsInterface.IccStatus newStatus) {
boolean transitionedIntoPinLocked;
boolean transitionedIntoAbsent;
boolean transitionedIntoNetworkLocked;
SimCard.State oldState, newState;
oldState = getState();
status = newStatus;
newState = getState();
updateStateProperty();
transitionedIntoPinLocked = (
(oldState != State.PIN_REQUIRED && newState == State.PIN_REQUIRED)
|| (oldState != State.PUK_REQUIRED && newState == State.PUK_REQUIRED));
transitionedIntoAbsent = (oldState != State.ABSENT && newState == State.ABSENT);
transitionedIntoNetworkLocked = (oldState != State.NETWORK_LOCKED
&& newState == State.NETWORK_LOCKED);
if (transitionedIntoPinLocked) {
if(DBG) log("Notify SIM pin or puk locked.");
pinLockedRegistrants.notifyRegistrants();
broadcastSimStateChangedIntent(SimCard.INTENT_VALUE_ICC_LOCKED,
(newState == State.PIN_REQUIRED) ?
INTENT_VALUE_LOCKED_ON_PIN : INTENT_VALUE_LOCKED_ON_PUK);
} else if (transitionedIntoAbsent) {
if(DBG) log("Notify SIM missing.");
absentRegistrants.notifyRegistrants();
broadcastSimStateChangedIntent(SimCard.INTENT_VALUE_ICC_ABSENT, null);
} else if (transitionedIntoNetworkLocked) {
if(DBG) log("Notify SIM network locked.");
networkLockedRegistrants.notifyRegistrants();
broadcastSimStateChangedIntent(SimCard.INTENT_VALUE_ICC_LOCKED,
INTENT_VALUE_LOCKED_NETWORK);
}
}
public void broadcastSimStateChangedIntent(String value, String reason) {
Intent intent = new Intent(TelephonyIntents.ACTION_SIM_STATE_CHANGED);
intent.putExtra(Phone.PHONE_NAME_KEY, phone.getPhoneName());
intent.putExtra(SimCard.INTENT_KEY_ICC_STATE, value);
intent.putExtra(SimCard.INTENT_KEY_LOCKED_REASON, reason);
if(DBG) log("Broadcasting intent SIM_STATE_CHANGED_ACTION " + value
+ " reason " + reason);
ActivityManagerNative.broadcastStickyIntent(intent, READ_PHONE_STATE);
public String getServiceProviderName () {
return ((GSMPhone)mPhone).mSIMRecords.getServiceProviderName();
}
public void updateImsiConfiguration(String imsi) {
@ -494,19 +62,8 @@ public final class SimCard extends Handler implements IccCard {
try {
ActivityManagerNative.getDefault().updateConfiguration(config);
} catch (RemoteException e) {
Log.e(mLogTag, "[SimCard] Remote Exception when updating imsi configuration");
}
}
}
private void
updateStateProperty() {
phone.setSystemProperty(
TelephonyProperties.PROPERTY_SIM_STATE,
getState().toString());
}
private void log(String msg) {
Log.d(LOG_TAG, "[GsmSimCard] " + msg);
}
}

View File

@ -27,10 +27,11 @@ import com.android.internal.telephony.BaseCommands;
import com.android.internal.telephony.CommandException;
import com.android.internal.telephony.CommandsInterface;
import com.android.internal.telephony.DataCallState;
import com.android.internal.telephony.IccCard;
import com.android.internal.telephony.Phone;
import com.android.internal.telephony.gsm.CallFailCause;
import com.android.internal.telephony.gsm.SmsBroadcastConfigInfo;
import com.android.internal.telephony.gsm.SuppServiceNotification;
import com.android.internal.telephony.Phone;
import java.util.ArrayList;
@ -103,39 +104,8 @@ public final class SimulatedCommands extends BaseCommands
//***** CommandsInterface implementation
public void getIccStatus(Message result) {
switch (mState) {
case SIM_READY:
resultSuccess(result, IccStatus.ICC_READY);
break;
case SIM_LOCKED_OR_ABSENT:
returnSimLockedStatus(result);
break;
default:
resultSuccess(result, IccStatus.ICC_NOT_READY);
break;
}
}
private void returnSimLockedStatus(Message result) {
switch (mSimLockedState) {
case REQUIRE_PIN:
Log.i(LOG_TAG, "[SimCmd] returnSimLockedStatus: ICC_PIN");
resultSuccess(result, IccStatus.ICC_PIN);
break;
case REQUIRE_PUK:
Log.i(LOG_TAG, "[SimCmd] returnSimLockedStatus: ICC_PUK");
resultSuccess(result, IccStatus.ICC_PUK);
break;
default:
Log.i(LOG_TAG,
"[SimCmd] returnSimLockedStatus: mSimLockedState==NONE !?");
break;
}
public void getIccCardStatus(Message result) {
unimplemented(result);
}
public void supplyIccPin(String pin, Message result) {