1 /* 2 * Copyright (C) 2007-2008 Esmertec AG. 3 * Copyright (C) 2007-2008 The Android Open Source Project 4 * 5 * Licensed under the Apache License, Version 2.0 (the "License"); 6 * you may not use this file except in compliance with the License. 7 * You may obtain a copy of the License at 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 */ 17 18 package com.android.mms.ui; 19 20 import android.app.ActionBar; 21 import android.app.AlertDialog; 22 import android.app.Dialog; 23 import android.content.BroadcastReceiver; 24 import android.content.Context; 25 import android.content.DialogInterface; 26 import android.content.Intent; 27 import android.content.IntentFilter; 28 import android.content.SharedPreferences; 29 import android.media.Ringtone; 30 import android.media.RingtoneManager; 31 import android.net.Uri; 32 import android.os.Bundle; 33 import android.os.Vibrator; 34 import android.preference.CheckBoxPreference; 35 import android.preference.Preference; 36 import android.preference.Preference.OnPreferenceChangeListener; 37 import android.preference.PreferenceActivity; 38 import android.preference.PreferenceCategory; 39 import android.preference.PreferenceManager; 40 import android.preference.PreferenceScreen; 41 import android.preference.RingtonePreference; 42 import android.provider.SearchRecentSuggestions; 43 import android.text.TextUtils; 44 import android.view.Menu; 45 import android.view.MenuItem; 46 47 import com.android.internal.telephony.IccCardConstants; 48 import com.android.internal.telephony.TelephonyIntents; 49 50 import com.android.mms.MmsApp; 51 import com.android.mms.MmsConfig; 52 import com.android.mms.R; 53 import com.android.mms.transaction.TransactionService; 54 import com.android.mms.util.Recycler; 55 56 /** 57 * With this activity, users can set preferences for MMS and SMS and 58 * can access and manipulate SMS messages stored on the SIM. 59 */ 60 public class MessagingPreferenceActivity extends PreferenceActivity 61 implements OnPreferenceChangeListener { 62 // Symbolic names for the keys used for preference lookup 63 public static final String MMS_DELIVERY_REPORT_MODE = "pref_key_mms_delivery_reports"; 64 public static final String EXPIRY_TIME = "pref_key_mms_expiry"; 65 public static final String PRIORITY = "pref_key_mms_priority"; 66 public static final String READ_REPORT_MODE = "pref_key_mms_read_reports"; 67 public static final String SMS_DELIVERY_REPORT_MODE = "pref_key_sms_delivery_reports"; 68 public static final String NOTIFICATION_ENABLED = "pref_key_enable_notifications"; 69 public static final String NOTIFICATION_VIBRATE = "pref_key_vibrate"; 70 public static final String NOTIFICATION_VIBRATE_WHEN= "pref_key_vibrateWhen"; 71 public static final String NOTIFICATION_RINGTONE = "pref_key_ringtone"; 72 public static final String AUTO_RETRIEVAL = "pref_key_mms_auto_retrieval"; 73 public static final String RETRIEVAL_DURING_ROAMING = "pref_key_mms_retrieval_during_roaming"; 74 public static final String AUTO_DELETE = "pref_key_auto_delete"; 75 public static final String GROUP_MMS_MODE = "pref_key_mms_group_mms"; 76 77 // Menu entries 78 private static final int MENU_RESTORE_DEFAULTS = 1; 79 80 // Preferences for enabling and disabling SMS 81 private Preference mSmsDisabledPref; 82 private Preference mSmsEnabledPref; 83 84 private PreferenceCategory mStoragePrefCategory; 85 private PreferenceCategory mSmsPrefCategory; 86 private PreferenceCategory mMmsPrefCategory; 87 private PreferenceCategory mNotificationPrefCategory; 88 89 private Preference mSmsLimitPref; 90 private Preference mSmsDeliveryReportPref; 91 private Preference mMmsLimitPref; 92 private Preference mMmsDeliveryReportPref; 93 private Preference mMmsGroupMmsPref; 94 private Preference mMmsReadReportPref; 95 private Preference mManageSimPref; 96 private Preference mClearHistoryPref; 97 private CheckBoxPreference mVibratePref; 98 private CheckBoxPreference mEnableNotificationsPref; 99 private CheckBoxPreference mMmsAutoRetrievialPref; 100 private RingtonePreference mRingtonePref; 101 private Recycler mSmsRecycler; 102 private Recycler mMmsRecycler; 103 private static final int CONFIRM_CLEAR_SEARCH_HISTORY_DIALOG = 3; 104 105 // Whether or not we are currently enabled for SMS. This field is updated in onResume to make 106 // sure we notice if the user has changed the default SMS app. 107 private boolean mIsSmsEnabled; 108 109 private BroadcastReceiver mReceiver = new BroadcastReceiver() { 110 public void onReceive(Context context, Intent intent) { 111 final String action = intent.getAction(); 112 if (TelephonyIntents.ACTION_SIM_STATE_CHANGED.equals(action)) { 113 String stateExtra = intent.getStringExtra(IccCardConstants.INTENT_KEY_ICC_STATE); 114 if (stateExtra != null 115 && IccCardConstants.INTENT_VALUE_ICC_ABSENT.equals(stateExtra)) { 116 PreferenceCategory smsCategory = 117 (PreferenceCategory)findPreference("pref_key_sms_settings"); 118 if (smsCategory != null) { 119 smsCategory.removePreference(mManageSimPref); 120 } 121 } 122 } 123 } 124 }; 125 126 @Override onCreate(Bundle icicle)127 protected void onCreate(Bundle icicle) { 128 super.onCreate(icicle); 129 130 loadPrefs(); 131 132 ActionBar actionBar = getActionBar(); 133 actionBar.setDisplayHomeAsUpEnabled(true); 134 } 135 136 @Override onResume()137 protected void onResume() { 138 super.onResume(); 139 boolean isSmsEnabled = MmsConfig.isSmsEnabled(this); 140 if (isSmsEnabled != mIsSmsEnabled) { 141 mIsSmsEnabled = isSmsEnabled; 142 invalidateOptionsMenu(); 143 } 144 145 // Since the enabled notifications pref can be changed outside of this activity, 146 // we have to reload it whenever we resume. 147 setEnabledNotificationsPref(); 148 registerListeners(); 149 updateSmsEnabledState(); 150 } 151 updateSmsEnabledState()152 private void updateSmsEnabledState() { 153 // Show the right pref (SMS Disabled or SMS Enabled) 154 PreferenceScreen prefRoot = (PreferenceScreen)findPreference("pref_key_root"); 155 if (!mIsSmsEnabled) { 156 prefRoot.addPreference(mSmsDisabledPref); 157 prefRoot.removePreference(mSmsEnabledPref); 158 } else { 159 prefRoot.removePreference(mSmsDisabledPref); 160 prefRoot.addPreference(mSmsEnabledPref); 161 } 162 163 // Enable or Disable the settings as appropriate 164 mStoragePrefCategory.setEnabled(mIsSmsEnabled); 165 mSmsPrefCategory.setEnabled(mIsSmsEnabled); 166 mMmsPrefCategory.setEnabled(mIsSmsEnabled); 167 mNotificationPrefCategory.setEnabled(mIsSmsEnabled); 168 } 169 170 @Override onPause()171 protected void onPause() { 172 super.onPause(); 173 unregisterReceiver(mReceiver); 174 } 175 loadPrefs()176 private void loadPrefs() { 177 addPreferencesFromResource(R.xml.preferences); 178 179 mSmsDisabledPref = findPreference("pref_key_sms_disabled"); 180 mSmsEnabledPref = findPreference("pref_key_sms_enabled"); 181 182 mStoragePrefCategory = (PreferenceCategory)findPreference("pref_key_storage_settings"); 183 mSmsPrefCategory = (PreferenceCategory)findPreference("pref_key_sms_settings"); 184 mMmsPrefCategory = (PreferenceCategory)findPreference("pref_key_mms_settings"); 185 mNotificationPrefCategory = 186 (PreferenceCategory)findPreference("pref_key_notification_settings"); 187 188 mManageSimPref = findPreference("pref_key_manage_sim_messages"); 189 mSmsLimitPref = findPreference("pref_key_sms_delete_limit"); 190 mSmsDeliveryReportPref = findPreference("pref_key_sms_delivery_reports"); 191 mMmsDeliveryReportPref = findPreference("pref_key_mms_delivery_reports"); 192 mMmsGroupMmsPref = findPreference("pref_key_mms_group_mms"); 193 mMmsReadReportPref = findPreference("pref_key_mms_read_reports"); 194 mMmsLimitPref = findPreference("pref_key_mms_delete_limit"); 195 mClearHistoryPref = findPreference("pref_key_mms_clear_history"); 196 mEnableNotificationsPref = (CheckBoxPreference) findPreference(NOTIFICATION_ENABLED); 197 mMmsAutoRetrievialPref = (CheckBoxPreference) findPreference(AUTO_RETRIEVAL); 198 mVibratePref = (CheckBoxPreference) findPreference(NOTIFICATION_VIBRATE); 199 Vibrator vibrator = (Vibrator) getSystemService(Context.VIBRATOR_SERVICE); 200 if (mVibratePref != null && (vibrator == null || !vibrator.hasVibrator())) { 201 mNotificationPrefCategory.removePreference(mVibratePref); 202 mVibratePref = null; 203 } 204 mRingtonePref = (RingtonePreference) findPreference(NOTIFICATION_RINGTONE); 205 206 setMessagePreferences(); 207 } 208 restoreDefaultPreferences()209 private void restoreDefaultPreferences() { 210 PreferenceManager.getDefaultSharedPreferences(this).edit().clear().apply(); 211 setPreferenceScreen(null); 212 loadPrefs(); 213 updateSmsEnabledState(); 214 215 // NOTE: After restoring preferences, the auto delete function (i.e. message recycler) 216 // will be turned off by default. However, we really want the default to be turned on. 217 // Because all the prefs are cleared, that'll cause: 218 // ConversationList.runOneTimeStorageLimitCheckForLegacyMessages to get executed the 219 // next time the user runs the Messaging app and it will either turn on the setting 220 // by default, or if the user is over the limits, encourage them to turn on the setting 221 // manually. 222 } 223 setMessagePreferences()224 private void setMessagePreferences() { 225 if (!MmsApp.getApplication().getTelephonyManager().hasIccCard()) { 226 // No SIM card, remove the SIM-related prefs 227 mSmsPrefCategory.removePreference(mManageSimPref); 228 } 229 230 if (!MmsConfig.getSMSDeliveryReportsEnabled()) { 231 mSmsPrefCategory.removePreference(mSmsDeliveryReportPref); 232 if (!MmsApp.getApplication().getTelephonyManager().hasIccCard()) { 233 getPreferenceScreen().removePreference(mSmsPrefCategory); 234 } 235 } 236 237 if (!MmsConfig.getMmsEnabled()) { 238 // No Mms, remove all the mms-related preferences 239 getPreferenceScreen().removePreference(mMmsPrefCategory); 240 241 mStoragePrefCategory.removePreference(findPreference("pref_key_mms_delete_limit")); 242 } else { 243 if (!MmsConfig.getMMSDeliveryReportsEnabled()) { 244 mMmsPrefCategory.removePreference(mMmsDeliveryReportPref); 245 } 246 if (!MmsConfig.getMMSReadReportsEnabled()) { 247 mMmsPrefCategory.removePreference(mMmsReadReportPref); 248 } 249 // If the phone's SIM doesn't know it's own number, disable group mms. 250 if (!MmsConfig.getGroupMmsEnabled() || 251 TextUtils.isEmpty(MessageUtils.getLocalNumber())) { 252 mMmsPrefCategory.removePreference(mMmsGroupMmsPref); 253 } 254 } 255 256 setEnabledNotificationsPref(); 257 258 // If needed, migrate vibration setting from the previous tri-state setting stored in 259 // NOTIFICATION_VIBRATE_WHEN to the boolean setting stored in NOTIFICATION_VIBRATE. 260 SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(this); 261 if (mVibratePref != null && sharedPreferences.contains(NOTIFICATION_VIBRATE_WHEN)) { 262 String vibrateWhen = sharedPreferences. 263 getString(MessagingPreferenceActivity.NOTIFICATION_VIBRATE_WHEN, null); 264 boolean vibrate = "always".equals(vibrateWhen); 265 SharedPreferences.Editor prefsEditor = sharedPreferences.edit(); 266 prefsEditor.putBoolean(NOTIFICATION_VIBRATE, vibrate); 267 prefsEditor.remove(NOTIFICATION_VIBRATE_WHEN); // remove obsolete setting 268 prefsEditor.apply(); 269 mVibratePref.setChecked(vibrate); 270 } 271 272 mSmsRecycler = Recycler.getSmsRecycler(); 273 mMmsRecycler = Recycler.getMmsRecycler(); 274 275 // Fix up the recycler's summary with the correct values 276 setSmsDisplayLimit(); 277 setMmsDisplayLimit(); 278 279 String soundValue = sharedPreferences.getString(NOTIFICATION_RINGTONE, null); 280 setRingtoneSummary(soundValue); 281 } 282 setRingtoneSummary(String soundValue)283 private void setRingtoneSummary(String soundValue) { 284 Uri soundUri = TextUtils.isEmpty(soundValue) ? null : Uri.parse(soundValue); 285 Ringtone tone = soundUri != null ? RingtoneManager.getRingtone(this, soundUri) : null; 286 mRingtonePref.setSummary(tone != null ? tone.getTitle(this) 287 : getResources().getString(R.string.silent_ringtone)); 288 } 289 setEnabledNotificationsPref()290 private void setEnabledNotificationsPref() { 291 // The "enable notifications" setting is really stored in our own prefs. Read the 292 // current value and set the checkbox to match. 293 mEnableNotificationsPref.setChecked(getNotificationEnabled(this)); 294 } 295 setSmsDisplayLimit()296 private void setSmsDisplayLimit() { 297 mSmsLimitPref.setSummary( 298 getString(R.string.pref_summary_delete_limit, 299 mSmsRecycler.getMessageLimit(this))); 300 } 301 setMmsDisplayLimit()302 private void setMmsDisplayLimit() { 303 mMmsLimitPref.setSummary( 304 getString(R.string.pref_summary_delete_limit, 305 mMmsRecycler.getMessageLimit(this))); 306 } 307 onCreateOptionsMenu(Menu menu)308 public boolean onCreateOptionsMenu(Menu menu) { 309 super.onCreateOptionsMenu(menu); 310 menu.clear(); 311 if (mIsSmsEnabled) { 312 menu.add(0, MENU_RESTORE_DEFAULTS, 0, R.string.restore_default); 313 } 314 return true; 315 } 316 317 @Override onOptionsItemSelected(MenuItem item)318 public boolean onOptionsItemSelected(MenuItem item) { 319 switch (item.getItemId()) { 320 case MENU_RESTORE_DEFAULTS: 321 restoreDefaultPreferences(); 322 return true; 323 324 case android.R.id.home: 325 // The user clicked on the Messaging icon in the action bar. Take them back from 326 // wherever they came from 327 finish(); 328 return true; 329 } 330 return false; 331 } 332 333 @Override onPreferenceTreeClick(PreferenceScreen preferenceScreen, Preference preference)334 public boolean onPreferenceTreeClick(PreferenceScreen preferenceScreen, 335 Preference preference) { 336 if (preference == mSmsLimitPref) { 337 new NumberPickerDialog(this, 338 mSmsLimitListener, 339 mSmsRecycler.getMessageLimit(this), 340 mSmsRecycler.getMessageMinLimit(), 341 mSmsRecycler.getMessageMaxLimit(), 342 R.string.pref_title_sms_delete).show(); 343 } else if (preference == mMmsLimitPref) { 344 new NumberPickerDialog(this, 345 mMmsLimitListener, 346 mMmsRecycler.getMessageLimit(this), 347 mMmsRecycler.getMessageMinLimit(), 348 mMmsRecycler.getMessageMaxLimit(), 349 R.string.pref_title_mms_delete).show(); 350 } else if (preference == mManageSimPref) { 351 startActivity(new Intent(this, ManageSimMessages.class)); 352 } else if (preference == mClearHistoryPref) { 353 showDialog(CONFIRM_CLEAR_SEARCH_HISTORY_DIALOG); 354 return true; 355 } else if (preference == mEnableNotificationsPref) { 356 // Update the actual "enable notifications" value that is stored in secure settings. 357 enableNotifications(mEnableNotificationsPref.isChecked(), this); 358 } else if (preference == mMmsAutoRetrievialPref) { 359 if (mMmsAutoRetrievialPref.isChecked()) { 360 startMmsDownload(); 361 } 362 } 363 364 return super.onPreferenceTreeClick(preferenceScreen, preference); 365 } 366 367 /** 368 * Trigger the TransactionService to download any outstanding messages. 369 */ startMmsDownload()370 private void startMmsDownload() { 371 startService(new Intent(TransactionService.ACTION_ENABLE_AUTO_RETRIEVE, null, this, 372 TransactionService.class)); 373 } 374 375 NumberPickerDialog.OnNumberSetListener mSmsLimitListener = 376 new NumberPickerDialog.OnNumberSetListener() { 377 public void onNumberSet(int limit) { 378 mSmsRecycler.setMessageLimit(MessagingPreferenceActivity.this, limit); 379 setSmsDisplayLimit(); 380 } 381 }; 382 383 NumberPickerDialog.OnNumberSetListener mMmsLimitListener = 384 new NumberPickerDialog.OnNumberSetListener() { 385 public void onNumberSet(int limit) { 386 mMmsRecycler.setMessageLimit(MessagingPreferenceActivity.this, limit); 387 setMmsDisplayLimit(); 388 } 389 }; 390 391 @Override onCreateDialog(int id)392 protected Dialog onCreateDialog(int id) { 393 switch (id) { 394 case CONFIRM_CLEAR_SEARCH_HISTORY_DIALOG: 395 return new AlertDialog.Builder(MessagingPreferenceActivity.this) 396 .setTitle(R.string.confirm_clear_search_title) 397 .setMessage(R.string.confirm_clear_search_text) 398 .setPositiveButton(android.R.string.ok, new AlertDialog.OnClickListener() { 399 public void onClick(DialogInterface dialog, int which) { 400 SearchRecentSuggestions recent = 401 ((MmsApp)getApplication()).getRecentSuggestions(); 402 if (recent != null) { 403 recent.clearHistory(); 404 } 405 dialog.dismiss(); 406 } 407 }) 408 .setNegativeButton(android.R.string.cancel, null) 409 .setIconAttribute(android.R.attr.alertDialogIcon) 410 .create(); 411 } 412 return super.onCreateDialog(id); 413 } 414 415 public static boolean getNotificationEnabled(Context context) { 416 SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context); 417 boolean notificationsEnabled = 418 prefs.getBoolean(MessagingPreferenceActivity.NOTIFICATION_ENABLED, true); 419 return notificationsEnabled; 420 } 421 422 public static void enableNotifications(boolean enabled, Context context) { 423 // Store the value of notifications in SharedPreferences 424 SharedPreferences.Editor editor = 425 PreferenceManager.getDefaultSharedPreferences(context).edit(); 426 427 editor.putBoolean(MessagingPreferenceActivity.NOTIFICATION_ENABLED, enabled); 428 429 editor.apply(); 430 } 431 432 private void registerListeners() { 433 mRingtonePref.setOnPreferenceChangeListener(this); 434 final IntentFilter intentFilter = 435 new IntentFilter(TelephonyIntents.ACTION_SIM_STATE_CHANGED); 436 registerReceiver(mReceiver, intentFilter); 437 } 438 439 public boolean onPreferenceChange(Preference preference, Object newValue) { 440 boolean result = false; 441 if (preference == mRingtonePref) { 442 setRingtoneSummary((String)newValue); 443 result = true; 444 } 445 return result; 446 } 447 448 // For the group mms feature to be enabled, the following must be true: 449 // 1. the feature is enabled in mms_config.xml (currently on by default) 450 // 2. the feature is enabled in the mms settings page 451 // 3. the SIM knows its own phone number 452 public static boolean getIsGroupMmsEnabled(Context context) { 453 SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context); 454 boolean groupMmsPrefOn = prefs.getBoolean( 455 MessagingPreferenceActivity.GROUP_MMS_MODE, true); 456 return MmsConfig.getGroupMmsEnabled() && 457 groupMmsPrefOn && 458 !TextUtils.isEmpty(MessageUtils.getLocalNumber()); 459 } 460 } 461