Loading src/java/com/android/internal/telephony/euicc/EuiccConnector.java +31 −0 Original line number Diff line number Diff line Loading @@ -46,12 +46,14 @@ import android.service.euicc.IGetDownloadableSubscriptionMetadataCallback; import android.service.euicc.IGetEidCallback; import android.service.euicc.IGetEuiccInfoCallback; import android.service.euicc.IGetEuiccProfileInfoListCallback; import android.service.euicc.IGetOtaStatusCallback; import android.service.euicc.IRetainSubscriptionsForFactoryResetCallback; import android.service.euicc.ISwitchToSubscriptionCallback; import android.service.euicc.IUpdateSubscriptionNicknameCallback; import android.telephony.SubscriptionManager; import android.telephony.euicc.DownloadableSubscription; import android.telephony.euicc.EuiccInfo; import android.telephony.euicc.EuiccManager.OtaStatus; import android.text.TextUtils; import android.util.ArraySet; import android.util.Log; Loading Loading @@ -132,6 +134,7 @@ public class EuiccConnector extends StateMachine implements ServiceConnection { private static final int CMD_UPDATE_SUBSCRIPTION_NICKNAME = 108; private static final int CMD_ERASE_SUBSCRIPTIONS = 109; private static final int CMD_RETAIN_SUBSCRIPTIONS = 110; private static final int CMD_GET_OTA_STATUS = 111; private static boolean isEuiccCommand(int what) { return what >= CMD_GET_EID; Loading Loading @@ -185,6 +188,13 @@ public class EuiccConnector extends StateMachine implements ServiceConnection { void onGetEidComplete(String eid); } /** Callback class for {@link #getOtaStatus}. */ @VisibleForTesting(visibility = PACKAGE) public interface GetOtaStatusCommandCallback extends BaseEuiccCommandCallback { /** Called when the getting OTA status lookup has completed. */ void onGetOtaStatusComplete(@OtaStatus int status); } static class GetMetadataRequest { DownloadableSubscription mSubscription; boolean mForceDeactivateSim; Loading Loading @@ -373,6 +383,12 @@ public class EuiccConnector extends StateMachine implements ServiceConnection { sendMessage(CMD_GET_EID, callback); } /** Asynchronously get OTA status. */ @VisibleForTesting(visibility = PACKAGE) public void getOtaStatus(GetOtaStatusCommandCallback callback) { sendMessage(CMD_GET_OTA_STATUS, callback); } /** Asynchronously fetch metadata for the given downloadable subscription. */ @VisibleForTesting(visibility = PACKAGE) public void getDownloadableSubscriptionMetadata(DownloadableSubscription subscription, Loading Loading @@ -809,6 +825,20 @@ public class EuiccConnector extends StateMachine implements ServiceConnection { }); break; } case CMD_GET_OTA_STATUS: { mEuiccService.getOtaStatus(slotId, new IGetOtaStatusCallback.Stub() { @Override public void onSuccess(@OtaStatus int status) { sendMessage(CMD_COMMAND_COMPLETE, (Runnable) () -> { ((GetOtaStatusCommandCallback) callback) .onGetOtaStatusComplete(status); onCommandEnd(callback); }); } }); break; } default: { Log.wtf(TAG, "Unimplemented eUICC command: " + message.what); callback.onEuiccServiceUnavailable(); Loading Loading @@ -851,6 +881,7 @@ public class EuiccConnector extends StateMachine implements ServiceConnection { case CMD_GET_EUICC_INFO: case CMD_ERASE_SUBSCRIPTIONS: case CMD_RETAIN_SUBSCRIPTIONS: case CMD_GET_OTA_STATUS: return (BaseEuiccCommandCallback) message.obj; case CMD_GET_DOWNLOADABLE_SUBSCRIPTION_METADATA: return ((GetMetadataRequest) message.obj).mCallback; Loading src/java/com/android/internal/telephony/euicc/EuiccController.java +41 −0 Original line number Diff line number Diff line Loading @@ -15,6 +15,8 @@ */ package com.android.internal.telephony.euicc; import static android.telephony.euicc.EuiccManager.EUICC_OTA_STATUS_UNAVAILABLE; import android.Manifest; import android.annotation.Nullable; import android.app.AppOpsManager; Loading @@ -38,6 +40,7 @@ import android.telephony.UiccAccessRule; import android.telephony.euicc.DownloadableSubscription; import android.telephony.euicc.EuiccInfo; import android.telephony.euicc.EuiccManager; import android.telephony.euicc.EuiccManager.OtaStatus; import android.text.TextUtils; import android.util.Log; Loading Loading @@ -169,6 +172,25 @@ public class EuiccController extends IEuiccController.Stub { } } /** * Return the current status of OTA update. * * <p>For API simplicity, this call blocks until completion; while it requires an IPC to load, * that IPC should generally be fast. */ @Override public @OtaStatus int getOtaStatus() { if (!callerCanWriteEmbeddedSubscriptions()) { throw new SecurityException("Must have WRITE_EMBEDDED_SUBSCRIPTIONS to get OTA status"); } long token = Binder.clearCallingIdentity(); try { return blockingGetOtaStatusFromEuiccService(); } finally { Binder.restoreCallingIdentity(token); } } @Override public void getDownloadableSubscriptionMetadata(DownloadableSubscription subscription, String callingPackage, PendingIntent callbackIntent) { Loading Loading @@ -953,6 +975,25 @@ public class EuiccController extends IEuiccController.Stub { return awaitResult(latch, eidRef); } private @OtaStatus int blockingGetOtaStatusFromEuiccService() { CountDownLatch latch = new CountDownLatch(1); AtomicReference<Integer> statusRef = new AtomicReference<>(EUICC_OTA_STATUS_UNAVAILABLE); mConnector.getOtaStatus(new EuiccConnector.GetOtaStatusCommandCallback() { @Override public void onGetOtaStatusComplete(@OtaStatus int status) { statusRef.set(status); latch.countDown(); } @Override public void onEuiccServiceUnavailable() { latch.countDown(); } }); return awaitResult(latch, statusRef); } @Nullable private EuiccInfo blockingGetEuiccInfoFromEuiccService() { CountDownLatch latch = new CountDownLatch(1); Loading tests/telephonytests/src/com/android/internal/telephony/euicc/EuiccControllerTest.java +39 −0 Original line number Diff line number Diff line Loading @@ -15,6 +15,8 @@ */ package com.android.internal.telephony.euicc; import static android.telephony.euicc.EuiccManager.EUICC_OTA_STATUS_UNAVAILABLE; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotNull; Loading Loading @@ -56,6 +58,7 @@ import android.telephony.euicc.EuiccInfo; import android.telephony.euicc.EuiccManager; import com.android.internal.telephony.TelephonyTest; import com.android.internal.telephony.euicc.EuiccConnector.GetOtaStatusCommandCallback; import org.junit.After; import org.junit.Before; Loading Loading @@ -203,6 +206,26 @@ public class EuiccControllerTest extends TelephonyTest { assertNull(callGetEid(true /* success */, null /* eid */)); } @Test(expected = SecurityException.class) public void testGetOtaStatus_noPrivileges() { setHasWriteEmbeddedPermission(false /* hasPermission */); callGetOtaStatus(true /* success */, 1 /* status */); } @Test public void testGetOtaStatus_withWriteEmbeddedPermission() { setHasWriteEmbeddedPermission(true /* hasPermission */); assertEquals(1, callGetOtaStatus(true /* success */, 1 /* status */)); } @Test public void testGetOtaStatus_failure() { setHasWriteEmbeddedPermission(true /* hasPermission */); assertEquals( EUICC_OTA_STATUS_UNAVAILABLE, callGetOtaStatus(false /* success */, 1 /* status */)); } @Test public void testGetEuiccInfo_success() { assertEquals(OS_VERSION, callGetEuiccInfo(true /* success */, EUICC_INFO).osVersion); Loading Loading @@ -806,6 +829,22 @@ public class EuiccControllerTest extends TelephonyTest { return mController.getEid(); } private int callGetOtaStatus(final boolean success, final int status) { doAnswer(new Answer<Void>() { @Override public Void answer(InvocationOnMock invocation) throws Exception { GetOtaStatusCommandCallback cb = invocation.getArgument(0); if (success) { cb.onGetOtaStatusComplete(status); } else { cb.onEuiccServiceUnavailable(); } return null; } }).when(mMockConnector).getOtaStatus(Mockito.<GetOtaStatusCommandCallback>any()); return mController.getOtaStatus(); } private EuiccInfo callGetEuiccInfo(final boolean success, final @Nullable EuiccInfo euiccInfo) { doAnswer(new Answer<Void>() { @Override Loading Loading
src/java/com/android/internal/telephony/euicc/EuiccConnector.java +31 −0 Original line number Diff line number Diff line Loading @@ -46,12 +46,14 @@ import android.service.euicc.IGetDownloadableSubscriptionMetadataCallback; import android.service.euicc.IGetEidCallback; import android.service.euicc.IGetEuiccInfoCallback; import android.service.euicc.IGetEuiccProfileInfoListCallback; import android.service.euicc.IGetOtaStatusCallback; import android.service.euicc.IRetainSubscriptionsForFactoryResetCallback; import android.service.euicc.ISwitchToSubscriptionCallback; import android.service.euicc.IUpdateSubscriptionNicknameCallback; import android.telephony.SubscriptionManager; import android.telephony.euicc.DownloadableSubscription; import android.telephony.euicc.EuiccInfo; import android.telephony.euicc.EuiccManager.OtaStatus; import android.text.TextUtils; import android.util.ArraySet; import android.util.Log; Loading Loading @@ -132,6 +134,7 @@ public class EuiccConnector extends StateMachine implements ServiceConnection { private static final int CMD_UPDATE_SUBSCRIPTION_NICKNAME = 108; private static final int CMD_ERASE_SUBSCRIPTIONS = 109; private static final int CMD_RETAIN_SUBSCRIPTIONS = 110; private static final int CMD_GET_OTA_STATUS = 111; private static boolean isEuiccCommand(int what) { return what >= CMD_GET_EID; Loading Loading @@ -185,6 +188,13 @@ public class EuiccConnector extends StateMachine implements ServiceConnection { void onGetEidComplete(String eid); } /** Callback class for {@link #getOtaStatus}. */ @VisibleForTesting(visibility = PACKAGE) public interface GetOtaStatusCommandCallback extends BaseEuiccCommandCallback { /** Called when the getting OTA status lookup has completed. */ void onGetOtaStatusComplete(@OtaStatus int status); } static class GetMetadataRequest { DownloadableSubscription mSubscription; boolean mForceDeactivateSim; Loading Loading @@ -373,6 +383,12 @@ public class EuiccConnector extends StateMachine implements ServiceConnection { sendMessage(CMD_GET_EID, callback); } /** Asynchronously get OTA status. */ @VisibleForTesting(visibility = PACKAGE) public void getOtaStatus(GetOtaStatusCommandCallback callback) { sendMessage(CMD_GET_OTA_STATUS, callback); } /** Asynchronously fetch metadata for the given downloadable subscription. */ @VisibleForTesting(visibility = PACKAGE) public void getDownloadableSubscriptionMetadata(DownloadableSubscription subscription, Loading Loading @@ -809,6 +825,20 @@ public class EuiccConnector extends StateMachine implements ServiceConnection { }); break; } case CMD_GET_OTA_STATUS: { mEuiccService.getOtaStatus(slotId, new IGetOtaStatusCallback.Stub() { @Override public void onSuccess(@OtaStatus int status) { sendMessage(CMD_COMMAND_COMPLETE, (Runnable) () -> { ((GetOtaStatusCommandCallback) callback) .onGetOtaStatusComplete(status); onCommandEnd(callback); }); } }); break; } default: { Log.wtf(TAG, "Unimplemented eUICC command: " + message.what); callback.onEuiccServiceUnavailable(); Loading Loading @@ -851,6 +881,7 @@ public class EuiccConnector extends StateMachine implements ServiceConnection { case CMD_GET_EUICC_INFO: case CMD_ERASE_SUBSCRIPTIONS: case CMD_RETAIN_SUBSCRIPTIONS: case CMD_GET_OTA_STATUS: return (BaseEuiccCommandCallback) message.obj; case CMD_GET_DOWNLOADABLE_SUBSCRIPTION_METADATA: return ((GetMetadataRequest) message.obj).mCallback; Loading
src/java/com/android/internal/telephony/euicc/EuiccController.java +41 −0 Original line number Diff line number Diff line Loading @@ -15,6 +15,8 @@ */ package com.android.internal.telephony.euicc; import static android.telephony.euicc.EuiccManager.EUICC_OTA_STATUS_UNAVAILABLE; import android.Manifest; import android.annotation.Nullable; import android.app.AppOpsManager; Loading @@ -38,6 +40,7 @@ import android.telephony.UiccAccessRule; import android.telephony.euicc.DownloadableSubscription; import android.telephony.euicc.EuiccInfo; import android.telephony.euicc.EuiccManager; import android.telephony.euicc.EuiccManager.OtaStatus; import android.text.TextUtils; import android.util.Log; Loading Loading @@ -169,6 +172,25 @@ public class EuiccController extends IEuiccController.Stub { } } /** * Return the current status of OTA update. * * <p>For API simplicity, this call blocks until completion; while it requires an IPC to load, * that IPC should generally be fast. */ @Override public @OtaStatus int getOtaStatus() { if (!callerCanWriteEmbeddedSubscriptions()) { throw new SecurityException("Must have WRITE_EMBEDDED_SUBSCRIPTIONS to get OTA status"); } long token = Binder.clearCallingIdentity(); try { return blockingGetOtaStatusFromEuiccService(); } finally { Binder.restoreCallingIdentity(token); } } @Override public void getDownloadableSubscriptionMetadata(DownloadableSubscription subscription, String callingPackage, PendingIntent callbackIntent) { Loading Loading @@ -953,6 +975,25 @@ public class EuiccController extends IEuiccController.Stub { return awaitResult(latch, eidRef); } private @OtaStatus int blockingGetOtaStatusFromEuiccService() { CountDownLatch latch = new CountDownLatch(1); AtomicReference<Integer> statusRef = new AtomicReference<>(EUICC_OTA_STATUS_UNAVAILABLE); mConnector.getOtaStatus(new EuiccConnector.GetOtaStatusCommandCallback() { @Override public void onGetOtaStatusComplete(@OtaStatus int status) { statusRef.set(status); latch.countDown(); } @Override public void onEuiccServiceUnavailable() { latch.countDown(); } }); return awaitResult(latch, statusRef); } @Nullable private EuiccInfo blockingGetEuiccInfoFromEuiccService() { CountDownLatch latch = new CountDownLatch(1); Loading
tests/telephonytests/src/com/android/internal/telephony/euicc/EuiccControllerTest.java +39 −0 Original line number Diff line number Diff line Loading @@ -15,6 +15,8 @@ */ package com.android.internal.telephony.euicc; import static android.telephony.euicc.EuiccManager.EUICC_OTA_STATUS_UNAVAILABLE; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotNull; Loading Loading @@ -56,6 +58,7 @@ import android.telephony.euicc.EuiccInfo; import android.telephony.euicc.EuiccManager; import com.android.internal.telephony.TelephonyTest; import com.android.internal.telephony.euicc.EuiccConnector.GetOtaStatusCommandCallback; import org.junit.After; import org.junit.Before; Loading Loading @@ -203,6 +206,26 @@ public class EuiccControllerTest extends TelephonyTest { assertNull(callGetEid(true /* success */, null /* eid */)); } @Test(expected = SecurityException.class) public void testGetOtaStatus_noPrivileges() { setHasWriteEmbeddedPermission(false /* hasPermission */); callGetOtaStatus(true /* success */, 1 /* status */); } @Test public void testGetOtaStatus_withWriteEmbeddedPermission() { setHasWriteEmbeddedPermission(true /* hasPermission */); assertEquals(1, callGetOtaStatus(true /* success */, 1 /* status */)); } @Test public void testGetOtaStatus_failure() { setHasWriteEmbeddedPermission(true /* hasPermission */); assertEquals( EUICC_OTA_STATUS_UNAVAILABLE, callGetOtaStatus(false /* success */, 1 /* status */)); } @Test public void testGetEuiccInfo_success() { assertEquals(OS_VERSION, callGetEuiccInfo(true /* success */, EUICC_INFO).osVersion); Loading Loading @@ -806,6 +829,22 @@ public class EuiccControllerTest extends TelephonyTest { return mController.getEid(); } private int callGetOtaStatus(final boolean success, final int status) { doAnswer(new Answer<Void>() { @Override public Void answer(InvocationOnMock invocation) throws Exception { GetOtaStatusCommandCallback cb = invocation.getArgument(0); if (success) { cb.onGetOtaStatusComplete(status); } else { cb.onEuiccServiceUnavailable(); } return null; } }).when(mMockConnector).getOtaStatus(Mockito.<GetOtaStatusCommandCallback>any()); return mController.getOtaStatus(); } private EuiccInfo callGetEuiccInfo(final boolean success, final @Nullable EuiccInfo euiccInfo) { doAnswer(new Answer<Void>() { @Override Loading