summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTreeHugger Robot <treehugger-gerrit@google.com>2017-04-17 19:22:43 +0000
committerAndroid (Google) Code Review <android-gerrit@google.com>2017-04-17 19:22:49 +0000
commit8e3b1a63f9cd76a71ecbfc8c6a0c68b4cbecab90 (patch)
treec65386d19eafacbab0b237cab86ca926ace21fe9
parentdbe270ce058afa3f61e5bf62c293ff37960d1617 (diff)
parentcfa70fa0abe90d91bd7997ef23432e5631b40d2a (diff)
Merge "EUICC API changes to support error resolution."
-rw-r--r--core/java/android/service/euicc/DownloadResult.java11
-rw-r--r--core/java/android/service/euicc/EuiccService.java50
-rw-r--r--core/java/android/service/euicc/GetDownloadableSubscriptionMetadataResult.java11
-rw-r--r--core/java/android/service/euicc/IEuiccService.aidl5
-rw-r--r--telephony/java/android/telephony/euicc/DownloadableSubscription.java37
-rw-r--r--telephony/java/android/telephony/euicc/EuiccManager.java81
-rw-r--r--telephony/java/com/android/internal/telephony/euicc/IEuiccController.aidl3
7 files changed, 138 insertions, 60 deletions
diff --git a/core/java/android/service/euicc/DownloadResult.java b/core/java/android/service/euicc/DownloadResult.java
index 0aa55fbbc0ff..4e2af5343232 100644
--- a/core/java/android/service/euicc/DownloadResult.java
+++ b/core/java/android/service/euicc/DownloadResult.java
@@ -46,14 +46,14 @@ public final class DownloadResult implements Parcelable {
@IntDef({
RESULT_OK,
RESULT_GENERIC_ERROR,
- RESULT_MUST_DEACTIVATE_REMOVABLE_SIM,
+ RESULT_MUST_DEACTIVATE_SIM,
})
@Retention(RetentionPolicy.SOURCE)
public @interface ResultCode {}
public static final int RESULT_OK = 0;
public static final int RESULT_GENERIC_ERROR = 1;
- public static final int RESULT_MUST_DEACTIVATE_REMOVABLE_SIM = 2;
+ public static final int RESULT_MUST_DEACTIVATE_SIM = 2;
/** Result of the operation - one of the RESULT_* constants. */
public final @ResultCode int result;
@@ -83,11 +83,10 @@ public final class DownloadResult implements Parcelable {
}
/**
- * Return a result indicating that the removable SIM must be deactivated to perform the
- * operation.
+ * Return a result indicating that an active SIM must be deactivated to perform the operation.
*/
- public static DownloadResult mustDeactivateRemovableSim() {
- return new DownloadResult(RESULT_MUST_DEACTIVATE_REMOVABLE_SIM, 0);
+ public static DownloadResult mustDeactivateSim() {
+ return new DownloadResult(RESULT_MUST_DEACTIVATE_SIM, 0);
}
/**
diff --git a/core/java/android/service/euicc/EuiccService.java b/core/java/android/service/euicc/EuiccService.java
index 6407507549b1..03aa967f9611 100644
--- a/core/java/android/service/euicc/EuiccService.java
+++ b/core/java/android/service/euicc/EuiccService.java
@@ -21,6 +21,7 @@ import android.content.Intent;
import android.os.IBinder;
import android.os.RemoteException;
import android.telephony.euicc.DownloadableSubscription;
+import android.util.ArraySet;
/**
* Service interface linking the system with an eUICC local profile assistant (LPA) application.
@@ -74,6 +75,33 @@ public abstract class EuiccService extends Service {
public static final String ACTION_PROVISION_EMBEDDED_SUBSCRIPTION =
"android.service.euicc.action.PROVISION_EMBEDDED_SUBSCRIPTION";
+ // LUI resolution actions. These are called by the platform to resolve errors in situations that
+ // require user interaction.
+ // TODO(b/33075886): Define extras for any input parameters to these dialogs once they are
+ // more scoped out.
+ /** Alert the user that this action will result in an active SIM being deactivated. */
+ public static final String ACTION_RESOLVE_DEACTIVATE_SIM =
+ "android.service.euicc.action.RESOLVE_DEACTIVATE_SIM";
+ /**
+ * Alert the user about a download/switch being done for an app that doesn't currently have
+ * carrier privileges.
+ */
+ public static final String ACTION_RESOLVE_NO_PRIVILEGES =
+ "android.service.euicc.action.RESOLVE_NO_PRIVILEGES";
+ /**
+ * List of all valid resolution actions for validation purposes.
+ * @hide
+ */
+ public static final ArraySet<String> RESOLUTION_ACTIONS;
+ static {
+ RESOLUTION_ACTIONS = new ArraySet<>();
+ RESOLUTION_ACTIONS.add(EuiccService.ACTION_RESOLVE_DEACTIVATE_SIM);
+ RESOLUTION_ACTIONS.add(EuiccService.ACTION_RESOLVE_NO_PRIVILEGES);
+ }
+
+ /** Boolean extra for resolution actions indicating whether the user granted consent. */
+ public static final String RESOLUTION_EXTRA_CONSENT = "consent";
+
private final IEuiccService.Stub mStubWrapper;
public EuiccService() {
@@ -107,11 +135,15 @@ public abstract class EuiccService extends Service {
* @param slotId ID of the SIM slot to use when starting the download. This is currently not
* populated but is here to future-proof the APIs.
* @param subscription A subscription whose metadata needs to be populated.
+ * @param forceDeactivateSim If true, and if an active SIM must be deactivated to access the
+ * eUICC, perform this action automatically. Otherwise,
+ * {@link GetDownloadableSubscriptionMetadataResult#mustDeactivateSim()} should be returned
+ * to allow the user to consent to this operation first.
* @return The result of the operation.
* @see android.telephony.euicc.EuiccManager#getDownloadableSubscriptionMetadata
*/
public abstract GetDownloadableSubscriptionMetadataResult getDownloadableSubscriptionMetadata(
- int slotId, DownloadableSubscription subscription);
+ int slotId, DownloadableSubscription subscription, boolean forceDeactivateSim);
/**
* Download the given subscription.
@@ -121,11 +153,16 @@ public abstract class EuiccService extends Service {
* @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 DownloadResult#mustDeactivateSim()} should be returned to allow the user to
+ * consent to this operation first.
* @return the result of the download operation.
* @see android.telephony.euicc.EuiccManager#downloadSubscription
*/
public abstract DownloadResult downloadSubscription(int slotId,
- DownloadableSubscription subscription, boolean switchAfterDownload);
+ DownloadableSubscription subscription, boolean switchAfterDownload,
+ boolean forceDeactivateSim);
/**
* Wrapper around IEuiccService that forwards calls to implementations of {@link EuiccService}.
@@ -133,9 +170,10 @@ public abstract class EuiccService extends Service {
private class IEuiccServiceWrapper extends IEuiccService.Stub {
@Override
public void downloadSubscription(int slotId, DownloadableSubscription subscription,
- boolean switchAfterDownload, IDownloadSubscriptionCallback callback) {
+ boolean switchAfterDownload, boolean forceDeactivateSim,
+ IDownloadSubscriptionCallback callback) {
DownloadResult result = EuiccService.this.downloadSubscription(
- slotId, subscription, switchAfterDownload);
+ slotId, subscription, switchAfterDownload, forceDeactivateSim);
try {
callback.onComplete(result);
} catch (RemoteException e) {
@@ -156,9 +194,11 @@ public abstract class EuiccService extends Service {
@Override
public void getDownloadableSubscriptionMetadata(int slotId,
DownloadableSubscription subscription,
+ boolean forceDeactivateSim,
IGetDownloadableSubscriptionMetadataCallback callback) {
GetDownloadableSubscriptionMetadataResult result =
- EuiccService.this.getDownloadableSubscriptionMetadata(slotId, subscription);
+ EuiccService.this.getDownloadableSubscriptionMetadata(
+ slotId, subscription, forceDeactivateSim);
try {
callback.onComplete(result);
} catch (RemoteException e) {
diff --git a/core/java/android/service/euicc/GetDownloadableSubscriptionMetadataResult.java b/core/java/android/service/euicc/GetDownloadableSubscriptionMetadataResult.java
index 04f49808b383..ca3c1597fa58 100644
--- a/core/java/android/service/euicc/GetDownloadableSubscriptionMetadataResult.java
+++ b/core/java/android/service/euicc/GetDownloadableSubscriptionMetadataResult.java
@@ -49,13 +49,13 @@ public final class GetDownloadableSubscriptionMetadataResult implements Parcelab
@IntDef({
RESULT_OK,
RESULT_GENERIC_ERROR,
- RESULT_MUST_DEACTIVATE_REMOVABLE_SIM,
+ RESULT_MUST_DEACTIVATE_SIM,
})
@Retention(RetentionPolicy.SOURCE)
public @interface ResultCode {}
public static final int RESULT_OK = 0;
- public static final int RESULT_MUST_DEACTIVATE_REMOVABLE_SIM = 1;
+ public static final int RESULT_MUST_DEACTIVATE_SIM = 1;
public static final int RESULT_GENERIC_ERROR = 2;
/** Result of the operation - one of the RESULT_* constants. */
@@ -100,11 +100,10 @@ public final class GetDownloadableSubscriptionMetadataResult implements Parcelab
}
/**
- * Return a result indicating that the removable SIM must be deactivated to perform the
- * operation.
+ * Return a result indicating that an active SIM must be deactivated to perform the operation.
*/
- public static GetDownloadableSubscriptionMetadataResult mustDeactivateRemovableSim() {
- return new GetDownloadableSubscriptionMetadataResult(RESULT_MUST_DEACTIVATE_REMOVABLE_SIM,
+ public static GetDownloadableSubscriptionMetadataResult mustDeactivateSim() {
+ return new GetDownloadableSubscriptionMetadataResult(RESULT_MUST_DEACTIVATE_SIM,
null /* subscription */, 0 /* detailedCode */);
}
diff --git a/core/java/android/service/euicc/IEuiccService.aidl b/core/java/android/service/euicc/IEuiccService.aidl
index 58fe262c8541..3658d9a357be 100644
--- a/core/java/android/service/euicc/IEuiccService.aidl
+++ b/core/java/android/service/euicc/IEuiccService.aidl
@@ -24,8 +24,9 @@ import android.telephony.euicc.DownloadableSubscription;
/** @hide */
oneway interface IEuiccService {
void downloadSubscription(int slotId, in DownloadableSubscription subscription,
- boolean switchAfterDownload, in IDownloadSubscriptionCallback callback);
+ boolean switchAfterDownload, boolean forceDeactivateSim,
+ in IDownloadSubscriptionCallback callback);
void getDownloadableSubscriptionMetadata(int slotId, in DownloadableSubscription subscription,
- in IGetDownloadableSubscriptionMetadataCallback callback);
+ boolean forceDeactivateSim, in IGetDownloadableSubscriptionMetadataCallback callback);
void getEid(int slotId, in IGetEidCallback callback);
} \ No newline at end of file
diff --git a/telephony/java/android/telephony/euicc/DownloadableSubscription.java b/telephony/java/android/telephony/euicc/DownloadableSubscription.java
index b12864cf3077..b5484e344a1c 100644
--- a/telephony/java/android/telephony/euicc/DownloadableSubscription.java
+++ b/telephony/java/android/telephony/euicc/DownloadableSubscription.java
@@ -56,8 +56,6 @@ public final class DownloadableSubscription implements Parcelable {
// see getCarrierName and setCarrierName
@Nullable
private String carrierName;
- // see isConsentGranted and setConsentGranted
- private boolean consentGranted;
// see getAccessRules and setAccessRules
private UiccAccessRule[] accessRules;
@@ -69,7 +67,6 @@ public final class DownloadableSubscription implements Parcelable {
private DownloadableSubscription(Parcel in) {
encodedActivationCode = in.readString();
carrierName = in.readString();
- consentGranted = in.readInt() == 1;
accessRules = in.createTypedArray(UiccAccessRule.CREATOR);
}
@@ -110,28 +107,6 @@ public final class DownloadableSubscription implements Parcelable {
return carrierName;
}
-
- /**
- * Mark this download as being consented to by the user.
- * @hide
- */
- public void setConsentGranted() {
- consentGranted = true;
- }
-
- /**
- * Returns whether the user has granted consent to download this subscription.
- *
- * <p>The {@link android.service.euicc.EuiccService} implementation should permit a subscription
- * download if this is set, even if the calling app doesn't have permission to download it.
- * @hide
- *
- * TODO(b/35851809): Make this a SystemApi.
- */
- public boolean isConsentGranted() {
- return consentGranted;
- }
-
/**
* Returns the {@link UiccAccessRule}s dictating access to this subscription.
*
@@ -156,22 +131,10 @@ public final class DownloadableSubscription implements Parcelable {
this.accessRules = accessRules;
}
- /**
- * Unset any untrusted fields.
- *
- * <p>Should be called by the platform whenever an instance is received from an untrusted
- * source to reset any secure fields that may only be set by the platform.
- * @hide
- */
- public final void clearUntrustedFields() {
- this.consentGranted = false;
- }
-
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeString(encodedActivationCode);
dest.writeString(carrierName);
- dest.writeInt(consentGranted ? 1 : 0);
dest.writeTypedArray(accessRules, flags);
}
diff --git a/telephony/java/android/telephony/euicc/EuiccManager.java b/telephony/java/android/telephony/euicc/EuiccManager.java
index 10492c0bb6ff..8bc0be636ddb 100644
--- a/telephony/java/android/telephony/euicc/EuiccManager.java
+++ b/telephony/java/android/telephony/euicc/EuiccManager.java
@@ -22,7 +22,9 @@ import android.app.Activity;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
+import android.content.IntentSender;
import android.content.pm.PackageManager;
+import android.os.Bundle;
import android.os.RemoteException;
import android.os.ServiceManager;
@@ -71,6 +73,13 @@ public class EuiccManager {
"android.telephony.euicc.action.PROVISION_EMBEDDED_SUBSCRIPTION";
/**
+ * Intent action to handle a resolvable error.
+ * @hide
+ */
+ public static final String ACTION_RESOLVE_ERROR =
+ "android.telephony.euicc.action.RESOLVE_ERROR";
+
+ /**
* Result code for an operation indicating that the operation succeeded.
*/
public static final int EMBEDDED_SUBSCRIPTION_RESULT_OK = 0;
@@ -105,7 +114,7 @@ public class EuiccManager {
"android.telephony.euicc.extra.EMBEDDED_SUBSCRIPTION_DETAILED_CODE";
/**
- * The key for an extra set on {@link #getDownloadableSubscriptionMetadata} PendingIntent result
+ * Key for an extra set on {@link #getDownloadableSubscriptionMetadata} PendingIntent result
* callbacks providing the downloadable subscription metadata.
* @hide
*
@@ -114,6 +123,30 @@ public class EuiccManager {
public static final String EXTRA_EMBEDDED_SUBSCRIPTION_DOWNLOADABLE_SUBSCRIPTION =
"android.telephony.euicc.extra.EMBEDDED_SUBSCRIPTION_DOWNLOADABLE_SUBSCRIPTION";
+ /**
+ * Key for an extra set on {@link PendingIntent} result callbacks providing the resolution
+ * pending intent for {@link #EMBEDDED_SUBSCRIPTION_RESULT_RESOLVABLE_ERROR}s.
+ * @hide
+ */
+ public static final String EXTRA_EMBEDDED_SUBSCRIPTION_RESOLUTION_INTENT =
+ "android.telephony.euicc.extra.EMBEDDED_SUBSCRIPTION_RESOLUTION_INTENT";
+
+ /**
+ * Key for an extra set on the {@link #EXTRA_EMBEDDED_SUBSCRIPTION_RESOLUTION_INTENT} intent
+ * containing the EuiccService action to launch for resolution.
+ * @hide
+ */
+ public static final String EXTRA_EMBEDDED_SUBSCRIPTION_RESOLUTION_ACTION =
+ "android.telephony.euicc.extra.EMBEDDED_SUBSCRIPTION_RESOLUTION_ACTION";
+
+ /**
+ * Key for an extra set on the {@link #EXTRA_EMBEDDED_SUBSCRIPTION_RESOLUTION_INTENT} intent
+ * providing the callback to execute after resolution is completed.
+ * @hide
+ */
+ public static final String EXTRA_EMBEDDED_SUBSCRIPTION_RESOLUTION_CALLBACK_INTENT =
+ "android.telephony.euicc.extra.EMBEDDED_SUBSCRIPTION_RESOLUTION_CALLBACK_INTENT";
+
private final Context mContext;
private final IEuiccController mController;
@@ -191,6 +224,8 @@ public class EuiccManager {
* <p>If an operation returns {@link #EMBEDDED_SUBSCRIPTION_RESULT_RESOLVABLE_ERROR}, this
* method may be called to prompt the user to resolve the issue.
*
+ * <p>This method may only be called once for a particular error.
+ *
* @param activity the calling activity (which should be in the foreground).
* @param requestCode an application-specific request code which will be provided to
* {@link Activity#onActivityResult} upon completion. Note that the operation may still be
@@ -200,11 +235,49 @@ public class EuiccManager {
* {@link #EMBEDDED_SUBSCRIPTION_RESULT_RESOLVABLE_ERROR}.
* @param callbackIntent a PendingIntent to launch when the operation completes. This is
* trigered upon completion of the original operation that required user resolution.
+ * @throws android.content.IntentSender.SendIntentException if called more than once.
*/
public void startResolutionActivity(Activity activity, int requestCode, Intent resultIntent,
- PendingIntent callbackIntent) {
- // TODO(b/33075886): Implement this API.
- throw new UnsupportedOperationException("Not implemented");
+ PendingIntent callbackIntent) throws IntentSender.SendIntentException {
+ PendingIntent resolutionIntent =
+ resultIntent.getParcelableExtra(EXTRA_EMBEDDED_SUBSCRIPTION_RESOLUTION_INTENT);
+ if (resolutionIntent == null) {
+ throw new IllegalArgumentException("Invalid result intent");
+ }
+ Intent fillInIntent = new Intent();
+ fillInIntent.putExtra(EuiccManager.EXTRA_EMBEDDED_SUBSCRIPTION_RESOLUTION_CALLBACK_INTENT,
+ callbackIntent);
+ activity.startIntentSenderForResult(resolutionIntent.getIntentSender(), requestCode,
+ fillInIntent, 0 /* flagsMask */, 0 /* flagsValues */, 0 /* extraFlags */);
+ }
+
+ /**
+ * Continue an operation after the user resolves an error.
+ *
+ * <p>To be called by the LUI upon completion of a resolvable error flow.
+ *
+ * @param resolutionIntent The original intent used to start the LUI.
+ * @param resolutionExtras Resolution-specific extras depending on the result of the resolution.
+ * For example, this may indicate whether the user has consented or may include the input
+ * they provided.
+ * @hide
+ */
+ @SystemApi
+ public void continueOperation(Intent resolutionIntent, Bundle resolutionExtras) {
+ if (!isEnabled()) {
+ PendingIntent callbackIntent =
+ resolutionIntent.getParcelableExtra(
+ EuiccManager.EXTRA_EMBEDDED_SUBSCRIPTION_RESOLUTION_CALLBACK_INTENT);
+ if (callbackIntent != null) {
+ sendUnavailableError(callbackIntent);
+ }
+ return;
+ }
+ try {
+ mController.continueOperation(resolutionIntent, resolutionExtras);
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
}
/**
diff --git a/telephony/java/com/android/internal/telephony/euicc/IEuiccController.aidl b/telephony/java/com/android/internal/telephony/euicc/IEuiccController.aidl
index de198c1a7675..5f03dd97d785 100644
--- a/telephony/java/com/android/internal/telephony/euicc/IEuiccController.aidl
+++ b/telephony/java/com/android/internal/telephony/euicc/IEuiccController.aidl
@@ -17,10 +17,13 @@
package com.android.internal.telephony.euicc;
import android.app.PendingIntent;
+import android.content.Intent;
+import android.os.Bundle;
import android.telephony.euicc.DownloadableSubscription;
/** @hide */
interface IEuiccController {
+ oneway void continueOperation(in Intent resolutionIntent, in Bundle resolutionExtras);
oneway void getDownloadableSubscriptionMetadata(in DownloadableSubscription subscription,
in PendingIntent callbackIntent);
String getEid();