/* * Copyright (C) 2007-2008 Esmertec AG. * Copyright (C) 2007-2008 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.android.mms.ui; import android.app.ActionBar; import android.app.AlertDialog; import android.app.Dialog; import android.content.BroadcastReceiver; import android.content.Context; import android.content.DialogInterface; import android.content.Intent; import android.content.IntentFilter; import android.content.SharedPreferences; import android.media.Ringtone; import android.media.RingtoneManager; import android.net.Uri; import android.os.Bundle; import android.os.Vibrator; import android.preference.CheckBoxPreference; import android.preference.Preference; import android.preference.Preference.OnPreferenceChangeListener; import android.preference.PreferenceActivity; import android.preference.PreferenceCategory; import android.preference.PreferenceManager; import android.preference.PreferenceScreen; import android.preference.RingtonePreference; import android.provider.SearchRecentSuggestions; import android.text.TextUtils; import android.view.Menu; import android.view.MenuItem; import com.android.internal.telephony.IccCardConstants; import com.android.internal.telephony.TelephonyIntents; import com.android.mms.MmsApp; import com.android.mms.MmsConfig; import com.android.mms.R; import com.android.mms.transaction.TransactionService; import com.android.mms.util.Recycler; /** * With this activity, users can set preferences for MMS and SMS and * can access and manipulate SMS messages stored on the SIM. */ public class MessagingPreferenceActivity extends PreferenceActivity implements OnPreferenceChangeListener { // Symbolic names for the keys used for preference lookup public static final String MMS_DELIVERY_REPORT_MODE = "pref_key_mms_delivery_reports"; public static final String EXPIRY_TIME = "pref_key_mms_expiry"; public static final String PRIORITY = "pref_key_mms_priority"; public static final String READ_REPORT_MODE = "pref_key_mms_read_reports"; public static final String SMS_DELIVERY_REPORT_MODE = "pref_key_sms_delivery_reports"; public static final String NOTIFICATION_ENABLED = "pref_key_enable_notifications"; public static final String NOTIFICATION_VIBRATE = "pref_key_vibrate"; public static final String NOTIFICATION_VIBRATE_WHEN= "pref_key_vibrateWhen"; public static final String NOTIFICATION_RINGTONE = "pref_key_ringtone"; public static final String AUTO_RETRIEVAL = "pref_key_mms_auto_retrieval"; public static final String RETRIEVAL_DURING_ROAMING = "pref_key_mms_retrieval_during_roaming"; public static final String AUTO_DELETE = "pref_key_auto_delete"; public static final String GROUP_MMS_MODE = "pref_key_mms_group_mms"; // Menu entries private static final int MENU_RESTORE_DEFAULTS = 1; // Preferences for enabling and disabling SMS private Preference mSmsDisabledPref; private Preference mSmsEnabledPref; private PreferenceCategory mStoragePrefCategory; private PreferenceCategory mSmsPrefCategory; private PreferenceCategory mMmsPrefCategory; private PreferenceCategory mNotificationPrefCategory; private Preference mSmsLimitPref; private Preference mSmsDeliveryReportPref; private Preference mMmsLimitPref; private Preference mMmsDeliveryReportPref; private Preference mMmsGroupMmsPref; private Preference mMmsReadReportPref; private Preference mManageSimPref; private Preference mClearHistoryPref; private CheckBoxPreference mVibratePref; private CheckBoxPreference mEnableNotificationsPref; private CheckBoxPreference mMmsAutoRetrievialPref; private RingtonePreference mRingtonePref; private Recycler mSmsRecycler; private Recycler mMmsRecycler; private static final int CONFIRM_CLEAR_SEARCH_HISTORY_DIALOG = 3; // Whether or not we are currently enabled for SMS. This field is updated in onResume to make // sure we notice if the user has changed the default SMS app. private boolean mIsSmsEnabled; private BroadcastReceiver mReceiver = new BroadcastReceiver() { public void onReceive(Context context, Intent intent) { final String action = intent.getAction(); if (TelephonyIntents.ACTION_SIM_STATE_CHANGED.equals(action)) { String stateExtra = intent.getStringExtra(IccCardConstants.INTENT_KEY_ICC_STATE); if (stateExtra != null && IccCardConstants.INTENT_VALUE_ICC_ABSENT.equals(stateExtra)) { PreferenceCategory smsCategory = (PreferenceCategory)findPreference("pref_key_sms_settings"); if (smsCategory != null) { smsCategory.removePreference(mManageSimPref); } } } } }; @Override protected void onCreate(Bundle icicle) { super.onCreate(icicle); loadPrefs(); ActionBar actionBar = getActionBar(); actionBar.setDisplayHomeAsUpEnabled(true); } @Override protected void onResume() { super.onResume(); boolean isSmsEnabled = MmsConfig.isSmsEnabled(this); if (isSmsEnabled != mIsSmsEnabled) { mIsSmsEnabled = isSmsEnabled; invalidateOptionsMenu(); } // Since the enabled notifications pref can be changed outside of this activity, // we have to reload it whenever we resume. setEnabledNotificationsPref(); registerListeners(); updateSmsEnabledState(); } private void updateSmsEnabledState() { // Show the right pref (SMS Disabled or SMS Enabled) PreferenceScreen prefRoot = (PreferenceScreen)findPreference("pref_key_root"); if (!mIsSmsEnabled) { prefRoot.addPreference(mSmsDisabledPref); prefRoot.removePreference(mSmsEnabledPref); } else { prefRoot.removePreference(mSmsDisabledPref); prefRoot.addPreference(mSmsEnabledPref); } // Enable or Disable the settings as appropriate mStoragePrefCategory.setEnabled(mIsSmsEnabled); mSmsPrefCategory.setEnabled(mIsSmsEnabled); mMmsPrefCategory.setEnabled(mIsSmsEnabled); mNotificationPrefCategory.setEnabled(mIsSmsEnabled); } @Override protected void onPause() { super.onPause(); unregisterReceiver(mReceiver); } private void loadPrefs() { addPreferencesFromResource(R.xml.preferences); mSmsDisabledPref = findPreference("pref_key_sms_disabled"); mSmsEnabledPref = findPreference("pref_key_sms_enabled"); mStoragePrefCategory = (PreferenceCategory)findPreference("pref_key_storage_settings"); mSmsPrefCategory = (PreferenceCategory)findPreference("pref_key_sms_settings"); mMmsPrefCategory = (PreferenceCategory)findPreference("pref_key_mms_settings"); mNotificationPrefCategory = (PreferenceCategory)findPreference("pref_key_notification_settings"); mManageSimPref = findPreference("pref_key_manage_sim_messages"); mSmsLimitPref = findPreference("pref_key_sms_delete_limit"); mSmsDeliveryReportPref = findPreference("pref_key_sms_delivery_reports"); mMmsDeliveryReportPref = findPreference("pref_key_mms_delivery_reports"); mMmsGroupMmsPref = findPreference("pref_key_mms_group_mms"); mMmsReadReportPref = findPreference("pref_key_mms_read_reports"); mMmsLimitPref = findPreference("pref_key_mms_delete_limit"); mClearHistoryPref = findPreference("pref_key_mms_clear_history"); mEnableNotificationsPref = (CheckBoxPreference) findPreference(NOTIFICATION_ENABLED); mMmsAutoRetrievialPref = (CheckBoxPreference) findPreference(AUTO_RETRIEVAL); mVibratePref = (CheckBoxPreference) findPreference(NOTIFICATION_VIBRATE); Vibrator vibrator = (Vibrator) getSystemService(Context.VIBRATOR_SERVICE); if (mVibratePref != null && (vibrator == null || !vibrator.hasVibrator())) { mNotificationPrefCategory.removePreference(mVibratePref); mVibratePref = null; } mRingtonePref = (RingtonePreference) findPreference(NOTIFICATION_RINGTONE); setMessagePreferences(); } private void restoreDefaultPreferences() { PreferenceManager.getDefaultSharedPreferences(this).edit().clear().apply(); setPreferenceScreen(null); loadPrefs(); updateSmsEnabledState(); // NOTE: After restoring preferences, the auto delete function (i.e. message recycler) // will be turned off by default. However, we really want the default to be turned on. // Because all the prefs are cleared, that'll cause: // ConversationList.runOneTimeStorageLimitCheckForLegacyMessages to get executed the // next time the user runs the Messaging app and it will either turn on the setting // by default, or if the user is over the limits, encourage them to turn on the setting // manually. } private void setMessagePreferences() { if (!MmsApp.getApplication().getTelephonyManager().hasIccCard()) { // No SIM card, remove the SIM-related prefs mSmsPrefCategory.removePreference(mManageSimPref); } if (!MmsConfig.getSMSDeliveryReportsEnabled()) { mSmsPrefCategory.removePreference(mSmsDeliveryReportPref); if (!MmsApp.getApplication().getTelephonyManager().hasIccCard()) { getPreferenceScreen().removePreference(mSmsPrefCategory); } } if (!MmsConfig.getMmsEnabled()) { // No Mms, remove all the mms-related preferences getPreferenceScreen().removePreference(mMmsPrefCategory); mStoragePrefCategory.removePreference(findPreference("pref_key_mms_delete_limit")); } else { if (!MmsConfig.getMMSDeliveryReportsEnabled()) { mMmsPrefCategory.removePreference(mMmsDeliveryReportPref); } if (!MmsConfig.getMMSReadReportsEnabled()) { mMmsPrefCategory.removePreference(mMmsReadReportPref); } // If the phone's SIM doesn't know it's own number, disable group mms. if (!MmsConfig.getGroupMmsEnabled() || TextUtils.isEmpty(MessageUtils.getLocalNumber())) { mMmsPrefCategory.removePreference(mMmsGroupMmsPref); } } setEnabledNotificationsPref(); // If needed, migrate vibration setting from the previous tri-state setting stored in // NOTIFICATION_VIBRATE_WHEN to the boolean setting stored in NOTIFICATION_VIBRATE. SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(this); if (mVibratePref != null && sharedPreferences.contains(NOTIFICATION_VIBRATE_WHEN)) { String vibrateWhen = sharedPreferences. getString(MessagingPreferenceActivity.NOTIFICATION_VIBRATE_WHEN, null); boolean vibrate = "always".equals(vibrateWhen); SharedPreferences.Editor prefsEditor = sharedPreferences.edit(); prefsEditor.putBoolean(NOTIFICATION_VIBRATE, vibrate); prefsEditor.remove(NOTIFICATION_VIBRATE_WHEN); // remove obsolete setting prefsEditor.apply(); mVibratePref.setChecked(vibrate); } mSmsRecycler = Recycler.getSmsRecycler(); mMmsRecycler = Recycler.getMmsRecycler(); // Fix up the recycler's summary with the correct values setSmsDisplayLimit(); setMmsDisplayLimit(); String soundValue = sharedPreferences.getString(NOTIFICATION_RINGTONE, null); setRingtoneSummary(soundValue); } private void setRingtoneSummary(String soundValue) { Uri soundUri = TextUtils.isEmpty(soundValue) ? null : Uri.parse(soundValue); Ringtone tone = soundUri != null ? RingtoneManager.getRingtone(this, soundUri) : null; mRingtonePref.setSummary(tone != null ? tone.getTitle(this) : getResources().getString(R.string.silent_ringtone)); } private void setEnabledNotificationsPref() { // The "enable notifications" setting is really stored in our own prefs. Read the // current value and set the checkbox to match. mEnableNotificationsPref.setChecked(getNotificationEnabled(this)); } private void setSmsDisplayLimit() { mSmsLimitPref.setSummary( getString(R.string.pref_summary_delete_limit, mSmsRecycler.getMessageLimit(this))); } private void setMmsDisplayLimit() { mMmsLimitPref.setSummary( getString(R.string.pref_summary_delete_limit, mMmsRecycler.getMessageLimit(this))); } public boolean onCreateOptionsMenu(Menu menu) { super.onCreateOptionsMenu(menu); menu.clear(); if (mIsSmsEnabled) { menu.add(0, MENU_RESTORE_DEFAULTS, 0, R.string.restore_default); } return true; } @Override public boolean onOptionsItemSelected(MenuItem item) { switch (item.getItemId()) { case MENU_RESTORE_DEFAULTS: restoreDefaultPreferences(); return true; case android.R.id.home: // The user clicked on the Messaging icon in the action bar. Take them back from // wherever they came from finish(); return true; } return false; } @Override public boolean onPreferenceTreeClick(PreferenceScreen preferenceScreen, Preference preference) { if (preference == mSmsLimitPref) { new NumberPickerDialog(this, mSmsLimitListener, mSmsRecycler.getMessageLimit(this), mSmsRecycler.getMessageMinLimit(), mSmsRecycler.getMessageMaxLimit(), R.string.pref_title_sms_delete).show(); } else if (preference == mMmsLimitPref) { new NumberPickerDialog(this, mMmsLimitListener, mMmsRecycler.getMessageLimit(this), mMmsRecycler.getMessageMinLimit(), mMmsRecycler.getMessageMaxLimit(), R.string.pref_title_mms_delete).show(); } else if (preference == mManageSimPref) { startActivity(new Intent(this, ManageSimMessages.class)); } else if (preference == mClearHistoryPref) { showDialog(CONFIRM_CLEAR_SEARCH_HISTORY_DIALOG); return true; } else if (preference == mEnableNotificationsPref) { // Update the actual "enable notifications" value that is stored in secure settings. enableNotifications(mEnableNotificationsPref.isChecked(), this); } else if (preference == mMmsAutoRetrievialPref) { if (mMmsAutoRetrievialPref.isChecked()) { startMmsDownload(); } } return super.onPreferenceTreeClick(preferenceScreen, preference); } /** * Trigger the TransactionService to download any outstanding messages. */ private void startMmsDownload() { startService(new Intent(TransactionService.ACTION_ENABLE_AUTO_RETRIEVE, null, this, TransactionService.class)); } NumberPickerDialog.OnNumberSetListener mSmsLimitListener = new NumberPickerDialog.OnNumberSetListener() { public void onNumberSet(int limit) { mSmsRecycler.setMessageLimit(MessagingPreferenceActivity.this, limit); setSmsDisplayLimit(); } }; NumberPickerDialog.OnNumberSetListener mMmsLimitListener = new NumberPickerDialog.OnNumberSetListener() { public void onNumberSet(int limit) { mMmsRecycler.setMessageLimit(MessagingPreferenceActivity.this, limit); setMmsDisplayLimit(); } }; @Override protected Dialog onCreateDialog(int id) { switch (id) { case CONFIRM_CLEAR_SEARCH_HISTORY_DIALOG: return new AlertDialog.Builder(MessagingPreferenceActivity.this) .setTitle(R.string.confirm_clear_search_title) .setMessage(R.string.confirm_clear_search_text) .setPositiveButton(android.R.string.ok, new AlertDialog.OnClickListener() { public void onClick(DialogInterface dialog, int which) { SearchRecentSuggestions recent = ((MmsApp)getApplication()).getRecentSuggestions(); if (recent != null) { recent.clearHistory(); } dialog.dismiss(); } }) .setNegativeButton(android.R.string.cancel, null) .setIconAttribute(android.R.attr.alertDialogIcon) .create(); } return super.onCreateDialog(id); } public static boolean getNotificationEnabled(Context context) { SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context); boolean notificationsEnabled = prefs.getBoolean(MessagingPreferenceActivity.NOTIFICATION_ENABLED, true); return notificationsEnabled; } public static void enableNotifications(boolean enabled, Context context) { // Store the value of notifications in SharedPreferences SharedPreferences.Editor editor = PreferenceManager.getDefaultSharedPreferences(context).edit(); editor.putBoolean(MessagingPreferenceActivity.NOTIFICATION_ENABLED, enabled); editor.apply(); } private void registerListeners() { mRingtonePref.setOnPreferenceChangeListener(this); final IntentFilter intentFilter = new IntentFilter(TelephonyIntents.ACTION_SIM_STATE_CHANGED); registerReceiver(mReceiver, intentFilter); } public boolean onPreferenceChange(Preference preference, Object newValue) { boolean result = false; if (preference == mRingtonePref) { setRingtoneSummary((String)newValue); result = true; } return result; } // For the group mms feature to be enabled, the following must be true: // 1. the feature is enabled in mms_config.xml (currently on by default) // 2. the feature is enabled in the mms settings page // 3. the SIM knows its own phone number public static boolean getIsGroupMmsEnabled(Context context) { SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context); boolean groupMmsPrefOn = prefs.getBoolean( MessagingPreferenceActivity.GROUP_MMS_MODE, true); return MmsConfig.getGroupMmsEnabled() && groupMmsPrefOn && !TextUtils.isEmpty(MessageUtils.getLocalNumber()); } }