1 /*
2  * Copyright (C) 2017 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 package com.android.phone.euicc;
17 
18 import android.annotation.Nullable;
19 import android.app.PendingIntent;
20 import android.content.Intent;
21 import android.service.euicc.EuiccService;
22 import android.telephony.euicc.EuiccManager;
23 import android.util.ArraySet;
24 import android.util.Log;
25 
26 /**
27  * Trampoline activity to forward eUICC intents for error resolutions to the active UI
28  * implementation.
29  *
30  * <p>Unlike {@link EuiccUiDispatcherActivity}, this activity is started with extras that must not
31  * be tampered with, because they are used to resume the operation after the error is resolved. We
32  * thus declare it as a separate activity which requires a locked-down permission to start.
33  */
34 public class EuiccResolutionUiDispatcherActivity extends EuiccUiDispatcherActivity {
35     private static final String TAG = "EuiccResUiDispatcher";
36 
37     /** List of all valid resolution actions for validation purposes. */
38     private static final ArraySet<String> RESOLUTION_ACTIONS = new ArraySet<>();
39     static {
40         RESOLUTION_ACTIONS.add(EuiccService.ACTION_RESOLVE_DEACTIVATE_SIM);
41         RESOLUTION_ACTIONS.add(EuiccService.ACTION_RESOLVE_NO_PRIVILEGES);
42         RESOLUTION_ACTIONS.add(EuiccService.ACTION_RESOLVE_RESOLVABLE_ERRORS);
43     }
44 
45     @Override
46     @Nullable
getEuiccUiIntent()47     protected Intent getEuiccUiIntent() {
48         String action = getIntent().getAction();
49         if (!EuiccManager.ACTION_RESOLVE_ERROR.equals(action)) {
50             Log.w(TAG, "Unsupported action: " + action);
51             return null;
52         }
53 
54         String euiccUiAction =
55                 getIntent().getStringExtra(
56                         EuiccManager.EXTRA_EMBEDDED_SUBSCRIPTION_RESOLUTION_ACTION);
57         if (!RESOLUTION_ACTIONS.contains(euiccUiAction)) {
58             Log.w(TAG, "Unknown resolution action: " + euiccUiAction);
59             return null;
60         }
61 
62         Intent euiccUiIntent = new Intent(euiccUiAction);
63         // Propagate the extras from the original Intent.
64         euiccUiIntent.putExtras(getIntent());
65         return euiccUiIntent;
66     }
67 
68     @Override
onDispatchFailure()69     protected void onDispatchFailure() {
70         // Attempt to dispatch the callback so the caller knows the operation has failed.
71         PendingIntent callbackIntent =
72                 getIntent().getParcelableExtra(
73                         EuiccManager.EXTRA_EMBEDDED_SUBSCRIPTION_RESOLUTION_CALLBACK_INTENT);
74         if (callbackIntent != null) {
75             try {
76                 callbackIntent.send(EuiccManager.EMBEDDED_SUBSCRIPTION_RESULT_ERROR);
77             } catch (PendingIntent.CanceledException e) {
78                 // Caller canceled the callback; do nothing.
79             }
80         }
81     }
82 }
83