Loading src/java/com/android/internal/telephony/SubscriptionController.java +29 −0 Original line number Original line Diff line number Diff line Loading @@ -1078,6 +1078,35 @@ public class SubscriptionController extends ISub.Stub { return 0; return 0; } } /** * Clear an subscriptionInfo to subinfo database if needed by updating slot index to invalid. * @param slotIndex the slot which the SIM is removed */ public void clearSubInfoRecord(int slotIndex) { if (DBG) logdl("[clearSubInfoRecord]+ iccId:" + " slotIndex:" + slotIndex); // update simInfo db with invalid slot index List<SubscriptionInfo> oldSubInfo = getSubInfoUsingSlotIndexPrivileged(slotIndex, false); ContentResolver resolver = mContext.getContentResolver(); ContentValues value = new ContentValues(1); value.put(SubscriptionManager.SIM_SLOT_INDEX, SubscriptionManager.INVALID_SIM_SLOT_INDEX); if (oldSubInfo != null) { for (int i = 0; i < oldSubInfo.size(); i++) { resolver.update(SubscriptionManager.getUriForSubscriptionId( oldSubInfo.get(i).getSubscriptionId()), value, null, null); } } // Refresh the Cache of Active Subscription Info List refreshCachedActiveSubscriptionInfoList(); sSlotIndexToSubId.remove(slotIndex); // update default subId clearDefaultsForInactiveSubIds(); } /** /** * Insert an empty SubInfo record into the database. * Insert an empty SubInfo record into the database. * * Loading src/java/com/android/internal/telephony/SubscriptionInfoUpdater.java +53 −173 Original line number Original line Diff line number Diff line Loading @@ -85,28 +85,6 @@ public class SubscriptionInfoUpdater extends Handler { private static final int EVENT_REFRESH_EMBEDDED_SUBSCRIPTIONS = 12; private static final int EVENT_REFRESH_EMBEDDED_SUBSCRIPTIONS = 12; private static final String ICCID_STRING_FOR_NO_SIM = ""; private static final String ICCID_STRING_FOR_NO_SIM = ""; /** * int[] sInsertSimState maintains all slots' SIM inserted status currently, * it may contain 4 kinds of values: * SIM_NOT_INSERT : no SIM inserted in slot i now * SIM_CHANGED : a valid SIM insert in slot i and is different SIM from last time * it will later become SIM_NEW or SIM_REPOSITION during update procedure * SIM_NOT_CHANGE : a valid SIM insert in slot i and is the same SIM as last time * SIM_NEW : a valid SIM insert in slot i and is a new SIM * SIM_REPOSITION : a valid SIM insert in slot i and is inserted in different slot last time * positive integer #: index to distinguish SIM cards with the same IccId */ public static final int SIM_NOT_CHANGE = 0; public static final int SIM_CHANGED = -1; public static final int SIM_NEW = -2; public static final int SIM_REPOSITION = -3; public static final int SIM_NOT_INSERT = -99; public static final int STATUS_NO_SIM_INSERTED = 0x00; public static final int STATUS_SIM1_INSERTED = 0x01; public static final int STATUS_SIM2_INSERTED = 0x02; public static final int STATUS_SIM3_INSERTED = 0x04; public static final int STATUS_SIM4_INSERTED = 0x08; // Key used to read/write the current IMSI. Updated on SIM_STATE_CHANGED - LOADED. // Key used to read/write the current IMSI. Updated on SIM_STATE_CHANGED - LOADED. public static final String CURR_SUBID = "curr_subid"; public static final String CURR_SUBID = "curr_subid"; Loading @@ -114,7 +92,6 @@ public class SubscriptionInfoUpdater extends Handler { private static Phone[] mPhone; private static Phone[] mPhone; private static Context mContext = null; private static Context mContext = null; private static String mIccId[] = new String[PROJECT_SIM_NUM]; private static String mIccId[] = new String[PROJECT_SIM_NUM]; private static int[] mInsertSimState = new int[PROJECT_SIM_NUM]; private static int[] sSimCardState = new int[PROJECT_SIM_NUM]; private static int[] sSimCardState = new int[PROJECT_SIM_NUM]; private static int[] sSimApplicationState = new int[PROJECT_SIM_NUM]; private static int[] sSimApplicationState = new int[PROJECT_SIM_NUM]; private SubscriptionManager mSubscriptionManager = null; private SubscriptionManager mSubscriptionManager = null; Loading Loading @@ -330,9 +307,7 @@ public class SubscriptionInfoUpdater extends Handler { logd("NOT Querying IccId its already set sIccid[" + slotId + "]=" + iccId); logd("NOT Querying IccId its already set sIccid[" + slotId + "]=" + iccId); } } if (isAllIccIdQueryDone()) { updateSubscriptionInfoByIccId(slotId); updateSubscriptionInfoByIccId(); } broadcastSimStateChanged(slotId, IccCardConstants.INTENT_VALUE_ICC_LOCKED, reason); broadcastSimStateChanged(slotId, IccCardConstants.INTENT_VALUE_ICC_LOCKED, reason); broadcastSimCardStateChanged(slotId, TelephonyManager.SIM_STATE_PRESENT); broadcastSimCardStateChanged(slotId, TelephonyManager.SIM_STATE_PRESENT); Loading Loading @@ -366,9 +341,7 @@ public class SubscriptionInfoUpdater extends Handler { // phase, the subscription list is accessible. Treating NOT_READY // phase, the subscription list is accessible. Treating NOT_READY // as equivalent to ABSENT, once the rest of the system can handle it. // as equivalent to ABSENT, once the rest of the system can handle it. mIccId[slotId] = ICCID_STRING_FOR_NO_SIM; mIccId[slotId] = ICCID_STRING_FOR_NO_SIM; if (isAllIccIdQueryDone()) { updateSubscriptionInfoByIccId(slotId); updateSubscriptionInfoByIccId(); } } } broadcastSimStateChanged(slotId, IccCardConstants.INTENT_VALUE_ICC_NOT_READY, broadcastSimStateChanged(slotId, IccCardConstants.INTENT_VALUE_ICC_NOT_READY, Loading Loading @@ -400,14 +373,16 @@ public class SubscriptionInfoUpdater extends Handler { } } mIccId[slotId] = IccUtils.stripTrailingFs(records.getFullIccId()); mIccId[slotId] = IccUtils.stripTrailingFs(records.getFullIccId()); if (isAllIccIdQueryDone()) { updateSubscriptionInfoByIccId(slotId); updateSubscriptionInfoByIccId(); List<SubscriptionInfo> subscriptionInfos = SubscriptionController.getInstance() int[] subIds = mSubscriptionManager.getActiveSubscriptionIdList(); .getSubInfoUsingSlotIndexPrivileged(slotId, false); for (int subId : subIds) { if (subscriptionInfos == null || subscriptionInfos.isEmpty()) { loge("empty subinfo for slotId: " + slotId + "could not update ContentResolver"); } else { for (SubscriptionInfo sub : subscriptionInfos) { int subId = sub.getSubscriptionId(); TelephonyManager tm = TelephonyManager.getDefault(); TelephonyManager tm = TelephonyManager.getDefault(); String operator = tm.getSimOperatorNumeric(subId); String operator = tm.getSimOperatorNumeric(subId); slotId = SubscriptionController.getInstance().getPhoneId(subId); if (!TextUtils.isEmpty(operator)) { if (!TextUtils.isEmpty(operator)) { if (subId == SubscriptionController.getInstance().getDefaultSubId()) { if (subId == SubscriptionController.getInstance().getDefaultSubId()) { Loading @@ -427,8 +402,6 @@ public class SubscriptionInfoUpdater extends Handler { } } String msisdn = tm.getLine1Number(subId); String msisdn = tm.getLine1Number(subId); ContentResolver contentResolver = mContext.getContentResolver(); if (msisdn != null) { if (msisdn != null) { SubscriptionController.getInstance().setDisplayNumber(msisdn, subId); SubscriptionController.getInstance().setDisplayNumber(msisdn, subId); } } Loading @@ -449,7 +422,8 @@ public class SubscriptionInfoUpdater extends Handler { } } /* Update preferred network type and network selection mode on SIM change. /* Update preferred network type and network selection mode on SIM change. * Storing last subId in SharedPreference for now to detect SIM change. */ * Storing last subId in SharedPreference for now to detect SIM change. */ SharedPreferences sp = SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(mContext); PreferenceManager.getDefaultSharedPreferences(mContext); int storedSubId = sp.getInt(CURR_SUBID + slotId, -1); int storedSubId = sp.getInt(CURR_SUBID + slotId, -1); Loading Loading @@ -530,9 +504,7 @@ public class SubscriptionInfoUpdater extends Handler { logd("SIM" + (slotId + 1) + " hot plug out"); logd("SIM" + (slotId + 1) + " hot plug out"); } } mIccId[slotId] = ICCID_STRING_FOR_NO_SIM; mIccId[slotId] = ICCID_STRING_FOR_NO_SIM; if (isAllIccIdQueryDone()) { updateSubscriptionInfoByIccId(slotId); updateSubscriptionInfoByIccId(); } broadcastSimStateChanged(slotId, IccCardConstants.INTENT_VALUE_ICC_ABSENT, null); broadcastSimStateChanged(slotId, IccCardConstants.INTENT_VALUE_ICC_ABSENT, null); broadcastSimCardStateChanged(slotId, TelephonyManager.SIM_STATE_ABSENT); broadcastSimCardStateChanged(slotId, TelephonyManager.SIM_STATE_ABSENT); broadcastSimApplicationStateChanged(slotId, TelephonyManager.SIM_STATE_NOT_READY); broadcastSimApplicationStateChanged(slotId, TelephonyManager.SIM_STATE_NOT_READY); Loading @@ -545,9 +517,7 @@ public class SubscriptionInfoUpdater extends Handler { logd("SIM" + (slotId + 1) + " Error "); logd("SIM" + (slotId + 1) + " Error "); } } mIccId[slotId] = ICCID_STRING_FOR_NO_SIM; mIccId[slotId] = ICCID_STRING_FOR_NO_SIM; if (isAllIccIdQueryDone()) { updateSubscriptionInfoByIccId(slotId); updateSubscriptionInfoByIccId(); } broadcastSimStateChanged(slotId, IccCardConstants.INTENT_VALUE_ICC_CARD_IO_ERROR, broadcastSimStateChanged(slotId, IccCardConstants.INTENT_VALUE_ICC_CARD_IO_ERROR, IccCardConstants.INTENT_VALUE_ICC_CARD_IO_ERROR); IccCardConstants.INTENT_VALUE_ICC_CARD_IO_ERROR); broadcastSimCardStateChanged(slotId, TelephonyManager.SIM_STATE_CARD_IO_ERROR); broadcastSimCardStateChanged(slotId, TelephonyManager.SIM_STATE_CARD_IO_ERROR); Loading @@ -556,145 +526,51 @@ public class SubscriptionInfoUpdater extends Handler { updateCarrierServices(slotId, IccCardConstants.INTENT_VALUE_ICC_CARD_IO_ERROR); updateCarrierServices(slotId, IccCardConstants.INTENT_VALUE_ICC_CARD_IO_ERROR); } } /** synchronized private void updateSubscriptionInfoByIccId(int slotIndex) { * TODO: Simplify more, as no one is interested in what happened * only what the current list contains. */ synchronized private void updateSubscriptionInfoByIccId() { logd("updateSubscriptionInfoByIccId:+ Start"); logd("updateSubscriptionInfoByIccId:+ Start"); if (!SubscriptionManager.isValidSlotIndex(slotIndex)) { for (int i = 0; i < PROJECT_SIM_NUM; i++) { loge("[updateSubscriptionInfoByIccId]- invalid slotIndex=" + slotIndex); mInsertSimState[i] = SIM_NOT_CHANGE; return; } int insertedSimCount = PROJECT_SIM_NUM; for (int i = 0; i < PROJECT_SIM_NUM; i++) { if (ICCID_STRING_FOR_NO_SIM.equals(mIccId[i])) { insertedSimCount--; mInsertSimState[i] = SIM_NOT_INSERT; } } logd("insertedSimCount = " + insertedSimCount); // We only clear the slot-to-sub map when one/some SIM was removed. Note this is a // workaround for some race conditions that the empty map was accessed while we are // rebuilding the map. if (SubscriptionController.getInstance().getActiveSubIdList().length > insertedSimCount) { SubscriptionController.getInstance().clearSubInfo(); } int index = 0; for (int i = 0; i < PROJECT_SIM_NUM; i++) { if (mInsertSimState[i] == SIM_NOT_INSERT) { continue; } index = 2; for (int j = i + 1; j < PROJECT_SIM_NUM; j++) { if (mInsertSimState[j] == SIM_NOT_CHANGE && mIccId[i].equals(mIccId[j])) { mInsertSimState[i] = 1; mInsertSimState[j] = index; index++; } } } ContentResolver contentResolver = mContext.getContentResolver(); String[] oldIccId = new String[PROJECT_SIM_NUM]; String[] decIccId = new String[PROJECT_SIM_NUM]; for (int i = 0; i < PROJECT_SIM_NUM; i++) { oldIccId[i] = null; List<SubscriptionInfo> oldSubInfo = SubscriptionController.getInstance() .getSubInfoUsingSlotIndexPrivileged(i, false); decIccId[i] = IccUtils.getDecimalSubstring(mIccId[i]); if (oldSubInfo != null && oldSubInfo.size() > 0) { oldIccId[i] = oldSubInfo.get(0).getIccId(); logd("updateSubscriptionInfoByIccId: oldSubId = " + oldSubInfo.get(0).getSubscriptionId()); if (mInsertSimState[i] == SIM_NOT_CHANGE && !(mIccId[i].equals(oldIccId[i]) || (decIccId[i] != null && decIccId[i].equals(oldIccId[i])))) { mInsertSimState[i] = SIM_CHANGED; } if (mInsertSimState[i] != SIM_NOT_CHANGE) { ContentValues value = new ContentValues(1); value.put(SubscriptionManager.SIM_SLOT_INDEX, SubscriptionManager.INVALID_SIM_SLOT_INDEX); contentResolver.update(SubscriptionManager.getUriForSubscriptionId( oldSubInfo.get(0).getSubscriptionId()), value, null, null); // refresh Cached Active Subscription Info List SubscriptionController.getInstance().refreshCachedActiveSubscriptionInfoList(); } } else { if (mInsertSimState[i] == SIM_NOT_CHANGE) { // no SIM inserted last time, but there is one SIM inserted now mInsertSimState[i] = SIM_CHANGED; } oldIccId[i] = ICCID_STRING_FOR_NO_SIM; logd("updateSubscriptionInfoByIccId: No SIM in slot " + i + " last time"); } } for (int i = 0; i < PROJECT_SIM_NUM; i++) { logd("updateSubscriptionInfoByIccId: oldIccId[" + i + "] = " + oldIccId[i] + ", sIccId[" + i + "] = " + mIccId[i]); } } logd("updateSubscriptionInfoByIccId: removing subscription info record: slotIndex " + slotIndex); // Clear slotIndex only when sim absent is not enough. It's possible to switch SIM profile // within the same slot. Need to clear the slot index of the previous sub. Thus always clear // for the changing slot first. SubscriptionController.getInstance().clearSubInfoRecord(slotIndex); //check if the inserted SIM is new SIM // If SIM is not absent, insert new record or update existing record. for (int i = 0; i < PROJECT_SIM_NUM; i++) { if (!ICCID_STRING_FOR_NO_SIM.equals(mIccId[slotIndex])) { if (mInsertSimState[i] == SIM_NOT_INSERT) { logd("updateSubscriptionInfoByIccId: No SIM inserted in slot " + i + " this time"); } else { if (mInsertSimState[i] > 0) { //some special SIMs may have the same IccIds, add suffix to distinguish them //FIXME: addSubInfoRecord can return an error. mSubscriptionManager.addSubscriptionInfoRecord(mIccId[i] + Integer.toString(mInsertSimState[i]), i); logd("SUB" + (i + 1) + " has invalid IccId"); } else /*if (sInsertSimState[i] != SIM_NOT_INSERT)*/ { logd("updateSubscriptionInfoByIccId: adding subscription info record: iccid: " logd("updateSubscriptionInfoByIccId: adding subscription info record: iccid: " + mIccId[i] + "slot: " + i); + mIccId[slotIndex] + "slot: " + slotIndex); mSubscriptionManager.addSubscriptionInfoRecord(mIccId[i], i); mSubscriptionManager.addSubscriptionInfoRecord(mIccId[slotIndex], slotIndex); } if (isNewSim(mIccId[i], decIccId[i], oldIccId)) { mInsertSimState[i] = SIM_NEW; } } } for (int i = 0; i < PROJECT_SIM_NUM; i++) { if (mInsertSimState[i] == SIM_CHANGED) { mInsertSimState[i] = SIM_REPOSITION; } logd("updateSubscriptionInfoByIccId: sInsertSimState[" + i + "] = " + mInsertSimState[i]); } } List<SubscriptionInfo> subInfos = mSubscriptionManager.getActiveSubscriptionInfoList(); List<SubscriptionInfo> subInfos = SubscriptionController.getInstance() int nSubCount = (subInfos == null) ? 0 : subInfos.size(); .getSubInfoUsingSlotIndexPrivileged(slotIndex, false); logd("updateSubscriptionInfoByIccId: nSubCount = " + nSubCount); if (subInfos != null) { for (int i=0; i < nSubCount; i++) { for (int i = 0; i < subInfos.size(); i++) { SubscriptionInfo temp = subInfos.get(i); SubscriptionInfo temp = subInfos.get(i); ContentValues value = new ContentValues(1); String msisdn = TelephonyManager.getDefault().getLine1Number( String msisdn = TelephonyManager.getDefault().getLine1Number( temp.getSubscriptionId()); temp.getSubscriptionId()); if (msisdn != null) { if (msisdn != null) { ContentValues value = new ContentValues(1); value.put(SubscriptionManager.NUMBER, msisdn); value.put(SubscriptionManager.NUMBER, msisdn); contentResolver.update(SubscriptionManager.getUriForSubscriptionId( mContext.getContentResolver().update(SubscriptionManager.getUriForSubscriptionId( temp.getSubscriptionId()), value, null, null); temp.getSubscriptionId()), value, null, null); // refresh Cached Active Subscription Info List // refresh Cached Active Subscription Info List SubscriptionController.getInstance().refreshCachedActiveSubscriptionInfoList(); SubscriptionController.getInstance().refreshCachedActiveSubscriptionInfoList(); } } } } } // TODO investigate if we can update for each slot separately. if (isAllIccIdQueryDone()) { // Ensure the modems are mapped correctly // Ensure the modems are mapped correctly mSubscriptionManager.setDefaultDataSubId( mSubscriptionManager.setDefaultDataSubId( mSubscriptionManager.getDefaultDataSubscriptionId()); mSubscriptionManager.getDefaultDataSubscriptionId()); // No need to check return value here as we notify for the above changes anyway. if (subInfos != null) { UiccController uiccController = UiccController.getInstance(); UiccController uiccController = UiccController.getInstance(); UiccSlot[] uiccSlots = uiccController.getUiccSlots(); UiccSlot[] uiccSlots = uiccController.getUiccSlots(); if (uiccSlots != null) { if (uiccSlots != null) { Loading Loading @@ -951,6 +827,10 @@ public class SubscriptionInfoUpdater extends Handler { Rlog.d(LOG_TAG, message); Rlog.d(LOG_TAG, message); } } private void loge(String message) { Rlog.e(LOG_TAG, message); } public void dump(FileDescriptor fd, PrintWriter pw, String[] args) { public void dump(FileDescriptor fd, PrintWriter pw, String[] args) { pw.println("SubscriptionInfoUpdater:"); pw.println("SubscriptionInfoUpdater:"); mCarrierServiceBindHelper.dump(fd, pw, args); mCarrierServiceBindHelper.dump(fd, pw, args); Loading tests/telephonytests/src/com/android/internal/telephony/SubscriptionInfoUpdaterTest.java +19 −25 Original line number Original line Diff line number Diff line Loading @@ -122,7 +122,6 @@ public class SubscriptionInfoUpdaterTest extends TelephonyTest { super.setUp(this.getClass().getSimpleName()); super.setUp(this.getClass().getSimpleName()); replaceInstance(SubscriptionInfoUpdater.class, "mIccId", null, new String[1]); replaceInstance(SubscriptionInfoUpdater.class, "mIccId", null, new String[1]); replaceInstance(SubscriptionInfoUpdater.class, "mInsertSimState", null, new int[1]); replaceInstance(SubscriptionInfoUpdater.class, "mContext", null, null); replaceInstance(SubscriptionInfoUpdater.class, "mContext", null, null); replaceInstance(SubscriptionInfoUpdater.class, "PROJECT_SIM_NUM", null, 1); replaceInstance(SubscriptionInfoUpdater.class, "PROJECT_SIM_NUM", null, 1); replaceInstance(SubscriptionInfoUpdater.class, "sSimCardState", null, new int[1]); replaceInstance(SubscriptionInfoUpdater.class, "sSimCardState", null, new int[1]); Loading Loading @@ -176,14 +175,12 @@ public class SubscriptionInfoUpdaterTest extends TelephonyTest { IccCardConstants.INTENT_VALUE_ICC_ABSENT, null, FAKE_SUB_ID_1); IccCardConstants.INTENT_VALUE_ICC_ABSENT, null, FAKE_SUB_ID_1); waitForMs(100); waitForMs(100); verify(mSubscriptionContent).put(eq(SubscriptionManager.SIM_SLOT_INDEX), verify(mSubscriptionController, times(1)).clearSubInfoRecord(eq(FAKE_SUB_ID_1)); eq(SubscriptionManager.INVALID_SIM_SLOT_INDEX)); CarrierConfigManager mConfigManager = (CarrierConfigManager) CarrierConfigManager mConfigManager = (CarrierConfigManager) mContext.getSystemService(Context.CARRIER_CONFIG_SERVICE); mContext.getSystemService(Context.CARRIER_CONFIG_SERVICE); verify(mConfigManager).updateConfigForPhoneId(eq(FAKE_SUB_ID_1), verify(mConfigManager).updateConfigForPhoneId(eq(FAKE_SUB_ID_1), eq(IccCardConstants.INTENT_VALUE_ICC_ABSENT)); eq(IccCardConstants.INTENT_VALUE_ICC_ABSENT)); verify(mSubscriptionController, times(1)).clearSubInfo(); verify(mSubscriptionController, times(1)).notifySubscriptionInfoChanged(); verify(mSubscriptionController, times(1)).notifySubscriptionInfoChanged(); } } Loading Loading @@ -238,8 +235,8 @@ public class SubscriptionInfoUpdaterTest extends TelephonyTest { @Test @Test @SmallTest @SmallTest public void testSimLoaded() throws Exception { public void testSimLoaded() throws Exception { /* mock new sim got loaded and there is no sim loaded before */ doReturn(FAKE_SUB_ID_1).when(mSubInfo).getSubscriptionId(); doReturn(null).when(mSubscriptionController) doReturn(Arrays.asList(mSubInfo)).when(mSubscriptionController) .getSubInfoUsingSlotIndexPrivileged(eq(FAKE_SUB_ID_1), anyBoolean()); .getSubInfoUsingSlotIndexPrivileged(eq(FAKE_SUB_ID_1), anyBoolean()); doReturn("89012604200000000000").when(mIccRecord).getFullIccId(); doReturn("89012604200000000000").when(mIccRecord).getFullIccId(); doReturn(FAKE_MCC_MNC_1).when(mTelephonyManager).getSimOperatorNumeric(FAKE_SUB_ID_1); doReturn(FAKE_MCC_MNC_1).when(mTelephonyManager).getSimOperatorNumeric(FAKE_SUB_ID_1); Loading Loading @@ -303,12 +300,12 @@ public class SubscriptionInfoUpdaterTest extends TelephonyTest { @Test @Test @SmallTest @SmallTest public void testSimLoadedEmptyOperatorNumeric() throws Exception { public void testSimLoadedEmptyOperatorNumeric() throws Exception { /* mock new sim got loaded and there is no sim loaded before */ doReturn(null).when(mSubscriptionController) .getSubInfoUsingSlotIndexPrivileged(eq(FAKE_SUB_ID_1), anyBoolean()); doReturn("89012604200000000000").when(mIccRecord).getFullIccId(); doReturn("89012604200000000000").when(mIccRecord).getFullIccId(); // operator numeric is empty // operator numeric is empty doReturn("").when(mTelephonyManager).getSimOperatorNumeric(FAKE_SUB_ID_1); doReturn("").when(mTelephonyManager).getSimOperatorNumeric(FAKE_SUB_ID_1); doReturn(FAKE_SUB_ID_1).when(mSubInfo).getSubscriptionId(); doReturn(Arrays.asList(mSubInfo)).when(mSubscriptionController) .getSubInfoUsingSlotIndexPrivileged(eq(FAKE_SUB_ID_1), anyBoolean()); mUpdater.updateInternalIccState( mUpdater.updateInternalIccState( IccCardConstants.INTENT_VALUE_ICC_LOADED, null, FAKE_SUB_ID_1); IccCardConstants.INTENT_VALUE_ICC_LOADED, null, FAKE_SUB_ID_1); Loading Loading @@ -340,9 +337,6 @@ public class SubscriptionInfoUpdaterTest extends TelephonyTest { waitForMs(100); waitForMs(100); /* old IccId != new queried IccId */ verify(mSubscriptionContent).put(eq(SubscriptionManager.SIM_SLOT_INDEX), eq(SubscriptionManager.INVALID_SIM_SLOT_INDEX)); SubscriptionManager mSubscriptionManager = SubscriptionManager.from(mContext); SubscriptionManager mSubscriptionManager = SubscriptionManager.from(mContext); verify(mSubscriptionManager, times(1)).addSubscriptionInfoRecord( verify(mSubscriptionManager, times(1)).addSubscriptionInfoRecord( eq("98106240020000000000"), eq(FAKE_SUB_ID_1)); eq("98106240020000000000"), eq(FAKE_SUB_ID_1)); Loading @@ -359,15 +353,11 @@ public class SubscriptionInfoUpdaterTest extends TelephonyTest { @SmallTest @SmallTest public void testDualSimLoaded() throws Exception { public void testDualSimLoaded() throws Exception { // Mock there is two sim cards // Mock there is two sim cards replaceInstance(SubscriptionInfoUpdater.class, "mIccId", null, replaceInstance(SubscriptionInfoUpdater.class, "mIccId", null, new String[]{null, null}); new String[]{null, null}); replaceInstance(SubscriptionInfoUpdater.class, "PROJECT_SIM_NUM", null, 2); replaceInstance(SubscriptionInfoUpdater.class, "PROJECT_SIM_NUM", null, 2); replaceInstance(SubscriptionInfoUpdater.class, "mPhone", null, replaceInstance(SubscriptionInfoUpdater.class, "mPhone", null, new Phone[]{mPhone, mPhone}); new Phone[]{mPhone, mPhone}); replaceInstance(SubscriptionInfoUpdater.class, "mInsertSimState", null, new int[]{SubscriptionInfoUpdater.SIM_NOT_CHANGE, SubscriptionInfoUpdater.SIM_NOT_CHANGE}); replaceInstance(SubscriptionInfoUpdater.class, "sSimCardState", null, replaceInstance(SubscriptionInfoUpdater.class, "sSimCardState", null, new int[]{0, 0}); new int[]{0, 0}); replaceInstance(SubscriptionInfoUpdater.class, "sSimApplicationState", null, replaceInstance(SubscriptionInfoUpdater.class, "sSimApplicationState", null, Loading @@ -380,24 +370,29 @@ public class SubscriptionInfoUpdaterTest extends TelephonyTest { doReturn(2).when(mTelephonyManager).getSimCount(); doReturn(2).when(mTelephonyManager).getSimCount(); doReturn(FAKE_MCC_MNC_1).when(mTelephonyManager).getSimOperatorNumeric(eq(FAKE_SUB_ID_1)); doReturn(FAKE_MCC_MNC_1).when(mTelephonyManager).getSimOperatorNumeric(eq(FAKE_SUB_ID_1)); doReturn(FAKE_MCC_MNC_2).when(mTelephonyManager).getSimOperatorNumeric(eq(FAKE_SUB_ID_2)); doReturn(FAKE_MCC_MNC_2).when(mTelephonyManager).getSimOperatorNumeric(eq(FAKE_SUB_ID_2)); // Mock there is no sim inserted before doReturn(null).when(mSubscriptionController) .getSubInfoUsingSlotIndexPrivileged(anyInt(), anyBoolean()); verify(mSubscriptionController, times(0)).clearSubInfo(); verify(mSubscriptionController, times(0)).clearSubInfo(); doReturn("89012604200000000000").when(mIccRecord).getFullIccId(); doReturn("89012604200000000000").when(mIccRecord).getFullIccId(); SubscriptionManager mSubscriptionManager = SubscriptionManager.from(mContext); verify(mSubscriptionManager, times(0)).addSubscriptionInfoRecord(anyString(), anyInt()); verify(mSubscriptionController, times(0)).notifySubscriptionInfoChanged(); verify(mSubscriptionController, times(0)).setMccMnc(anyString(), anyInt()); // Mock sending a sim loaded for SIM 1 // Mock sending a sim loaded for SIM 1 doReturn(Arrays.asList(mSubInfo)).when(mSubscriptionController) .getSubInfoUsingSlotIndexPrivileged(eq(FAKE_SUB_ID_1), anyBoolean()); mUpdater.updateInternalIccState( mUpdater.updateInternalIccState( IccCardConstants.INTENT_VALUE_ICC_LOADED, null, FAKE_SUB_ID_1); IccCardConstants.INTENT_VALUE_ICC_LOADED, null, FAKE_SUB_ID_1); waitForMs(100); waitForMs(100); SubscriptionManager mSubscriptionManager = SubscriptionManager.from(mContext); verify(mSubscriptionManager, times(1)).addSubscriptionInfoRecord(anyString(), anyInt()); verify(mSubscriptionManager, times(0)).addSubscriptionInfoRecord(anyString(), anyInt()); verify(mSubscriptionController, times(1)).notifySubscriptionInfoChanged(); verify(mSubscriptionController, times(0)).notifySubscriptionInfoChanged(); verify(mSubscriptionController, times(1)).setMccMnc(anyString(), anyInt()); verify(mSubscriptionController, times(0)).setMccMnc(anyString(), anyInt()); // Mock sending a sim loaded for SIM 2 // Mock sending a sim loaded for SIM 2 doReturn(Arrays.asList(mSubInfo)).when(mSubscriptionController) .getSubInfoUsingSlotIndexPrivileged(eq(FAKE_SUB_ID_2), anyBoolean()); doReturn(FAKE_SUB_ID_2).when(mSubInfo).getSubscriptionId(); doReturn("89012604200000000001").when(mIccRecord).getFullIccId(); doReturn("89012604200000000001").when(mIccRecord).getFullIccId(); mUpdater.updateInternalIccState( mUpdater.updateInternalIccState( Loading @@ -411,8 +406,7 @@ public class SubscriptionInfoUpdaterTest extends TelephonyTest { eq(FAKE_SUB_ID_2)); eq(FAKE_SUB_ID_2)); verify(mSubscriptionController, times(1)).setMccMnc(eq(FAKE_MCC_MNC_1), eq(FAKE_SUB_ID_1)); verify(mSubscriptionController, times(1)).setMccMnc(eq(FAKE_MCC_MNC_1), eq(FAKE_SUB_ID_1)); verify(mSubscriptionController, times(1)).setMccMnc(eq(FAKE_MCC_MNC_2), eq(FAKE_SUB_ID_2)); verify(mSubscriptionController, times(1)).setMccMnc(eq(FAKE_MCC_MNC_2), eq(FAKE_SUB_ID_2)); verify(mSubscriptionController, times(0)).clearSubInfo(); verify(mSubscriptionController, times(2)).notifySubscriptionInfoChanged(); verify(mSubscriptionController, times(1)).notifySubscriptionInfoChanged(); } } @Test @Test Loading Loading
src/java/com/android/internal/telephony/SubscriptionController.java +29 −0 Original line number Original line Diff line number Diff line Loading @@ -1078,6 +1078,35 @@ public class SubscriptionController extends ISub.Stub { return 0; return 0; } } /** * Clear an subscriptionInfo to subinfo database if needed by updating slot index to invalid. * @param slotIndex the slot which the SIM is removed */ public void clearSubInfoRecord(int slotIndex) { if (DBG) logdl("[clearSubInfoRecord]+ iccId:" + " slotIndex:" + slotIndex); // update simInfo db with invalid slot index List<SubscriptionInfo> oldSubInfo = getSubInfoUsingSlotIndexPrivileged(slotIndex, false); ContentResolver resolver = mContext.getContentResolver(); ContentValues value = new ContentValues(1); value.put(SubscriptionManager.SIM_SLOT_INDEX, SubscriptionManager.INVALID_SIM_SLOT_INDEX); if (oldSubInfo != null) { for (int i = 0; i < oldSubInfo.size(); i++) { resolver.update(SubscriptionManager.getUriForSubscriptionId( oldSubInfo.get(i).getSubscriptionId()), value, null, null); } } // Refresh the Cache of Active Subscription Info List refreshCachedActiveSubscriptionInfoList(); sSlotIndexToSubId.remove(slotIndex); // update default subId clearDefaultsForInactiveSubIds(); } /** /** * Insert an empty SubInfo record into the database. * Insert an empty SubInfo record into the database. * * Loading
src/java/com/android/internal/telephony/SubscriptionInfoUpdater.java +53 −173 Original line number Original line Diff line number Diff line Loading @@ -85,28 +85,6 @@ public class SubscriptionInfoUpdater extends Handler { private static final int EVENT_REFRESH_EMBEDDED_SUBSCRIPTIONS = 12; private static final int EVENT_REFRESH_EMBEDDED_SUBSCRIPTIONS = 12; private static final String ICCID_STRING_FOR_NO_SIM = ""; private static final String ICCID_STRING_FOR_NO_SIM = ""; /** * int[] sInsertSimState maintains all slots' SIM inserted status currently, * it may contain 4 kinds of values: * SIM_NOT_INSERT : no SIM inserted in slot i now * SIM_CHANGED : a valid SIM insert in slot i and is different SIM from last time * it will later become SIM_NEW or SIM_REPOSITION during update procedure * SIM_NOT_CHANGE : a valid SIM insert in slot i and is the same SIM as last time * SIM_NEW : a valid SIM insert in slot i and is a new SIM * SIM_REPOSITION : a valid SIM insert in slot i and is inserted in different slot last time * positive integer #: index to distinguish SIM cards with the same IccId */ public static final int SIM_NOT_CHANGE = 0; public static final int SIM_CHANGED = -1; public static final int SIM_NEW = -2; public static final int SIM_REPOSITION = -3; public static final int SIM_NOT_INSERT = -99; public static final int STATUS_NO_SIM_INSERTED = 0x00; public static final int STATUS_SIM1_INSERTED = 0x01; public static final int STATUS_SIM2_INSERTED = 0x02; public static final int STATUS_SIM3_INSERTED = 0x04; public static final int STATUS_SIM4_INSERTED = 0x08; // Key used to read/write the current IMSI. Updated on SIM_STATE_CHANGED - LOADED. // Key used to read/write the current IMSI. Updated on SIM_STATE_CHANGED - LOADED. public static final String CURR_SUBID = "curr_subid"; public static final String CURR_SUBID = "curr_subid"; Loading @@ -114,7 +92,6 @@ public class SubscriptionInfoUpdater extends Handler { private static Phone[] mPhone; private static Phone[] mPhone; private static Context mContext = null; private static Context mContext = null; private static String mIccId[] = new String[PROJECT_SIM_NUM]; private static String mIccId[] = new String[PROJECT_SIM_NUM]; private static int[] mInsertSimState = new int[PROJECT_SIM_NUM]; private static int[] sSimCardState = new int[PROJECT_SIM_NUM]; private static int[] sSimCardState = new int[PROJECT_SIM_NUM]; private static int[] sSimApplicationState = new int[PROJECT_SIM_NUM]; private static int[] sSimApplicationState = new int[PROJECT_SIM_NUM]; private SubscriptionManager mSubscriptionManager = null; private SubscriptionManager mSubscriptionManager = null; Loading Loading @@ -330,9 +307,7 @@ public class SubscriptionInfoUpdater extends Handler { logd("NOT Querying IccId its already set sIccid[" + slotId + "]=" + iccId); logd("NOT Querying IccId its already set sIccid[" + slotId + "]=" + iccId); } } if (isAllIccIdQueryDone()) { updateSubscriptionInfoByIccId(slotId); updateSubscriptionInfoByIccId(); } broadcastSimStateChanged(slotId, IccCardConstants.INTENT_VALUE_ICC_LOCKED, reason); broadcastSimStateChanged(slotId, IccCardConstants.INTENT_VALUE_ICC_LOCKED, reason); broadcastSimCardStateChanged(slotId, TelephonyManager.SIM_STATE_PRESENT); broadcastSimCardStateChanged(slotId, TelephonyManager.SIM_STATE_PRESENT); Loading Loading @@ -366,9 +341,7 @@ public class SubscriptionInfoUpdater extends Handler { // phase, the subscription list is accessible. Treating NOT_READY // phase, the subscription list is accessible. Treating NOT_READY // as equivalent to ABSENT, once the rest of the system can handle it. // as equivalent to ABSENT, once the rest of the system can handle it. mIccId[slotId] = ICCID_STRING_FOR_NO_SIM; mIccId[slotId] = ICCID_STRING_FOR_NO_SIM; if (isAllIccIdQueryDone()) { updateSubscriptionInfoByIccId(slotId); updateSubscriptionInfoByIccId(); } } } broadcastSimStateChanged(slotId, IccCardConstants.INTENT_VALUE_ICC_NOT_READY, broadcastSimStateChanged(slotId, IccCardConstants.INTENT_VALUE_ICC_NOT_READY, Loading Loading @@ -400,14 +373,16 @@ public class SubscriptionInfoUpdater extends Handler { } } mIccId[slotId] = IccUtils.stripTrailingFs(records.getFullIccId()); mIccId[slotId] = IccUtils.stripTrailingFs(records.getFullIccId()); if (isAllIccIdQueryDone()) { updateSubscriptionInfoByIccId(slotId); updateSubscriptionInfoByIccId(); List<SubscriptionInfo> subscriptionInfos = SubscriptionController.getInstance() int[] subIds = mSubscriptionManager.getActiveSubscriptionIdList(); .getSubInfoUsingSlotIndexPrivileged(slotId, false); for (int subId : subIds) { if (subscriptionInfos == null || subscriptionInfos.isEmpty()) { loge("empty subinfo for slotId: " + slotId + "could not update ContentResolver"); } else { for (SubscriptionInfo sub : subscriptionInfos) { int subId = sub.getSubscriptionId(); TelephonyManager tm = TelephonyManager.getDefault(); TelephonyManager tm = TelephonyManager.getDefault(); String operator = tm.getSimOperatorNumeric(subId); String operator = tm.getSimOperatorNumeric(subId); slotId = SubscriptionController.getInstance().getPhoneId(subId); if (!TextUtils.isEmpty(operator)) { if (!TextUtils.isEmpty(operator)) { if (subId == SubscriptionController.getInstance().getDefaultSubId()) { if (subId == SubscriptionController.getInstance().getDefaultSubId()) { Loading @@ -427,8 +402,6 @@ public class SubscriptionInfoUpdater extends Handler { } } String msisdn = tm.getLine1Number(subId); String msisdn = tm.getLine1Number(subId); ContentResolver contentResolver = mContext.getContentResolver(); if (msisdn != null) { if (msisdn != null) { SubscriptionController.getInstance().setDisplayNumber(msisdn, subId); SubscriptionController.getInstance().setDisplayNumber(msisdn, subId); } } Loading @@ -449,7 +422,8 @@ public class SubscriptionInfoUpdater extends Handler { } } /* Update preferred network type and network selection mode on SIM change. /* Update preferred network type and network selection mode on SIM change. * Storing last subId in SharedPreference for now to detect SIM change. */ * Storing last subId in SharedPreference for now to detect SIM change. */ SharedPreferences sp = SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(mContext); PreferenceManager.getDefaultSharedPreferences(mContext); int storedSubId = sp.getInt(CURR_SUBID + slotId, -1); int storedSubId = sp.getInt(CURR_SUBID + slotId, -1); Loading Loading @@ -530,9 +504,7 @@ public class SubscriptionInfoUpdater extends Handler { logd("SIM" + (slotId + 1) + " hot plug out"); logd("SIM" + (slotId + 1) + " hot plug out"); } } mIccId[slotId] = ICCID_STRING_FOR_NO_SIM; mIccId[slotId] = ICCID_STRING_FOR_NO_SIM; if (isAllIccIdQueryDone()) { updateSubscriptionInfoByIccId(slotId); updateSubscriptionInfoByIccId(); } broadcastSimStateChanged(slotId, IccCardConstants.INTENT_VALUE_ICC_ABSENT, null); broadcastSimStateChanged(slotId, IccCardConstants.INTENT_VALUE_ICC_ABSENT, null); broadcastSimCardStateChanged(slotId, TelephonyManager.SIM_STATE_ABSENT); broadcastSimCardStateChanged(slotId, TelephonyManager.SIM_STATE_ABSENT); broadcastSimApplicationStateChanged(slotId, TelephonyManager.SIM_STATE_NOT_READY); broadcastSimApplicationStateChanged(slotId, TelephonyManager.SIM_STATE_NOT_READY); Loading @@ -545,9 +517,7 @@ public class SubscriptionInfoUpdater extends Handler { logd("SIM" + (slotId + 1) + " Error "); logd("SIM" + (slotId + 1) + " Error "); } } mIccId[slotId] = ICCID_STRING_FOR_NO_SIM; mIccId[slotId] = ICCID_STRING_FOR_NO_SIM; if (isAllIccIdQueryDone()) { updateSubscriptionInfoByIccId(slotId); updateSubscriptionInfoByIccId(); } broadcastSimStateChanged(slotId, IccCardConstants.INTENT_VALUE_ICC_CARD_IO_ERROR, broadcastSimStateChanged(slotId, IccCardConstants.INTENT_VALUE_ICC_CARD_IO_ERROR, IccCardConstants.INTENT_VALUE_ICC_CARD_IO_ERROR); IccCardConstants.INTENT_VALUE_ICC_CARD_IO_ERROR); broadcastSimCardStateChanged(slotId, TelephonyManager.SIM_STATE_CARD_IO_ERROR); broadcastSimCardStateChanged(slotId, TelephonyManager.SIM_STATE_CARD_IO_ERROR); Loading @@ -556,145 +526,51 @@ public class SubscriptionInfoUpdater extends Handler { updateCarrierServices(slotId, IccCardConstants.INTENT_VALUE_ICC_CARD_IO_ERROR); updateCarrierServices(slotId, IccCardConstants.INTENT_VALUE_ICC_CARD_IO_ERROR); } } /** synchronized private void updateSubscriptionInfoByIccId(int slotIndex) { * TODO: Simplify more, as no one is interested in what happened * only what the current list contains. */ synchronized private void updateSubscriptionInfoByIccId() { logd("updateSubscriptionInfoByIccId:+ Start"); logd("updateSubscriptionInfoByIccId:+ Start"); if (!SubscriptionManager.isValidSlotIndex(slotIndex)) { for (int i = 0; i < PROJECT_SIM_NUM; i++) { loge("[updateSubscriptionInfoByIccId]- invalid slotIndex=" + slotIndex); mInsertSimState[i] = SIM_NOT_CHANGE; return; } int insertedSimCount = PROJECT_SIM_NUM; for (int i = 0; i < PROJECT_SIM_NUM; i++) { if (ICCID_STRING_FOR_NO_SIM.equals(mIccId[i])) { insertedSimCount--; mInsertSimState[i] = SIM_NOT_INSERT; } } logd("insertedSimCount = " + insertedSimCount); // We only clear the slot-to-sub map when one/some SIM was removed. Note this is a // workaround for some race conditions that the empty map was accessed while we are // rebuilding the map. if (SubscriptionController.getInstance().getActiveSubIdList().length > insertedSimCount) { SubscriptionController.getInstance().clearSubInfo(); } int index = 0; for (int i = 0; i < PROJECT_SIM_NUM; i++) { if (mInsertSimState[i] == SIM_NOT_INSERT) { continue; } index = 2; for (int j = i + 1; j < PROJECT_SIM_NUM; j++) { if (mInsertSimState[j] == SIM_NOT_CHANGE && mIccId[i].equals(mIccId[j])) { mInsertSimState[i] = 1; mInsertSimState[j] = index; index++; } } } ContentResolver contentResolver = mContext.getContentResolver(); String[] oldIccId = new String[PROJECT_SIM_NUM]; String[] decIccId = new String[PROJECT_SIM_NUM]; for (int i = 0; i < PROJECT_SIM_NUM; i++) { oldIccId[i] = null; List<SubscriptionInfo> oldSubInfo = SubscriptionController.getInstance() .getSubInfoUsingSlotIndexPrivileged(i, false); decIccId[i] = IccUtils.getDecimalSubstring(mIccId[i]); if (oldSubInfo != null && oldSubInfo.size() > 0) { oldIccId[i] = oldSubInfo.get(0).getIccId(); logd("updateSubscriptionInfoByIccId: oldSubId = " + oldSubInfo.get(0).getSubscriptionId()); if (mInsertSimState[i] == SIM_NOT_CHANGE && !(mIccId[i].equals(oldIccId[i]) || (decIccId[i] != null && decIccId[i].equals(oldIccId[i])))) { mInsertSimState[i] = SIM_CHANGED; } if (mInsertSimState[i] != SIM_NOT_CHANGE) { ContentValues value = new ContentValues(1); value.put(SubscriptionManager.SIM_SLOT_INDEX, SubscriptionManager.INVALID_SIM_SLOT_INDEX); contentResolver.update(SubscriptionManager.getUriForSubscriptionId( oldSubInfo.get(0).getSubscriptionId()), value, null, null); // refresh Cached Active Subscription Info List SubscriptionController.getInstance().refreshCachedActiveSubscriptionInfoList(); } } else { if (mInsertSimState[i] == SIM_NOT_CHANGE) { // no SIM inserted last time, but there is one SIM inserted now mInsertSimState[i] = SIM_CHANGED; } oldIccId[i] = ICCID_STRING_FOR_NO_SIM; logd("updateSubscriptionInfoByIccId: No SIM in slot " + i + " last time"); } } for (int i = 0; i < PROJECT_SIM_NUM; i++) { logd("updateSubscriptionInfoByIccId: oldIccId[" + i + "] = " + oldIccId[i] + ", sIccId[" + i + "] = " + mIccId[i]); } } logd("updateSubscriptionInfoByIccId: removing subscription info record: slotIndex " + slotIndex); // Clear slotIndex only when sim absent is not enough. It's possible to switch SIM profile // within the same slot. Need to clear the slot index of the previous sub. Thus always clear // for the changing slot first. SubscriptionController.getInstance().clearSubInfoRecord(slotIndex); //check if the inserted SIM is new SIM // If SIM is not absent, insert new record or update existing record. for (int i = 0; i < PROJECT_SIM_NUM; i++) { if (!ICCID_STRING_FOR_NO_SIM.equals(mIccId[slotIndex])) { if (mInsertSimState[i] == SIM_NOT_INSERT) { logd("updateSubscriptionInfoByIccId: No SIM inserted in slot " + i + " this time"); } else { if (mInsertSimState[i] > 0) { //some special SIMs may have the same IccIds, add suffix to distinguish them //FIXME: addSubInfoRecord can return an error. mSubscriptionManager.addSubscriptionInfoRecord(mIccId[i] + Integer.toString(mInsertSimState[i]), i); logd("SUB" + (i + 1) + " has invalid IccId"); } else /*if (sInsertSimState[i] != SIM_NOT_INSERT)*/ { logd("updateSubscriptionInfoByIccId: adding subscription info record: iccid: " logd("updateSubscriptionInfoByIccId: adding subscription info record: iccid: " + mIccId[i] + "slot: " + i); + mIccId[slotIndex] + "slot: " + slotIndex); mSubscriptionManager.addSubscriptionInfoRecord(mIccId[i], i); mSubscriptionManager.addSubscriptionInfoRecord(mIccId[slotIndex], slotIndex); } if (isNewSim(mIccId[i], decIccId[i], oldIccId)) { mInsertSimState[i] = SIM_NEW; } } } for (int i = 0; i < PROJECT_SIM_NUM; i++) { if (mInsertSimState[i] == SIM_CHANGED) { mInsertSimState[i] = SIM_REPOSITION; } logd("updateSubscriptionInfoByIccId: sInsertSimState[" + i + "] = " + mInsertSimState[i]); } } List<SubscriptionInfo> subInfos = mSubscriptionManager.getActiveSubscriptionInfoList(); List<SubscriptionInfo> subInfos = SubscriptionController.getInstance() int nSubCount = (subInfos == null) ? 0 : subInfos.size(); .getSubInfoUsingSlotIndexPrivileged(slotIndex, false); logd("updateSubscriptionInfoByIccId: nSubCount = " + nSubCount); if (subInfos != null) { for (int i=0; i < nSubCount; i++) { for (int i = 0; i < subInfos.size(); i++) { SubscriptionInfo temp = subInfos.get(i); SubscriptionInfo temp = subInfos.get(i); ContentValues value = new ContentValues(1); String msisdn = TelephonyManager.getDefault().getLine1Number( String msisdn = TelephonyManager.getDefault().getLine1Number( temp.getSubscriptionId()); temp.getSubscriptionId()); if (msisdn != null) { if (msisdn != null) { ContentValues value = new ContentValues(1); value.put(SubscriptionManager.NUMBER, msisdn); value.put(SubscriptionManager.NUMBER, msisdn); contentResolver.update(SubscriptionManager.getUriForSubscriptionId( mContext.getContentResolver().update(SubscriptionManager.getUriForSubscriptionId( temp.getSubscriptionId()), value, null, null); temp.getSubscriptionId()), value, null, null); // refresh Cached Active Subscription Info List // refresh Cached Active Subscription Info List SubscriptionController.getInstance().refreshCachedActiveSubscriptionInfoList(); SubscriptionController.getInstance().refreshCachedActiveSubscriptionInfoList(); } } } } } // TODO investigate if we can update for each slot separately. if (isAllIccIdQueryDone()) { // Ensure the modems are mapped correctly // Ensure the modems are mapped correctly mSubscriptionManager.setDefaultDataSubId( mSubscriptionManager.setDefaultDataSubId( mSubscriptionManager.getDefaultDataSubscriptionId()); mSubscriptionManager.getDefaultDataSubscriptionId()); // No need to check return value here as we notify for the above changes anyway. if (subInfos != null) { UiccController uiccController = UiccController.getInstance(); UiccController uiccController = UiccController.getInstance(); UiccSlot[] uiccSlots = uiccController.getUiccSlots(); UiccSlot[] uiccSlots = uiccController.getUiccSlots(); if (uiccSlots != null) { if (uiccSlots != null) { Loading Loading @@ -951,6 +827,10 @@ public class SubscriptionInfoUpdater extends Handler { Rlog.d(LOG_TAG, message); Rlog.d(LOG_TAG, message); } } private void loge(String message) { Rlog.e(LOG_TAG, message); } public void dump(FileDescriptor fd, PrintWriter pw, String[] args) { public void dump(FileDescriptor fd, PrintWriter pw, String[] args) { pw.println("SubscriptionInfoUpdater:"); pw.println("SubscriptionInfoUpdater:"); mCarrierServiceBindHelper.dump(fd, pw, args); mCarrierServiceBindHelper.dump(fd, pw, args); Loading
tests/telephonytests/src/com/android/internal/telephony/SubscriptionInfoUpdaterTest.java +19 −25 Original line number Original line Diff line number Diff line Loading @@ -122,7 +122,6 @@ public class SubscriptionInfoUpdaterTest extends TelephonyTest { super.setUp(this.getClass().getSimpleName()); super.setUp(this.getClass().getSimpleName()); replaceInstance(SubscriptionInfoUpdater.class, "mIccId", null, new String[1]); replaceInstance(SubscriptionInfoUpdater.class, "mIccId", null, new String[1]); replaceInstance(SubscriptionInfoUpdater.class, "mInsertSimState", null, new int[1]); replaceInstance(SubscriptionInfoUpdater.class, "mContext", null, null); replaceInstance(SubscriptionInfoUpdater.class, "mContext", null, null); replaceInstance(SubscriptionInfoUpdater.class, "PROJECT_SIM_NUM", null, 1); replaceInstance(SubscriptionInfoUpdater.class, "PROJECT_SIM_NUM", null, 1); replaceInstance(SubscriptionInfoUpdater.class, "sSimCardState", null, new int[1]); replaceInstance(SubscriptionInfoUpdater.class, "sSimCardState", null, new int[1]); Loading Loading @@ -176,14 +175,12 @@ public class SubscriptionInfoUpdaterTest extends TelephonyTest { IccCardConstants.INTENT_VALUE_ICC_ABSENT, null, FAKE_SUB_ID_1); IccCardConstants.INTENT_VALUE_ICC_ABSENT, null, FAKE_SUB_ID_1); waitForMs(100); waitForMs(100); verify(mSubscriptionContent).put(eq(SubscriptionManager.SIM_SLOT_INDEX), verify(mSubscriptionController, times(1)).clearSubInfoRecord(eq(FAKE_SUB_ID_1)); eq(SubscriptionManager.INVALID_SIM_SLOT_INDEX)); CarrierConfigManager mConfigManager = (CarrierConfigManager) CarrierConfigManager mConfigManager = (CarrierConfigManager) mContext.getSystemService(Context.CARRIER_CONFIG_SERVICE); mContext.getSystemService(Context.CARRIER_CONFIG_SERVICE); verify(mConfigManager).updateConfigForPhoneId(eq(FAKE_SUB_ID_1), verify(mConfigManager).updateConfigForPhoneId(eq(FAKE_SUB_ID_1), eq(IccCardConstants.INTENT_VALUE_ICC_ABSENT)); eq(IccCardConstants.INTENT_VALUE_ICC_ABSENT)); verify(mSubscriptionController, times(1)).clearSubInfo(); verify(mSubscriptionController, times(1)).notifySubscriptionInfoChanged(); verify(mSubscriptionController, times(1)).notifySubscriptionInfoChanged(); } } Loading Loading @@ -238,8 +235,8 @@ public class SubscriptionInfoUpdaterTest extends TelephonyTest { @Test @Test @SmallTest @SmallTest public void testSimLoaded() throws Exception { public void testSimLoaded() throws Exception { /* mock new sim got loaded and there is no sim loaded before */ doReturn(FAKE_SUB_ID_1).when(mSubInfo).getSubscriptionId(); doReturn(null).when(mSubscriptionController) doReturn(Arrays.asList(mSubInfo)).when(mSubscriptionController) .getSubInfoUsingSlotIndexPrivileged(eq(FAKE_SUB_ID_1), anyBoolean()); .getSubInfoUsingSlotIndexPrivileged(eq(FAKE_SUB_ID_1), anyBoolean()); doReturn("89012604200000000000").when(mIccRecord).getFullIccId(); doReturn("89012604200000000000").when(mIccRecord).getFullIccId(); doReturn(FAKE_MCC_MNC_1).when(mTelephonyManager).getSimOperatorNumeric(FAKE_SUB_ID_1); doReturn(FAKE_MCC_MNC_1).when(mTelephonyManager).getSimOperatorNumeric(FAKE_SUB_ID_1); Loading Loading @@ -303,12 +300,12 @@ public class SubscriptionInfoUpdaterTest extends TelephonyTest { @Test @Test @SmallTest @SmallTest public void testSimLoadedEmptyOperatorNumeric() throws Exception { public void testSimLoadedEmptyOperatorNumeric() throws Exception { /* mock new sim got loaded and there is no sim loaded before */ doReturn(null).when(mSubscriptionController) .getSubInfoUsingSlotIndexPrivileged(eq(FAKE_SUB_ID_1), anyBoolean()); doReturn("89012604200000000000").when(mIccRecord).getFullIccId(); doReturn("89012604200000000000").when(mIccRecord).getFullIccId(); // operator numeric is empty // operator numeric is empty doReturn("").when(mTelephonyManager).getSimOperatorNumeric(FAKE_SUB_ID_1); doReturn("").when(mTelephonyManager).getSimOperatorNumeric(FAKE_SUB_ID_1); doReturn(FAKE_SUB_ID_1).when(mSubInfo).getSubscriptionId(); doReturn(Arrays.asList(mSubInfo)).when(mSubscriptionController) .getSubInfoUsingSlotIndexPrivileged(eq(FAKE_SUB_ID_1), anyBoolean()); mUpdater.updateInternalIccState( mUpdater.updateInternalIccState( IccCardConstants.INTENT_VALUE_ICC_LOADED, null, FAKE_SUB_ID_1); IccCardConstants.INTENT_VALUE_ICC_LOADED, null, FAKE_SUB_ID_1); Loading Loading @@ -340,9 +337,6 @@ public class SubscriptionInfoUpdaterTest extends TelephonyTest { waitForMs(100); waitForMs(100); /* old IccId != new queried IccId */ verify(mSubscriptionContent).put(eq(SubscriptionManager.SIM_SLOT_INDEX), eq(SubscriptionManager.INVALID_SIM_SLOT_INDEX)); SubscriptionManager mSubscriptionManager = SubscriptionManager.from(mContext); SubscriptionManager mSubscriptionManager = SubscriptionManager.from(mContext); verify(mSubscriptionManager, times(1)).addSubscriptionInfoRecord( verify(mSubscriptionManager, times(1)).addSubscriptionInfoRecord( eq("98106240020000000000"), eq(FAKE_SUB_ID_1)); eq("98106240020000000000"), eq(FAKE_SUB_ID_1)); Loading @@ -359,15 +353,11 @@ public class SubscriptionInfoUpdaterTest extends TelephonyTest { @SmallTest @SmallTest public void testDualSimLoaded() throws Exception { public void testDualSimLoaded() throws Exception { // Mock there is two sim cards // Mock there is two sim cards replaceInstance(SubscriptionInfoUpdater.class, "mIccId", null, replaceInstance(SubscriptionInfoUpdater.class, "mIccId", null, new String[]{null, null}); new String[]{null, null}); replaceInstance(SubscriptionInfoUpdater.class, "PROJECT_SIM_NUM", null, 2); replaceInstance(SubscriptionInfoUpdater.class, "PROJECT_SIM_NUM", null, 2); replaceInstance(SubscriptionInfoUpdater.class, "mPhone", null, replaceInstance(SubscriptionInfoUpdater.class, "mPhone", null, new Phone[]{mPhone, mPhone}); new Phone[]{mPhone, mPhone}); replaceInstance(SubscriptionInfoUpdater.class, "mInsertSimState", null, new int[]{SubscriptionInfoUpdater.SIM_NOT_CHANGE, SubscriptionInfoUpdater.SIM_NOT_CHANGE}); replaceInstance(SubscriptionInfoUpdater.class, "sSimCardState", null, replaceInstance(SubscriptionInfoUpdater.class, "sSimCardState", null, new int[]{0, 0}); new int[]{0, 0}); replaceInstance(SubscriptionInfoUpdater.class, "sSimApplicationState", null, replaceInstance(SubscriptionInfoUpdater.class, "sSimApplicationState", null, Loading @@ -380,24 +370,29 @@ public class SubscriptionInfoUpdaterTest extends TelephonyTest { doReturn(2).when(mTelephonyManager).getSimCount(); doReturn(2).when(mTelephonyManager).getSimCount(); doReturn(FAKE_MCC_MNC_1).when(mTelephonyManager).getSimOperatorNumeric(eq(FAKE_SUB_ID_1)); doReturn(FAKE_MCC_MNC_1).when(mTelephonyManager).getSimOperatorNumeric(eq(FAKE_SUB_ID_1)); doReturn(FAKE_MCC_MNC_2).when(mTelephonyManager).getSimOperatorNumeric(eq(FAKE_SUB_ID_2)); doReturn(FAKE_MCC_MNC_2).when(mTelephonyManager).getSimOperatorNumeric(eq(FAKE_SUB_ID_2)); // Mock there is no sim inserted before doReturn(null).when(mSubscriptionController) .getSubInfoUsingSlotIndexPrivileged(anyInt(), anyBoolean()); verify(mSubscriptionController, times(0)).clearSubInfo(); verify(mSubscriptionController, times(0)).clearSubInfo(); doReturn("89012604200000000000").when(mIccRecord).getFullIccId(); doReturn("89012604200000000000").when(mIccRecord).getFullIccId(); SubscriptionManager mSubscriptionManager = SubscriptionManager.from(mContext); verify(mSubscriptionManager, times(0)).addSubscriptionInfoRecord(anyString(), anyInt()); verify(mSubscriptionController, times(0)).notifySubscriptionInfoChanged(); verify(mSubscriptionController, times(0)).setMccMnc(anyString(), anyInt()); // Mock sending a sim loaded for SIM 1 // Mock sending a sim loaded for SIM 1 doReturn(Arrays.asList(mSubInfo)).when(mSubscriptionController) .getSubInfoUsingSlotIndexPrivileged(eq(FAKE_SUB_ID_1), anyBoolean()); mUpdater.updateInternalIccState( mUpdater.updateInternalIccState( IccCardConstants.INTENT_VALUE_ICC_LOADED, null, FAKE_SUB_ID_1); IccCardConstants.INTENT_VALUE_ICC_LOADED, null, FAKE_SUB_ID_1); waitForMs(100); waitForMs(100); SubscriptionManager mSubscriptionManager = SubscriptionManager.from(mContext); verify(mSubscriptionManager, times(1)).addSubscriptionInfoRecord(anyString(), anyInt()); verify(mSubscriptionManager, times(0)).addSubscriptionInfoRecord(anyString(), anyInt()); verify(mSubscriptionController, times(1)).notifySubscriptionInfoChanged(); verify(mSubscriptionController, times(0)).notifySubscriptionInfoChanged(); verify(mSubscriptionController, times(1)).setMccMnc(anyString(), anyInt()); verify(mSubscriptionController, times(0)).setMccMnc(anyString(), anyInt()); // Mock sending a sim loaded for SIM 2 // Mock sending a sim loaded for SIM 2 doReturn(Arrays.asList(mSubInfo)).when(mSubscriptionController) .getSubInfoUsingSlotIndexPrivileged(eq(FAKE_SUB_ID_2), anyBoolean()); doReturn(FAKE_SUB_ID_2).when(mSubInfo).getSubscriptionId(); doReturn("89012604200000000001").when(mIccRecord).getFullIccId(); doReturn("89012604200000000001").when(mIccRecord).getFullIccId(); mUpdater.updateInternalIccState( mUpdater.updateInternalIccState( Loading @@ -411,8 +406,7 @@ public class SubscriptionInfoUpdaterTest extends TelephonyTest { eq(FAKE_SUB_ID_2)); eq(FAKE_SUB_ID_2)); verify(mSubscriptionController, times(1)).setMccMnc(eq(FAKE_MCC_MNC_1), eq(FAKE_SUB_ID_1)); verify(mSubscriptionController, times(1)).setMccMnc(eq(FAKE_MCC_MNC_1), eq(FAKE_SUB_ID_1)); verify(mSubscriptionController, times(1)).setMccMnc(eq(FAKE_MCC_MNC_2), eq(FAKE_SUB_ID_2)); verify(mSubscriptionController, times(1)).setMccMnc(eq(FAKE_MCC_MNC_2), eq(FAKE_SUB_ID_2)); verify(mSubscriptionController, times(0)).clearSubInfo(); verify(mSubscriptionController, times(2)).notifySubscriptionInfoChanged(); verify(mSubscriptionController, times(1)).notifySubscriptionInfoChanged(); } } @Test @Test Loading