Loading src/java/com/android/internal/telephony/SubscriptionController.java +44 −5 Original line number Diff line number Diff line Loading @@ -21,6 +21,7 @@ import static android.content.pm.PackageManager.PERMISSION_GRANTED; import android.Manifest; import android.annotation.Nullable; import android.app.AppOpsManager; import android.app.PendingIntent; import android.content.ContentResolver; import android.content.ContentValues; import android.content.Context; Loading Loading @@ -615,7 +616,7 @@ public class SubscriptionController extends ISub.Stub { return; } boolean opptSubListChanged = false; boolean opptSubListChanged; synchronized (mSubInfoListLock) { mCacheActiveSubInfoList.clear(); Loading Loading @@ -2450,14 +2451,31 @@ public class SubscriptionController extends ISub.Stub { } } private boolean refreshCachedOpportunisticSubscriptionInfoList() { synchronized (mSubInfoListLock) { List<SubscriptionInfo> oldOpptCachedList = mCacheOpportunisticSubInfoList; mCacheOpportunisticSubInfoList = mCacheActiveSubInfoList.stream() .filter(subscriptionInfo -> subscriptionInfo.isOpportunistic()) .collect(Collectors.toList()); List<SubscriptionInfo> subList = getSubInfo( SubscriptionManager.IS_OPPORTUNISTIC + "=1 AND (" + SubscriptionManager.SIM_SLOT_INDEX + ">=0 OR " + SubscriptionManager.IS_EMBEDDED + "=1)", null); if (subList != null) { subList.sort(SUBSCRIPTION_INFO_COMPARATOR); } else { subList = new ArrayList<>(); } mCacheOpportunisticSubInfoList = subList; for (SubscriptionInfo info : mCacheOpportunisticSubInfoList) { if (shouldDisableSubGroup(info.getGroupUuid())) { info.setGroupDisabled(true); if (isActiveSubId(info.getSubscriptionId())) { deactivateSubscription(info); } } } if (DBG_CACHE) { if (!mCacheOpportunisticSubInfoList.isEmpty()) { Loading @@ -2473,4 +2491,25 @@ public class SubscriptionController extends ISub.Stub { return !oldOpptCachedList.equals(mCacheOpportunisticSubInfoList); } } private boolean shouldDisableSubGroup(String groupUuid) { if (groupUuid == null) return false; for (SubscriptionInfo activeInfo : mCacheActiveSubInfoList) { if (!activeInfo.isOpportunistic() && groupUuid.equals(activeInfo.getGroupUuid())) { return false; } } return true; } private void deactivateSubscription(SubscriptionInfo info) { // TODO: b/120439488 deactivate pSIM. if (info.isEmbedded()) { EuiccManager euiccManager = new EuiccManager(mContext); euiccManager.switchToSubscription(SubscriptionManager.INVALID_SUBSCRIPTION_ID, PendingIntent.getService(mContext, 0, new Intent(), 0)); } } } tests/telephonytests/src/com/android/internal/telephony/SubscriptionControllerTest.java +48 −0 Original line number Diff line number Diff line Loading @@ -469,6 +469,54 @@ public class SubscriptionControllerTest extends TelephonyTest { assertNotEquals(groupId, newGroupId); } @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(); verify(mTelephonyRegisteryMock, times(1)) .notifyOpportunisticSubscriptionInfoChanged(); // Set sub 1 and 2 into same group. int[] subIdList = new int[] {1, 2}; String groupId = mSubscriptionControllerUT.setSubscriptionGroup( subIdList, mContext.getOpPackageName()); assertNotEquals(null, groupId); 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(); 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()); } private void registerMockTelephonyRegistry() { mServiceManagerMockedServices.put("telephony.registry", mTelephonyRegisteryMock); doReturn(mTelephonyRegisteryMock).when(mTelephonyRegisteryMock) Loading Loading
src/java/com/android/internal/telephony/SubscriptionController.java +44 −5 Original line number Diff line number Diff line Loading @@ -21,6 +21,7 @@ import static android.content.pm.PackageManager.PERMISSION_GRANTED; import android.Manifest; import android.annotation.Nullable; import android.app.AppOpsManager; import android.app.PendingIntent; import android.content.ContentResolver; import android.content.ContentValues; import android.content.Context; Loading Loading @@ -615,7 +616,7 @@ public class SubscriptionController extends ISub.Stub { return; } boolean opptSubListChanged = false; boolean opptSubListChanged; synchronized (mSubInfoListLock) { mCacheActiveSubInfoList.clear(); Loading Loading @@ -2450,14 +2451,31 @@ public class SubscriptionController extends ISub.Stub { } } private boolean refreshCachedOpportunisticSubscriptionInfoList() { synchronized (mSubInfoListLock) { List<SubscriptionInfo> oldOpptCachedList = mCacheOpportunisticSubInfoList; mCacheOpportunisticSubInfoList = mCacheActiveSubInfoList.stream() .filter(subscriptionInfo -> subscriptionInfo.isOpportunistic()) .collect(Collectors.toList()); List<SubscriptionInfo> subList = getSubInfo( SubscriptionManager.IS_OPPORTUNISTIC + "=1 AND (" + SubscriptionManager.SIM_SLOT_INDEX + ">=0 OR " + SubscriptionManager.IS_EMBEDDED + "=1)", null); if (subList != null) { subList.sort(SUBSCRIPTION_INFO_COMPARATOR); } else { subList = new ArrayList<>(); } mCacheOpportunisticSubInfoList = subList; for (SubscriptionInfo info : mCacheOpportunisticSubInfoList) { if (shouldDisableSubGroup(info.getGroupUuid())) { info.setGroupDisabled(true); if (isActiveSubId(info.getSubscriptionId())) { deactivateSubscription(info); } } } if (DBG_CACHE) { if (!mCacheOpportunisticSubInfoList.isEmpty()) { Loading @@ -2473,4 +2491,25 @@ public class SubscriptionController extends ISub.Stub { return !oldOpptCachedList.equals(mCacheOpportunisticSubInfoList); } } private boolean shouldDisableSubGroup(String groupUuid) { if (groupUuid == null) return false; for (SubscriptionInfo activeInfo : mCacheActiveSubInfoList) { if (!activeInfo.isOpportunistic() && groupUuid.equals(activeInfo.getGroupUuid())) { return false; } } return true; } private void deactivateSubscription(SubscriptionInfo info) { // TODO: b/120439488 deactivate pSIM. if (info.isEmbedded()) { EuiccManager euiccManager = new EuiccManager(mContext); euiccManager.switchToSubscription(SubscriptionManager.INVALID_SUBSCRIPTION_ID, PendingIntent.getService(mContext, 0, new Intent(), 0)); } } }
tests/telephonytests/src/com/android/internal/telephony/SubscriptionControllerTest.java +48 −0 Original line number Diff line number Diff line Loading @@ -469,6 +469,54 @@ public class SubscriptionControllerTest extends TelephonyTest { assertNotEquals(groupId, newGroupId); } @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(); verify(mTelephonyRegisteryMock, times(1)) .notifyOpportunisticSubscriptionInfoChanged(); // Set sub 1 and 2 into same group. int[] subIdList = new int[] {1, 2}; String groupId = mSubscriptionControllerUT.setSubscriptionGroup( subIdList, mContext.getOpPackageName()); assertNotEquals(null, groupId); 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(); 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()); } private void registerMockTelephonyRegistry() { mServiceManagerMockedServices.put("telephony.registry", mTelephonyRegisteryMock); doReturn(mTelephonyRegisteryMock).when(mTelephonyRegisteryMock) Loading