blob: 33782b2b642da05afc8d554fb00a4c04600869f9 [file] [log] [blame]
/*
* Copyright (C) 2016 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.internal.telephony;
import static com.android.internal.telephony.TelephonyTestUtils.waitForMs;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
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;
import static org.mockito.Mockito.eq;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import android.content.ContentProvider;
import android.content.ContentValues;
import android.content.Context;
import android.content.Intent;
import android.content.pm.UserInfo;
import android.net.Uri;
import android.os.HandlerThread;
import android.service.euicc.EuiccProfileInfo;
import android.service.euicc.EuiccService;
import android.service.euicc.GetEuiccProfileInfoListResult;
import android.telephony.CarrierConfigManager;
import android.telephony.SubscriptionInfo;
import android.telephony.SubscriptionManager;
import android.test.mock.MockContentProvider;
import android.test.mock.MockContentResolver;
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 org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.mockito.ArgumentCaptor;
import org.mockito.Mock;
import org.mockito.invocation.InvocationOnMock;
import org.mockito.stubbing.Answer;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
public class SubscriptionInfoUpdaterTest extends TelephonyTest {
private static final int FAKE_SUB_ID_1 = 0;
private static final int FAKE_SUB_ID_2 = 1;
private static final String FAKE_MCC_MNC_1 = "123456";
private static final String FAKE_MCC_MNC_2 = "456789";
private SubscriptionInfoUpdaterHandlerThread mSubscriptionInfoUpdaterHandlerThread;
private SubscriptionInfoUpdater mUpdater;
private IccRecords mIccRecord;
@Mock
private UserInfo mUserInfo;
@Mock
private SubscriptionInfo mSubInfo;
@Mock
private ContentProvider mContentProvider;
@Mock
private HashMap<String, Object> mSubscriptionContent;
@Mock
private IccFileHandler mIccFileHandler;
@Mock
private EuiccController mEuiccController;
@Mock
private IntentBroadcaster mIntentBroadcaster;
/*Custom ContentProvider */
private class FakeSubscriptionContentProvider extends MockContentProvider {
@Override
public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) {
return mContentProvider.update(uri, values, selection, selectionArgs);
}
}
private class SubscriptionInfoUpdaterHandlerThread extends HandlerThread {
private SubscriptionInfoUpdaterHandlerThread(String name) {
super(name);
}
@Override
public void onLooperPrepared() {
mUpdater = new SubscriptionInfoUpdater(getLooper(), mContext, new Phone[]{mPhone},
new CommandsInterface[]{mSimulatedCommands});
setReady(true);
}
}
@Before
public void setUp() throws Exception {
super.setUp(this.getClass().getSimpleName());
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, "PROJECT_SIM_NUM", null, 1);
replaceInstance(SubscriptionInfoUpdater.class, "sSimCardState", null, new int[1]);
replaceInstance(SubscriptionInfoUpdater.class, "sSimApplicationState", null, new int[1]);
replaceInstance(EuiccController.class, "sInstance", null, mEuiccController);
replaceInstance(IntentBroadcaster.class, "sIntentBroadcaster", null, mIntentBroadcaster);
doReturn(1).when(mTelephonyManager).getSimCount();
doReturn(1).when(mTelephonyManager).getPhoneCount();
when(mContentProvider.update(any(), any(), any(), isNull())).thenAnswer(
new Answer<Integer>() {
@Override
public Integer answer(InvocationOnMock invocation) throws Throwable {
ContentValues values = invocation.getArgument(1);
for (String key : values.keySet()) {
mSubscriptionContent.put(key, values.get(key));
}
return 1;
}
});
doReturn(mUserInfo).when(mIActivityManager).getCurrentUser();
doReturn(new int[]{FAKE_SUB_ID_1}).when(mSubscriptionController).getSubId(0);
doReturn(new int[]{FAKE_SUB_ID_1}).when(mSubscriptionManager).getActiveSubscriptionIdList();
((MockContentResolver) mContext.getContentResolver()).addProvider(
SubscriptionManager.CONTENT_URI.getAuthority(),
new FakeSubscriptionContentProvider());
doReturn(new int[]{}).when(mSubscriptionController).getActiveSubIdList();
mIccRecord = mUiccProfile.getIccRecords();
mSubscriptionInfoUpdaterHandlerThread = new SubscriptionInfoUpdaterHandlerThread(TAG);
mSubscriptionInfoUpdaterHandlerThread.start();
waitUntilReady();
}
@After
public void tearDown() throws Exception {
mSubscriptionInfoUpdaterHandlerThread.quit();
super.tearDown();
}
@Test
@SmallTest
public void testSimAbsent() throws Exception {
doReturn(Arrays.asList(mSubInfo)).when(mSubscriptionController)
.getSubInfoUsingSlotIndexPrivileged(eq(FAKE_SUB_ID_1), anyBoolean());
doReturn(new int[]{FAKE_SUB_ID_1}).when(mSubscriptionController).getActiveSubIdList();
mUpdater.updateInternalIccState(
IccCardConstants.INTENT_VALUE_ICC_ABSENT, null, FAKE_SUB_ID_1);
waitForMs(100);
verify(mSubscriptionContent).put(eq(SubscriptionManager.SIM_SLOT_INDEX),
eq(SubscriptionManager.INVALID_SIM_SLOT_INDEX));
CarrierConfigManager mConfigManager = (CarrierConfigManager)
mContext.getSystemService(Context.CARRIER_CONFIG_SERVICE);
verify(mConfigManager).updateConfigForPhoneId(eq(FAKE_SUB_ID_1),
eq(IccCardConstants.INTENT_VALUE_ICC_ABSENT));
verify(mSubscriptionController, times(1)).clearSubInfo();
verify(mSubscriptionController, times(1)).notifySubscriptionInfoChanged();
}
@Test
@SmallTest
public void testSimUnknown() throws Exception {
mUpdater.updateInternalIccState(
IccCardConstants.INTENT_VALUE_ICC_UNKNOWN, null, FAKE_SUB_ID_1);
waitForMs(100);
verify(mSubscriptionContent, times(0)).put(anyString(), any());
CarrierConfigManager mConfigManager = (CarrierConfigManager)
mContext.getSystemService(Context.CARRIER_CONFIG_SERVICE);
verify(mConfigManager).updateConfigForPhoneId(eq(FAKE_SUB_ID_1),
eq(IccCardConstants.INTENT_VALUE_ICC_UNKNOWN));
verify(mSubscriptionController, times(0)).clearSubInfo();
verify(mSubscriptionController, times(0)).notifySubscriptionInfoChanged();
}
@Test
@SmallTest
public void testSimError() throws Exception {
mUpdater.updateInternalIccState(
IccCardConstants.INTENT_VALUE_ICC_CARD_IO_ERROR, null, FAKE_SUB_ID_1);
waitForMs(100);
verify(mSubscriptionContent, times(0)).put(anyString(), any());
CarrierConfigManager mConfigManager = (CarrierConfigManager)
mContext.getSystemService(Context.CARRIER_CONFIG_SERVICE);
verify(mConfigManager).updateConfigForPhoneId(eq(FAKE_SUB_ID_1),
eq(IccCardConstants.INTENT_VALUE_ICC_CARD_IO_ERROR));
verify(mSubscriptionController, times(0)).clearSubInfo();
verify(mSubscriptionController, times(1)).notifySubscriptionInfoChanged();
}
@Test
@SmallTest
public void testWrongSimState() throws Exception {
mUpdater.updateInternalIccState(
IccCardConstants.INTENT_VALUE_ICC_IMSI, null, 2);
waitForMs(100);
verify(mSubscriptionContent, times(0)).put(anyString(), any());
CarrierConfigManager mConfigManager = (CarrierConfigManager)
mContext.getSystemService(Context.CARRIER_CONFIG_SERVICE);
verify(mConfigManager, times(0)).updateConfigForPhoneId(eq(2),
eq(IccCardConstants.INTENT_VALUE_ICC_IMSI));
verify(mSubscriptionController, times(0)).clearSubInfo();
verify(mSubscriptionController, times(0)).notifySubscriptionInfoChanged();
}
@Test
@SmallTest
public void testSimLoaded() 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(FAKE_MCC_MNC_1).when(mTelephonyManager).getSimOperatorNumeric(FAKE_SUB_ID_1);
mUpdater.updateInternalIccState(
IccCardConstants.INTENT_VALUE_ICC_LOADED, null, FAKE_SUB_ID_1);
waitForMs(100);
// verify SIM_STATE_CHANGED broadcast. It should be broadcast twice, once for
// READ_PHONE_STATE and once for READ_PRIVILEGED_PHONE_STATE
/* todo: cannot verify as intent is sent using ActivityManagerNative.broadcastStickyIntent()
* uncomment code below when that is fixed
*/
/* ArgumentCaptor<Intent> intentArgumentCaptor = ArgumentCaptor.forClass(Intent.class);
ArgumentCaptor<String> stringArgumentCaptor = ArgumentCaptor.forClass(String.class);
verify(mContext, times(2)).sendBroadcast(intentArgumentCaptor.capture(),
stringArgumentCaptor.capture());
assertEquals(TelephonyIntents.ACTION_SIM_STATE_CHANGED,
intentArgumentCaptor.getAllValues().get(0).getAction());
assertEquals(Manifest.permission.READ_PHONE_STATE,
stringArgumentCaptor.getAllValues().get(0));
assertEquals(TelephonyIntents.ACTION_SIM_STATE_CHANGED,
intentArgumentCaptor.getAllValues().get(1).getAction());
assertEquals(Manifest.permission.READ_PRIVILEGED_PHONE_STATE,
stringArgumentCaptor.getAllValues().get(1)); */
SubscriptionManager mSubscriptionManager = SubscriptionManager.from(mContext);
verify(mTelephonyManager).getSimOperatorNumeric(FAKE_SUB_ID_1);
verify(mSubscriptionManager, times(1)).addSubscriptionInfoRecord(
eq("89012604200000000000"), eq(FAKE_SUB_ID_1));
verify(mSubscriptionController, times(1)).notifySubscriptionInfoChanged();
verify(mSubscriptionController, times(1)).setMccMnc(FAKE_MCC_MNC_1, FAKE_SUB_ID_1);
verify(mSubscriptionController, times(0)).clearSubInfo();
CarrierConfigManager mConfigManager = (CarrierConfigManager)
mContext.getSystemService(Context.CARRIER_CONFIG_SERVICE);
verify(mConfigManager, times(1)).updateConfigForPhoneId(eq(FAKE_SUB_ID_1),
eq(IccCardConstants.INTENT_VALUE_ICC_LOADED));
// ACTION_USER_UNLOCKED should trigger another SIM_STATE_CHANGED
Intent intentSimStateChanged = new Intent(Intent.ACTION_USER_UNLOCKED);
mContext.sendBroadcast(intentSimStateChanged);
waitForMs(100);
// verify SIM_STATE_CHANGED broadcast
/* todo: cannot verify as intent is sent using ActivityManagerNative.broadcastStickyIntent()
* uncomment code below when that is fixed
*/
/* verify(mContext, times(4)).sendBroadcast(intentArgumentCaptor.capture(),
stringArgumentCaptor.capture());
assertEquals(TelephonyIntents.ACTION_SIM_STATE_CHANGED,
intentArgumentCaptor.getAllValues().get(2).getAction());
assertEquals(Manifest.permission.READ_PHONE_STATE,
stringArgumentCaptor.getAllValues().get(2));
assertEquals(TelephonyIntents.ACTION_SIM_STATE_CHANGED,
intentArgumentCaptor.getAllValues().get(3).getAction());
assertEquals(Manifest.permission.READ_PRIVILEGED_PHONE_STATE,
stringArgumentCaptor.getAllValues().get(3)); */
}
@Test
@SmallTest
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();
// operator numeric is empty
doReturn("").when(mTelephonyManager).getSimOperatorNumeric(FAKE_SUB_ID_1);
mUpdater.updateInternalIccState(
IccCardConstants.INTENT_VALUE_ICC_LOADED, null, FAKE_SUB_ID_1);
waitForMs(100);
SubscriptionManager mSubscriptionManager = SubscriptionManager.from(mContext);
verify(mTelephonyManager).getSimOperatorNumeric(FAKE_SUB_ID_1);
verify(mSubscriptionManager, times(1)).addSubscriptionInfoRecord(
eq("89012604200000000000"), eq(FAKE_SUB_ID_1));
verify(mSubscriptionController, times(1)).notifySubscriptionInfoChanged();
verify(mSubscriptionController, times(0)).setMccMnc(anyString(), anyInt());
verify(mSubscriptionController, times(0)).clearSubInfo();
CarrierConfigManager mConfigManager = (CarrierConfigManager)
mContext.getSystemService(Context.CARRIER_CONFIG_SERVICE);
verify(mConfigManager, times(1)).updateConfigForPhoneId(eq(FAKE_SUB_ID_1),
eq(IccCardConstants.INTENT_VALUE_ICC_LOADED));
}
@Test
@SmallTest
public void testSimLockedWithOutIccId() throws Exception {
/* mock no IccId Info present and try to query IccId
after IccId query, update subscriptionDB */
doReturn("98106240020000000000").when(mIccRecord).getFullIccId();
doReturn(Arrays.asList(mSubInfo)).when(mSubscriptionController)
.getSubInfoUsingSlotIndexPrivileged(eq(FAKE_SUB_ID_1), anyBoolean());
mUpdater.updateInternalIccState(
IccCardConstants.INTENT_VALUE_ICC_LOCKED, "TESTING", FAKE_SUB_ID_1);
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);
verify(mSubscriptionManager, times(1)).addSubscriptionInfoRecord(
eq("98106240020000000000"), eq(FAKE_SUB_ID_1));
verify(mSubscriptionController, times(1)).notifySubscriptionInfoChanged();
verify(mSubscriptionController, times(0)).clearSubInfo();
CarrierConfigManager mConfigManager = (CarrierConfigManager)
mContext.getSystemService(Context.CARRIER_CONFIG_SERVICE);
verify(mConfigManager, times(1)).updateConfigForPhoneId(eq(FAKE_SUB_ID_1),
eq(IccCardConstants.INTENT_VALUE_ICC_LOCKED));
}
@Test
@SmallTest
public void testDualSimLoaded() throws Exception {
// Mock there is two sim cards
replaceInstance(SubscriptionInfoUpdater.class, "mIccId", null,
new String[]{null, null});
replaceInstance(SubscriptionInfoUpdater.class, "PROJECT_SIM_NUM", null, 2);
replaceInstance(SubscriptionInfoUpdater.class, "mPhone", null,
new Phone[]{mPhone, mPhone});
replaceInstance(SubscriptionInfoUpdater.class, "mInsertSimState", null,
new int[]{SubscriptionInfoUpdater.SIM_NOT_CHANGE,
SubscriptionInfoUpdater.SIM_NOT_CHANGE});
replaceInstance(SubscriptionInfoUpdater.class, "sSimCardState", null,
new int[]{0, 0});
replaceInstance(SubscriptionInfoUpdater.class, "sSimApplicationState", null,
new int[]{0, 0});
doReturn(new int[]{FAKE_SUB_ID_1, FAKE_SUB_ID_2}).when(mSubscriptionManager)
.getActiveSubscriptionIdList();
doReturn(FAKE_SUB_ID_1).when(mSubscriptionController).getPhoneId(eq(FAKE_SUB_ID_1));
doReturn(FAKE_SUB_ID_2).when(mSubscriptionController).getPhoneId(eq(FAKE_SUB_ID_2));
doReturn(2).when(mTelephonyManager).getSimCount();
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));
// Mock there is no sim inserted before
doReturn(null).when(mSubscriptionController)
.getSubInfoUsingSlotIndexPrivileged(anyInt(), anyBoolean());
verify(mSubscriptionController, times(0)).clearSubInfo();
doReturn("89012604200000000000").when(mIccRecord).getFullIccId();
// Mock sending a sim loaded for SIM 1
mUpdater.updateInternalIccState(
IccCardConstants.INTENT_VALUE_ICC_LOADED, null, FAKE_SUB_ID_1);
waitForMs(100);
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 2
doReturn("89012604200000000001").when(mIccRecord).getFullIccId();
mUpdater.updateInternalIccState(
IccCardConstants.INTENT_VALUE_ICC_LOADED, null, FAKE_SUB_ID_2);
waitForMs(100);
verify(mSubscriptionManager, times(1)).addSubscriptionInfoRecord(eq("89012604200000000000"),
eq(FAKE_SUB_ID_1));
verify(mSubscriptionManager, times(1)).addSubscriptionInfoRecord(eq("89012604200000000001"),
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_2), eq(FAKE_SUB_ID_2));
verify(mSubscriptionController, times(0)).clearSubInfo();
verify(mSubscriptionController, times(1)).notifySubscriptionInfoChanged();
}
@Test
@SmallTest
public void testSimLockWithIccId() throws Exception {
/* no need for IccId query */
replaceInstance(SubscriptionInfoUpdater.class, "mIccId", null,
new String[]{"89012604200000000000"});
mUpdater.updateInternalIccState(
IccCardConstants.INTENT_VALUE_ICC_LOCKED, "TESTING", FAKE_SUB_ID_1);
waitForMs(100);
SubscriptionManager mSubscriptionManager = SubscriptionManager.from(mContext);
verify(mSubscriptionManager, times(1)).addSubscriptionInfoRecord(
anyString(), eq(FAKE_SUB_ID_1));
verify(mSubscriptionController, times(1)).notifySubscriptionInfoChanged();
verify(mSubscriptionController, times(0)).clearSubInfo();
CarrierConfigManager mConfigManager = (CarrierConfigManager)
mContext.getSystemService(Context.CARRIER_CONFIG_SERVICE);
/* broadcast is done */
verify(mConfigManager, times(1)).updateConfigForPhoneId(eq(FAKE_SUB_ID_1),
eq(IccCardConstants.INTENT_VALUE_ICC_LOCKED));
}
@Test
@SmallTest
public void testUpdateEmbeddedSubscriptions_listSuccess() throws Exception {
when(mEuiccManager.isEnabled()).thenReturn(true);
EuiccProfileInfo[] euiccProfiles = new EuiccProfileInfo[] {
new EuiccProfileInfo("1", null /* accessRules */, null /* nickname */),
new EuiccProfileInfo("3", null /* accessRules */, null /* nickname */),
};
when(mEuiccController.blockingGetEuiccProfileInfoList()).thenReturn(
new GetEuiccProfileInfoListResult(
EuiccService.RESULT_OK, euiccProfiles, false /* removable */));
List<SubscriptionInfo> subInfoList = new ArrayList<>();
// 1: not embedded, but has matching iccid with an embedded subscription.
subInfoList.add(new SubscriptionInfo(
0, "1", 0, "", "", 0, 0, "", 0, null, "0", "0", "", false /* isEmbedded */,
null /* accessRules */));
// 2: embedded but no longer present.
subInfoList.add(new SubscriptionInfo(
0, "2", 0, "", "", 0, 0, "", 0, null, "0", "0", "", true /* isEmbedded */,
null /* accessRules */));
when(mSubscriptionController.getSubscriptionInfoListForEmbeddedSubscriptionUpdate(
new String[] { "1", "3"}, false /* removable */)).thenReturn(subInfoList);
assertTrue(mUpdater.updateEmbeddedSubscriptions());
// 3 is new and so a new entry should have been created.
verify(mSubscriptionController).insertEmptySubInfoRecord(
"3", SubscriptionManager.SIM_NOT_INSERTED);
// 1 already existed, so no new entries should be created for it.
verify(mSubscriptionController, times(0)).clearSubInfo();
verify(mSubscriptionController, never()).insertEmptySubInfoRecord(eq("1"), anyInt());
// Info for 1 and 3 should be updated as active embedded subscriptions.
ArgumentCaptor<ContentValues> iccid1Values = ArgumentCaptor.forClass(ContentValues.class);
verify(mContentProvider).update(eq(SubscriptionManager.CONTENT_URI), iccid1Values.capture(),
eq(SubscriptionManager.ICC_ID + "=\"1\""), isNull());
assertEquals(1,
iccid1Values.getValue().getAsInteger(SubscriptionManager.IS_EMBEDDED).intValue());
ArgumentCaptor<ContentValues> iccid3Values = ArgumentCaptor.forClass(ContentValues.class);
verify(mContentProvider).update(eq(SubscriptionManager.CONTENT_URI), iccid3Values.capture(),
eq(SubscriptionManager.ICC_ID + "=\"3\""), isNull());
assertEquals(1,
iccid3Values.getValue().getAsInteger(SubscriptionManager.IS_EMBEDDED).intValue());
// 2 should have been removed since it was returned from the cache but was not present
// in the list provided by the LPA.
ArgumentCaptor<ContentValues> iccid2Values = ArgumentCaptor.forClass(ContentValues.class);
verify(mContentProvider).update(eq(SubscriptionManager.CONTENT_URI), iccid2Values.capture(),
eq(SubscriptionManager.ICC_ID + " IN (\"2\")"), isNull());
assertEquals(0,
iccid2Values.getValue().getAsInteger(SubscriptionManager.IS_EMBEDDED).intValue());
}
@Test
@SmallTest
public void testUpdateEmbeddedSubscriptions_listFailure() throws Exception {
when(mEuiccManager.isEnabled()).thenReturn(true);
when(mEuiccController.blockingGetEuiccProfileInfoList())
.thenReturn(new GetEuiccProfileInfoListResult(
42, null /* subscriptions */, false /* removable */));
List<SubscriptionInfo> subInfoList = new ArrayList<>();
// 1: not embedded, but has matching iccid with an embedded subscription.
subInfoList.add(new SubscriptionInfo(
0, "1", 0, "", "", 0, 0, "", 0, null, "0", "0", "", false /* isEmbedded */,
null /* accessRules */));
// 2: embedded.
subInfoList.add(new SubscriptionInfo(
0, "2", 0, "", "", 0, 0, "", 0, null, "0", "0", "", true /* isEmbedded */,
null /* accessRules */));
when(mSubscriptionController.getSubscriptionInfoListForEmbeddedSubscriptionUpdate(
new String[0], false /* removable */)).thenReturn(subInfoList);
assertTrue(mUpdater.updateEmbeddedSubscriptions());
// No new entries should be created.
verify(mSubscriptionController, times(0)).clearSubInfo();
verify(mSubscriptionController, never()).insertEmptySubInfoRecord(anyString(), anyInt());
// 1 should not have been touched.
verify(mContentProvider, never()).update(eq(SubscriptionManager.CONTENT_URI), any(),
eq(SubscriptionManager.ICC_ID + "=\"1\""), isNull());
verify(mContentProvider, never()).update(eq(SubscriptionManager.CONTENT_URI), any(),
eq(SubscriptionManager.ICC_ID + "IN (\"1\")"), isNull());
// 2 should have been removed since it was returned from the cache but the LPA had an
// error when listing.
ArgumentCaptor<ContentValues> iccid2Values = ArgumentCaptor.forClass(ContentValues.class);
verify(mContentProvider).update(eq(SubscriptionManager.CONTENT_URI), iccid2Values.capture(),
eq(SubscriptionManager.ICC_ID + " IN (\"2\")"), isNull());
assertEquals(0,
iccid2Values.getValue().getAsInteger(SubscriptionManager.IS_EMBEDDED).intValue());
}
@Test
@SmallTest
public void testUpdateEmbeddedSubscriptions_emptyToEmpty() throws Exception {
when(mEuiccManager.isEnabled()).thenReturn(true);
when(mEuiccController.blockingGetEuiccProfileInfoList())
.thenReturn(new GetEuiccProfileInfoListResult(
42, null /* subscriptions */, true /* removable */));
List<SubscriptionInfo> subInfoList = new ArrayList<>();
// 1: not embedded.
subInfoList.add(new SubscriptionInfo(
0, "1", 0, "", "", 0, 0, "", 0, null, "0", "0", "", false /* isEmbedded */,
null /* accessRules */));
when(mSubscriptionController.getSubscriptionInfoListForEmbeddedSubscriptionUpdate(
new String[0], false /* removable */)).thenReturn(subInfoList);
assertFalse(mUpdater.updateEmbeddedSubscriptions());
// No new entries should be created.
verify(mSubscriptionController, never()).insertEmptySubInfoRecord(anyString(), anyInt());
// No existing entries should have been updated.
verify(mContentProvider, never()).update(eq(SubscriptionManager.CONTENT_URI), any(),
any(), isNull());
}
@Test
@SmallTest
public void testHexIccIdSuffix() throws Exception {
doReturn(null).when(mSubscriptionController)
.getSubInfoUsingSlotIndexPrivileged(anyInt(), anyBoolean());
verify(mSubscriptionController, times(0)).clearSubInfo();
doReturn("890126042000000000Ff").when(mIccRecord).getFullIccId();
// Mock sending a sim loaded for SIM 1
mUpdater.updateInternalIccState(
IccCardConstants.INTENT_VALUE_ICC_LOADED, "TESTING", FAKE_SUB_ID_1);
waitForMs(100);
SubscriptionManager mSubscriptionManager = SubscriptionManager.from(mContext);
verify(mSubscriptionController, times(1)).notifySubscriptionInfoChanged();
verify(mSubscriptionManager, times(1)).addSubscriptionInfoRecord(eq("890126042000000000"),
eq(FAKE_SUB_ID_1));
verify(mSubscriptionController, times(0)).clearSubInfo();
}
}