Loading src/java/com/android/internal/telephony/SubscriptionController.java +14 −0 Original line number Diff line number Diff line Loading @@ -547,6 +547,20 @@ public class SubscriptionController extends ISub.Stub { return null; } /** * Get a single subscription info record for a given subscription. * * @param subId the subId to query. * * @hide */ public SubscriptionInfo getSubscriptionInfo(int subId) { List<SubscriptionInfo> subInfoList = getSubInfo( SubscriptionManager.UNIQUE_KEY_SUBSCRIPTION_ID + "=" + subId, null); if (subInfoList == null || subInfoList.isEmpty()) return null; return subInfoList.get(0); } /** * Get the active SubscriptionInfo associated with the iccId * @param iccId the IccId of SIM card Loading src/java/com/android/internal/telephony/SubscriptionInfoUpdater.java +112 −2 Original line number Diff line number Diff line Loading @@ -32,12 +32,15 @@ import android.os.Handler; import android.os.IRemoteCallback; import android.os.Looper; import android.os.Message; import android.os.ParcelUuid; import android.os.PersistableBundle; import android.os.RemoteException; import android.os.ServiceManager; import android.preference.PreferenceManager; import android.provider.Settings; import android.provider.Settings.Global; import android.provider.Settings.SettingNotFoundException; import android.service.carrier.CarrierService; import android.service.euicc.EuiccProfileInfo; import android.service.euicc.EuiccService; import android.service.euicc.GetEuiccProfileInfoListResult; Loading Loading @@ -90,6 +93,9 @@ public class SubscriptionInfoUpdater extends Handler { private static final String ICCID_STRING_FOR_NO_SIM = ""; private static final ParcelUuid REMOVE_GROUP_UUID = ParcelUuid.fromString(CarrierConfigManager.REMOVE_GROUP_UUID_STRING); // Key used to read/write the current IMSI. Updated on SIM_STATE_CHANGED - LOADED. public static final String CURR_SUBID = "curr_subid"; Loading @@ -111,6 +117,8 @@ public class SubscriptionInfoUpdater extends Handler { private int mCurrentlyActiveUserId; private CarrierServiceBindHelper mCarrierServiceBindHelper; // TODO: The SubscriptionController instance should be passed in here from PhoneFactory // rather than invoking the static getter all over the place. public SubscriptionInfoUpdater( Looper looper, Context context, Phone[] phone, CommandsInterface[] ci) { this(looper, context, phone, ci, Loading Loading @@ -512,8 +520,8 @@ public class SubscriptionInfoUpdater extends Handler { } private void updateCarrierServices(int slotId, String simState) { CarrierConfigManager configManager = (CarrierConfigManager) mContext.getSystemService(Context.CARRIER_CONFIG_SERVICE); CarrierConfigManager configManager = (CarrierConfigManager) mContext.getSystemService(Context.CARRIER_CONFIG_SERVICE); configManager.updateConfigForPhoneId(slotId, simState); mCarrierServiceBindHelper.updateForPhoneId(slotId, simState); } Loading Loading @@ -752,6 +760,108 @@ public class SubscriptionInfoUpdater extends Handler { return hasChanges; } /** * Called by CarrierConfigLoader to update the subscription before sending a broadcast. */ public void updateSubscriptionByCarrierConfigAndNotifyComplete(int phoneId, String configPackageName, PersistableBundle config, Message onComplete) { post(() -> { updateSubscriptionByCarrierConfig(phoneId, configPackageName, config); onComplete.sendToTarget(); }); } private String getDefaultCarrierServicePackageName() { CarrierConfigManager configManager = (CarrierConfigManager) mContext.getSystemService(Context.CARRIER_CONFIG_SERVICE); return configManager.getDefaultCarrierServicePackageName(); } private boolean isCarrierServicePackage(int phoneId, String pkgName) { if (pkgName.equals(getDefaultCarrierServicePackageName())) return false; List<String> carrierPackageNames = TelephonyManager.from(mContext) .getCarrierPackageNamesForIntentAndPhone( new Intent(CarrierService.CARRIER_SERVICE_INTERFACE), phoneId); if (DBG) logd("Carrier Packages For Subscription = " + carrierPackageNames); return carrierPackageNames != null && carrierPackageNames.contains(pkgName); } /** * Update the currently active Subscription based on information from CarrierConfig */ @VisibleForTesting public void updateSubscriptionByCarrierConfig( int phoneId, String configPackageName, PersistableBundle config) { if (!SubscriptionManager.isValidPhoneId(phoneId) || TextUtils.isEmpty(configPackageName) || config == null) { if (DBG) { logd("In updateSubscriptionByCarrierConfig(): phoneId=" + phoneId + " configPackageName=" + configPackageName + " config=" + ((config == null) ? "null" : config.hashCode())); } return; } SubscriptionController sc = SubscriptionController.getInstance(); if (sc == null) { loge("SubscriptionController was null"); return; } int currentSubId = sc.getSubIdUsingPhoneId(phoneId); if (!SubscriptionManager.isValidSubscriptionId(currentSubId) || currentSubId == SubscriptionManager.DEFAULT_SUBSCRIPTION_ID) { if (DBG) logd("No subscription is active for phone being updated"); return; } SubscriptionInfo currentSubInfo = sc.getSubscriptionInfo(currentSubId); if (currentSubInfo == null) { loge("Couldn't retrieve subscription info for current subscription"); return; } if (!isCarrierServicePackage(phoneId, configPackageName)) { loge("Cannot manage subId=" + currentSubId + ", carrierPackage=" + configPackageName); return; } ContentValues cv = new ContentValues(); boolean isOpportunistic = config.getBoolean( CarrierConfigManager.KEY_IS_OPPORTUNISTIC_SUBSCRIPTION_BOOL, false); if (currentSubInfo.isOpportunistic() != isOpportunistic) { if (DBG) logd("Set SubId=" + currentSubId + " isOpportunistic=" + isOpportunistic); cv.put(SubscriptionManager.IS_OPPORTUNISTIC, isOpportunistic ? "1" : "0"); } String groupUuidString = config.getString(CarrierConfigManager.KEY_SUBSCRIPTION_GROUP_UUID_STRING, ""); ParcelUuid groupId = null; if (!TextUtils.isEmpty(groupUuidString)) { try { // Update via a UUID Structure to ensure consistent formatting ParcelUuid groupUuid = ParcelUuid.fromString(groupUuidString); if (groupUuid.equals(REMOVE_GROUP_UUID) && currentSubInfo.getGroupUuid() != null) { cv.put(SubscriptionManager.GROUP_UUID, (String) null); if (DBG) logd("Group Removed for" + currentSubId); } else { // TODO: validate and update group owner information once feasible. cv.put(SubscriptionManager.GROUP_UUID, groupUuid.toString()); if (DBG) logd("Group Added for" + currentSubId); } } catch (IllegalArgumentException e) { loge("Invalid Group UUID=" + groupUuidString); } } if (cv.size() > 0 && mContext.getContentResolver().update(SubscriptionManager .getUriForSubscriptionId(currentSubId), cv, null, null) > 0) { sc.refreshCachedActiveSubscriptionInfoList(); sc.notifySubscriptionInfoChanged(); } } private static int findSubscriptionInfoForIccid(List<SubscriptionInfo> list, String iccid) { for (int i = 0; i < list.size(); i++) { if (TextUtils.equals(iccid, list.get(i).getIccId())) { Loading tests/telephonytests/src/com/android/internal/telephony/SubscriptionInfoUpdaterTest.java +126 −0 Original line number Diff line number Diff line Loading @@ -19,6 +19,7 @@ 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.assertNull; import static org.junit.Assert.assertTrue; import static org.mockito.ArgumentMatchers.isNull; import static org.mockito.Mockito.any; Loading @@ -40,6 +41,8 @@ import android.content.pm.IPackageManager; import android.content.pm.UserInfo; import android.net.Uri; import android.os.HandlerThread; import android.os.ParcelUuid; import android.os.PersistableBundle; import android.service.euicc.EuiccProfileInfo; import android.service.euicc.EuiccService; import android.service.euicc.GetEuiccProfileInfoListResult; Loading @@ -64,6 +67,7 @@ import org.mockito.stubbing.Answer; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.HashMap; import java.util.List; Loading Loading @@ -571,4 +575,126 @@ public class SubscriptionInfoUpdaterTest extends TelephonyTest { eq(FAKE_SUB_ID_1)); verify(mSubscriptionController, times(0)).clearSubInfo(); } PersistableBundle getCarrierConfigForSubInfoUpdate( boolean isOpportunistic, String groupUuid) { PersistableBundle p = new PersistableBundle(); p.putBoolean(CarrierConfigManager.KEY_IS_OPPORTUNISTIC_SUBSCRIPTION_BOOL, isOpportunistic); p.putString(CarrierConfigManager.KEY_SUBSCRIPTION_GROUP_UUID_STRING, groupUuid); return p; } @Test @SmallTest public void testUpdateFromCarrierConfigOpportunisticUnchanged() throws Exception { final int phoneId = mPhone.getPhoneId(); String carrierPackageName = "FakeCarrierPackageName"; doReturn(FAKE_SUB_ID_1).when(mSubscriptionController).getSubIdUsingPhoneId(phoneId); doReturn(mSubInfo).when(mSubscriptionController).getSubscriptionInfo(eq(FAKE_SUB_ID_1)); doReturn(Collections.singletonList(carrierPackageName)).when(mTelephonyManager) .getCarrierPackageNamesForIntentAndPhone(any(), eq(phoneId)); ((MockContentResolver) mContext.getContentResolver()).addProvider( SubscriptionManager.CONTENT_URI.getAuthority(), new FakeSubscriptionContentProvider()); mUpdater.updateSubscriptionByCarrierConfig(mPhone.getPhoneId(), carrierPackageName, new PersistableBundle()); verify(mContentProvider, never()).update(any(), any(), any(), any()); verify(mSubscriptionController, never()).refreshCachedActiveSubscriptionInfoList(); verify(mSubscriptionController, never()).notifySubscriptionInfoChanged(); } @Test @SmallTest public void testUpdateFromCarrierConfigOpportunisticSetOpportunistic() throws Exception { final int phoneId = mPhone.getPhoneId(); PersistableBundle carrierConfig = getCarrierConfigForSubInfoUpdate( true, ""); String carrierPackageName = "FakeCarrierPackageName"; doReturn(FAKE_SUB_ID_1).when(mSubscriptionController).getSubIdUsingPhoneId(phoneId); doReturn(mSubInfo).when(mSubscriptionController).getSubscriptionInfo(eq(FAKE_SUB_ID_1)); doReturn(false).when(mSubInfo).isOpportunistic(); doReturn(Collections.singletonList(carrierPackageName)).when(mTelephonyManager) .getCarrierPackageNamesForIntentAndPhone(any(), eq(phoneId)); ((MockContentResolver) mContext.getContentResolver()).addProvider( SubscriptionManager.CONTENT_URI.getAuthority(), new FakeSubscriptionContentProvider()); mUpdater.updateSubscriptionByCarrierConfig(mPhone.getPhoneId(), carrierPackageName, carrierConfig); ArgumentCaptor<ContentValues> cvCaptor = ArgumentCaptor.forClass(ContentValues.class); verify(mContentProvider, times(1)).update( eq(SubscriptionManager.getUriForSubscriptionId(FAKE_SUB_ID_1)), cvCaptor.capture(), eq(null), eq(null)); assertEquals(1, cvCaptor.getValue().getAsInteger( SubscriptionManager.IS_OPPORTUNISTIC).intValue()); assertEquals(1, cvCaptor.getValue().size()); verify(mSubscriptionController, times(1)).refreshCachedActiveSubscriptionInfoList(); verify(mSubscriptionController, times(1)).notifySubscriptionInfoChanged(); } @Test @SmallTest public void testUpdateFromCarrierConfigOpportunisticAddToGroup() throws Exception { final int phoneId = mPhone.getPhoneId(); PersistableBundle carrierConfig = getCarrierConfigForSubInfoUpdate( true, "11111111-2222-3333-4444-555555555555"); String carrierPackageName = "FakeCarrierPackageName"; doReturn(FAKE_SUB_ID_1).when(mSubscriptionController).getSubIdUsingPhoneId(phoneId); doReturn(mSubInfo).when(mSubscriptionController).getSubscriptionInfo(eq(FAKE_SUB_ID_1)); doReturn(Collections.singletonList(carrierPackageName)).when(mTelephonyManager) .getCarrierPackageNamesForIntentAndPhone(any(), eq(phoneId)); ((MockContentResolver) mContext.getContentResolver()).addProvider( SubscriptionManager.CONTENT_URI.getAuthority(), new FakeSubscriptionContentProvider()); mUpdater.updateSubscriptionByCarrierConfig(mPhone.getPhoneId(), carrierPackageName, carrierConfig); ArgumentCaptor<ContentValues> cvCaptor = ArgumentCaptor.forClass(ContentValues.class); verify(mContentProvider, times(1)).update( eq(SubscriptionManager.getUriForSubscriptionId(FAKE_SUB_ID_1)), cvCaptor.capture(), eq(null), eq(null)); assertEquals(1, cvCaptor.getValue().getAsInteger( SubscriptionManager.IS_OPPORTUNISTIC).intValue()); assertEquals("11111111-2222-3333-4444-555555555555", cvCaptor.getValue().getAsString(SubscriptionManager.GROUP_UUID)); assertEquals(2, cvCaptor.getValue().size()); } @Test @SmallTest public void testUpdateFromCarrierConfigOpportunisticRemoveFromGroup() throws Exception { final int phoneId = mPhone.getPhoneId(); PersistableBundle carrierConfig = getCarrierConfigForSubInfoUpdate( true, "00000000-0000-0000-0000-000000000000"); String carrierPackageName = "FakeCarrierPackageName"; doReturn(FAKE_SUB_ID_1).when(mSubscriptionController).getSubIdUsingPhoneId(phoneId); doReturn(mSubInfo).when(mSubscriptionController).getSubscriptionInfo(eq(FAKE_SUB_ID_1)); doReturn(ParcelUuid.fromString("11111111-2222-3333-4444-555555555555")) .when(mSubInfo).getGroupUuid(); doReturn(Collections.singletonList(carrierPackageName)).when(mTelephonyManager) .getCarrierPackageNamesForIntentAndPhone(any(), eq(phoneId)); ((MockContentResolver) mContext.getContentResolver()).addProvider( SubscriptionManager.CONTENT_URI.getAuthority(), new FakeSubscriptionContentProvider()); mUpdater.updateSubscriptionByCarrierConfig(mPhone.getPhoneId(), carrierPackageName, carrierConfig); ArgumentCaptor<ContentValues> cvCaptor = ArgumentCaptor.forClass(ContentValues.class); verify(mContentProvider, times(1)).update( eq(SubscriptionManager.getUriForSubscriptionId(FAKE_SUB_ID_1)), cvCaptor.capture(), eq(null), eq(null)); assertEquals(1, cvCaptor.getValue().getAsInteger( SubscriptionManager.IS_OPPORTUNISTIC).intValue()); assertNull(cvCaptor.getValue().getAsString(SubscriptionManager.GROUP_UUID)); assertEquals(2, cvCaptor.getValue().size()); } } Loading
src/java/com/android/internal/telephony/SubscriptionController.java +14 −0 Original line number Diff line number Diff line Loading @@ -547,6 +547,20 @@ public class SubscriptionController extends ISub.Stub { return null; } /** * Get a single subscription info record for a given subscription. * * @param subId the subId to query. * * @hide */ public SubscriptionInfo getSubscriptionInfo(int subId) { List<SubscriptionInfo> subInfoList = getSubInfo( SubscriptionManager.UNIQUE_KEY_SUBSCRIPTION_ID + "=" + subId, null); if (subInfoList == null || subInfoList.isEmpty()) return null; return subInfoList.get(0); } /** * Get the active SubscriptionInfo associated with the iccId * @param iccId the IccId of SIM card Loading
src/java/com/android/internal/telephony/SubscriptionInfoUpdater.java +112 −2 Original line number Diff line number Diff line Loading @@ -32,12 +32,15 @@ import android.os.Handler; import android.os.IRemoteCallback; import android.os.Looper; import android.os.Message; import android.os.ParcelUuid; import android.os.PersistableBundle; import android.os.RemoteException; import android.os.ServiceManager; import android.preference.PreferenceManager; import android.provider.Settings; import android.provider.Settings.Global; import android.provider.Settings.SettingNotFoundException; import android.service.carrier.CarrierService; import android.service.euicc.EuiccProfileInfo; import android.service.euicc.EuiccService; import android.service.euicc.GetEuiccProfileInfoListResult; Loading Loading @@ -90,6 +93,9 @@ public class SubscriptionInfoUpdater extends Handler { private static final String ICCID_STRING_FOR_NO_SIM = ""; private static final ParcelUuid REMOVE_GROUP_UUID = ParcelUuid.fromString(CarrierConfigManager.REMOVE_GROUP_UUID_STRING); // Key used to read/write the current IMSI. Updated on SIM_STATE_CHANGED - LOADED. public static final String CURR_SUBID = "curr_subid"; Loading @@ -111,6 +117,8 @@ public class SubscriptionInfoUpdater extends Handler { private int mCurrentlyActiveUserId; private CarrierServiceBindHelper mCarrierServiceBindHelper; // TODO: The SubscriptionController instance should be passed in here from PhoneFactory // rather than invoking the static getter all over the place. public SubscriptionInfoUpdater( Looper looper, Context context, Phone[] phone, CommandsInterface[] ci) { this(looper, context, phone, ci, Loading Loading @@ -512,8 +520,8 @@ public class SubscriptionInfoUpdater extends Handler { } private void updateCarrierServices(int slotId, String simState) { CarrierConfigManager configManager = (CarrierConfigManager) mContext.getSystemService(Context.CARRIER_CONFIG_SERVICE); CarrierConfigManager configManager = (CarrierConfigManager) mContext.getSystemService(Context.CARRIER_CONFIG_SERVICE); configManager.updateConfigForPhoneId(slotId, simState); mCarrierServiceBindHelper.updateForPhoneId(slotId, simState); } Loading Loading @@ -752,6 +760,108 @@ public class SubscriptionInfoUpdater extends Handler { return hasChanges; } /** * Called by CarrierConfigLoader to update the subscription before sending a broadcast. */ public void updateSubscriptionByCarrierConfigAndNotifyComplete(int phoneId, String configPackageName, PersistableBundle config, Message onComplete) { post(() -> { updateSubscriptionByCarrierConfig(phoneId, configPackageName, config); onComplete.sendToTarget(); }); } private String getDefaultCarrierServicePackageName() { CarrierConfigManager configManager = (CarrierConfigManager) mContext.getSystemService(Context.CARRIER_CONFIG_SERVICE); return configManager.getDefaultCarrierServicePackageName(); } private boolean isCarrierServicePackage(int phoneId, String pkgName) { if (pkgName.equals(getDefaultCarrierServicePackageName())) return false; List<String> carrierPackageNames = TelephonyManager.from(mContext) .getCarrierPackageNamesForIntentAndPhone( new Intent(CarrierService.CARRIER_SERVICE_INTERFACE), phoneId); if (DBG) logd("Carrier Packages For Subscription = " + carrierPackageNames); return carrierPackageNames != null && carrierPackageNames.contains(pkgName); } /** * Update the currently active Subscription based on information from CarrierConfig */ @VisibleForTesting public void updateSubscriptionByCarrierConfig( int phoneId, String configPackageName, PersistableBundle config) { if (!SubscriptionManager.isValidPhoneId(phoneId) || TextUtils.isEmpty(configPackageName) || config == null) { if (DBG) { logd("In updateSubscriptionByCarrierConfig(): phoneId=" + phoneId + " configPackageName=" + configPackageName + " config=" + ((config == null) ? "null" : config.hashCode())); } return; } SubscriptionController sc = SubscriptionController.getInstance(); if (sc == null) { loge("SubscriptionController was null"); return; } int currentSubId = sc.getSubIdUsingPhoneId(phoneId); if (!SubscriptionManager.isValidSubscriptionId(currentSubId) || currentSubId == SubscriptionManager.DEFAULT_SUBSCRIPTION_ID) { if (DBG) logd("No subscription is active for phone being updated"); return; } SubscriptionInfo currentSubInfo = sc.getSubscriptionInfo(currentSubId); if (currentSubInfo == null) { loge("Couldn't retrieve subscription info for current subscription"); return; } if (!isCarrierServicePackage(phoneId, configPackageName)) { loge("Cannot manage subId=" + currentSubId + ", carrierPackage=" + configPackageName); return; } ContentValues cv = new ContentValues(); boolean isOpportunistic = config.getBoolean( CarrierConfigManager.KEY_IS_OPPORTUNISTIC_SUBSCRIPTION_BOOL, false); if (currentSubInfo.isOpportunistic() != isOpportunistic) { if (DBG) logd("Set SubId=" + currentSubId + " isOpportunistic=" + isOpportunistic); cv.put(SubscriptionManager.IS_OPPORTUNISTIC, isOpportunistic ? "1" : "0"); } String groupUuidString = config.getString(CarrierConfigManager.KEY_SUBSCRIPTION_GROUP_UUID_STRING, ""); ParcelUuid groupId = null; if (!TextUtils.isEmpty(groupUuidString)) { try { // Update via a UUID Structure to ensure consistent formatting ParcelUuid groupUuid = ParcelUuid.fromString(groupUuidString); if (groupUuid.equals(REMOVE_GROUP_UUID) && currentSubInfo.getGroupUuid() != null) { cv.put(SubscriptionManager.GROUP_UUID, (String) null); if (DBG) logd("Group Removed for" + currentSubId); } else { // TODO: validate and update group owner information once feasible. cv.put(SubscriptionManager.GROUP_UUID, groupUuid.toString()); if (DBG) logd("Group Added for" + currentSubId); } } catch (IllegalArgumentException e) { loge("Invalid Group UUID=" + groupUuidString); } } if (cv.size() > 0 && mContext.getContentResolver().update(SubscriptionManager .getUriForSubscriptionId(currentSubId), cv, null, null) > 0) { sc.refreshCachedActiveSubscriptionInfoList(); sc.notifySubscriptionInfoChanged(); } } private static int findSubscriptionInfoForIccid(List<SubscriptionInfo> list, String iccid) { for (int i = 0; i < list.size(); i++) { if (TextUtils.equals(iccid, list.get(i).getIccId())) { Loading
tests/telephonytests/src/com/android/internal/telephony/SubscriptionInfoUpdaterTest.java +126 −0 Original line number Diff line number Diff line Loading @@ -19,6 +19,7 @@ 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.assertNull; import static org.junit.Assert.assertTrue; import static org.mockito.ArgumentMatchers.isNull; import static org.mockito.Mockito.any; Loading @@ -40,6 +41,8 @@ import android.content.pm.IPackageManager; import android.content.pm.UserInfo; import android.net.Uri; import android.os.HandlerThread; import android.os.ParcelUuid; import android.os.PersistableBundle; import android.service.euicc.EuiccProfileInfo; import android.service.euicc.EuiccService; import android.service.euicc.GetEuiccProfileInfoListResult; Loading @@ -64,6 +67,7 @@ import org.mockito.stubbing.Answer; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.HashMap; import java.util.List; Loading Loading @@ -571,4 +575,126 @@ public class SubscriptionInfoUpdaterTest extends TelephonyTest { eq(FAKE_SUB_ID_1)); verify(mSubscriptionController, times(0)).clearSubInfo(); } PersistableBundle getCarrierConfigForSubInfoUpdate( boolean isOpportunistic, String groupUuid) { PersistableBundle p = new PersistableBundle(); p.putBoolean(CarrierConfigManager.KEY_IS_OPPORTUNISTIC_SUBSCRIPTION_BOOL, isOpportunistic); p.putString(CarrierConfigManager.KEY_SUBSCRIPTION_GROUP_UUID_STRING, groupUuid); return p; } @Test @SmallTest public void testUpdateFromCarrierConfigOpportunisticUnchanged() throws Exception { final int phoneId = mPhone.getPhoneId(); String carrierPackageName = "FakeCarrierPackageName"; doReturn(FAKE_SUB_ID_1).when(mSubscriptionController).getSubIdUsingPhoneId(phoneId); doReturn(mSubInfo).when(mSubscriptionController).getSubscriptionInfo(eq(FAKE_SUB_ID_1)); doReturn(Collections.singletonList(carrierPackageName)).when(mTelephonyManager) .getCarrierPackageNamesForIntentAndPhone(any(), eq(phoneId)); ((MockContentResolver) mContext.getContentResolver()).addProvider( SubscriptionManager.CONTENT_URI.getAuthority(), new FakeSubscriptionContentProvider()); mUpdater.updateSubscriptionByCarrierConfig(mPhone.getPhoneId(), carrierPackageName, new PersistableBundle()); verify(mContentProvider, never()).update(any(), any(), any(), any()); verify(mSubscriptionController, never()).refreshCachedActiveSubscriptionInfoList(); verify(mSubscriptionController, never()).notifySubscriptionInfoChanged(); } @Test @SmallTest public void testUpdateFromCarrierConfigOpportunisticSetOpportunistic() throws Exception { final int phoneId = mPhone.getPhoneId(); PersistableBundle carrierConfig = getCarrierConfigForSubInfoUpdate( true, ""); String carrierPackageName = "FakeCarrierPackageName"; doReturn(FAKE_SUB_ID_1).when(mSubscriptionController).getSubIdUsingPhoneId(phoneId); doReturn(mSubInfo).when(mSubscriptionController).getSubscriptionInfo(eq(FAKE_SUB_ID_1)); doReturn(false).when(mSubInfo).isOpportunistic(); doReturn(Collections.singletonList(carrierPackageName)).when(mTelephonyManager) .getCarrierPackageNamesForIntentAndPhone(any(), eq(phoneId)); ((MockContentResolver) mContext.getContentResolver()).addProvider( SubscriptionManager.CONTENT_URI.getAuthority(), new FakeSubscriptionContentProvider()); mUpdater.updateSubscriptionByCarrierConfig(mPhone.getPhoneId(), carrierPackageName, carrierConfig); ArgumentCaptor<ContentValues> cvCaptor = ArgumentCaptor.forClass(ContentValues.class); verify(mContentProvider, times(1)).update( eq(SubscriptionManager.getUriForSubscriptionId(FAKE_SUB_ID_1)), cvCaptor.capture(), eq(null), eq(null)); assertEquals(1, cvCaptor.getValue().getAsInteger( SubscriptionManager.IS_OPPORTUNISTIC).intValue()); assertEquals(1, cvCaptor.getValue().size()); verify(mSubscriptionController, times(1)).refreshCachedActiveSubscriptionInfoList(); verify(mSubscriptionController, times(1)).notifySubscriptionInfoChanged(); } @Test @SmallTest public void testUpdateFromCarrierConfigOpportunisticAddToGroup() throws Exception { final int phoneId = mPhone.getPhoneId(); PersistableBundle carrierConfig = getCarrierConfigForSubInfoUpdate( true, "11111111-2222-3333-4444-555555555555"); String carrierPackageName = "FakeCarrierPackageName"; doReturn(FAKE_SUB_ID_1).when(mSubscriptionController).getSubIdUsingPhoneId(phoneId); doReturn(mSubInfo).when(mSubscriptionController).getSubscriptionInfo(eq(FAKE_SUB_ID_1)); doReturn(Collections.singletonList(carrierPackageName)).when(mTelephonyManager) .getCarrierPackageNamesForIntentAndPhone(any(), eq(phoneId)); ((MockContentResolver) mContext.getContentResolver()).addProvider( SubscriptionManager.CONTENT_URI.getAuthority(), new FakeSubscriptionContentProvider()); mUpdater.updateSubscriptionByCarrierConfig(mPhone.getPhoneId(), carrierPackageName, carrierConfig); ArgumentCaptor<ContentValues> cvCaptor = ArgumentCaptor.forClass(ContentValues.class); verify(mContentProvider, times(1)).update( eq(SubscriptionManager.getUriForSubscriptionId(FAKE_SUB_ID_1)), cvCaptor.capture(), eq(null), eq(null)); assertEquals(1, cvCaptor.getValue().getAsInteger( SubscriptionManager.IS_OPPORTUNISTIC).intValue()); assertEquals("11111111-2222-3333-4444-555555555555", cvCaptor.getValue().getAsString(SubscriptionManager.GROUP_UUID)); assertEquals(2, cvCaptor.getValue().size()); } @Test @SmallTest public void testUpdateFromCarrierConfigOpportunisticRemoveFromGroup() throws Exception { final int phoneId = mPhone.getPhoneId(); PersistableBundle carrierConfig = getCarrierConfigForSubInfoUpdate( true, "00000000-0000-0000-0000-000000000000"); String carrierPackageName = "FakeCarrierPackageName"; doReturn(FAKE_SUB_ID_1).when(mSubscriptionController).getSubIdUsingPhoneId(phoneId); doReturn(mSubInfo).when(mSubscriptionController).getSubscriptionInfo(eq(FAKE_SUB_ID_1)); doReturn(ParcelUuid.fromString("11111111-2222-3333-4444-555555555555")) .when(mSubInfo).getGroupUuid(); doReturn(Collections.singletonList(carrierPackageName)).when(mTelephonyManager) .getCarrierPackageNamesForIntentAndPhone(any(), eq(phoneId)); ((MockContentResolver) mContext.getContentResolver()).addProvider( SubscriptionManager.CONTENT_URI.getAuthority(), new FakeSubscriptionContentProvider()); mUpdater.updateSubscriptionByCarrierConfig(mPhone.getPhoneId(), carrierPackageName, carrierConfig); ArgumentCaptor<ContentValues> cvCaptor = ArgumentCaptor.forClass(ContentValues.class); verify(mContentProvider, times(1)).update( eq(SubscriptionManager.getUriForSubscriptionId(FAKE_SUB_ID_1)), cvCaptor.capture(), eq(null), eq(null)); assertEquals(1, cvCaptor.getValue().getAsInteger( SubscriptionManager.IS_OPPORTUNISTIC).intValue()); assertNull(cvCaptor.getValue().getAsString(SubscriptionManager.GROUP_UUID)); assertEquals(2, cvCaptor.getValue().size()); } }