Home | History | Annotate | Download | only in ui
      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