diff --git a/Android.bp b/Android.bp index 2dcbc92974a95..7d36a88b31b0c 100644 --- a/Android.bp +++ b/Android.bp @@ -256,6 +256,7 @@ java_library { "core/java/android/service/euicc/IGetEidCallback.aidl", "core/java/android/service/euicc/IGetEuiccInfoCallback.aidl", "core/java/android/service/euicc/IGetEuiccProfileInfoListCallback.aidl", + "core/java/android/service/euicc/IGetOtaStatusCallback.aidl", "core/java/android/service/euicc/IRetainSubscriptionsForFactoryResetCallback.aidl", "core/java/android/service/euicc/ISwitchToSubscriptionCallback.aidl", "core/java/android/service/euicc/IUpdateSubscriptionNicknameCallback.aidl", diff --git a/core/java/android/service/euicc/EuiccService.java b/core/java/android/service/euicc/EuiccService.java index df0842f7fb0de..fb530074d5b06 100644 --- a/core/java/android/service/euicc/EuiccService.java +++ b/core/java/android/service/euicc/EuiccService.java @@ -23,6 +23,7 @@ import android.os.IBinder; import android.os.RemoteException; import android.telephony.euicc.DownloadableSubscription; import android.telephony.euicc.EuiccInfo; +import android.telephony.euicc.EuiccManager.OtaStatus; import android.util.ArraySet; import java.util.concurrent.LinkedBlockingQueue; @@ -202,6 +203,16 @@ public abstract class EuiccService extends Service { // TODO(b/36260308): Update doc when we have multi-SIM support. public abstract String onGetEid(int slotId); + /** + * Return the status of OTA update. + * + * @param slotId ID of the SIM slot to use for the operation. This is currently not populated + * but is here to future-proof the APIs. + * @return The status of Euicc OTA update. + * @see android.telephony.euicc.EuiccManager#getOtaStatus + */ + public abstract @OtaStatus int onGetOtaStatus(int slotId); + /** * Populate {@link DownloadableSubscription} metadata for the given downloadable subscription. * @@ -384,6 +395,21 @@ public abstract class EuiccService extends Service { }); } + @Override + public void getOtaStatus(int slotId, IGetOtaStatusCallback callback) { + mExecutor.execute(new Runnable() { + @Override + public void run() { + int status = EuiccService.this.onGetOtaStatus(slotId); + try { + callback.onSuccess(status); + } catch (RemoteException e) { + // Can't communicate with the phone process; ignore. + } + } + }); + } + @Override public void getDownloadableSubscriptionMetadata(int slotId, DownloadableSubscription subscription, diff --git a/core/java/android/service/euicc/IEuiccService.aidl b/core/java/android/service/euicc/IEuiccService.aidl index e10dd8cdf616e..a24e5c35c1cbe 100644 --- a/core/java/android/service/euicc/IEuiccService.aidl +++ b/core/java/android/service/euicc/IEuiccService.aidl @@ -24,6 +24,7 @@ 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; @@ -37,6 +38,7 @@ oneway interface IEuiccService { void getDownloadableSubscriptionMetadata(int slotId, in DownloadableSubscription subscription, boolean forceDeactivateSim, in IGetDownloadableSubscriptionMetadataCallback callback); void getEid(int slotId, in IGetEidCallback callback); + void getOtaStatus(int slotId, in IGetOtaStatusCallback callback); void getEuiccProfileInfoList(int slotId, in IGetEuiccProfileInfoListCallback callback); void getDefaultDownloadableSubscriptionList(int slotId, boolean forceDeactivateSim, in IGetDefaultDownloadableSubscriptionListCallback callback); diff --git a/core/java/android/service/euicc/IGetOtaStatusCallback.aidl b/core/java/android/service/euicc/IGetOtaStatusCallback.aidl new file mode 100644 index 0000000000000..f6678889ccc73 --- /dev/null +++ b/core/java/android/service/euicc/IGetOtaStatusCallback.aidl @@ -0,0 +1,22 @@ +/* + * Copyright (C) 2017 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 android.service.euicc; + +/** @hide */ +oneway interface IGetOtaStatusCallback { + void onSuccess(int status); +} \ No newline at end of file diff --git a/telephony/java/android/telephony/euicc/EuiccManager.java b/telephony/java/android/telephony/euicc/EuiccManager.java index 973df316d2802..176057ddc23ee 100644 --- a/telephony/java/android/telephony/euicc/EuiccManager.java +++ b/telephony/java/android/telephony/euicc/EuiccManager.java @@ -15,8 +15,10 @@ */ package android.telephony.euicc; +import android.annotation.IntDef; import android.annotation.Nullable; import android.annotation.SdkConstant; +import android.annotation.SystemApi; import android.app.Activity; import android.app.PendingIntent; import android.content.Context; @@ -29,6 +31,9 @@ import android.os.ServiceManager; import com.android.internal.telephony.euicc.IEuiccController; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; + /** * EuiccManager is the application interface to eUICCs, or eSIMs/embedded SIMs. * @@ -167,6 +172,35 @@ public class EuiccManager { */ public static final String META_DATA_CARRIER_ICON = "android.telephony.euicc.carriericon"; + /** + * Euicc OTA update status which can be got by {@link #getOtaStatus} + * @hide + */ + @Retention(RetentionPolicy.SOURCE) + @IntDef(prefix = {"EUICC_OTA_"}, value = { + EUICC_OTA_IN_PROGRESS, + EUICC_OTA_FAILED, + EUICC_OTA_SUCCEEDED, + EUICC_OTA_NOT_NEEDED, + EUICC_OTA_STATUS_UNAVAILABLE + + }) + public @interface OtaStatus{} + + /** + * An OTA is in progress. During this time, the eUICC is not available and the user may lose + * network access. + */ + public static final int EUICC_OTA_IN_PROGRESS = 1; + /** The OTA update failed. */ + public static final int EUICC_OTA_FAILED = 2; + /** The OTA update finished successfully. */ + public static final int EUICC_OTA_SUCCEEDED = 3; + /** The OTA update not needed since current eUICC OS is latest. */ + public static final int EUICC_OTA_NOT_NEEDED = 4; + /** The OTA status is unavailable since eUICC service is unavailable. */ + public static final int EUICC_OTA_STATUS_UNAVAILABLE = 5; + private final Context mContext; /** @hide */ @@ -210,6 +244,26 @@ public class EuiccManager { } } + /** + * Returns the current status of eUICC OTA. + * + *
Requires the {@link android.Manifest.permission#WRITE_EMBEDDED_SUBSCRIPTIONS} permission. + * + * @return the status of eUICC OTA. If {@link #isEnabled()} is false or the eUICC is not ready, + * {@link OtaStatus#EUICC_OTA_STATUS_UNAVAILABLE} will be returned. + */ + @SystemApi + public int getOtaStatus() { + if (!isEnabled()) { + return EUICC_OTA_STATUS_UNAVAILABLE; + } + try { + return getIEuiccController().getOtaStatus(); + } catch (RemoteException e) { + throw e.rethrowFromSystemServer(); + } + } + /** * Attempt to download the given {@link DownloadableSubscription}. * diff --git a/telephony/java/com/android/internal/telephony/euicc/IEuiccController.aidl b/telephony/java/com/android/internal/telephony/euicc/IEuiccController.aidl index b3fc90db75d3b..0a0ad90b59540 100644 --- a/telephony/java/com/android/internal/telephony/euicc/IEuiccController.aidl +++ b/telephony/java/com/android/internal/telephony/euicc/IEuiccController.aidl @@ -30,6 +30,7 @@ interface IEuiccController { oneway void getDefaultDownloadableSubscriptionList( String callingPackage, in PendingIntent callbackIntent); String getEid(); + int getOtaStatus(); oneway void downloadSubscription(in DownloadableSubscription subscription, boolean switchAfterDownload, String callingPackage, in PendingIntent callbackIntent); EuiccInfo getEuiccInfo();