/* * 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 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 com.google.android.mail.common.base.Strings; import com.google.common.collect.ImmutableSet; 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 (true), or just * once for the folder (false) */ public static final String NOTIFICATION_NOTIFY_EVERY_MESSAGE = "notification-notify-every-message"; public static final ImmutableSet BACKUP_KEYS = new ImmutableSet.Builder() .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 accountEmail The account email. This must never change for the account. * @param folder The folder */ public FolderPreferences(final Context context, final String accountEmail, final Folder folder, final boolean useInboxDefaultNotificationSettings) { this(context, accountEmail, 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 accountEmail The account email. 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 accountEmail, final String persistentId, final boolean useInboxDefaultNotificationSettings) { this(context, accountEmail, null, persistentId, useInboxDefaultNotificationSettings); } private FolderPreferences(final Context context, final String accountEmail, final Folder folder, final String persistentId, final boolean useInboxDefaultNotificationSettings) { super(context, buildSharedPrefsName(accountEmail, 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 true, we use inbox-defaults for notification settings. If false, * 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 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 notificationActions = new LinkedHashSet(2); notificationActions.add(destructiveAction); notificationActions.add(replyAction); return notificationActions; } }