1 package com.android.phone.settings;
2 
3 import android.content.ActivityNotFoundException;
4 import android.content.Context;
5 import android.content.Intent;
6 import android.net.sip.SipManager;
7 import android.os.Bundle;
8 import android.os.UserHandle;
9 import android.preference.CheckBoxPreference;
10 import android.preference.ListPreference;
11 import android.preference.Preference;
12 import android.preference.PreferenceCategory;
13 import android.preference.PreferenceFragment;
14 import android.telecom.PhoneAccountHandle;
15 import android.telecom.TelecomManager;
16 import android.telephony.SubscriptionInfo;
17 import android.telephony.SubscriptionManager;
18 import android.telephony.TelephonyManager;
19 import android.util.Log;
20 
21 import com.android.phone.R;
22 import com.android.phone.SubscriptionInfoHelper;
23 import com.android.services.telephony.sip.SipAccountRegistry;
24 import com.android.services.telephony.sip.SipSharedPreferences;
25 import com.android.services.telephony.sip.SipUtil;
26 
27 import java.util.List;
28 
29 public class PhoneAccountSettingsFragment extends PreferenceFragment
30         implements Preference.OnPreferenceChangeListener,
31                 Preference.OnPreferenceClickListener,
32                 AccountSelectionPreference.AccountSelectionListener {
33 
34     private static final String ACCOUNTS_LIST_CATEGORY_KEY =
35             "phone_accounts_accounts_list_category_key";
36 
37     private static final String DEFAULT_OUTGOING_ACCOUNT_KEY = "default_outgoing_account";
38 
39     private static final String CONFIGURE_CALL_ASSISTANT_PREF_KEY =
40             "wifi_calling_configure_call_assistant_preference";
41     private static final String CALL_ASSISTANT_CATEGORY_PREF_KEY =
42             "phone_accounts_call_assistant_settings_category_key";
43     private static final String SELECT_CALL_ASSISTANT_PREF_KEY =
44             "wifi_calling_call_assistant_preference";
45 
46     private static final String SIP_SETTINGS_CATEGORY_PREF_KEY =
47             "phone_accounts_sip_settings_category_key";
48     private static final String USE_SIP_PREF_KEY = "use_sip_calling_options_key";
49     private static final String SIP_RECEIVE_CALLS_PREF_KEY = "sip_receive_calls_key";
50 
51     private String LOG_TAG = PhoneAccountSettingsFragment.class.getSimpleName();
52 
53     private TelecomManager mTelecomManager;
54     private SubscriptionManager mSubscriptionManager;
55 
56     private PreferenceCategory mAccountList;
57 
58     private AccountSelectionPreference mDefaultOutgoingAccount;
59     private AccountSelectionPreference mSelectCallAssistant;
60     private Preference mConfigureCallAssistant;
61 
62     private ListPreference mUseSipCalling;
63     private CheckBoxPreference mSipReceiveCallsPreference;
64     private SipSharedPreferences mSipSharedPreferences;
65 
66     @Override
onCreate(Bundle icicle)67     public void onCreate(Bundle icicle) {
68         super.onCreate(icicle);
69 
70         mTelecomManager = TelecomManager.from(getActivity());
71         mSubscriptionManager = SubscriptionManager.from(getActivity());
72     }
73 
74     @Override
onResume()75     public void onResume() {
76         super.onResume();
77 
78         if (getPreferenceScreen() != null) {
79             getPreferenceScreen().removeAll();
80         }
81 
82         addPreferencesFromResource(R.xml.phone_account_settings);
83 
84         TelephonyManager telephonyManager =
85                 (TelephonyManager) getActivity().getSystemService(Context.TELEPHONY_SERVICE);
86         mAccountList = (PreferenceCategory) getPreferenceScreen().findPreference(
87                 ACCOUNTS_LIST_CATEGORY_KEY);
88         TtyModeListPreference ttyModeListPreference =
89                 (TtyModeListPreference) getPreferenceScreen().findPreference(
90                         getResources().getString(R.string.tty_mode_key));
91         if (telephonyManager.isMultiSimEnabled()) {
92             initAccountList();
93             ttyModeListPreference.init();
94         } else {
95             getPreferenceScreen().removePreference(mAccountList);
96             getPreferenceScreen().removePreference(ttyModeListPreference);
97         }
98 
99         mDefaultOutgoingAccount = (AccountSelectionPreference)
100                 getPreferenceScreen().findPreference(DEFAULT_OUTGOING_ACCOUNT_KEY);
101         if (mTelecomManager.hasMultipleCallCapableAccounts()) {
102             mDefaultOutgoingAccount.setListener(this);
103             updateDefaultOutgoingAccountsModel();
104         } else {
105             getPreferenceScreen().removePreference(mDefaultOutgoingAccount);
106         }
107 
108         List<PhoneAccountHandle> simCallManagers = mTelecomManager.getSimCallManagers();
109         PreferenceCategory callAssistantCategory = (PreferenceCategory)
110                 getPreferenceScreen().findPreference(CALL_ASSISTANT_CATEGORY_PREF_KEY);
111         if (simCallManagers.isEmpty()) {
112             getPreferenceScreen().removePreference(callAssistantCategory);
113         } else {
114             // Display a list of call assistants. Choosing an item from the list enables the
115             // corresponding call assistant.
116             mSelectCallAssistant = (AccountSelectionPreference)
117                     getPreferenceScreen().findPreference(SELECT_CALL_ASSISTANT_PREF_KEY);
118             mSelectCallAssistant.setListener(this);
119             mSelectCallAssistant.setDialogTitle(
120                     R.string.wifi_calling_select_call_assistant_summary);
121             updateCallAssistantModel();
122 
123             mConfigureCallAssistant =
124                     getPreferenceScreen().findPreference(CONFIGURE_CALL_ASSISTANT_PREF_KEY);
125             mConfigureCallAssistant.setOnPreferenceClickListener(this);
126             updateConfigureCallAssistant();
127         }
128 
129         if (SipUtil.isVoipSupported(getActivity())) {
130             mSipSharedPreferences = new SipSharedPreferences(getActivity());
131 
132             mUseSipCalling = (ListPreference)
133                     getPreferenceScreen().findPreference(USE_SIP_PREF_KEY);
134             mUseSipCalling.setEntries(!SipManager.isSipWifiOnly(getActivity())
135                     ? R.array.sip_call_options_wifi_only_entries
136                     : R.array.sip_call_options_entries);
137             mUseSipCalling.setOnPreferenceChangeListener(this);
138 
139             int optionsValueIndex =
140                     mUseSipCalling.findIndexOfValue(mSipSharedPreferences.getSipCallOption());
141             if (optionsValueIndex == -1) {
142                 // If the option is invalid (eg. deprecated value), default to SIP_ADDRESS_ONLY.
143                 mSipSharedPreferences.setSipCallOption(
144                         getResources().getString(R.string.sip_address_only));
145                 optionsValueIndex =
146                         mUseSipCalling.findIndexOfValue(mSipSharedPreferences.getSipCallOption());
147             }
148             mUseSipCalling.setValueIndex(optionsValueIndex);
149             mUseSipCalling.setSummary(mUseSipCalling.getEntry());
150 
151             mSipReceiveCallsPreference = (CheckBoxPreference)
152                     getPreferenceScreen().findPreference(SIP_RECEIVE_CALLS_PREF_KEY);
153             mSipReceiveCallsPreference.setEnabled(SipUtil.isPhoneIdle(getActivity()));
154             mSipReceiveCallsPreference.setChecked(
155                     mSipSharedPreferences.isReceivingCallsEnabled());
156             mSipReceiveCallsPreference.setOnPreferenceChangeListener(this);
157         } else {
158             getPreferenceScreen().removePreference(
159                     getPreferenceScreen().findPreference(SIP_SETTINGS_CATEGORY_PREF_KEY));
160         }
161     }
162 
163     /**
164      * Handles changes to the preferences.
165      *
166      * @param pref The preference changed.
167      * @param objValue The changed value.
168      * @return True if the preference change has been handled, and false otherwise.
169      */
170     @Override
onPreferenceChange(Preference pref, Object objValue)171     public boolean onPreferenceChange(Preference pref, Object objValue) {
172         if (pref == mUseSipCalling) {
173             String option = objValue.toString();
174             mSipSharedPreferences.setSipCallOption(option);
175             mUseSipCalling.setValueIndex(mUseSipCalling.findIndexOfValue(option));
176             mUseSipCalling.setSummary(mUseSipCalling.getEntry());
177             return true;
178         } else if (pref == mSipReceiveCallsPreference) {
179             final boolean isEnabled = !mSipReceiveCallsPreference.isChecked();
180             new Thread(new Runnable() {
181                 public void run() {
182                     handleSipReceiveCallsOption(isEnabled);
183                 }
184             }).start();
185             return true;
186         }
187         return false;
188     }
189 
190     @Override
onPreferenceClick(Preference pref)191     public boolean onPreferenceClick(Preference pref) {
192         if (pref == mConfigureCallAssistant) {
193             Intent intent = getConfigureCallAssistantIntent();
194             if (intent != null) {
195                 PhoneAccountHandle handle = mTelecomManager.getSimCallManager();
196                 UserHandle userHandle = handle.getUserHandle();
197                 try {
198                     if (userHandle != null) {
199                         getActivity().startActivityAsUser(intent, userHandle);
200                     } else {
201                         startActivity(intent);
202                     }
203                 } catch (ActivityNotFoundException e) {
204                     Log.d(LOG_TAG, "Could not resolve call assistant configure intent: " + intent);
205                 }
206             }
207             return true;
208         }
209         return false;
210     }
211 
212     /**
213      * Handles a phone account selection, namely when a call assistant has been selected.
214      *
215      * @param pref The account selection preference which triggered the account selected event.
216      * @param account The account selected.
217      * @return True if the account selection has been handled, and false otherwise.
218      */
219     @Override
onAccountSelected(AccountSelectionPreference pref, PhoneAccountHandle account)220     public boolean onAccountSelected(AccountSelectionPreference pref, PhoneAccountHandle account) {
221         if (pref == mDefaultOutgoingAccount) {
222             mTelecomManager.setUserSelectedOutgoingPhoneAccount(account);
223             return true;
224         } else if (pref == mSelectCallAssistant) {
225             mTelecomManager.setSimCallManager(account);
226             return true;
227         }
228         return false;
229     }
230 
231     /**
232      * Repopulate the dialog to pick up changes before showing.
233      *
234      * @param pref The account selection preference dialog being shown.
235      */
236     @Override
onAccountSelectionDialogShow(AccountSelectionPreference pref)237     public void onAccountSelectionDialogShow(AccountSelectionPreference pref) {
238         if (pref == mDefaultOutgoingAccount) {
239             updateDefaultOutgoingAccountsModel();
240         } else if (pref == mSelectCallAssistant) {
241             updateCallAssistantModel();
242             updateConfigureCallAssistant();
243         }
244     }
245 
246     /**
247      * Update the configure preference summary when the call assistant changes.
248      */
249     @Override
onAccountChanged(AccountSelectionPreference pref)250     public void onAccountChanged(AccountSelectionPreference pref) {
251         if (pref == mSelectCallAssistant) {
252             updateConfigureCallAssistant();
253         }
254     }
255 
handleSipReceiveCallsOption(boolean isEnabled)256     private synchronized void handleSipReceiveCallsOption(boolean isEnabled) {
257         Context context = getActivity();
258         if (context == null) {
259             // Return if the fragment is detached from parent activity before executed by thread.
260             return;
261         }
262 
263         mSipSharedPreferences.setReceivingCallsEnabled(isEnabled);
264 
265         SipUtil.useSipToReceiveIncomingCalls(context, isEnabled);
266 
267         // Restart all Sip services to ensure we reflect whether we are receiving calls.
268         SipAccountRegistry sipAccountRegistry = SipAccountRegistry.getInstance();
269         sipAccountRegistry.restartSipService(context);
270     }
271 
272     /**
273      * Queries the telcomm manager to update the default outgoing account selection preference
274      * with the list of outgoing accounts and the current default outgoing account.
275      */
updateDefaultOutgoingAccountsModel()276     private void updateDefaultOutgoingAccountsModel() {
277         mDefaultOutgoingAccount.setModel(
278                 mTelecomManager,
279                 mTelecomManager.getCallCapablePhoneAccounts(),
280                 mTelecomManager.getUserSelectedOutgoingPhoneAccount(),
281                 getString(R.string.phone_accounts_ask_every_time));
282     }
283 
284     /**
285      * Queries the telecomm manager to update the account selection preference with the list of
286      * call assistants, and the currently selected call assistant.
287      */
updateCallAssistantModel()288     public void updateCallAssistantModel() {
289         mSelectCallAssistant.setModel(
290                 mTelecomManager,
291                 mTelecomManager.getSimCallManagers(),
292                 mTelecomManager.getSimCallManager(),
293                 getString(R.string.wifi_calling_call_assistant_none));
294     }
295 
296     /**
297      * Shows or hides the "configure call assistant" preference.
298      */
updateConfigureCallAssistant()299     private void updateConfigureCallAssistant() {
300         Intent intent = getConfigureCallAssistantIntent();
301         boolean shouldShow = intent != null && !getActivity().getPackageManager()
302             .queryIntentActivities(intent, 0).isEmpty();
303 
304         PreferenceCategory callAssistantCategory = (PreferenceCategory)
305                 getPreferenceScreen().findPreference(CALL_ASSISTANT_CATEGORY_PREF_KEY);
306         if (shouldShow) {
307             callAssistantCategory.addPreference(mConfigureCallAssistant);
308         } else {
309             callAssistantCategory.removePreference(mConfigureCallAssistant);
310         }
311     }
312 
initAccountList()313     private void initAccountList() {
314         List<SubscriptionInfo> sil = mSubscriptionManager.getActiveSubscriptionInfoList();
315         if (sil == null) {
316             return;
317         }
318         for (SubscriptionInfo subscription : sil) {
319             CharSequence label = subscription.getDisplayName();
320             Intent intent = new Intent(TelecomManager.ACTION_SHOW_CALL_SETTINGS);
321             intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
322             SubscriptionInfoHelper.addExtrasToIntent(intent, subscription);
323 
324             Preference accountPreference = new Preference(getActivity());
325             accountPreference.setTitle(label);
326             accountPreference.setIntent(intent);
327             mAccountList.addPreference(accountPreference);
328         }
329     }
330 
getConfigureCallAssistantIntent()331     private Intent getConfigureCallAssistantIntent() {
332         PhoneAccountHandle handle = mTelecomManager.getSimCallManager();
333         if (handle != null) {
334             String packageName = handle.getComponentName().getPackageName();
335             if (packageName != null) {
336                 return new Intent(TelecomManager.ACTION_CONNECTION_SERVICE_CONFIGURE)
337                         .addCategory(Intent.CATEGORY_DEFAULT)
338                         .setPackage(packageName);
339             }
340         }
341         return null;
342     }
343 }
344