Loading src/java/com/android/internal/telephony/MultiSimSettingController.java +8 −6 Original line number Diff line number Diff line Loading @@ -63,7 +63,6 @@ public class MultiSimSettingController extends Handler { private final Context mContext; private final SubscriptionController mSubController; private boolean mIsAllSubscriptionsLoaded; private List<SubscriptionInfo> mPrimarySubList; /** The singleton instance. */ Loading Loading @@ -117,7 +116,8 @@ public class MultiSimSettingController extends Handler { } /** * Notify that, for the first time after boot, SIMs are all loaded * Notify that, for the first time after boot, SIMs are initialized. * Should only be triggered once. */ public void notifyAllSubscriptionLoaded() { obtainMessage(EVENT_ALL_SUBSCRIPTIONS_LOADED).sendToTarget(); Loading Loading @@ -207,12 +207,12 @@ public class MultiSimSettingController extends Handler { } /** * Mark mIsAllSubscriptionsLoaded and update defaults and mobile data enabling. * Upon initialization, update defaults and mobile data enabling. * Should only be triggered once. */ @VisibleForTesting public void onAllSubscriptionsLoaded() { if (DBG) log("onAllSubscriptionsLoaded"); mIsAllSubscriptionsLoaded = true; updateDefaults(); disableDataForNonDefaultNonOpportunisticSubscriptions(); } Loading @@ -225,7 +225,7 @@ public class MultiSimSettingController extends Handler { @VisibleForTesting public void onSubscriptionsChanged() { if (DBG) log("onSubscriptionsChanged"); if (!mIsAllSubscriptionsLoaded) return; if (!SubscriptionInfoUpdater.isSubInfoInitialized()) return; updateDefaults(); disableDataForNonDefaultNonOpportunisticSubscriptions(); } Loading Loading @@ -310,7 +310,7 @@ public class MultiSimSettingController extends Handler { public void updateDefaults() { if (DBG) log("updateDefaults"); if (!mIsAllSubscriptionsLoaded) return; if (!SubscriptionInfoUpdater.isSubInfoInitialized()) return; List<SubscriptionInfo> activeSubInfos = mSubController .getActiveSubscriptionInfoList(mContext.getOpPackageName()); Loading Loading @@ -399,6 +399,8 @@ public class MultiSimSettingController extends Handler { } private void disableDataForNonDefaultNonOpportunisticSubscriptions() { if (!SubscriptionInfoUpdater.isSubInfoInitialized()) return; int defaultDataSub = mSubController.getDefaultDataSubId(); // Only disable data for non-default subscription if default sub is active. if (!mSubController.isActiveSubId(defaultDataSub)) { Loading src/java/com/android/internal/telephony/SubscriptionController.java +17 −42 Original line number Diff line number Diff line Loading @@ -211,27 +211,17 @@ public class SubscriptionController extends ISub.Stub { if (DBG) logdl("[SubscriptionController] init by Context"); } /** * Should only be triggered once. */ public void notifySubInfoReady() { // broadcast default subId. sendDefaultChangedBroadcast(SubscriptionManager.getDefaultSubscriptionId()); } @UnsupportedAppUsage private boolean isSubInfoReady() { if (VDBG) { // make sure sSlotIndexToSubIds is consistent with cached subinfo list int count = 0; for (Integer i : sSlotIndexToSubIds.keySet()) { count += sSlotIndexToSubIds.get(i).size(); } if (count != mCacheActiveSubInfoList.size()) { logdl("mismatch between map and list. list size = " + mCacheActiveSubInfoList.size() + ", map size = " + count); for (Integer i : sSlotIndexToSubIds.keySet()) { logdl("From the Map, subs in map at slot index: " + i + " are: " + sSlotIndexToSubIds.get(i)); } for (SubscriptionInfo info : mCacheActiveSubInfoList) { logdl("From the Cached list, subinfo is: " + info); } } } return sSlotIndexToSubIds.size() > 0; return SubscriptionInfoUpdater.isSubInfoInitialized(); } /** Loading Loading @@ -703,14 +693,6 @@ public class SubscriptionController extends ISub.Stub { */ @VisibleForTesting // For mockito to mock this method public void refreshCachedActiveSubscriptionInfoList() { if (!isSubInfoReady()) { if (DBG_CACHE) { logdl("[refreshCachedActiveSubscriptionInfoList] " + "Sub Controller not ready "); } return; } boolean opptSubListChanged; synchronized (mSubInfoListLock) { Loading Loading @@ -1365,8 +1347,7 @@ public class SubscriptionController extends ISub.Stub { if (DBG) logdl("[clearSubInfoRecord]+ iccId:" + " slotIndex:" + slotIndex); // update simInfo db with invalid slot index List<SubscriptionInfo> oldSubInfo = getSubInfoUsingSlotIndexPrivileged(slotIndex, false); List<SubscriptionInfo> oldSubInfo = getSubInfoUsingSlotIndexPrivileged(slotIndex); ContentResolver resolver = mContext.getContentResolver(); ContentValues value = new ContentValues(1); value.put(SubscriptionManager.SIM_SLOT_INDEX, Loading Loading @@ -2327,8 +2308,7 @@ public class SubscriptionController extends ISub.Stub { /** Must be public for access from instrumentation tests. */ @VisibleForTesting public List<SubscriptionInfo> getSubInfoUsingSlotIndexPrivileged(int slotIndex, boolean needCheck) { public List<SubscriptionInfo> getSubInfoUsingSlotIndexPrivileged(int slotIndex) { if (DBG) logd("[getSubInfoUsingSlotIndexPrivileged]+ slotIndex:" + slotIndex); if (slotIndex == SubscriptionManager.DEFAULT_SIM_SLOT_INDEX) { slotIndex = getSlotIndex(getDefaultSubId()); Loading @@ -2338,11 +2318,6 @@ public class SubscriptionController extends ISub.Stub { return null; } if (needCheck && !isSubInfoReady()) { if (DBG) logd("[getSubInfoUsingSlotIndexPrivileged]- not ready"); return null; } Cursor cursor = mContext.getContentResolver().query(SubscriptionManager.CONTENT_URI, null, SubscriptionManager.SIM_SLOT_INDEX + "=?", new String[]{String.valueOf(slotIndex)}, null); Loading Loading @@ -3467,11 +3442,6 @@ public class SubscriptionController extends ISub.Stub { // They are doing similar things except operating on different cache. private List<SubscriptionInfo> getSubscriptionInfoListFromCacheHelper( String callingPackage, List<SubscriptionInfo> cacheSubList) { if (!isSubInfoReady()) { if (DBG) logd("[getSubscriptionInfoList] Sub Controller not ready"); return null; } boolean canReadAllPhoneState; try { canReadAllPhoneState = TelephonyPermissions.checkReadPhoneState(mContext, Loading Loading @@ -3580,7 +3550,11 @@ public class SubscriptionController extends ISub.Stub { for (SubscriptionInfo info : mCacheOpportunisticSubInfoList) { if (shouldDisableSubGroup(info.getGroupUuid())) { info.setGroupDisabled(true); if (isActiveSubId(info.getSubscriptionId())) { // TODO: move it to ONS. if (isActiveSubId(info.getSubscriptionId()) && isSubInfoReady()) { logd("[refreshCachedOpportunisticSubscriptionInfoList] " + "Deactivating grouped opportunistic subscription " + info.getSubscriptionId()); deactivateSubscription(info); } } Loading Loading @@ -3616,6 +3590,7 @@ public class SubscriptionController extends ISub.Stub { private void deactivateSubscription(SubscriptionInfo info) { // TODO: b/120439488 deactivate pSIM. if (info.isEmbedded()) { logd("[deactivateSubscription] eSIM profile " + info.getSubscriptionId()); EuiccManager euiccManager = (EuiccManager) mContext.getSystemService(Context.EUICC_SERVICE); euiccManager.switchToSubscription(SubscriptionManager.INVALID_SUBSCRIPTION_ID, Loading src/java/com/android/internal/telephony/SubscriptionInfoUpdater.java +23 −9 Original line number Diff line number Diff line Loading @@ -108,6 +108,7 @@ public class SubscriptionInfoUpdater extends Handler { private static String mIccId[] = new String[PROJECT_SIM_NUM]; private static int[] sSimCardState = new int[PROJECT_SIM_NUM]; private static int[] sSimApplicationState = new int[PROJECT_SIM_NUM]; private static boolean sIsSubInfoInitialized = false; private SubscriptionManager mSubscriptionManager = null; private EuiccManager mEuiccManager; @UnsupportedAppUsage Loading Loading @@ -420,7 +421,7 @@ public class SubscriptionInfoUpdater extends Handler { updateSubscriptionInfoByIccId(slotId); List<SubscriptionInfo> subscriptionInfos = SubscriptionController.getInstance() .getSubInfoUsingSlotIndexPrivileged(slotId, false); .getSubInfoUsingSlotIndexPrivileged(slotId); if (subscriptionInfos == null || subscriptionInfos.isEmpty()) { loge("empty subinfo for slotId: " + slotId + "could not update ContentResolver"); } else { Loading Loading @@ -587,7 +588,7 @@ public class SubscriptionInfoUpdater extends Handler { } List<SubscriptionInfo> subInfos = SubscriptionController.getInstance() .getSubInfoUsingSlotIndexPrivileged(slotIndex, false); .getSubInfoUsingSlotIndexPrivileged(slotIndex); if (subInfos != null) { boolean changed = false; for (int i = 0; i < subInfos.size(); i++) { Loading Loading @@ -629,17 +630,30 @@ public class SubscriptionInfoUpdater extends Handler { uiccSlot.getUiccCard().getCardId())) .forEach(cardId -> updateEmbeddedSubscriptions(cardId)); } // update default subId MultiSimSettingController.getInstance().notifyAllSubscriptionLoaded(); // broadcast default subId SubscriptionController.getInstance().sendDefaultChangedBroadcast( SubscriptionManager.getDefaultSubscriptionId()); setSubInfoInitialized(); } SubscriptionController.getInstance().notifySubscriptionInfoChanged(); logd("updateSubscriptionInfoByIccId:- SubscriptionInfo update complete"); } private static void setSubInfoInitialized() { // Should only be triggered once. if (!sIsSubInfoInitialized) { if (DBG) logd("SubInfo Initialized"); sIsSubInfoInitialized = true; SubscriptionController.getInstance().notifySubInfoReady(); MultiSimSettingController.getInstance().notifyAllSubscriptionLoaded(); } } /** * Whether subscriptions of all SIMs are initialized. */ public static boolean isSubInfoInitialized() { return sIsSubInfoInitialized; } /** * Update the cached list of embedded subscription for the eUICC with the given card ID * {@code cardId}. Loading Loading @@ -1013,11 +1027,11 @@ public class SubscriptionInfoUpdater extends Handler { } @UnsupportedAppUsage private void logd(String message) { private static void logd(String message) { Rlog.d(LOG_TAG, message); } private void loge(String message) { private static void loge(String message) { Rlog.e(LOG_TAG, message); } Loading tests/telephonytests/src/com/android/internal/telephony/SubscriptionInfoUpdaterTest.java +27 −9 Original line number Diff line number Diff line Loading @@ -23,7 +23,6 @@ import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; import static org.mockito.ArgumentMatchers.isNull; import static org.mockito.Mockito.any; import static org.mockito.Mockito.anyBoolean; import static org.mockito.Mockito.anyInt; import static org.mockito.Mockito.anyString; import static org.mockito.Mockito.doReturn; Loading Loading @@ -56,6 +55,7 @@ import android.test.suitebuilder.annotation.SmallTest; import com.android.internal.telephony.euicc.EuiccController; import com.android.internal.telephony.uicc.IccFileHandler; import com.android.internal.telephony.uicc.IccRecords; import com.android.internal.telephony.uicc.UiccSlot; import org.junit.After; import org.junit.Before; Loading Loading @@ -98,6 +98,8 @@ public class SubscriptionInfoUpdaterTest extends TelephonyTest { private IntentBroadcaster mIntentBroadcaster; @Mock private IPackageManager mPackageManager; @Mock private UiccSlot mUiccSlot; /*Custom ContentProvider */ private class FakeSubscriptionContentProvider extends MockContentProvider { Loading Loading @@ -130,10 +132,13 @@ public class SubscriptionInfoUpdaterTest extends TelephonyTest { replaceInstance(SubscriptionInfoUpdater.class, "PROJECT_SIM_NUM", null, 1); replaceInstance(SubscriptionInfoUpdater.class, "sSimCardState", null, new int[1]); replaceInstance(SubscriptionInfoUpdater.class, "sSimApplicationState", null, new int[1]); replaceInstance(SubscriptionInfoUpdater.class, "sIsSubInfoInitialized", null, false); replaceInstance(EuiccController.class, "sInstance", null, mEuiccController); replaceInstance(IntentBroadcaster.class, "sIntentBroadcaster", null, mIntentBroadcaster); doReturn(true).when(mUiccSlot).isActive(); doReturn(mUiccSlot).when(mUiccController).getUiccSlotForPhone(anyInt()); doReturn(1).when(mTelephonyManager).getSimCount(); doReturn(1).when(mTelephonyManager).getPhoneCount(); Loading Loading @@ -162,6 +167,8 @@ public class SubscriptionInfoUpdaterTest extends TelephonyTest { mSubscriptionInfoUpdaterHandlerThread = new SubscriptionInfoUpdaterHandlerThread(TAG); mSubscriptionInfoUpdaterHandlerThread.start(); waitUntilReady(); assertFalse(mUpdater.isSubInfoInitialized()); } @After Loading @@ -174,13 +181,14 @@ public class SubscriptionInfoUpdaterTest extends TelephonyTest { @SmallTest public void testSimAbsent() throws Exception { doReturn(Arrays.asList(mSubInfo)).when(mSubscriptionController) .getSubInfoUsingSlotIndexPrivileged(eq(FAKE_SUB_ID_1), anyBoolean()); .getSubInfoUsingSlotIndexPrivileged(eq(FAKE_SUB_ID_1)); doReturn(new int[]{FAKE_SUB_ID_1}).when(mSubscriptionController) .getActiveSubIdList(/*visibleOnly*/false); mUpdater.updateInternalIccState( IccCardConstants.INTENT_VALUE_ICC_ABSENT, null, FAKE_SUB_ID_1, false); waitForMs(100); assertTrue(mUpdater.isSubInfoInitialized()); verify(mSubscriptionController, times(1)).clearSubInfoRecord(eq(FAKE_SUB_ID_1)); CarrierConfigManager mConfigManager = (CarrierConfigManager) Loading @@ -194,13 +202,14 @@ public class SubscriptionInfoUpdaterTest extends TelephonyTest { @SmallTest public void testSimAbsentAndInactive() throws Exception { doReturn(Arrays.asList(mSubInfo)).when(mSubscriptionController) .getSubInfoUsingSlotIndexPrivileged(eq(FAKE_SUB_ID_1), anyBoolean()); .getSubInfoUsingSlotIndexPrivileged(eq(FAKE_SUB_ID_1)); doReturn(new int[]{FAKE_SUB_ID_1}).when(mSubscriptionController) .getActiveSubIdList(/*visibleOnly*/false); mUpdater.updateInternalIccState( IccCardConstants.INTENT_VALUE_ICC_ABSENT, null, FAKE_SUB_ID_1, true); waitForMs(100); assertTrue(mUpdater.isSubInfoInitialized()); verify(mSubscriptionController, times(1)).clearSubInfoRecord(eq(FAKE_SUB_ID_1)); // Verify that in the special absent and inactive case, we update subscriptions without Loading @@ -220,6 +229,7 @@ public class SubscriptionInfoUpdaterTest extends TelephonyTest { IccCardConstants.INTENT_VALUE_ICC_UNKNOWN, null, FAKE_SUB_ID_1, false); waitForMs(100); assertFalse(mUpdater.isSubInfoInitialized()); verify(mSubscriptionContent, times(0)).put(anyString(), any()); CarrierConfigManager mConfigManager = (CarrierConfigManager) mContext.getSystemService(Context.CARRIER_CONFIG_SERVICE); Loading @@ -236,6 +246,7 @@ public class SubscriptionInfoUpdaterTest extends TelephonyTest { IccCardConstants.INTENT_VALUE_ICC_CARD_IO_ERROR, null, FAKE_SUB_ID_1, false); waitForMs(100); assertTrue(mUpdater.isSubInfoInitialized()); verify(mSubscriptionContent, times(0)).put(anyString(), any()); CarrierConfigManager mConfigManager = (CarrierConfigManager) mContext.getSystemService(Context.CARRIER_CONFIG_SERVICE); Loading @@ -252,6 +263,7 @@ public class SubscriptionInfoUpdaterTest extends TelephonyTest { IccCardConstants.INTENT_VALUE_ICC_IMSI, null, 2, false); waitForMs(100); assertFalse(mUpdater.isSubInfoInitialized()); verify(mSubscriptionContent, times(0)).put(anyString(), any()); CarrierConfigManager mConfigManager = (CarrierConfigManager) mContext.getSystemService(Context.CARRIER_CONFIG_SERVICE); Loading @@ -266,7 +278,7 @@ public class SubscriptionInfoUpdaterTest extends TelephonyTest { public void testSimLoaded() throws Exception { doReturn(FAKE_SUB_ID_1).when(mSubInfo).getSubscriptionId(); doReturn(Arrays.asList(mSubInfo)).when(mSubscriptionController) .getSubInfoUsingSlotIndexPrivileged(eq(FAKE_SUB_ID_1), anyBoolean()); .getSubInfoUsingSlotIndexPrivileged(eq(FAKE_SUB_ID_1)); doReturn("89012604200000000000").when(mIccRecord).getFullIccId(); doReturn(FAKE_MCC_MNC_1).when(mTelephonyManager).getSimOperatorNumeric(FAKE_SUB_ID_1); Loading @@ -274,6 +286,7 @@ public class SubscriptionInfoUpdaterTest extends TelephonyTest { IccCardConstants.INTENT_VALUE_ICC_LOADED, null, FAKE_SUB_ID_1, false); waitForMs(100); assertTrue(mUpdater.isSubInfoInitialized()); // verify SIM_STATE_CHANGED broadcast. It should be broadcast twice, once for // READ_PHONE_STATE and once for READ_PRIVILEGED_PHONE_STATE Loading Loading @@ -334,11 +347,12 @@ public class SubscriptionInfoUpdaterTest extends TelephonyTest { 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()); .getSubInfoUsingSlotIndexPrivileged(eq(FAKE_SUB_ID_1)); mUpdater.updateInternalIccState( IccCardConstants.INTENT_VALUE_ICC_LOADED, null, FAKE_SUB_ID_1, false); waitForMs(300); assertTrue(mUpdater.isSubInfoInitialized()); SubscriptionManager mSubscriptionManager = SubscriptionManager.from(mContext); verify(mTelephonyManager).getSimOperatorNumeric(FAKE_SUB_ID_1); verify(mSubscriptionManager, times(1)).addSubscriptionInfoRecord( Loading @@ -360,12 +374,13 @@ public class SubscriptionInfoUpdaterTest extends TelephonyTest { doReturn("98106240020000000000").when(mIccRecord).getFullIccId(); doReturn(Arrays.asList(mSubInfo)).when(mSubscriptionController) .getSubInfoUsingSlotIndexPrivileged(eq(FAKE_SUB_ID_1), anyBoolean()); .getSubInfoUsingSlotIndexPrivileged(eq(FAKE_SUB_ID_1)); mUpdater.updateInternalIccState( IccCardConstants.INTENT_VALUE_ICC_LOCKED, "TESTING", FAKE_SUB_ID_1, false); waitForMs(100); assertTrue(mUpdater.isSubInfoInitialized()); SubscriptionManager mSubscriptionManager = SubscriptionManager.from(mContext); verify(mSubscriptionManager, times(1)).addSubscriptionInfoRecord( eq("98106240020000000000"), eq(FAKE_SUB_ID_1)); Loading Loading @@ -408,7 +423,7 @@ public class SubscriptionInfoUpdaterTest extends TelephonyTest { // Mock sending a sim loaded for SIM 1 doReturn(Arrays.asList(mSubInfo)).when(mSubscriptionController) .getSubInfoUsingSlotIndexPrivileged(eq(FAKE_SUB_ID_1), anyBoolean()); .getSubInfoUsingSlotIndexPrivileged(eq(FAKE_SUB_ID_1)); mUpdater.updateInternalIccState( IccCardConstants.INTENT_VALUE_ICC_LOADED, null, FAKE_SUB_ID_1, false); Loading @@ -417,10 +432,11 @@ public class SubscriptionInfoUpdaterTest extends TelephonyTest { verify(mSubscriptionManager, times(1)).addSubscriptionInfoRecord(anyString(), anyInt()); verify(mSubscriptionController, times(1)).notifySubscriptionInfoChanged(); verify(mSubscriptionController, times(1)).setMccMnc(anyString(), anyInt()); assertFalse(mUpdater.isSubInfoInitialized()); // Mock sending a sim loaded for SIM 2 doReturn(Arrays.asList(mSubInfo)).when(mSubscriptionController) .getSubInfoUsingSlotIndexPrivileged(eq(FAKE_SUB_ID_2), anyBoolean()); .getSubInfoUsingSlotIndexPrivileged(eq(FAKE_SUB_ID_2)); doReturn(FAKE_SUB_ID_2).when(mSubInfo).getSubscriptionId(); doReturn("89012604200000000001").when(mIccRecord).getFullIccId(); Loading @@ -436,6 +452,7 @@ public class SubscriptionInfoUpdaterTest extends TelephonyTest { 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(2)).notifySubscriptionInfoChanged(); assertTrue(mUpdater.isSubInfoInitialized()); } @Test Loading @@ -451,6 +468,7 @@ public class SubscriptionInfoUpdaterTest extends TelephonyTest { waitForMs(100); assertTrue(mUpdater.isSubInfoInitialized()); SubscriptionManager mSubscriptionManager = SubscriptionManager.from(mContext); verify(mSubscriptionManager, times(1)).addSubscriptionInfoRecord( anyString(), eq(FAKE_SUB_ID_1)); Loading Loading @@ -582,7 +600,7 @@ public class SubscriptionInfoUpdaterTest extends TelephonyTest { @SmallTest public void testHexIccIdSuffix() throws Exception { doReturn(null).when(mSubscriptionController) .getSubInfoUsingSlotIndexPrivileged(anyInt(), anyBoolean()); .getSubInfoUsingSlotIndexPrivileged(anyInt()); verify(mSubscriptionController, times(0)).clearSubInfo(); doReturn("890126042000000000Ff").when(mIccRecord).getFullIccId(); Loading tests/telephonytests/src/com/android/internal/telephony/TelephonyTest.java +1 −0 Original line number Diff line number Diff line Loading @@ -563,6 +563,7 @@ public abstract class TelephonyTest { mCellularNetworkValidator); replaceInstance(MultiSimSettingController.class, "sInstance", null, mMultiSimSettingController); replaceInstance(SubscriptionInfoUpdater.class, "sIsSubInfoInitialized", null, true); assertNotNull("Failed to set up SubscriptionController singleton", SubscriptionController.getInstance()); Loading Loading
src/java/com/android/internal/telephony/MultiSimSettingController.java +8 −6 Original line number Diff line number Diff line Loading @@ -63,7 +63,6 @@ public class MultiSimSettingController extends Handler { private final Context mContext; private final SubscriptionController mSubController; private boolean mIsAllSubscriptionsLoaded; private List<SubscriptionInfo> mPrimarySubList; /** The singleton instance. */ Loading Loading @@ -117,7 +116,8 @@ public class MultiSimSettingController extends Handler { } /** * Notify that, for the first time after boot, SIMs are all loaded * Notify that, for the first time after boot, SIMs are initialized. * Should only be triggered once. */ public void notifyAllSubscriptionLoaded() { obtainMessage(EVENT_ALL_SUBSCRIPTIONS_LOADED).sendToTarget(); Loading Loading @@ -207,12 +207,12 @@ public class MultiSimSettingController extends Handler { } /** * Mark mIsAllSubscriptionsLoaded and update defaults and mobile data enabling. * Upon initialization, update defaults and mobile data enabling. * Should only be triggered once. */ @VisibleForTesting public void onAllSubscriptionsLoaded() { if (DBG) log("onAllSubscriptionsLoaded"); mIsAllSubscriptionsLoaded = true; updateDefaults(); disableDataForNonDefaultNonOpportunisticSubscriptions(); } Loading @@ -225,7 +225,7 @@ public class MultiSimSettingController extends Handler { @VisibleForTesting public void onSubscriptionsChanged() { if (DBG) log("onSubscriptionsChanged"); if (!mIsAllSubscriptionsLoaded) return; if (!SubscriptionInfoUpdater.isSubInfoInitialized()) return; updateDefaults(); disableDataForNonDefaultNonOpportunisticSubscriptions(); } Loading Loading @@ -310,7 +310,7 @@ public class MultiSimSettingController extends Handler { public void updateDefaults() { if (DBG) log("updateDefaults"); if (!mIsAllSubscriptionsLoaded) return; if (!SubscriptionInfoUpdater.isSubInfoInitialized()) return; List<SubscriptionInfo> activeSubInfos = mSubController .getActiveSubscriptionInfoList(mContext.getOpPackageName()); Loading Loading @@ -399,6 +399,8 @@ public class MultiSimSettingController extends Handler { } private void disableDataForNonDefaultNonOpportunisticSubscriptions() { if (!SubscriptionInfoUpdater.isSubInfoInitialized()) return; int defaultDataSub = mSubController.getDefaultDataSubId(); // Only disable data for non-default subscription if default sub is active. if (!mSubController.isActiveSubId(defaultDataSub)) { Loading
src/java/com/android/internal/telephony/SubscriptionController.java +17 −42 Original line number Diff line number Diff line Loading @@ -211,27 +211,17 @@ public class SubscriptionController extends ISub.Stub { if (DBG) logdl("[SubscriptionController] init by Context"); } /** * Should only be triggered once. */ public void notifySubInfoReady() { // broadcast default subId. sendDefaultChangedBroadcast(SubscriptionManager.getDefaultSubscriptionId()); } @UnsupportedAppUsage private boolean isSubInfoReady() { if (VDBG) { // make sure sSlotIndexToSubIds is consistent with cached subinfo list int count = 0; for (Integer i : sSlotIndexToSubIds.keySet()) { count += sSlotIndexToSubIds.get(i).size(); } if (count != mCacheActiveSubInfoList.size()) { logdl("mismatch between map and list. list size = " + mCacheActiveSubInfoList.size() + ", map size = " + count); for (Integer i : sSlotIndexToSubIds.keySet()) { logdl("From the Map, subs in map at slot index: " + i + " are: " + sSlotIndexToSubIds.get(i)); } for (SubscriptionInfo info : mCacheActiveSubInfoList) { logdl("From the Cached list, subinfo is: " + info); } } } return sSlotIndexToSubIds.size() > 0; return SubscriptionInfoUpdater.isSubInfoInitialized(); } /** Loading Loading @@ -703,14 +693,6 @@ public class SubscriptionController extends ISub.Stub { */ @VisibleForTesting // For mockito to mock this method public void refreshCachedActiveSubscriptionInfoList() { if (!isSubInfoReady()) { if (DBG_CACHE) { logdl("[refreshCachedActiveSubscriptionInfoList] " + "Sub Controller not ready "); } return; } boolean opptSubListChanged; synchronized (mSubInfoListLock) { Loading Loading @@ -1365,8 +1347,7 @@ public class SubscriptionController extends ISub.Stub { if (DBG) logdl("[clearSubInfoRecord]+ iccId:" + " slotIndex:" + slotIndex); // update simInfo db with invalid slot index List<SubscriptionInfo> oldSubInfo = getSubInfoUsingSlotIndexPrivileged(slotIndex, false); List<SubscriptionInfo> oldSubInfo = getSubInfoUsingSlotIndexPrivileged(slotIndex); ContentResolver resolver = mContext.getContentResolver(); ContentValues value = new ContentValues(1); value.put(SubscriptionManager.SIM_SLOT_INDEX, Loading Loading @@ -2327,8 +2308,7 @@ public class SubscriptionController extends ISub.Stub { /** Must be public for access from instrumentation tests. */ @VisibleForTesting public List<SubscriptionInfo> getSubInfoUsingSlotIndexPrivileged(int slotIndex, boolean needCheck) { public List<SubscriptionInfo> getSubInfoUsingSlotIndexPrivileged(int slotIndex) { if (DBG) logd("[getSubInfoUsingSlotIndexPrivileged]+ slotIndex:" + slotIndex); if (slotIndex == SubscriptionManager.DEFAULT_SIM_SLOT_INDEX) { slotIndex = getSlotIndex(getDefaultSubId()); Loading @@ -2338,11 +2318,6 @@ public class SubscriptionController extends ISub.Stub { return null; } if (needCheck && !isSubInfoReady()) { if (DBG) logd("[getSubInfoUsingSlotIndexPrivileged]- not ready"); return null; } Cursor cursor = mContext.getContentResolver().query(SubscriptionManager.CONTENT_URI, null, SubscriptionManager.SIM_SLOT_INDEX + "=?", new String[]{String.valueOf(slotIndex)}, null); Loading Loading @@ -3467,11 +3442,6 @@ public class SubscriptionController extends ISub.Stub { // They are doing similar things except operating on different cache. private List<SubscriptionInfo> getSubscriptionInfoListFromCacheHelper( String callingPackage, List<SubscriptionInfo> cacheSubList) { if (!isSubInfoReady()) { if (DBG) logd("[getSubscriptionInfoList] Sub Controller not ready"); return null; } boolean canReadAllPhoneState; try { canReadAllPhoneState = TelephonyPermissions.checkReadPhoneState(mContext, Loading Loading @@ -3580,7 +3550,11 @@ public class SubscriptionController extends ISub.Stub { for (SubscriptionInfo info : mCacheOpportunisticSubInfoList) { if (shouldDisableSubGroup(info.getGroupUuid())) { info.setGroupDisabled(true); if (isActiveSubId(info.getSubscriptionId())) { // TODO: move it to ONS. if (isActiveSubId(info.getSubscriptionId()) && isSubInfoReady()) { logd("[refreshCachedOpportunisticSubscriptionInfoList] " + "Deactivating grouped opportunistic subscription " + info.getSubscriptionId()); deactivateSubscription(info); } } Loading Loading @@ -3616,6 +3590,7 @@ public class SubscriptionController extends ISub.Stub { private void deactivateSubscription(SubscriptionInfo info) { // TODO: b/120439488 deactivate pSIM. if (info.isEmbedded()) { logd("[deactivateSubscription] eSIM profile " + info.getSubscriptionId()); EuiccManager euiccManager = (EuiccManager) mContext.getSystemService(Context.EUICC_SERVICE); euiccManager.switchToSubscription(SubscriptionManager.INVALID_SUBSCRIPTION_ID, Loading
src/java/com/android/internal/telephony/SubscriptionInfoUpdater.java +23 −9 Original line number Diff line number Diff line Loading @@ -108,6 +108,7 @@ public class SubscriptionInfoUpdater extends Handler { private static String mIccId[] = new String[PROJECT_SIM_NUM]; private static int[] sSimCardState = new int[PROJECT_SIM_NUM]; private static int[] sSimApplicationState = new int[PROJECT_SIM_NUM]; private static boolean sIsSubInfoInitialized = false; private SubscriptionManager mSubscriptionManager = null; private EuiccManager mEuiccManager; @UnsupportedAppUsage Loading Loading @@ -420,7 +421,7 @@ public class SubscriptionInfoUpdater extends Handler { updateSubscriptionInfoByIccId(slotId); List<SubscriptionInfo> subscriptionInfos = SubscriptionController.getInstance() .getSubInfoUsingSlotIndexPrivileged(slotId, false); .getSubInfoUsingSlotIndexPrivileged(slotId); if (subscriptionInfos == null || subscriptionInfos.isEmpty()) { loge("empty subinfo for slotId: " + slotId + "could not update ContentResolver"); } else { Loading Loading @@ -587,7 +588,7 @@ public class SubscriptionInfoUpdater extends Handler { } List<SubscriptionInfo> subInfos = SubscriptionController.getInstance() .getSubInfoUsingSlotIndexPrivileged(slotIndex, false); .getSubInfoUsingSlotIndexPrivileged(slotIndex); if (subInfos != null) { boolean changed = false; for (int i = 0; i < subInfos.size(); i++) { Loading Loading @@ -629,17 +630,30 @@ public class SubscriptionInfoUpdater extends Handler { uiccSlot.getUiccCard().getCardId())) .forEach(cardId -> updateEmbeddedSubscriptions(cardId)); } // update default subId MultiSimSettingController.getInstance().notifyAllSubscriptionLoaded(); // broadcast default subId SubscriptionController.getInstance().sendDefaultChangedBroadcast( SubscriptionManager.getDefaultSubscriptionId()); setSubInfoInitialized(); } SubscriptionController.getInstance().notifySubscriptionInfoChanged(); logd("updateSubscriptionInfoByIccId:- SubscriptionInfo update complete"); } private static void setSubInfoInitialized() { // Should only be triggered once. if (!sIsSubInfoInitialized) { if (DBG) logd("SubInfo Initialized"); sIsSubInfoInitialized = true; SubscriptionController.getInstance().notifySubInfoReady(); MultiSimSettingController.getInstance().notifyAllSubscriptionLoaded(); } } /** * Whether subscriptions of all SIMs are initialized. */ public static boolean isSubInfoInitialized() { return sIsSubInfoInitialized; } /** * Update the cached list of embedded subscription for the eUICC with the given card ID * {@code cardId}. Loading Loading @@ -1013,11 +1027,11 @@ public class SubscriptionInfoUpdater extends Handler { } @UnsupportedAppUsage private void logd(String message) { private static void logd(String message) { Rlog.d(LOG_TAG, message); } private void loge(String message) { private static void loge(String message) { Rlog.e(LOG_TAG, message); } Loading
tests/telephonytests/src/com/android/internal/telephony/SubscriptionInfoUpdaterTest.java +27 −9 Original line number Diff line number Diff line Loading @@ -23,7 +23,6 @@ import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; import static org.mockito.ArgumentMatchers.isNull; import static org.mockito.Mockito.any; import static org.mockito.Mockito.anyBoolean; import static org.mockito.Mockito.anyInt; import static org.mockito.Mockito.anyString; import static org.mockito.Mockito.doReturn; Loading Loading @@ -56,6 +55,7 @@ import android.test.suitebuilder.annotation.SmallTest; import com.android.internal.telephony.euicc.EuiccController; import com.android.internal.telephony.uicc.IccFileHandler; import com.android.internal.telephony.uicc.IccRecords; import com.android.internal.telephony.uicc.UiccSlot; import org.junit.After; import org.junit.Before; Loading Loading @@ -98,6 +98,8 @@ public class SubscriptionInfoUpdaterTest extends TelephonyTest { private IntentBroadcaster mIntentBroadcaster; @Mock private IPackageManager mPackageManager; @Mock private UiccSlot mUiccSlot; /*Custom ContentProvider */ private class FakeSubscriptionContentProvider extends MockContentProvider { Loading Loading @@ -130,10 +132,13 @@ public class SubscriptionInfoUpdaterTest extends TelephonyTest { replaceInstance(SubscriptionInfoUpdater.class, "PROJECT_SIM_NUM", null, 1); replaceInstance(SubscriptionInfoUpdater.class, "sSimCardState", null, new int[1]); replaceInstance(SubscriptionInfoUpdater.class, "sSimApplicationState", null, new int[1]); replaceInstance(SubscriptionInfoUpdater.class, "sIsSubInfoInitialized", null, false); replaceInstance(EuiccController.class, "sInstance", null, mEuiccController); replaceInstance(IntentBroadcaster.class, "sIntentBroadcaster", null, mIntentBroadcaster); doReturn(true).when(mUiccSlot).isActive(); doReturn(mUiccSlot).when(mUiccController).getUiccSlotForPhone(anyInt()); doReturn(1).when(mTelephonyManager).getSimCount(); doReturn(1).when(mTelephonyManager).getPhoneCount(); Loading Loading @@ -162,6 +167,8 @@ public class SubscriptionInfoUpdaterTest extends TelephonyTest { mSubscriptionInfoUpdaterHandlerThread = new SubscriptionInfoUpdaterHandlerThread(TAG); mSubscriptionInfoUpdaterHandlerThread.start(); waitUntilReady(); assertFalse(mUpdater.isSubInfoInitialized()); } @After Loading @@ -174,13 +181,14 @@ public class SubscriptionInfoUpdaterTest extends TelephonyTest { @SmallTest public void testSimAbsent() throws Exception { doReturn(Arrays.asList(mSubInfo)).when(mSubscriptionController) .getSubInfoUsingSlotIndexPrivileged(eq(FAKE_SUB_ID_1), anyBoolean()); .getSubInfoUsingSlotIndexPrivileged(eq(FAKE_SUB_ID_1)); doReturn(new int[]{FAKE_SUB_ID_1}).when(mSubscriptionController) .getActiveSubIdList(/*visibleOnly*/false); mUpdater.updateInternalIccState( IccCardConstants.INTENT_VALUE_ICC_ABSENT, null, FAKE_SUB_ID_1, false); waitForMs(100); assertTrue(mUpdater.isSubInfoInitialized()); verify(mSubscriptionController, times(1)).clearSubInfoRecord(eq(FAKE_SUB_ID_1)); CarrierConfigManager mConfigManager = (CarrierConfigManager) Loading @@ -194,13 +202,14 @@ public class SubscriptionInfoUpdaterTest extends TelephonyTest { @SmallTest public void testSimAbsentAndInactive() throws Exception { doReturn(Arrays.asList(mSubInfo)).when(mSubscriptionController) .getSubInfoUsingSlotIndexPrivileged(eq(FAKE_SUB_ID_1), anyBoolean()); .getSubInfoUsingSlotIndexPrivileged(eq(FAKE_SUB_ID_1)); doReturn(new int[]{FAKE_SUB_ID_1}).when(mSubscriptionController) .getActiveSubIdList(/*visibleOnly*/false); mUpdater.updateInternalIccState( IccCardConstants.INTENT_VALUE_ICC_ABSENT, null, FAKE_SUB_ID_1, true); waitForMs(100); assertTrue(mUpdater.isSubInfoInitialized()); verify(mSubscriptionController, times(1)).clearSubInfoRecord(eq(FAKE_SUB_ID_1)); // Verify that in the special absent and inactive case, we update subscriptions without Loading @@ -220,6 +229,7 @@ public class SubscriptionInfoUpdaterTest extends TelephonyTest { IccCardConstants.INTENT_VALUE_ICC_UNKNOWN, null, FAKE_SUB_ID_1, false); waitForMs(100); assertFalse(mUpdater.isSubInfoInitialized()); verify(mSubscriptionContent, times(0)).put(anyString(), any()); CarrierConfigManager mConfigManager = (CarrierConfigManager) mContext.getSystemService(Context.CARRIER_CONFIG_SERVICE); Loading @@ -236,6 +246,7 @@ public class SubscriptionInfoUpdaterTest extends TelephonyTest { IccCardConstants.INTENT_VALUE_ICC_CARD_IO_ERROR, null, FAKE_SUB_ID_1, false); waitForMs(100); assertTrue(mUpdater.isSubInfoInitialized()); verify(mSubscriptionContent, times(0)).put(anyString(), any()); CarrierConfigManager mConfigManager = (CarrierConfigManager) mContext.getSystemService(Context.CARRIER_CONFIG_SERVICE); Loading @@ -252,6 +263,7 @@ public class SubscriptionInfoUpdaterTest extends TelephonyTest { IccCardConstants.INTENT_VALUE_ICC_IMSI, null, 2, false); waitForMs(100); assertFalse(mUpdater.isSubInfoInitialized()); verify(mSubscriptionContent, times(0)).put(anyString(), any()); CarrierConfigManager mConfigManager = (CarrierConfigManager) mContext.getSystemService(Context.CARRIER_CONFIG_SERVICE); Loading @@ -266,7 +278,7 @@ public class SubscriptionInfoUpdaterTest extends TelephonyTest { public void testSimLoaded() throws Exception { doReturn(FAKE_SUB_ID_1).when(mSubInfo).getSubscriptionId(); doReturn(Arrays.asList(mSubInfo)).when(mSubscriptionController) .getSubInfoUsingSlotIndexPrivileged(eq(FAKE_SUB_ID_1), anyBoolean()); .getSubInfoUsingSlotIndexPrivileged(eq(FAKE_SUB_ID_1)); doReturn("89012604200000000000").when(mIccRecord).getFullIccId(); doReturn(FAKE_MCC_MNC_1).when(mTelephonyManager).getSimOperatorNumeric(FAKE_SUB_ID_1); Loading @@ -274,6 +286,7 @@ public class SubscriptionInfoUpdaterTest extends TelephonyTest { IccCardConstants.INTENT_VALUE_ICC_LOADED, null, FAKE_SUB_ID_1, false); waitForMs(100); assertTrue(mUpdater.isSubInfoInitialized()); // verify SIM_STATE_CHANGED broadcast. It should be broadcast twice, once for // READ_PHONE_STATE and once for READ_PRIVILEGED_PHONE_STATE Loading Loading @@ -334,11 +347,12 @@ public class SubscriptionInfoUpdaterTest extends TelephonyTest { 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()); .getSubInfoUsingSlotIndexPrivileged(eq(FAKE_SUB_ID_1)); mUpdater.updateInternalIccState( IccCardConstants.INTENT_VALUE_ICC_LOADED, null, FAKE_SUB_ID_1, false); waitForMs(300); assertTrue(mUpdater.isSubInfoInitialized()); SubscriptionManager mSubscriptionManager = SubscriptionManager.from(mContext); verify(mTelephonyManager).getSimOperatorNumeric(FAKE_SUB_ID_1); verify(mSubscriptionManager, times(1)).addSubscriptionInfoRecord( Loading @@ -360,12 +374,13 @@ public class SubscriptionInfoUpdaterTest extends TelephonyTest { doReturn("98106240020000000000").when(mIccRecord).getFullIccId(); doReturn(Arrays.asList(mSubInfo)).when(mSubscriptionController) .getSubInfoUsingSlotIndexPrivileged(eq(FAKE_SUB_ID_1), anyBoolean()); .getSubInfoUsingSlotIndexPrivileged(eq(FAKE_SUB_ID_1)); mUpdater.updateInternalIccState( IccCardConstants.INTENT_VALUE_ICC_LOCKED, "TESTING", FAKE_SUB_ID_1, false); waitForMs(100); assertTrue(mUpdater.isSubInfoInitialized()); SubscriptionManager mSubscriptionManager = SubscriptionManager.from(mContext); verify(mSubscriptionManager, times(1)).addSubscriptionInfoRecord( eq("98106240020000000000"), eq(FAKE_SUB_ID_1)); Loading Loading @@ -408,7 +423,7 @@ public class SubscriptionInfoUpdaterTest extends TelephonyTest { // Mock sending a sim loaded for SIM 1 doReturn(Arrays.asList(mSubInfo)).when(mSubscriptionController) .getSubInfoUsingSlotIndexPrivileged(eq(FAKE_SUB_ID_1), anyBoolean()); .getSubInfoUsingSlotIndexPrivileged(eq(FAKE_SUB_ID_1)); mUpdater.updateInternalIccState( IccCardConstants.INTENT_VALUE_ICC_LOADED, null, FAKE_SUB_ID_1, false); Loading @@ -417,10 +432,11 @@ public class SubscriptionInfoUpdaterTest extends TelephonyTest { verify(mSubscriptionManager, times(1)).addSubscriptionInfoRecord(anyString(), anyInt()); verify(mSubscriptionController, times(1)).notifySubscriptionInfoChanged(); verify(mSubscriptionController, times(1)).setMccMnc(anyString(), anyInt()); assertFalse(mUpdater.isSubInfoInitialized()); // Mock sending a sim loaded for SIM 2 doReturn(Arrays.asList(mSubInfo)).when(mSubscriptionController) .getSubInfoUsingSlotIndexPrivileged(eq(FAKE_SUB_ID_2), anyBoolean()); .getSubInfoUsingSlotIndexPrivileged(eq(FAKE_SUB_ID_2)); doReturn(FAKE_SUB_ID_2).when(mSubInfo).getSubscriptionId(); doReturn("89012604200000000001").when(mIccRecord).getFullIccId(); Loading @@ -436,6 +452,7 @@ public class SubscriptionInfoUpdaterTest extends TelephonyTest { 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(2)).notifySubscriptionInfoChanged(); assertTrue(mUpdater.isSubInfoInitialized()); } @Test Loading @@ -451,6 +468,7 @@ public class SubscriptionInfoUpdaterTest extends TelephonyTest { waitForMs(100); assertTrue(mUpdater.isSubInfoInitialized()); SubscriptionManager mSubscriptionManager = SubscriptionManager.from(mContext); verify(mSubscriptionManager, times(1)).addSubscriptionInfoRecord( anyString(), eq(FAKE_SUB_ID_1)); Loading Loading @@ -582,7 +600,7 @@ public class SubscriptionInfoUpdaterTest extends TelephonyTest { @SmallTest public void testHexIccIdSuffix() throws Exception { doReturn(null).when(mSubscriptionController) .getSubInfoUsingSlotIndexPrivileged(anyInt(), anyBoolean()); .getSubInfoUsingSlotIndexPrivileged(anyInt()); verify(mSubscriptionController, times(0)).clearSubInfo(); doReturn("890126042000000000Ff").when(mIccRecord).getFullIccId(); Loading
tests/telephonytests/src/com/android/internal/telephony/TelephonyTest.java +1 −0 Original line number Diff line number Diff line Loading @@ -563,6 +563,7 @@ public abstract class TelephonyTest { mCellularNetworkValidator); replaceInstance(MultiSimSettingController.class, "sInstance", null, mMultiSimSettingController); replaceInstance(SubscriptionInfoUpdater.class, "sIsSubInfoInitialized", null, true); assertNotNull("Failed to set up SubscriptionController singleton", SubscriptionController.getInstance()); Loading