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