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.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
    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
    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 
    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
    171     protected void onPause() {
    172         super.onPause();
    173         unregisterReceiver(mReceiver);
    174     }
    175 
    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 
    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 
    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 
    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 
    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 
    296     private void setSmsDisplayLimit() {
    297         mSmsLimitPref.setSummary(
    298                 getString(R.string.pref_summary_delete_limit,
    299                         mSmsRecycler.getMessageLimit(this)));
    300     }
    301 
    302     private void setMmsDisplayLimit() {
    303         mMmsLimitPref.setSummary(
    304                 getString(R.string.pref_summary_delete_limit,
    305                         mMmsRecycler.getMessageLimit(this)));
    306     }
    307 
    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
    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
    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      */
    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
    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