IccCardProxy 主要是对IccCard的实现,它主要有如下几个功能。
<1> 通过 UiccController,获取UiccCard,UiccCardApplication,IccRecords 的最新状态。
1.通过 UiccController监听SIM卡的变化信息
mUiccController = UiccController.getInstance();
mUiccController.registerForIccChanged(this, EVENT_ICC_CHANGED, null);
...
case EVENT_ICC_CHANGED:
if (mInitialized) {
updateIccAvailability();
}
break;
private void updateIccAvailability() {
synchronized (mLock) {
UiccCard newCard = mUiccController.getUiccCard();
CardState state = CardState.CARDSTATE_ABSENT;
UiccCardApplication newApp = null;
IccRecords newRecords = null;
if (newCard != null) {
state = newCard.getCardState();
newApp = newCard.getApplication(mCurrentAppType);
if (newApp != null) {
newRecords = newApp.getIccRecords();
}
}
if (mIccRecords != newRecords || mUiccApplication != newApp || mUiccCard != newCard) {
if (DBG) log("Icc changed. Reregestering.");
unregisterUiccCardEvents();
mUiccCard = newCard;
mUiccApplication = newApp;
mIccRecords = newRecords;
registerUiccCardEvents();// 注册成为 UiccCard、UiccCardApplication、IccRecords 的监听器,可以从他们获取SIM卡的相关信息
}
updateExternalState();
}
}
// 通过这个方法,当SIM卡被锁定或者SIM卡的信息加载完毕时,IccCardProxy 都可以收到
private void registerUiccCardEvents() {
if (mUiccCard != null) mUiccCard.registerForAbsent(this, EVENT_ICC_ABSENT, null);
if (mUiccApplication != null) {
mUiccApplication.registerForReady(this, EVENT_APP_READY, null);// SIM卡Ready
mUiccApplication.registerForLocked(this, EVENT_ICC_LOCKED, null);// SIM卡被PIN锁
mUiccApplication.registerForNetworkLocked(this, EVENT_NETWORK_LOCKED, null);//SIM卡被网络锁
}
if (mIccRecords != null) {
mIccRecords.registerForImsiReady(this, EVENT_IMSI_READY, null);// IMS卡准备好
mIccRecords.registerForRecordsLoaded(this, EVENT_RECORDS_LOADED, null);// SIM卡的记录加载完毕
}
}
2.监听 Radio 的状态,间接获取SIM卡的状态。
ci.registerForOn(this,EVENT_RADIO_ON, null);
ci.registerForOffOrNotAvailable(this, EVENT_RADIO_OFF_OR_UNAVAILABLE, null);
....
private void updateQuietMode() {
synchronized (mLock) {
boolean oldQuietMode = mQuietMode;
boolean newQuietMode;
int cdmaSource = Phone.CDMA_SUBSCRIPTION_UNKNOWN;
boolean isLteOnCdmaMode = TelephonyManager.getLteOnCdmaModeStatic()
== PhoneConstants.LTE_ON_CDMA_TRUE;
if (mCurrentAppType == UiccController.APP_FAM_3GPP) {
newQuietMode = false;
if (DBG) log("updateQuietMode: 3GPP subscription -> newQuietMode=" + newQuietMode);
} else {
if (isLteOnCdmaMode) {
log("updateQuietMode: is cdma/lte device, force IccCardProxy into 3gpp mode");
mCurrentAppType = UiccController.APP_FAM_3GPP;
}
cdmaSource = mCdmaSSM != null ?
mCdmaSSM.getCdmaSubscriptionSource() : Phone.CDMA_SUBSCRIPTION_UNKNOWN;
newQuietMode = (cdmaSource == Phone.CDMA_SUBSCRIPTION_NV)
&& (mCurrentAppType == UiccController.APP_FAM_3GPP2)
&& !isLteOnCdmaMode;
}
if (mQuietMode == false && newQuietMode == true) {
// Last thing to do before switching to quiet mode is
// broadcast ICC_READY
log("Switching to QuietMode.");
setExternalState(State.READY);
mQuietMode = newQuietMode;
} else if (mQuietMode == true && newQuietMode == false) {
if (DBG) {
log("updateQuietMode: Switching out from QuietMode."
+ " Force broadcast of current state=" + mExternalState);
}
mQuietMode = newQuietMode;
setExternalState(mExternalState, true);
}
if (DBG) {
log("updateQuietMode: QuietMode is " + mQuietMode + " (app_type="
+ mCurrentAppType + " isLteOnCdmaMode=" + isLteOnCdmaMode
+ " cdmaSource=" + cdmaSource + ")");
}
mInitialized = true;
sendMessage(obtainMessage(EVENT_ICC_CHANGED));
}
}
private void setExternalState(State newState, boolean override) {
synchronized (mLock) {
if (!override && newState == mExternalState) {
return;
}
mExternalState = newState;
SystemProperties.set(PROPERTY_SIM_STATE, mExternalState.toString());
broadcastIccStateChangedIntent(getIccStateIntentString(mExternalState),
getIccStateReason(mExternalState));
}
}
3.获得SIM卡的最新的状态信息后,将SIM卡的信息广播除去.(ACTION_SIM_STATE_CHANGED)
private void broadcastIccStateChangedIntent(String value, String reason) {
synchronized (mLock) {
if (mQuietMode) {
log("QuietMode: NOT Broadcasting intent ACTION_SIM_STATE_CHANGED " + value
+ " reason " + reason);
return;
}
Intent intent = new Intent(TelephonyIntents.ACTION_SIM_STATE_CHANGED);
intent.addFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING);
intent.putExtra(PhoneConstants.PHONE_NAME_KEY, "Phone");
intent.putExtra(IccCardConstants.INTENT_KEY_ICC_STATE, value);
intent.putExtra(IccCardConstants.INTENT_KEY_LOCKED_REASON, reason);
if (DBG) log("Broadcasting intent ACTION_SIM_STATE_CHANGED " + value
+ " reason " + reason);
ActivityManagerNative.broadcastStickyIntent(intent, READ_PHONE_STATE,
UserHandle.USER_ALL);
}
}
<2>通过 CdmaSubscriptionSourceManager,管理CDMA网络订阅信息,从RUIM或者NV获取CDMA的订阅信息
<1> 通过 UiccController,获取UiccCard,UiccCardApplication,IccRecords 的最新状态。
1.通过 UiccController监听SIM卡的变化信息
mUiccController = UiccController.getInstance();
mUiccController.registerForIccChanged(this, EVENT_ICC_CHANGED, null);
...
case EVENT_ICC_CHANGED:
if (mInitialized) {
updateIccAvailability();
}
break;
private void updateIccAvailability() {
synchronized (mLock) {
UiccCard newCard = mUiccController.getUiccCard();
CardState state = CardState.CARDSTATE_ABSENT;
UiccCardApplication newApp = null;
IccRecords newRecords = null;
if (newCard != null) {
state = newCard.getCardState();
newApp = newCard.getApplication(mCurrentAppType);
if (newApp != null) {
newRecords = newApp.getIccRecords();
}
}
if (mIccRecords != newRecords || mUiccApplication != newApp || mUiccCard != newCard) {
if (DBG) log("Icc changed. Reregestering.");
unregisterUiccCardEvents();
mUiccCard = newCard;
mUiccApplication = newApp;
mIccRecords = newRecords;
registerUiccCardEvents();// 注册成为 UiccCard、UiccCardApplication、IccRecords 的监听器,可以从他们获取SIM卡的相关信息
}
updateExternalState();
}
}
// 通过这个方法,当SIM卡被锁定或者SIM卡的信息加载完毕时,IccCardProxy 都可以收到
private void registerUiccCardEvents() {
if (mUiccCard != null) mUiccCard.registerForAbsent(this, EVENT_ICC_ABSENT, null);
if (mUiccApplication != null) {
mUiccApplication.registerForReady(this, EVENT_APP_READY, null);// SIM卡Ready
mUiccApplication.registerForLocked(this, EVENT_ICC_LOCKED, null);// SIM卡被PIN锁
mUiccApplication.registerForNetworkLocked(this, EVENT_NETWORK_LOCKED, null);//SIM卡被网络锁
}
if (mIccRecords != null) {
mIccRecords.registerForImsiReady(this, EVENT_IMSI_READY, null);// IMS卡准备好
mIccRecords.registerForRecordsLoaded(this, EVENT_RECORDS_LOADED, null);// SIM卡的记录加载完毕
}
}
2.监听 Radio 的状态,间接获取SIM卡的状态。
ci.registerForOn(this,EVENT_RADIO_ON, null);
ci.registerForOffOrNotAvailable(this, EVENT_RADIO_OFF_OR_UNAVAILABLE, null);
....
private void updateQuietMode() {
synchronized (mLock) {
boolean oldQuietMode = mQuietMode;
boolean newQuietMode;
int cdmaSource = Phone.CDMA_SUBSCRIPTION_UNKNOWN;
boolean isLteOnCdmaMode = TelephonyManager.getLteOnCdmaModeStatic()
== PhoneConstants.LTE_ON_CDMA_TRUE;
if (mCurrentAppType == UiccController.APP_FAM_3GPP) {
newQuietMode = false;
if (DBG) log("updateQuietMode: 3GPP subscription -> newQuietMode=" + newQuietMode);
} else {
if (isLteOnCdmaMode) {
log("updateQuietMode: is cdma/lte device, force IccCardProxy into 3gpp mode");
mCurrentAppType = UiccController.APP_FAM_3GPP;
}
cdmaSource = mCdmaSSM != null ?
mCdmaSSM.getCdmaSubscriptionSource() : Phone.CDMA_SUBSCRIPTION_UNKNOWN;
newQuietMode = (cdmaSource == Phone.CDMA_SUBSCRIPTION_NV)
&& (mCurrentAppType == UiccController.APP_FAM_3GPP2)
&& !isLteOnCdmaMode;
}
if (mQuietMode == false && newQuietMode == true) {
// Last thing to do before switching to quiet mode is
// broadcast ICC_READY
log("Switching to QuietMode.");
setExternalState(State.READY);
mQuietMode = newQuietMode;
} else if (mQuietMode == true && newQuietMode == false) {
if (DBG) {
log("updateQuietMode: Switching out from QuietMode."
+ " Force broadcast of current state=" + mExternalState);
}
mQuietMode = newQuietMode;
setExternalState(mExternalState, true);
}
if (DBG) {
log("updateQuietMode: QuietMode is " + mQuietMode + " (app_type="
+ mCurrentAppType + " isLteOnCdmaMode=" + isLteOnCdmaMode
+ " cdmaSource=" + cdmaSource + ")");
}
mInitialized = true;
sendMessage(obtainMessage(EVENT_ICC_CHANGED));
}
}
private void setExternalState(State newState, boolean override) {
synchronized (mLock) {
if (!override && newState == mExternalState) {
return;
}
mExternalState = newState;
SystemProperties.set(PROPERTY_SIM_STATE, mExternalState.toString());
broadcastIccStateChangedIntent(getIccStateIntentString(mExternalState),
getIccStateReason(mExternalState));
}
}
3.获得SIM卡的最新的状态信息后,将SIM卡的信息广播除去.(ACTION_SIM_STATE_CHANGED)
private void broadcastIccStateChangedIntent(String value, String reason) {
synchronized (mLock) {
if (mQuietMode) {
log("QuietMode: NOT Broadcasting intent ACTION_SIM_STATE_CHANGED " + value
+ " reason " + reason);
return;
}
Intent intent = new Intent(TelephonyIntents.ACTION_SIM_STATE_CHANGED);
intent.addFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING);
intent.putExtra(PhoneConstants.PHONE_NAME_KEY, "Phone");
intent.putExtra(IccCardConstants.INTENT_KEY_ICC_STATE, value);
intent.putExtra(IccCardConstants.INTENT_KEY_LOCKED_REASON, reason);
if (DBG) log("Broadcasting intent ACTION_SIM_STATE_CHANGED " + value
+ " reason " + reason);
ActivityManagerNative.broadcastStickyIntent(intent, READ_PHONE_STATE,
UserHandle.USER_ALL);
}
}
<2>通过 CdmaSubscriptionSourceManager,管理CDMA网络订阅信息,从RUIM或者NV获取CDMA的订阅信息