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 static android.content.Context.MODE_PRIVATE; 20 21 import android.app.Activity; 22 import android.content.Intent; 23 import android.content.SharedPreferences; 24 import android.os.Bundle; 25 import android.telecom.PhoneAccountHandle; 26 import android.telecom.TelecomManager; 27 import android.telephony.SubscriptionManager; 28 import android.telephony.TelephonyManager; 29 import android.util.Log; 30 import android.view.WindowManager; 31 import android.widget.Toast; 32 33 import androidx.fragment.app.Fragment; 34 import androidx.fragment.app.FragmentActivity; 35 import androidx.fragment.app.FragmentManager; 36 37 import com.android.settings.R; 38 import com.android.settings.network.SubscriptionUtil; 39 import com.android.settings.network.telephony.SubscriptionActionDialogActivity; 40 41 import java.util.List; 42 43 /** 44 * This activity provides singleton semantics per dialog type for showing various kinds of 45 * dialogs asking the user to make choices about which SIM to use for various services 46 * (calls, SMS, and data). 47 */ 48 public class SimDialogActivity extends FragmentActivity { 49 private static String TAG = "SimDialogActivity"; 50 51 public static String PREFERRED_SIM = "preferred_sim"; 52 public static String DIALOG_TYPE_KEY = "dialog_type"; 53 // sub ID returned from startActivityForResult 54 public static String RESULT_SUB_ID = "result_sub_id"; 55 public static final int INVALID_PICK = -1; 56 public static final int DATA_PICK = 0; 57 public static final int CALLS_PICK = 1; 58 public static final int SMS_PICK = 2; 59 public static final int PREFERRED_PICK = 3; 60 // Show the "select SMS subscription" dialog, but don't save as default, just return a result 61 public static final int SMS_PICK_FOR_MESSAGE = 4; 62 // Dismiss the current dialog and finish the activity. 63 public static final int PICK_DISMISS = 5; 64 65 @Override onCreate(Bundle savedInstanceState)66 protected void onCreate(Bundle savedInstanceState) { 67 super.onCreate(savedInstanceState); 68 69 if (!SubscriptionUtil.isSimHardwareVisible(this)) { 70 Log.d(TAG, "Not support on device without SIM."); 71 finish(); 72 return; 73 } 74 SimDialogProhibitService.supportDismiss(this); 75 76 getWindow().addSystemFlags( 77 WindowManager.LayoutParams.SYSTEM_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS); 78 showOrUpdateDialog(); 79 } 80 81 @Override onNewIntent(Intent intent)82 protected void onNewIntent(Intent intent) { 83 super.onNewIntent(intent); 84 setIntent(intent); 85 showOrUpdateDialog(); 86 } 87 getProgressState()88 private int getProgressState() { 89 final SharedPreferences prefs = getSharedPreferences( 90 SubscriptionActionDialogActivity.SIM_ACTION_DIALOG_PREFS, MODE_PRIVATE); 91 return prefs.getInt(SubscriptionActionDialogActivity.KEY_PROGRESS_STATE, 92 SubscriptionActionDialogActivity.PROGRESS_IS_NOT_SHOWING); 93 } 94 showOrUpdateDialog()95 private void showOrUpdateDialog() { 96 final int dialogType = getIntent().getIntExtra(DIALOG_TYPE_KEY, INVALID_PICK); 97 98 if (dialogType == PICK_DISMISS) { 99 finishAndRemoveTask(); 100 return; 101 } 102 103 if (dialogType == PREFERRED_PICK 104 && getProgressState() == SubscriptionActionDialogActivity.PROGRESS_IS_SHOWING) { 105 Log.d(TAG, "Finish the sim dialog since the sim action dialog is showing the progress"); 106 finish(); 107 return; 108 } 109 110 final String tag = Integer.toString(dialogType); 111 final FragmentManager fragmentManager = getSupportFragmentManager(); 112 SimDialogFragment fragment = (SimDialogFragment) fragmentManager.findFragmentByTag(tag); 113 114 if (fragment == null) { 115 fragment = createFragment(dialogType); 116 fragment.show(fragmentManager, tag); 117 } else { 118 fragment.updateDialog(); 119 } 120 } 121 createFragment(int dialogType)122 private SimDialogFragment createFragment(int dialogType) { 123 switch (dialogType) { 124 case DATA_PICK: 125 return getDataPickDialogFramgent(); 126 case CALLS_PICK: 127 return CallsSimListDialogFragment.newInstance(dialogType, 128 R.string.select_sim_for_calls, 129 true /* includeAskEveryTime */, 130 false /* isCancelItemShowed */); 131 case SMS_PICK: 132 return SimListDialogFragment.newInstance(dialogType, R.string.select_sim_for_sms, 133 true /* includeAskEveryTime */, 134 false /* isCancelItemShowed */); 135 case PREFERRED_PICK: 136 if (!getIntent().hasExtra(PREFERRED_SIM)) { 137 throw new IllegalArgumentException("Missing required extra " + PREFERRED_SIM); 138 } 139 return PreferredSimDialogFragment.newInstance(); 140 case SMS_PICK_FOR_MESSAGE: 141 return SimListDialogFragment.newInstance(dialogType, R.string.select_sim_for_sms, 142 false /* includeAskEveryTime */, 143 false /* isCancelItemShowed */); 144 default: 145 throw new IllegalArgumentException("Invalid dialog type " + dialogType + " sent."); 146 } 147 } 148 getDataPickDialogFramgent()149 private SimDialogFragment getDataPickDialogFramgent() { 150 if (SubscriptionManager.getDefaultDataSubscriptionId() 151 == SubscriptionManager.INVALID_SUBSCRIPTION_ID) { 152 return SimListDialogFragment.newInstance(DATA_PICK, R.string.select_sim_for_data, 153 false /* includeAskEveryTime */, 154 true /* isCancelItemShowed */); 155 } 156 return SelectSpecificDataSimDialogFragment.newInstance(); 157 } 158 onSubscriptionSelected(int dialogType, int subId)159 public void onSubscriptionSelected(int dialogType, int subId) { 160 if (getSupportFragmentManager().findFragmentByTag(Integer.toString(dialogType)) == null) { 161 Log.w(TAG, "onSubscriptionSelected ignored because stored fragment was null"); 162 return; 163 } 164 switch (dialogType) { 165 case DATA_PICK: 166 setDefaultDataSubId(subId); 167 break; 168 case CALLS_PICK: 169 setDefaultCallsSubId(subId); 170 break; 171 case SMS_PICK: 172 setDefaultSmsSubId(subId); 173 break; 174 case PREFERRED_PICK: 175 setPreferredSim(subId); 176 break; 177 case SMS_PICK_FOR_MESSAGE: 178 // Don't set a default here. 179 // The caller has created this dialog waiting for a result. 180 Intent intent = new Intent(); 181 intent.putExtra(RESULT_SUB_ID, subId); 182 setResult(Activity.RESULT_OK, intent); 183 break; 184 default: 185 throw new IllegalArgumentException( 186 "Invalid dialog type " + dialogType + " sent."); 187 } 188 } 189 onFragmentDismissed(SimDialogFragment simDialogFragment)190 public void onFragmentDismissed(SimDialogFragment simDialogFragment) { 191 final List<Fragment> fragments = getSupportFragmentManager().getFragments(); 192 if (fragments.size() == 1 && fragments.get(0) == simDialogFragment) { 193 finishAndRemoveTask(); 194 } 195 } 196 setDefaultDataSubId(final int subId)197 private void setDefaultDataSubId(final int subId) { 198 final SubscriptionManager subscriptionManager = getSystemService(SubscriptionManager.class); 199 final TelephonyManager telephonyManager = getSystemService( 200 TelephonyManager.class).createForSubscriptionId(subId); 201 subscriptionManager.setDefaultDataSubId(subId); 202 if (subId != SubscriptionManager.INVALID_SUBSCRIPTION_ID) { 203 telephonyManager.setDataEnabled(true); 204 Toast.makeText(this, R.string.data_switch_started, Toast.LENGTH_LONG).show(); 205 } 206 } 207 setDefaultCallsSubId(final int subId)208 private void setDefaultCallsSubId(final int subId) { 209 final PhoneAccountHandle phoneAccount = subscriptionIdToPhoneAccountHandle(subId); 210 final TelecomManager telecomManager = getSystemService(TelecomManager.class); 211 telecomManager.setUserSelectedOutgoingPhoneAccount(phoneAccount); 212 } 213 setDefaultSmsSubId(final int subId)214 private void setDefaultSmsSubId(final int subId) { 215 final SubscriptionManager subscriptionManager = getSystemService(SubscriptionManager.class); 216 subscriptionManager.setDefaultSmsSubId(subId); 217 } 218 setPreferredSim(final int subId)219 private void setPreferredSim(final int subId) { 220 setDefaultDataSubId(subId); 221 setDefaultSmsSubId(subId); 222 setDefaultCallsSubId(subId); 223 } 224 subscriptionIdToPhoneAccountHandle(final int subId)225 private PhoneAccountHandle subscriptionIdToPhoneAccountHandle(final int subId) { 226 final TelecomManager telecomManager = getSystemService(TelecomManager.class); 227 final TelephonyManager telephonyManager = getSystemService(TelephonyManager.class); 228 229 for (PhoneAccountHandle handle : telecomManager.getCallCapablePhoneAccounts()) { 230 if (subId == telephonyManager.getSubscriptionId(handle)) { 231 return handle; 232 } 233 } 234 return null; 235 } 236 237 /* 238 * Force dismiss this Activity. 239 */ forceClose()240 protected void forceClose() { 241 if (isFinishing() || isDestroyed()) { 242 return; 243 } 244 Log.d(TAG, "Dismissed by Service"); 245 finishAndRemoveTask(); 246 } 247 } 248