Settings.java revision 6006991395131d7d1db4f883ff8c7a87498b6eec
1/** 2 * Copyright (c) 2012, Google Inc. 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17package com.android.mail.providers; 18 19import com.google.common.base.Objects; 20 21import com.android.mail.providers.UIProvider.AccountColumns; 22import com.android.mail.providers.UIProvider.AutoAdvance; 23import com.android.mail.providers.UIProvider.DefaultReplyBehavior; 24import com.android.mail.providers.UIProvider.MessageTextSize; 25import com.android.mail.providers.UIProvider.SnapHeaderValue; 26import com.android.mail.providers.UIProvider.Swipe; 27import com.android.mail.utils.LogTag; 28import com.android.mail.utils.LogUtils; 29import com.android.mail.utils.Utils; 30 31import android.database.Cursor; 32import android.net.Uri; 33import android.os.Parcel; 34import android.os.Parcelable; 35import android.text.TextUtils; 36 37import org.json.JSONException; 38import org.json.JSONObject; 39 40/** 41 * Model to hold Settings for an account. 42 */ 43public class Settings implements Parcelable { 44 /** 45 * Interface to listen to settings changes. You need to register with the 46 * {@link com.android.mail.ui.ActivityController} for observing changes to settings. 47 */ 48 public interface ChangeListener { 49 /** 50 * Method that is called when settings are changed. 51 * @param updatedSettings the updated settings. 52 */ 53 public void onSettingsChanged(Settings updatedSettings); 54 } 55 56 private static final String LOG_TAG = LogTag.getLogTag(); 57 58 static final Settings EMPTY_SETTINGS = new Settings(); 59 60 // Max size for attachments (5 megs). Will be overridden by an account 61 // setting, if found. 62 private static final int DEFAULT_MAX_ATTACHMENT_SIZE = 5 * 1024 * 1024; 63 64 public static final int SWIPE_SETTING_ARCHIVE = 0; 65 public static final int SWIPE_SETTING_DELETE = 1; 66 public static final int SWIPE_SETTING_DISABLED = 2; 67 68 private static final int DEFAULT = SWIPE_SETTING_ARCHIVE; 69 70 public final String signature; 71 /** 72 * Auto advance setting for this account. 73 * Integer, one of {@link AutoAdvance#LIST}, {@link AutoAdvance#NEWER}, 74 * {@link AutoAdvance#OLDER} or {@link AutoAdvance#UNSET} 75 */ 76 public final int autoAdvance; 77 public final int messageTextSize; 78 public final int snapHeaders; 79 public final int replyBehavior; 80 public final boolean hideCheckboxes; 81 public final boolean confirmDelete; 82 public final boolean confirmArchive; 83 public final boolean confirmSend; 84 public final Uri defaultInbox; 85 /** 86 * The name of the default inbox: "Inbox" or "Priority Inbox", internationalized... 87 */ 88 public final String defaultInboxName; 89 // If you find the need for more default Inbox information: ID or capabilities, then 90 // ask viki to replace the above two members with a single JSON object representing the default 91 // folder. That should make all the information about the folder available without an 92 // explosion in the number of members. 93 94 public final boolean forceReplyFromDefault; 95 public final int maxAttachmentSize; 96 public final int swipe; 97 98 /** Cached value of hashCode */ 99 private int mHashCode; 100 101 private Settings() { 102 signature = null; 103 autoAdvance = AutoAdvance.LIST; 104 messageTextSize = MessageTextSize.NORMAL; 105 snapHeaders = SnapHeaderValue.ALWAYS; 106 replyBehavior = DefaultReplyBehavior.REPLY; 107 hideCheckboxes = false; 108 confirmDelete = false; 109 confirmArchive = false; 110 confirmSend = false; 111 defaultInbox = Uri.EMPTY; 112 defaultInboxName = ""; 113 forceReplyFromDefault = false; 114 maxAttachmentSize = 0; 115 swipe = DEFAULT; 116 } 117 118 public Settings(Parcel inParcel) { 119 signature = inParcel.readString(); 120 autoAdvance = inParcel.readInt(); 121 messageTextSize = inParcel.readInt(); 122 snapHeaders = inParcel.readInt(); 123 replyBehavior = inParcel.readInt(); 124 hideCheckboxes = inParcel.readInt() != 0; 125 confirmDelete = inParcel.readInt() != 0; 126 confirmArchive = inParcel.readInt() != 0; 127 confirmSend = inParcel.readInt() != 0; 128 defaultInbox = Utils.getValidUri(inParcel.readString()); 129 defaultInboxName = inParcel.readString(); 130 forceReplyFromDefault = inParcel.readInt() != 0; 131 maxAttachmentSize = inParcel.readInt(); 132 swipe = inParcel.readInt(); 133 } 134 135 public Settings(Cursor cursor) { 136 signature = cursor.getString(UIProvider.ACCOUNT_SETTINGS_SIGNATURE_COLUMN); 137 autoAdvance = cursor.getInt(UIProvider.ACCOUNT_SETTINGS_AUTO_ADVANCE_COLUMN); 138 messageTextSize = cursor.getInt(UIProvider.ACCOUNT_SETTINGS_MESSAGE_TEXT_SIZE_COLUMN); 139 snapHeaders = cursor.getInt(UIProvider.ACCOUNT_SETTINGS_SNAP_HEADERS_COLUMN); 140 replyBehavior = cursor.getInt(UIProvider.ACCOUNT_SETTINGS_REPLY_BEHAVIOR_COLUMN); 141 hideCheckboxes = cursor.getInt(UIProvider.ACCOUNT_SETTINGS_HIDE_CHECKBOXES_COLUMN) != 0; 142 confirmDelete = cursor.getInt(UIProvider.ACCOUNT_SETTINGS_CONFIRM_DELETE_COLUMN) != 0; 143 confirmArchive = cursor.getInt(UIProvider.ACCOUNT_SETTINGS_CONFIRM_ARCHIVE_COLUMN) != 0; 144 confirmSend = cursor.getInt(UIProvider.ACCOUNT_SETTINGS_CONFIRM_SEND_COLUMN) != 0; 145 defaultInbox = Utils.getValidUri( 146 cursor.getString(UIProvider.ACCOUNT_SETTINGS_DEFAULT_INBOX_COLUMN)); 147 defaultInboxName = cursor.getString(UIProvider.ACCOUNT_SETTINGS_DEFAULT_INBOX_NAME_COLUMN); 148 forceReplyFromDefault = cursor.getInt( 149 UIProvider.ACCOUNT_SETTINGS_FORCE_REPLY_FROM_DEFAULT_COLUMN) != 0; 150 maxAttachmentSize = cursor.getInt(UIProvider.ACCOUNT_SETTINGS_MAX_ATTACHMENT_SIZE_COLUMN); 151 swipe = cursor.getInt(UIProvider.ACCOUNT_SETTINGS_SWIPE_COLUMN); 152 } 153 154 private Settings(JSONObject json) throws JSONException { 155 signature = json.optString(AccountColumns.SettingsColumns.SIGNATURE); 156 157 autoAdvance = json.optInt(AccountColumns.SettingsColumns.AUTO_ADVANCE); 158 messageTextSize = json.optInt(AccountColumns.SettingsColumns.MESSAGE_TEXT_SIZE); 159 snapHeaders = json.optInt(AccountColumns.SettingsColumns.SNAP_HEADERS); 160 replyBehavior = json.optInt(AccountColumns.SettingsColumns.REPLY_BEHAVIOR); 161 hideCheckboxes = json.optBoolean(AccountColumns.SettingsColumns.HIDE_CHECKBOXES); 162 confirmDelete = json.optBoolean(AccountColumns.SettingsColumns.CONFIRM_DELETE); 163 confirmArchive = json.optBoolean(AccountColumns.SettingsColumns.CONFIRM_ARCHIVE); 164 confirmSend = json.optBoolean(AccountColumns.SettingsColumns.CONFIRM_SEND); 165 defaultInbox = Utils.getValidUri( 166 json.optString(AccountColumns.SettingsColumns.DEFAULT_INBOX)); 167 defaultInboxName = json.optString(AccountColumns.SettingsColumns.DEFAULT_INBOX_NAME); 168 forceReplyFromDefault = 169 json.optBoolean(AccountColumns.SettingsColumns.FORCE_REPLY_FROM_DEFAULT); 170 maxAttachmentSize = json.getInt(AccountColumns.SettingsColumns.MAX_ATTACHMENT_SIZE); 171 swipe = json.optInt(AccountColumns.SettingsColumns.SWIPE); 172 } 173 174 /** 175 * Return a serialized String for these settings. 176 */ 177 public synchronized String serialize() { 178 final JSONObject json = toJSON(); 179 return json.toString(); 180 } 181 182 /** 183 * Return a JSONObject for these settings. 184 */ 185 public synchronized JSONObject toJSON() { 186 final JSONObject json = new JSONObject(); 187 try { 188 json.put(AccountColumns.SettingsColumns.SIGNATURE, signature); 189 json.put(AccountColumns.SettingsColumns.AUTO_ADVANCE, autoAdvance); 190 json.put(AccountColumns.SettingsColumns.MESSAGE_TEXT_SIZE, messageTextSize); 191 json.put(AccountColumns.SettingsColumns.SNAP_HEADERS, snapHeaders); 192 json.put(AccountColumns.SettingsColumns.REPLY_BEHAVIOR, replyBehavior); 193 json.put(AccountColumns.SettingsColumns.HIDE_CHECKBOXES, hideCheckboxes); 194 json.put(AccountColumns.SettingsColumns.CONFIRM_DELETE, confirmDelete); 195 json.put(AccountColumns.SettingsColumns.CONFIRM_ARCHIVE, confirmArchive); 196 json.put(AccountColumns.SettingsColumns.CONFIRM_SEND, confirmSend); 197 json.put(AccountColumns.SettingsColumns.DEFAULT_INBOX, defaultInbox); 198 json.put(AccountColumns.SettingsColumns.DEFAULT_INBOX_NAME, defaultInboxName); 199 json.put(AccountColumns.SettingsColumns.FORCE_REPLY_FROM_DEFAULT, 200 forceReplyFromDefault); 201 json.put(AccountColumns.SettingsColumns.MAX_ATTACHMENT_SIZE, 202 maxAttachmentSize); 203 json.put(AccountColumns.SettingsColumns.SWIPE, swipe); 204 } catch (JSONException e) { 205 LogUtils.wtf(LOG_TAG, e, "Could not serialize settings"); 206 } 207 return json; 208 } 209 210 /** 211 * Create a new instance of an Settings object using a serialized instance created previously 212 * using {@link #serialize()}. This returns null if the serialized instance was invalid or does 213 * not represent a valid account object. 214 * 215 * @param serializedAccount 216 * @return 217 */ 218 public static Settings newInstance(String serializedSettings) { 219 JSONObject json = null; 220 try { 221 json = new JSONObject(serializedSettings); 222 return new Settings(json); 223 } catch (JSONException e) { 224 LogUtils.e(LOG_TAG, e, "Could not create an settings from this input: \"%s\"", 225 serializedSettings); 226 return null; 227 } 228 } 229 230 231 /** 232 * Create a new instance of an Settings object using a JSONObject instance created previously 233 * using {@link #toJSON(). This returns null if the serialized instance was invalid or does 234 * not represent a valid account object. 235 * 236 * @param serializedAccount 237 * @return 238 */ 239 public static Settings newInstance(JSONObject json) { 240 if (json == null) { 241 return null; 242 } 243 try { 244 return new Settings(json); 245 } catch (JSONException e) { 246 LogUtils.e(LOG_TAG, e, "Could not create an settings from this input: \"%s\"", 247 json.toString()); 248 return null; 249 } 250 } 251 252 @Override 253 public int describeContents() { 254 return 0; 255 } 256 257 @Override 258 public void writeToParcel(Parcel dest, int flags) { 259 dest.writeString(signature); 260 dest.writeInt(autoAdvance); 261 dest.writeInt(messageTextSize); 262 dest.writeInt(snapHeaders); 263 dest.writeInt(replyBehavior); 264 dest.writeInt(hideCheckboxes ? 1 : 0); 265 dest.writeInt(confirmDelete ? 1 : 0); 266 dest.writeInt(confirmArchive? 1 : 0); 267 dest.writeInt(confirmSend? 1 : 0); 268 dest.writeString(defaultInbox.toString()); 269 dest.writeString(defaultInboxName); 270 dest.writeInt(forceReplyFromDefault ? 1 : 0); 271 dest.writeInt(maxAttachmentSize); 272 dest.writeInt(swipe); 273 } 274 275 /** 276 * Returns the URI of the current account's default inbox if available, otherwise 277 * returns the empty URI {@link Uri#EMPTY} 278 * @param settings a settings object, possibly null. 279 * @return a valid default Inbox URI, or {@link Uri#EMPTY} if settings are null or no default 280 * is specified. 281 */ 282 public static Uri getDefaultInboxUri(Settings settings) { 283 if (settings != null && settings.defaultInbox != null) { 284 return settings.defaultInbox; 285 } 286 return Uri.EMPTY; 287 } 288 289 /** 290 * Return the auto advance setting for the settings provided. It is safe to pass this method 291 * a null object. It always returns a valid {@link AutoAdvance} setting. 292 * @return the auto advance setting, a constant from {@link AutoAdvance} 293 */ 294 public static int getAutoAdvanceSetting(Settings settings) { 295 // TODO(mindyp): if this isn't set, then show the dialog telling the user to set it. 296 // Remove defaulting to AutoAdvance.LIST. 297 final int autoAdvance = (settings != null) ? 298 (settings.autoAdvance == AutoAdvance.UNSET ? 299 AutoAdvance.LIST : settings.autoAdvance) 300 : AutoAdvance.LIST; 301 return autoAdvance; 302 } 303 304 /** 305 * Return the swipe setting for the settings provided. It is safe to pass this method 306 * a null object. It always returns a valid {@link Swipe} setting. 307 * @return the auto advance setting, a constant from {@link Swipe} 308 */ 309 public static int getSwipeSetting(Settings settings) { 310 return settings != null ? settings.swipe : Swipe.DEFAULT; 311 } 312 313 @SuppressWarnings("hiding") 314 public static final Creator<Settings> CREATOR = new Creator<Settings>() { 315 @Override 316 public Settings createFromParcel(Parcel source) { 317 return new Settings(source); 318 } 319 320 @Override 321 public Settings[] newArray(int size) { 322 return new Settings[size]; 323 } 324 }; 325 326 /** 327 * Get the maximum size in KB for attachments. 328 */ 329 public int getMaxAttachmentSize() { 330 return maxAttachmentSize <= 0 ? DEFAULT_MAX_ATTACHMENT_SIZE : maxAttachmentSize; 331 } 332 333 @Override 334 public boolean equals(final Object aThat) { 335 LogUtils.d(LOG_TAG, "Settings.equals(%s)", aThat); 336 if (this == aThat) { 337 return true; 338 } 339 if ((aThat == null) || (aThat.getClass() != this.getClass())) { 340 return false; 341 } 342 final Settings that = (Settings) aThat; 343 return (TextUtils.equals(signature, that.signature) 344 && autoAdvance == that.autoAdvance 345 && messageTextSize == that.messageTextSize 346 && replyBehavior == that.replyBehavior 347 && hideCheckboxes == that.hideCheckboxes 348 && confirmDelete == that.confirmDelete 349 && confirmArchive == that.confirmArchive 350 && confirmSend == that.confirmSend 351 && Objects.equal(defaultInbox, that.defaultInbox) 352 // Not checking default Inbox name, since is is identical to the URI check above. 353 && forceReplyFromDefault == that.forceReplyFromDefault 354 && maxAttachmentSize == that.maxAttachmentSize); 355 } 356 357 @Override 358 public int hashCode() { 359 if (mHashCode == 0) { 360 mHashCode = calculateHashCode(); 361 } 362 return mHashCode; 363 } 364 365 /** 366 * Returns the hash code for this object. 367 * @return 368 */ 369 private final int calculateHashCode() { 370 return super.hashCode() 371 ^ Objects.hashCode(signature, autoAdvance, messageTextSize, replyBehavior, 372 hideCheckboxes, confirmDelete, confirmArchive, confirmSend, 373 defaultInbox, forceReplyFromDefault, maxAttachmentSize); 374 } 375} 376