1732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang/**
2732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang * Copyright (c) 2012, Google Inc.
3732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang *
4732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang * Licensed under the Apache License, Version 2.0 (the "License");
5732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang * you may not use this file except in compliance with the License.
6732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang * You may obtain a copy of the License at
7732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang *
8732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang *     http://www.apache.org/licenses/LICENSE-2.0
9732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang *
10732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang * Unless required by applicable law or agreed to in writing, software
11732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang * distributed under the License is distributed on an "AS IS" BASIS,
12732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang * See the License for the specific language governing permissions and
14732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang * limitations under the License.
15732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang */
16732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang
17732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huangpackage com.android.mail.providers;
18732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang
191bca265b7a8a3f9ea08e0ae51eeb145f0883a266Andy Huangimport android.content.ContentValues;
20bf9508d3877d05742b2f5d23e1780366d3e1aa2eMindy Pereiraimport android.content.Context;
21732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huangimport android.database.Cursor;
22732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huangimport android.net.Uri;
237f39bbd358f7003a72ae2b480dfe38a84e830e5fAndy Huangimport android.os.Bundle;
24732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huangimport android.os.Parcel;
25732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huangimport android.os.Parcelable;
26e623a0f6e3caa9cafec913cf826e946628833517Andy Huangimport android.provider.BaseColumns;
275c765b9c5dd8a9a9421260ba8b46d06073391c73Mindy Pereiraimport android.text.TextUtils;
28732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang
29bf9508d3877d05742b2f5d23e1780366d3e1aa2eMindy Pereiraimport com.android.mail.R;
305f578144cc01738d5f9988d61674a643df19fdaeScott Kennedyimport com.android.mail.browse.ConversationCursor;
315f578144cc01738d5f9988d61674a643df19fdaeScott Kennedyimport com.android.mail.content.CursorCreator;
32ebdfd98264104cb5a6888acd663970b7c0b31382Mindy Pereiraimport com.android.mail.providers.UIProvider.ConversationColumns;
335f578144cc01738d5f9988d61674a643df19fdaeScott Kennedyimport com.android.mail.ui.ConversationCursorLoader;
349e4ca7993213d296043d20fe9cf4e166b5d595e8Andy Huangimport com.android.mail.utils.LogTag;
359e4ca7993213d296043d20fe9cf4e166b5d595e8Andy Huangimport com.android.mail.utils.LogUtils;
36a6b671dd9f5ba358a05888b3ab3bf1c5cb5cf493Marc Blankimport com.google.common.collect.ImmutableList;
37d198fa7ddb2d0c730847af34f06aa2e940b2537dMark Weiimport com.google.common.collect.Lists;
38a6b671dd9f5ba358a05888b3ab3bf1c5cb5cf493Marc Blank
3900ffece08e94ff5774b2a53c0adeb2f3d0815d66Mindy Pereiraimport java.util.ArrayList;
40440fe79194314b25ef5829702494735ce2f1e2e8Vikram Aggarwalimport java.util.Collection;
41440fe79194314b25ef5829702494735ce2f1e2e8Vikram Aggarwalimport java.util.Collections;
42b2033d855ab0f13e253e5403ce25989bcbc49488Andy Huangimport java.util.List;
43440fe79194314b25ef5829702494735ce2f1e2e8Vikram Aggarwal
44732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huangpublic class Conversation implements Parcelable {
45f892f0a57d5c24b09fdc805f0fe2007ecd0d0e91Marc Blank    public static final int NO_POSITION = -1;
46732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang
479e4ca7993213d296043d20fe9cf4e166b5d595e8Andy Huang    private static final String LOG_TAG = LogTag.getLogTag();
489e4ca7993213d296043d20fe9cf4e166b5d595e8Andy Huang
49820f051b37b45b3e3729bda5c4302a879ee6aa4dPaul Westbrook    private static final String EMPTY_STRING = "";
50820f051b37b45b3e3729bda5c4302a879ee6aa4dPaul Westbrook
51e623a0f6e3caa9cafec913cf826e946628833517Andy Huang    /**
52e623a0f6e3caa9cafec913cf826e946628833517Andy Huang     * @see BaseColumns#_ID
53e623a0f6e3caa9cafec913cf826e946628833517Andy Huang     */
54732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang    public long id;
55e623a0f6e3caa9cafec913cf826e946628833517Andy Huang    /**
56e623a0f6e3caa9cafec913cf826e946628833517Andy Huang     * @see UIProvider.ConversationColumns#URI
57e623a0f6e3caa9cafec913cf826e946628833517Andy Huang     */
58c43bc0a606e41144a780c4f873b5450e0ede0c91Marc Blank    public Uri uri;
59e623a0f6e3caa9cafec913cf826e946628833517Andy Huang    /**
60e623a0f6e3caa9cafec913cf826e946628833517Andy Huang     * @see UIProvider.ConversationColumns#SUBJECT
61e623a0f6e3caa9cafec913cf826e946628833517Andy Huang     */
62732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang    public String subject;
63e623a0f6e3caa9cafec913cf826e946628833517Andy Huang    /**
64e623a0f6e3caa9cafec913cf826e946628833517Andy Huang     * @see UIProvider.ConversationColumns#DATE_RECEIVED_MS
65e623a0f6e3caa9cafec913cf826e946628833517Andy Huang     */
66732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang    public long dateMs;
67e623a0f6e3caa9cafec913cf826e946628833517Andy Huang    /**
68e623a0f6e3caa9cafec913cf826e946628833517Andy Huang     * @see UIProvider.ConversationColumns#SNIPPET
69e623a0f6e3caa9cafec913cf826e946628833517Andy Huang     */
70aa1f945612847bc4cf5c8909b8acfab4b5ecf54eMindy Pereira    @Deprecated
71732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang    public String snippet;
72e623a0f6e3caa9cafec913cf826e946628833517Andy Huang    /**
73e623a0f6e3caa9cafec913cf826e946628833517Andy Huang     * @see UIProvider.ConversationColumns#HAS_ATTACHMENTS
74e623a0f6e3caa9cafec913cf826e946628833517Andy Huang     */
75732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang    public boolean hasAttachments;
76e623a0f6e3caa9cafec913cf826e946628833517Andy Huang    /**
77479505d71969e26b0785d8e0e1b81108731cf827Mark Wei     * Union of attachmentPreviewUri0 and attachmentPreviewUri1
78479505d71969e26b0785d8e0e1b81108731cf827Mark Wei     */
79479505d71969e26b0785d8e0e1b81108731cf827Mark Wei    public transient ArrayList<String> attachmentPreviews;
80479505d71969e26b0785d8e0e1b81108731cf827Mark Wei    /**
81479505d71969e26b0785d8e0e1b81108731cf827Mark Wei     * @see UIProvider.ConversationColumns#ATTACHMENT_PREVIEW_URI0
82479505d71969e26b0785d8e0e1b81108731cf827Mark Wei     */
83479505d71969e26b0785d8e0e1b81108731cf827Mark Wei    public String attachmentPreviewUri0;
84479505d71969e26b0785d8e0e1b81108731cf827Mark Wei    /**
85479505d71969e26b0785d8e0e1b81108731cf827Mark Wei     * @see UIProvider.ConversationColumns#ATTACHMENT_PREVIEW_URI1
86479505d71969e26b0785d8e0e1b81108731cf827Mark Wei     */
87479505d71969e26b0785d8e0e1b81108731cf827Mark Wei    public String attachmentPreviewUri1;
88479505d71969e26b0785d8e0e1b81108731cf827Mark Wei    /**
89479505d71969e26b0785d8e0e1b81108731cf827Mark Wei     * @see UIProvider.ConversationColumns#ATTACHMENT_PREVIEW_STATES
90479505d71969e26b0785d8e0e1b81108731cf827Mark Wei     */
91479505d71969e26b0785d8e0e1b81108731cf827Mark Wei    public int attachmentPreviewStates;
92479505d71969e26b0785d8e0e1b81108731cf827Mark Wei    /**
93479505d71969e26b0785d8e0e1b81108731cf827Mark Wei     * @see UIProvider.ConversationColumns#ATTACHMENT_PREVIEWS_COUNT
94479505d71969e26b0785d8e0e1b81108731cf827Mark Wei     */
95479505d71969e26b0785d8e0e1b81108731cf827Mark Wei    public int attachmentPreviewsCount;
96479505d71969e26b0785d8e0e1b81108731cf827Mark Wei    /**
97e623a0f6e3caa9cafec913cf826e946628833517Andy Huang     * @see UIProvider.ConversationColumns#MESSAGE_LIST_URI
98e623a0f6e3caa9cafec913cf826e946628833517Andy Huang     */
99cfb7f33ff8ef9dc60b9143af32de64c7a3d71f36Mindy Pereira    public Uri messageListUri;
100e623a0f6e3caa9cafec913cf826e946628833517Andy Huang    /**
101e623a0f6e3caa9cafec913cf826e946628833517Andy Huang     * @see UIProvider.ConversationColumns#SENDER_INFO
102e623a0f6e3caa9cafec913cf826e946628833517Andy Huang     */
103648df3f0b0ebcd3c4adf907d70ff0938e5dfc78fMindy Pereira    @Deprecated
1044db59c58c0af9f44d95a12dbe21322bed58cc518Mindy Pereira    public String senders;
105e623a0f6e3caa9cafec913cf826e946628833517Andy Huang    /**
106e623a0f6e3caa9cafec913cf826e946628833517Andy Huang     * @see UIProvider.ConversationColumns#NUM_MESSAGES
107e623a0f6e3caa9cafec913cf826e946628833517Andy Huang     */
1080972e0793cc321670391d063348aecb5031b2677Mindy Pereira    private int numMessages;
109e623a0f6e3caa9cafec913cf826e946628833517Andy Huang    /**
110e623a0f6e3caa9cafec913cf826e946628833517Andy Huang     * @see UIProvider.ConversationColumns#NUM_DRAFTS
111e623a0f6e3caa9cafec913cf826e946628833517Andy Huang     */
1120972e0793cc321670391d063348aecb5031b2677Mindy Pereira    private int numDrafts;
113e623a0f6e3caa9cafec913cf826e946628833517Andy Huang    /**
114e623a0f6e3caa9cafec913cf826e946628833517Andy Huang     * @see UIProvider.ConversationColumns#SENDING_STATE
115e623a0f6e3caa9cafec913cf826e946628833517Andy Huang     */
1164db59c58c0af9f44d95a12dbe21322bed58cc518Mindy Pereira    public int sendingState;
117e623a0f6e3caa9cafec913cf826e946628833517Andy Huang    /**
118e623a0f6e3caa9cafec913cf826e946628833517Andy Huang     * @see UIProvider.ConversationColumns#PRIORITY
119e623a0f6e3caa9cafec913cf826e946628833517Andy Huang     */
1204db59c58c0af9f44d95a12dbe21322bed58cc518Mindy Pereira    public int priority;
121e623a0f6e3caa9cafec913cf826e946628833517Andy Huang    /**
122e623a0f6e3caa9cafec913cf826e946628833517Andy Huang     * @see UIProvider.ConversationColumns#READ
123e623a0f6e3caa9cafec913cf826e946628833517Andy Huang     */
124c8a994227b9c686d88ee05840544162711a85712Marc Blank    public boolean read;
125e623a0f6e3caa9cafec913cf826e946628833517Andy Huang    /**
126d5edd2d02649dffb40065fdb6a16acf91552b800Scott Kennedy     * @see UIProvider.ConversationColumns#SEEN
127d5edd2d02649dffb40065fdb6a16acf91552b800Scott Kennedy     */
128d5edd2d02649dffb40065fdb6a16acf91552b800Scott Kennedy    public boolean seen;
129d5edd2d02649dffb40065fdb6a16acf91552b800Scott Kennedy    /**
130e623a0f6e3caa9cafec913cf826e946628833517Andy Huang     * @see UIProvider.ConversationColumns#STARRED
131e623a0f6e3caa9cafec913cf826e946628833517Andy Huang     */
132c8a994227b9c686d88ee05840544162711a85712Marc Blank    public boolean starred;
133e623a0f6e3caa9cafec913cf826e946628833517Andy Huang    /**
134e623a0f6e3caa9cafec913cf826e946628833517Andy Huang     * @see UIProvider.ConversationColumns#RAW_FOLDERS
135e623a0f6e3caa9cafec913cf826e946628833517Andy Huang     */
136b2033d855ab0f13e253e5403ce25989bcbc49488Andy Huang    private FolderList rawFolders;
137e623a0f6e3caa9cafec913cf826e946628833517Andy Huang    /**
138e623a0f6e3caa9cafec913cf826e946628833517Andy Huang     * @see UIProvider.ConversationColumns#FLAGS
139e623a0f6e3caa9cafec913cf826e946628833517Andy Huang     */
14022657529437c160dec072115c5982409306c1313Mindy Pereira    public int convFlags;
141e623a0f6e3caa9cafec913cf826e946628833517Andy Huang    /**
142e623a0f6e3caa9cafec913cf826e946628833517Andy Huang     * @see UIProvider.ConversationColumns#PERSONAL_LEVEL
143e623a0f6e3caa9cafec913cf826e946628833517Andy Huang     */
14422657529437c160dec072115c5982409306c1313Mindy Pereira    public int personalLevel;
145e623a0f6e3caa9cafec913cf826e946628833517Andy Huang    /**
146e623a0f6e3caa9cafec913cf826e946628833517Andy Huang     * @see UIProvider.ConversationColumns#SPAM
147e623a0f6e3caa9cafec913cf826e946628833517Andy Huang     */
148863e44160d9175023d30e7e225ecb69ad3892eecMindy Pereira    public boolean spam;
149e623a0f6e3caa9cafec913cf826e946628833517Andy Huang    /**
150e623a0f6e3caa9cafec913cf826e946628833517Andy Huang     * @see UIProvider.ConversationColumns#MUTED
151e623a0f6e3caa9cafec913cf826e946628833517Andy Huang     */
152863e44160d9175023d30e7e225ecb69ad3892eecMindy Pereira    public boolean muted;
153e623a0f6e3caa9cafec913cf826e946628833517Andy Huang    /**
15476b2062b8c6d18a7b3a05292c385b47b0fcbd09fPaul Westbrook     * @see UIProvider.ConversationColumns#PHISHING
15576b2062b8c6d18a7b3a05292c385b47b0fcbd09fPaul Westbrook     */
15676b2062b8c6d18a7b3a05292c385b47b0fcbd09fPaul Westbrook    public boolean phishing;
15776b2062b8c6d18a7b3a05292c385b47b0fcbd09fPaul Westbrook    /**
158e623a0f6e3caa9cafec913cf826e946628833517Andy Huang     * @see UIProvider.ConversationColumns#COLOR
159e623a0f6e3caa9cafec913cf826e946628833517Andy Huang     */
16092939fc7b40a56e17fb0d2fde987133ca1614e29Marc Blank    public int color;
161e623a0f6e3caa9cafec913cf826e946628833517Andy Huang    /**
162e623a0f6e3caa9cafec913cf826e946628833517Andy Huang     * @see UIProvider.ConversationColumns#ACCOUNT_URI
163e623a0f6e3caa9cafec913cf826e946628833517Andy Huang     */
164a6b671dd9f5ba358a05888b3ab3bf1c5cb5cf493Marc Blank    public Uri accountUri;
165648df3f0b0ebcd3c4adf907d70ff0938e5dfc78fMindy Pereira    /**
166648df3f0b0ebcd3c4adf907d70ff0938e5dfc78fMindy Pereira     * @see UIProvider.ConversationColumns#CONVERSATION_INFO
167648df3f0b0ebcd3c4adf907d70ff0938e5dfc78fMindy Pereira     */
168648df3f0b0ebcd3c4adf907d70ff0938e5dfc78fMindy Pereira    public ConversationInfo conversationInfo;
16941dca185f7683b36bdafd9520c0648c897a95834Paul Westbrook    /**
170cebcc64fbd69618ff89f9fac0bfe9b9e7d7ce104Paul Westbrook     * @see UIProvider.ConversationColumns#CONVERSATION_BASE_URI
17141dca185f7683b36bdafd9520c0648c897a95834Paul Westbrook     */
17241dca185f7683b36bdafd9520c0648c897a95834Paul Westbrook    public Uri conversationBaseUri;
173f98bc898cbc7014a203c35a13427d3f949bce705Andy Huang    /**
174f98bc898cbc7014a203c35a13427d3f949bce705Andy Huang     * @see UIProvider.ConversationColumns#REMOTE
175f98bc898cbc7014a203c35a13427d3f949bce705Andy Huang     */
176f98bc898cbc7014a203c35a13427d3f949bce705Andy Huang    public boolean isRemote;
17722657529437c160dec072115c5982409306c1313Mindy Pereira
178dbb587f15c723ae80edb33f65c29cc2b6c15eba0Scott Kennedy    /**
179dbb587f15c723ae80edb33f65c29cc2b6c15eba0Scott Kennedy     * Used within the UI to indicate the adapter position of this conversation
180dbb587f15c723ae80edb33f65c29cc2b6c15eba0Scott Kennedy     *
181dbb587f15c723ae80edb33f65c29cc2b6c15eba0Scott Kennedy     * @deprecated Keeping this in sync with the desired value is a not always done properly, is a
182dbb587f15c723ae80edb33f65c29cc2b6c15eba0Scott Kennedy     *             source of bugs, and is a bad idea in general. Do not trust this value. Try to
183dbb587f15c723ae80edb33f65c29cc2b6c15eba0Scott Kennedy     *             migrate code away from using it.
184dbb587f15c723ae80edb33f65c29cc2b6c15eba0Scott Kennedy     */
185dbb587f15c723ae80edb33f65c29cc2b6c15eba0Scott Kennedy    @Deprecated
186f892f0a57d5c24b09fdc805f0fe2007ecd0d0e91Marc Blank    public transient int position;
187648df3f0b0ebcd3c4adf907d70ff0938e5dfc78fMindy Pereira    // Used within the UI to indicate that a Conversation should be removed from
188648df3f0b0ebcd3c4adf907d70ff0938e5dfc78fMindy Pereira    // the ConversationCursor when executing an update, e.g. the the
189648df3f0b0ebcd3c4adf907d70ff0938e5dfc78fMindy Pereira    // Conversation is no longer in the ConversationList for the current folder,
190648df3f0b0ebcd3c4adf907d70ff0938e5dfc78fMindy Pereira    // that is it's now in some other folder(s)
191ce53818e1e185a845bd2f7f601c20e7085b40725Marc Blank    public transient boolean localDeleteOnUpdate;
192732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang
193cd5c5eeae167885ffa2959c200233fea2f39c5f7Andy Huang    private transient boolean viewed;
194cd5c5eeae167885ffa2959c200233fea2f39c5f7Andy Huang
1952909b7442130800d6c6c20c1227d65295262f03emindyp    private static String sSubjectAndSnippet;
1962909b7442130800d6c6c20c1227d65295262f03emindyp
197e1d1b07cdb0026097eb80f6c2912a16353aacec1Marc Blank    // Constituents of convFlags below
198648df3f0b0ebcd3c4adf907d70ff0938e5dfc78fMindy Pereira    // Flag indicating that the item has been deleted, but will continue being
199648df3f0b0ebcd3c4adf907d70ff0938e5dfc78fMindy Pereira    // shown in the list Delete/Archive of a mostly-dead item will NOT propagate
200648df3f0b0ebcd3c4adf907d70ff0938e5dfc78fMindy Pereira    // the delete/archive, but WILL remove the item from the cursor
201e1d1b07cdb0026097eb80f6c2912a16353aacec1Marc Blank    public static final int FLAG_MOSTLY_DEAD = 1 << 0;
202e1d1b07cdb0026097eb80f6c2912a16353aacec1Marc Blank
203440fe79194314b25ef5829702494735ce2f1e2e8Vikram Aggarwal    /** An immutable, empty conversation list */
204440fe79194314b25ef5829702494735ce2f1e2e8Vikram Aggarwal    public static final Collection<Conversation> EMPTY = Collections.emptyList();
205440fe79194314b25ef5829702494735ce2f1e2e8Vikram Aggarwal
206732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang    @Override
207732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang    public int describeContents() {
208732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang        return 0;
209732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang    }
210732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang
211732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang    @Override
212732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang    public void writeToParcel(Parcel dest, int flags) {
213732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang        dest.writeLong(id);
214c43bc0a606e41144a780c4f873b5450e0ede0c91Marc Blank        dest.writeParcelable(uri, flags);
215732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang        dest.writeString(subject);
216732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang        dest.writeLong(dateMs);
217732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang        dest.writeString(snippet);
218f98bc898cbc7014a203c35a13427d3f949bce705Andy Huang        dest.writeInt(hasAttachments ? 1 : 0);
219cfb7f33ff8ef9dc60b9143af32de64c7a3d71f36Mindy Pereira        dest.writeParcelable(messageListUri, 0);
2204db59c58c0af9f44d95a12dbe21322bed58cc518Mindy Pereira        dest.writeString(senders);
2214db59c58c0af9f44d95a12dbe21322bed58cc518Mindy Pereira        dest.writeInt(numMessages);
2224db59c58c0af9f44d95a12dbe21322bed58cc518Mindy Pereira        dest.writeInt(numDrafts);
2234db59c58c0af9f44d95a12dbe21322bed58cc518Mindy Pereira        dest.writeInt(sendingState);
2244db59c58c0af9f44d95a12dbe21322bed58cc518Mindy Pereira        dest.writeInt(priority);
225f98bc898cbc7014a203c35a13427d3f949bce705Andy Huang        dest.writeInt(read ? 1 : 0);
226d5edd2d02649dffb40065fdb6a16acf91552b800Scott Kennedy        dest.writeInt(seen ? 1 : 0);
227f98bc898cbc7014a203c35a13427d3f949bce705Andy Huang        dest.writeInt(starred ? 1 : 0);
228b2033d855ab0f13e253e5403ce25989bcbc49488Andy Huang        dest.writeParcelable(rawFolders, 0);
22922657529437c160dec072115c5982409306c1313Mindy Pereira        dest.writeInt(convFlags);
23022657529437c160dec072115c5982409306c1313Mindy Pereira        dest.writeInt(personalLevel);
231863e44160d9175023d30e7e225ecb69ad3892eecMindy Pereira        dest.writeInt(spam ? 1 : 0);
23276b2062b8c6d18a7b3a05292c385b47b0fcbd09fPaul Westbrook        dest.writeInt(phishing ? 1 : 0);
233863e44160d9175023d30e7e225ecb69ad3892eecMindy Pereira        dest.writeInt(muted ? 1 : 0);
23492939fc7b40a56e17fb0d2fde987133ca1614e29Marc Blank        dest.writeInt(color);
235a6b671dd9f5ba358a05888b3ab3bf1c5cb5cf493Marc Blank        dest.writeParcelable(accountUri, 0);
236351ad4e87e0b0b98df9ca88266a8a63541dc5a81Andy Huang        dest.writeParcelable(conversationInfo, 0);
23741dca185f7683b36bdafd9520c0648c897a95834Paul Westbrook        dest.writeParcelable(conversationBaseUri, 0);
238f98bc898cbc7014a203c35a13427d3f949bce705Andy Huang        dest.writeInt(isRemote ? 1 : 0);
239479505d71969e26b0785d8e0e1b81108731cf827Mark Wei        dest.writeString(attachmentPreviewUri0);
240479505d71969e26b0785d8e0e1b81108731cf827Mark Wei        dest.writeString(attachmentPreviewUri1);
241479505d71969e26b0785d8e0e1b81108731cf827Mark Wei        dest.writeInt(attachmentPreviewStates);
242479505d71969e26b0785d8e0e1b81108731cf827Mark Wei        dest.writeInt(attachmentPreviewsCount);
243732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang    }
244732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang
245351ad4e87e0b0b98df9ca88266a8a63541dc5a81Andy Huang    private Conversation(Parcel in, ClassLoader loader) {
246732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang        id = in.readLong();
247c43bc0a606e41144a780c4f873b5450e0ede0c91Marc Blank        uri = in.readParcelable(null);
248732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang        subject = in.readString();
249732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang        dateMs = in.readLong();
250732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang        snippet = in.readString();
251f98bc898cbc7014a203c35a13427d3f949bce705Andy Huang        hasAttachments = (in.readInt() != 0);
252cfb7f33ff8ef9dc60b9143af32de64c7a3d71f36Mindy Pereira        messageListUri = in.readParcelable(null);
253820f051b37b45b3e3729bda5c4302a879ee6aa4dPaul Westbrook        senders = emptyIfNull(in.readString());
2544db59c58c0af9f44d95a12dbe21322bed58cc518Mindy Pereira        numMessages = in.readInt();
2554db59c58c0af9f44d95a12dbe21322bed58cc518Mindy Pereira        numDrafts = in.readInt();
2564db59c58c0af9f44d95a12dbe21322bed58cc518Mindy Pereira        sendingState = in.readInt();
2574db59c58c0af9f44d95a12dbe21322bed58cc518Mindy Pereira        priority = in.readInt();
258f98bc898cbc7014a203c35a13427d3f949bce705Andy Huang        read = (in.readInt() != 0);
259d5edd2d02649dffb40065fdb6a16acf91552b800Scott Kennedy        seen = (in.readInt() != 0);
260f98bc898cbc7014a203c35a13427d3f949bce705Andy Huang        starred = (in.readInt() != 0);
261b2033d855ab0f13e253e5403ce25989bcbc49488Andy Huang        rawFolders = in.readParcelable(loader);
26222657529437c160dec072115c5982409306c1313Mindy Pereira        convFlags = in.readInt();
26322657529437c160dec072115c5982409306c1313Mindy Pereira        personalLevel = in.readInt();
264863e44160d9175023d30e7e225ecb69ad3892eecMindy Pereira        spam = in.readInt() != 0;
26576b2062b8c6d18a7b3a05292c385b47b0fcbd09fPaul Westbrook        phishing = in.readInt() != 0;
266863e44160d9175023d30e7e225ecb69ad3892eecMindy Pereira        muted = in.readInt() != 0;
26792939fc7b40a56e17fb0d2fde987133ca1614e29Marc Blank        color = in.readInt();
268a6b671dd9f5ba358a05888b3ab3bf1c5cb5cf493Marc Blank        accountUri = in.readParcelable(null);
269f892f0a57d5c24b09fdc805f0fe2007ecd0d0e91Marc Blank        position = NO_POSITION;
270ce53818e1e185a845bd2f7f601c20e7085b40725Marc Blank        localDeleteOnUpdate = false;
271351ad4e87e0b0b98df9ca88266a8a63541dc5a81Andy Huang        conversationInfo = in.readParcelable(loader);
27241dca185f7683b36bdafd9520c0648c897a95834Paul Westbrook        conversationBaseUri = in.readParcelable(null);
273f98bc898cbc7014a203c35a13427d3f949bce705Andy Huang        isRemote = in.readInt() != 0;
274479505d71969e26b0785d8e0e1b81108731cf827Mark Wei        attachmentPreviews = null;
275479505d71969e26b0785d8e0e1b81108731cf827Mark Wei        attachmentPreviewUri0 = in.readString();
276479505d71969e26b0785d8e0e1b81108731cf827Mark Wei        attachmentPreviewUri1 = in.readString();
277479505d71969e26b0785d8e0e1b81108731cf827Mark Wei        attachmentPreviewStates = in.readInt();
278479505d71969e26b0785d8e0e1b81108731cf827Mark Wei        attachmentPreviewsCount = in.readInt();
279732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang    }
280732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang
281732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang    @Override
282732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang    public String toString() {
2839e4ca7993213d296043d20fe9cf4e166b5d595e8Andy Huang        // log extra info at DEBUG level or finer
2849e4ca7993213d296043d20fe9cf4e166b5d595e8Andy Huang        final StringBuilder sb = new StringBuilder("[conversation id=");
2859e4ca7993213d296043d20fe9cf4e166b5d595e8Andy Huang        sb.append(id);
2869e4ca7993213d296043d20fe9cf4e166b5d595e8Andy Huang        if (LogUtils.isLoggable(LOG_TAG, LogUtils.DEBUG)) {
2879e4ca7993213d296043d20fe9cf4e166b5d595e8Andy Huang            sb.append(", subject=");
2889e4ca7993213d296043d20fe9cf4e166b5d595e8Andy Huang            sb.append(subject);
2899e4ca7993213d296043d20fe9cf4e166b5d595e8Andy Huang        }
2909e4ca7993213d296043d20fe9cf4e166b5d595e8Andy Huang        sb.append("]");
2919e4ca7993213d296043d20fe9cf4e166b5d595e8Andy Huang        return sb.toString();
292732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang    }
293732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang
294351ad4e87e0b0b98df9ca88266a8a63541dc5a81Andy Huang    public static final ClassLoaderCreator<Conversation> CREATOR =
295351ad4e87e0b0b98df9ca88266a8a63541dc5a81Andy Huang            new ClassLoaderCreator<Conversation>() {
296732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang
297732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang        @Override
298732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang        public Conversation createFromParcel(Parcel source) {
299351ad4e87e0b0b98df9ca88266a8a63541dc5a81Andy Huang            return new Conversation(source, null);
300351ad4e87e0b0b98df9ca88266a8a63541dc5a81Andy Huang        }
301351ad4e87e0b0b98df9ca88266a8a63541dc5a81Andy Huang
302351ad4e87e0b0b98df9ca88266a8a63541dc5a81Andy Huang        @Override
303351ad4e87e0b0b98df9ca88266a8a63541dc5a81Andy Huang        public Conversation createFromParcel(Parcel source, ClassLoader loader) {
304351ad4e87e0b0b98df9ca88266a8a63541dc5a81Andy Huang            return new Conversation(source, loader);
305732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang        }
306732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang
307732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang        @Override
308732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang        public Conversation[] newArray(int size) {
309732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang            return new Conversation[size];
310732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang        }
311732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang
312732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang    };
313732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang
314acf6039a23382f18c35f6b487d90d53cb67b5858Mindy Pereira    public static final Uri MOVE_CONVERSATIONS_URI = Uri.parse("content://moveconversations");
315acf6039a23382f18c35f6b487d90d53cb67b5858Mindy Pereira
316ebdfd98264104cb5a6888acd663970b7c0b31382Mindy Pereira    /**
317ae7e6a0786a2d890b77c783d7ac39a90523b8154mindyp     * The column that needs to be updated to change the folders for a conversation.
318ebdfd98264104cb5a6888acd663970b7c0b31382Mindy Pereira     */
31900ffece08e94ff5774b2a53c0adeb2f3d0815d66Mindy Pereira    public static final String UPDATE_FOLDER_COLUMN = ConversationColumns.RAW_FOLDERS;
320ebdfd98264104cb5a6888acd663970b7c0b31382Mindy Pereira
321a831b2f1ba6d3c18d5e54563df8bae1f589c4257Mindy Pereira    public Conversation(Cursor cursor) {
322732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang        if (cursor != null) {
323732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang            id = cursor.getLong(UIProvider.CONVERSATION_ID_COLUMN);
324c43bc0a606e41144a780c4f873b5450e0ede0c91Marc Blank            uri = Uri.parse(cursor.getString(UIProvider.CONVERSATION_URI_COLUMN));
325732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang            dateMs = cursor.getLong(UIProvider.CONVERSATION_DATE_RECEIVED_MS_COLUMN);
326732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang            subject = cursor.getString(UIProvider.CONVERSATION_SUBJECT_COLUMN);
327374863eeb0ee37f1ca7d57840e6f02aaa052e284Marc Blank            // Don't allow null subject
328374863eeb0ee37f1ca7d57840e6f02aaa052e284Marc Blank            if (subject == null) {
329374863eeb0ee37f1ca7d57840e6f02aaa052e284Marc Blank                subject = "";
330374863eeb0ee37f1ca7d57840e6f02aaa052e284Marc Blank            }
33187d535fe423d782c3a0343c649330d309976f655Mindy Pereira            hasAttachments = cursor.getInt(UIProvider.CONVERSATION_HAS_ATTACHMENTS_COLUMN) != 0;
332648df3f0b0ebcd3c4adf907d70ff0938e5dfc78fMindy Pereira            String messageList = cursor.getString(UIProvider.CONVERSATION_MESSAGE_LIST_URI_COLUMN);
3335c765b9c5dd8a9a9421260ba8b46d06073391c73Mindy Pereira            messageListUri = !TextUtils.isEmpty(messageList) ? Uri.parse(messageList) : null;
3344db59c58c0af9f44d95a12dbe21322bed58cc518Mindy Pereira            sendingState = cursor.getInt(UIProvider.CONVERSATION_SENDING_STATE_COLUMN);
3354db59c58c0af9f44d95a12dbe21322bed58cc518Mindy Pereira            priority = cursor.getInt(UIProvider.CONVERSATION_PRIORITY_COLUMN);
33687d535fe423d782c3a0343c649330d309976f655Mindy Pereira            read = cursor.getInt(UIProvider.CONVERSATION_READ_COLUMN) != 0;
337d5edd2d02649dffb40065fdb6a16acf91552b800Scott Kennedy            seen = cursor.getInt(UIProvider.CONVERSATION_SEEN_COLUMN) != 0;
33887d535fe423d782c3a0343c649330d309976f655Mindy Pereira            starred = cursor.getInt(UIProvider.CONVERSATION_STARRED_COLUMN) != 0;
3397f39bbd358f7003a72ae2b480dfe38a84e830e5fAndy Huang            rawFolders = readRawFolders(cursor);
34022657529437c160dec072115c5982409306c1313Mindy Pereira            convFlags = cursor.getInt(UIProvider.CONVERSATION_FLAGS_COLUMN);
34122657529437c160dec072115c5982409306c1313Mindy Pereira            personalLevel = cursor.getInt(UIProvider.CONVERSATION_PERSONAL_LEVEL_COLUMN);
342863e44160d9175023d30e7e225ecb69ad3892eecMindy Pereira            spam = cursor.getInt(UIProvider.CONVERSATION_IS_SPAM_COLUMN) != 0;
34376b2062b8c6d18a7b3a05292c385b47b0fcbd09fPaul Westbrook            phishing = cursor.getInt(UIProvider.CONVERSATION_IS_PHISHING_COLUMN) != 0;
344863e44160d9175023d30e7e225ecb69ad3892eecMindy Pereira            muted = cursor.getInt(UIProvider.CONVERSATION_MUTED_COLUMN) != 0;
34592939fc7b40a56e17fb0d2fde987133ca1614e29Marc Blank            color = cursor.getInt(UIProvider.CONVERSATION_COLOR_COLUMN);
346a6b671dd9f5ba358a05888b3ab3bf1c5cb5cf493Marc Blank            String account = cursor.getString(UIProvider.CONVERSATION_ACCOUNT_URI_COLUMN);
347a6b671dd9f5ba358a05888b3ab3bf1c5cb5cf493Marc Blank            accountUri = !TextUtils.isEmpty(account) ? Uri.parse(account) : null;
348f892f0a57d5c24b09fdc805f0fe2007ecd0d0e91Marc Blank            position = NO_POSITION;
349ce53818e1e185a845bd2f7f601c20e7085b40725Marc Blank            localDeleteOnUpdate = false;
3507f39bbd358f7003a72ae2b480dfe38a84e830e5fAndy Huang            conversationInfo = readConversationInfo(cursor);
35141dca185f7683b36bdafd9520c0648c897a95834Paul Westbrook            final String conversationBase =
35241dca185f7683b36bdafd9520c0648c897a95834Paul Westbrook                    cursor.getString(UIProvider.CONVERSATION_BASE_URI_COLUMN);
35341dca185f7683b36bdafd9520c0648c897a95834Paul Westbrook            conversationBaseUri = !TextUtils.isEmpty(conversationBase) ?
35441dca185f7683b36bdafd9520c0648c897a95834Paul Westbrook                    Uri.parse(conversationBase) : null;
355e8a3eecf0a481665c5e886ebfb4a6184b5125f78Mindy Pereira            if (conversationInfo == null) {
356e8a3eecf0a481665c5e886ebfb4a6184b5125f78Mindy Pereira                snippet = cursor.getString(UIProvider.CONVERSATION_SNIPPET_COLUMN);
357820f051b37b45b3e3729bda5c4302a879ee6aa4dPaul Westbrook                senders = emptyIfNull(cursor.getString(UIProvider.CONVERSATION_SENDER_INFO_COLUMN));
3580972e0793cc321670391d063348aecb5031b2677Mindy Pereira                numMessages = cursor.getInt(UIProvider.CONVERSATION_NUM_MESSAGES_COLUMN);
3590972e0793cc321670391d063348aecb5031b2677Mindy Pereira                numDrafts = cursor.getInt(UIProvider.CONVERSATION_NUM_DRAFTS_COLUMN);
360e8a3eecf0a481665c5e886ebfb4a6184b5125f78Mindy Pereira            }
361f98bc898cbc7014a203c35a13427d3f949bce705Andy Huang            isRemote = cursor.getInt(UIProvider.CONVERSATION_REMOTE_COLUMN) != 0;
362479505d71969e26b0785d8e0e1b81108731cf827Mark Wei            attachmentPreviews = null;
363479505d71969e26b0785d8e0e1b81108731cf827Mark Wei            attachmentPreviewUri0 = cursor.getString(
364479505d71969e26b0785d8e0e1b81108731cf827Mark Wei                    UIProvider.CONVERSATION_ATTACHMENT_PREVIEW_URI0_COLUMN);
365479505d71969e26b0785d8e0e1b81108731cf827Mark Wei            attachmentPreviewUri1 = cursor.getString(
366479505d71969e26b0785d8e0e1b81108731cf827Mark Wei                    UIProvider.CONVERSATION_ATTACHMENT_PREVIEW_URI1_COLUMN);
367479505d71969e26b0785d8e0e1b81108731cf827Mark Wei            attachmentPreviewStates = cursor.getInt(
368479505d71969e26b0785d8e0e1b81108731cf827Mark Wei                    UIProvider.CONVERSATION_ATTACHMENT_PREVIEW_STATES_COLUMN);
369479505d71969e26b0785d8e0e1b81108731cf827Mark Wei            attachmentPreviewsCount = cursor.getInt(
370479505d71969e26b0785d8e0e1b81108731cf827Mark Wei                    UIProvider.CONVERSATION_ATTACHMENT_PREVIEWS_COUNT_COLUMN);
371732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang        }
372732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang    }
373732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang
3741bca265b7a8a3f9ea08e0ae51eeb145f0883a266Andy Huang    public Conversation(Conversation other) {
3751bca265b7a8a3f9ea08e0ae51eeb145f0883a266Andy Huang        if (other == null) {
3761bca265b7a8a3f9ea08e0ae51eeb145f0883a266Andy Huang            return;
3771bca265b7a8a3f9ea08e0ae51eeb145f0883a266Andy Huang        }
3781bca265b7a8a3f9ea08e0ae51eeb145f0883a266Andy Huang
3791bca265b7a8a3f9ea08e0ae51eeb145f0883a266Andy Huang        id = other.id;
3801bca265b7a8a3f9ea08e0ae51eeb145f0883a266Andy Huang        uri = other.uri;
3811bca265b7a8a3f9ea08e0ae51eeb145f0883a266Andy Huang        dateMs = other.dateMs;
3821bca265b7a8a3f9ea08e0ae51eeb145f0883a266Andy Huang        subject = other.subject;
3831bca265b7a8a3f9ea08e0ae51eeb145f0883a266Andy Huang        hasAttachments = other.hasAttachments;
3841bca265b7a8a3f9ea08e0ae51eeb145f0883a266Andy Huang        messageListUri = other.messageListUri;
3851bca265b7a8a3f9ea08e0ae51eeb145f0883a266Andy Huang        sendingState = other.sendingState;
3861bca265b7a8a3f9ea08e0ae51eeb145f0883a266Andy Huang        priority = other.priority;
3871bca265b7a8a3f9ea08e0ae51eeb145f0883a266Andy Huang        read = other.read;
3881bca265b7a8a3f9ea08e0ae51eeb145f0883a266Andy Huang        seen = other.seen;
3891bca265b7a8a3f9ea08e0ae51eeb145f0883a266Andy Huang        starred = other.starred;
3901bca265b7a8a3f9ea08e0ae51eeb145f0883a266Andy Huang        rawFolders = other.rawFolders; // FolderList is immutable, shallow copy is OK
3911bca265b7a8a3f9ea08e0ae51eeb145f0883a266Andy Huang        convFlags = other.convFlags;
3921bca265b7a8a3f9ea08e0ae51eeb145f0883a266Andy Huang        personalLevel = other.personalLevel;
3931bca265b7a8a3f9ea08e0ae51eeb145f0883a266Andy Huang        spam = other.spam;
3941bca265b7a8a3f9ea08e0ae51eeb145f0883a266Andy Huang        phishing = other.phishing;
3951bca265b7a8a3f9ea08e0ae51eeb145f0883a266Andy Huang        muted = other.muted;
3961bca265b7a8a3f9ea08e0ae51eeb145f0883a266Andy Huang        color = other.color;
3971bca265b7a8a3f9ea08e0ae51eeb145f0883a266Andy Huang        accountUri = other.accountUri;
3981bca265b7a8a3f9ea08e0ae51eeb145f0883a266Andy Huang        position = other.position;
3991bca265b7a8a3f9ea08e0ae51eeb145f0883a266Andy Huang        localDeleteOnUpdate = other.localDeleteOnUpdate;
4001bca265b7a8a3f9ea08e0ae51eeb145f0883a266Andy Huang        // although ConversationInfo is mutable (see ConversationInfo.markRead), applyCachedValues
4011bca265b7a8a3f9ea08e0ae51eeb145f0883a266Andy Huang        // will overwrite this if cached changes exist anyway, so a shallow copy is OK
4021bca265b7a8a3f9ea08e0ae51eeb145f0883a266Andy Huang        conversationInfo = other.conversationInfo;
4031bca265b7a8a3f9ea08e0ae51eeb145f0883a266Andy Huang        conversationBaseUri = other.conversationBaseUri;
4041bca265b7a8a3f9ea08e0ae51eeb145f0883a266Andy Huang        snippet = other.snippet;
4051bca265b7a8a3f9ea08e0ae51eeb145f0883a266Andy Huang        senders = other.senders;
4061bca265b7a8a3f9ea08e0ae51eeb145f0883a266Andy Huang        numMessages = other.numMessages;
4071bca265b7a8a3f9ea08e0ae51eeb145f0883a266Andy Huang        numDrafts = other.numDrafts;
4081bca265b7a8a3f9ea08e0ae51eeb145f0883a266Andy Huang        isRemote = other.isRemote;
409479505d71969e26b0785d8e0e1b81108731cf827Mark Wei        attachmentPreviews = null;
410479505d71969e26b0785d8e0e1b81108731cf827Mark Wei        attachmentPreviewUri0 = other.attachmentPreviewUri0;
411479505d71969e26b0785d8e0e1b81108731cf827Mark Wei        attachmentPreviewUri1 = other.attachmentPreviewUri1;
412479505d71969e26b0785d8e0e1b81108731cf827Mark Wei        attachmentPreviewStates = other.attachmentPreviewStates;
413479505d71969e26b0785d8e0e1b81108731cf827Mark Wei        attachmentPreviewsCount = other.attachmentPreviewsCount;
4141bca265b7a8a3f9ea08e0ae51eeb145f0883a266Andy Huang    }
4151bca265b7a8a3f9ea08e0ae51eeb145f0883a266Andy Huang
416bf232c3735f65b1a4746943e4a134e59e36f0bdePaul Westbrook    public Conversation() {
417ff5c757ed2bcf7004a70b0675382ef894196558dPaul Westbrook    }
418ff5c757ed2bcf7004a70b0675382ef894196558dPaul Westbrook
419479505d71969e26b0785d8e0e1b81108731cf827Mark Wei    public static Conversation create(long id, Uri uri, String subject, long dateMs, String snippet,
420479505d71969e26b0785d8e0e1b81108731cf827Mark Wei            boolean hasAttachment, Uri messageListUri, String senders,
421863e44160d9175023d30e7e225ecb69ad3892eecMindy Pereira            int numMessages, int numDrafts, int sendingState, int priority, boolean read,
422d5edd2d02649dffb40065fdb6a16acf91552b800Scott Kennedy            boolean seen, boolean starred, FolderList rawFolders, int convFlags, int personalLevel,
423d5edd2d02649dffb40065fdb6a16acf91552b800Scott Kennedy            boolean spam, boolean phishing, boolean muted, Uri accountUri,
424479505d71969e26b0785d8e0e1b81108731cf827Mark Wei            ConversationInfo conversationInfo, Uri conversationBase, boolean isRemote,
425479505d71969e26b0785d8e0e1b81108731cf827Mark Wei            String attachmentPreviewUri0, String attachmentPreviewUri1, int attachmentPreviewStates,
426b6f1998c9151ad236dd3c6c5d0be3280df3ae895Mark Wei            int attachmentPreviewsCount) {
427ff5c757ed2bcf7004a70b0675382ef894196558dPaul Westbrook        final Conversation conversation = new Conversation();
428ff5c757ed2bcf7004a70b0675382ef894196558dPaul Westbrook
429ff5c757ed2bcf7004a70b0675382ef894196558dPaul Westbrook        conversation.id = id;
430ff5c757ed2bcf7004a70b0675382ef894196558dPaul Westbrook        conversation.uri = uri;
431ff5c757ed2bcf7004a70b0675382ef894196558dPaul Westbrook        conversation.subject = subject;
432ff5c757ed2bcf7004a70b0675382ef894196558dPaul Westbrook        conversation.dateMs = dateMs;
433ff5c757ed2bcf7004a70b0675382ef894196558dPaul Westbrook        conversation.snippet = snippet;
434ff5c757ed2bcf7004a70b0675382ef894196558dPaul Westbrook        conversation.hasAttachments = hasAttachment;
435ff5c757ed2bcf7004a70b0675382ef894196558dPaul Westbrook        conversation.messageListUri = messageListUri;
436820f051b37b45b3e3729bda5c4302a879ee6aa4dPaul Westbrook        conversation.senders = emptyIfNull(senders);
437ff5c757ed2bcf7004a70b0675382ef894196558dPaul Westbrook        conversation.numMessages = numMessages;
438ff5c757ed2bcf7004a70b0675382ef894196558dPaul Westbrook        conversation.numDrafts = numDrafts;
439ff5c757ed2bcf7004a70b0675382ef894196558dPaul Westbrook        conversation.sendingState = sendingState;
440ff5c757ed2bcf7004a70b0675382ef894196558dPaul Westbrook        conversation.priority = priority;
441ff5c757ed2bcf7004a70b0675382ef894196558dPaul Westbrook        conversation.read = read;
442d5edd2d02649dffb40065fdb6a16acf91552b800Scott Kennedy        conversation.seen = seen;
443ff5c757ed2bcf7004a70b0675382ef894196558dPaul Westbrook        conversation.starred = starred;
444ff5c757ed2bcf7004a70b0675382ef894196558dPaul Westbrook        conversation.rawFolders = rawFolders;
445ff5c757ed2bcf7004a70b0675382ef894196558dPaul Westbrook        conversation.convFlags = convFlags;
446ff5c757ed2bcf7004a70b0675382ef894196558dPaul Westbrook        conversation.personalLevel = personalLevel;
447863e44160d9175023d30e7e225ecb69ad3892eecMindy Pereira        conversation.spam = spam;
44876b2062b8c6d18a7b3a05292c385b47b0fcbd09fPaul Westbrook        conversation.phishing = phishing;
449863e44160d9175023d30e7e225ecb69ad3892eecMindy Pereira        conversation.muted = muted;
45092939fc7b40a56e17fb0d2fde987133ca1614e29Marc Blank        conversation.color = 0;
451a6b671dd9f5ba358a05888b3ab3bf1c5cb5cf493Marc Blank        conversation.accountUri = accountUri;
4527e854f52f0890b9621846ac7fe201a5681e65666Andy Huang        conversation.conversationInfo = conversationInfo;
45341dca185f7683b36bdafd9520c0648c897a95834Paul Westbrook        conversation.conversationBaseUri = conversationBase;
454f98bc898cbc7014a203c35a13427d3f949bce705Andy Huang        conversation.isRemote = isRemote;
455479505d71969e26b0785d8e0e1b81108731cf827Mark Wei        conversation.attachmentPreviews = null;
456479505d71969e26b0785d8e0e1b81108731cf827Mark Wei        conversation.attachmentPreviewUri0 = attachmentPreviewUri0;
457479505d71969e26b0785d8e0e1b81108731cf827Mark Wei        conversation.attachmentPreviewUri1 = attachmentPreviewUri1;
458479505d71969e26b0785d8e0e1b81108731cf827Mark Wei        conversation.attachmentPreviewStates = attachmentPreviewStates;
459479505d71969e26b0785d8e0e1b81108731cf827Mark Wei        conversation.attachmentPreviewsCount = attachmentPreviewsCount;
460ff5c757ed2bcf7004a70b0675382ef894196558dPaul Westbrook        return conversation;
461ff5c757ed2bcf7004a70b0675382ef894196558dPaul Westbrook    }
462ff5c757ed2bcf7004a70b0675382ef894196558dPaul Westbrook
4637f39bbd358f7003a72ae2b480dfe38a84e830e5fAndy Huang    private static final Bundle sConversationInfoRequest = new Bundle(1);
4647f39bbd358f7003a72ae2b480dfe38a84e830e5fAndy Huang    private static final Bundle sRawFoldersRequest = new Bundle(1);
4657f39bbd358f7003a72ae2b480dfe38a84e830e5fAndy Huang
4667f39bbd358f7003a72ae2b480dfe38a84e830e5fAndy Huang    private static ConversationInfo readConversationInfo(Cursor cursor) {
4677f39bbd358f7003a72ae2b480dfe38a84e830e5fAndy Huang        final ConversationInfo ci;
4687f39bbd358f7003a72ae2b480dfe38a84e830e5fAndy Huang
469f8b613c1103952ae5cc1f8a5e6ae60aa62d73decAndy Huang        if (cursor instanceof ConversationCursor) {
470f8b613c1103952ae5cc1f8a5e6ae60aa62d73decAndy Huang            final byte[] blob = ((ConversationCursor) cursor).getCachedBlob(
471f8b613c1103952ae5cc1f8a5e6ae60aa62d73decAndy Huang                    UIProvider.CONVERSATION_INFO_COLUMN);
472f8b613c1103952ae5cc1f8a5e6ae60aa62d73decAndy Huang            if (blob != null && blob.length > 0) {
473f8b613c1103952ae5cc1f8a5e6ae60aa62d73decAndy Huang                return ConversationInfo.fromBlob(blob);
474f8b613c1103952ae5cc1f8a5e6ae60aa62d73decAndy Huang            }
475f8b613c1103952ae5cc1f8a5e6ae60aa62d73decAndy Huang        }
476f8b613c1103952ae5cc1f8a5e6ae60aa62d73decAndy Huang
4777f39bbd358f7003a72ae2b480dfe38a84e830e5fAndy Huang        final String key = UIProvider.ConversationCursorCommand.COMMAND_GET_CONVERSATION_INFO;
4787f39bbd358f7003a72ae2b480dfe38a84e830e5fAndy Huang        if (sConversationInfoRequest.isEmpty()) {
4797f39bbd358f7003a72ae2b480dfe38a84e830e5fAndy Huang            sConversationInfoRequest.putBoolean(key, true);
480d521baf3a51c9fc1306bd55e027ce57d0a1d18aaAndy Huang            sConversationInfoRequest.putInt(
481d521baf3a51c9fc1306bd55e027ce57d0a1d18aaAndy Huang                    UIProvider.ConversationCursorCommand.COMMAND_KEY_OPTIONS,
482d521baf3a51c9fc1306bd55e027ce57d0a1d18aaAndy Huang                    UIProvider.ConversationCursorCommand.OPTION_MOVE_POSITION);
4837f39bbd358f7003a72ae2b480dfe38a84e830e5fAndy Huang        }
4847f39bbd358f7003a72ae2b480dfe38a84e830e5fAndy Huang        final Bundle response = cursor.respond(sConversationInfoRequest);
4857f39bbd358f7003a72ae2b480dfe38a84e830e5fAndy Huang        if (response.containsKey(key)) {
4867f39bbd358f7003a72ae2b480dfe38a84e830e5fAndy Huang            ci = response.getParcelable(key);
4877f39bbd358f7003a72ae2b480dfe38a84e830e5fAndy Huang        } else {
4887f39bbd358f7003a72ae2b480dfe38a84e830e5fAndy Huang            // legacy fallback
4897f39bbd358f7003a72ae2b480dfe38a84e830e5fAndy Huang            ci = ConversationInfo.fromBlob(cursor.getBlob(UIProvider.CONVERSATION_INFO_COLUMN));
4907f39bbd358f7003a72ae2b480dfe38a84e830e5fAndy Huang        }
4917f39bbd358f7003a72ae2b480dfe38a84e830e5fAndy Huang        return ci;
4927f39bbd358f7003a72ae2b480dfe38a84e830e5fAndy Huang    }
4937f39bbd358f7003a72ae2b480dfe38a84e830e5fAndy Huang
4947f39bbd358f7003a72ae2b480dfe38a84e830e5fAndy Huang    private static FolderList readRawFolders(Cursor cursor) {
4957f39bbd358f7003a72ae2b480dfe38a84e830e5fAndy Huang        final FolderList fl;
4967f39bbd358f7003a72ae2b480dfe38a84e830e5fAndy Huang
497f8b613c1103952ae5cc1f8a5e6ae60aa62d73decAndy Huang        if (cursor instanceof ConversationCursor) {
498f8b613c1103952ae5cc1f8a5e6ae60aa62d73decAndy Huang            final byte[] blob = ((ConversationCursor) cursor).getCachedBlob(
499f8b613c1103952ae5cc1f8a5e6ae60aa62d73decAndy Huang                    UIProvider.CONVERSATION_RAW_FOLDERS_COLUMN);
500f8b613c1103952ae5cc1f8a5e6ae60aa62d73decAndy Huang            if (blob != null && blob.length > 0) {
501f8b613c1103952ae5cc1f8a5e6ae60aa62d73decAndy Huang                return FolderList.fromBlob(blob);
502f8b613c1103952ae5cc1f8a5e6ae60aa62d73decAndy Huang            }
503f8b613c1103952ae5cc1f8a5e6ae60aa62d73decAndy Huang        }
504f8b613c1103952ae5cc1f8a5e6ae60aa62d73decAndy Huang
5057f39bbd358f7003a72ae2b480dfe38a84e830e5fAndy Huang        final String key = UIProvider.ConversationCursorCommand.COMMAND_GET_RAW_FOLDERS;
5067f39bbd358f7003a72ae2b480dfe38a84e830e5fAndy Huang        if (sRawFoldersRequest.isEmpty()) {
5077f39bbd358f7003a72ae2b480dfe38a84e830e5fAndy Huang            sRawFoldersRequest.putBoolean(key, true);
508d521baf3a51c9fc1306bd55e027ce57d0a1d18aaAndy Huang            sRawFoldersRequest.putInt(
509d521baf3a51c9fc1306bd55e027ce57d0a1d18aaAndy Huang                    UIProvider.ConversationCursorCommand.COMMAND_KEY_OPTIONS,
510d521baf3a51c9fc1306bd55e027ce57d0a1d18aaAndy Huang                    UIProvider.ConversationCursorCommand.OPTION_MOVE_POSITION);
5117f39bbd358f7003a72ae2b480dfe38a84e830e5fAndy Huang        }
5127f39bbd358f7003a72ae2b480dfe38a84e830e5fAndy Huang        final Bundle response = cursor.respond(sRawFoldersRequest);
5137f39bbd358f7003a72ae2b480dfe38a84e830e5fAndy Huang        if (response.containsKey(key)) {
5147f39bbd358f7003a72ae2b480dfe38a84e830e5fAndy Huang            fl = response.getParcelable(key);
5157f39bbd358f7003a72ae2b480dfe38a84e830e5fAndy Huang        } else {
5167f39bbd358f7003a72ae2b480dfe38a84e830e5fAndy Huang            // legacy fallback
517db5356a92ebc593e9eb564aaadad8dac8cd83554Paul Westbrook            // TODO: delete this once Email supports the respond call
5187f39bbd358f7003a72ae2b480dfe38a84e830e5fAndy Huang            fl = FolderList.fromBlob(
5197f39bbd358f7003a72ae2b480dfe38a84e830e5fAndy Huang                    cursor.getBlob(UIProvider.CONVERSATION_RAW_FOLDERS_COLUMN));
5207f39bbd358f7003a72ae2b480dfe38a84e830e5fAndy Huang        }
5217f39bbd358f7003a72ae2b480dfe38a84e830e5fAndy Huang        return fl;
5227f39bbd358f7003a72ae2b480dfe38a84e830e5fAndy Huang    }
5237f39bbd358f7003a72ae2b480dfe38a84e830e5fAndy Huang
524b2033d855ab0f13e253e5403ce25989bcbc49488Andy Huang    /**
5251bca265b7a8a3f9ea08e0ae51eeb145f0883a266Andy Huang     * Apply any column values from the given {@link ContentValues} (where column names are the
5261bca265b7a8a3f9ea08e0ae51eeb145f0883a266Andy Huang     * keys) to this conversation.
5271bca265b7a8a3f9ea08e0ae51eeb145f0883a266Andy Huang     *
5281bca265b7a8a3f9ea08e0ae51eeb145f0883a266Andy Huang     */
5291bca265b7a8a3f9ea08e0ae51eeb145f0883a266Andy Huang    public void applyCachedValues(ContentValues values) {
5301bca265b7a8a3f9ea08e0ae51eeb145f0883a266Andy Huang        if (values == null) {
5311bca265b7a8a3f9ea08e0ae51eeb145f0883a266Andy Huang            return;
5321bca265b7a8a3f9ea08e0ae51eeb145f0883a266Andy Huang        }
5331bca265b7a8a3f9ea08e0ae51eeb145f0883a266Andy Huang        for (String key : values.keySet()) {
5341bca265b7a8a3f9ea08e0ae51eeb145f0883a266Andy Huang            final Object val = values.get(key);
5351bca265b7a8a3f9ea08e0ae51eeb145f0883a266Andy Huang            LogUtils.i(LOG_TAG, "Conversation: applying cached value to col=%s val=%s", key,
5361bca265b7a8a3f9ea08e0ae51eeb145f0883a266Andy Huang                    val);
5371bca265b7a8a3f9ea08e0ae51eeb145f0883a266Andy Huang            if (ConversationColumns.READ.equals(key)) {
5381bca265b7a8a3f9ea08e0ae51eeb145f0883a266Andy Huang                read = (Integer) val != 0;
5391bca265b7a8a3f9ea08e0ae51eeb145f0883a266Andy Huang            } else if (ConversationColumns.CONVERSATION_INFO.equals(key)) {
5401bca265b7a8a3f9ea08e0ae51eeb145f0883a266Andy Huang                conversationInfo = ConversationInfo.fromBlob((byte[]) val);
5411bca265b7a8a3f9ea08e0ae51eeb145f0883a266Andy Huang            } else if (ConversationColumns.FLAGS.equals(key)) {
5421bca265b7a8a3f9ea08e0ae51eeb145f0883a266Andy Huang                convFlags = (Integer) val;
5431bca265b7a8a3f9ea08e0ae51eeb145f0883a266Andy Huang            } else if (ConversationColumns.STARRED.equals(key)) {
5441bca265b7a8a3f9ea08e0ae51eeb145f0883a266Andy Huang                starred = (Integer) val != 0;
5457f4b6140b40c1d1d2624ca1dabe229fbb5c6959aAndy Huang            } else if (ConversationColumns.SEEN.equals(key)) {
5467f4b6140b40c1d1d2624ca1dabe229fbb5c6959aAndy Huang                seen = (Integer) val != 0;
5478ebc2ce34ed7d979662cf88b1c9fa60d63142fe4Andy Huang            } else if (ConversationColumns.RAW_FOLDERS.equals(key)) {
5488ebc2ce34ed7d979662cf88b1c9fa60d63142fe4Andy Huang                rawFolders = FolderList.fromBlob((byte[]) val);
5491bca265b7a8a3f9ea08e0ae51eeb145f0883a266Andy Huang            } else if (ConversationColumns.VIEWED.equals(key)) {
5501bca265b7a8a3f9ea08e0ae51eeb145f0883a266Andy Huang                // ignore. this is not read from the cursor, either.
5511bca265b7a8a3f9ea08e0ae51eeb145f0883a266Andy Huang            } else {
5521bca265b7a8a3f9ea08e0ae51eeb145f0883a266Andy Huang                LogUtils.e(LOG_TAG, new UnsupportedOperationException(),
5531bca265b7a8a3f9ea08e0ae51eeb145f0883a266Andy Huang                        "unsupported cached conv value in col=%s", key);
5541bca265b7a8a3f9ea08e0ae51eeb145f0883a266Andy Huang            }
5551bca265b7a8a3f9ea08e0ae51eeb145f0883a266Andy Huang        }
5561bca265b7a8a3f9ea08e0ae51eeb145f0883a266Andy Huang    }
5571bca265b7a8a3f9ea08e0ae51eeb145f0883a266Andy Huang
5581bca265b7a8a3f9ea08e0ae51eeb145f0883a266Andy Huang    /**
559b2033d855ab0f13e253e5403ce25989bcbc49488Andy Huang     * Get the <strong>immutable</strong> list of {@link Folder}s for this conversation. To modify
560b2033d855ab0f13e253e5403ce25989bcbc49488Andy Huang     * this list, make a new {@link FolderList} and use {@link #setRawFolders(FolderList)}.
561b2033d855ab0f13e253e5403ce25989bcbc49488Andy Huang     *
562b2033d855ab0f13e253e5403ce25989bcbc49488Andy Huang     * @return <strong>Immutable</strong> list of {@link Folder}s.
563b2033d855ab0f13e253e5403ce25989bcbc49488Andy Huang     */
564b2033d855ab0f13e253e5403ce25989bcbc49488Andy Huang    public List<Folder> getRawFolders() {
565b2033d855ab0f13e253e5403ce25989bcbc49488Andy Huang        return rawFolders.folders;
56600ffece08e94ff5774b2a53c0adeb2f3d0815d66Mindy Pereira    }
56700ffece08e94ff5774b2a53c0adeb2f3d0815d66Mindy Pereira
568b2033d855ab0f13e253e5403ce25989bcbc49488Andy Huang    public void setRawFolders(FolderList folders) {
569b2033d855ab0f13e253e5403ce25989bcbc49488Andy Huang        rawFolders = folders;
57085c4a77abd849f5f3f0236d51554bb1bb99fe8f6Mindy Pereira    }
57185c4a77abd849f5f3f0236d51554bb1bb99fe8f6Mindy Pereira
572e1d1b07cdb0026097eb80f6c2912a16353aacec1Marc Blank    @Override
573e1d1b07cdb0026097eb80f6c2912a16353aacec1Marc Blank    public boolean equals(Object o) {
5743c9bcef43b4f103697034abbf2eab99111e8d987Marc Blank        if (o instanceof Conversation) {
575648df3f0b0ebcd3c4adf907d70ff0938e5dfc78fMindy Pereira            Conversation conv = (Conversation) o;
5763c9bcef43b4f103697034abbf2eab99111e8d987Marc Blank            return conv.uri.equals(uri);
5773c9bcef43b4f103697034abbf2eab99111e8d987Marc Blank        }
5783c9bcef43b4f103697034abbf2eab99111e8d987Marc Blank        return false;
579e1d1b07cdb0026097eb80f6c2912a16353aacec1Marc Blank    }
580e1d1b07cdb0026097eb80f6c2912a16353aacec1Marc Blank
581e1d1b07cdb0026097eb80f6c2912a16353aacec1Marc Blank    @Override
582e1d1b07cdb0026097eb80f6c2912a16353aacec1Marc Blank    public int hashCode() {
583e1d1b07cdb0026097eb80f6c2912a16353aacec1Marc Blank        return uri.hashCode();
584e1d1b07cdb0026097eb80f6c2912a16353aacec1Marc Blank    }
585e1d1b07cdb0026097eb80f6c2912a16353aacec1Marc Blank
5867f0a962513503cb01aec093b14c1b48dfae08f12Mindy Pereira    /**
5877f0a962513503cb01aec093b14c1b48dfae08f12Mindy Pereira     * Get if this conversation is marked as high priority.
5887f0a962513503cb01aec093b14c1b48dfae08f12Mindy Pereira     */
5897f0a962513503cb01aec093b14c1b48dfae08f12Mindy Pereira    public boolean isImportant() {
59022657529437c160dec072115c5982409306c1313Mindy Pereira        return priority == UIProvider.ConversationPriority.IMPORTANT;
5917f0a962513503cb01aec093b14c1b48dfae08f12Mindy Pereira    }
5927f0a962513503cb01aec093b14c1b48dfae08f12Mindy Pereira
593e1d1b07cdb0026097eb80f6c2912a16353aacec1Marc Blank    /**
594e1d1b07cdb0026097eb80f6c2912a16353aacec1Marc Blank     * Get if this conversation is mostly dead
595e1d1b07cdb0026097eb80f6c2912a16353aacec1Marc Blank     */
596e1d1b07cdb0026097eb80f6c2912a16353aacec1Marc Blank    public boolean isMostlyDead() {
597e1d1b07cdb0026097eb80f6c2912a16353aacec1Marc Blank        return (convFlags & FLAG_MOSTLY_DEAD) != 0;
598e1d1b07cdb0026097eb80f6c2912a16353aacec1Marc Blank    }
599440fe79194314b25ef5829702494735ce2f1e2e8Vikram Aggarwal
600440fe79194314b25ef5829702494735ce2f1e2e8Vikram Aggarwal    /**
601648df3f0b0ebcd3c4adf907d70ff0938e5dfc78fMindy Pereira     * Returns true if the URI of the conversation specified as the needle was
602648df3f0b0ebcd3c4adf907d70ff0938e5dfc78fMindy Pereira     * found in the collection of conversations specified as the haystack. False
603192fac189e6aed434556a4e37bd3c5c29ef02f29Vikram Aggarwal     * otherwise. This method is safe to call with null arguments.
604f98bc898cbc7014a203c35a13427d3f949bce705Andy Huang     *
605d503df4f0c31bbf842c6a1d3cba18df8c074bf67Vikram Aggarwal     * @param haystack
606d503df4f0c31bbf842c6a1d3cba18df8c074bf67Vikram Aggarwal     * @param needle
607d503df4f0c31bbf842c6a1d3cba18df8c074bf67Vikram Aggarwal     * @return true if the needle was found in the haystack, false otherwise.
608d503df4f0c31bbf842c6a1d3cba18df8c074bf67Vikram Aggarwal     */
609d503df4f0c31bbf842c6a1d3cba18df8c074bf67Vikram Aggarwal    public final static boolean contains(Collection<Conversation> haystack, Conversation needle) {
610d503df4f0c31bbf842c6a1d3cba18df8c074bf67Vikram Aggarwal        // If the haystack is empty, it cannot contain anything.
611d503df4f0c31bbf842c6a1d3cba18df8c074bf67Vikram Aggarwal        if (haystack == null || haystack.size() <= 0) {
612d503df4f0c31bbf842c6a1d3cba18df8c074bf67Vikram Aggarwal            return false;
613d503df4f0c31bbf842c6a1d3cba18df8c074bf67Vikram Aggarwal        }
614d503df4f0c31bbf842c6a1d3cba18df8c074bf67Vikram Aggarwal        // The null folder exists everywhere.
615d503df4f0c31bbf842c6a1d3cba18df8c074bf67Vikram Aggarwal        if (needle == null) {
616d503df4f0c31bbf842c6a1d3cba18df8c074bf67Vikram Aggarwal            return true;
617d503df4f0c31bbf842c6a1d3cba18df8c074bf67Vikram Aggarwal        }
6187dd054e39986de84a213c56a3c11ac94731402e6Vikram Aggarwal        final long toFind = needle.id;
619d503df4f0c31bbf842c6a1d3cba18df8c074bf67Vikram Aggarwal        for (final Conversation c : haystack) {
6207dd054e39986de84a213c56a3c11ac94731402e6Vikram Aggarwal            if (toFind == c.id) {
621d503df4f0c31bbf842c6a1d3cba18df8c074bf67Vikram Aggarwal                return true;
622d503df4f0c31bbf842c6a1d3cba18df8c074bf67Vikram Aggarwal            }
623d503df4f0c31bbf842c6a1d3cba18df8c074bf67Vikram Aggarwal        }
624d503df4f0c31bbf842c6a1d3cba18df8c074bf67Vikram Aggarwal        return false;
625d503df4f0c31bbf842c6a1d3cba18df8c074bf67Vikram Aggarwal    }
626d503df4f0c31bbf842c6a1d3cba18df8c074bf67Vikram Aggarwal
627d503df4f0c31bbf842c6a1d3cba18df8c074bf67Vikram Aggarwal    /**
628648df3f0b0ebcd3c4adf907d70ff0938e5dfc78fMindy Pereira     * Returns a collection of a single conversation. This method always returns
629648df3f0b0ebcd3c4adf907d70ff0938e5dfc78fMindy Pereira     * a valid collection even if the input conversation is null.
630f98bc898cbc7014a203c35a13427d3f949bce705Andy Huang     *
631440fe79194314b25ef5829702494735ce2f1e2e8Vikram Aggarwal     * @param in a conversation, possibly null.
632440fe79194314b25ef5829702494735ce2f1e2e8Vikram Aggarwal     * @return a collection of the conversation.
633440fe79194314b25ef5829702494735ce2f1e2e8Vikram Aggarwal     */
634440fe79194314b25ef5829702494735ce2f1e2e8Vikram Aggarwal    public static Collection<Conversation> listOf(Conversation in) {
635440fe79194314b25ef5829702494735ce2f1e2e8Vikram Aggarwal        final Collection<Conversation> target = (in == null) ? EMPTY : ImmutableList.of(in);
636440fe79194314b25ef5829702494735ce2f1e2e8Vikram Aggarwal        return target;
637440fe79194314b25ef5829702494735ce2f1e2e8Vikram Aggarwal    }
6387dd054e39986de84a213c56a3c11ac94731402e6Vikram Aggarwal
6397dd054e39986de84a213c56a3c11ac94731402e6Vikram Aggarwal    /**
640aa1f945612847bc4cf5c8909b8acfab4b5ecf54eMindy Pereira     * Get the snippet for this conversation. Masks that it may come from
641aa1f945612847bc4cf5c8909b8acfab4b5ecf54eMindy Pereira     * conversation info or the original deprecated snippet string.
642aa1f945612847bc4cf5c8909b8acfab4b5ecf54eMindy Pereira     */
643aa1f945612847bc4cf5c8909b8acfab4b5ecf54eMindy Pereira    public String getSnippet() {
644d97782206889a5508279b75cce19d7c0fb8a3bcaMindy Pereira        return conversationInfo != null && !TextUtils.isEmpty(conversationInfo.firstSnippet) ?
645d97782206889a5508279b75cce19d7c0fb8a3bcaMindy Pereira                conversationInfo.firstSnippet : snippet;
646aa1f945612847bc4cf5c8909b8acfab4b5ecf54eMindy Pereira    }
647aa1f945612847bc4cf5c8909b8acfab4b5ecf54eMindy Pereira
648aa1f945612847bc4cf5c8909b8acfab4b5ecf54eMindy Pereira    /**
6490972e0793cc321670391d063348aecb5031b2677Mindy Pereira     * Get the number of messages for this conversation.
6500972e0793cc321670391d063348aecb5031b2677Mindy Pereira     */
6510972e0793cc321670391d063348aecb5031b2677Mindy Pereira    public int getNumMessages() {
6520972e0793cc321670391d063348aecb5031b2677Mindy Pereira        return conversationInfo != null ? conversationInfo.messageCount : numMessages;
6530972e0793cc321670391d063348aecb5031b2677Mindy Pereira    }
6540972e0793cc321670391d063348aecb5031b2677Mindy Pereira
6550972e0793cc321670391d063348aecb5031b2677Mindy Pereira    /**
6560972e0793cc321670391d063348aecb5031b2677Mindy Pereira     * Get the number of drafts for this conversation.
6570972e0793cc321670391d063348aecb5031b2677Mindy Pereira     */
6580972e0793cc321670391d063348aecb5031b2677Mindy Pereira    public int numDrafts() {
6590972e0793cc321670391d063348aecb5031b2677Mindy Pereira        return conversationInfo != null ? conversationInfo.draftCount : numDrafts;
6600972e0793cc321670391d063348aecb5031b2677Mindy Pereira    }
6610972e0793cc321670391d063348aecb5031b2677Mindy Pereira
662cd5c5eeae167885ffa2959c200233fea2f39c5f7Andy Huang    public boolean isViewed() {
663cd5c5eeae167885ffa2959c200233fea2f39c5f7Andy Huang        return viewed;
664cd5c5eeae167885ffa2959c200233fea2f39c5f7Andy Huang    }
665cd5c5eeae167885ffa2959c200233fea2f39c5f7Andy Huang
666cd5c5eeae167885ffa2959c200233fea2f39c5f7Andy Huang    public void markViewed() {
667cd5c5eeae167885ffa2959c200233fea2f39c5f7Andy Huang        viewed = true;
668cd5c5eeae167885ffa2959c200233fea2f39c5f7Andy Huang    }
669cd5c5eeae167885ffa2959c200233fea2f39c5f7Andy Huang
670c1fb9a9c2730178105977fca629e80951bfc3cdcAndy Huang    public String getBaseUri(String defaultValue) {
671c1fb9a9c2730178105977fca629e80951bfc3cdcAndy Huang        return conversationBaseUri != null ? conversationBaseUri.toString() : defaultValue;
672c1fb9a9c2730178105977fca629e80951bfc3cdcAndy Huang    }
673c1fb9a9c2730178105977fca629e80951bfc3cdcAndy Huang
674479505d71969e26b0785d8e0e1b81108731cf827Mark Wei    public ArrayList<String> getAttachmentPreviewUris() {
675479505d71969e26b0785d8e0e1b81108731cf827Mark Wei        if (attachmentPreviews == null) {
676479505d71969e26b0785d8e0e1b81108731cf827Mark Wei            attachmentPreviews = Lists.newArrayListWithCapacity(2);
677479505d71969e26b0785d8e0e1b81108731cf827Mark Wei            if (!TextUtils.isEmpty(attachmentPreviewUri0)) {
678479505d71969e26b0785d8e0e1b81108731cf827Mark Wei                attachmentPreviews.add(attachmentPreviewUri0);
679479505d71969e26b0785d8e0e1b81108731cf827Mark Wei            }
680479505d71969e26b0785d8e0e1b81108731cf827Mark Wei            if (!TextUtils.isEmpty(attachmentPreviewUri1)) {
681479505d71969e26b0785d8e0e1b81108731cf827Mark Wei                attachmentPreviews.add(attachmentPreviewUri1);
682479505d71969e26b0785d8e0e1b81108731cf827Mark Wei            }
683479505d71969e26b0785d8e0e1b81108731cf827Mark Wei        }
684479505d71969e26b0785d8e0e1b81108731cf827Mark Wei        return attachmentPreviews;
685d198fa7ddb2d0c730847af34f06aa2e940b2537dMark Wei    }
686d198fa7ddb2d0c730847af34f06aa2e940b2537dMark Wei
6870972e0793cc321670391d063348aecb5031b2677Mindy Pereira    /**
6887dd054e39986de84a213c56a3c11ac94731402e6Vikram Aggarwal     * Create a human-readable string of all the conversations
6897dd054e39986de84a213c56a3c11ac94731402e6Vikram Aggarwal     * @param collection Any collection of conversations
6907dd054e39986de84a213c56a3c11ac94731402e6Vikram Aggarwal     * @return string with a human readable representation of the conversations.
6917dd054e39986de84a213c56a3c11ac94731402e6Vikram Aggarwal     */
6927dd054e39986de84a213c56a3c11ac94731402e6Vikram Aggarwal    public static String toString(Collection<Conversation> collection) {
6937dd054e39986de84a213c56a3c11ac94731402e6Vikram Aggarwal        final StringBuilder out = new StringBuilder(collection.size() + " conversations:");
6947dd054e39986de84a213c56a3c11ac94731402e6Vikram Aggarwal        int count = 0;
6957dd054e39986de84a213c56a3c11ac94731402e6Vikram Aggarwal        for (final Conversation c : collection) {
6967dd054e39986de84a213c56a3c11ac94731402e6Vikram Aggarwal            count++;
697648df3f0b0ebcd3c4adf907d70ff0938e5dfc78fMindy Pereira            // Indent the conversations to make them easy to read in debug
698648df3f0b0ebcd3c4adf907d70ff0938e5dfc78fMindy Pereira            // output.
6997dd054e39986de84a213c56a3c11ac94731402e6Vikram Aggarwal            out.append("      " + count + ": " + c.toString() + "\n");
7007dd054e39986de84a213c56a3c11ac94731402e6Vikram Aggarwal        }
7017dd054e39986de84a213c56a3c11ac94731402e6Vikram Aggarwal        return out.toString();
7027dd054e39986de84a213c56a3c11ac94731402e6Vikram Aggarwal    }
703820f051b37b45b3e3729bda5c4302a879ee6aa4dPaul Westbrook
704820f051b37b45b3e3729bda5c4302a879ee6aa4dPaul Westbrook    /**
705820f051b37b45b3e3729bda5c4302a879ee6aa4dPaul Westbrook     * Returns an empty string if the specified string is null
706820f051b37b45b3e3729bda5c4302a879ee6aa4dPaul Westbrook     */
707820f051b37b45b3e3729bda5c4302a879ee6aa4dPaul Westbrook    private static String emptyIfNull(String in) {
708820f051b37b45b3e3729bda5c4302a879ee6aa4dPaul Westbrook        return in != null ? in : EMPTY_STRING;
709820f051b37b45b3e3729bda5c4302a879ee6aa4dPaul Westbrook    }
710bf9508d3877d05742b2f5d23e1780366d3e1aa2eMindy Pereira
711bf9508d3877d05742b2f5d23e1780366d3e1aa2eMindy Pereira    /**
712f2caf91209e4e2d4182d6b379a3cd79eed81af71mindyp     * Get the properly formatted subject and snippet string for display a
713f2caf91209e4e2d4182d6b379a3cd79eed81af71mindyp     * conversation.
714f2caf91209e4e2d4182d6b379a3cd79eed81af71mindyp     *
715f2caf91209e4e2d4182d6b379a3cd79eed81af71mindyp     * @param context
716f2caf91209e4e2d4182d6b379a3cd79eed81af71mindyp     * @param filteredSubject
717f2caf91209e4e2d4182d6b379a3cd79eed81af71mindyp     * @param snippet
718bf9508d3877d05742b2f5d23e1780366d3e1aa2eMindy Pereira     */
719c046e4a310462aa6998a34ff50439eb5e2508d85mindyp    public static String getSubjectAndSnippetForDisplay(Context context,
720c046e4a310462aa6998a34ff50439eb5e2508d85mindyp            String filteredSubject, String snippet) {
7212909b7442130800d6c6c20c1227d65295262f03emindyp        if (sSubjectAndSnippet == null) {
7222909b7442130800d6c6c20c1227d65295262f03emindyp            sSubjectAndSnippet = context.getString(R.string.subject_and_snippet);
7232909b7442130800d6c6c20c1227d65295262f03emindyp        }
72461bd0e84a3b0545a722bbfe931233b47afdf52e2Scott Kennedy        if (TextUtils.isEmpty(filteredSubject) && TextUtils.isEmpty(snippet)) {
72561bd0e84a3b0545a722bbfe931233b47afdf52e2Scott Kennedy            return "";
72661bd0e84a3b0545a722bbfe931233b47afdf52e2Scott Kennedy        } else if (TextUtils.isEmpty(filteredSubject)) {
72761bd0e84a3b0545a722bbfe931233b47afdf52e2Scott Kennedy            return snippet;
72861bd0e84a3b0545a722bbfe931233b47afdf52e2Scott Kennedy        } else if (TextUtils.isEmpty(snippet)) {
72961bd0e84a3b0545a722bbfe931233b47afdf52e2Scott Kennedy            return filteredSubject;
73061bd0e84a3b0545a722bbfe931233b47afdf52e2Scott Kennedy        }
73161bd0e84a3b0545a722bbfe931233b47afdf52e2Scott Kennedy
73261bd0e84a3b0545a722bbfe931233b47afdf52e2Scott Kennedy        return String.format(sSubjectAndSnippet, filteredSubject, snippet);
733bf9508d3877d05742b2f5d23e1780366d3e1aa2eMindy Pereira    }
7345f578144cc01738d5f9988d61674a643df19fdaeScott Kennedy
7355f578144cc01738d5f9988d61674a643df19fdaeScott Kennedy    /**
7365f578144cc01738d5f9988d61674a643df19fdaeScott Kennedy     * Public object that knows how to construct Conversation given Cursors. This is not used by
7375f578144cc01738d5f9988d61674a643df19fdaeScott Kennedy     * {@link ConversationCursor} or {@link ConversationCursorLoader}.
7385f578144cc01738d5f9988d61674a643df19fdaeScott Kennedy     */
7395f578144cc01738d5f9988d61674a643df19fdaeScott Kennedy    public static final CursorCreator<Conversation> FACTORY = new CursorCreator<Conversation>() {
7405f578144cc01738d5f9988d61674a643df19fdaeScott Kennedy        @Override
7415f578144cc01738d5f9988d61674a643df19fdaeScott Kennedy        public Conversation createFromCursor(final Cursor c) {
7425f578144cc01738d5f9988d61674a643df19fdaeScott Kennedy            return new Conversation(c);
7435f578144cc01738d5f9988d61674a643df19fdaeScott Kennedy        }
7445f578144cc01738d5f9988d61674a643df19fdaeScott Kennedy
7455f578144cc01738d5f9988d61674a643df19fdaeScott Kennedy        @Override
7465f578144cc01738d5f9988d61674a643df19fdaeScott Kennedy        public String toString() {
7475f578144cc01738d5f9988d61674a643df19fdaeScott Kennedy            return "Conversation CursorCreator";
7485f578144cc01738d5f9988d61674a643df19fdaeScott Kennedy        }
7495f578144cc01738d5f9988d61674a643df19fdaeScott Kennedy    };
750648df3f0b0ebcd3c4adf907d70ff0938e5dfc78fMindy Pereira}
751