blob: 52e6a2fb2d349cdc2c67f9941d060f040c95b6c8 [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 org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNotSame;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.Mockito.atLeast;
import static org.mockito.Mockito.clearInvocations;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.eq;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import android.Manifest;
import android.content.ContentResolver;
import android.content.ContentValues;
import android.content.Intent;
import android.os.Bundle;
import android.os.ParcelUuid;
import android.os.UserHandle;
import android.provider.Settings;
import android.telephony.SubscriptionInfo;
import android.telephony.SubscriptionManager;
import android.telephony.UiccSlotInfo;
import android.test.mock.MockContentResolver;
import android.test.suitebuilder.annotation.SmallTest;
import androidx.test.filters.FlakyTest;
import com.android.internal.telephony.uicc.UiccController;
import com.android.internal.telephony.uicc.UiccSlot;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.mockito.ArgumentCaptor;
import org.mockito.Mock;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
public class SubscriptionControllerTest extends TelephonyTest {
private static final int SINGLE_SIM = 1;
private static final int DUAL_SIM = 2;
private String mCallingPackage;
private SubscriptionController mSubscriptionControllerUT;
private MockContentResolver mMockContentResolver;
private FakeTelephonyProvider mFakeTelephonyProvider;
@Mock
private UiccSlot mUiccSlot;
@Mock
private ITelephonyRegistry.Stub mTelephonyRegisteryMock;
@Mock
private MultiSimSettingController mMultiSimSettingControllerMock;
private static final String MAC_ADDRESS_PREFIX = "mac_";
private static final String DISPLAY_NAME_PREFIX = "my_phone_";
private static final String UNAVAILABLE_ICCID = "";
@Before
public void setUp() throws Exception {
super.setUp("SubscriptionControllerTest");
doReturn(SINGLE_SIM).when(mTelephonyManager).getSimCount();
doReturn(SINGLE_SIM).when(mTelephonyManager).getPhoneCount();
mMockContentResolver = (MockContentResolver) mContext.getContentResolver();
mFakeTelephonyProvider = new FakeTelephonyProvider();
mMockContentResolver.addProvider(SubscriptionManager.CONTENT_URI.getAuthority(),
mFakeTelephonyProvider);
replaceInstance(SubscriptionController.class, "sInstance", null, null);
replaceInstance(MultiSimSettingController.class, "sInstance", null,
mMultiSimSettingControllerMock);
SubscriptionController.init(mContext, null);
mSubscriptionControllerUT = SubscriptionController.getInstance();
mCallingPackage = mContext.getOpPackageName();
doReturn(1).when(mProxyController).getMaxRafSupported();
mContextFixture.putIntArrayResource(com.android.internal.R.array.sim_colors, new int[]{5});
mSubscriptionControllerUT.getInstance().updatePhonesAvailability(new Phone[]{mPhone});
}
@After
public void tearDown() throws Exception {
mContextFixture.addCallingOrSelfPermission(ContextFixture.PERMISSION_ENABLE_ALL);
/* should clear fake content provider and resolver here */
mContext.getContentResolver().delete(SubscriptionManager.CONTENT_URI, null, null);
/*clear sub info in mSubscriptionControllerUT since they will otherwise be persistent
* between each test case. */
mSubscriptionControllerUT.clearSubInfo();
mSubscriptionControllerUT.resetStaticMembers();
/* clear settings for default voice/data/sms sub ID */
Settings.Global.putInt(mContext.getContentResolver(),
Settings.Global.MULTI_SIM_VOICE_CALL_SUBSCRIPTION,
SubscriptionManager.INVALID_SUBSCRIPTION_ID);
Settings.Global.putInt(mContext.getContentResolver(),
Settings.Global.MULTI_SIM_DATA_CALL_SUBSCRIPTION,
SubscriptionManager.INVALID_SUBSCRIPTION_ID);
Settings.Global.putInt(mContext.getContentResolver(),
Settings.Global.MULTI_SIM_SMS_SUBSCRIPTION,
SubscriptionManager.INVALID_SUBSCRIPTION_ID);
mSubscriptionControllerUT = null;
super.tearDown();
}
@Test @SmallTest
public void testInsertSim() {
//verify there is no sim inserted in the SubscriptionManager
assertEquals(0, mSubscriptionControllerUT.getAllSubInfoCount(mCallingPackage));
int slotID = 0;
//insert one Subscription Info
mSubscriptionControllerUT.addSubInfoRecord("test", slotID);
//verify there is one sim
assertEquals(1, mSubscriptionControllerUT.getAllSubInfoCount(mCallingPackage));
//sanity for slot id and sub id
List<SubscriptionInfo> mSubList = mSubscriptionControllerUT
.getActiveSubscriptionInfoList(mCallingPackage);
assertTrue(mSubList != null && mSubList.size() > 0);
for (int i = 0; i < mSubList.size(); i++) {
assertTrue(SubscriptionManager.isValidSubscriptionId(
mSubList.get(i).getSubscriptionId()));
assertTrue(SubscriptionManager.isValidSlotIndex(mSubList.get(i).getSimSlotIndex()));
}
}
@Test @SmallTest
public void testChangeSIMProperty() {
int dataRoaming = 1;
int iconTint = 1;
String disName = "TESTING";
String disNum = "12345";
boolean isOpportunistic = true;
testInsertSim();
/* Get SUB ID */
int[] subIds = mSubscriptionControllerUT.getActiveSubIdList(/*visibleOnly*/false);
assertTrue(subIds != null && subIds.length != 0);
int subID = subIds[0];
/* Getting, there is no direct getter function for each fields of property */
SubscriptionInfo subInfo = mSubscriptionControllerUT
.getActiveSubscriptionInfo(subID, mCallingPackage);
/* Setting */
mSubscriptionControllerUT.setDisplayNameUsingSrc(disName, subID,
SubscriptionManager.NAME_SOURCE_USER_INPUT);
mSubscriptionControllerUT.setDataRoaming(dataRoaming, subID);
mSubscriptionControllerUT.setDisplayNumber(disNum, subID);
mSubscriptionControllerUT.setIconTint(iconTint, subID);
mSubscriptionControllerUT.setOpportunistic(isOpportunistic, subID, mCallingPackage);
subInfo = mSubscriptionControllerUT
.getActiveSubscriptionInfo(subID, mCallingPackage);
assertNotNull(subInfo);
assertEquals(dataRoaming, subInfo.getDataRoaming());
assertEquals(disName, subInfo.getDisplayName());
assertEquals(iconTint, subInfo.getIconTint());
assertEquals(disNum, subInfo.getNumber());
assertEquals(isOpportunistic, subInfo.isOpportunistic());
/* verify broadcast intent */
ArgumentCaptor<Intent> captorIntent = ArgumentCaptor.forClass(Intent.class);
verify(mContext, atLeast(1)).sendBroadcast(captorIntent.capture());
assertEquals(TelephonyIntents.ACTION_SUBINFO_RECORD_UPDATED,
captorIntent.getValue().getAction());
}
@Test @SmallTest
public void testSetGetDisplayNameSrc() {
testInsertSim();
/* Get SUB ID */
int[] subIds = mSubscriptionControllerUT.getActiveSubIdList(/*visibleOnly*/false);
assertTrue(subIds != null && subIds.length != 0);
int subID = subIds[0];
/* Setting */
String disName = "TESTING";
int nameSource = SubscriptionManager.NAME_SOURCE_SIM_SOURCE;
mSubscriptionControllerUT.setDisplayNameUsingSrc(disName, subID, nameSource);
SubscriptionInfo subInfo = mSubscriptionControllerUT
.getActiveSubscriptionInfo(subID, mCallingPackage);
assertNotNull(subInfo);
assertEquals(disName, subInfo.getDisplayName());
assertEquals(nameSource, subInfo.getNameSource());
/* verify broadcast intent */
ArgumentCaptor<Intent> captorIntent = ArgumentCaptor.forClass(Intent.class);
verify(mContext, atLeast(1)).sendBroadcast(captorIntent.capture());
assertEquals(TelephonyIntents.ACTION_SUBINFO_RECORD_UPDATED,
captorIntent.getValue().getAction());
}
@Test @SmallTest
public void testCleanUpSIM() {
testInsertSim();
assertFalse(mSubscriptionControllerUT.isActiveSubId(2));
mSubscriptionControllerUT.clearSubInfo();
assertFalse(mSubscriptionControllerUT.isActiveSubId(1));
assertEquals(SubscriptionManager.SIM_NOT_INSERTED,
mSubscriptionControllerUT.getSlotIndex(1));
}
@Test @SmallTest
public void testDefaultSubIdOnSingleSimDevice() {
assertEquals(SubscriptionManager.INVALID_SUBSCRIPTION_ID,
mSubscriptionControllerUT.getDefaultDataSubId());
assertEquals(SubscriptionManager.INVALID_SUBSCRIPTION_ID,
mSubscriptionControllerUT.getDefaultSmsSubId());
assertEquals(SubscriptionManager.INVALID_SUBSCRIPTION_ID,
mSubscriptionControllerUT.getDefaultSmsSubId());
/* insert one sim */
testInsertSim();
// if support single sim, sms/data/voice default sub should be the same
assertEquals(1, mSubscriptionControllerUT.getDefaultSubId());
assertEquals(1, mSubscriptionControllerUT.getDefaultDataSubId());
assertEquals(1, mSubscriptionControllerUT.getDefaultSmsSubId());
assertEquals(1, mSubscriptionControllerUT.getDefaultVoiceSubId());
}
@Test @SmallTest
public void testSetGetMCCMNC() {
testInsertSim();
String mCcMncVERIZON = "310004";
mSubscriptionControllerUT.setMccMnc(mCcMncVERIZON, 1);
SubscriptionInfo subInfo = mSubscriptionControllerUT
.getActiveSubscriptionInfo(1, mCallingPackage);
assertNotNull(subInfo);
assertEquals(Integer.parseInt(mCcMncVERIZON.substring(0, 3)), subInfo.getMcc());
assertEquals(Integer.parseInt(mCcMncVERIZON.substring(3)), subInfo.getMnc());
/* verify broadcast intent */
ArgumentCaptor<Intent> captorIntent = ArgumentCaptor.forClass(Intent.class);
verify(mContext, atLeast(1)).sendBroadcast(captorIntent.capture());
assertEquals(TelephonyIntents.ACTION_SUBINFO_RECORD_UPDATED,
captorIntent.getValue().getAction());
}
@Test @SmallTest
public void testSetGetCarrierId() {
testInsertSim();
int carrierId = 1234;
mSubscriptionControllerUT.setCarrierId(carrierId, 1);
SubscriptionInfo subInfo = mSubscriptionControllerUT
.getActiveSubscriptionInfo(1, mCallingPackage);
assertNotNull(subInfo);
assertEquals(carrierId, subInfo.getCarrierId());
/* verify broadcast intent */
ArgumentCaptor<Intent> captorIntent = ArgumentCaptor.forClass(Intent.class);
verify(mContext, atLeast(1)).sendBroadcast(captorIntent.capture());
assertEquals(TelephonyIntents.ACTION_SUBINFO_RECORD_UPDATED,
captorIntent.getValue().getAction());
}
@Test
@SmallTest
public void testSetDefaultDataSubId() throws Exception {
doReturn(1).when(mPhone).getSubId();
mSubscriptionControllerUT.setDefaultDataSubId(1);
verify(mPhone, times(1)).updateDataConnectionTracker();
ArgumentCaptor<Intent> captorIntent = ArgumentCaptor.forClass(Intent.class);
verify(mContext, times(1)).sendStickyBroadcastAsUser(
captorIntent.capture(), eq(UserHandle.ALL));
Intent intent = captorIntent.getValue();
assertEquals(TelephonyIntents.ACTION_DEFAULT_DATA_SUBSCRIPTION_CHANGED, intent.getAction());
Bundle b = intent.getExtras();
assertTrue(b.containsKey(PhoneConstants.SUBSCRIPTION_KEY));
assertEquals(1, b.getInt(PhoneConstants.SUBSCRIPTION_KEY));
}
@Test
@SmallTest
public void testMigrateImsSettings() throws Exception {
testInsertSim();
int[] subIds = mSubscriptionControllerUT.getActiveSubIdList(/*visibleOnly*/false);
assertTrue(subIds != null && subIds.length != 0);
int subID = subIds[0];
// Set default void subId.
Settings.Global.putInt(mContext.getContentResolver(),
Settings.Global.MULTI_SIM_VOICE_CALL_SUBSCRIPTION,
subID);
Settings.Global.putInt(mContext.getContentResolver(),
Settings.Global.ENHANCED_4G_MODE_ENABLED,
1);
Settings.Global.putInt(mContext.getContentResolver(),
Settings.Global.VT_IMS_ENABLED,
0);
Settings.Global.putInt(mContext.getContentResolver(),
Settings.Global.WFC_IMS_ENABLED,
1);
Settings.Global.putInt(mContext.getContentResolver(),
Settings.Global.WFC_IMS_MODE,
2);
Settings.Global.putInt(mContext.getContentResolver(),
Settings.Global.WFC_IMS_ROAMING_MODE,
3);
mSubscriptionControllerUT.migrateImsSettings();
// Global settings should be all set.
assertEquals(-1, Settings.Global.getInt(mContext.getContentResolver(),
Settings.Global.ENHANCED_4G_MODE_ENABLED));
assertEquals(-1, Settings.Global.getInt(mContext.getContentResolver(),
Settings.Global.VT_IMS_ENABLED));
assertEquals(-1, Settings.Global.getInt(mContext.getContentResolver(),
Settings.Global.WFC_IMS_ENABLED));
assertEquals(-1, Settings.Global.getInt(mContext.getContentResolver(),
Settings.Global.WFC_IMS_MODE));
assertEquals(-1, Settings.Global.getInt(mContext.getContentResolver(),
Settings.Global.WFC_IMS_ROAMING_MODE));
// The values should be migrated to its DB.
assertEquals("1", mSubscriptionControllerUT.getSubscriptionProperty(
subID,
SubscriptionManager.ENHANCED_4G_MODE_ENABLED,
mCallingPackage));
assertEquals("0", mSubscriptionControllerUT.getSubscriptionProperty(
subID,
SubscriptionManager.VT_IMS_ENABLED,
mCallingPackage));
assertEquals("1", mSubscriptionControllerUT.getSubscriptionProperty(
subID,
SubscriptionManager.WFC_IMS_ENABLED,
mCallingPackage));
assertEquals("2", mSubscriptionControllerUT.getSubscriptionProperty(
subID,
SubscriptionManager.WFC_IMS_MODE,
mCallingPackage));
assertEquals("3", mSubscriptionControllerUT.getSubscriptionProperty(
subID,
SubscriptionManager.WFC_IMS_ROAMING_MODE,
mCallingPackage));
}
@Test
@SmallTest
public void testSkipMigrateImsSettings() throws Exception {
// Set default invalid subId.
Settings.Global.putInt(mContext.getContentResolver(),
Settings.Global.MULTI_SIM_VOICE_CALL_SUBSCRIPTION,
-1);
int enhanced4gModeEnabled = 1;
Settings.Global.putInt(mContext.getContentResolver(),
Settings.Global.ENHANCED_4G_MODE_ENABLED,
enhanced4gModeEnabled);
int vtImsEnabled = 0;
Settings.Global.putInt(mContext.getContentResolver(),
Settings.Global.VT_IMS_ENABLED,
vtImsEnabled);
int wfcImsEnabled = 1;
Settings.Global.putInt(mContext.getContentResolver(),
Settings.Global.WFC_IMS_ENABLED,
wfcImsEnabled);
int wfcImsMode = 2;
Settings.Global.putInt(mContext.getContentResolver(),
Settings.Global.WFC_IMS_MODE,
wfcImsMode);
int wfcImsRoamingMode = 3;
Settings.Global.putInt(mContext.getContentResolver(),
Settings.Global.WFC_IMS_ROAMING_MODE,
wfcImsRoamingMode);
mSubscriptionControllerUT.migrateImsSettings();
// Migration should be skipped because subId was invalid
assertEquals(enhanced4gModeEnabled, Settings.Global.getInt(mContext.getContentResolver(),
Settings.Global.ENHANCED_4G_MODE_ENABLED));
assertEquals(vtImsEnabled, Settings.Global.getInt(mContext.getContentResolver(),
Settings.Global.VT_IMS_ENABLED));
assertEquals(wfcImsEnabled, Settings.Global.getInt(mContext.getContentResolver(),
Settings.Global.WFC_IMS_ENABLED));
assertEquals(wfcImsMode, Settings.Global.getInt(mContext.getContentResolver(),
Settings.Global.WFC_IMS_MODE));
assertEquals(wfcImsRoamingMode, Settings.Global.getInt(mContext.getContentResolver(),
Settings.Global.WFC_IMS_ROAMING_MODE));
}
@Test
@SmallTest
public void testOpptSubInfoListChanged() throws Exception {
registerMockTelephonyRegistry();
verify(mTelephonyRegisteryMock, times(0))
.notifyOpportunisticSubscriptionInfoChanged();
testInsertSim();
mSubscriptionControllerUT.addSubInfoRecord("test2", 0);
// Neither sub1 or sub2 are opportunistic. So getOpportunisticSubscriptions
// should return empty list and no callback triggered.
List<SubscriptionInfo> opptSubList = mSubscriptionControllerUT
.getOpportunisticSubscriptions(mCallingPackage);
assertTrue(opptSubList.isEmpty());
verify(mTelephonyRegisteryMock, times(0))
.notifyOpportunisticSubscriptionInfoChanged();
// Setting sub2 as opportunistic should trigger callback.
mSubscriptionControllerUT.setOpportunistic(true, 2, mCallingPackage);
verify(mTelephonyRegisteryMock, times(1))
.notifyOpportunisticSubscriptionInfoChanged();
opptSubList = mSubscriptionControllerUT
.getOpportunisticSubscriptions(mCallingPackage);
assertEquals(1, opptSubList.size());
assertEquals("test2", opptSubList.get(0).getIccId());
// Changing non-opportunistic sub1 shouldn't trigger callback.
mSubscriptionControllerUT.setDisplayNameUsingSrc("DisplayName", 1,
SubscriptionManager.NAME_SOURCE_SIM_SOURCE);
verify(mTelephonyRegisteryMock, times(1))
.notifyOpportunisticSubscriptionInfoChanged();
mSubscriptionControllerUT.setDisplayNameUsingSrc("DisplayName", 2,
SubscriptionManager.NAME_SOURCE_SIM_SOURCE);
verify(mTelephonyRegisteryMock, times(2))
.notifyOpportunisticSubscriptionInfoChanged();
}
@Test @SmallTest
public void testInsertRemoteSim() {
makeThisDeviceMultiSimCapable();
// verify there are no sim's in the system.
assertEquals(0, mSubscriptionControllerUT.getAllSubInfoCount(mCallingPackage));
addAndVerifyRemoteSimAddition(1, 0);
}
private void addAndVerifyRemoteSimAddition(int num, int numOfCurrentSubs) {
// Verify the number of current subs in the system
assertEquals(numOfCurrentSubs,
mSubscriptionControllerUT.getAllSubInfoCount(mCallingPackage));
// if there are current subs in the system, get that info
List<SubscriptionInfo> mSubList;
ArrayList<String> macAddresses = new ArrayList<>();
ArrayList<String> displayNames = new ArrayList<>();
if (numOfCurrentSubs > 0) {
mSubList = mSubscriptionControllerUT.getActiveSubscriptionInfoList(mCallingPackage);
assertNotNull(mSubList);
assertEquals(numOfCurrentSubs, mSubList.size());
for (SubscriptionInfo info : mSubList) {
assertNotNull(info.getIccId());
assertNotNull(info.getDisplayName());
macAddresses.add(info.getIccId());
displayNames.add(info.getDisplayName().toString());
}
}
// To add more subs, we need to create macAddresses + displaynames.
for (int i = 0; i < num; i++) {
macAddresses.add(MAC_ADDRESS_PREFIX + (numOfCurrentSubs + i));
displayNames.add(DISPLAY_NAME_PREFIX + (numOfCurrentSubs + i));
}
// Add subs - one at a time and verify the contents in subscription info data structs
for (int i = 0; i < num; i++) {
int index = numOfCurrentSubs + i;
mSubscriptionControllerUT.addSubInfo(macAddresses.get(index), displayNames.get(index),
SubscriptionManager.SLOT_INDEX_FOR_REMOTE_SIM_SUB,
SubscriptionManager.SUBSCRIPTION_TYPE_REMOTE_SIM);
// make sure the subscription is added in SubscriptionController data structs
Map<Integer, ArrayList<Integer>> slotIndexToSubsMap =
mSubscriptionControllerUT.getSlotIndexToSubIdsMap();
assertNotNull(slotIndexToSubsMap);
// Since All remote sim's go to the same slot index, there should only be one entry
assertEquals(1, slotIndexToSubsMap.size());
// get all the subscriptions available. should be what is just added in this method
// PLUS the number of subs that already existed before
int expectedNumOfSubs = numOfCurrentSubs + i + 1;
ArrayList<Integer> subIdsList =
slotIndexToSubsMap.get(SubscriptionManager.SLOT_INDEX_FOR_REMOTE_SIM_SUB);
assertNotNull(subIdsList);
assertEquals(expectedNumOfSubs, subIdsList.size());
// validate slot index, sub id etc
mSubList = mSubscriptionControllerUT.getActiveSubscriptionInfoList(mCallingPackage);
assertNotNull(mSubList);
assertEquals(expectedNumOfSubs, mSubList.size());
// sort on subscription-id which will make sure the previously existing subscriptions
// are in earlier slots in the array
mSubList.sort(SUBSCRIPTION_INFO_COMPARATOR);
// Verify the subscription data. Skip the verification for the existing subs.
for (int j = numOfCurrentSubs; j < mSubList.size(); j++) {
SubscriptionInfo info = mSubList.get(j);
assertTrue(SubscriptionManager.isValidSubscriptionId(info.getSubscriptionId()));
assertEquals(SubscriptionManager.SLOT_INDEX_FOR_REMOTE_SIM_SUB,
info.getSimSlotIndex());
assertEquals(SubscriptionManager.SUBSCRIPTION_TYPE_REMOTE_SIM,
info.getSubscriptionType());
assertEquals(macAddresses.get(j), info.getIccId());
assertEquals(displayNames.get(j), info.getDisplayName());
}
}
}
private static final Comparator<SubscriptionInfo> SUBSCRIPTION_INFO_COMPARATOR =
Comparator.comparingInt(o -> o.getSubscriptionId());
@Test @SmallTest
public void testInsertMultipleRemoteSims() {
makeThisDeviceMultiSimCapable();
// verify that there are no subscription info records
assertEquals(0, mSubscriptionControllerUT.getAllSubInfoCount(mCallingPackage));
Map<Integer, ArrayList<Integer>> slotIndexToSubsMap =
mSubscriptionControllerUT.getSlotIndexToSubIdsMap();
assertNotNull(slotIndexToSubsMap);
assertTrue(slotIndexToSubsMap.isEmpty());
// Add a few subscriptions
addAndVerifyRemoteSimAddition(4, 0);
}
@FlakyTest
@Test @SmallTest
public void testDefaultSubIdOnMultiSimDevice() {
makeThisDeviceMultiSimCapable();
// Initially, defaults should be -1
assertEquals(SubscriptionManager.INVALID_SUBSCRIPTION_ID,
mSubscriptionControllerUT.getDefaultDataSubId());
assertEquals(SubscriptionManager.INVALID_SUBSCRIPTION_ID,
mSubscriptionControllerUT.getDefaultSmsSubId());
assertEquals(SubscriptionManager.INVALID_SUBSCRIPTION_ID,
mSubscriptionControllerUT.getDefaultSmsSubId());
// Insert one Remote-Sim.
testInsertRemoteSim();
// defaults should be set to this newly-inserted subscription
assertEquals(1, mSubscriptionControllerUT.getDefaultSubId());
assertEquals(1, mSubscriptionControllerUT.getDefaultDataSubId());
assertEquals(1, mSubscriptionControllerUT.getDefaultSmsSubId());
assertEquals(1, mSubscriptionControllerUT.getDefaultVoiceSubId());
// Add a few subscriptions
addAndVerifyRemoteSimAddition(4, 1);
// defaults should be still be set to the first sub - and unchanged by the addition of
// the above multiple sims.
assertEquals(1, mSubscriptionControllerUT.getDefaultSubId());
assertEquals(1, mSubscriptionControllerUT.getDefaultDataSubId());
assertEquals(1, mSubscriptionControllerUT.getDefaultSmsSubId());
assertEquals(1, mSubscriptionControllerUT.getDefaultVoiceSubId());
}
@Test @SmallTest
public void testRemoveSubscription() {
makeThisDeviceMultiSimCapable();
/* insert some sims */
testInsertMultipleRemoteSims();
assertEquals(1, mSubscriptionControllerUT.getDefaultSubId());
int[] subIdsArray = mSubscriptionControllerUT.getActiveSubIdList(/*visibleOnly*/false);
assertTrue(subIdsArray.length > 0);
int len = subIdsArray.length;
// remove the first sim - which also is the default sim.
int result = mSubscriptionControllerUT.removeSubInfo(MAC_ADDRESS_PREFIX + 0,
SubscriptionManager.SUBSCRIPTION_TYPE_REMOTE_SIM);
assertTrue(result > 0);
// now check the number of subs left. should be one less than earlier
int[] newSubIdsArray = mSubscriptionControllerUT.getActiveSubIdList(/*visibleOnly*/false);
assertTrue(newSubIdsArray.length > 0);
assertEquals(len - 1, newSubIdsArray.length);
// now check that there is a new default
assertNotSame(1, mSubscriptionControllerUT.getDefaultSubId());
}
private void makeThisDeviceMultiSimCapable() {
doReturn(10).when(mTelephonyManager).getSimCount();
}
@Test
@SmallTest
public void testSetSubscriptionGroupWithModifyPermission() throws Exception {
testInsertSim();
mSubscriptionControllerUT.addSubInfoRecord("test2", 0);
mContextFixture.removeCallingOrSelfPermission(ContextFixture.PERMISSION_ENABLE_ALL);
mContextFixture.addCallingOrSelfPermission(Manifest.permission.READ_PHONE_STATE);
int[] subIdList = new int[] {1, 2};
try {
mSubscriptionControllerUT.createSubscriptionGroup(
subIdList, mContext.getOpPackageName());
fail("createSubscriptionGroup should fail with no permission.");
} catch (SecurityException e) {
// Expected result.
}
// With modify permission it should succeed.
mContextFixture.addCallingOrSelfPermission(android.Manifest.permission.MODIFY_PHONE_STATE);
ParcelUuid groupId = mSubscriptionControllerUT.createSubscriptionGroup(
subIdList, mContext.getOpPackageName());
assertNotEquals(null, groupId);
// Calling it again should generate a new group ID.
ParcelUuid newGroupId = mSubscriptionControllerUT.createSubscriptionGroup(
subIdList, mContext.getOpPackageName());
assertNotEquals(null, newGroupId);
assertNotEquals(groupId, newGroupId);
}
@Test
@SmallTest
public void testCreateSubscriptionGroupWithCarrierPrivilegePermission() throws Exception {
testInsertSim();
// Adding a second profile and mark as embedded.
// TODO b/123300875 slot index 1 is not expected to be valid
mSubscriptionControllerUT.addSubInfoRecord("test2", 1);
ContentValues values = new ContentValues();
values.put(SubscriptionManager.IS_EMBEDDED, 1);
mFakeTelephonyProvider.update(SubscriptionManager.CONTENT_URI, values,
SubscriptionManager.UNIQUE_KEY_SUBSCRIPTION_ID + "=" + 2, null);
mSubscriptionControllerUT.refreshCachedActiveSubscriptionInfoList();
mContextFixture.removeCallingOrSelfPermission(ContextFixture.PERMISSION_ENABLE_ALL);
mContextFixture.addCallingOrSelfPermission(Manifest.permission.READ_PHONE_STATE);
int[] subIdList = new int[] {1, 2};
// It should fail since it has no permission.
try {
mSubscriptionControllerUT.createSubscriptionGroup(
subIdList, mContext.getOpPackageName());
fail("createSubscriptionGroup should fail with no permission.");
} catch (SecurityException e) {
// Expected result.
}
doReturn(true).when(mTelephonyManager).hasCarrierPrivileges(1);
try {
mSubscriptionControllerUT.createSubscriptionGroup(
subIdList, mContext.getOpPackageName());
fail("createSubscriptionGroup should fail with no permission on sub 2.");
} catch (SecurityException e) {
// Expected result.
}
doReturn(true).when(mTelephonyManager).hasCarrierPrivileges(2);
ParcelUuid groupId = mSubscriptionControllerUT.createSubscriptionGroup(
subIdList, mContext.getOpPackageName());
assertNotEquals(null, groupId);
List<SubscriptionInfo> subInfoList = mSubscriptionControllerUT
.getActiveSubscriptionInfoList(mContext.getOpPackageName());
// Put sub3 into slot 1 to make sub2 inactive.
mContextFixture.addCallingOrSelfPermission(
android.Manifest.permission.MODIFY_PHONE_STATE);
// TODO b/123300875 slot index 1 is not expected to be valid
mSubscriptionControllerUT.addSubInfoRecord("test3", 1);
mContextFixture.removeCallingOrSelfPermission(
android.Manifest.permission.MODIFY_PHONE_STATE);
// As sub2 is inactive, it will checks carrier privilege against access rules in the db.
doReturn(true).when(mSubscriptionManager).canManageSubscription(
eq(subInfoList.get(1)), anyString());
ParcelUuid newGroupId = mSubscriptionControllerUT.createSubscriptionGroup(
subIdList, mContext.getOpPackageName());
assertNotEquals(null, newGroupId);
assertNotEquals(groupId, newGroupId);
}
@Test
@SmallTest
public void testUpdateSubscriptionGroupWithCarrierPrivilegePermission() throws Exception {
testInsertSim();
// Adding a second profile and mark as embedded.
// TODO b/123300875 slot index 1 is not expected to be valid
mSubscriptionControllerUT.addSubInfoRecord("test2", 1);
ContentValues values = new ContentValues();
values.put(SubscriptionManager.IS_EMBEDDED, 1);
mFakeTelephonyProvider.update(SubscriptionManager.CONTENT_URI, values,
SubscriptionManager.UNIQUE_KEY_SUBSCRIPTION_ID + "=" + 2, null);
mSubscriptionControllerUT.refreshCachedActiveSubscriptionInfoList();
mContextFixture.removeCallingOrSelfPermission(ContextFixture.PERMISSION_ENABLE_ALL);
mContextFixture.addCallingOrSelfPermission(Manifest.permission.READ_PHONE_STATE);
int[] subIdList = new int[] {1};
doReturn(true).when(mTelephonyManager).hasCarrierPrivileges(1);
doReturn(true).when(mTelephonyManager).hasCarrierPrivileges(2);
ParcelUuid groupId = mSubscriptionControllerUT.createSubscriptionGroup(
subIdList, "packageName1");
assertNotEquals(null, groupId);
mSubscriptionControllerUT.addSubscriptionsIntoGroup(
new int[] {2}, groupId, "packageName1");
List<SubscriptionInfo> infoList = mSubscriptionControllerUT.getSubscriptionsInGroup(
groupId, "packageName1");
assertEquals(2, infoList.size());
assertEquals(1, infoList.get(0).getSubscriptionId());
assertEquals(2, infoList.get(1).getSubscriptionId());
mSubscriptionControllerUT.removeSubscriptionsFromGroup(
new int[] {2}, groupId, "packageName1");
infoList = mSubscriptionControllerUT.getSubscriptionsInGroup(
groupId, "packageName1");
assertEquals(1, infoList.size());
assertEquals(1, infoList.get(0).getSubscriptionId());
// Make sub 1 inactive.
mSubscriptionControllerUT.clearSubInfoRecord(0);
try {
mSubscriptionControllerUT.addSubscriptionsIntoGroup(
new int[] {2}, groupId, "packageName2");
fail("addSubscriptionsIntoGroup should fail with wrong callingPackage name");
} catch (SecurityException e) {
// Expected result.
}
// Adding and removing subscription should still work for packageName1, as it's the group
// owner who created the group earlier..
mSubscriptionControllerUT.addSubscriptionsIntoGroup(
new int[] {2}, groupId, "packageName1");
infoList = mSubscriptionControllerUT.getSubscriptionsInGroup(
groupId, "packageName1");
assertEquals(2, infoList.size());
assertEquals(1, infoList.get(0).getSubscriptionId());
assertEquals(2, infoList.get(1).getSubscriptionId());
mSubscriptionControllerUT.removeSubscriptionsFromGroup(
new int[] {2}, groupId, "packageName1");
infoList = mSubscriptionControllerUT.getSubscriptionsInGroup(
groupId, "packageName1");
assertEquals(1, infoList.size());
assertEquals(1, infoList.get(0).getSubscriptionId());
}
@Test
@SmallTest
public void testDisabledSubscriptionGroup() throws Exception {
registerMockTelephonyRegistry();
testInsertSim();
// Adding a second profile and mark as embedded.
mSubscriptionControllerUT.addSubInfoRecord("test2", 0);
ContentValues values = new ContentValues();
values.put(SubscriptionManager.IS_EMBEDDED, 1);
values.put(SubscriptionManager.IS_OPPORTUNISTIC, 1);
mFakeTelephonyProvider.update(SubscriptionManager.CONTENT_URI, values,
SubscriptionManager.UNIQUE_KEY_SUBSCRIPTION_ID + "=" + 2, null);
mSubscriptionControllerUT.refreshCachedActiveSubscriptionInfoList();
mSubscriptionControllerUT.notifySubscriptionInfoChanged();
verify(mTelephonyRegisteryMock, times(1))
.notifyOpportunisticSubscriptionInfoChanged();
// Set sub 1 and 2 into same group.
int[] subIdList = new int[] {1, 2};
ParcelUuid groupId = mSubscriptionControllerUT.createSubscriptionGroup(
subIdList, mContext.getOpPackageName());
assertNotEquals(null, groupId);
mSubscriptionControllerUT.notifySubscriptionInfoChanged();
verify(mTelephonyRegisteryMock, times(2))
.notifyOpportunisticSubscriptionInfoChanged();
List<SubscriptionInfo> opptSubList = mSubscriptionControllerUT
.getOpportunisticSubscriptions(mCallingPackage);
assertEquals(1, opptSubList.size());
assertEquals(2, opptSubList.get(0).getSubscriptionId());
assertEquals(false, opptSubList.get(0).isGroupDisabled());
// Unplug SIM 1. This should trigger subscription controller disabling sub 2.
values = new ContentValues();
values.put(SubscriptionManager.SIM_SLOT_INDEX, -1);
mFakeTelephonyProvider.update(SubscriptionManager.CONTENT_URI, values,
SubscriptionManager.UNIQUE_KEY_SUBSCRIPTION_ID + "=" + 1, null);
mSubscriptionControllerUT.refreshCachedActiveSubscriptionInfoList();
mSubscriptionControllerUT.notifySubscriptionInfoChanged();
verify(mTelephonyRegisteryMock, times(3))
.notifyOpportunisticSubscriptionInfoChanged();
opptSubList = mSubscriptionControllerUT.getOpportunisticSubscriptions(mCallingPackage);
assertEquals(1, opptSubList.size());
assertEquals(2, opptSubList.get(0).getSubscriptionId());
assertEquals(true, opptSubList.get(0).isGroupDisabled());
}
@Test
@SmallTest
public void testSetSubscriptionGroup() throws Exception {
testInsertSim();
// Adding a second profile and mark as embedded.
mSubscriptionControllerUT.addSubInfoRecord("test2", 1);
ContentValues values = new ContentValues();
values.put(SubscriptionManager.IS_EMBEDDED, 1);
mFakeTelephonyProvider.update(SubscriptionManager.CONTENT_URI, values,
SubscriptionManager.UNIQUE_KEY_SUBSCRIPTION_ID + "=" + 2, null);
mSubscriptionControllerUT.refreshCachedActiveSubscriptionInfoList();
assertTrue(mSubscriptionControllerUT.isActiveSubId(1));
assertTrue(mSubscriptionControllerUT.isActiveSubId(2));
assertTrue(TelephonyPermissions.checkCallingOrSelfReadPhoneState(mContext, 1,
mContext.getOpPackageName(), "getSubscriptionsInGroup"));
int[] subIdList = new int[] {1};
ParcelUuid groupUuid = mSubscriptionControllerUT.createSubscriptionGroup(
subIdList, mContext.getOpPackageName());
assertNotEquals(null, groupUuid);
// Sub 1 and sub 2 should be in same group.
List<SubscriptionInfo> infoList = mSubscriptionControllerUT
.getSubscriptionsInGroup(groupUuid, mContext.getOpPackageName());
assertNotEquals(null, infoList);
assertEquals(1, infoList.size());
assertEquals(1, infoList.get(0).getSubscriptionId());
subIdList = new int[] {2};
mSubscriptionControllerUT.addSubscriptionsIntoGroup(
subIdList, groupUuid, mContext.getOpPackageName());
infoList = mSubscriptionControllerUT
.getSubscriptionsInGroup(groupUuid, mContext.getOpPackageName());
assertEquals(2, infoList.size());
assertEquals(2, infoList.get(1).getSubscriptionId());
// Remove group of sub 1.
subIdList = new int[] {1};
mSubscriptionControllerUT.removeSubscriptionsFromGroup(
subIdList, groupUuid, mContext.getOpPackageName());
infoList = mSubscriptionControllerUT
.getSubscriptionsInGroup(groupUuid, mContext.getOpPackageName());
assertEquals(1, infoList.size());
assertEquals(2, infoList.get(0).getSubscriptionId());
}
private void registerMockTelephonyRegistry() {
mServiceManagerMockedServices.put("telephony.registry", mTelephonyRegisteryMock);
doReturn(mTelephonyRegisteryMock).when(mTelephonyRegisteryMock)
.queryLocalInterface(anyString());
}
@Test
@SmallTest
public void testEnableDisableSubscriptionSanity() throws Exception {
testInsertSim();
// Non existing subId.
assertFalse(mSubscriptionControllerUT.isSubscriptionEnabled(2));
// Test invalid arguments.
try {
assertFalse(mSubscriptionControllerUT.isSubscriptionEnabled(-1));
fail("Should throw IllegalArgumentException with invalid subId.");
} catch (IllegalArgumentException exception) {
// Expected.
}
try {
mSubscriptionControllerUT.getEnabledSubscriptionId(3);
fail("Should throw IllegalArgumentException with invalid subId.");
} catch (IllegalArgumentException exception) {
// Expected.
}
}
@Test
@SmallTest
public void testGetActiveSubIdList() throws Exception {
// TODO b/123300875 slot index 1 is not expected to be valid
mSubscriptionControllerUT.addSubInfoRecord("123", 1); // sub 1
mSubscriptionControllerUT.addSubInfoRecord("456", 0); // sub 2
int[] subIds = mSubscriptionControllerUT.getActiveSubIdList(/*visibleOnly*/false);
// Make sure the return sub ids are sorted by slot index
assertTrue("active sub ids = " + subIds, Arrays.equals(subIds, new int[]{2, 1}));
}
@Test
public void testGetActiveSubscriptionInfoWithNoPermissions() throws Exception {
// If the calling package does not have the READ_PHONE_STATE permission or carrier
// privileges then getActiveSubscriptionInfo should throw a SecurityException;
testInsertSim();
mContextFixture.removeCallingOrSelfPermission(ContextFixture.PERMISSION_ENABLE_ALL);
int subId = getFirstSubId();
try {
mSubscriptionControllerUT.getActiveSubscriptionInfo(subId, mCallingPackage);
fail("getActiveSubscriptionInfo should fail when invoked with no permissions");
} catch (SecurityException expected) {
}
}
@Test
public void testGetActiveSubscriptionInfoWithReadPhoneState() throws Exception {
// If the calling package only has the READ_PHONE_STATE permission then
// getActiveSubscriptionInfo should still return a result but the ICC ID should not be
// available via getIccId or getCardString.
testInsertSim();
mContextFixture.removeCallingOrSelfPermission(ContextFixture.PERMISSION_ENABLE_ALL);
mContextFixture.addCallingOrSelfPermission(Manifest.permission.READ_PHONE_STATE);
setupMocksForTelephonyPermissions();
int subId = getFirstSubId();
SubscriptionInfo subscriptionInfo = mSubscriptionControllerUT.getActiveSubscriptionInfo(
subId, mCallingPackage);
assertNotNull(subscriptionInfo);
assertEquals(UNAVAILABLE_ICCID, subscriptionInfo.getIccId());
assertEquals(UNAVAILABLE_ICCID, subscriptionInfo.getCardString());
}
@Test
public void testGetActiveSubscriptionWithPrivilegedPermission() throws Exception {
// If the calling package has the READ_PRIVILEGED_PHONE_STATE permission or carrier
// privileges the ICC ID should be available in the SubscriptionInfo.
testInsertSim();
int subId = getFirstSubId();
SubscriptionInfo subscriptionInfo = mSubscriptionControllerUT.getActiveSubscriptionInfo(
subId, mCallingPackage);
assertNotNull(subscriptionInfo);
assertTrue(subscriptionInfo.getIccId().length() > 0);
assertTrue(subscriptionInfo.getCardString().length() > 0);
}
@Test
public void testGetActiveSubscriptionInfoForSimSlotIndexWithNoPermission() throws Exception {
// If the calling package does not have the READ_PHONE_STATE permission or carrier
// privileges then getActiveSubscriptionInfoForSimSlotIndex should throw a
// SecurityException.
testInsertSim();
mContextFixture.removeCallingOrSelfPermission(ContextFixture.PERMISSION_ENABLE_ALL);
try {
mSubscriptionControllerUT.getActiveSubscriptionInfoForSimSlotIndex(0, mCallingPackage);
fail("getActiveSubscriptionInfoForSimSlotIndex should fail when invoked with no "
+ "permissions");
} catch (SecurityException expected) {
}
}
@Test
public void testGetActiveSubscriptionInfoForSimSlotIndexWithReadPhoneState() throws Exception {
// If the calling package only has the READ_PHONE_STATE permission then
// getActiveSubscriptionInfoForSimlSlotIndex should still return the SubscriptionInfo but
// the ICC ID should not be available via getIccId or getCardString.
testInsertSim();
mContextFixture.removeCallingOrSelfPermission(ContextFixture.PERMISSION_ENABLE_ALL);
mContextFixture.addCallingOrSelfPermission(Manifest.permission.READ_PHONE_STATE);
setupMocksForTelephonyPermissions();
SubscriptionInfo subscriptionInfo =
mSubscriptionControllerUT.getActiveSubscriptionInfoForSimSlotIndex(0,
mCallingPackage);
assertNotNull(subscriptionInfo);
assertEquals(UNAVAILABLE_ICCID, subscriptionInfo.getIccId());
assertEquals(UNAVAILABLE_ICCID, subscriptionInfo.getCardString());
}
@Test
public void testGetActiveSubscriptionInfoForSimSlotIndexWithPrivilegedPermission()
throws Exception {
// If the calling package has the READ_PRIVILEGED_PHONE_STATE permission or carrier
// privileges the ICC ID should be available in the SubscriptionInfo.
testInsertSim();
SubscriptionInfo subscriptionInfo =
mSubscriptionControllerUT.getActiveSubscriptionInfoForSimSlotIndex(0,
mCallingPackage);
assertNotNull(subscriptionInfo);
assertTrue(subscriptionInfo.getIccId().length() > 0);
assertTrue(subscriptionInfo.getCardString().length() > 0);
}
@Test
public void testGetActiveSubscriptionInfoListWithNoPermission() throws Exception {
// If the calling package does not have the READ_PHONE_STATE permission or carrier
// privileges then getActiveSubscriptionInfoList should return a list with 0 elements.
testInsertSim();
mContextFixture.removeCallingOrSelfPermission(ContextFixture.PERMISSION_ENABLE_ALL);
List<SubscriptionInfo> subInfoList =
mSubscriptionControllerUT.getActiveSubscriptionInfoList(mCallingPackage);
assertNotNull(subInfoList);
assertTrue(subInfoList.size() == 0);
}
@Test
public void testGetActiveSubscriptionInfoListWithReadPhoneState() throws Exception {
// If the calling package only has the READ_PHONE_STATE permission then
// getActiveSubscriptionInfoList should still return the list of SubscriptionInfo objects
// but the ICC ID should not be available via getIccId or getCardString.
testInsertSim();
mContextFixture.removeCallingOrSelfPermission(ContextFixture.PERMISSION_ENABLE_ALL);
mContextFixture.addCallingOrSelfPermission(Manifest.permission.READ_PHONE_STATE);
setupMocksForTelephonyPermissions();
List<SubscriptionInfo> subInfoList =
mSubscriptionControllerUT.getActiveSubscriptionInfoList(mCallingPackage);
assertTrue(subInfoList.size() > 0);
for (SubscriptionInfo info : subInfoList) {
assertEquals(UNAVAILABLE_ICCID, info.getIccId());
assertEquals(UNAVAILABLE_ICCID, info.getCardString());
}
}
@Test
public void testGetActiveSubscriptionInfoListWithIdentifierAccessWithoutNumberAccess()
throws Exception {
// An app with access to device identifiers may not have access to the device phone number
// (ie an app that passes the device / profile owner check or an app that has been granted
// the device identifiers appop); this test verifies that an app with identifier access
// can read the ICC ID but does not receive the phone number.
testInsertSim();
List<SubscriptionInfo> subInfoList =
mSubscriptionControllerUT.getActiveSubscriptionInfoList(mCallingPackage);
assertEquals(1, subInfoList.size());
SubscriptionInfo subInfo = subInfoList.get(0);
assertEquals("test", subInfo.getIccId());
}
@Test
public void testGetActiveSubscriptionInfoListWithPrivilegedPermission() throws Exception {
// If the calling package has the READ_PRIVILEGED_PHONE_STATE permission or carrier
// privileges the ICC ID should be available in the SubscriptionInfo objects in the List.
testInsertSim();
List<SubscriptionInfo> subInfoList =
mSubscriptionControllerUT.getActiveSubscriptionInfoList(mCallingPackage);
assertTrue(subInfoList.size() > 0);
for (SubscriptionInfo info : subInfoList) {
assertTrue(info.getIccId().length() > 0);
assertTrue(info.getCardString().length() > 0);
}
}
@Test
public void testGetSubscriptionsInGroupWithNoPermission() throws Exception {
// If the calling package does not have the READ_PHONE_STATE permission or carrier
// privileges then getSubscriptionsInGroup should throw a SecurityException when the
// READ_PHONE_STATE permission check is performed.
ParcelUuid groupUuid = setupGetSubscriptionsInGroupTest();
mContextFixture.removeCallingOrSelfPermission(ContextFixture.PERMISSION_ENABLE_ALL);
try {
mSubscriptionControllerUT.getSubscriptionsInGroup(groupUuid, mCallingPackage);
fail("getSubscriptionsInGroup should fail when invoked with no permissions");
} catch (SecurityException expected) {
}
}
@Test
public void testGetSubscriptionsInGroupWithReadPhoneState() throws Exception {
// If the calling package only has the READ_PHONE_STATE permission then
// getSubscriptionsInGroup should still return the list of SubscriptionInfo objects
// but the ICC ID should not be available via getIccId or getCardString.
ParcelUuid groupUuid = setupGetSubscriptionsInGroupTest();
mContextFixture.removeCallingOrSelfPermission(ContextFixture.PERMISSION_ENABLE_ALL);
mContextFixture.addCallingOrSelfPermission(Manifest.permission.READ_PHONE_STATE);
setupMocksForTelephonyPermissions();
List<SubscriptionInfo> subInfoList = mSubscriptionControllerUT.getSubscriptionsInGroup(
groupUuid, mCallingPackage);
assertTrue(subInfoList.size() > 0);
for (SubscriptionInfo info : subInfoList) {
assertEquals(UNAVAILABLE_ICCID, info.getIccId());
assertEquals(UNAVAILABLE_ICCID, info.getCardString());
}
}
@Test
public void testGetSubscriptionsInGroupWithPrivilegedPermission() throws Exception {
// If the calling package has the READ_PRIVILEGED_PHONE_STATE permission or carrier
// privileges the ICC ID should be available in the SubscriptionInfo objects in the List.
ParcelUuid groupUuid = setupGetSubscriptionsInGroupTest();
List<SubscriptionInfo> subInfoList = mSubscriptionControllerUT.getSubscriptionsInGroup(
groupUuid, mCallingPackage);
assertTrue(subInfoList.size() > 0);
for (SubscriptionInfo info : subInfoList) {
assertTrue(info.getIccId().length() > 0);
assertTrue(info.getCardString().length() > 0);
}
}
private ParcelUuid setupGetSubscriptionsInGroupTest() throws Exception {
testInsertSim();
int[] subIdList = new int[]{getFirstSubId()};
ParcelUuid groupUuid = mSubscriptionControllerUT.createSubscriptionGroup(subIdList,
mCallingPackage);
assertNotNull(groupUuid);
return groupUuid;
}
private int getFirstSubId() throws Exception {
return getSubIdAtIndex(0);
}
private int getSubIdAtIndex(int index) throws Exception {
int[] subIds = mSubscriptionControllerUT.getActiveSubIdList(/*visibleOnly*/false);
assertTrue(subIds != null && subIds.length > index);
return subIds[index];
}
@Test
public void testGetEnabledSubscriptionIdSingleSIM() {
// A single SIM device may have logical slot 0 mapped to physical slot 1
// (i.e. logical slot -1 mapped to physical slot 0)
UiccSlotInfo slot0 = getFakeUiccSlotInfo(false, -1);
UiccSlotInfo slot1 = getFakeUiccSlotInfo(true, 0);
UiccSlotInfo [] uiccSlotInfos = {slot0, slot1};
UiccSlot [] uiccSlots = {mUiccSlot, mUiccSlot};
doReturn(uiccSlotInfos).when(mTelephonyManager).getUiccSlotsInfo();
doReturn(uiccSlots).when(mUiccController).getUiccSlots();
assertEquals(2, UiccController.getInstance().getUiccSlots().length);
ContentResolver resolver = mContext.getContentResolver();
// logical 0 should find physical 1, has settings enabled subscription 0
Settings.Global.putInt(resolver, Settings.Global.ENABLED_SUBSCRIPTION_FOR_SLOT + 1, 0);
int enabledSubscription = mSubscriptionControllerUT.getEnabledSubscriptionId(0);
assertEquals(0, enabledSubscription);
}
@Test
public void testGetEnabledSubscriptionIdDualSIM() {
doReturn(SINGLE_SIM).when(mTelephonyManager).getSimCount();
doReturn(SINGLE_SIM).when(mTelephonyManager).getPhoneCount();
// A dual SIM device may have logical slot 0 mapped to physical slot 0
// (i.e. logical slot 1 mapped to physical slot 1)
UiccSlotInfo slot0 = getFakeUiccSlotInfo(true, 0);
UiccSlotInfo slot1 = getFakeUiccSlotInfo(true, 1);
UiccSlotInfo [] uiccSlotInfos = {slot0, slot1};
UiccSlot [] uiccSlots = {mUiccSlot, mUiccSlot};
doReturn(2).when(mTelephonyManager).getPhoneCount();
doReturn(uiccSlotInfos).when(mTelephonyManager).getUiccSlotsInfo();
doReturn(uiccSlots).when(mUiccController).getUiccSlots();
assertEquals(2, UiccController.getInstance().getUiccSlots().length);
ContentResolver resolver = mContext.getContentResolver();
// logical 0 should find physical 0, has settings enabled subscription 0
Settings.Global.putInt(resolver, Settings.Global.ENABLED_SUBSCRIPTION_FOR_SLOT + 0, 0);
Settings.Global.putInt(resolver, Settings.Global.ENABLED_SUBSCRIPTION_FOR_SLOT + 1, 1);
int enabledSubscription = mSubscriptionControllerUT.getEnabledSubscriptionId(0);
int secondEabledSubscription = mSubscriptionControllerUT.getEnabledSubscriptionId(1);
assertEquals(0, enabledSubscription);
assertEquals(1, secondEabledSubscription);
}
private UiccSlotInfo getFakeUiccSlotInfo(boolean active, int logicalSlotIndex) {
return new UiccSlotInfo(active, false, "fake card Id",
UiccSlotInfo.CARD_STATE_INFO_PRESENT, logicalSlotIndex, true, true);
}
// TODO: Move this test once SubscriptionManager.setAlwaysAllowMmsData is moved to telephony
// manager.
@Test
@SmallTest
public void testSetAlwaysAllowMmsData() throws Exception {
mSubscriptionControllerUT.setAlwaysAllowMmsData(0, true);
verify(mDataEnabledSettings).setAlwaysAllowMmsData(eq(true));
clearInvocations(mDataEnabledSettings);
mSubscriptionControllerUT.setAlwaysAllowMmsData(0, false);
verify(mDataEnabledSettings).setAlwaysAllowMmsData(eq(false));
}
}