Mailbox.java revision 6e418aa41a17136be0dddb816d843428a0a1e722
1/* 2 * Copyright (C) 2009 The Android Open Source Project 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 17 18package com.android.emailcommon.provider; 19 20import android.content.ContentUris; 21import android.content.ContentValues; 22import android.content.Context; 23import android.database.Cursor; 24import android.net.Uri; 25import android.os.Parcel; 26import android.os.Parcelable; 27import android.util.Log; 28 29import com.android.emailcommon.Logging; 30import com.android.emailcommon.provider.EmailContent.MailboxColumns; 31import com.android.emailcommon.provider.EmailContent.SyncColumns; 32import com.android.emailcommon.utility.Utility; 33 34public class Mailbox extends EmailContent implements SyncColumns, MailboxColumns, Parcelable { 35 public static final String TABLE_NAME = "Mailbox"; 36 @SuppressWarnings("hiding") 37 public static final Uri CONTENT_URI = Uri.parse(EmailContent.CONTENT_URI + "/mailbox"); 38 public static final Uri ADD_TO_FIELD_URI = 39 Uri.parse(EmailContent.CONTENT_URI + "/mailboxIdAddToField"); 40 public static final Uri FROM_ACCOUNT_AND_TYPE_URI = 41 Uri.parse(EmailContent.CONTENT_URI + "/mailboxIdFromAccountAndType"); 42 43 public String mDisplayName; 44 public String mServerId; 45 public String mParentServerId; 46 public long mParentKey; 47 public long mAccountKey; 48 public int mType; 49 public int mDelimiter; 50 public String mSyncKey; 51 public int mSyncLookback; 52 public int mSyncInterval; 53 public long mSyncTime; 54 public boolean mFlagVisible = true; 55 public int mFlags; 56 public int mVisibleLimit; 57 public String mSyncStatus; 58 public long mLastSeenMessageKey; 59 public long mLastTouchedTime; 60 61 public static final int CONTENT_ID_COLUMN = 0; 62 public static final int CONTENT_DISPLAY_NAME_COLUMN = 1; 63 public static final int CONTENT_SERVER_ID_COLUMN = 2; 64 public static final int CONTENT_PARENT_SERVER_ID_COLUMN = 3; 65 public static final int CONTENT_ACCOUNT_KEY_COLUMN = 4; 66 public static final int CONTENT_TYPE_COLUMN = 5; 67 public static final int CONTENT_DELIMITER_COLUMN = 6; 68 public static final int CONTENT_SYNC_KEY_COLUMN = 7; 69 public static final int CONTENT_SYNC_LOOKBACK_COLUMN = 8; 70 public static final int CONTENT_SYNC_INTERVAL_COLUMN = 9; 71 public static final int CONTENT_SYNC_TIME_COLUMN = 10; 72 public static final int CONTENT_FLAG_VISIBLE_COLUMN = 11; 73 public static final int CONTENT_FLAGS_COLUMN = 12; 74 public static final int CONTENT_VISIBLE_LIMIT_COLUMN = 13; 75 public static final int CONTENT_SYNC_STATUS_COLUMN = 14; 76 public static final int CONTENT_PARENT_KEY_COLUMN = 15; 77 public static final int CONTENT_LAST_SEEN_MESSAGE_KEY_COLUMN = 16; 78 public static final int CONTENT_LAST_TOUCHED_TIME_COLUMN = 17; 79 80 /** 81 * <em>NOTE</em>: If fields are added or removed, the method {@link #getHashes()} 82 * MUST be updated. 83 */ 84 public static final String[] CONTENT_PROJECTION = new String[] { 85 RECORD_ID, MailboxColumns.DISPLAY_NAME, MailboxColumns.SERVER_ID, 86 MailboxColumns.PARENT_SERVER_ID, MailboxColumns.ACCOUNT_KEY, MailboxColumns.TYPE, 87 MailboxColumns.DELIMITER, MailboxColumns.SYNC_KEY, MailboxColumns.SYNC_LOOKBACK, 88 MailboxColumns.SYNC_INTERVAL, MailboxColumns.SYNC_TIME, 89 MailboxColumns.FLAG_VISIBLE, MailboxColumns.FLAGS, MailboxColumns.VISIBLE_LIMIT, 90 MailboxColumns.SYNC_STATUS, MailboxColumns.PARENT_KEY, 91 MailboxColumns.LAST_SEEN_MESSAGE_KEY, MailboxColumns.LAST_TOUCHED_TIME, 92 }; 93 94 private static final String ACCOUNT_AND_MAILBOX_TYPE_SELECTION = 95 MailboxColumns.ACCOUNT_KEY + " =? AND " + 96 MailboxColumns.TYPE + " =?"; 97 private static final String MAILBOX_TYPE_SELECTION = 98 MailboxColumns.TYPE + " =?"; 99 /** Selection by server pathname for a given account */ 100 private static final String PATH_AND_ACCOUNT_SELECTION = 101 MailboxColumns.SERVER_ID + "=? and " + MailboxColumns.ACCOUNT_KEY + "=?"; 102 103 private static final String[] MAILBOX_SUM_OF_UNREAD_COUNT_PROJECTION = new String [] { 104 "sum(" + MailboxColumns.UNREAD_COUNT + ")" 105 }; 106 private static final int UNREAD_COUNT_COUNT_COLUMN = 0; 107 private static final String[] MAILBOX_SUM_OF_MESSAGE_COUNT_PROJECTION = new String [] { 108 "sum(" + MailboxColumns.MESSAGE_COUNT + ")" 109 }; 110 private static final int MESSAGE_COUNT_COUNT_COLUMN = 0; 111 112 private static final String[] MAILBOX_TYPE_PROJECTION = new String [] { 113 MailboxColumns.TYPE 114 }; 115 private static final int MAILBOX_TYPE_TYPE_COLUMN = 0; 116 117 private static final String[] MAILBOX_DISPLAY_NAME_PROJECTION = new String [] { 118 MailboxColumns.DISPLAY_NAME 119 }; 120 private static final int MAILBOX_DISPLAY_NAME_COLUMN = 0; 121 122 public static final long NO_MAILBOX = -1; 123 124 // Sentinel values for the mSyncInterval field of both Mailbox records 125 public static final int CHECK_INTERVAL_NEVER = -1; 126 public static final int CHECK_INTERVAL_PUSH = -2; 127 // The following two sentinel values are used by EAS 128 // Ping indicates that the EAS mailbox is synced based on a "ping" from the server 129 public static final int CHECK_INTERVAL_PING = -3; 130 // Push-Hold indicates an EAS push or ping Mailbox shouldn't sync just yet 131 public static final int CHECK_INTERVAL_PUSH_HOLD = -4; 132 133 // Sentinel for PARENT_KEY. Use NO_MAILBOX for toplevel mailboxes (i.e. no parents). 134 public static final long PARENT_KEY_UNINITIALIZED = 0L; 135 136 private static final String WHERE_TYPE_AND_ACCOUNT_KEY = 137 MailboxColumns.TYPE + "=? and " + MailboxColumns.ACCOUNT_KEY + "=?"; 138 139 public static final Integer[] INVALID_DROP_TARGETS = new Integer[] {Mailbox.TYPE_DRAFTS, 140 Mailbox.TYPE_OUTBOX, Mailbox.TYPE_SENT}; 141 142 public static final String USER_VISIBLE_MAILBOX_SELECTION = 143 MailboxColumns.TYPE + "<" + Mailbox.TYPE_NOT_EMAIL + 144 " AND " + MailboxColumns.FLAG_VISIBLE + "=1"; 145 146 // Types of mailboxes. The list is ordered to match a typical UI presentation, e.g. 147 // placing the inbox at the top. 148 // Arrays of "special_mailbox_display_names" and "special_mailbox_icons" are depends on 149 // types Id of mailboxes. 150 /** No type specified */ 151 public static final int TYPE_NONE = -1; 152 /** The "main" mailbox for the account, almost always referred to as "Inbox" */ 153 public static final int TYPE_INBOX = 0; 154 // Types of mailboxes 155 /** Generic mailbox that holds mail */ 156 public static final int TYPE_MAIL = 1; 157 /** Parent-only mailbox; does not hold any mail */ 158 public static final int TYPE_PARENT = 2; 159 /** Drafts mailbox */ 160 public static final int TYPE_DRAFTS = 3; 161 /** Local mailbox associated with the account's outgoing mail */ 162 public static final int TYPE_OUTBOX = 4; 163 /** Sent mail; mail that was sent from the account */ 164 public static final int TYPE_SENT = 5; 165 /** Deleted mail */ 166 public static final int TYPE_TRASH = 6; 167 /** Junk mail */ 168 public static final int TYPE_JUNK = 7; 169 /** Search results */ 170 public static final int TYPE_SEARCH = 8; 171 172 // Types after this are used for non-mail mailboxes (as in EAS) 173 public static final int TYPE_NOT_EMAIL = 0x40; 174 public static final int TYPE_CALENDAR = 0x41; 175 public static final int TYPE_CONTACTS = 0x42; 176 public static final int TYPE_TASKS = 0x43; 177 public static final int TYPE_EAS_ACCOUNT_MAILBOX = 0x44; 178 public static final int TYPE_UNKNOWN = 0x45; 179 180 public static final int TYPE_NOT_SYNCABLE = 0x100; 181 // A mailbox that holds Messages that are attachments 182 public static final int TYPE_ATTACHMENT = 0x101; 183 184 // Bit field flags; each is defined below 185 // Warning: Do not read these flags until POP/IMAP/EAS all populate them 186 /** No flags set */ 187 public static final int FLAG_NONE = 0; 188 /** Has children in the mailbox hierarchy */ 189 public static final int FLAG_HAS_CHILDREN = 1<<0; 190 /** Children are visible in the UI */ 191 public static final int FLAG_CHILDREN_VISIBLE = 1<<1; 192 /** cannot receive "pushed" mail */ 193 public static final int FLAG_CANT_PUSH = 1<<2; 194 /** can hold emails (i.e. some parent mailboxes cannot themselves contain mail) */ 195 public static final int FLAG_HOLDS_MAIL = 1<<3; 196 /** can be used as a target for moving messages within the account */ 197 public static final int FLAG_ACCEPTS_MOVED_MAIL = 1<<4; 198 /** can be used as a target for appending messages */ 199 public static final int FLAG_ACCEPTS_APPENDED_MAIL = 1<<5; 200 201 // Magic mailbox ID's 202 // NOTE: This is a quick solution for merged mailboxes. I would rather implement this 203 // with a more generic way of packaging and sharing queries between activities 204 public static final long QUERY_ALL_INBOXES = -2; 205 public static final long QUERY_ALL_UNREAD = -3; 206 public static final long QUERY_ALL_FAVORITES = -4; 207 public static final long QUERY_ALL_DRAFTS = -5; 208 public static final long QUERY_ALL_OUTBOX = -6; 209 210 public Mailbox() { 211 mBaseUri = CONTENT_URI; 212 } 213 214 /** 215 * Restore a Mailbox from the database, given its unique id 216 * @param context 217 * @param id 218 * @return the instantiated Mailbox 219 */ 220 public static Mailbox restoreMailboxWithId(Context context, long id) { 221 return EmailContent.restoreContentWithId(context, Mailbox.class, 222 Mailbox.CONTENT_URI, Mailbox.CONTENT_PROJECTION, id); 223 } 224 225 /** 226 * Returns a Mailbox from the database, given its pathname and account id. All mailbox 227 * paths for a particular account must be unique. Paths are stored in the column 228 * {@link MailboxColumns#SERVER_ID} for want of yet another column in the table. 229 * @param context 230 * @param accountId the ID of the account 231 * @param path the fully qualified, remote pathname 232 */ 233 public static Mailbox restoreMailboxForPath(Context context, long accountId, String path) { 234 Cursor c = context.getContentResolver().query( 235 Mailbox.CONTENT_URI, 236 Mailbox.CONTENT_PROJECTION, 237 Mailbox.PATH_AND_ACCOUNT_SELECTION, 238 new String[] { path, Long.toString(accountId) }, 239 null); 240 if (c == null) throw new ProviderUnavailableException(); 241 try { 242 Mailbox mailbox = null; 243 if (c.moveToFirst()) { 244 mailbox = getContent(c, Mailbox.class); 245 if (c.moveToNext()) { 246 Log.w(Logging.LOG_TAG, "Multiple mailboxes named \"" + path + "\""); 247 } 248 } else { 249 Log.i(Logging.LOG_TAG, "Could not find mailbox at \"" + path + "\""); 250 } 251 return mailbox; 252 } finally { 253 c.close(); 254 } 255 } 256 257 @Override 258 public void restore(Cursor cursor) { 259 mBaseUri = CONTENT_URI; 260 mId = cursor.getLong(CONTENT_ID_COLUMN); 261 mDisplayName = cursor.getString(CONTENT_DISPLAY_NAME_COLUMN); 262 mServerId = cursor.getString(CONTENT_SERVER_ID_COLUMN); 263 mParentServerId = cursor.getString(CONTENT_PARENT_SERVER_ID_COLUMN); 264 mParentKey = cursor.getLong(CONTENT_PARENT_KEY_COLUMN); 265 mAccountKey = cursor.getLong(CONTENT_ACCOUNT_KEY_COLUMN); 266 mType = cursor.getInt(CONTENT_TYPE_COLUMN); 267 mDelimiter = cursor.getInt(CONTENT_DELIMITER_COLUMN); 268 mSyncKey = cursor.getString(CONTENT_SYNC_KEY_COLUMN); 269 mSyncLookback = cursor.getInt(CONTENT_SYNC_LOOKBACK_COLUMN); 270 mSyncInterval = cursor.getInt(CONTENT_SYNC_INTERVAL_COLUMN); 271 mSyncTime = cursor.getLong(CONTENT_SYNC_TIME_COLUMN); 272 mFlagVisible = cursor.getInt(CONTENT_FLAG_VISIBLE_COLUMN) == 1; 273 mFlags = cursor.getInt(CONTENT_FLAGS_COLUMN); 274 mVisibleLimit = cursor.getInt(CONTENT_VISIBLE_LIMIT_COLUMN); 275 mSyncStatus = cursor.getString(CONTENT_SYNC_STATUS_COLUMN); 276 mLastSeenMessageKey = cursor.getLong(CONTENT_LAST_SEEN_MESSAGE_KEY_COLUMN); 277 mLastTouchedTime = cursor.getLong(CONTENT_LAST_TOUCHED_TIME_COLUMN); 278 } 279 280 @Override 281 public ContentValues toContentValues() { 282 ContentValues values = new ContentValues(); 283 values.put(MailboxColumns.DISPLAY_NAME, mDisplayName); 284 values.put(MailboxColumns.SERVER_ID, mServerId); 285 values.put(MailboxColumns.PARENT_SERVER_ID, mParentServerId); 286 values.put(MailboxColumns.PARENT_KEY, mParentKey); 287 values.put(MailboxColumns.ACCOUNT_KEY, mAccountKey); 288 values.put(MailboxColumns.TYPE, mType); 289 values.put(MailboxColumns.DELIMITER, mDelimiter); 290 values.put(MailboxColumns.SYNC_KEY, mSyncKey); 291 values.put(MailboxColumns.SYNC_LOOKBACK, mSyncLookback); 292 values.put(MailboxColumns.SYNC_INTERVAL, mSyncInterval); 293 values.put(MailboxColumns.SYNC_TIME, mSyncTime); 294 values.put(MailboxColumns.FLAG_VISIBLE, mFlagVisible); 295 values.put(MailboxColumns.FLAGS, mFlags); 296 values.put(MailboxColumns.VISIBLE_LIMIT, mVisibleLimit); 297 values.put(MailboxColumns.SYNC_STATUS, mSyncStatus); 298 values.put(MailboxColumns.LAST_SEEN_MESSAGE_KEY, mLastSeenMessageKey); 299 values.put(MailboxColumns.LAST_TOUCHED_TIME, mLastTouchedTime); 300 return values; 301 } 302 303 /** 304 * Convenience method to return the id of a given type of Mailbox for a given Account; the 305 * common Mailbox types (Inbox, Outbox, Sent, Drafts, Trash, and Search) are all cached by 306 * EmailProvider; therefore, we warn if the mailbox is not found in the cache 307 * 308 * @param context the caller's context, used to get a ContentResolver 309 * @param accountId the id of the account to be queried 310 * @param type the mailbox type, as defined above 311 * @return the id of the mailbox, or -1 if not found 312 */ 313 public static long findMailboxOfType(Context context, long accountId, int type) { 314 // First use special URI 315 Uri uri = FROM_ACCOUNT_AND_TYPE_URI.buildUpon().appendPath(Long.toString(accountId)) 316 .appendPath(Integer.toString(type)).build(); 317 Cursor c = context.getContentResolver().query(uri, ID_PROJECTION, null, null, null); 318 c.moveToFirst(); 319 Long mailboxId = c.getLong(ID_PROJECTION_COLUMN); 320 if (mailboxId != null && mailboxId.intValue() != 0) { 321 return mailboxId; 322 } else { 323 Log.w(Logging.LOG_TAG, "========== Mailbox of type " + type + " not found in cache??"); 324 } 325 String[] bindArguments = new String[] {Long.toString(type), Long.toString(accountId)}; 326 return Utility.getFirstRowLong(context, Mailbox.CONTENT_URI, 327 ID_PROJECTION, WHERE_TYPE_AND_ACCOUNT_KEY, bindArguments, null, 328 ID_PROJECTION_COLUMN, NO_MAILBOX); 329 } 330 331 /** 332 * Convenience method that returns the mailbox found using the method above 333 */ 334 public static Mailbox restoreMailboxOfType(Context context, long accountId, int type) { 335 long mailboxId = findMailboxOfType(context, accountId, type); 336 if (mailboxId != Mailbox.NO_MAILBOX) { 337 return Mailbox.restoreMailboxWithId(context, mailboxId); 338 } 339 return null; 340 } 341 342 public static int getUnreadCountByAccountAndMailboxType(Context context, long accountId, 343 int type) { 344 return Utility.getFirstRowInt(context, Mailbox.CONTENT_URI, 345 MAILBOX_SUM_OF_UNREAD_COUNT_PROJECTION, 346 ACCOUNT_AND_MAILBOX_TYPE_SELECTION, 347 new String[] { String.valueOf(accountId), String.valueOf(type) }, 348 null, UNREAD_COUNT_COUNT_COLUMN, 0); 349 } 350 351 public static int getUnreadCountByMailboxType(Context context, int type) { 352 return Utility.getFirstRowInt(context, Mailbox.CONTENT_URI, 353 MAILBOX_SUM_OF_UNREAD_COUNT_PROJECTION, 354 MAILBOX_TYPE_SELECTION, 355 new String[] { String.valueOf(type) }, null, UNREAD_COUNT_COUNT_COLUMN, 0); 356 } 357 358 public static int getMessageCountByMailboxType(Context context, int type) { 359 return Utility.getFirstRowInt(context, Mailbox.CONTENT_URI, 360 MAILBOX_SUM_OF_MESSAGE_COUNT_PROJECTION, 361 MAILBOX_TYPE_SELECTION, 362 new String[] { String.valueOf(type) }, null, MESSAGE_COUNT_COUNT_COLUMN, 0); 363 } 364 365 /** 366 * Return the mailbox for a message with a given id 367 * @param context the caller's context 368 * @param messageId the id of the message 369 * @return the mailbox, or null if the mailbox doesn't exist 370 */ 371 public static Mailbox getMailboxForMessageId(Context context, long messageId) { 372 long mailboxId = Message.getKeyColumnLong(context, messageId, 373 MessageColumns.MAILBOX_KEY); 374 if (mailboxId != -1) { 375 return Mailbox.restoreMailboxWithId(context, mailboxId); 376 } 377 return null; 378 } 379 380 /** 381 * @return mailbox type, or -1 if mailbox not found. 382 */ 383 public static int getMailboxType(Context context, long mailboxId) { 384 Uri url = ContentUris.withAppendedId(Mailbox.CONTENT_URI, mailboxId); 385 return Utility.getFirstRowInt(context, url, MAILBOX_TYPE_PROJECTION, 386 null, null, null, MAILBOX_TYPE_TYPE_COLUMN, -1); 387 } 388 389 /** 390 * @return mailbox display name, or null if mailbox not found. 391 */ 392 public static String getDisplayName(Context context, long mailboxId) { 393 Uri url = ContentUris.withAppendedId(Mailbox.CONTENT_URI, mailboxId); 394 return Utility.getFirstRowString(context, url, MAILBOX_DISPLAY_NAME_PROJECTION, 395 null, null, null, MAILBOX_DISPLAY_NAME_COLUMN); 396 } 397 398 /** 399 * @param mailboxId ID of a mailbox. This method accepts magic mailbox IDs, such as 400 * {@link #QUERY_ALL_INBOXES}. (They're all non-refreshable.) 401 * @return true if a mailbox is refreshable. 402 */ 403 public static boolean isRefreshable(Context context, long mailboxId) { 404 if (mailboxId < 0) { 405 return false; // magic mailboxes 406 } 407 switch (getMailboxType(context, mailboxId)) { 408 case -1: // not found 409 case TYPE_DRAFTS: 410 case TYPE_OUTBOX: 411 return false; 412 } 413 return true; 414 } 415 416 /** 417 * @param mailboxId ID of a mailbox. This method DOES NOT accept magic mailbox IDs, such as 418 * {@link #QUERY_ALL_INBOXES} (because only the actual mailbox ID matters here. e.g. 419 * {@link #QUERY_ALL_FAVORITES} can contain ANY kind of messages), so don't pass a negative 420 * value. 421 * @return true if messages in a mailbox can be moved to another mailbox. 422 * This method only checks the mailbox information. It doesn't check its account/protocol, 423 * so it may return true even for POP3 mailbox. 424 */ 425 public static boolean canMoveFrom(Context context, long mailboxId) { 426 if (mailboxId < 0) { 427 throw new IllegalArgumentException(); 428 } 429 Uri url = ContentUris.withAppendedId(Mailbox.CONTENT_URI, mailboxId); 430 int type = Utility.getFirstRowInt(context, url, MAILBOX_TYPE_PROJECTION, 431 null, null, null, MAILBOX_TYPE_TYPE_COLUMN); 432 switch (type) { 433 case TYPE_INBOX: 434 case TYPE_MAIL: 435 case TYPE_TRASH: 436 case TYPE_JUNK: 437 return true; 438 } 439 return false; // TYPE_DRAFTS, TYPE_OUTBOX, TYPE_SENT, etc 440 } 441 442 /** 443 * @return true if messages in a mailbox of a type can be replied/forwarded. 444 */ 445 public static boolean isMailboxTypeReplyAndForwardable(int type) { 446 return (type != TYPE_TRASH) && (type != TYPE_DRAFTS); 447 } 448 449 /** 450 * Returns a set of hashes that can identify this mailbox. These can be used to 451 * determine if any of the fields have been modified. 452 */ 453 public Object[] getHashes() { 454 Object[] hash = new Object[CONTENT_PROJECTION.length]; 455 456 hash[CONTENT_ID_COLUMN] 457 = mId; 458 hash[CONTENT_DISPLAY_NAME_COLUMN] 459 = mDisplayName; 460 hash[CONTENT_SERVER_ID_COLUMN] 461 = mServerId; 462 hash[CONTENT_PARENT_SERVER_ID_COLUMN] 463 = mParentServerId; 464 hash[CONTENT_ACCOUNT_KEY_COLUMN] 465 = mAccountKey; 466 hash[CONTENT_TYPE_COLUMN] 467 = mType; 468 hash[CONTENT_DELIMITER_COLUMN] 469 = mDelimiter; 470 hash[CONTENT_SYNC_KEY_COLUMN] 471 = mSyncKey; 472 hash[CONTENT_SYNC_LOOKBACK_COLUMN] 473 = mSyncLookback; 474 hash[CONTENT_SYNC_INTERVAL_COLUMN] 475 = mSyncInterval; 476 hash[CONTENT_SYNC_TIME_COLUMN] 477 = mSyncTime; 478 hash[CONTENT_FLAG_VISIBLE_COLUMN] 479 = mFlagVisible; 480 hash[CONTENT_FLAGS_COLUMN] 481 = mFlags; 482 hash[CONTENT_VISIBLE_LIMIT_COLUMN] 483 = mVisibleLimit; 484 hash[CONTENT_SYNC_STATUS_COLUMN] 485 = mSyncStatus; 486 hash[CONTENT_PARENT_KEY_COLUMN] 487 = mParentKey; 488 hash[CONTENT_LAST_SEEN_MESSAGE_KEY_COLUMN] 489 = mLastSeenMessageKey; 490 hash[CONTENT_LAST_TOUCHED_TIME_COLUMN] 491 = mLastTouchedTime; 492 return hash; 493 } 494 495 // Parcelable 496 @Override 497 public int describeContents() { 498 return 0; 499 } 500 501 // Parcelable 502 @Override 503 public void writeToParcel(Parcel dest, int flags) { 504 dest.writeParcelable(mBaseUri, flags); 505 dest.writeLong(mId); 506 dest.writeString(mDisplayName); 507 dest.writeString(mServerId); 508 dest.writeString(mParentServerId); 509 dest.writeLong(mParentKey); 510 dest.writeLong(mAccountKey); 511 dest.writeInt(mType); 512 dest.writeInt(mDelimiter); 513 dest.writeString(mSyncKey); 514 dest.writeInt(mSyncLookback); 515 dest.writeInt(mSyncInterval); 516 dest.writeLong(mSyncTime); 517 dest.writeInt(mFlagVisible ? 1 : 0); 518 dest.writeInt(mFlags); 519 dest.writeInt(mVisibleLimit); 520 dest.writeString(mSyncStatus); 521 dest.writeLong(mLastSeenMessageKey); 522 dest.writeLong(mLastTouchedTime); 523 } 524 525 public Mailbox(Parcel in) { 526 mBaseUri = in.readParcelable(null); 527 mId = in.readLong(); 528 mDisplayName = in.readString(); 529 mServerId = in.readString(); 530 mParentServerId = in.readString(); 531 mParentKey = in.readLong(); 532 mAccountKey = in.readLong(); 533 mType = in.readInt(); 534 mDelimiter = in.readInt(); 535 mSyncKey = in.readString(); 536 mSyncLookback = in.readInt(); 537 mSyncInterval = in.readInt(); 538 mSyncTime = in.readLong(); 539 mFlagVisible = in.readInt() == 1; 540 mFlags = in.readInt(); 541 mVisibleLimit = in.readInt(); 542 mSyncStatus = in.readString(); 543 mLastSeenMessageKey = in.readLong(); 544 mLastTouchedTime = in.readLong(); 545 } 546 547 public static final Parcelable.Creator<Mailbox> CREATOR = new Parcelable.Creator<Mailbox>() { 548 @Override 549 public Mailbox createFromParcel(Parcel source) { 550 return new Mailbox(source); 551 } 552 553 @Override 554 public Mailbox[] newArray(int size) { 555 return new Mailbox[size]; 556 } 557 }; 558} 559