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:
@ -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);
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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();
|
||||
|
@ -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();
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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) {
|
||||
|
Reference in New Issue
Block a user