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