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