1 /*
2  * Copyright (C) 2020 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 
17 package com.android.settings.network;
18 
19 import android.annotation.IntDef;
20 import android.app.FragmentManager;
21 import android.os.Bundle;
22 import android.telephony.SubscriptionInfo;
23 import android.util.Log;
24 
25 import com.android.settings.AsyncTaskSidecar;
26 import com.android.settings.SidecarFragment;
27 
28 import java.lang.annotation.Retention;
29 import java.lang.annotation.RetentionPolicy;
30 
31 import javax.annotation.Nullable;
32 
33 /** {@link SidecarFragment} to switch SIM slot. */
34 public class SwitchSlotSidecar
35         extends AsyncTaskSidecar<SwitchSlotSidecar.Param, SwitchSlotSidecar.Result> {
36     private static final String TAG = "SwitchSlotSidecar";
37 
38     /** Commands */
39     @Retention(RetentionPolicy.SOURCE)
40     @IntDef({
41         Command.SWITCH_TO_REMOVABLE_SIM,
42     })
43     private @interface Command {
44         int SWITCH_TO_REMOVABLE_SIM = 0;
45         int SWITCH_TO_EUICC_SIM = 1;
46     }
47 
48     static class Param {
49         @Command int command;
50         int slotId;
51         int port;
52         SubscriptionInfo removedSubInfo;
53     }
54 
55     static class Result {
56         Exception exception;
57     }
58 
59     /** Returns a SwitchSlotSidecar sidecar instance. */
get(FragmentManager fm)60     public static SwitchSlotSidecar get(FragmentManager fm) {
61         return SidecarFragment.get(fm, TAG, SwitchSlotSidecar.class, null /* args */);
62     }
63 
64     @Nullable private Exception mException;
65 
66     @Override
onCreate(Bundle savedInstanceState)67     public void onCreate(Bundle savedInstanceState) {
68         super.onCreate(savedInstanceState);
69     }
70 
71     /** Starts switching to the removable slot. */
runSwitchToRemovableSlot(int id, SubscriptionInfo removedSubInfo)72     public void runSwitchToRemovableSlot(int id, SubscriptionInfo removedSubInfo) {
73         Param param = new Param();
74         param.command = Command.SWITCH_TO_REMOVABLE_SIM;
75         param.slotId = id;
76         param.removedSubInfo = removedSubInfo;
77         param.port = 0;
78         super.run(param);
79     }
80 
81     /**
82      * Start the SimSlotMapping process if the euicc slot is not in SimSlotMapping list.
83      * @param physicalSlotId The physical slot id.
84      * @param port The port id.
85      * @param removedSubInfo The subscriptionInfo which is selected by the user to disable when all
86      *                      of sim slots are full in the device. If all of slots are not full in
87      *                       the device, then this is null.
88      */
runSwitchToEuiccSlot(int physicalSlotId, int port, SubscriptionInfo removedSubInfo)89     public void runSwitchToEuiccSlot(int physicalSlotId, int port,
90             SubscriptionInfo removedSubInfo) {
91         Param param = new Param();
92         param.command = Command.SWITCH_TO_EUICC_SIM;
93         param.slotId = physicalSlotId;
94         param.removedSubInfo = removedSubInfo;
95         param.port = port;
96         super.run(param);
97     }
98     /**
99      * Returns the exception thrown during the execution of a command. Will be null in any state
100      * other than {@link State#SUCCESS}, and may be null in that state if there was not an error.
101      */
102     @Nullable
getException()103     public Exception getException() {
104         return mException;
105     }
106 
107     @Override
doInBackground(@ullable Param param)108     protected Result doInBackground(@Nullable Param param) {
109         Result result = new Result();
110         if (param == null) {
111             result.exception = new UiccSlotsException("Null param");
112             return result;
113         }
114         try {
115             switch (param.command) {
116                 case Command.SWITCH_TO_REMOVABLE_SIM:
117                     Log.i(TAG, "Start to switch to removable slot.");
118                     UiccSlotUtil.switchToRemovableSlot(getContext(), param.slotId,
119                             param.removedSubInfo);
120                     break;
121                 case Command.SWITCH_TO_EUICC_SIM:
122                     Log.i(TAG, "Start to switch to euicc slot.");
123                     UiccSlotUtil.switchToEuiccSlot(getContext(), param.slotId, param.port,
124                             param.removedSubInfo);
125                     break;
126                 default:
127                     Log.e(TAG, "Wrong command.");
128                     break;
129             }
130         } catch (UiccSlotsException e) {
131             result.exception = e;
132         }
133         Log.i(TAG, "return command.");
134         return result;
135     }
136 
137     @Override
onPostExecute(Result result)138     protected void onPostExecute(Result result) {
139         Log.i(TAG, "onPostExecute: get result");
140         if (result.exception == null) {
141             setState(State.SUCCESS, Substate.UNUSED);
142         } else {
143             mException = result.exception;
144             setState(State.ERROR, Substate.UNUSED);
145         }
146     }
147 }
148