Merge "Add EuiccManager#retainSubscriptionsOnFactoryReset API." into oc-dr1-dev
diff --git a/Android.mk b/Android.mk
index 933ac62..55ea69a 100644
--- a/Android.mk
+++ b/Android.mk
@@ -292,6 +292,7 @@
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/IRetainSubscriptionsForFactoryResetCallback.aidl \
core/java/android/service/euicc/ISwitchToSubscriptionCallback.aidl \
core/java/android/service/euicc/IUpdateSubscriptionNicknameCallback.aidl \
core/java/android/service/gatekeeper/IGateKeeperService.aidl \
diff --git a/core/java/android/service/euicc/EuiccService.java b/core/java/android/service/euicc/EuiccService.java
index 26f8528..0c2e4b7 100644
--- a/core/java/android/service/euicc/EuiccService.java
+++ b/core/java/android/service/euicc/EuiccService.java
@@ -317,6 +317,21 @@
public abstract int onEraseSubscriptions(int slotId);
/**
+ * Ensure that subscriptions will be retained on the next factory reset.
+ *
+ * <p>Called directly before a factory reset. Assumes that a normal factory reset will lead to
+ * profiles being erased on first boot (to cover fastboot/recovery wipes), so the implementation
+ * 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.
+ * @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}.
+ */
+ public abstract int onRetainSubscriptionsForFactoryReset(int slotId);
+
+ /**
* Wrapper around IEuiccService that forwards calls to implementations of {@link EuiccService}.
*/
private class IEuiccServiceWrapper extends IEuiccService.Stub {
@@ -488,5 +503,21 @@
}
});
}
+
+ @Override
+ public void retainSubscriptionsForFactoryReset(int slotId,
+ IRetainSubscriptionsForFactoryResetCallback callback) {
+ mExecutor.execute(new Runnable() {
+ @Override
+ public void run() {
+ int result = EuiccService.this.onRetainSubscriptionsForFactoryReset(slotId);
+ try {
+ callback.onComplete(result);
+ } catch (RemoteException e) {
+ // Can't communicate with the phone process; ignore.
+ }
+ }
+ });
+ }
}
}
diff --git a/core/java/android/service/euicc/IEuiccService.aidl b/core/java/android/service/euicc/IEuiccService.aidl
index 18ea915..e10dd8c 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.IGetEidCallback;
import android.service.euicc.IGetEuiccInfoCallback;
import android.service.euicc.IGetEuiccProfileInfoListCallback;
+import android.service.euicc.IRetainSubscriptionsForFactoryResetCallback;
import android.service.euicc.ISwitchToSubscriptionCallback;
import android.service.euicc.IUpdateSubscriptionNicknameCallback;
import android.telephony.euicc.DownloadableSubscription;
@@ -46,4 +47,6 @@
void updateSubscriptionNickname(int slotId, String iccid, String nickname,
in IUpdateSubscriptionNicknameCallback callback);
void eraseSubscriptions(int slotId, in IEraseSubscriptionsCallback callback);
+ void retainSubscriptionsForFactoryReset(
+ int slotId, in IRetainSubscriptionsForFactoryResetCallback callback);
}
\ No newline at end of file
diff --git a/core/java/android/service/euicc/IRetainSubscriptionsForFactoryResetCallback.aidl b/core/java/android/service/euicc/IRetainSubscriptionsForFactoryResetCallback.aidl
new file mode 100644
index 0000000..1276830
--- /dev/null
+++ b/core/java/android/service/euicc/IRetainSubscriptionsForFactoryResetCallback.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 IRetainSubscriptionsForFactoryResetCallback {
+ void onComplete(int result);
+}
\ 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 f22a632..8304d84 100644
--- a/telephony/java/android/telephony/euicc/EuiccManager.java
+++ b/telephony/java/android/telephony/euicc/EuiccManager.java
@@ -475,6 +475,36 @@
}
}
+ /**
+ * Ensure that subscriptions will be retained on the next factory reset.
+ *
+ * <p>By default, all subscriptions on the eUICC are erased the first time a device boots (ever
+ * and after factory resets). This ensures that the data is wiped after a factory reset is
+ * performed via fastboot or recovery mode, as these modes do not support the necessary radio
+ * communication needed to wipe the eSIM.
+ *
+ * <p>However, this method may be called right before a factory reset issued via settings when
+ * the user elects to retain subscriptions. Doing so will mark them for retention so that they
+ * are not cleared after the ensuing reset.
+ *
+ * <p>Requires that the calling app has the {@link android.Manifest.permission#MASTER_CLEAR}
+ * permission. This is for internal system use only.
+ *
+ * @param callbackIntent a PendingIntent to launch when the operation completes.
+ * @hide
+ */
+ public void retainSubscriptionsForFactoryReset(PendingIntent callbackIntent) {
+ if (!isEnabled()) {
+ sendUnavailableError(callbackIntent);
+ return;
+ }
+ try {
+ mController.retainSubscriptionsForFactoryReset(callbackIntent);
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
+ }
+
private static void sendUnavailableError(PendingIntent callbackIntent) {
try {
callbackIntent.send(EMBEDDED_SUBSCRIPTION_RESULT_ERROR);
diff --git a/telephony/java/com/android/internal/telephony/euicc/IEuiccController.aidl b/telephony/java/com/android/internal/telephony/euicc/IEuiccController.aidl
index fa43631..b3fc90d 100644
--- a/telephony/java/com/android/internal/telephony/euicc/IEuiccController.aidl
+++ b/telephony/java/com/android/internal/telephony/euicc/IEuiccController.aidl
@@ -40,4 +40,5 @@
oneway void updateSubscriptionNickname(int subscriptionId, String nickname,
in PendingIntent callbackIntent);
oneway void eraseSubscriptions(in PendingIntent callbackIntent);
+ oneway void retainSubscriptionsForFactoryReset(in PendingIntent callbackIntent);
}
\ No newline at end of file