1 /*
2  * Copyright (C) 2014 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.sim;
18 
19 import android.app.Activity;
20 import android.content.Intent;
21 import android.os.Bundle;
22 import android.telecom.PhoneAccount;
23 import android.telecom.PhoneAccountHandle;
24 import android.telecom.TelecomManager;
25 import android.telephony.SubscriptionManager;
26 import android.telephony.TelephonyManager;
27 import android.util.Log;
28 import android.widget.Toast;
29 
30 import androidx.fragment.app.Fragment;
31 import androidx.fragment.app.FragmentActivity;
32 import androidx.fragment.app.FragmentManager;
33 
34 import com.android.settings.R;
35 
36 import java.util.List;
37 
38 /**
39  * This activity provides singleton semantics per dialog type for showing various kinds of
40  * dialogs asking the user to make choices about which SIM to use for various services
41  * (calls, SMS, and data).
42  */
43 public class SimDialogActivity extends FragmentActivity {
44     private static String TAG = "SimDialogActivity";
45 
46     public static String PREFERRED_SIM = "preferred_sim";
47     public static String DIALOG_TYPE_KEY = "dialog_type";
48     // sub ID returned from startActivityForResult
49     public static String RESULT_SUB_ID = "result_sub_id";
50     public static final int INVALID_PICK = -1;
51     public static final int DATA_PICK = 0;
52     public static final int CALLS_PICK = 1;
53     public static final int SMS_PICK = 2;
54     public static final int PREFERRED_PICK = 3;
55     // Show the "select SMS subscription" dialog, but don't save as default, just return a result
56     public static final int SMS_PICK_FOR_MESSAGE = 4;
57 
58     @Override
onCreate(Bundle savedInstanceState)59     protected void onCreate(Bundle savedInstanceState) {
60         super.onCreate(savedInstanceState);
61         showOrUpdateDialog();
62     }
63 
64     @Override
onNewIntent(Intent intent)65     protected void onNewIntent(Intent intent) {
66         super.onNewIntent(intent);
67         setIntent(intent);
68         showOrUpdateDialog();
69     }
70 
showOrUpdateDialog()71     private void showOrUpdateDialog() {
72         final int dialogType = getIntent().getIntExtra(DIALOG_TYPE_KEY, INVALID_PICK);
73         final String tag = Integer.toString(dialogType);
74         final FragmentManager fragmentManager = getSupportFragmentManager();
75         SimDialogFragment fragment = (SimDialogFragment) fragmentManager.findFragmentByTag(tag);
76 
77         if (fragment == null) {
78             fragment = createFragment(dialogType);
79             fragment.show(fragmentManager, tag);
80         } else {
81             fragment.updateDialog();
82         }
83     }
84 
createFragment(int dialogType)85     private SimDialogFragment createFragment(int dialogType) {
86         switch (dialogType) {
87             case DATA_PICK:
88                 return SimListDialogFragment.newInstance(dialogType, R.string.select_sim_for_data,
89                         false /* includeAskEveryTime */);
90             case CALLS_PICK:
91                 return CallsSimListDialogFragment.newInstance(dialogType,
92                         R.string.select_sim_for_calls,
93                         true /* includeAskEveryTime */);
94             case SMS_PICK:
95                 return SimListDialogFragment.newInstance(dialogType, R.string.select_sim_for_sms,
96                         true /* includeAskEveryTime */);
97             case PREFERRED_PICK:
98                 if (!getIntent().hasExtra(PREFERRED_SIM)) {
99                     throw new IllegalArgumentException("Missing required extra " + PREFERRED_SIM);
100                 }
101                 return PreferredSimDialogFragment.newInstance();
102             case SMS_PICK_FOR_MESSAGE:
103                 return SimListDialogFragment.newInstance(dialogType, R.string.select_sim_for_sms,
104                         false /* includeAskEveryTime */);
105             default:
106                 throw new IllegalArgumentException("Invalid dialog type " + dialogType + " sent.");
107         }
108     }
109 
onSubscriptionSelected(int dialogType, int subId)110     public void onSubscriptionSelected(int dialogType, int subId) {
111         if (getSupportFragmentManager().findFragmentByTag(Integer.toString(dialogType)) == null) {
112             Log.w(TAG, "onSubscriptionSelected ignored because stored fragment was null");
113             return;
114         }
115         switch (dialogType) {
116             case DATA_PICK:
117                 setDefaultDataSubId(subId);
118                 break;
119             case CALLS_PICK:
120                 setDefaultCallsSubId(subId);
121                 break;
122             case SMS_PICK:
123                 setDefaultSmsSubId(subId);
124                 break;
125             case PREFERRED_PICK:
126                 setPreferredSim(subId);
127                 break;
128             case SMS_PICK_FOR_MESSAGE:
129                 // Don't set a default here.
130                 // The caller has created this dialog waiting for a result.
131                 Intent intent = new Intent();
132                 intent.putExtra(RESULT_SUB_ID, subId);
133                 setResult(Activity.RESULT_OK, intent);
134                 break;
135             default:
136                 throw new IllegalArgumentException(
137                         "Invalid dialog type " + dialogType + " sent.");
138         }
139     }
140 
onFragmentDismissed(SimDialogFragment simDialogFragment)141     public void onFragmentDismissed(SimDialogFragment simDialogFragment) {
142         final List<Fragment> fragments = getSupportFragmentManager().getFragments();
143         if (fragments.size() == 1 && fragments.get(0) == simDialogFragment) {
144             finishAndRemoveTask();
145         }
146     }
147 
setDefaultDataSubId(final int subId)148     private void setDefaultDataSubId(final int subId) {
149         final SubscriptionManager subscriptionManager = getSystemService(SubscriptionManager.class);
150         final TelephonyManager telephonyManager = getSystemService(
151                 TelephonyManager.class).createForSubscriptionId(subId);
152         subscriptionManager.setDefaultDataSubId(subId);
153         telephonyManager.setDataEnabled(true);
154         Toast.makeText(this, R.string.data_switch_started, Toast.LENGTH_LONG).show();
155     }
156 
setDefaultCallsSubId(final int subId)157     private void setDefaultCallsSubId(final int subId) {
158         final PhoneAccountHandle phoneAccount = subscriptionIdToPhoneAccountHandle(subId);
159         final TelecomManager telecomManager = getSystemService(TelecomManager.class);
160         telecomManager.setUserSelectedOutgoingPhoneAccount(phoneAccount);
161     }
162 
setDefaultSmsSubId(final int subId)163     private void setDefaultSmsSubId(final int subId) {
164         final SubscriptionManager subscriptionManager = getSystemService(SubscriptionManager.class);
165         subscriptionManager.setDefaultSmsSubId(subId);
166     }
167 
setPreferredSim(final int subId)168     private void setPreferredSim(final int subId) {
169         setDefaultDataSubId(subId);
170         setDefaultSmsSubId(subId);
171         setDefaultCallsSubId(subId);
172     }
173 
subscriptionIdToPhoneAccountHandle(final int subId)174     private PhoneAccountHandle subscriptionIdToPhoneAccountHandle(final int subId) {
175         final TelecomManager telecomManager = getSystemService(TelecomManager.class);
176         final TelephonyManager telephonyManager = getSystemService(TelephonyManager.class);
177 
178         for (PhoneAccountHandle handle : telecomManager.getCallCapablePhoneAccounts()) {
179             if (subId == telephonyManager.getSubscriptionId(handle)) {
180                 return handle;
181             }
182         }
183         return null;
184     }
185 }
186