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