diff options
Diffstat (limited to 'core/java/android')
5 files changed, 263 insertions, 28 deletions
diff --git a/core/java/android/service/euicc/DownloadSubscriptionResult.aidl b/core/java/android/service/euicc/DownloadSubscriptionResult.aidl new file mode 100644 index 000000000000..b625fd6d3cb4 --- /dev/null +++ b/core/java/android/service/euicc/DownloadSubscriptionResult.aidl @@ -0,0 +1,19 @@ +/* + * Copyright (C) 2018 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; + +parcelable DownloadSubscriptionResult; diff --git a/core/java/android/service/euicc/DownloadSubscriptionResult.java b/core/java/android/service/euicc/DownloadSubscriptionResult.java new file mode 100644 index 000000000000..b410e35f3f83 --- /dev/null +++ b/core/java/android/service/euicc/DownloadSubscriptionResult.java @@ -0,0 +1,99 @@ +/* + * Copyright (C) 2018 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; + +import android.annotation.SystemApi; +import android.os.Parcel; +import android.os.Parcelable; +import android.service.euicc.EuiccService.ResolvableError; +import android.service.euicc.EuiccService.Result; + +/** + * Result of a {@link EuiccService#onDownloadSubscription} operation. + * @hide + */ +@SystemApi +public final class DownloadSubscriptionResult implements Parcelable { + + public static final Creator<DownloadSubscriptionResult> CREATOR = + new Creator<DownloadSubscriptionResult>() { + @Override + public DownloadSubscriptionResult createFromParcel(Parcel in) { + return new DownloadSubscriptionResult(in); + } + + @Override + public DownloadSubscriptionResult[] newArray(int size) { + return new DownloadSubscriptionResult[size]; + } + }; + + private final @Result int mResult; + private final @ResolvableError int mResolvableErrors; + private final int mCardId; + + public DownloadSubscriptionResult(@Result int result, @ResolvableError int resolvableErrors, + int cardId) { + this.mResult = result; + this.mResolvableErrors = resolvableErrors; + this.mCardId = cardId; + } + + /** Gets the result of the operation. */ + public @Result int getResult() { + return mResult; + } + + /** + * Gets the bit map of resolvable errors. + * + * <p>The value is passed from EuiccService. The values can be + * + * <ul> + * <li>{@link EuiccService#RESOLVABLE_ERROR_CONFIRMATION_CODE} + * <li>{@link EuiccService#RESOLVABLE_ERROR_POLICY_RULES} + * </ul> + */ + public @ResolvableError int getResolvableErrors() { + return mResolvableErrors; + } + + /** + * Gets the card Id. This is used when resolving resolvable errors. The value is passed from + * EuiccService. + */ + public int getCardId() { + return mCardId; + } + + @Override + public void writeToParcel(Parcel dest, int flags) { + dest.writeInt(mResult); + dest.writeInt(mResolvableErrors); + dest.writeInt(mCardId); + } + + @Override + public int describeContents() { + return 0; + } + + private DownloadSubscriptionResult(Parcel in) { + this.mResult = in.readInt(); + this.mResolvableErrors = in.readInt(); + this.mCardId = in.readInt(); + } +} diff --git a/core/java/android/service/euicc/EuiccService.java b/core/java/android/service/euicc/EuiccService.java index 49a7320dab6d..4be1f9cd6ae5 100644 --- a/core/java/android/service/euicc/EuiccService.java +++ b/core/java/android/service/euicc/EuiccService.java @@ -16,17 +16,24 @@ package android.service.euicc; import android.annotation.CallSuper; +import android.annotation.IntDef; +import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.SystemApi; import android.app.Service; import android.content.Intent; +import android.os.Bundle; import android.os.IBinder; import android.os.RemoteException; +import android.telephony.TelephonyManager; import android.telephony.euicc.DownloadableSubscription; import android.telephony.euicc.EuiccInfo; import android.telephony.euicc.EuiccManager.OtaStatus; import android.util.ArraySet; +import android.util.Log; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; import java.util.concurrent.LinkedBlockingQueue; import java.util.concurrent.ThreadFactory; import java.util.concurrent.ThreadPoolExecutor; @@ -73,6 +80,8 @@ import java.util.concurrent.atomic.AtomicInteger; */ @SystemApi public abstract class EuiccService extends Service { + private static final String TAG = "EuiccService"; + /** Action which must be included in this service's intent filter. */ public static final String EUICC_SERVICE_INTERFACE = "android.service.euicc.EuiccService"; @@ -115,30 +124,91 @@ public abstract class EuiccService extends Service { public static final String ACTION_RESOLVE_NO_PRIVILEGES = "android.service.euicc.action.RESOLVE_NO_PRIVILEGES"; - /** Ask the user to input carrier confirmation code. */ + /** + * Ask the user to input carrier confirmation code. + * + * @deprecated From Q, the resolvable errors happened in the download step are presented as + * bit map in {@link #EXTRA_RESOLVABLE_ERRORS}. The corresponding action would be + * {@link #ACTION_RESOLVE_RESOLVABLE_ERRORS}. + */ + @Deprecated public static final String ACTION_RESOLVE_CONFIRMATION_CODE = "android.service.euicc.action.RESOLVE_CONFIRMATION_CODE"; + /** Ask the user to resolve all the resolvable errors. */ + public static final String ACTION_RESOLVE_RESOLVABLE_ERRORS = + "android.service.euicc.action.RESOLVE_RESOLVABLE_ERRORS"; + + /** @hide */ + @Retention(RetentionPolicy.SOURCE) + @IntDef(flag = true, prefix = { "RESOLVABLE_ERROR_" }, value = { + RESOLVABLE_ERROR_CONFIRMATION_CODE, + RESOLVABLE_ERROR_POLICY_RULES, + }) + public @interface ResolvableError {} + + /** + * Possible value for the bit map of resolvable errors indicating the download process needs + * the user to input confirmation code. + */ + public static final int RESOLVABLE_ERROR_CONFIRMATION_CODE = 1 << 0; + /** + * Possible value for the bit map of resolvable errors indicating the download process needs + * the user's consent to allow profile policy rules. + */ + public static final int RESOLVABLE_ERROR_POLICY_RULES = 1 << 1; + /** * Intent extra set for resolution requests containing the package name of the calling app. * This is used by the above actions including ACTION_RESOLVE_DEACTIVATE_SIM, - * ACTION_RESOLVE_NO_PRIVILEGES and ACTION_RESOLVE_CONFIRMATION_CODE. + * ACTION_RESOLVE_NO_PRIVILEGES and ACTION_RESOLVE_RESOLVABLE_ERRORS. */ public static final String EXTRA_RESOLUTION_CALLING_PACKAGE = "android.service.euicc.extra.RESOLUTION_CALLING_PACKAGE"; /** + * Intent extra set for resolution requests containing the list of resolvable errors to be + * resolved. Each resolvable error is an integer. Its possible values include: + * <UL> + * <LI>{@link #RESOLVABLE_ERROR_CONFIRMATION_CODE} + * <LI>{@link #RESOLVABLE_ERROR_POLICY_RULES} + * </UL> + */ + public static final String EXTRA_RESOLVABLE_ERRORS = + "android.service.euicc.extra.RESOLVABLE_ERRORS"; + + /** * Intent extra set for resolution requests containing a boolean indicating whether to ask the * user to retry another confirmation code. */ public static final String EXTRA_RESOLUTION_CONFIRMATION_CODE_RETRIED = "android.service.euicc.extra.RESOLUTION_CONFIRMATION_CODE_RETRIED"; + /** @hide */ + @Retention(RetentionPolicy.SOURCE) + @IntDef(prefix = { "RESULT_" }, value = { + RESULT_OK, + RESULT_MUST_DEACTIVATE_SIM, + RESULT_RESOLVABLE_ERRORS, + RESULT_NEED_CONFIRMATION_CODE, + RESULT_FIRST_USER, + }) + public @interface Result {} + /** Result code for a successful operation. */ public static final int RESULT_OK = 0; /** Result code indicating that an active SIM must be deactivated to perform the operation. */ public static final int RESULT_MUST_DEACTIVATE_SIM = -1; - /** Result code indicating that the user must input a carrier confirmation code. */ + /** Result code indicating that the user must resolve resolvable errors. */ + public static final int RESULT_RESOLVABLE_ERRORS = -2; + /** + * Result code indicating that the user must input a carrier confirmation code. + * + * @deprecated From Q, the resolvable errors happened in the download step are presented as + * bit map in {@link #EXTRA_RESOLVABLE_ERRORS}. The corresponding result would be + * {@link #RESULT_RESOLVABLE_ERRORS}. + */ + @Deprecated public static final int RESULT_NEED_CONFIRMATION_CODE = -2; // New predefined codes should have negative values. @@ -154,7 +224,7 @@ public abstract class EuiccService extends Service { RESOLUTION_ACTIONS = new ArraySet<>(); RESOLUTION_ACTIONS.add(EuiccService.ACTION_RESOLVE_DEACTIVATE_SIM); RESOLUTION_ACTIONS.add(EuiccService.ACTION_RESOLVE_NO_PRIVILEGES); - RESOLUTION_ACTIONS.add(EuiccService.ACTION_RESOLVE_CONFIRMATION_CODE); + RESOLUTION_ACTIONS.add(EuiccService.ACTION_RESOLVE_RESOLVABLE_ERRORS); } /** @@ -169,6 +239,12 @@ public abstract class EuiccService extends Service { */ public static final String EXTRA_RESOLUTION_CONFIRMATION_CODE = "android.service.euicc.extra.RESOLUTION_CONFIRMATION_CODE"; + /** + * String extra for resolution actions indicating whether the user allows policy rules. + * This is used and set by the implementation and used in {@code EuiccOperation}. + */ + public static final String EXTRA_RESOLUTION_ALLOW_POLICY_RULES = + "android.service.euicc.extra.RESOLUTION_ALLOW_POLICY_RULES"; private final IEuiccService.Stub mStubWrapper; @@ -236,8 +312,7 @@ public abstract class EuiccService extends Service { /** * Return the EID of the eUICC. * - * @param slotId ID of the SIM slot being queried. This is currently not populated but is here - * to future-proof the APIs. + * @param slotId ID of the SIM slot being queried. * @return the EID. * @see android.telephony.euicc.EuiccManager#getEid */ @@ -247,8 +322,7 @@ public abstract class EuiccService extends Service { /** * 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. + * @param slotId ID of the SIM slot to use for the operation. * @return The status of Euicc OTA update. * @see android.telephony.euicc.EuiccManager#getOtaStatus */ @@ -257,8 +331,7 @@ public abstract class EuiccService extends Service { /** * Perform OTA if current OS is not the latest one. * - * @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. + * @param slotId ID of the SIM slot to use for the operation. * @param statusChangedCallback Function called when OTA status changed. */ public abstract void onStartOtaIfNecessary( @@ -281,8 +354,7 @@ public abstract class EuiccService extends Service { /** * Return metadata for subscriptions which are available for download for this device. * - * @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. + * @param slotId ID of the SIM slot to use for the operation. * @param forceDeactivateSim If true, and if an active SIM must be deactivated to access the * eUICC, perform this action automatically. Otherwise, {@link #RESULT_MUST_DEACTIVATE_SIM)} * should be returned to allow the user to consent to this operation first. @@ -302,13 +374,44 @@ public abstract class EuiccService extends Service { * @param forceDeactivateSim If true, and if an active SIM must be deactivated to access the * eUICC, perform this action automatically. Otherwise, {@link #RESULT_MUST_DEACTIVATE_SIM} * should be returned to allow the user to consent to this operation first. + * @param resolvedBundle The bundle containing information on resolved errors. It can contain + * a string of confirmation code for the key {@link #EXTRA_RESOLUTION_CONFIRMATION_CODE}, + * and a boolean for key {@link #EXTRA_RESOLUTION_ALLOW_POLICY_RULES} indicating whether + * the user allows profile policy rules or not. + * @return a DownloadSubscriptionResult instance including a result code, a resolvable errors + * bit map, and original the card Id. The result code may be one of the predefined + * {@code RESULT_} constants or any implementation-specific code starting with + * {@link #RESULT_FIRST_USER}. The resolvable error bit map can be either 0 or values + * defined in {@code RESOLVABLE_ERROR_}. + * @see android.telephony.euicc.EuiccManager#downloadSubscription + */ + public abstract DownloadSubscriptionResult onDownloadSubscription(int slotId, + @NonNull DownloadableSubscription subscription, boolean switchAfterDownload, + boolean forceDeactivateSim, @Nullable Bundle resolvedBundle); + + /** + * Download the given subscription. + * + * @param slotId ID of the SIM slot to use for the operation. + * @param subscription The subscription to download. + * @param switchAfterDownload If true, the subscription should be enabled upon successful + * download. + * @param forceDeactivateSim If true, and if an active SIM must be deactivated to access the + * eUICC, perform this action automatically. Otherwise, {@link #RESULT_MUST_DEACTIVATE_SIM} + * should be returned to allow the user to consent to this operation first. * @return the result of the download operation. May be one of the predefined {@code RESULT_} * constants or any implementation-specific code starting with {@link #RESULT_FIRST_USER}. * @see android.telephony.euicc.EuiccManager#downloadSubscription + * + * @deprecated From Q, please use the above + * {@link #onDownloadSubscription(int, DownloadableSubscription, boolean, boolean, Bundle)}. */ - public abstract int onDownloadSubscription(int slotId, - DownloadableSubscription subscription, boolean switchAfterDownload, - boolean forceDeactivateSim); + @Deprecated public @Result int onDownloadSubscription(int slotId, + @NonNull DownloadableSubscription subscription, boolean switchAfterDownload, + boolean forceDeactivateSim) { + throw new UnsupportedOperationException("onDownloadSubscription(int, " + + "DownloadableSubscription, boolean, boolean) is deprecated."); + } /** * Return a list of all @link EuiccProfileInfo}s. @@ -318,7 +421,7 @@ public abstract class EuiccService extends Service { * @see android.telephony.SubscriptionManager#getAvailableSubscriptionInfoList * @see android.telephony.SubscriptionManager#getAccessibleSubscriptionInfoList */ - public abstract GetEuiccProfileInfoListResult onGetEuiccProfileInfoList(int slotId); + public abstract @NonNull GetEuiccProfileInfoListResult onGetEuiccProfileInfoList(int slotId); /** * Return info about the eUICC chip/device. @@ -327,7 +430,7 @@ public abstract class EuiccService extends Service { * @return the {@link EuiccInfo} for the eUICC chip/device. * @see android.telephony.euicc.EuiccManager#getEuiccInfo */ - public abstract EuiccInfo onGetEuiccInfo(int slotId); + public abstract @NonNull EuiccInfo onGetEuiccInfo(int slotId); /** * Delete the given subscription. @@ -341,7 +444,7 @@ public abstract class EuiccService extends Service { * constants or any implementation-specific code starting with {@link #RESULT_FIRST_USER}. * @see android.telephony.euicc.EuiccManager#deleteSubscription */ - public abstract int onDeleteSubscription(int slotId, String iccid); + public abstract @Result int onDeleteSubscription(int slotId, String iccid); /** * Switch to the given subscription. @@ -357,7 +460,7 @@ public abstract class EuiccService extends Service { * constants or any implementation-specific code starting with {@link #RESULT_FIRST_USER}. * @see android.telephony.euicc.EuiccManager#switchToSubscription */ - public abstract int onSwitchToSubscription(int slotId, @Nullable String iccid, + public abstract @Result int onSwitchToSubscription(int slotId, @Nullable String iccid, boolean forceDeactivateSim); /** @@ -379,8 +482,7 @@ public abstract class EuiccService extends Service { * <p>This is intended to be used for device resets. As such, the reset should be performed even * if an active SIM must be deactivated in order to access the eUICC. * - * @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. + * @param slotId ID of the SIM slot to use for the operation. * @return the result of the erase operation. May be one of the predefined {@code RESULT_} * constants or any implementation-specific code starting with {@link #RESULT_FIRST_USER}. * @see android.telephony.euicc.EuiccManager#eraseSubscriptions @@ -395,8 +497,7 @@ public abstract class EuiccService extends Service { * should persist some bit that will remain accessible after the factory reset to bypass this * flow when this method is called. * - * @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. + * @param slotId ID of the SIM slot to use for the operation. * @return the result of the operation. May be one of the predefined {@code RESULT_} constants * or any implementation-specific code starting with {@link #RESULT_FIRST_USER}. */ @@ -408,13 +509,26 @@ public abstract class EuiccService extends Service { private class IEuiccServiceWrapper extends IEuiccService.Stub { @Override public void downloadSubscription(int slotId, DownloadableSubscription subscription, - boolean switchAfterDownload, boolean forceDeactivateSim, + boolean switchAfterDownload, boolean forceDeactivateSim, Bundle resolvedBundle, IDownloadSubscriptionCallback callback) { mExecutor.execute(new Runnable() { @Override public void run() { - int result = EuiccService.this.onDownloadSubscription( - slotId, subscription, switchAfterDownload, forceDeactivateSim); + DownloadSubscriptionResult result; + try { + result = + EuiccService.this.onDownloadSubscription( + slotId, subscription, switchAfterDownload, forceDeactivateSim, + resolvedBundle); + } catch (AbstractMethodError e) { + Log.w(TAG, "The new onDownloadSubscription(int, " + + "DownloadableSubscription, boolean, boolean, Bundle) is not " + + "implemented. Fall back to the old one.", e); + int resultCode = EuiccService.this.onDownloadSubscription( + slotId, subscription, switchAfterDownload, forceDeactivateSim); + result = new DownloadSubscriptionResult(resultCode, + 0 /* resolvableErrors */, TelephonyManager.INVALID_CARD_ID); + } try { callback.onComplete(result); } catch (RemoteException e) { diff --git a/core/java/android/service/euicc/IDownloadSubscriptionCallback.aidl b/core/java/android/service/euicc/IDownloadSubscriptionCallback.aidl index 6893c8559d9d..50ecbebf5e84 100644 --- a/core/java/android/service/euicc/IDownloadSubscriptionCallback.aidl +++ b/core/java/android/service/euicc/IDownloadSubscriptionCallback.aidl @@ -16,7 +16,9 @@ package android.service.euicc; +import android.service.euicc.DownloadSubscriptionResult; + /** @hide */ oneway interface IDownloadSubscriptionCallback { - void onComplete(int result); + void onComplete(in DownloadSubscriptionResult result); }
\ No newline at end of file diff --git a/core/java/android/service/euicc/IEuiccService.aidl b/core/java/android/service/euicc/IEuiccService.aidl index 45be52740f32..c2cdf093706f 100644 --- a/core/java/android/service/euicc/IEuiccService.aidl +++ b/core/java/android/service/euicc/IEuiccService.aidl @@ -30,11 +30,12 @@ import android.service.euicc.IRetainSubscriptionsForFactoryResetCallback; import android.service.euicc.ISwitchToSubscriptionCallback; import android.service.euicc.IUpdateSubscriptionNicknameCallback; import android.telephony.euicc.DownloadableSubscription; +import android.os.Bundle; /** @hide */ oneway interface IEuiccService { void downloadSubscription(int slotId, in DownloadableSubscription subscription, - boolean switchAfterDownload, boolean forceDeactivateSim, + boolean switchAfterDownload, boolean forceDeactivateSim, in Bundle resolvedBundle, in IDownloadSubscriptionCallback callback); void getDownloadableSubscriptionMetadata(int slotId, in DownloadableSubscription subscription, boolean forceDeactivateSim, in IGetDownloadableSubscriptionMetadataCallback callback); |
