Loading src/java/com/android/internal/telephony/PhoneFactory.java +8 −3 Original line number Diff line number Diff line Loading @@ -353,9 +353,14 @@ public class PhoneFactory { return ImsPhoneFactory.makePhone(sContext, phoneNotifier, defaultPhone); } /** Request a refresh of the embedded subscription list. */ public static void refreshEmbeddedSubscriptionList() { sSubInfoRecordUpdater.refreshEmbeddedSubscriptionList(); /** * Request a refresh of the embedded subscription list. * * @param callback Optional callback to execute after the refresh completes. Must terminate * quickly as it will be called from SubscriptionInfoUpdater's handler thread. */ public static void requestEmbeddedSubscriptionInfoListRefresh(@Nullable Runnable callback) { sSubInfoRecordUpdater.requestEmbeddedSubscriptionInfoListRefresh(callback); } /** Loading src/java/com/android/internal/telephony/SubscriptionController.java +13 −1 Original line number Diff line number Diff line Loading @@ -17,6 +17,7 @@ package com.android.internal.telephony; import android.Manifest; import android.annotation.Nullable; import android.app.AppOpsManager; import android.content.ContentResolver; import android.content.ContentValues; Loading Loading @@ -813,12 +814,23 @@ public class SubscriptionController extends ISub.Stub { "requestEmbeddedSubscriptionInfoListRefresh"); long token = Binder.clearCallingIdentity(); try { PhoneFactory.refreshEmbeddedSubscriptionList(); PhoneFactory.requestEmbeddedSubscriptionInfoListRefresh(null /* callback */); } finally { Binder.restoreCallingIdentity(token); } } /** * Asynchronously refresh the embedded subscription info list. * * @param callback Optional callback to execute after the refresh completes. Must terminate * quickly as it will be called from SubscriptionInfoUpdater's handler thread. */ // No permission check needed as this is not exposed via AIDL. public void requestEmbeddedSubscriptionInfoListRefresh(@Nullable Runnable callback) { PhoneFactory.requestEmbeddedSubscriptionInfoListRefresh(callback); } /** * Add a new SubInfoRecord to subinfo database if needed * @param iccId the IccId of the SIM card Loading src/java/com/android/internal/telephony/SubscriptionInfoUpdater.java +6 −2 Original line number Diff line number Diff line Loading @@ -16,6 +16,7 @@ package com.android.internal.telephony; import android.annotation.Nullable; import android.app.ActivityManager; import android.app.UserSwitchObserver; import android.content.BroadcastReceiver; Loading Loading @@ -353,6 +354,9 @@ public class SubscriptionInfoUpdater extends Handler { updateEmbeddedSubscriptions(); SubscriptionController.getInstance().notifySubscriptionInfoChanged(); } if (msg.obj != null) { ((Runnable) msg.obj).run(); } break; default: Loading @@ -360,8 +364,8 @@ public class SubscriptionInfoUpdater extends Handler { } } void refreshEmbeddedSubscriptionList() { sendEmptyMessage(EVENT_REFRESH_EMBEDDED_SUBSCRIPTIONS); void requestEmbeddedSubscriptionInfoListRefresh(@Nullable Runnable callback) { sendMessage(obtainMessage(EVENT_REFRESH_EMBEDDED_SUBSCRIPTIONS, callback)); } private static class QueryIccIdUserObj { Loading src/java/com/android/internal/telephony/euicc/EuiccController.java +17 −8 Original line number Diff line number Diff line Loading @@ -397,8 +397,9 @@ public class EuiccController extends IEuiccController.Stub { if (!switchAfterDownload) { // Since we're not switching, nothing will trigger a // subscription list refresh on its own, so request one here. SubscriptionController.getInstance() .requestEmbeddedSubscriptionInfoListRefresh(); refreshSubscriptionsAndSendResult( callbackIntent, resultCode, extrasIntent); return; } break; case EuiccService.RESULT_MUST_DEACTIVATE_SIM: Loading Loading @@ -587,9 +588,9 @@ public class EuiccController extends IEuiccController.Stub { switch (result) { case EuiccService.RESULT_OK: resultCode = OK; SubscriptionController.getInstance() .requestEmbeddedSubscriptionInfoListRefresh(); break; refreshSubscriptionsAndSendResult( callbackIntent, resultCode, extrasIntent); return; default: resultCode = ERROR; extrasIntent.putExtra( Loading Loading @@ -783,9 +784,9 @@ public class EuiccController extends IEuiccController.Stub { switch (result) { case EuiccService.RESULT_OK: resultCode = OK; SubscriptionController.getInstance() .requestEmbeddedSubscriptionInfoListRefresh(); break; refreshSubscriptionsAndSendResult( callbackIntent, resultCode, extrasIntent); return; default: resultCode = ERROR; extrasIntent.putExtra( Loading @@ -807,6 +808,14 @@ public class EuiccController extends IEuiccController.Stub { } } /** Refresh the embedded subscription list and dispatch the given result upon completion. */ @VisibleForTesting(visibility = VisibleForTesting.Visibility.PRIVATE) public void refreshSubscriptionsAndSendResult( PendingIntent callbackIntent, int resultCode, Intent extrasIntent) { SubscriptionController.getInstance() .requestEmbeddedSubscriptionInfoListRefresh( () -> sendResult(callbackIntent, resultCode, extrasIntent)); } /** Dispatch the given callback intent with the given result code and data. */ @VisibleForTesting(visibility = VisibleForTesting.Visibility.PRIVATE) Loading tests/telephonytests/src/com/android/internal/telephony/euicc/EuiccControllerTest.java +28 −0 Original line number Diff line number Diff line Loading @@ -16,8 +16,10 @@ package com.android.internal.telephony.euicc; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyBoolean; import static org.mockito.ArgumentMatchers.anyInt; Loading Loading @@ -114,6 +116,9 @@ public class EuiccControllerTest extends TelephonyTest { private int mResultCode; private Intent mExtrasIntent; // Whether refreshSubscriptionsAndSendResult was called. private boolean mCalledRefreshSubscriptionsAndSendResult; TestEuiccController(Context context, EuiccConnector connector) { super(context, connector); } Loading @@ -133,6 +138,13 @@ public class EuiccControllerTest extends TelephonyTest { mResultCode = resultCode; mExtrasIntent = extrasIntent; } @Override public void refreshSubscriptionsAndSendResult( PendingIntent callbackIntent, int resultCode, Intent extrasIntent) { mCalledRefreshSubscriptionsAndSendResult = true; sendResult(callbackIntent, resultCode, extrasIntent); } } @Before Loading Loading @@ -340,6 +352,17 @@ public class EuiccControllerTest extends TelephonyTest { callDownloadSubscription(SUBSCRIPTION, true /* switchAfterDownload */, true /* complete */, EuiccService.RESULT_OK, "whatever" /* callingPackage */); verifyIntentSent(EuiccManager.EMBEDDED_SUBSCRIPTION_RESULT_OK, 0 /* detailedCode */); // switchAfterDownload = true so no refresh should occur. assertFalse(mController.mCalledRefreshSubscriptionsAndSendResult); } @Test public void testDownloadSubscription_noSwitch_success() throws Exception { setHasWriteEmbeddedPermission(true); callDownloadSubscription(SUBSCRIPTION, false /* switchAfterDownload */, true /* complete */, EuiccService.RESULT_OK, "whatever" /* callingPackage */); verifyIntentSent(EuiccManager.EMBEDDED_SUBSCRIPTION_RESULT_OK, 0 /* detailedCode */); assertTrue(mController.mCalledRefreshSubscriptionsAndSendResult); } @Test Loading Loading @@ -399,6 +422,8 @@ public class EuiccControllerTest extends TelephonyTest { callDownloadSubscription(SUBSCRIPTION, true /* switchAfterDownload */, true /* complete */, EuiccService.RESULT_OK, PACKAGE_NAME /* callingPackage */); verifyIntentSent(EuiccManager.EMBEDDED_SUBSCRIPTION_RESULT_OK, 0 /* detailedCode */); // switchAfterDownload = true so no refresh should occur. assertFalse(mController.mCalledRefreshSubscriptionsAndSendResult); } @Test Loading Loading @@ -481,6 +506,7 @@ public class EuiccControllerTest extends TelephonyTest { SUBSCRIPTION_ID, ICC_ID, true /* complete */, EuiccService.RESULT_OK, "whatever" /* callingPackage */); verifyIntentSent(EuiccManager.EMBEDDED_SUBSCRIPTION_RESULT_OK, 0 /* detailedCode */); assertTrue(mController.mCalledRefreshSubscriptionsAndSendResult); } @Test Loading @@ -502,6 +528,7 @@ public class EuiccControllerTest extends TelephonyTest { callDeleteSubscription( SUBSCRIPTION_ID, ICC_ID, true /* complete */, EuiccService.RESULT_OK, PACKAGE_NAME); verifyIntentSent(EuiccManager.EMBEDDED_SUBSCRIPTION_RESULT_OK, 0 /* detailedCode */); assertTrue(mController.mCalledRefreshSubscriptionsAndSendResult); } @Test Loading Loading @@ -692,6 +719,7 @@ public class EuiccControllerTest extends TelephonyTest { setHasWriteEmbeddedPermission(true); callEraseSubscriptions(true /* complete */, EuiccService.RESULT_OK); verifyIntentSent(EuiccManager.EMBEDDED_SUBSCRIPTION_RESULT_OK, 0 /* detailedCode */); assertTrue(mController.mCalledRefreshSubscriptionsAndSendResult); } private void setGetEidPermissions( Loading Loading
src/java/com/android/internal/telephony/PhoneFactory.java +8 −3 Original line number Diff line number Diff line Loading @@ -353,9 +353,14 @@ public class PhoneFactory { return ImsPhoneFactory.makePhone(sContext, phoneNotifier, defaultPhone); } /** Request a refresh of the embedded subscription list. */ public static void refreshEmbeddedSubscriptionList() { sSubInfoRecordUpdater.refreshEmbeddedSubscriptionList(); /** * Request a refresh of the embedded subscription list. * * @param callback Optional callback to execute after the refresh completes. Must terminate * quickly as it will be called from SubscriptionInfoUpdater's handler thread. */ public static void requestEmbeddedSubscriptionInfoListRefresh(@Nullable Runnable callback) { sSubInfoRecordUpdater.requestEmbeddedSubscriptionInfoListRefresh(callback); } /** Loading
src/java/com/android/internal/telephony/SubscriptionController.java +13 −1 Original line number Diff line number Diff line Loading @@ -17,6 +17,7 @@ package com.android.internal.telephony; import android.Manifest; import android.annotation.Nullable; import android.app.AppOpsManager; import android.content.ContentResolver; import android.content.ContentValues; Loading Loading @@ -813,12 +814,23 @@ public class SubscriptionController extends ISub.Stub { "requestEmbeddedSubscriptionInfoListRefresh"); long token = Binder.clearCallingIdentity(); try { PhoneFactory.refreshEmbeddedSubscriptionList(); PhoneFactory.requestEmbeddedSubscriptionInfoListRefresh(null /* callback */); } finally { Binder.restoreCallingIdentity(token); } } /** * Asynchronously refresh the embedded subscription info list. * * @param callback Optional callback to execute after the refresh completes. Must terminate * quickly as it will be called from SubscriptionInfoUpdater's handler thread. */ // No permission check needed as this is not exposed via AIDL. public void requestEmbeddedSubscriptionInfoListRefresh(@Nullable Runnable callback) { PhoneFactory.requestEmbeddedSubscriptionInfoListRefresh(callback); } /** * Add a new SubInfoRecord to subinfo database if needed * @param iccId the IccId of the SIM card Loading
src/java/com/android/internal/telephony/SubscriptionInfoUpdater.java +6 −2 Original line number Diff line number Diff line Loading @@ -16,6 +16,7 @@ package com.android.internal.telephony; import android.annotation.Nullable; import android.app.ActivityManager; import android.app.UserSwitchObserver; import android.content.BroadcastReceiver; Loading Loading @@ -353,6 +354,9 @@ public class SubscriptionInfoUpdater extends Handler { updateEmbeddedSubscriptions(); SubscriptionController.getInstance().notifySubscriptionInfoChanged(); } if (msg.obj != null) { ((Runnable) msg.obj).run(); } break; default: Loading @@ -360,8 +364,8 @@ public class SubscriptionInfoUpdater extends Handler { } } void refreshEmbeddedSubscriptionList() { sendEmptyMessage(EVENT_REFRESH_EMBEDDED_SUBSCRIPTIONS); void requestEmbeddedSubscriptionInfoListRefresh(@Nullable Runnable callback) { sendMessage(obtainMessage(EVENT_REFRESH_EMBEDDED_SUBSCRIPTIONS, callback)); } private static class QueryIccIdUserObj { Loading
src/java/com/android/internal/telephony/euicc/EuiccController.java +17 −8 Original line number Diff line number Diff line Loading @@ -397,8 +397,9 @@ public class EuiccController extends IEuiccController.Stub { if (!switchAfterDownload) { // Since we're not switching, nothing will trigger a // subscription list refresh on its own, so request one here. SubscriptionController.getInstance() .requestEmbeddedSubscriptionInfoListRefresh(); refreshSubscriptionsAndSendResult( callbackIntent, resultCode, extrasIntent); return; } break; case EuiccService.RESULT_MUST_DEACTIVATE_SIM: Loading Loading @@ -587,9 +588,9 @@ public class EuiccController extends IEuiccController.Stub { switch (result) { case EuiccService.RESULT_OK: resultCode = OK; SubscriptionController.getInstance() .requestEmbeddedSubscriptionInfoListRefresh(); break; refreshSubscriptionsAndSendResult( callbackIntent, resultCode, extrasIntent); return; default: resultCode = ERROR; extrasIntent.putExtra( Loading Loading @@ -783,9 +784,9 @@ public class EuiccController extends IEuiccController.Stub { switch (result) { case EuiccService.RESULT_OK: resultCode = OK; SubscriptionController.getInstance() .requestEmbeddedSubscriptionInfoListRefresh(); break; refreshSubscriptionsAndSendResult( callbackIntent, resultCode, extrasIntent); return; default: resultCode = ERROR; extrasIntent.putExtra( Loading @@ -807,6 +808,14 @@ public class EuiccController extends IEuiccController.Stub { } } /** Refresh the embedded subscription list and dispatch the given result upon completion. */ @VisibleForTesting(visibility = VisibleForTesting.Visibility.PRIVATE) public void refreshSubscriptionsAndSendResult( PendingIntent callbackIntent, int resultCode, Intent extrasIntent) { SubscriptionController.getInstance() .requestEmbeddedSubscriptionInfoListRefresh( () -> sendResult(callbackIntent, resultCode, extrasIntent)); } /** Dispatch the given callback intent with the given result code and data. */ @VisibleForTesting(visibility = VisibleForTesting.Visibility.PRIVATE) Loading
tests/telephonytests/src/com/android/internal/telephony/euicc/EuiccControllerTest.java +28 −0 Original line number Diff line number Diff line Loading @@ -16,8 +16,10 @@ package com.android.internal.telephony.euicc; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyBoolean; import static org.mockito.ArgumentMatchers.anyInt; Loading Loading @@ -114,6 +116,9 @@ public class EuiccControllerTest extends TelephonyTest { private int mResultCode; private Intent mExtrasIntent; // Whether refreshSubscriptionsAndSendResult was called. private boolean mCalledRefreshSubscriptionsAndSendResult; TestEuiccController(Context context, EuiccConnector connector) { super(context, connector); } Loading @@ -133,6 +138,13 @@ public class EuiccControllerTest extends TelephonyTest { mResultCode = resultCode; mExtrasIntent = extrasIntent; } @Override public void refreshSubscriptionsAndSendResult( PendingIntent callbackIntent, int resultCode, Intent extrasIntent) { mCalledRefreshSubscriptionsAndSendResult = true; sendResult(callbackIntent, resultCode, extrasIntent); } } @Before Loading Loading @@ -340,6 +352,17 @@ public class EuiccControllerTest extends TelephonyTest { callDownloadSubscription(SUBSCRIPTION, true /* switchAfterDownload */, true /* complete */, EuiccService.RESULT_OK, "whatever" /* callingPackage */); verifyIntentSent(EuiccManager.EMBEDDED_SUBSCRIPTION_RESULT_OK, 0 /* detailedCode */); // switchAfterDownload = true so no refresh should occur. assertFalse(mController.mCalledRefreshSubscriptionsAndSendResult); } @Test public void testDownloadSubscription_noSwitch_success() throws Exception { setHasWriteEmbeddedPermission(true); callDownloadSubscription(SUBSCRIPTION, false /* switchAfterDownload */, true /* complete */, EuiccService.RESULT_OK, "whatever" /* callingPackage */); verifyIntentSent(EuiccManager.EMBEDDED_SUBSCRIPTION_RESULT_OK, 0 /* detailedCode */); assertTrue(mController.mCalledRefreshSubscriptionsAndSendResult); } @Test Loading Loading @@ -399,6 +422,8 @@ public class EuiccControllerTest extends TelephonyTest { callDownloadSubscription(SUBSCRIPTION, true /* switchAfterDownload */, true /* complete */, EuiccService.RESULT_OK, PACKAGE_NAME /* callingPackage */); verifyIntentSent(EuiccManager.EMBEDDED_SUBSCRIPTION_RESULT_OK, 0 /* detailedCode */); // switchAfterDownload = true so no refresh should occur. assertFalse(mController.mCalledRefreshSubscriptionsAndSendResult); } @Test Loading Loading @@ -481,6 +506,7 @@ public class EuiccControllerTest extends TelephonyTest { SUBSCRIPTION_ID, ICC_ID, true /* complete */, EuiccService.RESULT_OK, "whatever" /* callingPackage */); verifyIntentSent(EuiccManager.EMBEDDED_SUBSCRIPTION_RESULT_OK, 0 /* detailedCode */); assertTrue(mController.mCalledRefreshSubscriptionsAndSendResult); } @Test Loading @@ -502,6 +528,7 @@ public class EuiccControllerTest extends TelephonyTest { callDeleteSubscription( SUBSCRIPTION_ID, ICC_ID, true /* complete */, EuiccService.RESULT_OK, PACKAGE_NAME); verifyIntentSent(EuiccManager.EMBEDDED_SUBSCRIPTION_RESULT_OK, 0 /* detailedCode */); assertTrue(mController.mCalledRefreshSubscriptionsAndSendResult); } @Test Loading Loading @@ -692,6 +719,7 @@ public class EuiccControllerTest extends TelephonyTest { setHasWriteEmbeddedPermission(true); callEraseSubscriptions(true /* complete */, EuiccService.RESULT_OK); verifyIntentSent(EuiccManager.EMBEDDED_SUBSCRIPTION_RESULT_OK, 0 /* detailedCode */); assertTrue(mController.mCalledRefreshSubscriptionsAndSendResult); } private void setGetEidPermissions( Loading