1 /*
2  * Copyright (C) 2008 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.phone;
18 
19 import android.app.ActionBar;
20 import android.app.Activity;
21 import android.app.ActivityOptions;
22 import android.app.AlertDialog;
23 import android.app.Dialog;
24 import android.content.ContentResolver;
25 import android.content.Context;
26 import android.content.DialogInterface;
27 import android.content.Intent;
28 import android.content.pm.PackageManager;
29 import android.content.pm.ResolveInfo;
30 import android.os.Bundle;
31 import android.os.PersistableBundle;
32 import android.os.UserHandle;
33 import android.os.UserManager;
34 import android.preference.CheckBoxPreference;
35 import android.preference.ListPreference;
36 import android.preference.Preference;
37 import android.preference.PreferenceActivity;
38 import android.preference.PreferenceScreen;
39 import android.provider.Settings;
40 import android.telecom.PhoneAccountHandle;
41 import android.telecom.TelecomManager;
42 import android.telephony.CarrierConfigManager;
43 import android.telephony.TelephonyManager;
44 import android.text.TextUtils;
45 import android.util.Log;
46 import android.view.MenuItem;
47 import android.widget.Toast;
48 
49 import com.android.ims.ImsConfig;
50 import com.android.ims.ImsManager;
51 import com.android.internal.telephony.CallForwardInfo;
52 import com.android.internal.telephony.Phone;
53 import com.android.internal.telephony.PhoneConstants;
54 import com.android.phone.common.util.SettingsUtil;
55 import com.android.phone.settings.AccountSelectionPreference;
56 import com.android.phone.settings.PhoneAccountSettingsFragment;
57 import com.android.phone.settings.VoicemailSettingsActivity;
58 import com.android.phone.settings.fdn.FdnSetting;
59 import com.android.services.telephony.sip.SipUtil;
60 
61 import java.lang.String;
62 import java.util.ArrayList;
63 import java.util.List;
64 
65 /**
66  * Top level "Call settings" UI; see res/xml/call_feature_setting.xml
67  *
68  * This preference screen is the root of the "Call settings" hierarchy available from the Phone
69  * app; the settings here let you control various features related to phone calls (including
70  * voicemail settings, the "Respond via SMS" feature, and others.)  It's used only on
71  * voice-capable phone devices.
72  *
73  * Note that this activity is part of the package com.android.phone, even
74  * though you reach it from the "Phone" app (i.e. DialtactsActivity) which
75  * is from the package com.android.contacts.
76  *
77  * For the "Mobile network settings" screen under the main Settings app,
78  * See {@link MobileNetworkSettings}.
79  *
80  * @see com.android.phone.MobileNetworkSettings
81  */
82 public class CallFeaturesSetting extends PreferenceActivity
83         implements Preference.OnPreferenceChangeListener {
84     private static final String LOG_TAG = "CallFeaturesSetting";
85     private static final boolean DBG = (PhoneGlobals.DBG_LEVEL >= 2);
86 
87     // String keys for preference lookup
88     // TODO: Naming these "BUTTON_*" is confusing since they're not actually buttons(!)
89     // TODO: Consider moving these strings to strings.xml, so that they are not duplicated here and
90     // in the layout files. These strings need to be treated carefully; if the setting is
91     // persistent, they are used as the key to store shared preferences and the name should not be
92     // changed unless the settings are also migrated.
93     private static final String VOICEMAIL_SETTING_SCREEN_PREF_KEY = "button_voicemail_category_key";
94     private static final String BUTTON_FDN_KEY   = "button_fdn_key";
95     private static final String BUTTON_RETRY_KEY       = "button_auto_retry_key";
96     private static final String BUTTON_GSM_UMTS_OPTIONS = "button_gsm_more_expand_key";
97     private static final String BUTTON_CDMA_OPTIONS = "button_cdma_more_expand_key";
98 
99     private static final String PHONE_ACCOUNT_SETTINGS_KEY =
100             "phone_account_settings_preference_screen";
101 
102     private static final String ENABLE_VIDEO_CALLING_KEY = "button_enable_video_calling";
103 
104     private Phone mPhone;
105     private SubscriptionInfoHelper mSubscriptionInfoHelper;
106     private TelecomManager mTelecomManager;
107 
108     private CheckBoxPreference mButtonAutoRetry;
109     private PreferenceScreen mVoicemailSettingsScreen;
110     private CheckBoxPreference mEnableVideoCalling;
111 
112     /*
113      * Click Listeners, handle click based on objects attached to UI.
114      */
115 
116     // Click listener for all toggle events
117     @Override
onPreferenceTreeClick(PreferenceScreen preferenceScreen, Preference preference)118     public boolean onPreferenceTreeClick(PreferenceScreen preferenceScreen, Preference preference) {
119         if (preference == mButtonAutoRetry) {
120             android.provider.Settings.Global.putInt(mPhone.getContext().getContentResolver(),
121                     android.provider.Settings.Global.CALL_AUTO_RETRY,
122                     mButtonAutoRetry.isChecked() ? 1 : 0);
123             return true;
124         }
125         return false;
126     }
127 
128     /**
129      * Implemented to support onPreferenceChangeListener to look for preference
130      * changes.
131      *
132      * @param preference is the preference to be changed
133      * @param objValue should be the value of the selection, NOT its localized
134      * display value.
135      */
136     @Override
onPreferenceChange(Preference preference, Object objValue)137     public boolean onPreferenceChange(Preference preference, Object objValue) {
138         if (DBG) log("onPreferenceChange: \"" + preference + "\" changed to \"" + objValue + "\"");
139 
140         if (preference == mEnableVideoCalling) {
141             if (ImsManager.isEnhanced4gLteModeSettingEnabledByUser(mPhone.getContext())) {
142                 PhoneGlobals.getInstance().phoneMgr.enableVideoCalling((boolean) objValue);
143             } else {
144                 AlertDialog.Builder builder = new AlertDialog.Builder(this);
145                 DialogInterface.OnClickListener networkSettingsClickListener =
146                         new Dialog.OnClickListener() {
147                             @Override
148                             public void onClick(DialogInterface dialog, int which) {
149                                 startActivity(new Intent(mPhone.getContext(),
150                                         com.android.phone.MobileNetworkSettings.class));
151                             }
152                         };
153                 builder.setMessage(getResources().getString(
154                                 R.string.enable_video_calling_dialog_msg))
155                         .setNeutralButton(getResources().getString(
156                                 R.string.enable_video_calling_dialog_settings),
157                                 networkSettingsClickListener)
158                         .setPositiveButton(android.R.string.ok, null)
159                         .show();
160                 return false;
161             }
162         }
163 
164         // Always let the preference setting proceed.
165         return true;
166     }
167 
168     @Override
onCreate(Bundle icicle)169     protected void onCreate(Bundle icicle) {
170         super.onCreate(icicle);
171         if (DBG) log("onCreate: Intent is " + getIntent());
172 
173         // Make sure we are running as an admin user.
174         if (!UserManager.get(this).isAdminUser()) {
175             Toast.makeText(this, R.string.call_settings_admin_user_only,
176                     Toast.LENGTH_SHORT).show();
177             finish();
178             return;
179         }
180 
181         mSubscriptionInfoHelper = new SubscriptionInfoHelper(this, getIntent());
182         mSubscriptionInfoHelper.setActionBarTitle(
183                 getActionBar(), getResources(), R.string.call_settings_with_label);
184         mPhone = mSubscriptionInfoHelper.getPhone();
185         mTelecomManager = TelecomManager.from(this);
186     }
187 
188     @Override
onResume()189     protected void onResume() {
190         super.onResume();
191 
192         PreferenceScreen preferenceScreen = getPreferenceScreen();
193         if (preferenceScreen != null) {
194             preferenceScreen.removeAll();
195         }
196 
197         addPreferencesFromResource(R.xml.call_feature_setting);
198 
199         TelephonyManager telephonyManager =
200                 (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE);
201 
202         Preference phoneAccountSettingsPreference = findPreference(PHONE_ACCOUNT_SETTINGS_KEY);
203         if (telephonyManager.isMultiSimEnabled() || !SipUtil.isVoipSupported(mPhone.getContext())) {
204             getPreferenceScreen().removePreference(phoneAccountSettingsPreference);
205         }
206 
207         PreferenceScreen prefSet = getPreferenceScreen();
208         mVoicemailSettingsScreen =
209                 (PreferenceScreen) findPreference(VOICEMAIL_SETTING_SCREEN_PREF_KEY);
210         mVoicemailSettingsScreen.setIntent(mSubscriptionInfoHelper.getIntent(
211                 VoicemailSettingsActivity.class));
212 
213         mButtonAutoRetry = (CheckBoxPreference) findPreference(BUTTON_RETRY_KEY);
214 
215         mEnableVideoCalling = (CheckBoxPreference) findPreference(ENABLE_VIDEO_CALLING_KEY);
216 
217         PersistableBundle carrierConfig =
218                 PhoneGlobals.getInstance().getCarrierConfigForSubId(mPhone.getSubId());
219 
220         if (carrierConfig.getBoolean(CarrierConfigManager.KEY_AUTO_RETRY_ENABLED_BOOL)) {
221             mButtonAutoRetry.setOnPreferenceChangeListener(this);
222             int autoretry = Settings.Global.getInt(
223                     getContentResolver(), Settings.Global.CALL_AUTO_RETRY, 0);
224             mButtonAutoRetry.setChecked(autoretry != 0);
225         } else {
226             prefSet.removePreference(mButtonAutoRetry);
227             mButtonAutoRetry = null;
228         }
229 
230         Preference cdmaOptions = prefSet.findPreference(BUTTON_CDMA_OPTIONS);
231         Preference gsmOptions = prefSet.findPreference(BUTTON_GSM_UMTS_OPTIONS);
232         if (carrierConfig.getBoolean(CarrierConfigManager.KEY_WORLD_PHONE_BOOL)) {
233             cdmaOptions.setIntent(mSubscriptionInfoHelper.getIntent(CdmaCallOptions.class));
234             gsmOptions.setIntent(mSubscriptionInfoHelper.getIntent(GsmUmtsCallOptions.class));
235         } else {
236             prefSet.removePreference(cdmaOptions);
237             prefSet.removePreference(gsmOptions);
238 
239             int phoneType = mPhone.getPhoneType();
240             Preference fdnButton = prefSet.findPreference(BUTTON_FDN_KEY);
241             if (carrierConfig.getBoolean(CarrierConfigManager.KEY_HIDE_CARRIER_NETWORK_SETTINGS_BOOL)) {
242                 prefSet.removePreference(fdnButton);
243             } else {
244                 if (phoneType == PhoneConstants.PHONE_TYPE_CDMA) {
245                     prefSet.removePreference(fdnButton);
246 
247                     if (!carrierConfig.getBoolean(
248                             CarrierConfigManager.KEY_VOICE_PRIVACY_DISABLE_UI_BOOL)) {
249                         addPreferencesFromResource(R.xml.cdma_call_privacy);
250                     }
251                 } else if (phoneType == PhoneConstants.PHONE_TYPE_GSM) {
252                     fdnButton.setIntent(mSubscriptionInfoHelper.getIntent(FdnSetting.class));
253 
254                     if (carrierConfig.getBoolean(
255                             CarrierConfigManager.KEY_ADDITIONAL_CALL_SETTING_BOOL)) {
256                         addPreferencesFromResource(R.xml.gsm_umts_call_options);
257                         GsmUmtsCallOptions.init(prefSet, mSubscriptionInfoHelper);
258                     }
259                 } else {
260                     throw new IllegalStateException("Unexpected phone type: " + phoneType);
261                 }
262             }
263         }
264 
265         if (ImsManager.isVtEnabledByPlatform(mPhone.getContext())) {
266             boolean currentValue =
267                     ImsManager.isEnhanced4gLteModeSettingEnabledByUser(mPhone.getContext())
268                     ? PhoneGlobals.getInstance().phoneMgr.isVideoCallingEnabled(
269                             getOpPackageName()) : false;
270             mEnableVideoCalling.setChecked(currentValue);
271             mEnableVideoCalling.setOnPreferenceChangeListener(this);
272         } else {
273             prefSet.removePreference(mEnableVideoCalling);
274         }
275 
276         if (ImsManager.isVolteEnabledByPlatform(this) &&
277                 !carrierConfig.getBoolean(
278                         CarrierConfigManager.KEY_CARRIER_VOLTE_TTY_SUPPORTED_BOOL)) {
279             TelephonyManager tm = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE);
280             /* tm.listen(mPhoneStateListener, PhoneStateListener.LISTEN_CALL_STATE); */
281         }
282 
283         Preference wifiCallingSettings = findPreference(
284                 getResources().getString(R.string.wifi_calling_settings_key));
285 
286         final PhoneAccountHandle simCallManager = mTelecomManager.getSimCallManager();
287         if (simCallManager != null) {
288             Intent intent = PhoneAccountSettingsFragment.buildPhoneAccountConfigureIntent(
289                     this, simCallManager);
290             if (intent != null) {
291                 PackageManager pm = mPhone.getContext().getPackageManager();
292                 List<ResolveInfo> resolutions = pm.queryIntentActivities(intent, 0);
293                 if (!resolutions.isEmpty()) {
294                     wifiCallingSettings.setTitle(resolutions.get(0).loadLabel(pm));
295                     wifiCallingSettings.setSummary(null);
296                     wifiCallingSettings.setIntent(intent);
297                 } else {
298                     prefSet.removePreference(wifiCallingSettings);
299                 }
300             } else {
301                 prefSet.removePreference(wifiCallingSettings);
302             }
303         } else if (!ImsManager.isWfcEnabledByPlatform(mPhone.getContext())) {
304             prefSet.removePreference(wifiCallingSettings);
305         } else {
306             int resId = com.android.internal.R.string.wifi_calling_off_summary;
307             if (ImsManager.isWfcEnabledByUser(mPhone.getContext())) {
308                 int wfcMode = ImsManager.getWfcMode(mPhone.getContext());
309                 switch (wfcMode) {
310                     case ImsConfig.WfcModeFeatureValueConstants.WIFI_ONLY:
311                         resId = com.android.internal.R.string.wfc_mode_wifi_only_summary;
312                         break;
313                     case ImsConfig.WfcModeFeatureValueConstants.CELLULAR_PREFERRED:
314                         resId = com.android.internal.R.string.wfc_mode_cellular_preferred_summary;
315                         break;
316                     case ImsConfig.WfcModeFeatureValueConstants.WIFI_PREFERRED:
317                         resId = com.android.internal.R.string.wfc_mode_wifi_preferred_summary;
318                         break;
319                     default:
320                         if (DBG) log("Unexpected WFC mode value: " + wfcMode);
321                 }
322             }
323             wifiCallingSettings.setSummary(resId);
324         }
325     }
326 
327     @Override
onNewIntent(Intent newIntent)328     protected void onNewIntent(Intent newIntent) {
329         setIntent(newIntent);
330 
331         mSubscriptionInfoHelper = new SubscriptionInfoHelper(this, getIntent());
332         mSubscriptionInfoHelper.setActionBarTitle(
333                 getActionBar(), getResources(), R.string.call_settings_with_label);
334         mPhone = mSubscriptionInfoHelper.getPhone();
335     }
336 
log(String msg)337     private static void log(String msg) {
338         Log.d(LOG_TAG, msg);
339     }
340 
341     @Override
onOptionsItemSelected(MenuItem item)342     public boolean onOptionsItemSelected(MenuItem item) {
343         final int itemId = item.getItemId();
344         if (itemId == android.R.id.home) {  // See ActionBar#setDisplayHomeAsUpEnabled()
345             onBackPressed();
346             return true;
347         }
348         return super.onOptionsItemSelected(item);
349     }
350 
351     /**
352      * Finish current Activity and go up to the top level Settings ({@link CallFeaturesSetting}).
353      * This is useful for implementing "HomeAsUp" capability for second-level Settings.
354      */
goUpToTopLevelSetting( Activity activity, SubscriptionInfoHelper subscriptionInfoHelper)355     public static void goUpToTopLevelSetting(
356             Activity activity, SubscriptionInfoHelper subscriptionInfoHelper) {
357         Intent intent = subscriptionInfoHelper.getIntent(CallFeaturesSetting.class);
358         intent.setAction(Intent.ACTION_MAIN);
359         intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
360         activity.startActivity(intent);
361         activity.finish();
362     }
363 }
364