Loading src/java/com/android/internal/telephony/uicc/IccCardProxy.java +9 −4 Original line number Diff line number Diff line Loading @@ -97,6 +97,7 @@ public class IccCardProxy extends Handler implements IccCard { private int mCurrentAppType = UiccController.APP_FAM_3GPP; //default to 3gpp? private UiccController mUiccController = null; private UiccSlot mUiccSlot = null; private UiccCard mUiccCard = null; private UiccCardApplication mUiccApplication = null; private IccRecords mIccRecords = null; Loading Loading @@ -293,6 +294,7 @@ public class IccCardProxy extends Handler implements IccCard { private void updateIccAvailability() { synchronized (mLock) { UiccSlot newSlot = mUiccController.getUiccSlotForPhone(mPhoneId); UiccCard newCard = mUiccController.getUiccCard(mPhoneId); UiccCardApplication newApp = null; IccRecords newRecords = null; Loading @@ -303,9 +305,11 @@ public class IccCardProxy extends Handler implements IccCard { } } if (mIccRecords != newRecords || mUiccApplication != newApp || mUiccCard != newCard) { if (mIccRecords != newRecords || mUiccApplication != newApp || mUiccCard != newCard || mUiccSlot != newSlot) { if (DBG) log("Icc changed. Reregistering."); unregisterUiccCardEvents(); mUiccSlot = newSlot; mUiccCard = newCard; mUiccApplication = newApp; mIccRecords = newRecords; Loading Loading @@ -406,8 +410,9 @@ public class IccCardProxy extends Handler implements IccCard { } private void registerUiccCardEvents() { if (mUiccCard != null) { mUiccCard.registerForAbsent(this, EVENT_ICC_ABSENT, null); if (mUiccSlot != null) { // todo: reregistration is not needed unless slot mapping changes mUiccSlot.registerForAbsent(this, EVENT_ICC_ABSENT, null); } if (mUiccApplication != null) { mUiccApplication.registerForReady(this, EVENT_APP_READY, null); Loading @@ -422,7 +427,7 @@ public class IccCardProxy extends Handler implements IccCard { } private void unregisterUiccCardEvents() { if (mUiccCard != null) mUiccCard.unregisterForAbsent(this); if (mUiccSlot != null) mUiccSlot.unregisterForAbsent(this); if (mUiccCard != null) mUiccCard.unregisterForCarrierPrivilegeRulesLoaded(this); if (mUiccApplication != null) mUiccApplication.unregisterForReady(this); if (mUiccApplication != null) mUiccApplication.unregisterForLocked(this); Loading src/java/com/android/internal/telephony/uicc/UiccCard.java +0 −133 Original line number Diff line number Diff line Loading @@ -18,8 +18,6 @@ package com.android.internal.telephony.uicc; import android.app.AlertDialog; import android.app.usage.UsageStatsManager; import android.content.ActivityNotFoundException; import android.content.ComponentName; import android.content.Context; import android.content.DialogInterface; import android.content.Intent; Loading @@ -34,7 +32,6 @@ import android.os.Binder; import android.os.Handler; import android.os.Message; import android.os.PersistableBundle; import android.os.PowerManager; import android.os.Registrant; import android.os.RegistrantList; import android.preference.PreferenceManager; Loading @@ -48,7 +45,6 @@ import android.view.WindowManager; import com.android.internal.R; import com.android.internal.telephony.CommandsInterface; import com.android.internal.telephony.CommandsInterface.RadioState; import com.android.internal.telephony.SubscriptionController; import com.android.internal.telephony.cat.CatService; import com.android.internal.telephony.uicc.IccCardApplicationStatus.AppType; Loading Loading @@ -84,14 +80,10 @@ public class UiccCard { private Context mContext; private CommandsInterface mCi; private CatService mCatService; private RadioState mLastRadioState = RadioState.RADIO_UNAVAILABLE; private UiccCarrierPrivilegeRules mCarrierPrivilegeRules; private RegistrantList mAbsentRegistrants = new RegistrantList(); private RegistrantList mCarrierPrivilegeRegistrants = new RegistrantList(); private static final int EVENT_CARD_REMOVED = 13; private static final int EVENT_CARD_ADDED = 14; private static final int EVENT_OPEN_LOGICAL_CHANNEL_DONE = 15; private static final int EVENT_CLOSE_LOGICAL_CHANNEL_DONE = 16; private static final int EVENT_TRANSMIT_APDU_LOGICAL_CHANNEL_DONE = 17; Loading Loading @@ -168,24 +160,6 @@ public class UiccCard { } sanitizeApplicationIndexesLocked(); RadioState radioState = mCi.getRadioState(); if (DBG) log("update: radioState=" + radioState + " mLastRadioState=" + mLastRadioState); // No notifications while radio is off or we just powering up if (radioState == RadioState.RADIO_ON && mLastRadioState == RadioState.RADIO_ON) { if (oldState != CardState.CARDSTATE_ABSENT && mCardState == CardState.CARDSTATE_ABSENT) { if (DBG) log("update: notify card removed"); mAbsentRegistrants.notifyRegistrants(); mHandler.sendMessage(mHandler.obtainMessage(EVENT_CARD_REMOVED, null)); } else if (oldState == CardState.CARDSTATE_ABSENT && mCardState != CardState.CARDSTATE_ABSENT) { if (DBG) log("update: notify card added"); mHandler.sendMessage(mHandler.obtainMessage(EVENT_CARD_ADDED, null)); } } mLastRadioState = radioState; } } Loading Loading @@ -248,27 +222,6 @@ public class UiccCard { return index; } /** * Notifies handler of any transition into State.ABSENT */ public void registerForAbsent(Handler h, int what, Object obj) { synchronized (mLock) { Registrant r = new Registrant (h, what, obj); mAbsentRegistrants.add(r); if (mCardState == CardState.CARDSTATE_ABSENT) { r.notifyRegistrant(); } } } public void unregisterForAbsent(Handler h) { synchronized (mLock) { mAbsentRegistrants.remove(h); } } /** * Notifies handler when carrier privilege rules are loaded. */ Loading @@ -290,90 +243,10 @@ public class UiccCard { } } private void onIccSwap(boolean isAdded) { boolean isHotSwapSupported = mContext.getResources().getBoolean( R.bool.config_hotswapCapable); if (isHotSwapSupported) { log("onIccSwap: isHotSwapSupported is true, don't prompt for rebooting"); return; } log("onIccSwap: isHotSwapSupported is false, prompt for rebooting"); promptForRestart(isAdded); } private void promptForRestart(boolean isAdded) { synchronized (mLock) { final Resources res = mContext.getResources(); final String dialogComponent = res.getString( R.string.config_iccHotswapPromptForRestartDialogComponent); if (dialogComponent != null) { Intent intent = new Intent().setComponent(ComponentName.unflattenFromString( dialogComponent)).addFlags(Intent.FLAG_ACTIVITY_NEW_TASK) .putExtra(EXTRA_ICC_CARD_ADDED, isAdded); try { mContext.startActivity(intent); return; } catch (ActivityNotFoundException e) { loge("Unable to find ICC hotswap prompt for restart activity: " + e); } } // TODO: Here we assume the device can't handle SIM hot-swap // and has to reboot. We may want to add a property, // e.g. REBOOT_ON_SIM_SWAP, to indicate if modem support // hot-swap. DialogInterface.OnClickListener listener = null; // TODO: SimRecords is not reset while SIM ABSENT (only reset while // Radio_off_or_not_available). Have to reset in both both // added or removed situation. listener = new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { synchronized (mLock) { if (which == DialogInterface.BUTTON_POSITIVE) { if (DBG) log("Reboot due to SIM swap"); PowerManager pm = (PowerManager) mContext .getSystemService(Context.POWER_SERVICE); pm.reboot("SIM is added."); } } } }; Resources r = Resources.getSystem(); String title = (isAdded) ? r.getString(R.string.sim_added_title) : r.getString(R.string.sim_removed_title); String message = (isAdded) ? r.getString(R.string.sim_added_message) : r.getString(R.string.sim_removed_message); String buttonTxt = r.getString(R.string.sim_restart_button); AlertDialog dialog = new AlertDialog.Builder(mContext) .setTitle(title) .setMessage(message) .setPositiveButton(buttonTxt, listener) .create(); dialog.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT); dialog.show(); } } protected Handler mHandler = new Handler() { @Override public void handleMessage(Message msg){ switch (msg.what) { case EVENT_CARD_REMOVED: onIccSwap(false); break; case EVENT_CARD_ADDED: onIccSwap(true); break; case EVENT_OPEN_LOGICAL_CHANNEL_DONE: case EVENT_CLOSE_LOGICAL_CHANNEL_DONE: case EVENT_TRANSMIT_APDU_LOGICAL_CHANNEL_DONE: Loading Loading @@ -792,13 +665,7 @@ public class UiccCard { public void dump(FileDescriptor fd, PrintWriter pw, String[] args) { pw.println("UiccCard:"); pw.println(" mCi=" + mCi); pw.println(" mLastRadioState=" + mLastRadioState); pw.println(" mCatService=" + mCatService); pw.println(" mAbsentRegistrants: size=" + mAbsentRegistrants.size()); for (int i = 0; i < mAbsentRegistrants.size(); i++) { pw.println(" mAbsentRegistrants[" + i + "]=" + ((Registrant)mAbsentRegistrants.get(i)).getHandler()); } for (int i = 0; i < mCarrierPrivilegeRegistrants.size(); i++) { pw.println(" mCarrierPrivilegeRegistrants[" + i + "]=" + ((Registrant)mCarrierPrivilegeRegistrants.get(i)).getHandler()); Loading src/java/com/android/internal/telephony/uicc/UiccController.java +123 −50 Original line number Diff line number Diff line Loading @@ -22,15 +22,13 @@ import android.os.Handler; import android.os.Message; import android.os.Registrant; import android.os.RegistrantList; import android.os.SystemProperties; import android.os.storage.StorageManager; import android.telephony.TelephonyManager; import android.telephony.Rlog; import android.telephony.TelephonyManager; import android.text.format.Time; import com.android.internal.telephony.CommandsInterface; import com.android.internal.telephony.PhoneConstants; import com.android.internal.telephony.SubscriptionController; import java.io.FileDescriptor; import java.io.PrintWriter; Loading Loading @@ -85,12 +83,21 @@ public class UiccController extends Handler { public static final int APP_FAM_IMS = 3; private static final int EVENT_ICC_STATUS_CHANGED = 1; private static final int EVENT_GET_ICC_STATUS_DONE = 2; private static final int EVENT_RADIO_UNAVAILABLE = 3; private static final int EVENT_SIM_REFRESH = 4; private static final int EVENT_SLOT_STATUS_CHANGED = 2; private static final int EVENT_ICC_OR_SLOT_STATUS_CHANGED = 3; private static final int EVENT_GET_ICC_STATUS_DONE = 4; private static final int EVENT_RADIO_UNAVAILABLE = 5; private static final int EVENT_SIM_REFRESH = 6; // this still needs to be here, because on bootup we dont know which index maps to which // UiccSlot private CommandsInterface[] mCis; private UiccCard[] mUiccCards = new UiccCard[TelephonyManager.getDefault().getPhoneCount()]; // todo: add a system property/mk file constant for this private UiccSlot[] mUiccSlots = new UiccSlot[TelephonyManager.getDefault().getPhoneCount()]; // flag to indicate if UiccSlots have been initialized. This will be set to true only after the // first slots status is received. That is when phoneId to slotId mapping is known as well. // todo: assuming true for now and hardcoding the mapping between UiccSlot index and phoneId private boolean mUiccSlotsInitialized = true; private static final Object mLock = new Object(); private static UiccController mInstance; Loading Loading @@ -120,17 +127,23 @@ public class UiccController extends Handler { mContext = c; mCis = ci; for (int i = 0; i < mCis.length; i++) { Integer index = new Integer(i); // todo: get rid of this once hardcoding of mapping between UiccSlot index and phoneId // is removed, instead do this when icc/slot status is received mUiccSlots[i] = new UiccSlot(c, true /* isActive */); Integer index = i; mCis[i].registerForIccStatusChanged(this, EVENT_ICC_STATUS_CHANGED, index); // todo: add registration for slot status changed here // TODO remove this once modem correctly notifies the unsols // If the device is unencrypted or has been decrypted or FBE is supported, // i.e. not in cryptkeeper bounce, read SIM when radio state isavailable. // Else wait for radio to be on. This is needed for the scenario when SIM is locked -- // to avoid overlap of CryptKeeper and SIM unlock screen. if (!StorageManager.inCryptKeeperBounce()) { mCis[i].registerForAvailable(this, EVENT_ICC_STATUS_CHANGED, index); mCis[i].registerForAvailable(this, EVENT_ICC_OR_SLOT_STATUS_CHANGED, index); } else { mCis[i].registerForOn(this, EVENT_ICC_STATUS_CHANGED, index); mCis[i].registerForOn(this, EVENT_ICC_OR_SLOT_STATUS_CHANGED, index); } mCis[i].registerForNotAvailable(this, EVENT_RADIO_UNAVAILABLE, index); mCis[i].registerForIccRefresh(this, EVENT_SIM_REFRESH, index); Loading @@ -139,6 +152,13 @@ public class UiccController extends Handler { mLauncher = new UiccStateChangedLauncher(c, this); } private int getSlotIdFromPhoneId(int phoneId) { // todo: implement (if mUiccSlotsInitialized || if info available about that specific // phoneId which will be the case if sim status for that phoneId is received first) // else return invalid slotId return phoneId; } public static UiccController getInstance() { synchronized (mLock) { if (mInstance == null) { Loading @@ -151,18 +171,74 @@ public class UiccController extends Handler { public UiccCard getUiccCard(int phoneId) { synchronized (mLock) { if (isValidCardIndex(phoneId)) { return mUiccCards[phoneId]; return getUiccCardForPhone(phoneId); } } /** * API to get UiccCard corresponding to given physical slot index * @param slotId index of physical slot on the device * @return UiccCard object corresponting to given physical slot index; null if card is * absent */ public UiccCard getUiccCardForSlot(int slotId) { synchronized (mLock) { UiccSlot uiccSlot = getUiccSlot(slotId); if (uiccSlot != null) { return uiccSlot.getUiccCard(); } return null; } } public UiccCard[] getUiccCards() { /** * API to get UiccCard corresponding to given phone id * @return UiccCard object corresponding to given phone id; null if there is no card present for * the phone id */ public UiccCard getUiccCardForPhone(int phoneId) { synchronized (mLock) { int slotId = getSlotIdFromPhoneId(phoneId); return getUiccCardForSlot(slotId); } } /** * API to get an array of all UiccSlots, which represents all physical slots on the device * @return array of all UiccSlots */ public UiccSlot[] getUiccSlots() { // Return cloned array since we don't want to give out reference // to internal data structure. synchronized (mLock) { return mUiccCards.clone(); return mUiccSlots.clone(); } } /** * API to get UiccSlot object for a specific physical slot index on the device * @return UiccSlot object for the given physical slot index */ public UiccSlot getUiccSlot(int slotId) { synchronized (mLock) { if (isValidSlotIndex(slotId)) { return mUiccSlots[slotId]; } return null; } } /** * API to get UiccSlot object for a given phone id * @return UiccSlot object for the given phone id */ public UiccSlot getUiccSlotForPhone(int phoneId) { synchronized (mLock) { int slotId = getSlotIdFromPhoneId(phoneId); if (isValidSlotIndex(slotId)) { return mUiccSlots[slotId]; } return null; } } Loading Loading @@ -209,34 +285,34 @@ public class UiccController extends Handler { @Override public void handleMessage (Message msg) { synchronized (mLock) { Integer index = getCiIndex(msg); Integer phoneId = getCiIndex(msg); if (index < 0 || index >= mCis.length) { Rlog.e(LOG_TAG, "Invalid index : " + index + " received with event " + msg.what); if (phoneId < 0 || phoneId >= mCis.length) { Rlog.e(LOG_TAG, "Invalid phoneId : " + phoneId + " received with event " + msg.what); return; } AsyncResult ar = (AsyncResult)msg.obj; switch (msg.what) { case EVENT_ICC_STATUS_CHANGED: case EVENT_ICC_OR_SLOT_STATUS_CHANGED: if (DBG) log("Received EVENT_ICC_STATUS_CHANGED, calling getIccCardStatus"); mCis[index].getIccCardStatus(obtainMessage(EVENT_GET_ICC_STATUS_DONE, index)); mCis[phoneId].getIccCardStatus(obtainMessage(EVENT_GET_ICC_STATUS_DONE, phoneId)); break; case EVENT_GET_ICC_STATUS_DONE: if (DBG) log("Received EVENT_GET_ICC_STATUS_DONE"); onGetIccCardStatusDone(ar, index); onGetIccCardStatusDone(ar, phoneId); break; case EVENT_RADIO_UNAVAILABLE: if (DBG) log("EVENT_RADIO_UNAVAILABLE, dispose card"); if (mUiccCards[index] != null) { mUiccCards[index].dispose(); } mUiccCards[index] = null; mIccChangedRegistrants.notifyRegistrants(new AsyncResult(null, index, null)); mUiccSlots[getSlotIdFromPhoneId(phoneId)].onRadioStateUnavailable(); mIccChangedRegistrants.notifyRegistrants(new AsyncResult(null, phoneId, null)); break; case EVENT_SIM_REFRESH: if (DBG) log("Received EVENT_SIM_REFRESH"); onSimRefresh(ar, index); onSimRefresh(ar, phoneId); break; default: Rlog.e(LOG_TAG, " Unknown Event " + msg.what); Loading Loading @@ -269,11 +345,9 @@ public class UiccController extends Handler { // Easy to use API public UiccCardApplication getUiccCardApplication(int phoneId, int family) { synchronized (mLock) { if (isValidCardIndex(phoneId)) { UiccCard c = mUiccCards[phoneId]; if (c != null) { return mUiccCards[phoneId].getApplication(family); } UiccCard uiccCard = getUiccCardForPhone(phoneId); if (uiccCard != null) { return uiccCard.getApplication(family); } return null; } Loading @@ -293,13 +367,7 @@ public class UiccController extends Handler { IccCardStatus status = (IccCardStatus)ar.result; if (mUiccCards[index] == null) { //Create new card mUiccCards[index] = new UiccCard(mContext, mCis[index], status, index); } else { //Update already existing card mUiccCards[index].update(mContext, mCis[index] , status); } mUiccSlots[getSlotIdFromPhoneId(index)].update(mContext, mCis[index], status, index); if (DBG) log("Notifying IccChangedRegistrants"); mIccChangedRegistrants.notifyRegistrants(new AsyncResult(null, index, null)); Loading @@ -320,7 +388,8 @@ public class UiccController extends Handler { IccRefreshResponse resp = (IccRefreshResponse) ar.result; Rlog.d(LOG_TAG, "onSimRefresh: " + resp); if (mUiccCards[index] == null) { UiccCard uiccCard = getUiccCardForPhone(index); if (uiccCard == null) { Rlog.e(LOG_TAG,"onSimRefresh: refresh on null card : " + index); return; } Loading @@ -332,7 +401,7 @@ public class UiccController extends Handler { Rlog.d(LOG_TAG, "Handling refresh reset: " + resp); boolean changed = mUiccCards[index].resetAppWithAid(resp.aid); boolean changed = uiccCard.resetAppWithAid(resp.aid); if (changed) { boolean requirePowerOffOnSimRefreshReset = mContext.getResources().getBoolean( com.android.internal.R.bool.config_requireRadioPowerOffOnSimRefreshReset); Loading @@ -346,7 +415,11 @@ public class UiccController extends Handler { } private boolean isValidCardIndex(int index) { return (index >= 0 && index < mUiccCards.length); return (index >= 0 && index < TelephonyManager.getDefault().getPhoneCount()); } private boolean isValidSlotIndex(int index) { return (index >= 0 && index < mUiccSlots.length); } private void log(String string) { Loading Loading @@ -374,13 +447,13 @@ public class UiccController extends Handler { } pw.println(); pw.flush(); pw.println(" mUiccCards: size=" + mUiccCards.length); for (int i = 0; i < mUiccCards.length; i++) { if (mUiccCards[i] == null) { pw.println(" mUiccCards[" + i + "]=null"); pw.println(" mUiccSlots: size=" + mUiccSlots.length); for (int i = 0; i < mUiccSlots.length; i++) { if (mUiccSlots[i] == null) { pw.println(" mUiccSlots[" + i + "]=null"); } else { pw.println(" mUiccCards[" + i + "]=" + mUiccCards[i]); mUiccCards[i].dump(fd, pw, args); pw.println(" mUiccSlots[" + i + "]=" + mUiccSlots[i]); mUiccSlots[i].dump(fd, pw, args); } } pw.println("mCardLogs: "); Loading src/java/com/android/internal/telephony/uicc/UiccSlot.java +72 −21 File changed.Preview size limit exceeded, changes collapsed. Show changes src/java/com/android/internal/telephony/uicc/UiccStateChangedLauncher.java +5 −4 Original line number Diff line number Diff line Loading @@ -65,11 +65,12 @@ public class UiccStateChangedLauncher extends Handler { mIsRestricted = new boolean[TelephonyManager.getDefault().getPhoneCount()]; shouldNotify = true; } UiccCard[] cards = mUiccController.getUiccCards(); for (int i = 0; cards != null && i < cards.length; ++i) { UiccSlot[] uiccSlots = mUiccController.getUiccSlots(); for (int i = 0; uiccSlots != null && i < uiccSlots.length; ++i) { // Update only if restricted state changes. if ((cards[i] == null || cards[i].getCardState() != CardState.CARDSTATE_RESTRICTED) UiccCard uiccCard = uiccSlots[i].getUiccCard(); if ((uiccCard == null || uiccCard.getCardState() != CardState.CARDSTATE_RESTRICTED) != mIsRestricted[i]) { mIsRestricted[i] = !mIsRestricted[i]; shouldNotify = true; Loading Loading
src/java/com/android/internal/telephony/uicc/IccCardProxy.java +9 −4 Original line number Diff line number Diff line Loading @@ -97,6 +97,7 @@ public class IccCardProxy extends Handler implements IccCard { private int mCurrentAppType = UiccController.APP_FAM_3GPP; //default to 3gpp? private UiccController mUiccController = null; private UiccSlot mUiccSlot = null; private UiccCard mUiccCard = null; private UiccCardApplication mUiccApplication = null; private IccRecords mIccRecords = null; Loading Loading @@ -293,6 +294,7 @@ public class IccCardProxy extends Handler implements IccCard { private void updateIccAvailability() { synchronized (mLock) { UiccSlot newSlot = mUiccController.getUiccSlotForPhone(mPhoneId); UiccCard newCard = mUiccController.getUiccCard(mPhoneId); UiccCardApplication newApp = null; IccRecords newRecords = null; Loading @@ -303,9 +305,11 @@ public class IccCardProxy extends Handler implements IccCard { } } if (mIccRecords != newRecords || mUiccApplication != newApp || mUiccCard != newCard) { if (mIccRecords != newRecords || mUiccApplication != newApp || mUiccCard != newCard || mUiccSlot != newSlot) { if (DBG) log("Icc changed. Reregistering."); unregisterUiccCardEvents(); mUiccSlot = newSlot; mUiccCard = newCard; mUiccApplication = newApp; mIccRecords = newRecords; Loading Loading @@ -406,8 +410,9 @@ public class IccCardProxy extends Handler implements IccCard { } private void registerUiccCardEvents() { if (mUiccCard != null) { mUiccCard.registerForAbsent(this, EVENT_ICC_ABSENT, null); if (mUiccSlot != null) { // todo: reregistration is not needed unless slot mapping changes mUiccSlot.registerForAbsent(this, EVENT_ICC_ABSENT, null); } if (mUiccApplication != null) { mUiccApplication.registerForReady(this, EVENT_APP_READY, null); Loading @@ -422,7 +427,7 @@ public class IccCardProxy extends Handler implements IccCard { } private void unregisterUiccCardEvents() { if (mUiccCard != null) mUiccCard.unregisterForAbsent(this); if (mUiccSlot != null) mUiccSlot.unregisterForAbsent(this); if (mUiccCard != null) mUiccCard.unregisterForCarrierPrivilegeRulesLoaded(this); if (mUiccApplication != null) mUiccApplication.unregisterForReady(this); if (mUiccApplication != null) mUiccApplication.unregisterForLocked(this); Loading
src/java/com/android/internal/telephony/uicc/UiccCard.java +0 −133 Original line number Diff line number Diff line Loading @@ -18,8 +18,6 @@ package com.android.internal.telephony.uicc; import android.app.AlertDialog; import android.app.usage.UsageStatsManager; import android.content.ActivityNotFoundException; import android.content.ComponentName; import android.content.Context; import android.content.DialogInterface; import android.content.Intent; Loading @@ -34,7 +32,6 @@ import android.os.Binder; import android.os.Handler; import android.os.Message; import android.os.PersistableBundle; import android.os.PowerManager; import android.os.Registrant; import android.os.RegistrantList; import android.preference.PreferenceManager; Loading @@ -48,7 +45,6 @@ import android.view.WindowManager; import com.android.internal.R; import com.android.internal.telephony.CommandsInterface; import com.android.internal.telephony.CommandsInterface.RadioState; import com.android.internal.telephony.SubscriptionController; import com.android.internal.telephony.cat.CatService; import com.android.internal.telephony.uicc.IccCardApplicationStatus.AppType; Loading Loading @@ -84,14 +80,10 @@ public class UiccCard { private Context mContext; private CommandsInterface mCi; private CatService mCatService; private RadioState mLastRadioState = RadioState.RADIO_UNAVAILABLE; private UiccCarrierPrivilegeRules mCarrierPrivilegeRules; private RegistrantList mAbsentRegistrants = new RegistrantList(); private RegistrantList mCarrierPrivilegeRegistrants = new RegistrantList(); private static final int EVENT_CARD_REMOVED = 13; private static final int EVENT_CARD_ADDED = 14; private static final int EVENT_OPEN_LOGICAL_CHANNEL_DONE = 15; private static final int EVENT_CLOSE_LOGICAL_CHANNEL_DONE = 16; private static final int EVENT_TRANSMIT_APDU_LOGICAL_CHANNEL_DONE = 17; Loading Loading @@ -168,24 +160,6 @@ public class UiccCard { } sanitizeApplicationIndexesLocked(); RadioState radioState = mCi.getRadioState(); if (DBG) log("update: radioState=" + radioState + " mLastRadioState=" + mLastRadioState); // No notifications while radio is off or we just powering up if (radioState == RadioState.RADIO_ON && mLastRadioState == RadioState.RADIO_ON) { if (oldState != CardState.CARDSTATE_ABSENT && mCardState == CardState.CARDSTATE_ABSENT) { if (DBG) log("update: notify card removed"); mAbsentRegistrants.notifyRegistrants(); mHandler.sendMessage(mHandler.obtainMessage(EVENT_CARD_REMOVED, null)); } else if (oldState == CardState.CARDSTATE_ABSENT && mCardState != CardState.CARDSTATE_ABSENT) { if (DBG) log("update: notify card added"); mHandler.sendMessage(mHandler.obtainMessage(EVENT_CARD_ADDED, null)); } } mLastRadioState = radioState; } } Loading Loading @@ -248,27 +222,6 @@ public class UiccCard { return index; } /** * Notifies handler of any transition into State.ABSENT */ public void registerForAbsent(Handler h, int what, Object obj) { synchronized (mLock) { Registrant r = new Registrant (h, what, obj); mAbsentRegistrants.add(r); if (mCardState == CardState.CARDSTATE_ABSENT) { r.notifyRegistrant(); } } } public void unregisterForAbsent(Handler h) { synchronized (mLock) { mAbsentRegistrants.remove(h); } } /** * Notifies handler when carrier privilege rules are loaded. */ Loading @@ -290,90 +243,10 @@ public class UiccCard { } } private void onIccSwap(boolean isAdded) { boolean isHotSwapSupported = mContext.getResources().getBoolean( R.bool.config_hotswapCapable); if (isHotSwapSupported) { log("onIccSwap: isHotSwapSupported is true, don't prompt for rebooting"); return; } log("onIccSwap: isHotSwapSupported is false, prompt for rebooting"); promptForRestart(isAdded); } private void promptForRestart(boolean isAdded) { synchronized (mLock) { final Resources res = mContext.getResources(); final String dialogComponent = res.getString( R.string.config_iccHotswapPromptForRestartDialogComponent); if (dialogComponent != null) { Intent intent = new Intent().setComponent(ComponentName.unflattenFromString( dialogComponent)).addFlags(Intent.FLAG_ACTIVITY_NEW_TASK) .putExtra(EXTRA_ICC_CARD_ADDED, isAdded); try { mContext.startActivity(intent); return; } catch (ActivityNotFoundException e) { loge("Unable to find ICC hotswap prompt for restart activity: " + e); } } // TODO: Here we assume the device can't handle SIM hot-swap // and has to reboot. We may want to add a property, // e.g. REBOOT_ON_SIM_SWAP, to indicate if modem support // hot-swap. DialogInterface.OnClickListener listener = null; // TODO: SimRecords is not reset while SIM ABSENT (only reset while // Radio_off_or_not_available). Have to reset in both both // added or removed situation. listener = new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { synchronized (mLock) { if (which == DialogInterface.BUTTON_POSITIVE) { if (DBG) log("Reboot due to SIM swap"); PowerManager pm = (PowerManager) mContext .getSystemService(Context.POWER_SERVICE); pm.reboot("SIM is added."); } } } }; Resources r = Resources.getSystem(); String title = (isAdded) ? r.getString(R.string.sim_added_title) : r.getString(R.string.sim_removed_title); String message = (isAdded) ? r.getString(R.string.sim_added_message) : r.getString(R.string.sim_removed_message); String buttonTxt = r.getString(R.string.sim_restart_button); AlertDialog dialog = new AlertDialog.Builder(mContext) .setTitle(title) .setMessage(message) .setPositiveButton(buttonTxt, listener) .create(); dialog.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT); dialog.show(); } } protected Handler mHandler = new Handler() { @Override public void handleMessage(Message msg){ switch (msg.what) { case EVENT_CARD_REMOVED: onIccSwap(false); break; case EVENT_CARD_ADDED: onIccSwap(true); break; case EVENT_OPEN_LOGICAL_CHANNEL_DONE: case EVENT_CLOSE_LOGICAL_CHANNEL_DONE: case EVENT_TRANSMIT_APDU_LOGICAL_CHANNEL_DONE: Loading Loading @@ -792,13 +665,7 @@ public class UiccCard { public void dump(FileDescriptor fd, PrintWriter pw, String[] args) { pw.println("UiccCard:"); pw.println(" mCi=" + mCi); pw.println(" mLastRadioState=" + mLastRadioState); pw.println(" mCatService=" + mCatService); pw.println(" mAbsentRegistrants: size=" + mAbsentRegistrants.size()); for (int i = 0; i < mAbsentRegistrants.size(); i++) { pw.println(" mAbsentRegistrants[" + i + "]=" + ((Registrant)mAbsentRegistrants.get(i)).getHandler()); } for (int i = 0; i < mCarrierPrivilegeRegistrants.size(); i++) { pw.println(" mCarrierPrivilegeRegistrants[" + i + "]=" + ((Registrant)mCarrierPrivilegeRegistrants.get(i)).getHandler()); Loading
src/java/com/android/internal/telephony/uicc/UiccController.java +123 −50 Original line number Diff line number Diff line Loading @@ -22,15 +22,13 @@ import android.os.Handler; import android.os.Message; import android.os.Registrant; import android.os.RegistrantList; import android.os.SystemProperties; import android.os.storage.StorageManager; import android.telephony.TelephonyManager; import android.telephony.Rlog; import android.telephony.TelephonyManager; import android.text.format.Time; import com.android.internal.telephony.CommandsInterface; import com.android.internal.telephony.PhoneConstants; import com.android.internal.telephony.SubscriptionController; import java.io.FileDescriptor; import java.io.PrintWriter; Loading Loading @@ -85,12 +83,21 @@ public class UiccController extends Handler { public static final int APP_FAM_IMS = 3; private static final int EVENT_ICC_STATUS_CHANGED = 1; private static final int EVENT_GET_ICC_STATUS_DONE = 2; private static final int EVENT_RADIO_UNAVAILABLE = 3; private static final int EVENT_SIM_REFRESH = 4; private static final int EVENT_SLOT_STATUS_CHANGED = 2; private static final int EVENT_ICC_OR_SLOT_STATUS_CHANGED = 3; private static final int EVENT_GET_ICC_STATUS_DONE = 4; private static final int EVENT_RADIO_UNAVAILABLE = 5; private static final int EVENT_SIM_REFRESH = 6; // this still needs to be here, because on bootup we dont know which index maps to which // UiccSlot private CommandsInterface[] mCis; private UiccCard[] mUiccCards = new UiccCard[TelephonyManager.getDefault().getPhoneCount()]; // todo: add a system property/mk file constant for this private UiccSlot[] mUiccSlots = new UiccSlot[TelephonyManager.getDefault().getPhoneCount()]; // flag to indicate if UiccSlots have been initialized. This will be set to true only after the // first slots status is received. That is when phoneId to slotId mapping is known as well. // todo: assuming true for now and hardcoding the mapping between UiccSlot index and phoneId private boolean mUiccSlotsInitialized = true; private static final Object mLock = new Object(); private static UiccController mInstance; Loading Loading @@ -120,17 +127,23 @@ public class UiccController extends Handler { mContext = c; mCis = ci; for (int i = 0; i < mCis.length; i++) { Integer index = new Integer(i); // todo: get rid of this once hardcoding of mapping between UiccSlot index and phoneId // is removed, instead do this when icc/slot status is received mUiccSlots[i] = new UiccSlot(c, true /* isActive */); Integer index = i; mCis[i].registerForIccStatusChanged(this, EVENT_ICC_STATUS_CHANGED, index); // todo: add registration for slot status changed here // TODO remove this once modem correctly notifies the unsols // If the device is unencrypted or has been decrypted or FBE is supported, // i.e. not in cryptkeeper bounce, read SIM when radio state isavailable. // Else wait for radio to be on. This is needed for the scenario when SIM is locked -- // to avoid overlap of CryptKeeper and SIM unlock screen. if (!StorageManager.inCryptKeeperBounce()) { mCis[i].registerForAvailable(this, EVENT_ICC_STATUS_CHANGED, index); mCis[i].registerForAvailable(this, EVENT_ICC_OR_SLOT_STATUS_CHANGED, index); } else { mCis[i].registerForOn(this, EVENT_ICC_STATUS_CHANGED, index); mCis[i].registerForOn(this, EVENT_ICC_OR_SLOT_STATUS_CHANGED, index); } mCis[i].registerForNotAvailable(this, EVENT_RADIO_UNAVAILABLE, index); mCis[i].registerForIccRefresh(this, EVENT_SIM_REFRESH, index); Loading @@ -139,6 +152,13 @@ public class UiccController extends Handler { mLauncher = new UiccStateChangedLauncher(c, this); } private int getSlotIdFromPhoneId(int phoneId) { // todo: implement (if mUiccSlotsInitialized || if info available about that specific // phoneId which will be the case if sim status for that phoneId is received first) // else return invalid slotId return phoneId; } public static UiccController getInstance() { synchronized (mLock) { if (mInstance == null) { Loading @@ -151,18 +171,74 @@ public class UiccController extends Handler { public UiccCard getUiccCard(int phoneId) { synchronized (mLock) { if (isValidCardIndex(phoneId)) { return mUiccCards[phoneId]; return getUiccCardForPhone(phoneId); } } /** * API to get UiccCard corresponding to given physical slot index * @param slotId index of physical slot on the device * @return UiccCard object corresponting to given physical slot index; null if card is * absent */ public UiccCard getUiccCardForSlot(int slotId) { synchronized (mLock) { UiccSlot uiccSlot = getUiccSlot(slotId); if (uiccSlot != null) { return uiccSlot.getUiccCard(); } return null; } } public UiccCard[] getUiccCards() { /** * API to get UiccCard corresponding to given phone id * @return UiccCard object corresponding to given phone id; null if there is no card present for * the phone id */ public UiccCard getUiccCardForPhone(int phoneId) { synchronized (mLock) { int slotId = getSlotIdFromPhoneId(phoneId); return getUiccCardForSlot(slotId); } } /** * API to get an array of all UiccSlots, which represents all physical slots on the device * @return array of all UiccSlots */ public UiccSlot[] getUiccSlots() { // Return cloned array since we don't want to give out reference // to internal data structure. synchronized (mLock) { return mUiccCards.clone(); return mUiccSlots.clone(); } } /** * API to get UiccSlot object for a specific physical slot index on the device * @return UiccSlot object for the given physical slot index */ public UiccSlot getUiccSlot(int slotId) { synchronized (mLock) { if (isValidSlotIndex(slotId)) { return mUiccSlots[slotId]; } return null; } } /** * API to get UiccSlot object for a given phone id * @return UiccSlot object for the given phone id */ public UiccSlot getUiccSlotForPhone(int phoneId) { synchronized (mLock) { int slotId = getSlotIdFromPhoneId(phoneId); if (isValidSlotIndex(slotId)) { return mUiccSlots[slotId]; } return null; } } Loading Loading @@ -209,34 +285,34 @@ public class UiccController extends Handler { @Override public void handleMessage (Message msg) { synchronized (mLock) { Integer index = getCiIndex(msg); Integer phoneId = getCiIndex(msg); if (index < 0 || index >= mCis.length) { Rlog.e(LOG_TAG, "Invalid index : " + index + " received with event " + msg.what); if (phoneId < 0 || phoneId >= mCis.length) { Rlog.e(LOG_TAG, "Invalid phoneId : " + phoneId + " received with event " + msg.what); return; } AsyncResult ar = (AsyncResult)msg.obj; switch (msg.what) { case EVENT_ICC_STATUS_CHANGED: case EVENT_ICC_OR_SLOT_STATUS_CHANGED: if (DBG) log("Received EVENT_ICC_STATUS_CHANGED, calling getIccCardStatus"); mCis[index].getIccCardStatus(obtainMessage(EVENT_GET_ICC_STATUS_DONE, index)); mCis[phoneId].getIccCardStatus(obtainMessage(EVENT_GET_ICC_STATUS_DONE, phoneId)); break; case EVENT_GET_ICC_STATUS_DONE: if (DBG) log("Received EVENT_GET_ICC_STATUS_DONE"); onGetIccCardStatusDone(ar, index); onGetIccCardStatusDone(ar, phoneId); break; case EVENT_RADIO_UNAVAILABLE: if (DBG) log("EVENT_RADIO_UNAVAILABLE, dispose card"); if (mUiccCards[index] != null) { mUiccCards[index].dispose(); } mUiccCards[index] = null; mIccChangedRegistrants.notifyRegistrants(new AsyncResult(null, index, null)); mUiccSlots[getSlotIdFromPhoneId(phoneId)].onRadioStateUnavailable(); mIccChangedRegistrants.notifyRegistrants(new AsyncResult(null, phoneId, null)); break; case EVENT_SIM_REFRESH: if (DBG) log("Received EVENT_SIM_REFRESH"); onSimRefresh(ar, index); onSimRefresh(ar, phoneId); break; default: Rlog.e(LOG_TAG, " Unknown Event " + msg.what); Loading Loading @@ -269,11 +345,9 @@ public class UiccController extends Handler { // Easy to use API public UiccCardApplication getUiccCardApplication(int phoneId, int family) { synchronized (mLock) { if (isValidCardIndex(phoneId)) { UiccCard c = mUiccCards[phoneId]; if (c != null) { return mUiccCards[phoneId].getApplication(family); } UiccCard uiccCard = getUiccCardForPhone(phoneId); if (uiccCard != null) { return uiccCard.getApplication(family); } return null; } Loading @@ -293,13 +367,7 @@ public class UiccController extends Handler { IccCardStatus status = (IccCardStatus)ar.result; if (mUiccCards[index] == null) { //Create new card mUiccCards[index] = new UiccCard(mContext, mCis[index], status, index); } else { //Update already existing card mUiccCards[index].update(mContext, mCis[index] , status); } mUiccSlots[getSlotIdFromPhoneId(index)].update(mContext, mCis[index], status, index); if (DBG) log("Notifying IccChangedRegistrants"); mIccChangedRegistrants.notifyRegistrants(new AsyncResult(null, index, null)); Loading @@ -320,7 +388,8 @@ public class UiccController extends Handler { IccRefreshResponse resp = (IccRefreshResponse) ar.result; Rlog.d(LOG_TAG, "onSimRefresh: " + resp); if (mUiccCards[index] == null) { UiccCard uiccCard = getUiccCardForPhone(index); if (uiccCard == null) { Rlog.e(LOG_TAG,"onSimRefresh: refresh on null card : " + index); return; } Loading @@ -332,7 +401,7 @@ public class UiccController extends Handler { Rlog.d(LOG_TAG, "Handling refresh reset: " + resp); boolean changed = mUiccCards[index].resetAppWithAid(resp.aid); boolean changed = uiccCard.resetAppWithAid(resp.aid); if (changed) { boolean requirePowerOffOnSimRefreshReset = mContext.getResources().getBoolean( com.android.internal.R.bool.config_requireRadioPowerOffOnSimRefreshReset); Loading @@ -346,7 +415,11 @@ public class UiccController extends Handler { } private boolean isValidCardIndex(int index) { return (index >= 0 && index < mUiccCards.length); return (index >= 0 && index < TelephonyManager.getDefault().getPhoneCount()); } private boolean isValidSlotIndex(int index) { return (index >= 0 && index < mUiccSlots.length); } private void log(String string) { Loading Loading @@ -374,13 +447,13 @@ public class UiccController extends Handler { } pw.println(); pw.flush(); pw.println(" mUiccCards: size=" + mUiccCards.length); for (int i = 0; i < mUiccCards.length; i++) { if (mUiccCards[i] == null) { pw.println(" mUiccCards[" + i + "]=null"); pw.println(" mUiccSlots: size=" + mUiccSlots.length); for (int i = 0; i < mUiccSlots.length; i++) { if (mUiccSlots[i] == null) { pw.println(" mUiccSlots[" + i + "]=null"); } else { pw.println(" mUiccCards[" + i + "]=" + mUiccCards[i]); mUiccCards[i].dump(fd, pw, args); pw.println(" mUiccSlots[" + i + "]=" + mUiccSlots[i]); mUiccSlots[i].dump(fd, pw, args); } } pw.println("mCardLogs: "); Loading
src/java/com/android/internal/telephony/uicc/UiccSlot.java +72 −21 File changed.Preview size limit exceeded, changes collapsed. Show changes
src/java/com/android/internal/telephony/uicc/UiccStateChangedLauncher.java +5 −4 Original line number Diff line number Diff line Loading @@ -65,11 +65,12 @@ public class UiccStateChangedLauncher extends Handler { mIsRestricted = new boolean[TelephonyManager.getDefault().getPhoneCount()]; shouldNotify = true; } UiccCard[] cards = mUiccController.getUiccCards(); for (int i = 0; cards != null && i < cards.length; ++i) { UiccSlot[] uiccSlots = mUiccController.getUiccSlots(); for (int i = 0; uiccSlots != null && i < uiccSlots.length; ++i) { // Update only if restricted state changes. if ((cards[i] == null || cards[i].getCardState() != CardState.CARDSTATE_RESTRICTED) UiccCard uiccCard = uiccSlots[i].getUiccCard(); if ((uiccCard == null || uiccCard.getCardState() != CardState.CARDSTATE_RESTRICTED) != mIsRestricted[i]) { mIsRestricted[i] = !mIsRestricted[i]; shouldNotify = true; Loading