EuiccController.java revision 8bf20cb416675744e28821f509a20ae2813ad44e
1277a5a2aae73ef0233fffc350f3829aee779899fJeff Davidson/* 2277a5a2aae73ef0233fffc350f3829aee779899fJeff Davidson * Copyright (C) 2017 The Android Open Source Project 3277a5a2aae73ef0233fffc350f3829aee779899fJeff Davidson * 4277a5a2aae73ef0233fffc350f3829aee779899fJeff Davidson * Licensed under the Apache License, Version 2.0 (the "License"); 5277a5a2aae73ef0233fffc350f3829aee779899fJeff Davidson * you may not use this file except in compliance with the License. 6277a5a2aae73ef0233fffc350f3829aee779899fJeff Davidson * You may obtain a copy of the License at 7277a5a2aae73ef0233fffc350f3829aee779899fJeff Davidson * 8277a5a2aae73ef0233fffc350f3829aee779899fJeff Davidson * http://www.apache.org/licenses/LICENSE-2.0 9277a5a2aae73ef0233fffc350f3829aee779899fJeff Davidson * 10277a5a2aae73ef0233fffc350f3829aee779899fJeff Davidson * Unless required by applicable law or agreed to in writing, software 11277a5a2aae73ef0233fffc350f3829aee779899fJeff Davidson * distributed under the License is distributed on an "AS IS" BASIS, 12277a5a2aae73ef0233fffc350f3829aee779899fJeff Davidson * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13277a5a2aae73ef0233fffc350f3829aee779899fJeff Davidson * See the License for the specific language governing permissions and 14277a5a2aae73ef0233fffc350f3829aee779899fJeff Davidson * limitations under the License. 15277a5a2aae73ef0233fffc350f3829aee779899fJeff Davidson */ 16277a5a2aae73ef0233fffc350f3829aee779899fJeff Davidsonpackage com.android.internal.telephony.euicc; 17277a5a2aae73ef0233fffc350f3829aee779899fJeff Davidson 18ebbbe7bdbf2c6226913480bbd83a88cd0460a86aQingxi Liimport static android.telephony.euicc.EuiccManager.EUICC_OTA_STATUS_UNAVAILABLE; 19ebbbe7bdbf2c6226913480bbd83a88cd0460a86aQingxi Li 20277a5a2aae73ef0233fffc350f3829aee779899fJeff Davidsonimport android.Manifest; 2196d4dfe105bae38079c1ad834e5840365f2b9cc6Qingxi Liimport android.Manifest.permission; 22277a5a2aae73ef0233fffc350f3829aee779899fJeff Davidsonimport android.annotation.Nullable; 2308d3d312d13c3194d8434aeb8c92ea220f4d0e2cJeff Davidsonimport android.app.AppOpsManager; 24277a5a2aae73ef0233fffc350f3829aee779899fJeff Davidsonimport android.app.PendingIntent; 25277a5a2aae73ef0233fffc350f3829aee779899fJeff Davidsonimport android.content.Context; 26277a5a2aae73ef0233fffc350f3829aee779899fJeff Davidsonimport android.content.Intent; 2708d3d312d13c3194d8434aeb8c92ea220f4d0e2cJeff Davidsonimport android.content.pm.PackageInfo; 28277a5a2aae73ef0233fffc350f3829aee779899fJeff Davidsonimport android.content.pm.PackageManager; 29277a5a2aae73ef0233fffc350f3829aee779899fJeff Davidsonimport android.os.Binder; 30953d76b6865b1f76c6fadbbd69898fe064b6c157Jeff Davidsonimport android.os.Bundle; 31277a5a2aae73ef0233fffc350f3829aee779899fJeff Davidsonimport android.os.ServiceManager; 324f62c3ddcc69bc8217e4794c73d38945e97380eeJeff Davidsonimport android.provider.Settings; 33953d76b6865b1f76c6fadbbd69898fe064b6c157Jeff Davidsonimport android.service.euicc.EuiccService; 348f32416b4c5f5657e7ccf3a1ee031598a0203fd9Jeff Davidsonimport android.service.euicc.GetDefaultDownloadableSubscriptionListResult; 35277a5a2aae73ef0233fffc350f3829aee779899fJeff Davidsonimport android.service.euicc.GetDownloadableSubscriptionMetadataResult; 36dce529f00c52bedf4377ee5f7ae1b284fe6452beJeff Davidsonimport android.service.euicc.GetEuiccProfileInfoListResult; 37dce529f00c52bedf4377ee5f7ae1b284fe6452beJeff Davidsonimport android.telephony.SubscriptionInfo; 38dce529f00c52bedf4377ee5f7ae1b284fe6452beJeff Davidsonimport android.telephony.SubscriptionManager; 39277a5a2aae73ef0233fffc350f3829aee779899fJeff Davidsonimport android.telephony.TelephonyManager; 4008d3d312d13c3194d8434aeb8c92ea220f4d0e2cJeff Davidsonimport android.telephony.UiccAccessRule; 41277a5a2aae73ef0233fffc350f3829aee779899fJeff Davidsonimport android.telephony.euicc.DownloadableSubscription; 428f32416b4c5f5657e7ccf3a1ee031598a0203fd9Jeff Davidsonimport android.telephony.euicc.EuiccInfo; 43277a5a2aae73ef0233fffc350f3829aee779899fJeff Davidsonimport android.telephony.euicc.EuiccManager; 44ebbbe7bdbf2c6226913480bbd83a88cd0460a86aQingxi Liimport android.telephony.euicc.EuiccManager.OtaStatus; 45f2e6e134218a3302a8889ceef73d0f7ccfbddb56Holly Jiuyu Sunimport android.text.TextUtils; 46277a5a2aae73ef0233fffc350f3829aee779899fJeff Davidsonimport android.util.Log; 47277a5a2aae73ef0233fffc350f3829aee779899fJeff Davidson 48277a5a2aae73ef0233fffc350f3829aee779899fJeff Davidsonimport com.android.internal.annotations.VisibleForTesting; 49dce529f00c52bedf4377ee5f7ae1b284fe6452beJeff Davidsonimport com.android.internal.telephony.SubscriptionController; 5096d4dfe105bae38079c1ad834e5840365f2b9cc6Qingxi Liimport com.android.internal.telephony.euicc.EuiccConnector.OtaStatusChangedCallback; 51277a5a2aae73ef0233fffc350f3829aee779899fJeff Davidson 52277a5a2aae73ef0233fffc350f3829aee779899fJeff Davidsonimport java.io.FileDescriptor; 53277a5a2aae73ef0233fffc350f3829aee779899fJeff Davidsonimport java.io.PrintWriter; 54dce529f00c52bedf4377ee5f7ae1b284fe6452beJeff Davidsonimport java.util.List; 55277a5a2aae73ef0233fffc350f3829aee779899fJeff Davidsonimport java.util.concurrent.CountDownLatch; 56277a5a2aae73ef0233fffc350f3829aee779899fJeff Davidsonimport java.util.concurrent.atomic.AtomicReference; 57277a5a2aae73ef0233fffc350f3829aee779899fJeff Davidson 58277a5a2aae73ef0233fffc350f3829aee779899fJeff Davidson/** Backing implementation of {@link android.telephony.euicc.EuiccManager}. */ 59277a5a2aae73ef0233fffc350f3829aee779899fJeff Davidsonpublic class EuiccController extends IEuiccController.Stub { 60277a5a2aae73ef0233fffc350f3829aee779899fJeff Davidson private static final String TAG = "EuiccController"; 61277a5a2aae73ef0233fffc350f3829aee779899fJeff Davidson 62953d76b6865b1f76c6fadbbd69898fe064b6c157Jeff Davidson /** Extra set on resolution intents containing the {@link EuiccOperation}. */ 63953d76b6865b1f76c6fadbbd69898fe064b6c157Jeff Davidson @VisibleForTesting 64953d76b6865b1f76c6fadbbd69898fe064b6c157Jeff Davidson static final String EXTRA_OPERATION = "operation"; 65953d76b6865b1f76c6fadbbd69898fe064b6c157Jeff Davidson 6608d3d312d13c3194d8434aeb8c92ea220f4d0e2cJeff Davidson // Aliases so line lengths stay short. 6708d3d312d13c3194d8434aeb8c92ea220f4d0e2cJeff Davidson private static final int OK = EuiccManager.EMBEDDED_SUBSCRIPTION_RESULT_OK; 6808d3d312d13c3194d8434aeb8c92ea220f4d0e2cJeff Davidson private static final int RESOLVABLE_ERROR = 6908d3d312d13c3194d8434aeb8c92ea220f4d0e2cJeff Davidson EuiccManager.EMBEDDED_SUBSCRIPTION_RESULT_RESOLVABLE_ERROR; 7031e69b5efbc9b9a39183acce93a4c1b2e73b3006Jeff Davidson private static final int ERROR = 7131e69b5efbc9b9a39183acce93a4c1b2e73b3006Jeff Davidson EuiccManager.EMBEDDED_SUBSCRIPTION_RESULT_ERROR; 728bf20cb416675744e28821f509a20ae2813ad44eHolly Jiuyu Sun private static final String EXTRA_EMBEDDED_SUBSCRIPTION_DOWNLOADABLE_SUBSCRIPTION = 738bf20cb416675744e28821f509a20ae2813ad44eHolly Jiuyu Sun EuiccManager.EXTRA_EMBEDDED_SUBSCRIPTION_DOWNLOADABLE_SUBSCRIPTION; 7408d3d312d13c3194d8434aeb8c92ea220f4d0e2cJeff Davidson 75277a5a2aae73ef0233fffc350f3829aee779899fJeff Davidson private static EuiccController sInstance; 76277a5a2aae73ef0233fffc350f3829aee779899fJeff Davidson 77277a5a2aae73ef0233fffc350f3829aee779899fJeff Davidson private final Context mContext; 78277a5a2aae73ef0233fffc350f3829aee779899fJeff Davidson private final EuiccConnector mConnector; 79dce529f00c52bedf4377ee5f7ae1b284fe6452beJeff Davidson private final SubscriptionManager mSubscriptionManager; 8008d3d312d13c3194d8434aeb8c92ea220f4d0e2cJeff Davidson private final AppOpsManager mAppOpsManager; 8108d3d312d13c3194d8434aeb8c92ea220f4d0e2cJeff Davidson private final PackageManager mPackageManager; 82277a5a2aae73ef0233fffc350f3829aee779899fJeff Davidson 83277a5a2aae73ef0233fffc350f3829aee779899fJeff Davidson /** Initialize the instance. Should only be called once. */ 84277a5a2aae73ef0233fffc350f3829aee779899fJeff Davidson public static EuiccController init(Context context) { 85277a5a2aae73ef0233fffc350f3829aee779899fJeff Davidson synchronized (EuiccController.class) { 86277a5a2aae73ef0233fffc350f3829aee779899fJeff Davidson if (sInstance == null) { 87277a5a2aae73ef0233fffc350f3829aee779899fJeff Davidson sInstance = new EuiccController(context); 88277a5a2aae73ef0233fffc350f3829aee779899fJeff Davidson } else { 89277a5a2aae73ef0233fffc350f3829aee779899fJeff Davidson Log.wtf(TAG, "init() called multiple times! sInstance = " + sInstance); 90277a5a2aae73ef0233fffc350f3829aee779899fJeff Davidson } 91277a5a2aae73ef0233fffc350f3829aee779899fJeff Davidson } 92277a5a2aae73ef0233fffc350f3829aee779899fJeff Davidson return sInstance; 93277a5a2aae73ef0233fffc350f3829aee779899fJeff Davidson } 94277a5a2aae73ef0233fffc350f3829aee779899fJeff Davidson 95277a5a2aae73ef0233fffc350f3829aee779899fJeff Davidson /** Get an instance. Assumes one has already been initialized with {@link #init}. */ 96277a5a2aae73ef0233fffc350f3829aee779899fJeff Davidson public static EuiccController get() { 97277a5a2aae73ef0233fffc350f3829aee779899fJeff Davidson if (sInstance == null) { 98277a5a2aae73ef0233fffc350f3829aee779899fJeff Davidson synchronized (EuiccController.class) { 99277a5a2aae73ef0233fffc350f3829aee779899fJeff Davidson if (sInstance == null) { 100277a5a2aae73ef0233fffc350f3829aee779899fJeff Davidson throw new IllegalStateException("get() called before init()"); 101277a5a2aae73ef0233fffc350f3829aee779899fJeff Davidson } 102277a5a2aae73ef0233fffc350f3829aee779899fJeff Davidson } 103277a5a2aae73ef0233fffc350f3829aee779899fJeff Davidson } 104277a5a2aae73ef0233fffc350f3829aee779899fJeff Davidson return sInstance; 105277a5a2aae73ef0233fffc350f3829aee779899fJeff Davidson } 106277a5a2aae73ef0233fffc350f3829aee779899fJeff Davidson 107277a5a2aae73ef0233fffc350f3829aee779899fJeff Davidson private EuiccController(Context context) { 108277a5a2aae73ef0233fffc350f3829aee779899fJeff Davidson this(context, new EuiccConnector(context)); 109277a5a2aae73ef0233fffc350f3829aee779899fJeff Davidson ServiceManager.addService("econtroller", this); 110277a5a2aae73ef0233fffc350f3829aee779899fJeff Davidson } 111277a5a2aae73ef0233fffc350f3829aee779899fJeff Davidson 112277a5a2aae73ef0233fffc350f3829aee779899fJeff Davidson @VisibleForTesting 113277a5a2aae73ef0233fffc350f3829aee779899fJeff Davidson public EuiccController(Context context, EuiccConnector connector) { 114277a5a2aae73ef0233fffc350f3829aee779899fJeff Davidson mContext = context; 115277a5a2aae73ef0233fffc350f3829aee779899fJeff Davidson mConnector = connector; 116dce529f00c52bedf4377ee5f7ae1b284fe6452beJeff Davidson mSubscriptionManager = (SubscriptionManager) 117dce529f00c52bedf4377ee5f7ae1b284fe6452beJeff Davidson context.getSystemService(Context.TELEPHONY_SUBSCRIPTION_SERVICE); 11808d3d312d13c3194d8434aeb8c92ea220f4d0e2cJeff Davidson mAppOpsManager = (AppOpsManager) context.getSystemService(Context.APP_OPS_SERVICE); 11908d3d312d13c3194d8434aeb8c92ea220f4d0e2cJeff Davidson mPackageManager = context.getPackageManager(); 120277a5a2aae73ef0233fffc350f3829aee779899fJeff Davidson } 121277a5a2aae73ef0233fffc350f3829aee779899fJeff Davidson 122277a5a2aae73ef0233fffc350f3829aee779899fJeff Davidson /** 123953d76b6865b1f76c6fadbbd69898fe064b6c157Jeff Davidson * Continue an operation which failed with a user-resolvable error. 124953d76b6865b1f76c6fadbbd69898fe064b6c157Jeff Davidson * 125953d76b6865b1f76c6fadbbd69898fe064b6c157Jeff Davidson * <p>The implementation here makes a key assumption that the resolutionIntent has not been 126953d76b6865b1f76c6fadbbd69898fe064b6c157Jeff Davidson * tampered with. This is guaranteed because: 127953d76b6865b1f76c6fadbbd69898fe064b6c157Jeff Davidson * <UL> 128953d76b6865b1f76c6fadbbd69898fe064b6c157Jeff Davidson * <LI>The intent is wrapped in a PendingIntent created by the phone process which is created 129953d76b6865b1f76c6fadbbd69898fe064b6c157Jeff Davidson * with {@link #EXTRA_OPERATION} already present. This means that the operation cannot be 130953d76b6865b1f76c6fadbbd69898fe064b6c157Jeff Davidson * overridden on the PendingIntent - a caller can only add new extras. 131953d76b6865b1f76c6fadbbd69898fe064b6c157Jeff Davidson * <LI>The resolution activity is restricted by a privileged permission; unprivileged apps 132953d76b6865b1f76c6fadbbd69898fe064b6c157Jeff Davidson * cannot start it directly. So the PendingIntent is the only way to start it. 133953d76b6865b1f76c6fadbbd69898fe064b6c157Jeff Davidson * </UL> 134953d76b6865b1f76c6fadbbd69898fe064b6c157Jeff Davidson */ 135953d76b6865b1f76c6fadbbd69898fe064b6c157Jeff Davidson @Override 136953d76b6865b1f76c6fadbbd69898fe064b6c157Jeff Davidson public void continueOperation(Intent resolutionIntent, Bundle resolutionExtras) { 137953d76b6865b1f76c6fadbbd69898fe064b6c157Jeff Davidson if (!callerCanWriteEmbeddedSubscriptions()) { 138953d76b6865b1f76c6fadbbd69898fe064b6c157Jeff Davidson throw new SecurityException( 139953d76b6865b1f76c6fadbbd69898fe064b6c157Jeff Davidson "Must have WRITE_EMBEDDED_SUBSCRIPTIONS to continue operation"); 140953d76b6865b1f76c6fadbbd69898fe064b6c157Jeff Davidson } 141953d76b6865b1f76c6fadbbd69898fe064b6c157Jeff Davidson long token = Binder.clearCallingIdentity(); 142953d76b6865b1f76c6fadbbd69898fe064b6c157Jeff Davidson try { 143953d76b6865b1f76c6fadbbd69898fe064b6c157Jeff Davidson EuiccOperation op = resolutionIntent.getParcelableExtra(EXTRA_OPERATION); 144953d76b6865b1f76c6fadbbd69898fe064b6c157Jeff Davidson if (op == null) { 145953d76b6865b1f76c6fadbbd69898fe064b6c157Jeff Davidson throw new IllegalArgumentException("Invalid resolution intent"); 146953d76b6865b1f76c6fadbbd69898fe064b6c157Jeff Davidson } 147953d76b6865b1f76c6fadbbd69898fe064b6c157Jeff Davidson 148953d76b6865b1f76c6fadbbd69898fe064b6c157Jeff Davidson PendingIntent callbackIntent = 149953d76b6865b1f76c6fadbbd69898fe064b6c157Jeff Davidson resolutionIntent.getParcelableExtra( 150953d76b6865b1f76c6fadbbd69898fe064b6c157Jeff Davidson EuiccManager.EXTRA_EMBEDDED_SUBSCRIPTION_RESOLUTION_CALLBACK_INTENT); 151953d76b6865b1f76c6fadbbd69898fe064b6c157Jeff Davidson op.continueOperation(resolutionExtras, callbackIntent); 152953d76b6865b1f76c6fadbbd69898fe064b6c157Jeff Davidson } finally { 153953d76b6865b1f76c6fadbbd69898fe064b6c157Jeff Davidson Binder.restoreCallingIdentity(token); 154953d76b6865b1f76c6fadbbd69898fe064b6c157Jeff Davidson } 155953d76b6865b1f76c6fadbbd69898fe064b6c157Jeff Davidson } 156953d76b6865b1f76c6fadbbd69898fe064b6c157Jeff Davidson 157953d76b6865b1f76c6fadbbd69898fe064b6c157Jeff Davidson /** 158277a5a2aae73ef0233fffc350f3829aee779899fJeff Davidson * Return the EID. 159277a5a2aae73ef0233fffc350f3829aee779899fJeff Davidson * 160277a5a2aae73ef0233fffc350f3829aee779899fJeff Davidson * <p>For API simplicity, this call blocks until completion; while it requires an IPC to load, 161277a5a2aae73ef0233fffc350f3829aee779899fJeff Davidson * that IPC should generally be fast, and the EID shouldn't be needed in the normal course of 162277a5a2aae73ef0233fffc350f3829aee779899fJeff Davidson * operation. 163277a5a2aae73ef0233fffc350f3829aee779899fJeff Davidson */ 164277a5a2aae73ef0233fffc350f3829aee779899fJeff Davidson @Override 165277a5a2aae73ef0233fffc350f3829aee779899fJeff Davidson public String getEid() { 166277a5a2aae73ef0233fffc350f3829aee779899fJeff Davidson if (!callerCanReadPhoneStatePrivileged() 167277a5a2aae73ef0233fffc350f3829aee779899fJeff Davidson && !callerHasCarrierPrivilegesForActiveSubscription()) { 168277a5a2aae73ef0233fffc350f3829aee779899fJeff Davidson throw new SecurityException( 169277a5a2aae73ef0233fffc350f3829aee779899fJeff Davidson "Must have carrier privileges on active subscription to read EID"); 170277a5a2aae73ef0233fffc350f3829aee779899fJeff Davidson } 171277a5a2aae73ef0233fffc350f3829aee779899fJeff Davidson long token = Binder.clearCallingIdentity(); 172277a5a2aae73ef0233fffc350f3829aee779899fJeff Davidson try { 173277a5a2aae73ef0233fffc350f3829aee779899fJeff Davidson return blockingGetEidFromEuiccService(); 174277a5a2aae73ef0233fffc350f3829aee779899fJeff Davidson } finally { 175277a5a2aae73ef0233fffc350f3829aee779899fJeff Davidson Binder.restoreCallingIdentity(token); 176277a5a2aae73ef0233fffc350f3829aee779899fJeff Davidson } 177277a5a2aae73ef0233fffc350f3829aee779899fJeff Davidson } 178277a5a2aae73ef0233fffc350f3829aee779899fJeff Davidson 179ebbbe7bdbf2c6226913480bbd83a88cd0460a86aQingxi Li /** 180ebbbe7bdbf2c6226913480bbd83a88cd0460a86aQingxi Li * Return the current status of OTA update. 181ebbbe7bdbf2c6226913480bbd83a88cd0460a86aQingxi Li * 182ebbbe7bdbf2c6226913480bbd83a88cd0460a86aQingxi Li * <p>For API simplicity, this call blocks until completion; while it requires an IPC to load, 183ebbbe7bdbf2c6226913480bbd83a88cd0460a86aQingxi Li * that IPC should generally be fast. 184ebbbe7bdbf2c6226913480bbd83a88cd0460a86aQingxi Li */ 185ebbbe7bdbf2c6226913480bbd83a88cd0460a86aQingxi Li @Override 186ebbbe7bdbf2c6226913480bbd83a88cd0460a86aQingxi Li public @OtaStatus int getOtaStatus() { 187ebbbe7bdbf2c6226913480bbd83a88cd0460a86aQingxi Li if (!callerCanWriteEmbeddedSubscriptions()) { 188ebbbe7bdbf2c6226913480bbd83a88cd0460a86aQingxi Li throw new SecurityException("Must have WRITE_EMBEDDED_SUBSCRIPTIONS to get OTA status"); 189ebbbe7bdbf2c6226913480bbd83a88cd0460a86aQingxi Li } 190ebbbe7bdbf2c6226913480bbd83a88cd0460a86aQingxi Li long token = Binder.clearCallingIdentity(); 191ebbbe7bdbf2c6226913480bbd83a88cd0460a86aQingxi Li try { 192ebbbe7bdbf2c6226913480bbd83a88cd0460a86aQingxi Li return blockingGetOtaStatusFromEuiccService(); 193ebbbe7bdbf2c6226913480bbd83a88cd0460a86aQingxi Li } finally { 194ebbbe7bdbf2c6226913480bbd83a88cd0460a86aQingxi Li Binder.restoreCallingIdentity(token); 195ebbbe7bdbf2c6226913480bbd83a88cd0460a86aQingxi Li } 196ebbbe7bdbf2c6226913480bbd83a88cd0460a86aQingxi Li } 197ebbbe7bdbf2c6226913480bbd83a88cd0460a86aQingxi Li 19896d4dfe105bae38079c1ad834e5840365f2b9cc6Qingxi Li 19996d4dfe105bae38079c1ad834e5840365f2b9cc6Qingxi Li /** 20096d4dfe105bae38079c1ad834e5840365f2b9cc6Qingxi Li * Start eUICC OTA update if current eUICC OS is not the latest one. When OTA is started or 20196d4dfe105bae38079c1ad834e5840365f2b9cc6Qingxi Li * finished, the broadcast {@link EuiccManager#ACTION_OTA_STATUS_CHANGED} will be sent. 20296d4dfe105bae38079c1ad834e5840365f2b9cc6Qingxi Li * 20396d4dfe105bae38079c1ad834e5840365f2b9cc6Qingxi Li * This function will only be called from phone process and isn't exposed to the other apps. 20496d4dfe105bae38079c1ad834e5840365f2b9cc6Qingxi Li */ 20596d4dfe105bae38079c1ad834e5840365f2b9cc6Qingxi Li public void startOtaUpdatingIfNecessary() { 20696d4dfe105bae38079c1ad834e5840365f2b9cc6Qingxi Li mConnector.startOtaIfNecessary( 20796d4dfe105bae38079c1ad834e5840365f2b9cc6Qingxi Li new OtaStatusChangedCallback() { 20896d4dfe105bae38079c1ad834e5840365f2b9cc6Qingxi Li @Override 20996d4dfe105bae38079c1ad834e5840365f2b9cc6Qingxi Li public void onOtaStatusChanged(int status) { 21096d4dfe105bae38079c1ad834e5840365f2b9cc6Qingxi Li sendOtaStatusChangedBroadcast(); 21196d4dfe105bae38079c1ad834e5840365f2b9cc6Qingxi Li } 21296d4dfe105bae38079c1ad834e5840365f2b9cc6Qingxi Li 21396d4dfe105bae38079c1ad834e5840365f2b9cc6Qingxi Li @Override 21496d4dfe105bae38079c1ad834e5840365f2b9cc6Qingxi Li public void onEuiccServiceUnavailable() {} 21596d4dfe105bae38079c1ad834e5840365f2b9cc6Qingxi Li }); 21696d4dfe105bae38079c1ad834e5840365f2b9cc6Qingxi Li } 21796d4dfe105bae38079c1ad834e5840365f2b9cc6Qingxi Li 218277a5a2aae73ef0233fffc350f3829aee779899fJeff Davidson @Override 219277a5a2aae73ef0233fffc350f3829aee779899fJeff Davidson public void getDownloadableSubscriptionMetadata(DownloadableSubscription subscription, 2209af6424827eb9e023e037dd5aefd229235aceddbJeff Davidson String callingPackage, PendingIntent callbackIntent) { 221953d76b6865b1f76c6fadbbd69898fe064b6c157Jeff Davidson getDownloadableSubscriptionMetadata( 2229af6424827eb9e023e037dd5aefd229235aceddbJeff Davidson subscription, false /* forceDeactivateSim */, callingPackage, callbackIntent); 223953d76b6865b1f76c6fadbbd69898fe064b6c157Jeff Davidson } 224953d76b6865b1f76c6fadbbd69898fe064b6c157Jeff Davidson 225953d76b6865b1f76c6fadbbd69898fe064b6c157Jeff Davidson void getDownloadableSubscriptionMetadata(DownloadableSubscription subscription, 2269af6424827eb9e023e037dd5aefd229235aceddbJeff Davidson boolean forceDeactivateSim, String callingPackage, PendingIntent callbackIntent) { 227277a5a2aae73ef0233fffc350f3829aee779899fJeff Davidson if (!callerCanWriteEmbeddedSubscriptions()) { 228277a5a2aae73ef0233fffc350f3829aee779899fJeff Davidson throw new SecurityException("Must have WRITE_EMBEDDED_SUBSCRIPTIONS to get metadata"); 229277a5a2aae73ef0233fffc350f3829aee779899fJeff Davidson } 2309af6424827eb9e023e037dd5aefd229235aceddbJeff Davidson mAppOpsManager.checkPackage(Binder.getCallingUid(), callingPackage); 231277a5a2aae73ef0233fffc350f3829aee779899fJeff Davidson long token = Binder.clearCallingIdentity(); 232277a5a2aae73ef0233fffc350f3829aee779899fJeff Davidson try { 23308d3d312d13c3194d8434aeb8c92ea220f4d0e2cJeff Davidson mConnector.getDownloadableSubscriptionMetadata( 234953d76b6865b1f76c6fadbbd69898fe064b6c157Jeff Davidson subscription, forceDeactivateSim, 2359af6424827eb9e023e037dd5aefd229235aceddbJeff Davidson new GetMetadataCommandCallback( 2369af6424827eb9e023e037dd5aefd229235aceddbJeff Davidson token, subscription, callingPackage, callbackIntent)); 237277a5a2aae73ef0233fffc350f3829aee779899fJeff Davidson } finally { 238277a5a2aae73ef0233fffc350f3829aee779899fJeff Davidson Binder.restoreCallingIdentity(token); 239277a5a2aae73ef0233fffc350f3829aee779899fJeff Davidson } 240277a5a2aae73ef0233fffc350f3829aee779899fJeff Davidson } 241277a5a2aae73ef0233fffc350f3829aee779899fJeff Davidson 24208d3d312d13c3194d8434aeb8c92ea220f4d0e2cJeff Davidson class GetMetadataCommandCallback implements EuiccConnector.GetMetadataCommandCallback { 243953d76b6865b1f76c6fadbbd69898fe064b6c157Jeff Davidson protected final long mCallingToken; 244953d76b6865b1f76c6fadbbd69898fe064b6c157Jeff Davidson protected final DownloadableSubscription mSubscription; 2459af6424827eb9e023e037dd5aefd229235aceddbJeff Davidson protected final String mCallingPackage; 24608d3d312d13c3194d8434aeb8c92ea220f4d0e2cJeff Davidson protected final PendingIntent mCallbackIntent; 24708d3d312d13c3194d8434aeb8c92ea220f4d0e2cJeff Davidson 248953d76b6865b1f76c6fadbbd69898fe064b6c157Jeff Davidson GetMetadataCommandCallback( 249953d76b6865b1f76c6fadbbd69898fe064b6c157Jeff Davidson long callingToken, 250953d76b6865b1f76c6fadbbd69898fe064b6c157Jeff Davidson DownloadableSubscription subscription, 2519af6424827eb9e023e037dd5aefd229235aceddbJeff Davidson String callingPackage, 252953d76b6865b1f76c6fadbbd69898fe064b6c157Jeff Davidson PendingIntent callbackIntent) { 253953d76b6865b1f76c6fadbbd69898fe064b6c157Jeff Davidson mCallingToken = callingToken; 254953d76b6865b1f76c6fadbbd69898fe064b6c157Jeff Davidson mSubscription = subscription; 2559af6424827eb9e023e037dd5aefd229235aceddbJeff Davidson mCallingPackage = callingPackage; 25608d3d312d13c3194d8434aeb8c92ea220f4d0e2cJeff Davidson mCallbackIntent = callbackIntent; 25708d3d312d13c3194d8434aeb8c92ea220f4d0e2cJeff Davidson } 25808d3d312d13c3194d8434aeb8c92ea220f4d0e2cJeff Davidson 25908d3d312d13c3194d8434aeb8c92ea220f4d0e2cJeff Davidson @Override 26008d3d312d13c3194d8434aeb8c92ea220f4d0e2cJeff Davidson public void onGetMetadataComplete( 26108d3d312d13c3194d8434aeb8c92ea220f4d0e2cJeff Davidson GetDownloadableSubscriptionMetadataResult result) { 26208d3d312d13c3194d8434aeb8c92ea220f4d0e2cJeff Davidson Intent extrasIntent = new Intent(); 26308d3d312d13c3194d8434aeb8c92ea220f4d0e2cJeff Davidson final int resultCode; 264d828468595f5483da81732d7e321c8204b0fa2b7Jiuyu Sun switch (result.getResult()) { 26531e69b5efbc9b9a39183acce93a4c1b2e73b3006Jeff Davidson case EuiccService.RESULT_OK: 26608d3d312d13c3194d8434aeb8c92ea220f4d0e2cJeff Davidson resultCode = OK; 26708d3d312d13c3194d8434aeb8c92ea220f4d0e2cJeff Davidson extrasIntent.putExtra( 2688bf20cb416675744e28821f509a20ae2813ad44eHolly Jiuyu Sun EXTRA_EMBEDDED_SUBSCRIPTION_DOWNLOADABLE_SUBSCRIPTION, 269d828468595f5483da81732d7e321c8204b0fa2b7Jiuyu Sun result.getDownloadableSubscription()); 27008d3d312d13c3194d8434aeb8c92ea220f4d0e2cJeff Davidson break; 27131e69b5efbc9b9a39183acce93a4c1b2e73b3006Jeff Davidson case EuiccService.RESULT_MUST_DEACTIVATE_SIM: 27208d3d312d13c3194d8434aeb8c92ea220f4d0e2cJeff Davidson resultCode = RESOLVABLE_ERROR; 273953d76b6865b1f76c6fadbbd69898fe064b6c157Jeff Davidson addResolutionIntent(extrasIntent, 274953d76b6865b1f76c6fadbbd69898fe064b6c157Jeff Davidson EuiccService.ACTION_RESOLVE_DEACTIVATE_SIM, 2759af6424827eb9e023e037dd5aefd229235aceddbJeff Davidson mCallingPackage, 276f2e6e134218a3302a8889ceef73d0f7ccfbddb56Holly Jiuyu Sun false /* confirmationCodeRetried */, 277953d76b6865b1f76c6fadbbd69898fe064b6c157Jeff Davidson getOperationForDeactivateSim()); 27808d3d312d13c3194d8434aeb8c92ea220f4d0e2cJeff Davidson break; 27931e69b5efbc9b9a39183acce93a4c1b2e73b3006Jeff Davidson default: 28031e69b5efbc9b9a39183acce93a4c1b2e73b3006Jeff Davidson resultCode = ERROR; 28108d3d312d13c3194d8434aeb8c92ea220f4d0e2cJeff Davidson extrasIntent.putExtra( 28208d3d312d13c3194d8434aeb8c92ea220f4d0e2cJeff Davidson EuiccManager.EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE, 283d828468595f5483da81732d7e321c8204b0fa2b7Jiuyu Sun result.getResult()); 28408d3d312d13c3194d8434aeb8c92ea220f4d0e2cJeff Davidson break; 28508d3d312d13c3194d8434aeb8c92ea220f4d0e2cJeff Davidson } 28608d3d312d13c3194d8434aeb8c92ea220f4d0e2cJeff Davidson 28708d3d312d13c3194d8434aeb8c92ea220f4d0e2cJeff Davidson sendResult(mCallbackIntent, resultCode, extrasIntent); 28808d3d312d13c3194d8434aeb8c92ea220f4d0e2cJeff Davidson } 28908d3d312d13c3194d8434aeb8c92ea220f4d0e2cJeff Davidson 29008d3d312d13c3194d8434aeb8c92ea220f4d0e2cJeff Davidson @Override 29108d3d312d13c3194d8434aeb8c92ea220f4d0e2cJeff Davidson public void onEuiccServiceUnavailable() { 29231e69b5efbc9b9a39183acce93a4c1b2e73b3006Jeff Davidson sendResult(mCallbackIntent, ERROR, null /* extrasIntent */); 29308d3d312d13c3194d8434aeb8c92ea220f4d0e2cJeff Davidson } 294953d76b6865b1f76c6fadbbd69898fe064b6c157Jeff Davidson 295953d76b6865b1f76c6fadbbd69898fe064b6c157Jeff Davidson protected EuiccOperation getOperationForDeactivateSim() { 2969af6424827eb9e023e037dd5aefd229235aceddbJeff Davidson return EuiccOperation.forGetMetadataDeactivateSim( 2979af6424827eb9e023e037dd5aefd229235aceddbJeff Davidson mCallingToken, mSubscription, mCallingPackage); 298953d76b6865b1f76c6fadbbd69898fe064b6c157Jeff Davidson } 29908d3d312d13c3194d8434aeb8c92ea220f4d0e2cJeff Davidson } 30008d3d312d13c3194d8434aeb8c92ea220f4d0e2cJeff Davidson 301277a5a2aae73ef0233fffc350f3829aee779899fJeff Davidson @Override 302277a5a2aae73ef0233fffc350f3829aee779899fJeff Davidson public void downloadSubscription(DownloadableSubscription subscription, 30308d3d312d13c3194d8434aeb8c92ea220f4d0e2cJeff Davidson boolean switchAfterDownload, String callingPackage, PendingIntent callbackIntent) { 304953d76b6865b1f76c6fadbbd69898fe064b6c157Jeff Davidson downloadSubscription(subscription, switchAfterDownload, callingPackage, 305953d76b6865b1f76c6fadbbd69898fe064b6c157Jeff Davidson false /* forceDeactivateSim */, callbackIntent); 306953d76b6865b1f76c6fadbbd69898fe064b6c157Jeff Davidson } 307953d76b6865b1f76c6fadbbd69898fe064b6c157Jeff Davidson 308953d76b6865b1f76c6fadbbd69898fe064b6c157Jeff Davidson void downloadSubscription(DownloadableSubscription subscription, 309953d76b6865b1f76c6fadbbd69898fe064b6c157Jeff Davidson boolean switchAfterDownload, String callingPackage, boolean forceDeactivateSim, 310953d76b6865b1f76c6fadbbd69898fe064b6c157Jeff Davidson PendingIntent callbackIntent) { 31108d3d312d13c3194d8434aeb8c92ea220f4d0e2cJeff Davidson boolean callerCanWriteEmbeddedSubscriptions = callerCanWriteEmbeddedSubscriptions(); 31208d3d312d13c3194d8434aeb8c92ea220f4d0e2cJeff Davidson mAppOpsManager.checkPackage(Binder.getCallingUid(), callingPackage); 31308d3d312d13c3194d8434aeb8c92ea220f4d0e2cJeff Davidson 314277a5a2aae73ef0233fffc350f3829aee779899fJeff Davidson long token = Binder.clearCallingIdentity(); 315277a5a2aae73ef0233fffc350f3829aee779899fJeff Davidson try { 31608d3d312d13c3194d8434aeb8c92ea220f4d0e2cJeff Davidson if (callerCanWriteEmbeddedSubscriptions) { 31708d3d312d13c3194d8434aeb8c92ea220f4d0e2cJeff Davidson // With WRITE_EMBEDDED_SUBSCRIPTIONS, we can skip profile-specific permission checks 31808d3d312d13c3194d8434aeb8c92ea220f4d0e2cJeff Davidson // and move straight to the profile download. 319953d76b6865b1f76c6fadbbd69898fe064b6c157Jeff Davidson downloadSubscriptionPrivileged(token, subscription, switchAfterDownload, 320953d76b6865b1f76c6fadbbd69898fe064b6c157Jeff Davidson forceDeactivateSim, callingPackage, callbackIntent); 32108d3d312d13c3194d8434aeb8c92ea220f4d0e2cJeff Davidson return; 32208d3d312d13c3194d8434aeb8c92ea220f4d0e2cJeff Davidson } 32308d3d312d13c3194d8434aeb8c92ea220f4d0e2cJeff Davidson // Without WRITE_EMBEDDED_SUBSCRIPTIONS, the caller *must* be whitelisted per the 32408d3d312d13c3194d8434aeb8c92ea220f4d0e2cJeff Davidson // metadata of the profile to be downloaded, so check the metadata first. 32508d3d312d13c3194d8434aeb8c92ea220f4d0e2cJeff Davidson mConnector.getDownloadableSubscriptionMetadata(subscription, 326953d76b6865b1f76c6fadbbd69898fe064b6c157Jeff Davidson forceDeactivateSim, 327953d76b6865b1f76c6fadbbd69898fe064b6c157Jeff Davidson new DownloadSubscriptionGetMetadataCommandCallback(token, subscription, 328953d76b6865b1f76c6fadbbd69898fe064b6c157Jeff Davidson switchAfterDownload, callingPackage, forceDeactivateSim, 329953d76b6865b1f76c6fadbbd69898fe064b6c157Jeff Davidson callbackIntent)); 330277a5a2aae73ef0233fffc350f3829aee779899fJeff Davidson } finally { 331277a5a2aae73ef0233fffc350f3829aee779899fJeff Davidson Binder.restoreCallingIdentity(token); 332277a5a2aae73ef0233fffc350f3829aee779899fJeff Davidson } 333277a5a2aae73ef0233fffc350f3829aee779899fJeff Davidson } 334277a5a2aae73ef0233fffc350f3829aee779899fJeff Davidson 33508d3d312d13c3194d8434aeb8c92ea220f4d0e2cJeff Davidson class DownloadSubscriptionGetMetadataCommandCallback extends GetMetadataCommandCallback { 33608d3d312d13c3194d8434aeb8c92ea220f4d0e2cJeff Davidson private final boolean mSwitchAfterDownload; 337953d76b6865b1f76c6fadbbd69898fe064b6c157Jeff Davidson private final boolean mForceDeactivateSim; 33808d3d312d13c3194d8434aeb8c92ea220f4d0e2cJeff Davidson 339953d76b6865b1f76c6fadbbd69898fe064b6c157Jeff Davidson DownloadSubscriptionGetMetadataCommandCallback(long callingToken, 340953d76b6865b1f76c6fadbbd69898fe064b6c157Jeff Davidson DownloadableSubscription subscription, boolean switchAfterDownload, 341953d76b6865b1f76c6fadbbd69898fe064b6c157Jeff Davidson String callingPackage, boolean forceDeactivateSim, 342953d76b6865b1f76c6fadbbd69898fe064b6c157Jeff Davidson PendingIntent callbackIntent) { 3439af6424827eb9e023e037dd5aefd229235aceddbJeff Davidson super(callingToken, subscription, callingPackage, callbackIntent); 34408d3d312d13c3194d8434aeb8c92ea220f4d0e2cJeff Davidson mSwitchAfterDownload = switchAfterDownload; 345953d76b6865b1f76c6fadbbd69898fe064b6c157Jeff Davidson mForceDeactivateSim = forceDeactivateSim; 34608d3d312d13c3194d8434aeb8c92ea220f4d0e2cJeff Davidson } 34708d3d312d13c3194d8434aeb8c92ea220f4d0e2cJeff Davidson 34808d3d312d13c3194d8434aeb8c92ea220f4d0e2cJeff Davidson @Override 34908d3d312d13c3194d8434aeb8c92ea220f4d0e2cJeff Davidson public void onGetMetadataComplete( 35008d3d312d13c3194d8434aeb8c92ea220f4d0e2cJeff Davidson GetDownloadableSubscriptionMetadataResult result) { 351d828468595f5483da81732d7e321c8204b0fa2b7Jiuyu Sun if (result.getResult() == EuiccService.RESULT_MUST_DEACTIVATE_SIM) { 3529af6424827eb9e023e037dd5aefd229235aceddbJeff Davidson // If we need to deactivate the current SIM to even check permissions, go ahead and 3539af6424827eb9e023e037dd5aefd229235aceddbJeff Davidson // require that the user resolve the stronger permission dialog. 3549af6424827eb9e023e037dd5aefd229235aceddbJeff Davidson Intent extrasIntent = new Intent(); 3559af6424827eb9e023e037dd5aefd229235aceddbJeff Davidson addResolutionIntent(extrasIntent, EuiccService.ACTION_RESOLVE_NO_PRIVILEGES, 3569af6424827eb9e023e037dd5aefd229235aceddbJeff Davidson mCallingPackage, 357f2e6e134218a3302a8889ceef73d0f7ccfbddb56Holly Jiuyu Sun false /* confirmationCodeRetried */, 3589af6424827eb9e023e037dd5aefd229235aceddbJeff Davidson EuiccOperation.forDownloadNoPrivileges( 3599af6424827eb9e023e037dd5aefd229235aceddbJeff Davidson mCallingToken, mSubscription, mSwitchAfterDownload, 3609af6424827eb9e023e037dd5aefd229235aceddbJeff Davidson mCallingPackage)); 3619af6424827eb9e023e037dd5aefd229235aceddbJeff Davidson sendResult(mCallbackIntent, RESOLVABLE_ERROR, extrasIntent); 3629af6424827eb9e023e037dd5aefd229235aceddbJeff Davidson return; 3639af6424827eb9e023e037dd5aefd229235aceddbJeff Davidson } 3649af6424827eb9e023e037dd5aefd229235aceddbJeff Davidson 365d828468595f5483da81732d7e321c8204b0fa2b7Jiuyu Sun if (result.getResult() != EuiccService.RESULT_OK) { 36608d3d312d13c3194d8434aeb8c92ea220f4d0e2cJeff Davidson // Just propagate the error as normal. 36708d3d312d13c3194d8434aeb8c92ea220f4d0e2cJeff Davidson super.onGetMetadataComplete(result); 36808d3d312d13c3194d8434aeb8c92ea220f4d0e2cJeff Davidson return; 36908d3d312d13c3194d8434aeb8c92ea220f4d0e2cJeff Davidson } 37008d3d312d13c3194d8434aeb8c92ea220f4d0e2cJeff Davidson 371d828468595f5483da81732d7e321c8204b0fa2b7Jiuyu Sun DownloadableSubscription subscription = result.getDownloadableSubscription(); 372d828468595f5483da81732d7e321c8204b0fa2b7Jiuyu Sun UiccAccessRule[] rules = null; 373d828468595f5483da81732d7e321c8204b0fa2b7Jiuyu Sun List<UiccAccessRule> rulesList = subscription.getAccessRules(); 374d828468595f5483da81732d7e321c8204b0fa2b7Jiuyu Sun if (rulesList != null) { 375d828468595f5483da81732d7e321c8204b0fa2b7Jiuyu Sun rules = rulesList.toArray(new UiccAccessRule[rulesList.size()]); 376d828468595f5483da81732d7e321c8204b0fa2b7Jiuyu Sun } 37708d3d312d13c3194d8434aeb8c92ea220f4d0e2cJeff Davidson if (rules == null) { 37808d3d312d13c3194d8434aeb8c92ea220f4d0e2cJeff Davidson Log.e(TAG, "No access rules but caller is unprivileged"); 37931e69b5efbc9b9a39183acce93a4c1b2e73b3006Jeff Davidson sendResult(mCallbackIntent, ERROR, null /* extrasIntent */); 38008d3d312d13c3194d8434aeb8c92ea220f4d0e2cJeff Davidson return; 38108d3d312d13c3194d8434aeb8c92ea220f4d0e2cJeff Davidson } 38208d3d312d13c3194d8434aeb8c92ea220f4d0e2cJeff Davidson 38308d3d312d13c3194d8434aeb8c92ea220f4d0e2cJeff Davidson final PackageInfo info; 38408d3d312d13c3194d8434aeb8c92ea220f4d0e2cJeff Davidson try { 38508d3d312d13c3194d8434aeb8c92ea220f4d0e2cJeff Davidson info = mPackageManager.getPackageInfo( 38608d3d312d13c3194d8434aeb8c92ea220f4d0e2cJeff Davidson mCallingPackage, PackageManager.GET_SIGNATURES); 38708d3d312d13c3194d8434aeb8c92ea220f4d0e2cJeff Davidson } catch (PackageManager.NameNotFoundException e) { 38808d3d312d13c3194d8434aeb8c92ea220f4d0e2cJeff Davidson Log.e(TAG, "Calling package valid but gone"); 38931e69b5efbc9b9a39183acce93a4c1b2e73b3006Jeff Davidson sendResult(mCallbackIntent, ERROR, null /* extrasIntent */); 39008d3d312d13c3194d8434aeb8c92ea220f4d0e2cJeff Davidson return; 39108d3d312d13c3194d8434aeb8c92ea220f4d0e2cJeff Davidson } 39208d3d312d13c3194d8434aeb8c92ea220f4d0e2cJeff Davidson 39308d3d312d13c3194d8434aeb8c92ea220f4d0e2cJeff Davidson for (int i = 0; i < rules.length; i++) { 39408d3d312d13c3194d8434aeb8c92ea220f4d0e2cJeff Davidson if (rules[i].getCarrierPrivilegeStatus(info) 39508d3d312d13c3194d8434aeb8c92ea220f4d0e2cJeff Davidson == TelephonyManager.CARRIER_PRIVILEGE_STATUS_HAS_ACCESS) { 396dce529f00c52bedf4377ee5f7ae1b284fe6452beJeff Davidson // Caller can download this profile. Now, determine whether the caller can also 397dce529f00c52bedf4377ee5f7ae1b284fe6452beJeff Davidson // manage the current profile; if so, we can perform the download silently; if 398dce529f00c52bedf4377ee5f7ae1b284fe6452beJeff Davidson // not, the user must provide consent. 3998f32416b4c5f5657e7ccf3a1ee031598a0203fd9Jeff Davidson if (canManageActiveSubscription(mCallingPackage)) { 4008f32416b4c5f5657e7ccf3a1ee031598a0203fd9Jeff Davidson downloadSubscriptionPrivileged( 4018f32416b4c5f5657e7ccf3a1ee031598a0203fd9Jeff Davidson mCallingToken, subscription, mSwitchAfterDownload, 4028f32416b4c5f5657e7ccf3a1ee031598a0203fd9Jeff Davidson mForceDeactivateSim, mCallingPackage, mCallbackIntent); 4038f32416b4c5f5657e7ccf3a1ee031598a0203fd9Jeff Davidson return; 40408d3d312d13c3194d8434aeb8c92ea220f4d0e2cJeff Davidson } 405dce529f00c52bedf4377ee5f7ae1b284fe6452beJeff Davidson 406dce529f00c52bedf4377ee5f7ae1b284fe6452beJeff Davidson // Switch might still be permitted, but the user must consent first. 407dce529f00c52bedf4377ee5f7ae1b284fe6452beJeff Davidson Intent extrasIntent = new Intent(); 408dce529f00c52bedf4377ee5f7ae1b284fe6452beJeff Davidson addResolutionIntent(extrasIntent, EuiccService.ACTION_RESOLVE_NO_PRIVILEGES, 4099af6424827eb9e023e037dd5aefd229235aceddbJeff Davidson mCallingPackage, 410f2e6e134218a3302a8889ceef73d0f7ccfbddb56Holly Jiuyu Sun false /* confirmationCodeRetried */, 411dce529f00c52bedf4377ee5f7ae1b284fe6452beJeff Davidson EuiccOperation.forDownloadNoPrivileges( 4128f32416b4c5f5657e7ccf3a1ee031598a0203fd9Jeff Davidson mCallingToken, subscription, mSwitchAfterDownload, 4138f32416b4c5f5657e7ccf3a1ee031598a0203fd9Jeff Davidson mCallingPackage)); 414dce529f00c52bedf4377ee5f7ae1b284fe6452beJeff Davidson sendResult(mCallbackIntent, RESOLVABLE_ERROR, extrasIntent); 41508d3d312d13c3194d8434aeb8c92ea220f4d0e2cJeff Davidson return; 41608d3d312d13c3194d8434aeb8c92ea220f4d0e2cJeff Davidson } 41708d3d312d13c3194d8434aeb8c92ea220f4d0e2cJeff Davidson } 41808d3d312d13c3194d8434aeb8c92ea220f4d0e2cJeff Davidson Log.e(TAG, "Caller is not permitted to download this profile"); 41931e69b5efbc9b9a39183acce93a4c1b2e73b3006Jeff Davidson sendResult(mCallbackIntent, ERROR, null /* extrasIntent */); 42008d3d312d13c3194d8434aeb8c92ea220f4d0e2cJeff Davidson } 421953d76b6865b1f76c6fadbbd69898fe064b6c157Jeff Davidson 422953d76b6865b1f76c6fadbbd69898fe064b6c157Jeff Davidson @Override 423953d76b6865b1f76c6fadbbd69898fe064b6c157Jeff Davidson protected EuiccOperation getOperationForDeactivateSim() { 424953d76b6865b1f76c6fadbbd69898fe064b6c157Jeff Davidson return EuiccOperation.forDownloadDeactivateSim( 425953d76b6865b1f76c6fadbbd69898fe064b6c157Jeff Davidson mCallingToken, mSubscription, mSwitchAfterDownload, mCallingPackage); 426953d76b6865b1f76c6fadbbd69898fe064b6c157Jeff Davidson } 42708d3d312d13c3194d8434aeb8c92ea220f4d0e2cJeff Davidson } 42808d3d312d13c3194d8434aeb8c92ea220f4d0e2cJeff Davidson 429953d76b6865b1f76c6fadbbd69898fe064b6c157Jeff Davidson void downloadSubscriptionPrivileged(final long callingToken, 430953d76b6865b1f76c6fadbbd69898fe064b6c157Jeff Davidson DownloadableSubscription subscription, boolean switchAfterDownload, 431953d76b6865b1f76c6fadbbd69898fe064b6c157Jeff Davidson boolean forceDeactivateSim, final String callingPackage, 432953d76b6865b1f76c6fadbbd69898fe064b6c157Jeff Davidson final PendingIntent callbackIntent) { 433953d76b6865b1f76c6fadbbd69898fe064b6c157Jeff Davidson mConnector.downloadSubscription( 434953d76b6865b1f76c6fadbbd69898fe064b6c157Jeff Davidson subscription, 435953d76b6865b1f76c6fadbbd69898fe064b6c157Jeff Davidson switchAfterDownload, 436953d76b6865b1f76c6fadbbd69898fe064b6c157Jeff Davidson forceDeactivateSim, 43708d3d312d13c3194d8434aeb8c92ea220f4d0e2cJeff Davidson new EuiccConnector.DownloadCommandCallback() { 43808d3d312d13c3194d8434aeb8c92ea220f4d0e2cJeff Davidson @Override 43931e69b5efbc9b9a39183acce93a4c1b2e73b3006Jeff Davidson public void onDownloadComplete(int result) { 44008d3d312d13c3194d8434aeb8c92ea220f4d0e2cJeff Davidson Intent extrasIntent = new Intent(); 44108d3d312d13c3194d8434aeb8c92ea220f4d0e2cJeff Davidson final int resultCode; 44231e69b5efbc9b9a39183acce93a4c1b2e73b3006Jeff Davidson switch (result) { 44331e69b5efbc9b9a39183acce93a4c1b2e73b3006Jeff Davidson case EuiccService.RESULT_OK: 44408d3d312d13c3194d8434aeb8c92ea220f4d0e2cJeff Davidson resultCode = OK; 4454f62c3ddcc69bc8217e4794c73d38945e97380eeJeff Davidson // Now that a profile has been successfully downloaded, mark the 4464f62c3ddcc69bc8217e4794c73d38945e97380eeJeff Davidson // eUICC as provisioned so it appears in settings UI as appropriate. 4474f62c3ddcc69bc8217e4794c73d38945e97380eeJeff Davidson Settings.Global.putInt( 4484f62c3ddcc69bc8217e4794c73d38945e97380eeJeff Davidson mContext.getContentResolver(), 4494f62c3ddcc69bc8217e4794c73d38945e97380eeJeff Davidson Settings.Global.EUICC_PROVISIONED, 4504f62c3ddcc69bc8217e4794c73d38945e97380eeJeff Davidson 1); 4518bf20cb416675744e28821f509a20ae2813ad44eHolly Jiuyu Sun extrasIntent.putExtra( 4528bf20cb416675744e28821f509a20ae2813ad44eHolly Jiuyu Sun EXTRA_EMBEDDED_SUBSCRIPTION_DOWNLOADABLE_SUBSCRIPTION, 4538bf20cb416675744e28821f509a20ae2813ad44eHolly Jiuyu Sun subscription); 454dce529f00c52bedf4377ee5f7ae1b284fe6452beJeff Davidson if (!switchAfterDownload) { 455dce529f00c52bedf4377ee5f7ae1b284fe6452beJeff Davidson // Since we're not switching, nothing will trigger a 456dce529f00c52bedf4377ee5f7ae1b284fe6452beJeff Davidson // subscription list refresh on its own, so request one here. 457d728841b17b19ab8268a426051f51f64a6913142Jeff Davidson refreshSubscriptionsAndSendResult( 458d728841b17b19ab8268a426051f51f64a6913142Jeff Davidson callbackIntent, resultCode, extrasIntent); 459d728841b17b19ab8268a426051f51f64a6913142Jeff Davidson return; 460dce529f00c52bedf4377ee5f7ae1b284fe6452beJeff Davidson } 46108d3d312d13c3194d8434aeb8c92ea220f4d0e2cJeff Davidson break; 46231e69b5efbc9b9a39183acce93a4c1b2e73b3006Jeff Davidson case EuiccService.RESULT_MUST_DEACTIVATE_SIM: 46308d3d312d13c3194d8434aeb8c92ea220f4d0e2cJeff Davidson resultCode = RESOLVABLE_ERROR; 464953d76b6865b1f76c6fadbbd69898fe064b6c157Jeff Davidson addResolutionIntent(extrasIntent, 465953d76b6865b1f76c6fadbbd69898fe064b6c157Jeff Davidson EuiccService.ACTION_RESOLVE_DEACTIVATE_SIM, 4669af6424827eb9e023e037dd5aefd229235aceddbJeff Davidson callingPackage, 467f2e6e134218a3302a8889ceef73d0f7ccfbddb56Holly Jiuyu Sun false /* confirmationCodeRetried */, 468953d76b6865b1f76c6fadbbd69898fe064b6c157Jeff Davidson EuiccOperation.forDownloadDeactivateSim( 469953d76b6865b1f76c6fadbbd69898fe064b6c157Jeff Davidson callingToken, subscription, switchAfterDownload, 470953d76b6865b1f76c6fadbbd69898fe064b6c157Jeff Davidson callingPackage)); 47108d3d312d13c3194d8434aeb8c92ea220f4d0e2cJeff Davidson break; 47280fc6417014d6a884b009557fd7d19861a1087abHolly Jiuyu Sun case EuiccService.RESULT_NEED_CONFIRMATION_CODE: 47380fc6417014d6a884b009557fd7d19861a1087abHolly Jiuyu Sun resultCode = RESOLVABLE_ERROR; 474f2e6e134218a3302a8889ceef73d0f7ccfbddb56Holly Jiuyu Sun boolean retried = false; 475f2e6e134218a3302a8889ceef73d0f7ccfbddb56Holly Jiuyu Sun if (!TextUtils.isEmpty(subscription.getConfirmationCode())) { 476f2e6e134218a3302a8889ceef73d0f7ccfbddb56Holly Jiuyu Sun retried = true; 477f2e6e134218a3302a8889ceef73d0f7ccfbddb56Holly Jiuyu Sun } 47880fc6417014d6a884b009557fd7d19861a1087abHolly Jiuyu Sun addResolutionIntent(extrasIntent, 47980fc6417014d6a884b009557fd7d19861a1087abHolly Jiuyu Sun EuiccService.ACTION_RESOLVE_CONFIRMATION_CODE, 48080fc6417014d6a884b009557fd7d19861a1087abHolly Jiuyu Sun callingPackage, 481f2e6e134218a3302a8889ceef73d0f7ccfbddb56Holly Jiuyu Sun retried /* confirmationCodeRetried */, 48280fc6417014d6a884b009557fd7d19861a1087abHolly Jiuyu Sun EuiccOperation.forDownloadConfirmationCode( 48380fc6417014d6a884b009557fd7d19861a1087abHolly Jiuyu Sun callingToken, subscription, switchAfterDownload, 48480fc6417014d6a884b009557fd7d19861a1087abHolly Jiuyu Sun callingPackage)); 48580fc6417014d6a884b009557fd7d19861a1087abHolly Jiuyu Sun break; 48631e69b5efbc9b9a39183acce93a4c1b2e73b3006Jeff Davidson default: 48731e69b5efbc9b9a39183acce93a4c1b2e73b3006Jeff Davidson resultCode = ERROR; 48808d3d312d13c3194d8434aeb8c92ea220f4d0e2cJeff Davidson extrasIntent.putExtra( 48908d3d312d13c3194d8434aeb8c92ea220f4d0e2cJeff Davidson EuiccManager.EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE, 49031e69b5efbc9b9a39183acce93a4c1b2e73b3006Jeff Davidson result); 49108d3d312d13c3194d8434aeb8c92ea220f4d0e2cJeff Davidson break; 49208d3d312d13c3194d8434aeb8c92ea220f4d0e2cJeff Davidson } 49308d3d312d13c3194d8434aeb8c92ea220f4d0e2cJeff Davidson 49408d3d312d13c3194d8434aeb8c92ea220f4d0e2cJeff Davidson sendResult(callbackIntent, resultCode, extrasIntent); 49508d3d312d13c3194d8434aeb8c92ea220f4d0e2cJeff Davidson } 49608d3d312d13c3194d8434aeb8c92ea220f4d0e2cJeff Davidson 49708d3d312d13c3194d8434aeb8c92ea220f4d0e2cJeff Davidson @Override 49808d3d312d13c3194d8434aeb8c92ea220f4d0e2cJeff Davidson public void onEuiccServiceUnavailable() { 49931e69b5efbc9b9a39183acce93a4c1b2e73b3006Jeff Davidson sendResult(callbackIntent, ERROR, null /* extrasIntent */); 50008d3d312d13c3194d8434aeb8c92ea220f4d0e2cJeff Davidson } 50108d3d312d13c3194d8434aeb8c92ea220f4d0e2cJeff Davidson }); 50208d3d312d13c3194d8434aeb8c92ea220f4d0e2cJeff Davidson } 50308d3d312d13c3194d8434aeb8c92ea220f4d0e2cJeff Davidson 504dce529f00c52bedf4377ee5f7ae1b284fe6452beJeff Davidson /** 505dce529f00c52bedf4377ee5f7ae1b284fe6452beJeff Davidson * Blocking call to {@link EuiccService#onGetEuiccProfileInfoList}. 506dce529f00c52bedf4377ee5f7ae1b284fe6452beJeff Davidson * 507dce529f00c52bedf4377ee5f7ae1b284fe6452beJeff Davidson * <p>Does not perform permission checks as this is not an exposed API and is only used within 508dce529f00c52bedf4377ee5f7ae1b284fe6452beJeff Davidson * the phone process. 509dce529f00c52bedf4377ee5f7ae1b284fe6452beJeff Davidson */ 510dce529f00c52bedf4377ee5f7ae1b284fe6452beJeff Davidson public GetEuiccProfileInfoListResult blockingGetEuiccProfileInfoList() { 511dce529f00c52bedf4377ee5f7ae1b284fe6452beJeff Davidson final CountDownLatch latch = new CountDownLatch(1); 512dce529f00c52bedf4377ee5f7ae1b284fe6452beJeff Davidson final AtomicReference<GetEuiccProfileInfoListResult> resultRef = new AtomicReference<>(); 513dce529f00c52bedf4377ee5f7ae1b284fe6452beJeff Davidson mConnector.getEuiccProfileInfoList( 514dce529f00c52bedf4377ee5f7ae1b284fe6452beJeff Davidson new EuiccConnector.GetEuiccProfileInfoListCommandCallback() { 515dce529f00c52bedf4377ee5f7ae1b284fe6452beJeff Davidson @Override 516dce529f00c52bedf4377ee5f7ae1b284fe6452beJeff Davidson public void onListComplete(GetEuiccProfileInfoListResult result) { 517dce529f00c52bedf4377ee5f7ae1b284fe6452beJeff Davidson resultRef.set(result); 518dce529f00c52bedf4377ee5f7ae1b284fe6452beJeff Davidson latch.countDown(); 519dce529f00c52bedf4377ee5f7ae1b284fe6452beJeff Davidson } 520dce529f00c52bedf4377ee5f7ae1b284fe6452beJeff Davidson 521dce529f00c52bedf4377ee5f7ae1b284fe6452beJeff Davidson @Override 522dce529f00c52bedf4377ee5f7ae1b284fe6452beJeff Davidson public void onEuiccServiceUnavailable() { 523dce529f00c52bedf4377ee5f7ae1b284fe6452beJeff Davidson latch.countDown(); 524dce529f00c52bedf4377ee5f7ae1b284fe6452beJeff Davidson } 525dce529f00c52bedf4377ee5f7ae1b284fe6452beJeff Davidson }); 526dce529f00c52bedf4377ee5f7ae1b284fe6452beJeff Davidson try { 527dce529f00c52bedf4377ee5f7ae1b284fe6452beJeff Davidson latch.await(); 528dce529f00c52bedf4377ee5f7ae1b284fe6452beJeff Davidson } catch (InterruptedException e) { 529dce529f00c52bedf4377ee5f7ae1b284fe6452beJeff Davidson Thread.currentThread().interrupt(); 530dce529f00c52bedf4377ee5f7ae1b284fe6452beJeff Davidson } 531dce529f00c52bedf4377ee5f7ae1b284fe6452beJeff Davidson return resultRef.get(); 532dce529f00c52bedf4377ee5f7ae1b284fe6452beJeff Davidson } 533dce529f00c52bedf4377ee5f7ae1b284fe6452beJeff Davidson 5348f32416b4c5f5657e7ccf3a1ee031598a0203fd9Jeff Davidson @Override 5359af6424827eb9e023e037dd5aefd229235aceddbJeff Davidson public void getDefaultDownloadableSubscriptionList( 5369af6424827eb9e023e037dd5aefd229235aceddbJeff Davidson String callingPackage, PendingIntent callbackIntent) { 5379af6424827eb9e023e037dd5aefd229235aceddbJeff Davidson getDefaultDownloadableSubscriptionList( 5389af6424827eb9e023e037dd5aefd229235aceddbJeff Davidson false /* forceDeactivateSim */, callingPackage, callbackIntent); 5398f32416b4c5f5657e7ccf3a1ee031598a0203fd9Jeff Davidson } 5408f32416b4c5f5657e7ccf3a1ee031598a0203fd9Jeff Davidson 5418f32416b4c5f5657e7ccf3a1ee031598a0203fd9Jeff Davidson void getDefaultDownloadableSubscriptionList( 5429af6424827eb9e023e037dd5aefd229235aceddbJeff Davidson boolean forceDeactivateSim, String callingPackage, PendingIntent callbackIntent) { 5438f32416b4c5f5657e7ccf3a1ee031598a0203fd9Jeff Davidson if (!callerCanWriteEmbeddedSubscriptions()) { 5448f32416b4c5f5657e7ccf3a1ee031598a0203fd9Jeff Davidson throw new SecurityException( 5458f32416b4c5f5657e7ccf3a1ee031598a0203fd9Jeff Davidson "Must have WRITE_EMBEDDED_SUBSCRIPTIONS to get default list"); 5468f32416b4c5f5657e7ccf3a1ee031598a0203fd9Jeff Davidson } 5479af6424827eb9e023e037dd5aefd229235aceddbJeff Davidson mAppOpsManager.checkPackage(Binder.getCallingUid(), callingPackage); 5488f32416b4c5f5657e7ccf3a1ee031598a0203fd9Jeff Davidson long token = Binder.clearCallingIdentity(); 5498f32416b4c5f5657e7ccf3a1ee031598a0203fd9Jeff Davidson try { 5508f32416b4c5f5657e7ccf3a1ee031598a0203fd9Jeff Davidson mConnector.getDefaultDownloadableSubscriptionList( 5519af6424827eb9e023e037dd5aefd229235aceddbJeff Davidson forceDeactivateSim, new GetDefaultListCommandCallback( 5529af6424827eb9e023e037dd5aefd229235aceddbJeff Davidson token, callingPackage, callbackIntent)); 5538f32416b4c5f5657e7ccf3a1ee031598a0203fd9Jeff Davidson } finally { 5548f32416b4c5f5657e7ccf3a1ee031598a0203fd9Jeff Davidson Binder.restoreCallingIdentity(token); 5558f32416b4c5f5657e7ccf3a1ee031598a0203fd9Jeff Davidson } 5568f32416b4c5f5657e7ccf3a1ee031598a0203fd9Jeff Davidson } 5578f32416b4c5f5657e7ccf3a1ee031598a0203fd9Jeff Davidson 5588f32416b4c5f5657e7ccf3a1ee031598a0203fd9Jeff Davidson class GetDefaultListCommandCallback implements EuiccConnector.GetDefaultListCommandCallback { 5599af6424827eb9e023e037dd5aefd229235aceddbJeff Davidson final long mCallingToken; 5609af6424827eb9e023e037dd5aefd229235aceddbJeff Davidson final String mCallingPackage; 5619af6424827eb9e023e037dd5aefd229235aceddbJeff Davidson final PendingIntent mCallbackIntent; 5628f32416b4c5f5657e7ccf3a1ee031598a0203fd9Jeff Davidson 5639af6424827eb9e023e037dd5aefd229235aceddbJeff Davidson GetDefaultListCommandCallback(long callingToken, String callingPackage, 5649af6424827eb9e023e037dd5aefd229235aceddbJeff Davidson PendingIntent callbackIntent) { 5658f32416b4c5f5657e7ccf3a1ee031598a0203fd9Jeff Davidson mCallingToken = callingToken; 5669af6424827eb9e023e037dd5aefd229235aceddbJeff Davidson mCallingPackage = callingPackage; 5678f32416b4c5f5657e7ccf3a1ee031598a0203fd9Jeff Davidson mCallbackIntent = callbackIntent; 5688f32416b4c5f5657e7ccf3a1ee031598a0203fd9Jeff Davidson } 5698f32416b4c5f5657e7ccf3a1ee031598a0203fd9Jeff Davidson 5708f32416b4c5f5657e7ccf3a1ee031598a0203fd9Jeff Davidson @Override 5718f32416b4c5f5657e7ccf3a1ee031598a0203fd9Jeff Davidson public void onGetDefaultListComplete(GetDefaultDownloadableSubscriptionListResult result) { 5728f32416b4c5f5657e7ccf3a1ee031598a0203fd9Jeff Davidson Intent extrasIntent = new Intent(); 5738f32416b4c5f5657e7ccf3a1ee031598a0203fd9Jeff Davidson final int resultCode; 574d828468595f5483da81732d7e321c8204b0fa2b7Jiuyu Sun switch (result.getResult()) { 57531e69b5efbc9b9a39183acce93a4c1b2e73b3006Jeff Davidson case EuiccService.RESULT_OK: 5768f32416b4c5f5657e7ccf3a1ee031598a0203fd9Jeff Davidson resultCode = OK; 577d828468595f5483da81732d7e321c8204b0fa2b7Jiuyu Sun List<DownloadableSubscription> list = result.getDownloadableSubscriptions(); 578d828468595f5483da81732d7e321c8204b0fa2b7Jiuyu Sun if (list != null && list.size() > 0) { 579d828468595f5483da81732d7e321c8204b0fa2b7Jiuyu Sun extrasIntent.putExtra( 580d828468595f5483da81732d7e321c8204b0fa2b7Jiuyu Sun EuiccManager.EXTRA_EMBEDDED_SUBSCRIPTION_DOWNLOADABLE_SUBSCRIPTIONS, 581d828468595f5483da81732d7e321c8204b0fa2b7Jiuyu Sun list.toArray(new DownloadableSubscription[list.size()])); 582d828468595f5483da81732d7e321c8204b0fa2b7Jiuyu Sun } 5838f32416b4c5f5657e7ccf3a1ee031598a0203fd9Jeff Davidson break; 58431e69b5efbc9b9a39183acce93a4c1b2e73b3006Jeff Davidson case EuiccService.RESULT_MUST_DEACTIVATE_SIM: 5858f32416b4c5f5657e7ccf3a1ee031598a0203fd9Jeff Davidson resultCode = RESOLVABLE_ERROR; 5868f32416b4c5f5657e7ccf3a1ee031598a0203fd9Jeff Davidson addResolutionIntent(extrasIntent, 5878f32416b4c5f5657e7ccf3a1ee031598a0203fd9Jeff Davidson EuiccService.ACTION_RESOLVE_DEACTIVATE_SIM, 5889af6424827eb9e023e037dd5aefd229235aceddbJeff Davidson mCallingPackage, 589f2e6e134218a3302a8889ceef73d0f7ccfbddb56Holly Jiuyu Sun false /* confirmationCodeRetried */, 5909af6424827eb9e023e037dd5aefd229235aceddbJeff Davidson EuiccOperation.forGetDefaultListDeactivateSim( 5919af6424827eb9e023e037dd5aefd229235aceddbJeff Davidson mCallingToken, mCallingPackage)); 5928f32416b4c5f5657e7ccf3a1ee031598a0203fd9Jeff Davidson break; 59331e69b5efbc9b9a39183acce93a4c1b2e73b3006Jeff Davidson default: 59431e69b5efbc9b9a39183acce93a4c1b2e73b3006Jeff Davidson resultCode = ERROR; 5958f32416b4c5f5657e7ccf3a1ee031598a0203fd9Jeff Davidson extrasIntent.putExtra( 5968f32416b4c5f5657e7ccf3a1ee031598a0203fd9Jeff Davidson EuiccManager.EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE, 597d828468595f5483da81732d7e321c8204b0fa2b7Jiuyu Sun result.getResult()); 5988f32416b4c5f5657e7ccf3a1ee031598a0203fd9Jeff Davidson break; 5998f32416b4c5f5657e7ccf3a1ee031598a0203fd9Jeff Davidson } 6008f32416b4c5f5657e7ccf3a1ee031598a0203fd9Jeff Davidson 6018f32416b4c5f5657e7ccf3a1ee031598a0203fd9Jeff Davidson sendResult(mCallbackIntent, resultCode, extrasIntent); 6028f32416b4c5f5657e7ccf3a1ee031598a0203fd9Jeff Davidson } 6038f32416b4c5f5657e7ccf3a1ee031598a0203fd9Jeff Davidson 6048f32416b4c5f5657e7ccf3a1ee031598a0203fd9Jeff Davidson @Override 6058f32416b4c5f5657e7ccf3a1ee031598a0203fd9Jeff Davidson public void onEuiccServiceUnavailable() { 60631e69b5efbc9b9a39183acce93a4c1b2e73b3006Jeff Davidson sendResult(mCallbackIntent, ERROR, null /* extrasIntent */); 6078f32416b4c5f5657e7ccf3a1ee031598a0203fd9Jeff Davidson } 6088f32416b4c5f5657e7ccf3a1ee031598a0203fd9Jeff Davidson } 6098f32416b4c5f5657e7ccf3a1ee031598a0203fd9Jeff Davidson 6108f32416b4c5f5657e7ccf3a1ee031598a0203fd9Jeff Davidson /** 6118f32416b4c5f5657e7ccf3a1ee031598a0203fd9Jeff Davidson * Return the {@link EuiccInfo}. 6128f32416b4c5f5657e7ccf3a1ee031598a0203fd9Jeff Davidson * 6138f32416b4c5f5657e7ccf3a1ee031598a0203fd9Jeff Davidson * <p>For API simplicity, this call blocks until completion; while it requires an IPC to load, 6148f32416b4c5f5657e7ccf3a1ee031598a0203fd9Jeff Davidson * that IPC should generally be fast, and this info shouldn't be needed in the normal course of 6158f32416b4c5f5657e7ccf3a1ee031598a0203fd9Jeff Davidson * operation. 6168f32416b4c5f5657e7ccf3a1ee031598a0203fd9Jeff Davidson */ 6178f32416b4c5f5657e7ccf3a1ee031598a0203fd9Jeff Davidson @Override 6188f32416b4c5f5657e7ccf3a1ee031598a0203fd9Jeff Davidson public EuiccInfo getEuiccInfo() { 6198f32416b4c5f5657e7ccf3a1ee031598a0203fd9Jeff Davidson // No permissions required as EuiccInfo is not sensitive. 6208f32416b4c5f5657e7ccf3a1ee031598a0203fd9Jeff Davidson long token = Binder.clearCallingIdentity(); 6218f32416b4c5f5657e7ccf3a1ee031598a0203fd9Jeff Davidson try { 6228f32416b4c5f5657e7ccf3a1ee031598a0203fd9Jeff Davidson return blockingGetEuiccInfoFromEuiccService(); 6238f32416b4c5f5657e7ccf3a1ee031598a0203fd9Jeff Davidson } finally { 6248f32416b4c5f5657e7ccf3a1ee031598a0203fd9Jeff Davidson Binder.restoreCallingIdentity(token); 6258f32416b4c5f5657e7ccf3a1ee031598a0203fd9Jeff Davidson } 6268f32416b4c5f5657e7ccf3a1ee031598a0203fd9Jeff Davidson } 6278f32416b4c5f5657e7ccf3a1ee031598a0203fd9Jeff Davidson 6288f32416b4c5f5657e7ccf3a1ee031598a0203fd9Jeff Davidson @Override 6298f32416b4c5f5657e7ccf3a1ee031598a0203fd9Jeff Davidson public void deleteSubscription(int subscriptionId, String callingPackage, 6308f32416b4c5f5657e7ccf3a1ee031598a0203fd9Jeff Davidson PendingIntent callbackIntent) { 6318f32416b4c5f5657e7ccf3a1ee031598a0203fd9Jeff Davidson boolean callerCanWriteEmbeddedSubscriptions = callerCanWriteEmbeddedSubscriptions(); 6328f32416b4c5f5657e7ccf3a1ee031598a0203fd9Jeff Davidson mAppOpsManager.checkPackage(Binder.getCallingUid(), callingPackage); 6338f32416b4c5f5657e7ccf3a1ee031598a0203fd9Jeff Davidson 6348f32416b4c5f5657e7ccf3a1ee031598a0203fd9Jeff Davidson long token = Binder.clearCallingIdentity(); 6358f32416b4c5f5657e7ccf3a1ee031598a0203fd9Jeff Davidson try { 6368f32416b4c5f5657e7ccf3a1ee031598a0203fd9Jeff Davidson SubscriptionInfo sub = getSubscriptionForSubscriptionId(subscriptionId); 6378f32416b4c5f5657e7ccf3a1ee031598a0203fd9Jeff Davidson if (sub == null) { 6388f32416b4c5f5657e7ccf3a1ee031598a0203fd9Jeff Davidson Log.e(TAG, "Cannot delete nonexistent subscription: " + subscriptionId); 63931e69b5efbc9b9a39183acce93a4c1b2e73b3006Jeff Davidson sendResult(callbackIntent, ERROR, null /* extrasIntent */); 6408f32416b4c5f5657e7ccf3a1ee031598a0203fd9Jeff Davidson return; 6418f32416b4c5f5657e7ccf3a1ee031598a0203fd9Jeff Davidson } 6428f32416b4c5f5657e7ccf3a1ee031598a0203fd9Jeff Davidson 6438f32416b4c5f5657e7ccf3a1ee031598a0203fd9Jeff Davidson if (!callerCanWriteEmbeddedSubscriptions 6448f32416b4c5f5657e7ccf3a1ee031598a0203fd9Jeff Davidson && !sub.canManageSubscription(mContext, callingPackage)) { 6458f32416b4c5f5657e7ccf3a1ee031598a0203fd9Jeff Davidson Log.e(TAG, "No permissions: " + subscriptionId); 64631e69b5efbc9b9a39183acce93a4c1b2e73b3006Jeff Davidson sendResult(callbackIntent, ERROR, null /* extrasIntent */); 6478f32416b4c5f5657e7ccf3a1ee031598a0203fd9Jeff Davidson return; 6488f32416b4c5f5657e7ccf3a1ee031598a0203fd9Jeff Davidson } 6498f32416b4c5f5657e7ccf3a1ee031598a0203fd9Jeff Davidson 6508f32416b4c5f5657e7ccf3a1ee031598a0203fd9Jeff Davidson deleteSubscriptionPrivileged(sub.getIccId(), callbackIntent); 6518f32416b4c5f5657e7ccf3a1ee031598a0203fd9Jeff Davidson } finally { 6528f32416b4c5f5657e7ccf3a1ee031598a0203fd9Jeff Davidson Binder.restoreCallingIdentity(token); 6538f32416b4c5f5657e7ccf3a1ee031598a0203fd9Jeff Davidson } 6548f32416b4c5f5657e7ccf3a1ee031598a0203fd9Jeff Davidson } 6558f32416b4c5f5657e7ccf3a1ee031598a0203fd9Jeff Davidson 6568f32416b4c5f5657e7ccf3a1ee031598a0203fd9Jeff Davidson void deleteSubscriptionPrivileged(String iccid, final PendingIntent callbackIntent) { 6578f32416b4c5f5657e7ccf3a1ee031598a0203fd9Jeff Davidson mConnector.deleteSubscription( 6588f32416b4c5f5657e7ccf3a1ee031598a0203fd9Jeff Davidson iccid, 6598f32416b4c5f5657e7ccf3a1ee031598a0203fd9Jeff Davidson new EuiccConnector.DeleteCommandCallback() { 6608f32416b4c5f5657e7ccf3a1ee031598a0203fd9Jeff Davidson @Override 66131e69b5efbc9b9a39183acce93a4c1b2e73b3006Jeff Davidson public void onDeleteComplete(int result) { 6628f32416b4c5f5657e7ccf3a1ee031598a0203fd9Jeff Davidson Intent extrasIntent = new Intent(); 6638f32416b4c5f5657e7ccf3a1ee031598a0203fd9Jeff Davidson final int resultCode; 66431e69b5efbc9b9a39183acce93a4c1b2e73b3006Jeff Davidson switch (result) { 66531e69b5efbc9b9a39183acce93a4c1b2e73b3006Jeff Davidson case EuiccService.RESULT_OK: 6668f32416b4c5f5657e7ccf3a1ee031598a0203fd9Jeff Davidson resultCode = OK; 667d728841b17b19ab8268a426051f51f64a6913142Jeff Davidson refreshSubscriptionsAndSendResult( 668d728841b17b19ab8268a426051f51f64a6913142Jeff Davidson callbackIntent, resultCode, extrasIntent); 669d728841b17b19ab8268a426051f51f64a6913142Jeff Davidson return; 67031e69b5efbc9b9a39183acce93a4c1b2e73b3006Jeff Davidson default: 67131e69b5efbc9b9a39183acce93a4c1b2e73b3006Jeff Davidson resultCode = ERROR; 6728f32416b4c5f5657e7ccf3a1ee031598a0203fd9Jeff Davidson extrasIntent.putExtra( 6738f32416b4c5f5657e7ccf3a1ee031598a0203fd9Jeff Davidson EuiccManager.EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE, 67431e69b5efbc9b9a39183acce93a4c1b2e73b3006Jeff Davidson result); 6758f32416b4c5f5657e7ccf3a1ee031598a0203fd9Jeff Davidson break; 6768f32416b4c5f5657e7ccf3a1ee031598a0203fd9Jeff Davidson } 6778f32416b4c5f5657e7ccf3a1ee031598a0203fd9Jeff Davidson 6788f32416b4c5f5657e7ccf3a1ee031598a0203fd9Jeff Davidson sendResult(callbackIntent, resultCode, extrasIntent); 6798f32416b4c5f5657e7ccf3a1ee031598a0203fd9Jeff Davidson } 6808f32416b4c5f5657e7ccf3a1ee031598a0203fd9Jeff Davidson 6818f32416b4c5f5657e7ccf3a1ee031598a0203fd9Jeff Davidson @Override 6828f32416b4c5f5657e7ccf3a1ee031598a0203fd9Jeff Davidson public void onEuiccServiceUnavailable() { 68331e69b5efbc9b9a39183acce93a4c1b2e73b3006Jeff Davidson sendResult(callbackIntent, ERROR, null /* extrasIntent */); 6848f32416b4c5f5657e7ccf3a1ee031598a0203fd9Jeff Davidson } 6858f32416b4c5f5657e7ccf3a1ee031598a0203fd9Jeff Davidson }); 6868f32416b4c5f5657e7ccf3a1ee031598a0203fd9Jeff Davidson } 6878f32416b4c5f5657e7ccf3a1ee031598a0203fd9Jeff Davidson 6888f32416b4c5f5657e7ccf3a1ee031598a0203fd9Jeff Davidson @Override 6898f32416b4c5f5657e7ccf3a1ee031598a0203fd9Jeff Davidson public void switchToSubscription(int subscriptionId, String callingPackage, 6908f32416b4c5f5657e7ccf3a1ee031598a0203fd9Jeff Davidson PendingIntent callbackIntent) { 6918f32416b4c5f5657e7ccf3a1ee031598a0203fd9Jeff Davidson switchToSubscription( 6928f32416b4c5f5657e7ccf3a1ee031598a0203fd9Jeff Davidson subscriptionId, false /* forceDeactivateSim */, callingPackage, callbackIntent); 6938f32416b4c5f5657e7ccf3a1ee031598a0203fd9Jeff Davidson } 6948f32416b4c5f5657e7ccf3a1ee031598a0203fd9Jeff Davidson 6958f32416b4c5f5657e7ccf3a1ee031598a0203fd9Jeff Davidson void switchToSubscription(int subscriptionId, boolean forceDeactivateSim, String callingPackage, 6968f32416b4c5f5657e7ccf3a1ee031598a0203fd9Jeff Davidson PendingIntent callbackIntent) { 6978f32416b4c5f5657e7ccf3a1ee031598a0203fd9Jeff Davidson boolean callerCanWriteEmbeddedSubscriptions = callerCanWriteEmbeddedSubscriptions(); 6988f32416b4c5f5657e7ccf3a1ee031598a0203fd9Jeff Davidson mAppOpsManager.checkPackage(Binder.getCallingUid(), callingPackage); 6998f32416b4c5f5657e7ccf3a1ee031598a0203fd9Jeff Davidson 7008f32416b4c5f5657e7ccf3a1ee031598a0203fd9Jeff Davidson long token = Binder.clearCallingIdentity(); 7018f32416b4c5f5657e7ccf3a1ee031598a0203fd9Jeff Davidson try { 7022938f11d0b1e409089828c0247a5b79f3550a35aJeff Davidson if (callerCanWriteEmbeddedSubscriptions) { 7032938f11d0b1e409089828c0247a5b79f3550a35aJeff Davidson // Assume that if a privileged caller is calling us, we don't need to prompt the 7042938f11d0b1e409089828c0247a5b79f3550a35aJeff Davidson // user about changing carriers, because the caller would only be acting in response 7052938f11d0b1e409089828c0247a5b79f3550a35aJeff Davidson // to user action. 7062938f11d0b1e409089828c0247a5b79f3550a35aJeff Davidson forceDeactivateSim = true; 7072938f11d0b1e409089828c0247a5b79f3550a35aJeff Davidson } 7082938f11d0b1e409089828c0247a5b79f3550a35aJeff Davidson 7098f32416b4c5f5657e7ccf3a1ee031598a0203fd9Jeff Davidson final String iccid; 7108f32416b4c5f5657e7ccf3a1ee031598a0203fd9Jeff Davidson if (subscriptionId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) { 7118f32416b4c5f5657e7ccf3a1ee031598a0203fd9Jeff Davidson // Switch to "no" subscription. Only the system can do this. 7128f32416b4c5f5657e7ccf3a1ee031598a0203fd9Jeff Davidson if (!callerCanWriteEmbeddedSubscriptions) { 7138f32416b4c5f5657e7ccf3a1ee031598a0203fd9Jeff Davidson Log.e(TAG, "Not permitted to switch to empty subscription"); 71431e69b5efbc9b9a39183acce93a4c1b2e73b3006Jeff Davidson sendResult(callbackIntent, ERROR, null /* extrasIntent */); 7158f32416b4c5f5657e7ccf3a1ee031598a0203fd9Jeff Davidson return; 7168f32416b4c5f5657e7ccf3a1ee031598a0203fd9Jeff Davidson } 7178f32416b4c5f5657e7ccf3a1ee031598a0203fd9Jeff Davidson iccid = null; 7188f32416b4c5f5657e7ccf3a1ee031598a0203fd9Jeff Davidson } else { 7198f32416b4c5f5657e7ccf3a1ee031598a0203fd9Jeff Davidson SubscriptionInfo sub = getSubscriptionForSubscriptionId(subscriptionId); 7208f32416b4c5f5657e7ccf3a1ee031598a0203fd9Jeff Davidson if (sub == null) { 7218f32416b4c5f5657e7ccf3a1ee031598a0203fd9Jeff Davidson Log.e(TAG, "Cannot switch to nonexistent subscription: " + subscriptionId); 72231e69b5efbc9b9a39183acce93a4c1b2e73b3006Jeff Davidson sendResult(callbackIntent, ERROR, null /* extrasIntent */); 7238f32416b4c5f5657e7ccf3a1ee031598a0203fd9Jeff Davidson return; 7248f32416b4c5f5657e7ccf3a1ee031598a0203fd9Jeff Davidson } 7258f32416b4c5f5657e7ccf3a1ee031598a0203fd9Jeff Davidson if (!callerCanWriteEmbeddedSubscriptions 726d828468595f5483da81732d7e321c8204b0fa2b7Jiuyu Sun && !mSubscriptionManager.canManageSubscription(sub, callingPackage)) { 7278f32416b4c5f5657e7ccf3a1ee031598a0203fd9Jeff Davidson Log.e(TAG, "Not permitted to switch to subscription: " + subscriptionId); 72831e69b5efbc9b9a39183acce93a4c1b2e73b3006Jeff Davidson sendResult(callbackIntent, ERROR, null /* extrasIntent */); 7298f32416b4c5f5657e7ccf3a1ee031598a0203fd9Jeff Davidson return; 7308f32416b4c5f5657e7ccf3a1ee031598a0203fd9Jeff Davidson } 7318f32416b4c5f5657e7ccf3a1ee031598a0203fd9Jeff Davidson iccid = sub.getIccId(); 7328f32416b4c5f5657e7ccf3a1ee031598a0203fd9Jeff Davidson } 7338f32416b4c5f5657e7ccf3a1ee031598a0203fd9Jeff Davidson 7348f32416b4c5f5657e7ccf3a1ee031598a0203fd9Jeff Davidson if (!callerCanWriteEmbeddedSubscriptions 7358f32416b4c5f5657e7ccf3a1ee031598a0203fd9Jeff Davidson && !canManageActiveSubscription(callingPackage)) { 7368f32416b4c5f5657e7ccf3a1ee031598a0203fd9Jeff Davidson // Switch needs consent. 7378f32416b4c5f5657e7ccf3a1ee031598a0203fd9Jeff Davidson Intent extrasIntent = new Intent(); 7388f32416b4c5f5657e7ccf3a1ee031598a0203fd9Jeff Davidson addResolutionIntent(extrasIntent, 7398f32416b4c5f5657e7ccf3a1ee031598a0203fd9Jeff Davidson EuiccService.ACTION_RESOLVE_NO_PRIVILEGES, 7409af6424827eb9e023e037dd5aefd229235aceddbJeff Davidson callingPackage, 741f2e6e134218a3302a8889ceef73d0f7ccfbddb56Holly Jiuyu Sun false /* confirmationCodeRetried */, 7428f32416b4c5f5657e7ccf3a1ee031598a0203fd9Jeff Davidson EuiccOperation.forSwitchNoPrivileges( 7438f32416b4c5f5657e7ccf3a1ee031598a0203fd9Jeff Davidson token, subscriptionId, callingPackage)); 7448f32416b4c5f5657e7ccf3a1ee031598a0203fd9Jeff Davidson sendResult(callbackIntent, RESOLVABLE_ERROR, extrasIntent); 7458f32416b4c5f5657e7ccf3a1ee031598a0203fd9Jeff Davidson return; 7468f32416b4c5f5657e7ccf3a1ee031598a0203fd9Jeff Davidson } 7478f32416b4c5f5657e7ccf3a1ee031598a0203fd9Jeff Davidson 7488f32416b4c5f5657e7ccf3a1ee031598a0203fd9Jeff Davidson switchToSubscriptionPrivileged(token, subscriptionId, iccid, forceDeactivateSim, 7498f32416b4c5f5657e7ccf3a1ee031598a0203fd9Jeff Davidson callingPackage, callbackIntent); 7508f32416b4c5f5657e7ccf3a1ee031598a0203fd9Jeff Davidson } finally { 7518f32416b4c5f5657e7ccf3a1ee031598a0203fd9Jeff Davidson Binder.restoreCallingIdentity(token); 7528f32416b4c5f5657e7ccf3a1ee031598a0203fd9Jeff Davidson } 7538f32416b4c5f5657e7ccf3a1ee031598a0203fd9Jeff Davidson } 7548f32416b4c5f5657e7ccf3a1ee031598a0203fd9Jeff Davidson 7558f32416b4c5f5657e7ccf3a1ee031598a0203fd9Jeff Davidson void switchToSubscriptionPrivileged(final long callingToken, int subscriptionId, 7568f32416b4c5f5657e7ccf3a1ee031598a0203fd9Jeff Davidson boolean forceDeactivateSim, final String callingPackage, 7578f32416b4c5f5657e7ccf3a1ee031598a0203fd9Jeff Davidson final PendingIntent callbackIntent) { 7588f32416b4c5f5657e7ccf3a1ee031598a0203fd9Jeff Davidson String iccid = null; 7598f32416b4c5f5657e7ccf3a1ee031598a0203fd9Jeff Davidson SubscriptionInfo sub = getSubscriptionForSubscriptionId(subscriptionId); 7608f32416b4c5f5657e7ccf3a1ee031598a0203fd9Jeff Davidson if (sub != null) { 7618f32416b4c5f5657e7ccf3a1ee031598a0203fd9Jeff Davidson iccid = sub.getIccId(); 7628f32416b4c5f5657e7ccf3a1ee031598a0203fd9Jeff Davidson } 7638f32416b4c5f5657e7ccf3a1ee031598a0203fd9Jeff Davidson switchToSubscriptionPrivileged(callingToken, subscriptionId, iccid, forceDeactivateSim, 7648f32416b4c5f5657e7ccf3a1ee031598a0203fd9Jeff Davidson callingPackage, callbackIntent); 7658f32416b4c5f5657e7ccf3a1ee031598a0203fd9Jeff Davidson } 7668f32416b4c5f5657e7ccf3a1ee031598a0203fd9Jeff Davidson 7678f32416b4c5f5657e7ccf3a1ee031598a0203fd9Jeff Davidson void switchToSubscriptionPrivileged(final long callingToken, int subscriptionId, 7688f32416b4c5f5657e7ccf3a1ee031598a0203fd9Jeff Davidson @Nullable String iccid, boolean forceDeactivateSim, final String callingPackage, 7698f32416b4c5f5657e7ccf3a1ee031598a0203fd9Jeff Davidson final PendingIntent callbackIntent) { 7708f32416b4c5f5657e7ccf3a1ee031598a0203fd9Jeff Davidson mConnector.switchToSubscription( 7718f32416b4c5f5657e7ccf3a1ee031598a0203fd9Jeff Davidson iccid, 7728f32416b4c5f5657e7ccf3a1ee031598a0203fd9Jeff Davidson forceDeactivateSim, 7738f32416b4c5f5657e7ccf3a1ee031598a0203fd9Jeff Davidson new EuiccConnector.SwitchCommandCallback() { 7748f32416b4c5f5657e7ccf3a1ee031598a0203fd9Jeff Davidson @Override 77531e69b5efbc9b9a39183acce93a4c1b2e73b3006Jeff Davidson public void onSwitchComplete(int result) { 7768f32416b4c5f5657e7ccf3a1ee031598a0203fd9Jeff Davidson Intent extrasIntent = new Intent(); 7778f32416b4c5f5657e7ccf3a1ee031598a0203fd9Jeff Davidson final int resultCode; 77831e69b5efbc9b9a39183acce93a4c1b2e73b3006Jeff Davidson switch (result) { 77931e69b5efbc9b9a39183acce93a4c1b2e73b3006Jeff Davidson case EuiccService.RESULT_OK: 7808f32416b4c5f5657e7ccf3a1ee031598a0203fd9Jeff Davidson resultCode = OK; 7818f32416b4c5f5657e7ccf3a1ee031598a0203fd9Jeff Davidson break; 78231e69b5efbc9b9a39183acce93a4c1b2e73b3006Jeff Davidson case EuiccService.RESULT_MUST_DEACTIVATE_SIM: 7838f32416b4c5f5657e7ccf3a1ee031598a0203fd9Jeff Davidson resultCode = RESOLVABLE_ERROR; 7848f32416b4c5f5657e7ccf3a1ee031598a0203fd9Jeff Davidson addResolutionIntent(extrasIntent, 7858f32416b4c5f5657e7ccf3a1ee031598a0203fd9Jeff Davidson EuiccService.ACTION_RESOLVE_DEACTIVATE_SIM, 7869af6424827eb9e023e037dd5aefd229235aceddbJeff Davidson callingPackage, 787f2e6e134218a3302a8889ceef73d0f7ccfbddb56Holly Jiuyu Sun false /* confirmationCodeRetried */, 7888f32416b4c5f5657e7ccf3a1ee031598a0203fd9Jeff Davidson EuiccOperation.forSwitchDeactivateSim( 7898f32416b4c5f5657e7ccf3a1ee031598a0203fd9Jeff Davidson callingToken, subscriptionId, callingPackage)); 7908f32416b4c5f5657e7ccf3a1ee031598a0203fd9Jeff Davidson break; 79131e69b5efbc9b9a39183acce93a4c1b2e73b3006Jeff Davidson default: 79231e69b5efbc9b9a39183acce93a4c1b2e73b3006Jeff Davidson resultCode = ERROR; 7938f32416b4c5f5657e7ccf3a1ee031598a0203fd9Jeff Davidson extrasIntent.putExtra( 7948f32416b4c5f5657e7ccf3a1ee031598a0203fd9Jeff Davidson EuiccManager.EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE, 79531e69b5efbc9b9a39183acce93a4c1b2e73b3006Jeff Davidson result); 7968f32416b4c5f5657e7ccf3a1ee031598a0203fd9Jeff Davidson break; 7978f32416b4c5f5657e7ccf3a1ee031598a0203fd9Jeff Davidson } 7988f32416b4c5f5657e7ccf3a1ee031598a0203fd9Jeff Davidson 7998f32416b4c5f5657e7ccf3a1ee031598a0203fd9Jeff Davidson sendResult(callbackIntent, resultCode, extrasIntent); 8008f32416b4c5f5657e7ccf3a1ee031598a0203fd9Jeff Davidson } 8018f32416b4c5f5657e7ccf3a1ee031598a0203fd9Jeff Davidson 8028f32416b4c5f5657e7ccf3a1ee031598a0203fd9Jeff Davidson @Override 8038f32416b4c5f5657e7ccf3a1ee031598a0203fd9Jeff Davidson public void onEuiccServiceUnavailable() { 80431e69b5efbc9b9a39183acce93a4c1b2e73b3006Jeff Davidson sendResult(callbackIntent, ERROR, null /* extrasIntent */); 8058f32416b4c5f5657e7ccf3a1ee031598a0203fd9Jeff Davidson } 8068f32416b4c5f5657e7ccf3a1ee031598a0203fd9Jeff Davidson }); 8078f32416b4c5f5657e7ccf3a1ee031598a0203fd9Jeff Davidson } 8088f32416b4c5f5657e7ccf3a1ee031598a0203fd9Jeff Davidson 8098f32416b4c5f5657e7ccf3a1ee031598a0203fd9Jeff Davidson @Override 8108f32416b4c5f5657e7ccf3a1ee031598a0203fd9Jeff Davidson public void updateSubscriptionNickname(int subscriptionId, String nickname, 8118f32416b4c5f5657e7ccf3a1ee031598a0203fd9Jeff Davidson PendingIntent callbackIntent) { 8128f32416b4c5f5657e7ccf3a1ee031598a0203fd9Jeff Davidson if (!callerCanWriteEmbeddedSubscriptions()) { 8138f32416b4c5f5657e7ccf3a1ee031598a0203fd9Jeff Davidson throw new SecurityException( 8148f32416b4c5f5657e7ccf3a1ee031598a0203fd9Jeff Davidson "Must have WRITE_EMBEDDED_SUBSCRIPTIONS to update nickname"); 8158f32416b4c5f5657e7ccf3a1ee031598a0203fd9Jeff Davidson } 8168f32416b4c5f5657e7ccf3a1ee031598a0203fd9Jeff Davidson long token = Binder.clearCallingIdentity(); 8178f32416b4c5f5657e7ccf3a1ee031598a0203fd9Jeff Davidson try { 8188f32416b4c5f5657e7ccf3a1ee031598a0203fd9Jeff Davidson SubscriptionInfo sub = getSubscriptionForSubscriptionId(subscriptionId); 8198f32416b4c5f5657e7ccf3a1ee031598a0203fd9Jeff Davidson if (sub == null) { 8208f32416b4c5f5657e7ccf3a1ee031598a0203fd9Jeff Davidson Log.e(TAG, "Cannot update nickname to nonexistent subscription: " + subscriptionId); 82131e69b5efbc9b9a39183acce93a4c1b2e73b3006Jeff Davidson sendResult(callbackIntent, ERROR, null /* extrasIntent */); 8228f32416b4c5f5657e7ccf3a1ee031598a0203fd9Jeff Davidson return; 8238f32416b4c5f5657e7ccf3a1ee031598a0203fd9Jeff Davidson } 8248f32416b4c5f5657e7ccf3a1ee031598a0203fd9Jeff Davidson mConnector.updateSubscriptionNickname( 8258f32416b4c5f5657e7ccf3a1ee031598a0203fd9Jeff Davidson sub.getIccId(), nickname, 8268f32416b4c5f5657e7ccf3a1ee031598a0203fd9Jeff Davidson new EuiccConnector.UpdateNicknameCommandCallback() { 8278f32416b4c5f5657e7ccf3a1ee031598a0203fd9Jeff Davidson @Override 82831e69b5efbc9b9a39183acce93a4c1b2e73b3006Jeff Davidson public void onUpdateNicknameComplete(int result) { 8298f32416b4c5f5657e7ccf3a1ee031598a0203fd9Jeff Davidson Intent extrasIntent = new Intent(); 8308f32416b4c5f5657e7ccf3a1ee031598a0203fd9Jeff Davidson final int resultCode; 83131e69b5efbc9b9a39183acce93a4c1b2e73b3006Jeff Davidson switch (result) { 83231e69b5efbc9b9a39183acce93a4c1b2e73b3006Jeff Davidson case EuiccService.RESULT_OK: 8338f32416b4c5f5657e7ccf3a1ee031598a0203fd9Jeff Davidson resultCode = OK; 8348f32416b4c5f5657e7ccf3a1ee031598a0203fd9Jeff Davidson break; 83531e69b5efbc9b9a39183acce93a4c1b2e73b3006Jeff Davidson default: 83631e69b5efbc9b9a39183acce93a4c1b2e73b3006Jeff Davidson resultCode = ERROR; 8378f32416b4c5f5657e7ccf3a1ee031598a0203fd9Jeff Davidson extrasIntent.putExtra( 8388f32416b4c5f5657e7ccf3a1ee031598a0203fd9Jeff Davidson EuiccManager.EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE, 83931e69b5efbc9b9a39183acce93a4c1b2e73b3006Jeff Davidson result); 8408f32416b4c5f5657e7ccf3a1ee031598a0203fd9Jeff Davidson break; 8418f32416b4c5f5657e7ccf3a1ee031598a0203fd9Jeff Davidson } 8428f32416b4c5f5657e7ccf3a1ee031598a0203fd9Jeff Davidson 8438f32416b4c5f5657e7ccf3a1ee031598a0203fd9Jeff Davidson sendResult(callbackIntent, resultCode, extrasIntent); 8448f32416b4c5f5657e7ccf3a1ee031598a0203fd9Jeff Davidson } 8458f32416b4c5f5657e7ccf3a1ee031598a0203fd9Jeff Davidson 8468f32416b4c5f5657e7ccf3a1ee031598a0203fd9Jeff Davidson @Override 8478f32416b4c5f5657e7ccf3a1ee031598a0203fd9Jeff Davidson public void onEuiccServiceUnavailable() { 84831e69b5efbc9b9a39183acce93a4c1b2e73b3006Jeff Davidson sendResult(callbackIntent, ERROR, null /* extrasIntent */); 8498f32416b4c5f5657e7ccf3a1ee031598a0203fd9Jeff Davidson } 8508f32416b4c5f5657e7ccf3a1ee031598a0203fd9Jeff Davidson }); 8518f32416b4c5f5657e7ccf3a1ee031598a0203fd9Jeff Davidson } finally { 8528f32416b4c5f5657e7ccf3a1ee031598a0203fd9Jeff Davidson Binder.restoreCallingIdentity(token); 8538f32416b4c5f5657e7ccf3a1ee031598a0203fd9Jeff Davidson } 8548f32416b4c5f5657e7ccf3a1ee031598a0203fd9Jeff Davidson } 8558f32416b4c5f5657e7ccf3a1ee031598a0203fd9Jeff Davidson 8568f32416b4c5f5657e7ccf3a1ee031598a0203fd9Jeff Davidson @Override 8578f32416b4c5f5657e7ccf3a1ee031598a0203fd9Jeff Davidson public void eraseSubscriptions(PendingIntent callbackIntent) { 8588f32416b4c5f5657e7ccf3a1ee031598a0203fd9Jeff Davidson if (!callerCanWriteEmbeddedSubscriptions()) { 8598f32416b4c5f5657e7ccf3a1ee031598a0203fd9Jeff Davidson throw new SecurityException( 8608f32416b4c5f5657e7ccf3a1ee031598a0203fd9Jeff Davidson "Must have WRITE_EMBEDDED_SUBSCRIPTIONS to erase subscriptions"); 8618f32416b4c5f5657e7ccf3a1ee031598a0203fd9Jeff Davidson } 8628f32416b4c5f5657e7ccf3a1ee031598a0203fd9Jeff Davidson long token = Binder.clearCallingIdentity(); 8638f32416b4c5f5657e7ccf3a1ee031598a0203fd9Jeff Davidson try { 8648f32416b4c5f5657e7ccf3a1ee031598a0203fd9Jeff Davidson mConnector.eraseSubscriptions(new EuiccConnector.EraseCommandCallback() { 8658f32416b4c5f5657e7ccf3a1ee031598a0203fd9Jeff Davidson @Override 86631e69b5efbc9b9a39183acce93a4c1b2e73b3006Jeff Davidson public void onEraseComplete(int result) { 8678f32416b4c5f5657e7ccf3a1ee031598a0203fd9Jeff Davidson Intent extrasIntent = new Intent(); 8688f32416b4c5f5657e7ccf3a1ee031598a0203fd9Jeff Davidson final int resultCode; 86931e69b5efbc9b9a39183acce93a4c1b2e73b3006Jeff Davidson switch (result) { 87031e69b5efbc9b9a39183acce93a4c1b2e73b3006Jeff Davidson case EuiccService.RESULT_OK: 8718f32416b4c5f5657e7ccf3a1ee031598a0203fd9Jeff Davidson resultCode = OK; 872d728841b17b19ab8268a426051f51f64a6913142Jeff Davidson refreshSubscriptionsAndSendResult( 873d728841b17b19ab8268a426051f51f64a6913142Jeff Davidson callbackIntent, resultCode, extrasIntent); 874d728841b17b19ab8268a426051f51f64a6913142Jeff Davidson return; 87531e69b5efbc9b9a39183acce93a4c1b2e73b3006Jeff Davidson default: 87631e69b5efbc9b9a39183acce93a4c1b2e73b3006Jeff Davidson resultCode = ERROR; 8778f32416b4c5f5657e7ccf3a1ee031598a0203fd9Jeff Davidson extrasIntent.putExtra( 8788f32416b4c5f5657e7ccf3a1ee031598a0203fd9Jeff Davidson EuiccManager.EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE, 87931e69b5efbc9b9a39183acce93a4c1b2e73b3006Jeff Davidson result); 8808f32416b4c5f5657e7ccf3a1ee031598a0203fd9Jeff Davidson break; 8818f32416b4c5f5657e7ccf3a1ee031598a0203fd9Jeff Davidson } 8828f32416b4c5f5657e7ccf3a1ee031598a0203fd9Jeff Davidson 8838f32416b4c5f5657e7ccf3a1ee031598a0203fd9Jeff Davidson sendResult(callbackIntent, resultCode, extrasIntent); 8848f32416b4c5f5657e7ccf3a1ee031598a0203fd9Jeff Davidson } 8858f32416b4c5f5657e7ccf3a1ee031598a0203fd9Jeff Davidson 8868f32416b4c5f5657e7ccf3a1ee031598a0203fd9Jeff Davidson @Override 8878f32416b4c5f5657e7ccf3a1ee031598a0203fd9Jeff Davidson public void onEuiccServiceUnavailable() { 88831e69b5efbc9b9a39183acce93a4c1b2e73b3006Jeff Davidson sendResult(callbackIntent, ERROR, null /* extrasIntent */); 8898f32416b4c5f5657e7ccf3a1ee031598a0203fd9Jeff Davidson } 8908f32416b4c5f5657e7ccf3a1ee031598a0203fd9Jeff Davidson }); 8918f32416b4c5f5657e7ccf3a1ee031598a0203fd9Jeff Davidson } finally { 8928f32416b4c5f5657e7ccf3a1ee031598a0203fd9Jeff Davidson Binder.restoreCallingIdentity(token); 8938f32416b4c5f5657e7ccf3a1ee031598a0203fd9Jeff Davidson } 8948f32416b4c5f5657e7ccf3a1ee031598a0203fd9Jeff Davidson } 8958f32416b4c5f5657e7ccf3a1ee031598a0203fd9Jeff Davidson 896a9c50823e758d35bac39cf2a7e674fcaf957fd4bJeff Davidson @Override 897a9c50823e758d35bac39cf2a7e674fcaf957fd4bJeff Davidson public void retainSubscriptionsForFactoryReset(PendingIntent callbackIntent) { 898a9c50823e758d35bac39cf2a7e674fcaf957fd4bJeff Davidson mContext.enforceCallingPermission(Manifest.permission.MASTER_CLEAR, 899a9c50823e758d35bac39cf2a7e674fcaf957fd4bJeff Davidson "Must have MASTER_CLEAR to retain subscriptions for factory reset"); 900a9c50823e758d35bac39cf2a7e674fcaf957fd4bJeff Davidson long token = Binder.clearCallingIdentity(); 901a9c50823e758d35bac39cf2a7e674fcaf957fd4bJeff Davidson try { 902a9c50823e758d35bac39cf2a7e674fcaf957fd4bJeff Davidson mConnector.retainSubscriptions( 903a9c50823e758d35bac39cf2a7e674fcaf957fd4bJeff Davidson new EuiccConnector.RetainSubscriptionsCommandCallback() { 904a9c50823e758d35bac39cf2a7e674fcaf957fd4bJeff Davidson @Override 905a9c50823e758d35bac39cf2a7e674fcaf957fd4bJeff Davidson public void onRetainSubscriptionsComplete(int result) { 906a9c50823e758d35bac39cf2a7e674fcaf957fd4bJeff Davidson Intent extrasIntent = new Intent(); 907a9c50823e758d35bac39cf2a7e674fcaf957fd4bJeff Davidson final int resultCode; 908a9c50823e758d35bac39cf2a7e674fcaf957fd4bJeff Davidson switch (result) { 909a9c50823e758d35bac39cf2a7e674fcaf957fd4bJeff Davidson case EuiccService.RESULT_OK: 910a9c50823e758d35bac39cf2a7e674fcaf957fd4bJeff Davidson resultCode = OK; 911a9c50823e758d35bac39cf2a7e674fcaf957fd4bJeff Davidson break; 912a9c50823e758d35bac39cf2a7e674fcaf957fd4bJeff Davidson default: 913a9c50823e758d35bac39cf2a7e674fcaf957fd4bJeff Davidson resultCode = ERROR; 914a9c50823e758d35bac39cf2a7e674fcaf957fd4bJeff Davidson extrasIntent.putExtra( 915a9c50823e758d35bac39cf2a7e674fcaf957fd4bJeff Davidson EuiccManager.EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE, 916a9c50823e758d35bac39cf2a7e674fcaf957fd4bJeff Davidson result); 917a9c50823e758d35bac39cf2a7e674fcaf957fd4bJeff Davidson break; 918a9c50823e758d35bac39cf2a7e674fcaf957fd4bJeff Davidson } 919a9c50823e758d35bac39cf2a7e674fcaf957fd4bJeff Davidson 920a9c50823e758d35bac39cf2a7e674fcaf957fd4bJeff Davidson sendResult(callbackIntent, resultCode, extrasIntent); 921a9c50823e758d35bac39cf2a7e674fcaf957fd4bJeff Davidson } 922a9c50823e758d35bac39cf2a7e674fcaf957fd4bJeff Davidson 923a9c50823e758d35bac39cf2a7e674fcaf957fd4bJeff Davidson @Override 924a9c50823e758d35bac39cf2a7e674fcaf957fd4bJeff Davidson public void onEuiccServiceUnavailable() { 925a9c50823e758d35bac39cf2a7e674fcaf957fd4bJeff Davidson sendResult(callbackIntent, ERROR, null /* extrasIntent */); 926a9c50823e758d35bac39cf2a7e674fcaf957fd4bJeff Davidson } 927a9c50823e758d35bac39cf2a7e674fcaf957fd4bJeff Davidson }); 928a9c50823e758d35bac39cf2a7e674fcaf957fd4bJeff Davidson } finally { 929a9c50823e758d35bac39cf2a7e674fcaf957fd4bJeff Davidson Binder.restoreCallingIdentity(token); 930a9c50823e758d35bac39cf2a7e674fcaf957fd4bJeff Davidson } 931a9c50823e758d35bac39cf2a7e674fcaf957fd4bJeff Davidson } 932a9c50823e758d35bac39cf2a7e674fcaf957fd4bJeff Davidson 933d728841b17b19ab8268a426051f51f64a6913142Jeff Davidson /** Refresh the embedded subscription list and dispatch the given result upon completion. */ 934d728841b17b19ab8268a426051f51f64a6913142Jeff Davidson @VisibleForTesting(visibility = VisibleForTesting.Visibility.PRIVATE) 935d728841b17b19ab8268a426051f51f64a6913142Jeff Davidson public void refreshSubscriptionsAndSendResult( 936d728841b17b19ab8268a426051f51f64a6913142Jeff Davidson PendingIntent callbackIntent, int resultCode, Intent extrasIntent) { 937d728841b17b19ab8268a426051f51f64a6913142Jeff Davidson SubscriptionController.getInstance() 938d728841b17b19ab8268a426051f51f64a6913142Jeff Davidson .requestEmbeddedSubscriptionInfoListRefresh( 939d728841b17b19ab8268a426051f51f64a6913142Jeff Davidson () -> sendResult(callbackIntent, resultCode, extrasIntent)); 940d728841b17b19ab8268a426051f51f64a6913142Jeff Davidson } 9418f32416b4c5f5657e7ccf3a1ee031598a0203fd9Jeff Davidson 942fc59bf75ccaaa45fcf8b9895f219a01955b75413Jeff Davidson /** Dispatch the given callback intent with the given result code and data. */ 943fc59bf75ccaaa45fcf8b9895f219a01955b75413Jeff Davidson @VisibleForTesting(visibility = VisibleForTesting.Visibility.PRIVATE) 944fc59bf75ccaaa45fcf8b9895f219a01955b75413Jeff Davidson public void sendResult(PendingIntent callbackIntent, int resultCode, Intent extrasIntent) { 945277a5a2aae73ef0233fffc350f3829aee779899fJeff Davidson try { 946277a5a2aae73ef0233fffc350f3829aee779899fJeff Davidson callbackIntent.send(mContext, resultCode, extrasIntent); 947277a5a2aae73ef0233fffc350f3829aee779899fJeff Davidson } catch (PendingIntent.CanceledException e) { 948277a5a2aae73ef0233fffc350f3829aee779899fJeff Davidson // Caller canceled the callback; do nothing. 949277a5a2aae73ef0233fffc350f3829aee779899fJeff Davidson } 950277a5a2aae73ef0233fffc350f3829aee779899fJeff Davidson } 951277a5a2aae73ef0233fffc350f3829aee779899fJeff Davidson 952953d76b6865b1f76c6fadbbd69898fe064b6c157Jeff Davidson /** Add a resolution intent to the given extras intent. */ 953953d76b6865b1f76c6fadbbd69898fe064b6c157Jeff Davidson @VisibleForTesting(visibility = VisibleForTesting.Visibility.PRIVATE) 954953d76b6865b1f76c6fadbbd69898fe064b6c157Jeff Davidson public void addResolutionIntent(Intent extrasIntent, String resolutionAction, 955f2e6e134218a3302a8889ceef73d0f7ccfbddb56Holly Jiuyu Sun String callingPackage, boolean confirmationCodeRetried, EuiccOperation op) { 956953d76b6865b1f76c6fadbbd69898fe064b6c157Jeff Davidson Intent intent = new Intent(EuiccManager.ACTION_RESOLVE_ERROR); 957953d76b6865b1f76c6fadbbd69898fe064b6c157Jeff Davidson intent.putExtra(EuiccManager.EXTRA_EMBEDDED_SUBSCRIPTION_RESOLUTION_ACTION, 958953d76b6865b1f76c6fadbbd69898fe064b6c157Jeff Davidson resolutionAction); 9599af6424827eb9e023e037dd5aefd229235aceddbJeff Davidson intent.putExtra(EuiccService.EXTRA_RESOLUTION_CALLING_PACKAGE, callingPackage); 960f2e6e134218a3302a8889ceef73d0f7ccfbddb56Holly Jiuyu Sun intent.putExtra(EuiccService.EXTRA_RESOLUTION_CONFIRMATION_CODE_RETRIED, 961f2e6e134218a3302a8889ceef73d0f7ccfbddb56Holly Jiuyu Sun confirmationCodeRetried); 962953d76b6865b1f76c6fadbbd69898fe064b6c157Jeff Davidson intent.putExtra(EXTRA_OPERATION, op); 963953d76b6865b1f76c6fadbbd69898fe064b6c157Jeff Davidson PendingIntent resolutionIntent = PendingIntent.getActivity( 964953d76b6865b1f76c6fadbbd69898fe064b6c157Jeff Davidson mContext, 0 /* requestCode */, intent, PendingIntent.FLAG_ONE_SHOT); 965953d76b6865b1f76c6fadbbd69898fe064b6c157Jeff Davidson extrasIntent.putExtra( 966953d76b6865b1f76c6fadbbd69898fe064b6c157Jeff Davidson EuiccManager.EXTRA_EMBEDDED_SUBSCRIPTION_RESOLUTION_INTENT, resolutionIntent); 967953d76b6865b1f76c6fadbbd69898fe064b6c157Jeff Davidson } 968953d76b6865b1f76c6fadbbd69898fe064b6c157Jeff Davidson 969277a5a2aae73ef0233fffc350f3829aee779899fJeff Davidson @Override 970277a5a2aae73ef0233fffc350f3829aee779899fJeff Davidson public void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 971277a5a2aae73ef0233fffc350f3829aee779899fJeff Davidson mContext.enforceCallingOrSelfPermission(android.Manifest.permission.DUMP, "Requires DUMP"); 972277a5a2aae73ef0233fffc350f3829aee779899fJeff Davidson final long token = Binder.clearCallingIdentity(); 973277a5a2aae73ef0233fffc350f3829aee779899fJeff Davidson try { 974277a5a2aae73ef0233fffc350f3829aee779899fJeff Davidson mConnector.dump(fd, pw, args); 975277a5a2aae73ef0233fffc350f3829aee779899fJeff Davidson } finally { 976277a5a2aae73ef0233fffc350f3829aee779899fJeff Davidson Binder.restoreCallingIdentity(token); 977277a5a2aae73ef0233fffc350f3829aee779899fJeff Davidson } 978277a5a2aae73ef0233fffc350f3829aee779899fJeff Davidson } 979277a5a2aae73ef0233fffc350f3829aee779899fJeff Davidson 98096d4dfe105bae38079c1ad834e5840365f2b9cc6Qingxi Li /** 98196d4dfe105bae38079c1ad834e5840365f2b9cc6Qingxi Li * Send broadcast {@link EuiccManager#ACTION_OTA_STATUS_CHANGED} for OTA status 98296d4dfe105bae38079c1ad834e5840365f2b9cc6Qingxi Li * changed. 98396d4dfe105bae38079c1ad834e5840365f2b9cc6Qingxi Li */ 98496d4dfe105bae38079c1ad834e5840365f2b9cc6Qingxi Li @VisibleForTesting(visibility = VisibleForTesting.Visibility.PRIVATE) 98596d4dfe105bae38079c1ad834e5840365f2b9cc6Qingxi Li public void sendOtaStatusChangedBroadcast() { 98696d4dfe105bae38079c1ad834e5840365f2b9cc6Qingxi Li Intent intent = new Intent(EuiccManager.ACTION_OTA_STATUS_CHANGED); 98796d4dfe105bae38079c1ad834e5840365f2b9cc6Qingxi Li mContext.sendBroadcast(intent, permission.WRITE_EMBEDDED_SUBSCRIPTIONS); 98896d4dfe105bae38079c1ad834e5840365f2b9cc6Qingxi Li } 98996d4dfe105bae38079c1ad834e5840365f2b9cc6Qingxi Li 990277a5a2aae73ef0233fffc350f3829aee779899fJeff Davidson @Nullable 9918f32416b4c5f5657e7ccf3a1ee031598a0203fd9Jeff Davidson private SubscriptionInfo getSubscriptionForSubscriptionId(int subscriptionId) { 9928f32416b4c5f5657e7ccf3a1ee031598a0203fd9Jeff Davidson List<SubscriptionInfo> subs = mSubscriptionManager.getAvailableSubscriptionInfoList(); 9938f32416b4c5f5657e7ccf3a1ee031598a0203fd9Jeff Davidson int subCount = subs.size(); 9948f32416b4c5f5657e7ccf3a1ee031598a0203fd9Jeff Davidson for (int i = 0; i < subCount; i++) { 9958f32416b4c5f5657e7ccf3a1ee031598a0203fd9Jeff Davidson SubscriptionInfo sub = subs.get(i); 9968f32416b4c5f5657e7ccf3a1ee031598a0203fd9Jeff Davidson if (subscriptionId == sub.getSubscriptionId()) { 9978f32416b4c5f5657e7ccf3a1ee031598a0203fd9Jeff Davidson return sub; 9988f32416b4c5f5657e7ccf3a1ee031598a0203fd9Jeff Davidson } 9998f32416b4c5f5657e7ccf3a1ee031598a0203fd9Jeff Davidson } 10008f32416b4c5f5657e7ccf3a1ee031598a0203fd9Jeff Davidson return null; 10018f32416b4c5f5657e7ccf3a1ee031598a0203fd9Jeff Davidson } 10028f32416b4c5f5657e7ccf3a1ee031598a0203fd9Jeff Davidson 10038f32416b4c5f5657e7ccf3a1ee031598a0203fd9Jeff Davidson @Nullable 1004277a5a2aae73ef0233fffc350f3829aee779899fJeff Davidson private String blockingGetEidFromEuiccService() { 10058f32416b4c5f5657e7ccf3a1ee031598a0203fd9Jeff Davidson CountDownLatch latch = new CountDownLatch(1); 10068f32416b4c5f5657e7ccf3a1ee031598a0203fd9Jeff Davidson AtomicReference<String> eidRef = new AtomicReference<>(); 1007277a5a2aae73ef0233fffc350f3829aee779899fJeff Davidson mConnector.getEid(new EuiccConnector.GetEidCommandCallback() { 1008277a5a2aae73ef0233fffc350f3829aee779899fJeff Davidson @Override 1009277a5a2aae73ef0233fffc350f3829aee779899fJeff Davidson public void onGetEidComplete(String eid) { 1010277a5a2aae73ef0233fffc350f3829aee779899fJeff Davidson eidRef.set(eid); 1011277a5a2aae73ef0233fffc350f3829aee779899fJeff Davidson latch.countDown(); 1012277a5a2aae73ef0233fffc350f3829aee779899fJeff Davidson } 1013277a5a2aae73ef0233fffc350f3829aee779899fJeff Davidson 1014277a5a2aae73ef0233fffc350f3829aee779899fJeff Davidson @Override 1015277a5a2aae73ef0233fffc350f3829aee779899fJeff Davidson public void onEuiccServiceUnavailable() { 1016277a5a2aae73ef0233fffc350f3829aee779899fJeff Davidson latch.countDown(); 1017277a5a2aae73ef0233fffc350f3829aee779899fJeff Davidson } 1018277a5a2aae73ef0233fffc350f3829aee779899fJeff Davidson }); 10198f32416b4c5f5657e7ccf3a1ee031598a0203fd9Jeff Davidson return awaitResult(latch, eidRef); 10208f32416b4c5f5657e7ccf3a1ee031598a0203fd9Jeff Davidson } 10218f32416b4c5f5657e7ccf3a1ee031598a0203fd9Jeff Davidson 1022ebbbe7bdbf2c6226913480bbd83a88cd0460a86aQingxi Li private @OtaStatus int blockingGetOtaStatusFromEuiccService() { 1023ebbbe7bdbf2c6226913480bbd83a88cd0460a86aQingxi Li CountDownLatch latch = new CountDownLatch(1); 1024ebbbe7bdbf2c6226913480bbd83a88cd0460a86aQingxi Li AtomicReference<Integer> statusRef = 1025ebbbe7bdbf2c6226913480bbd83a88cd0460a86aQingxi Li new AtomicReference<>(EUICC_OTA_STATUS_UNAVAILABLE); 1026ebbbe7bdbf2c6226913480bbd83a88cd0460a86aQingxi Li mConnector.getOtaStatus(new EuiccConnector.GetOtaStatusCommandCallback() { 1027ebbbe7bdbf2c6226913480bbd83a88cd0460a86aQingxi Li @Override 1028ebbbe7bdbf2c6226913480bbd83a88cd0460a86aQingxi Li public void onGetOtaStatusComplete(@OtaStatus int status) { 1029ebbbe7bdbf2c6226913480bbd83a88cd0460a86aQingxi Li statusRef.set(status); 1030ebbbe7bdbf2c6226913480bbd83a88cd0460a86aQingxi Li latch.countDown(); 1031ebbbe7bdbf2c6226913480bbd83a88cd0460a86aQingxi Li } 1032ebbbe7bdbf2c6226913480bbd83a88cd0460a86aQingxi Li 1033ebbbe7bdbf2c6226913480bbd83a88cd0460a86aQingxi Li @Override 1034ebbbe7bdbf2c6226913480bbd83a88cd0460a86aQingxi Li public void onEuiccServiceUnavailable() { 1035ebbbe7bdbf2c6226913480bbd83a88cd0460a86aQingxi Li latch.countDown(); 1036ebbbe7bdbf2c6226913480bbd83a88cd0460a86aQingxi Li } 1037ebbbe7bdbf2c6226913480bbd83a88cd0460a86aQingxi Li }); 1038ebbbe7bdbf2c6226913480bbd83a88cd0460a86aQingxi Li return awaitResult(latch, statusRef); 1039ebbbe7bdbf2c6226913480bbd83a88cd0460a86aQingxi Li } 1040ebbbe7bdbf2c6226913480bbd83a88cd0460a86aQingxi Li 10418f32416b4c5f5657e7ccf3a1ee031598a0203fd9Jeff Davidson @Nullable 10428f32416b4c5f5657e7ccf3a1ee031598a0203fd9Jeff Davidson private EuiccInfo blockingGetEuiccInfoFromEuiccService() { 10438f32416b4c5f5657e7ccf3a1ee031598a0203fd9Jeff Davidson CountDownLatch latch = new CountDownLatch(1); 10448f32416b4c5f5657e7ccf3a1ee031598a0203fd9Jeff Davidson AtomicReference<EuiccInfo> euiccInfoRef = new AtomicReference<>(); 10458f32416b4c5f5657e7ccf3a1ee031598a0203fd9Jeff Davidson mConnector.getEuiccInfo(new EuiccConnector.GetEuiccInfoCommandCallback() { 10468f32416b4c5f5657e7ccf3a1ee031598a0203fd9Jeff Davidson @Override 10478f32416b4c5f5657e7ccf3a1ee031598a0203fd9Jeff Davidson public void onGetEuiccInfoComplete(EuiccInfo euiccInfo) { 10488f32416b4c5f5657e7ccf3a1ee031598a0203fd9Jeff Davidson euiccInfoRef.set(euiccInfo); 10498f32416b4c5f5657e7ccf3a1ee031598a0203fd9Jeff Davidson latch.countDown(); 10508f32416b4c5f5657e7ccf3a1ee031598a0203fd9Jeff Davidson } 10518f32416b4c5f5657e7ccf3a1ee031598a0203fd9Jeff Davidson 10528f32416b4c5f5657e7ccf3a1ee031598a0203fd9Jeff Davidson @Override 10538f32416b4c5f5657e7ccf3a1ee031598a0203fd9Jeff Davidson public void onEuiccServiceUnavailable() { 10548f32416b4c5f5657e7ccf3a1ee031598a0203fd9Jeff Davidson latch.countDown(); 10558f32416b4c5f5657e7ccf3a1ee031598a0203fd9Jeff Davidson } 10568f32416b4c5f5657e7ccf3a1ee031598a0203fd9Jeff Davidson }); 10578f32416b4c5f5657e7ccf3a1ee031598a0203fd9Jeff Davidson return awaitResult(latch, euiccInfoRef); 10588f32416b4c5f5657e7ccf3a1ee031598a0203fd9Jeff Davidson } 10598f32416b4c5f5657e7ccf3a1ee031598a0203fd9Jeff Davidson 10608f32416b4c5f5657e7ccf3a1ee031598a0203fd9Jeff Davidson private static <T> T awaitResult(CountDownLatch latch, AtomicReference<T> resultRef) { 1061277a5a2aae73ef0233fffc350f3829aee779899fJeff Davidson try { 1062277a5a2aae73ef0233fffc350f3829aee779899fJeff Davidson latch.await(); 1063277a5a2aae73ef0233fffc350f3829aee779899fJeff Davidson } catch (InterruptedException e) { 1064277a5a2aae73ef0233fffc350f3829aee779899fJeff Davidson Thread.currentThread().interrupt(); 1065277a5a2aae73ef0233fffc350f3829aee779899fJeff Davidson } 10668f32416b4c5f5657e7ccf3a1ee031598a0203fd9Jeff Davidson return resultRef.get(); 10678f32416b4c5f5657e7ccf3a1ee031598a0203fd9Jeff Davidson } 10688f32416b4c5f5657e7ccf3a1ee031598a0203fd9Jeff Davidson 10698f32416b4c5f5657e7ccf3a1ee031598a0203fd9Jeff Davidson private boolean canManageActiveSubscription(String callingPackage) { 10708f32416b4c5f5657e7ccf3a1ee031598a0203fd9Jeff Davidson // TODO(b/36260308): We should plumb a slot ID through here for multi-SIM devices. 10718f32416b4c5f5657e7ccf3a1ee031598a0203fd9Jeff Davidson List<SubscriptionInfo> subInfoList = mSubscriptionManager.getActiveSubscriptionInfoList(); 107227590b4156bff85bcd8b68536216526d2dd029c7Jeff Davidson if (subInfoList == null) { 107327590b4156bff85bcd8b68536216526d2dd029c7Jeff Davidson return false; 107427590b4156bff85bcd8b68536216526d2dd029c7Jeff Davidson } 10758f32416b4c5f5657e7ccf3a1ee031598a0203fd9Jeff Davidson int size = subInfoList.size(); 10768f32416b4c5f5657e7ccf3a1ee031598a0203fd9Jeff Davidson for (int subIndex = 0; subIndex < size; subIndex++) { 10778f32416b4c5f5657e7ccf3a1ee031598a0203fd9Jeff Davidson SubscriptionInfo subInfo = subInfoList.get(subIndex); 1078d828468595f5483da81732d7e321c8204b0fa2b7Jiuyu Sun 1079d828468595f5483da81732d7e321c8204b0fa2b7Jiuyu Sun if (subInfo.isEmbedded() 1080d828468595f5483da81732d7e321c8204b0fa2b7Jiuyu Sun && mSubscriptionManager.canManageSubscription(subInfo, callingPackage)) { 10818f32416b4c5f5657e7ccf3a1ee031598a0203fd9Jeff Davidson return true; 10828f32416b4c5f5657e7ccf3a1ee031598a0203fd9Jeff Davidson } 10838f32416b4c5f5657e7ccf3a1ee031598a0203fd9Jeff Davidson } 10848f32416b4c5f5657e7ccf3a1ee031598a0203fd9Jeff Davidson return false; 1085277a5a2aae73ef0233fffc350f3829aee779899fJeff Davidson } 1086277a5a2aae73ef0233fffc350f3829aee779899fJeff Davidson 1087277a5a2aae73ef0233fffc350f3829aee779899fJeff Davidson private boolean callerCanReadPhoneStatePrivileged() { 1088277a5a2aae73ef0233fffc350f3829aee779899fJeff Davidson return mContext.checkCallingPermission(Manifest.permission.READ_PRIVILEGED_PHONE_STATE) 1089277a5a2aae73ef0233fffc350f3829aee779899fJeff Davidson == PackageManager.PERMISSION_GRANTED; 1090277a5a2aae73ef0233fffc350f3829aee779899fJeff Davidson } 1091277a5a2aae73ef0233fffc350f3829aee779899fJeff Davidson 1092277a5a2aae73ef0233fffc350f3829aee779899fJeff Davidson private boolean callerCanWriteEmbeddedSubscriptions() { 1093277a5a2aae73ef0233fffc350f3829aee779899fJeff Davidson return mContext.checkCallingPermission(Manifest.permission.WRITE_EMBEDDED_SUBSCRIPTIONS) 1094277a5a2aae73ef0233fffc350f3829aee779899fJeff Davidson == PackageManager.PERMISSION_GRANTED; 1095277a5a2aae73ef0233fffc350f3829aee779899fJeff Davidson } 1096277a5a2aae73ef0233fffc350f3829aee779899fJeff Davidson 1097277a5a2aae73ef0233fffc350f3829aee779899fJeff Davidson /** 1098277a5a2aae73ef0233fffc350f3829aee779899fJeff Davidson * Returns whether the caller has carrier privileges for the active mSubscription on this eUICC. 1099277a5a2aae73ef0233fffc350f3829aee779899fJeff Davidson */ 1100277a5a2aae73ef0233fffc350f3829aee779899fJeff Davidson private boolean callerHasCarrierPrivilegesForActiveSubscription() { 1101277a5a2aae73ef0233fffc350f3829aee779899fJeff Davidson // TODO(b/36260308): We should plumb a slot ID through here for multi-SIM devices. 1102277a5a2aae73ef0233fffc350f3829aee779899fJeff Davidson TelephonyManager tm = 1103277a5a2aae73ef0233fffc350f3829aee779899fJeff Davidson (TelephonyManager) mContext.getSystemService(Context.TELEPHONY_SERVICE); 1104277a5a2aae73ef0233fffc350f3829aee779899fJeff Davidson return tm.hasCarrierPrivileges(); 1105277a5a2aae73ef0233fffc350f3829aee779899fJeff Davidson } 1106277a5a2aae73ef0233fffc350f3829aee779899fJeff Davidson} 1107