| /* |
| * Copyright (C) 2012 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.mail.preferences; |
| |
| import com.google.android.mail.common.base.Strings; |
| import com.google.common.collect.ImmutableSet; |
| |
| import android.content.ContentUris; |
| import android.content.Context; |
| import android.database.Cursor; |
| import android.media.RingtoneManager; |
| import android.net.Uri; |
| import android.provider.Settings; |
| |
| import com.android.mail.providers.Account; |
| import com.android.mail.providers.Folder; |
| import com.android.mail.providers.UIProvider.AccountCapabilities; |
| import com.android.mail.providers.UIProvider.FolderCapabilities; |
| import com.android.mail.utils.NotificationActionUtils.NotificationActionType; |
| |
| import java.util.LinkedHashSet; |
| import java.util.Set; |
| |
| /** |
| * Preferences relevant to one specific folder. In Email, this would only be used for an account's |
| * inbox. In Gmail, this is used for every account/label pair. |
| */ |
| public class FolderPreferences extends VersionedPrefs { |
| |
| private static final String PREFS_NAME_PREFIX = "Folder"; |
| |
| public static final class PreferenceKeys { |
| /** Boolean value indicating whether notifications are enabled */ |
| public static final String NOTIFICATIONS_ENABLED = "notifications-enabled"; |
| /** String value of the notification ringtone URI */ |
| public static final String NOTIFICATION_RINGTONE = "notification-ringtone"; |
| /** Boolean value indicating whether we should explicitly vibrate */ |
| public static final String NOTIFICATION_VIBRATE = "notification-vibrate"; |
| /** |
| * Boolean value indicating whether we notify for every message (<code>true</code>), or just |
| * once for the folder (<code>false</code>) |
| */ |
| public static final String NOTIFICATION_NOTIFY_EVERY_MESSAGE = |
| "notification-notify-every-message"; |
| |
| public static final ImmutableSet<String> BACKUP_KEYS = |
| new ImmutableSet.Builder<String>() |
| .add(NOTIFICATIONS_ENABLED) |
| .add(NOTIFICATION_RINGTONE) |
| .add(NOTIFICATION_VIBRATE) |
| .add(NOTIFICATION_NOTIFY_EVERY_MESSAGE) |
| .build(); |
| } |
| |
| private final Folder mFolder; |
| /** An id that is constant across app installations. */ |
| private final String mPersistentId; |
| private final boolean mUseInboxDefaultNotificationSettings; |
| |
| /** |
| * @param account The account name. This must never change for the account. |
| * @param folder The folder |
| */ |
| public FolderPreferences(final Context context, final String account, final Folder folder, |
| final boolean useInboxDefaultNotificationSettings) { |
| this(context, account, folder, folder.persistentId, useInboxDefaultNotificationSettings); |
| } |
| |
| /** |
| * A constructor that can be used when no {@link Folder} object is available (like during a |
| * restore). This will function as expected except when calling |
| * {@link #getDefaultNotificationActions(Context)}, so |
| * {@link #FolderPreferences(Context, String, Folder, boolean)} should be used if at all |
| * possible. |
| * |
| * @param account The account name. This must never change for the account. |
| * @param persistentId An identifier for the folder that does not change across app |
| * installations. |
| */ |
| public FolderPreferences(final Context context, final String account, final String persistentId, |
| final boolean useInboxDefaultNotificationSettings) { |
| this(context, account, null, persistentId, useInboxDefaultNotificationSettings); |
| } |
| |
| private FolderPreferences(final Context context, final String account, final Folder folder, |
| final String persistentId, final boolean useInboxDefaultNotificationSettings) { |
| super(context, buildSharedPrefsName(account, persistentId)); |
| mFolder = folder; |
| mPersistentId = persistentId; |
| mUseInboxDefaultNotificationSettings = useInboxDefaultNotificationSettings; |
| } |
| |
| private static String buildSharedPrefsName(final String account, final String persistentId) { |
| return PREFS_NAME_PREFIX + '-' + account + '-' + persistentId; |
| } |
| |
| @Override |
| protected void performUpgrade(final int oldVersion, final int newVersion) { |
| if (oldVersion > newVersion) { |
| throw new IllegalStateException( |
| "You appear to have downgraded your app. Please clear app data."); |
| } |
| } |
| |
| @Override |
| protected boolean canBackup(final String key) { |
| if (mPersistentId == null) { |
| return false; |
| } |
| |
| return PreferenceKeys.BACKUP_KEYS.contains(key); |
| } |
| |
| @Override |
| protected Object getBackupValue(final String key, final Object value) { |
| if (PreferenceKeys.NOTIFICATION_RINGTONE.equals(key)) { |
| return getRingtoneTitle((String) value); |
| } |
| |
| return super.getBackupValue(key, value); |
| } |
| |
| @Override |
| protected Object getRestoreValue(final String key, final Object value) { |
| if (PreferenceKeys.NOTIFICATION_RINGTONE.equals(key)) { |
| return getRingtoneUri((String) value); |
| } |
| |
| return super.getBackupValue(key, value); |
| } |
| |
| private String getRingtoneTitle(final String ringtoneUriString) { |
| if (ringtoneUriString.length() == 0) { |
| return ringtoneUriString; |
| } |
| final Uri uri = Uri.parse(ringtoneUriString); |
| if (RingtoneManager.isDefault(uri)) { |
| return ringtoneUriString; |
| } |
| final RingtoneManager ringtoneManager = new RingtoneManager(getContext()); |
| ringtoneManager.setType(RingtoneManager.TYPE_NOTIFICATION); |
| final Cursor cursor = ringtoneManager.getCursor(); |
| try { |
| while (cursor.moveToNext()) { |
| final Uri cursorUri = ContentUris.withAppendedId( |
| Uri.parse(cursor.getString(RingtoneManager.URI_COLUMN_INDEX)), |
| cursor.getLong(RingtoneManager.ID_COLUMN_INDEX)); |
| if (cursorUri.toString().equals(ringtoneUriString)) { |
| final String title = cursor.getString(RingtoneManager.TITLE_COLUMN_INDEX); |
| if (!Strings.isNullOrEmpty(title)) { |
| return title; |
| } |
| } |
| } |
| } finally { |
| cursor.close(); |
| } |
| return null; |
| } |
| |
| private String getRingtoneUri(final String name) { |
| if (name.length() == 0 || RingtoneManager.isDefault(Uri.parse(name))) { |
| return name; |
| } |
| |
| final RingtoneManager ringtoneManager = new RingtoneManager(getContext()); |
| ringtoneManager.setType(RingtoneManager.TYPE_NOTIFICATION); |
| final Cursor cursor = ringtoneManager.getCursor(); |
| try { |
| while (cursor.moveToNext()) { |
| String title = cursor.getString(RingtoneManager.TITLE_COLUMN_INDEX); |
| if (name.equals(title)) { |
| Uri uri = ContentUris.withAppendedId( |
| Uri.parse(cursor.getString(RingtoneManager.URI_COLUMN_INDEX)), |
| cursor.getLong(RingtoneManager.ID_COLUMN_INDEX)); |
| return uri.toString(); |
| } |
| } |
| } finally { |
| cursor.close(); |
| } |
| return null; |
| } |
| |
| /** |
| * If <code>true</code>, we use inbox-defaults for notification settings. If <code>false</code>, |
| * we use standard defaults. |
| */ |
| private boolean getUseInboxDefaultNotificationSettings() { |
| return mUseInboxDefaultNotificationSettings; |
| } |
| |
| public boolean isNotificationsEnabledSet() { |
| return getSharedPreferences().contains(PreferenceKeys.NOTIFICATIONS_ENABLED); |
| } |
| |
| public boolean areNotificationsEnabled() { |
| return getSharedPreferences().getBoolean( |
| PreferenceKeys.NOTIFICATIONS_ENABLED, getUseInboxDefaultNotificationSettings()); |
| } |
| |
| public void setNotificationsEnabled(final boolean enabled) { |
| getEditor().putBoolean(PreferenceKeys.NOTIFICATIONS_ENABLED, enabled).apply(); |
| notifyBackupPreferenceChanged(); |
| } |
| |
| public String getNotificationRingtoneUri() { |
| return getSharedPreferences().getString(PreferenceKeys.NOTIFICATION_RINGTONE, |
| Settings.System.DEFAULT_NOTIFICATION_URI.toString()); |
| } |
| |
| public void setNotificationRingtoneUri(final String uri) { |
| getEditor().putString(PreferenceKeys.NOTIFICATION_RINGTONE, uri).apply(); |
| notifyBackupPreferenceChanged(); |
| } |
| |
| public boolean isNotificationVibrateEnabled() { |
| return getSharedPreferences().getBoolean(PreferenceKeys.NOTIFICATION_VIBRATE, false); |
| } |
| |
| public void setNotificationVibrateEnabled(final boolean enabled) { |
| getEditor().putBoolean(PreferenceKeys.NOTIFICATION_VIBRATE, enabled).apply(); |
| notifyBackupPreferenceChanged(); |
| } |
| |
| public boolean isEveryMessageNotificationEnabled() { |
| return getSharedPreferences() |
| .getBoolean(PreferenceKeys.NOTIFICATION_NOTIFY_EVERY_MESSAGE, false); |
| } |
| |
| public void setEveryMessageNotificationEnabled(final boolean enabled) { |
| getEditor().putBoolean(PreferenceKeys.NOTIFICATION_NOTIFY_EVERY_MESSAGE, enabled).apply(); |
| notifyBackupPreferenceChanged(); |
| } |
| |
| public Set<String> getNotificationActions(final Account account) { |
| final boolean supportsArchiveRemoveLabel = |
| mFolder.supportsCapability(FolderCapabilities.ARCHIVE) |
| || mFolder.supportsCapability(FolderCapabilities.ALLOWS_REMOVE_CONVERSATION); |
| final boolean preferDelete = MailPrefs.RemovalActions.DELETE.equals( |
| MailPrefs.get(getContext()).getRemovalAction( |
| account.supportsCapability(AccountCapabilities.ARCHIVE))); |
| final NotificationActionType destructiveActionType = |
| supportsArchiveRemoveLabel && !preferDelete ? |
| NotificationActionType.ARCHIVE_REMOVE_LABEL : NotificationActionType.DELETE; |
| final String destructiveAction = destructiveActionType.getPersistedValue(); |
| |
| final String replyAction = |
| MailPrefs.get(getContext()).getDefaultReplyAll() |
| ? NotificationActionType.REPLY_ALL.getPersistedValue() |
| : NotificationActionType.REPLY.getPersistedValue(); |
| |
| final Set<String> notificationActions = new LinkedHashSet<String>(2); |
| notificationActions.add(destructiveAction); |
| notificationActions.add(replyAction); |
| |
| return notificationActions; |
| } |
| } |