Conversation.java revision db5356a92ebc593e9eb564aaadad8dac8cd83554
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;
36479505d71969e26b0785d8e0e1b81108731cf827Mark Weiimport com.android.mail.utils.Utils;
37a6b671dd9f5ba358a05888b3ab3bf1c5cb5cf493Marc Blankimport com.google.common.collect.ImmutableList;
38d198fa7ddb2d0c730847af34f06aa2e940b2537dMark Weiimport com.google.common.collect.Lists;
39a6b671dd9f5ba358a05888b3ab3bf1c5cb5cf493Marc Blank
4000ffece08e94ff5774b2a53c0adeb2f3d0815d66Mindy Pereiraimport java.util.ArrayList;
41440fe79194314b25ef5829702494735ce2f1e2e8Vikram Aggarwalimport java.util.Collection;
42440fe79194314b25ef5829702494735ce2f1e2e8Vikram Aggarwalimport java.util.Collections;
43b2033d855ab0f13e253e5403ce25989bcbc49488Andy Huangimport java.util.List;
44440fe79194314b25ef5829702494735ce2f1e2e8Vikram Aggarwal
45732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huangpublic class Conversation implements Parcelable {
46f892f0a57d5c24b09fdc805f0fe2007ecd0d0e91Marc Blank    public static final int NO_POSITION = -1;
47732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang
489e4ca7993213d296043d20fe9cf4e166b5d595e8Andy Huang    private static final String LOG_TAG = LogTag.getLogTag();
499e4ca7993213d296043d20fe9cf4e166b5d595e8Andy Huang
50820f051b37b45b3e3729bda5c4302a879ee6aa4dPaul Westbrook    private static final String EMPTY_STRING = "";
51820f051b37b45b3e3729bda5c4302a879ee6aa4dPaul Westbrook
52e623a0f6e3caa9cafec913cf826e946628833517Andy Huang    /**
53e623a0f6e3caa9cafec913cf826e946628833517Andy Huang     * @see BaseColumns#_ID
54e623a0f6e3caa9cafec913cf826e946628833517Andy Huang     */
55732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang    public long id;
56e623a0f6e3caa9cafec913cf826e946628833517Andy Huang    /**
57e623a0f6e3caa9cafec913cf826e946628833517Andy Huang     * @see UIProvider.ConversationColumns#URI
58e623a0f6e3caa9cafec913cf826e946628833517Andy Huang     */
59c43bc0a606e41144a780c4f873b5450e0ede0c91Marc Blank    public Uri uri;
60e623a0f6e3caa9cafec913cf826e946628833517Andy Huang    /**
61e623a0f6e3caa9cafec913cf826e946628833517Andy Huang     * @see UIProvider.ConversationColumns#SUBJECT
62e623a0f6e3caa9cafec913cf826e946628833517Andy Huang     */
63732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang    public String subject;
64e623a0f6e3caa9cafec913cf826e946628833517Andy Huang    /**
65e623a0f6e3caa9cafec913cf826e946628833517Andy Huang     * @see UIProvider.ConversationColumns#DATE_RECEIVED_MS
66e623a0f6e3caa9cafec913cf826e946628833517Andy Huang     */
67732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang    public long dateMs;
68e623a0f6e3caa9cafec913cf826e946628833517Andy Huang    /**
69e623a0f6e3caa9cafec913cf826e946628833517Andy Huang     * @see UIProvider.ConversationColumns#SNIPPET
70e623a0f6e3caa9cafec913cf826e946628833517Andy Huang     */
71aa1f945612847bc4cf5c8909b8acfab4b5ecf54eMindy Pereira    @Deprecated
72732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang    public String snippet;
73e623a0f6e3caa9cafec913cf826e946628833517Andy Huang    /**
74e623a0f6e3caa9cafec913cf826e946628833517Andy Huang     * @see UIProvider.ConversationColumns#HAS_ATTACHMENTS
75e623a0f6e3caa9cafec913cf826e946628833517Andy Huang     */
76732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang    public boolean hasAttachments;
77e623a0f6e3caa9cafec913cf826e946628833517Andy Huang    /**
78479505d71969e26b0785d8e0e1b81108731cf827Mark Wei     * Union of attachmentPreviewUri0 and attachmentPreviewUri1
79479505d71969e26b0785d8e0e1b81108731cf827Mark Wei     */
80479505d71969e26b0785d8e0e1b81108731cf827Mark Wei    public transient ArrayList<String> attachmentPreviews;
81479505d71969e26b0785d8e0e1b81108731cf827Mark Wei    /**
82479505d71969e26b0785d8e0e1b81108731cf827Mark Wei     * @see UIProvider.ConversationColumns#ATTACHMENT_PREVIEW_URI0
83479505d71969e26b0785d8e0e1b81108731cf827Mark Wei     */
84479505d71969e26b0785d8e0e1b81108731cf827Mark Wei    public String attachmentPreviewUri0;
85479505d71969e26b0785d8e0e1b81108731cf827Mark Wei    /**
86479505d71969e26b0785d8e0e1b81108731cf827Mark Wei     * @see UIProvider.ConversationColumns#ATTACHMENT_PREVIEW_URI1
87479505d71969e26b0785d8e0e1b81108731cf827Mark Wei     */
88479505d71969e26b0785d8e0e1b81108731cf827Mark Wei    public String attachmentPreviewUri1;
89479505d71969e26b0785d8e0e1b81108731cf827Mark Wei    /**
90479505d71969e26b0785d8e0e1b81108731cf827Mark Wei     * @see UIProvider.ConversationColumns#ATTACHMENT_PREVIEW_STATES
91479505d71969e26b0785d8e0e1b81108731cf827Mark Wei     */
92479505d71969e26b0785d8e0e1b81108731cf827Mark Wei    public int attachmentPreviewStates;
93479505d71969e26b0785d8e0e1b81108731cf827Mark Wei    /**
94479505d71969e26b0785d8e0e1b81108731cf827Mark Wei     * @see UIProvider.ConversationColumns#ATTACHMENT_PREVIEWS_COUNT
95479505d71969e26b0785d8e0e1b81108731cf827Mark Wei     */
96479505d71969e26b0785d8e0e1b81108731cf827Mark Wei    public int attachmentPreviewsCount;
97479505d71969e26b0785d8e0e1b81108731cf827Mark Wei    public Uri attachmentPreviewsListUri;
98479505d71969e26b0785d8e0e1b81108731cf827Mark Wei    /**
99e623a0f6e3caa9cafec913cf826e946628833517Andy Huang     * @see UIProvider.ConversationColumns#MESSAGE_LIST_URI
100e623a0f6e3caa9cafec913cf826e946628833517Andy Huang     */
101cfb7f33ff8ef9dc60b9143af32de64c7a3d71f36Mindy Pereira    public Uri messageListUri;
102e623a0f6e3caa9cafec913cf826e946628833517Andy Huang    /**
103e623a0f6e3caa9cafec913cf826e946628833517Andy Huang     * @see UIProvider.ConversationColumns#SENDER_INFO
104e623a0f6e3caa9cafec913cf826e946628833517Andy Huang     */
105648df3f0b0ebcd3c4adf907d70ff0938e5dfc78fMindy Pereira    @Deprecated
1064db59c58c0af9f44d95a12dbe21322bed58cc518Mindy Pereira    public String senders;
107e623a0f6e3caa9cafec913cf826e946628833517Andy Huang    /**
108e623a0f6e3caa9cafec913cf826e946628833517Andy Huang     * @see UIProvider.ConversationColumns#NUM_MESSAGES
109e623a0f6e3caa9cafec913cf826e946628833517Andy Huang     */
1100972e0793cc321670391d063348aecb5031b2677Mindy Pereira    private int numMessages;
111e623a0f6e3caa9cafec913cf826e946628833517Andy Huang    /**
112e623a0f6e3caa9cafec913cf826e946628833517Andy Huang     * @see UIProvider.ConversationColumns#NUM_DRAFTS
113e623a0f6e3caa9cafec913cf826e946628833517Andy Huang     */
1140972e0793cc321670391d063348aecb5031b2677Mindy Pereira    private int numDrafts;
115e623a0f6e3caa9cafec913cf826e946628833517Andy Huang    /**
116e623a0f6e3caa9cafec913cf826e946628833517Andy Huang     * @see UIProvider.ConversationColumns#SENDING_STATE
117e623a0f6e3caa9cafec913cf826e946628833517Andy Huang     */
1184db59c58c0af9f44d95a12dbe21322bed58cc518Mindy Pereira    public int sendingState;
119e623a0f6e3caa9cafec913cf826e946628833517Andy Huang    /**
120e623a0f6e3caa9cafec913cf826e946628833517Andy Huang     * @see UIProvider.ConversationColumns#PRIORITY
121e623a0f6e3caa9cafec913cf826e946628833517Andy Huang     */
1224db59c58c0af9f44d95a12dbe21322bed58cc518Mindy Pereira    public int priority;
123e623a0f6e3caa9cafec913cf826e946628833517Andy Huang    /**
124e623a0f6e3caa9cafec913cf826e946628833517Andy Huang     * @see UIProvider.ConversationColumns#READ
125e623a0f6e3caa9cafec913cf826e946628833517Andy Huang     */
126c8a994227b9c686d88ee05840544162711a85712Marc Blank    public boolean read;
127e623a0f6e3caa9cafec913cf826e946628833517Andy Huang    /**
128d5edd2d02649dffb40065fdb6a16acf91552b800Scott Kennedy     * @see UIProvider.ConversationColumns#SEEN
129d5edd2d02649dffb40065fdb6a16acf91552b800Scott Kennedy     */
130d5edd2d02649dffb40065fdb6a16acf91552b800Scott Kennedy    public boolean seen;
131d5edd2d02649dffb40065fdb6a16acf91552b800Scott Kennedy    /**
132e623a0f6e3caa9cafec913cf826e946628833517Andy Huang     * @see UIProvider.ConversationColumns#STARRED
133e623a0f6e3caa9cafec913cf826e946628833517Andy Huang     */
134c8a994227b9c686d88ee05840544162711a85712Marc Blank    public boolean starred;
135e623a0f6e3caa9cafec913cf826e946628833517Andy Huang    /**
136e623a0f6e3caa9cafec913cf826e946628833517Andy Huang     * @see UIProvider.ConversationColumns#RAW_FOLDERS
137e623a0f6e3caa9cafec913cf826e946628833517Andy Huang     */
138b2033d855ab0f13e253e5403ce25989bcbc49488Andy Huang    private FolderList rawFolders;
139e623a0f6e3caa9cafec913cf826e946628833517Andy Huang    /**
140e623a0f6e3caa9cafec913cf826e946628833517Andy Huang     * @see UIProvider.ConversationColumns#FLAGS
141e623a0f6e3caa9cafec913cf826e946628833517Andy Huang     */
14222657529437c160dec072115c5982409306c1313Mindy Pereira    public int convFlags;
143e623a0f6e3caa9cafec913cf826e946628833517Andy Huang    /**
144e623a0f6e3caa9cafec913cf826e946628833517Andy Huang     * @see UIProvider.ConversationColumns#PERSONAL_LEVEL
145e623a0f6e3caa9cafec913cf826e946628833517Andy Huang     */
14622657529437c160dec072115c5982409306c1313Mindy Pereira    public int personalLevel;
147e623a0f6e3caa9cafec913cf826e946628833517Andy Huang    /**
148e623a0f6e3caa9cafec913cf826e946628833517Andy Huang     * @see UIProvider.ConversationColumns#SPAM
149e623a0f6e3caa9cafec913cf826e946628833517Andy Huang     */
150863e44160d9175023d30e7e225ecb69ad3892eecMindy Pereira    public boolean spam;
151e623a0f6e3caa9cafec913cf826e946628833517Andy Huang    /**
152e623a0f6e3caa9cafec913cf826e946628833517Andy Huang     * @see UIProvider.ConversationColumns#MUTED
153e623a0f6e3caa9cafec913cf826e946628833517Andy Huang     */
154863e44160d9175023d30e7e225ecb69ad3892eecMindy Pereira    public boolean muted;
155e623a0f6e3caa9cafec913cf826e946628833517Andy Huang    /**
15676b2062b8c6d18a7b3a05292c385b47b0fcbd09fPaul Westbrook     * @see UIProvider.ConversationColumns#PHISHING
15776b2062b8c6d18a7b3a05292c385b47b0fcbd09fPaul Westbrook     */
15876b2062b8c6d18a7b3a05292c385b47b0fcbd09fPaul Westbrook    public boolean phishing;
15976b2062b8c6d18a7b3a05292c385b47b0fcbd09fPaul Westbrook    /**
160e623a0f6e3caa9cafec913cf826e946628833517Andy Huang     * @see UIProvider.ConversationColumns#COLOR
161e623a0f6e3caa9cafec913cf826e946628833517Andy Huang     */
16292939fc7b40a56e17fb0d2fde987133ca1614e29Marc Blank    public int color;
163e623a0f6e3caa9cafec913cf826e946628833517Andy Huang    /**
164e623a0f6e3caa9cafec913cf826e946628833517Andy Huang     * @see UIProvider.ConversationColumns#ACCOUNT_URI
165e623a0f6e3caa9cafec913cf826e946628833517Andy Huang     */
166a6b671dd9f5ba358a05888b3ab3bf1c5cb5cf493Marc Blank    public Uri accountUri;
167648df3f0b0ebcd3c4adf907d70ff0938e5dfc78fMindy Pereira    /**
168648df3f0b0ebcd3c4adf907d70ff0938e5dfc78fMindy Pereira     * @see UIProvider.ConversationColumns#CONVERSATION_INFO
169648df3f0b0ebcd3c4adf907d70ff0938e5dfc78fMindy Pereira     */
170648df3f0b0ebcd3c4adf907d70ff0938e5dfc78fMindy Pereira    public ConversationInfo conversationInfo;
17141dca185f7683b36bdafd9520c0648c897a95834Paul Westbrook    /**
172cebcc64fbd69618ff89f9fac0bfe9b9e7d7ce104Paul Westbrook     * @see UIProvider.ConversationColumns#CONVERSATION_BASE_URI
17341dca185f7683b36bdafd9520c0648c897a95834Paul Westbrook     */
17441dca185f7683b36bdafd9520c0648c897a95834Paul Westbrook    public Uri conversationBaseUri;
175f98bc898cbc7014a203c35a13427d3f949bce705Andy Huang    /**
176f98bc898cbc7014a203c35a13427d3f949bce705Andy Huang     * @see UIProvider.ConversationColumns#REMOTE
177f98bc898cbc7014a203c35a13427d3f949bce705Andy Huang     */
178f98bc898cbc7014a203c35a13427d3f949bce705Andy Huang    public boolean isRemote;
17922657529437c160dec072115c5982409306c1313Mindy Pereira
180dbb587f15c723ae80edb33f65c29cc2b6c15eba0Scott Kennedy    /**
181dbb587f15c723ae80edb33f65c29cc2b6c15eba0Scott Kennedy     * Used within the UI to indicate the adapter position of this conversation
182dbb587f15c723ae80edb33f65c29cc2b6c15eba0Scott Kennedy     *
183dbb587f15c723ae80edb33f65c29cc2b6c15eba0Scott Kennedy     * @deprecated Keeping this in sync with the desired value is a not always done properly, is a
184dbb587f15c723ae80edb33f65c29cc2b6c15eba0Scott Kennedy     *             source of bugs, and is a bad idea in general. Do not trust this value. Try to
185dbb587f15c723ae80edb33f65c29cc2b6c15eba0Scott Kennedy     *             migrate code away from using it.
186dbb587f15c723ae80edb33f65c29cc2b6c15eba0Scott Kennedy     */
187dbb587f15c723ae80edb33f65c29cc2b6c15eba0Scott Kennedy    @Deprecated
188f892f0a57d5c24b09fdc805f0fe2007ecd0d0e91Marc Blank    public transient int position;
189648df3f0b0ebcd3c4adf907d70ff0938e5dfc78fMindy Pereira    // Used within the UI to indicate that a Conversation should be removed from
190648df3f0b0ebcd3c4adf907d70ff0938e5dfc78fMindy Pereira    // the ConversationCursor when executing an update, e.g. the the
191648df3f0b0ebcd3c4adf907d70ff0938e5dfc78fMindy Pereira    // Conversation is no longer in the ConversationList for the current folder,
192648df3f0b0ebcd3c4adf907d70ff0938e5dfc78fMindy Pereira    // that is it's now in some other folder(s)
193ce53818e1e185a845bd2f7f601c20e7085b40725Marc Blank    public transient boolean localDeleteOnUpdate;
194732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang
195cd5c5eeae167885ffa2959c200233fea2f39c5f7Andy Huang    private transient boolean viewed;
196cd5c5eeae167885ffa2959c200233fea2f39c5f7Andy Huang
1972909b7442130800d6c6c20c1227d65295262f03emindyp    private static String sSubjectAndSnippet;
1982909b7442130800d6c6c20c1227d65295262f03emindyp
199e1d1b07cdb0026097eb80f6c2912a16353aacec1Marc Blank    // Constituents of convFlags below
200648df3f0b0ebcd3c4adf907d70ff0938e5dfc78fMindy Pereira    // Flag indicating that the item has been deleted, but will continue being
201648df3f0b0ebcd3c4adf907d70ff0938e5dfc78fMindy Pereira    // shown in the list Delete/Archive of a mostly-dead item will NOT propagate
202648df3f0b0ebcd3c4adf907d70ff0938e5dfc78fMindy Pereira    // the delete/archive, but WILL remove the item from the cursor
203e1d1b07cdb0026097eb80f6c2912a16353aacec1Marc Blank    public static final int FLAG_MOSTLY_DEAD = 1 << 0;
204e1d1b07cdb0026097eb80f6c2912a16353aacec1Marc Blank
205440fe79194314b25ef5829702494735ce2f1e2e8Vikram Aggarwal    /** An immutable, empty conversation list */
206440fe79194314b25ef5829702494735ce2f1e2e8Vikram Aggarwal    public static final Collection<Conversation> EMPTY = Collections.emptyList();
207440fe79194314b25ef5829702494735ce2f1e2e8Vikram Aggarwal
208732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang    @Override
209732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang    public int describeContents() {
210732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang        return 0;
211732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang    }
212732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang
213732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang    @Override
214732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang    public void writeToParcel(Parcel dest, int flags) {
215732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang        dest.writeLong(id);
216c43bc0a606e41144a780c4f873b5450e0ede0c91Marc Blank        dest.writeParcelable(uri, flags);
217732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang        dest.writeString(subject);
218732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang        dest.writeLong(dateMs);
219732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang        dest.writeString(snippet);
220f98bc898cbc7014a203c35a13427d3f949bce705Andy Huang        dest.writeInt(hasAttachments ? 1 : 0);
221cfb7f33ff8ef9dc60b9143af32de64c7a3d71f36Mindy Pereira        dest.writeParcelable(messageListUri, 0);
2224db59c58c0af9f44d95a12dbe21322bed58cc518Mindy Pereira        dest.writeString(senders);
2234db59c58c0af9f44d95a12dbe21322bed58cc518Mindy Pereira        dest.writeInt(numMessages);
2244db59c58c0af9f44d95a12dbe21322bed58cc518Mindy Pereira        dest.writeInt(numDrafts);
2254db59c58c0af9f44d95a12dbe21322bed58cc518Mindy Pereira        dest.writeInt(sendingState);
2264db59c58c0af9f44d95a12dbe21322bed58cc518Mindy Pereira        dest.writeInt(priority);
227f98bc898cbc7014a203c35a13427d3f949bce705Andy Huang        dest.writeInt(read ? 1 : 0);
228d5edd2d02649dffb40065fdb6a16acf91552b800Scott Kennedy        dest.writeInt(seen ? 1 : 0);
229f98bc898cbc7014a203c35a13427d3f949bce705Andy Huang        dest.writeInt(starred ? 1 : 0);
230b2033d855ab0f13e253e5403ce25989bcbc49488Andy Huang        dest.writeParcelable(rawFolders, 0);
23122657529437c160dec072115c5982409306c1313Mindy Pereira        dest.writeInt(convFlags);
23222657529437c160dec072115c5982409306c1313Mindy Pereira        dest.writeInt(personalLevel);
233863e44160d9175023d30e7e225ecb69ad3892eecMindy Pereira        dest.writeInt(spam ? 1 : 0);
23476b2062b8c6d18a7b3a05292c385b47b0fcbd09fPaul Westbrook        dest.writeInt(phishing ? 1 : 0);
235863e44160d9175023d30e7e225ecb69ad3892eecMindy Pereira        dest.writeInt(muted ? 1 : 0);
23692939fc7b40a56e17fb0d2fde987133ca1614e29Marc Blank        dest.writeInt(color);
237a6b671dd9f5ba358a05888b3ab3bf1c5cb5cf493Marc Blank        dest.writeParcelable(accountUri, 0);
238351ad4e87e0b0b98df9ca88266a8a63541dc5a81Andy Huang        dest.writeParcelable(conversationInfo, 0);
23941dca185f7683b36bdafd9520c0648c897a95834Paul Westbrook        dest.writeParcelable(conversationBaseUri, 0);
240f98bc898cbc7014a203c35a13427d3f949bce705Andy Huang        dest.writeInt(isRemote ? 1 : 0);
241479505d71969e26b0785d8e0e1b81108731cf827Mark Wei        dest.writeString(attachmentPreviewUri0);
242479505d71969e26b0785d8e0e1b81108731cf827Mark Wei        dest.writeString(attachmentPreviewUri1);
243479505d71969e26b0785d8e0e1b81108731cf827Mark Wei        dest.writeInt(attachmentPreviewStates);
244479505d71969e26b0785d8e0e1b81108731cf827Mark Wei        dest.writeInt(attachmentPreviewsCount);
245479505d71969e26b0785d8e0e1b81108731cf827Mark Wei        dest.writeParcelable(attachmentPreviewsListUri, 0);
246732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang    }
247732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang
248351ad4e87e0b0b98df9ca88266a8a63541dc5a81Andy Huang    private Conversation(Parcel in, ClassLoader loader) {
249732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang        id = in.readLong();
250c43bc0a606e41144a780c4f873b5450e0ede0c91Marc Blank        uri = in.readParcelable(null);
251732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang        subject = in.readString();
252732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang        dateMs = in.readLong();
253732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang        snippet = in.readString();
254f98bc898cbc7014a203c35a13427d3f949bce705Andy Huang        hasAttachments = (in.readInt() != 0);
255cfb7f33ff8ef9dc60b9143af32de64c7a3d71f36Mindy Pereira        messageListUri = in.readParcelable(null);
256820f051b37b45b3e3729bda5c4302a879ee6aa4dPaul Westbrook        senders = emptyIfNull(in.readString());
2574db59c58c0af9f44d95a12dbe21322bed58cc518Mindy Pereira        numMessages = in.readInt();
2584db59c58c0af9f44d95a12dbe21322bed58cc518Mindy Pereira        numDrafts = in.readInt();
2594db59c58c0af9f44d95a12dbe21322bed58cc518Mindy Pereira        sendingState = in.readInt();
2604db59c58c0af9f44d95a12dbe21322bed58cc518Mindy Pereira        priority = in.readInt();
261f98bc898cbc7014a203c35a13427d3f949bce705Andy Huang        read = (in.readInt() != 0);
262d5edd2d02649dffb40065fdb6a16acf91552b800Scott Kennedy        seen = (in.readInt() != 0);
263f98bc898cbc7014a203c35a13427d3f949bce705Andy Huang        starred = (in.readInt() != 0);
264b2033d855ab0f13e253e5403ce25989bcbc49488Andy Huang        rawFolders = in.readParcelable(loader);
26522657529437c160dec072115c5982409306c1313Mindy Pereira        convFlags = in.readInt();
26622657529437c160dec072115c5982409306c1313Mindy Pereira        personalLevel = in.readInt();
267863e44160d9175023d30e7e225ecb69ad3892eecMindy Pereira        spam = in.readInt() != 0;
26876b2062b8c6d18a7b3a05292c385b47b0fcbd09fPaul Westbrook        phishing = in.readInt() != 0;
269863e44160d9175023d30e7e225ecb69ad3892eecMindy Pereira        muted = in.readInt() != 0;
27092939fc7b40a56e17fb0d2fde987133ca1614e29Marc Blank        color = in.readInt();
271a6b671dd9f5ba358a05888b3ab3bf1c5cb5cf493Marc Blank        accountUri = in.readParcelable(null);
272f892f0a57d5c24b09fdc805f0fe2007ecd0d0e91Marc Blank        position = NO_POSITION;
273ce53818e1e185a845bd2f7f601c20e7085b40725Marc Blank        localDeleteOnUpdate = false;
274351ad4e87e0b0b98df9ca88266a8a63541dc5a81Andy Huang        conversationInfo = in.readParcelable(loader);
27541dca185f7683b36bdafd9520c0648c897a95834Paul Westbrook        conversationBaseUri = in.readParcelable(null);
276f98bc898cbc7014a203c35a13427d3f949bce705Andy Huang        isRemote = in.readInt() != 0;
277479505d71969e26b0785d8e0e1b81108731cf827Mark Wei        attachmentPreviews = null;
278479505d71969e26b0785d8e0e1b81108731cf827Mark Wei        attachmentPreviewUri0 = in.readString();
279479505d71969e26b0785d8e0e1b81108731cf827Mark Wei        attachmentPreviewUri1 = in.readString();
280479505d71969e26b0785d8e0e1b81108731cf827Mark Wei        attachmentPreviewStates = in.readInt();
281479505d71969e26b0785d8e0e1b81108731cf827Mark Wei        attachmentPreviewsCount = in.readInt();
282479505d71969e26b0785d8e0e1b81108731cf827Mark Wei        attachmentPreviewsListUri = in.readParcelable(null);
283732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang    }
284732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang
285732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang    @Override
286732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang    public String toString() {
2879e4ca7993213d296043d20fe9cf4e166b5d595e8Andy Huang        // log extra info at DEBUG level or finer
2889e4ca7993213d296043d20fe9cf4e166b5d595e8Andy Huang        final StringBuilder sb = new StringBuilder("[conversation id=");
2899e4ca7993213d296043d20fe9cf4e166b5d595e8Andy Huang        sb.append(id);
2909e4ca7993213d296043d20fe9cf4e166b5d595e8Andy Huang        if (LogUtils.isLoggable(LOG_TAG, LogUtils.DEBUG)) {
2919e4ca7993213d296043d20fe9cf4e166b5d595e8Andy Huang            sb.append(", subject=");
2929e4ca7993213d296043d20fe9cf4e166b5d595e8Andy Huang            sb.append(subject);
2939e4ca7993213d296043d20fe9cf4e166b5d595e8Andy Huang        }
2949e4ca7993213d296043d20fe9cf4e166b5d595e8Andy Huang        sb.append("]");
2959e4ca7993213d296043d20fe9cf4e166b5d595e8Andy Huang        return sb.toString();
296732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang    }
297732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang
298351ad4e87e0b0b98df9ca88266a8a63541dc5a81Andy Huang    public static final ClassLoaderCreator<Conversation> CREATOR =
299351ad4e87e0b0b98df9ca88266a8a63541dc5a81Andy Huang            new ClassLoaderCreator<Conversation>() {
300732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang
301732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang        @Override
302732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang        public Conversation createFromParcel(Parcel source) {
303351ad4e87e0b0b98df9ca88266a8a63541dc5a81Andy Huang            return new Conversation(source, null);
304351ad4e87e0b0b98df9ca88266a8a63541dc5a81Andy Huang        }
305351ad4e87e0b0b98df9ca88266a8a63541dc5a81Andy Huang
306351ad4e87e0b0b98df9ca88266a8a63541dc5a81Andy Huang        @Override
307351ad4e87e0b0b98df9ca88266a8a63541dc5a81Andy Huang        public Conversation createFromParcel(Parcel source, ClassLoader loader) {
308351ad4e87e0b0b98df9ca88266a8a63541dc5a81Andy Huang            return new Conversation(source, loader);
309732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang        }
310732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang
311732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang        @Override
312732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang        public Conversation[] newArray(int size) {
313732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang            return new Conversation[size];
314732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang        }
315732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang
316732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang    };
317732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang
318acf6039a23382f18c35f6b487d90d53cb67b5858Mindy Pereira    public static final Uri MOVE_CONVERSATIONS_URI = Uri.parse("content://moveconversations");
319acf6039a23382f18c35f6b487d90d53cb67b5858Mindy Pereira
320ebdfd98264104cb5a6888acd663970b7c0b31382Mindy Pereira    /**
321ae7e6a0786a2d890b77c783d7ac39a90523b8154mindyp     * The column that needs to be updated to change the folders for a conversation.
322ebdfd98264104cb5a6888acd663970b7c0b31382Mindy Pereira     */
32300ffece08e94ff5774b2a53c0adeb2f3d0815d66Mindy Pereira    public static final String UPDATE_FOLDER_COLUMN = ConversationColumns.RAW_FOLDERS;
324ebdfd98264104cb5a6888acd663970b7c0b31382Mindy Pereira
325a831b2f1ba6d3c18d5e54563df8bae1f589c4257Mindy Pereira    public Conversation(Cursor cursor) {
326732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang        if (cursor != null) {
327732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang            id = cursor.getLong(UIProvider.CONVERSATION_ID_COLUMN);
328c43bc0a606e41144a780c4f873b5450e0ede0c91Marc Blank            uri = Uri.parse(cursor.getString(UIProvider.CONVERSATION_URI_COLUMN));
329732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang            dateMs = cursor.getLong(UIProvider.CONVERSATION_DATE_RECEIVED_MS_COLUMN);
330732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang            subject = cursor.getString(UIProvider.CONVERSATION_SUBJECT_COLUMN);
331374863eeb0ee37f1ca7d57840e6f02aaa052e284Marc Blank            // Don't allow null subject
332374863eeb0ee37f1ca7d57840e6f02aaa052e284Marc Blank            if (subject == null) {
333374863eeb0ee37f1ca7d57840e6f02aaa052e284Marc Blank                subject = "";
334374863eeb0ee37f1ca7d57840e6f02aaa052e284Marc Blank            }
33587d535fe423d782c3a0343c649330d309976f655Mindy Pereira            hasAttachments = cursor.getInt(UIProvider.CONVERSATION_HAS_ATTACHMENTS_COLUMN) != 0;
336648df3f0b0ebcd3c4adf907d70ff0938e5dfc78fMindy Pereira            String messageList = cursor.getString(UIProvider.CONVERSATION_MESSAGE_LIST_URI_COLUMN);
3375c765b9c5dd8a9a9421260ba8b46d06073391c73Mindy Pereira            messageListUri = !TextUtils.isEmpty(messageList) ? Uri.parse(messageList) : null;
3384db59c58c0af9f44d95a12dbe21322bed58cc518Mindy Pereira            sendingState = cursor.getInt(UIProvider.CONVERSATION_SENDING_STATE_COLUMN);
3394db59c58c0af9f44d95a12dbe21322bed58cc518Mindy Pereira            priority = cursor.getInt(UIProvider.CONVERSATION_PRIORITY_COLUMN);
34087d535fe423d782c3a0343c649330d309976f655Mindy Pereira            read = cursor.getInt(UIProvider.CONVERSATION_READ_COLUMN) != 0;
341d5edd2d02649dffb40065fdb6a16acf91552b800Scott Kennedy            seen = cursor.getInt(UIProvider.CONVERSATION_SEEN_COLUMN) != 0;
34287d535fe423d782c3a0343c649330d309976f655Mindy Pereira            starred = cursor.getInt(UIProvider.CONVERSATION_STARRED_COLUMN) != 0;
3437f39bbd358f7003a72ae2b480dfe38a84e830e5fAndy Huang            rawFolders = readRawFolders(cursor);
34422657529437c160dec072115c5982409306c1313Mindy Pereira            convFlags = cursor.getInt(UIProvider.CONVERSATION_FLAGS_COLUMN);
34522657529437c160dec072115c5982409306c1313Mindy Pereira            personalLevel = cursor.getInt(UIProvider.CONVERSATION_PERSONAL_LEVEL_COLUMN);
346863e44160d9175023d30e7e225ecb69ad3892eecMindy Pereira            spam = cursor.getInt(UIProvider.CONVERSATION_IS_SPAM_COLUMN) != 0;
34776b2062b8c6d18a7b3a05292c385b47b0fcbd09fPaul Westbrook            phishing = cursor.getInt(UIProvider.CONVERSATION_IS_PHISHING_COLUMN) != 0;
348863e44160d9175023d30e7e225ecb69ad3892eecMindy Pereira            muted = cursor.getInt(UIProvider.CONVERSATION_MUTED_COLUMN) != 0;
34992939fc7b40a56e17fb0d2fde987133ca1614e29Marc Blank            color = cursor.getInt(UIProvider.CONVERSATION_COLOR_COLUMN);
350a6b671dd9f5ba358a05888b3ab3bf1c5cb5cf493Marc Blank            String account = cursor.getString(UIProvider.CONVERSATION_ACCOUNT_URI_COLUMN);
351a6b671dd9f5ba358a05888b3ab3bf1c5cb5cf493Marc Blank            accountUri = !TextUtils.isEmpty(account) ? Uri.parse(account) : null;
352f892f0a57d5c24b09fdc805f0fe2007ecd0d0e91Marc Blank            position = NO_POSITION;
353ce53818e1e185a845bd2f7f601c20e7085b40725Marc Blank            localDeleteOnUpdate = false;
3547f39bbd358f7003a72ae2b480dfe38a84e830e5fAndy Huang            conversationInfo = readConversationInfo(cursor);
35541dca185f7683b36bdafd9520c0648c897a95834Paul Westbrook            final String conversationBase =
35641dca185f7683b36bdafd9520c0648c897a95834Paul Westbrook                    cursor.getString(UIProvider.CONVERSATION_BASE_URI_COLUMN);
35741dca185f7683b36bdafd9520c0648c897a95834Paul Westbrook            conversationBaseUri = !TextUtils.isEmpty(conversationBase) ?
35841dca185f7683b36bdafd9520c0648c897a95834Paul Westbrook                    Uri.parse(conversationBase) : null;
359e8a3eecf0a481665c5e886ebfb4a6184b5125f78Mindy Pereira            if (conversationInfo == null) {
360e8a3eecf0a481665c5e886ebfb4a6184b5125f78Mindy Pereira                snippet = cursor.getString(UIProvider.CONVERSATION_SNIPPET_COLUMN);
361820f051b37b45b3e3729bda5c4302a879ee6aa4dPaul Westbrook                senders = emptyIfNull(cursor.getString(UIProvider.CONVERSATION_SENDER_INFO_COLUMN));
3620972e0793cc321670391d063348aecb5031b2677Mindy Pereira                numMessages = cursor.getInt(UIProvider.CONVERSATION_NUM_MESSAGES_COLUMN);
3630972e0793cc321670391d063348aecb5031b2677Mindy Pereira                numDrafts = cursor.getInt(UIProvider.CONVERSATION_NUM_DRAFTS_COLUMN);
364e8a3eecf0a481665c5e886ebfb4a6184b5125f78Mindy Pereira            }
365f98bc898cbc7014a203c35a13427d3f949bce705Andy Huang            isRemote = cursor.getInt(UIProvider.CONVERSATION_REMOTE_COLUMN) != 0;
366479505d71969e26b0785d8e0e1b81108731cf827Mark Wei            attachmentPreviews = null;
367479505d71969e26b0785d8e0e1b81108731cf827Mark Wei            attachmentPreviewUri0 = cursor.getString(
368479505d71969e26b0785d8e0e1b81108731cf827Mark Wei                    UIProvider.CONVERSATION_ATTACHMENT_PREVIEW_URI0_COLUMN);
369479505d71969e26b0785d8e0e1b81108731cf827Mark Wei            attachmentPreviewUri1 = cursor.getString(
370479505d71969e26b0785d8e0e1b81108731cf827Mark Wei                    UIProvider.CONVERSATION_ATTACHMENT_PREVIEW_URI1_COLUMN);
371479505d71969e26b0785d8e0e1b81108731cf827Mark Wei            attachmentPreviewStates = cursor.getInt(
372479505d71969e26b0785d8e0e1b81108731cf827Mark Wei                    UIProvider.CONVERSATION_ATTACHMENT_PREVIEW_STATES_COLUMN);
373479505d71969e26b0785d8e0e1b81108731cf827Mark Wei            attachmentPreviewsCount = cursor.getInt(
374479505d71969e26b0785d8e0e1b81108731cf827Mark Wei                    UIProvider.CONVERSATION_ATTACHMENT_PREVIEWS_COUNT_COLUMN);
375479505d71969e26b0785d8e0e1b81108731cf827Mark Wei            attachmentPreviewsListUri = Utils.getValidUri(cursor
376479505d71969e26b0785d8e0e1b81108731cf827Mark Wei                    .getString(UIProvider.CONVERSATION_ATTACHMENT_PREVIEWS_LIST_URI_COLUMN));
377732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang        }
378732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang    }
379732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang
3801bca265b7a8a3f9ea08e0ae51eeb145f0883a266Andy Huang    public Conversation(Conversation other) {
3811bca265b7a8a3f9ea08e0ae51eeb145f0883a266Andy Huang        if (other == null) {
3821bca265b7a8a3f9ea08e0ae51eeb145f0883a266Andy Huang            return;
3831bca265b7a8a3f9ea08e0ae51eeb145f0883a266Andy Huang        }
3841bca265b7a8a3f9ea08e0ae51eeb145f0883a266Andy Huang
3851bca265b7a8a3f9ea08e0ae51eeb145f0883a266Andy Huang        id = other.id;
3861bca265b7a8a3f9ea08e0ae51eeb145f0883a266Andy Huang        uri = other.uri;
3871bca265b7a8a3f9ea08e0ae51eeb145f0883a266Andy Huang        dateMs = other.dateMs;
3881bca265b7a8a3f9ea08e0ae51eeb145f0883a266Andy Huang        subject = other.subject;
3891bca265b7a8a3f9ea08e0ae51eeb145f0883a266Andy Huang        hasAttachments = other.hasAttachments;
3901bca265b7a8a3f9ea08e0ae51eeb145f0883a266Andy Huang        messageListUri = other.messageListUri;
3911bca265b7a8a3f9ea08e0ae51eeb145f0883a266Andy Huang        sendingState = other.sendingState;
3921bca265b7a8a3f9ea08e0ae51eeb145f0883a266Andy Huang        priority = other.priority;
3931bca265b7a8a3f9ea08e0ae51eeb145f0883a266Andy Huang        read = other.read;
3941bca265b7a8a3f9ea08e0ae51eeb145f0883a266Andy Huang        seen = other.seen;
3951bca265b7a8a3f9ea08e0ae51eeb145f0883a266Andy Huang        starred = other.starred;
3961bca265b7a8a3f9ea08e0ae51eeb145f0883a266Andy Huang        rawFolders = other.rawFolders; // FolderList is immutable, shallow copy is OK
3971bca265b7a8a3f9ea08e0ae51eeb145f0883a266Andy Huang        convFlags = other.convFlags;
3981bca265b7a8a3f9ea08e0ae51eeb145f0883a266Andy Huang        personalLevel = other.personalLevel;
3991bca265b7a8a3f9ea08e0ae51eeb145f0883a266Andy Huang        spam = other.spam;
4001bca265b7a8a3f9ea08e0ae51eeb145f0883a266Andy Huang        phishing = other.phishing;
4011bca265b7a8a3f9ea08e0ae51eeb145f0883a266Andy Huang        muted = other.muted;
4021bca265b7a8a3f9ea08e0ae51eeb145f0883a266Andy Huang        color = other.color;
4031bca265b7a8a3f9ea08e0ae51eeb145f0883a266Andy Huang        accountUri = other.accountUri;
4041bca265b7a8a3f9ea08e0ae51eeb145f0883a266Andy Huang        position = other.position;
4051bca265b7a8a3f9ea08e0ae51eeb145f0883a266Andy Huang        localDeleteOnUpdate = other.localDeleteOnUpdate;
4061bca265b7a8a3f9ea08e0ae51eeb145f0883a266Andy Huang        // although ConversationInfo is mutable (see ConversationInfo.markRead), applyCachedValues
4071bca265b7a8a3f9ea08e0ae51eeb145f0883a266Andy Huang        // will overwrite this if cached changes exist anyway, so a shallow copy is OK
4081bca265b7a8a3f9ea08e0ae51eeb145f0883a266Andy Huang        conversationInfo = other.conversationInfo;
4091bca265b7a8a3f9ea08e0ae51eeb145f0883a266Andy Huang        conversationBaseUri = other.conversationBaseUri;
4101bca265b7a8a3f9ea08e0ae51eeb145f0883a266Andy Huang        snippet = other.snippet;
4111bca265b7a8a3f9ea08e0ae51eeb145f0883a266Andy Huang        senders = other.senders;
4121bca265b7a8a3f9ea08e0ae51eeb145f0883a266Andy Huang        numMessages = other.numMessages;
4131bca265b7a8a3f9ea08e0ae51eeb145f0883a266Andy Huang        numDrafts = other.numDrafts;
4141bca265b7a8a3f9ea08e0ae51eeb145f0883a266Andy Huang        isRemote = other.isRemote;
415479505d71969e26b0785d8e0e1b81108731cf827Mark Wei        attachmentPreviews = null;
416479505d71969e26b0785d8e0e1b81108731cf827Mark Wei        attachmentPreviewUri0 = other.attachmentPreviewUri0;
417479505d71969e26b0785d8e0e1b81108731cf827Mark Wei        attachmentPreviewUri1 = other.attachmentPreviewUri1;
418479505d71969e26b0785d8e0e1b81108731cf827Mark Wei        attachmentPreviewStates = other.attachmentPreviewStates;
419479505d71969e26b0785d8e0e1b81108731cf827Mark Wei        attachmentPreviewsCount = other.attachmentPreviewsCount;
420479505d71969e26b0785d8e0e1b81108731cf827Mark Wei        attachmentPreviewsListUri = other.attachmentPreviewsListUri;
4211bca265b7a8a3f9ea08e0ae51eeb145f0883a266Andy Huang    }
4221bca265b7a8a3f9ea08e0ae51eeb145f0883a266Andy Huang
423bf232c3735f65b1a4746943e4a134e59e36f0bdePaul Westbrook    public Conversation() {
424ff5c757ed2bcf7004a70b0675382ef894196558dPaul Westbrook    }
425ff5c757ed2bcf7004a70b0675382ef894196558dPaul Westbrook
426479505d71969e26b0785d8e0e1b81108731cf827Mark Wei    public static Conversation create(long id, Uri uri, String subject, long dateMs, String snippet,
427479505d71969e26b0785d8e0e1b81108731cf827Mark Wei            boolean hasAttachment, Uri messageListUri, String senders,
428863e44160d9175023d30e7e225ecb69ad3892eecMindy Pereira            int numMessages, int numDrafts, int sendingState, int priority, boolean read,
429d5edd2d02649dffb40065fdb6a16acf91552b800Scott Kennedy            boolean seen, boolean starred, FolderList rawFolders, int convFlags, int personalLevel,
430d5edd2d02649dffb40065fdb6a16acf91552b800Scott Kennedy            boolean spam, boolean phishing, boolean muted, Uri accountUri,
431479505d71969e26b0785d8e0e1b81108731cf827Mark Wei            ConversationInfo conversationInfo, Uri conversationBase, boolean isRemote,
432479505d71969e26b0785d8e0e1b81108731cf827Mark Wei            String attachmentPreviewUri0, String attachmentPreviewUri1, int attachmentPreviewStates,
433479505d71969e26b0785d8e0e1b81108731cf827Mark Wei            int attachmentPreviewsCount, Uri attachmentPreviewsListUri) {
434ff5c757ed2bcf7004a70b0675382ef894196558dPaul Westbrook        final Conversation conversation = new Conversation();
435ff5c757ed2bcf7004a70b0675382ef894196558dPaul Westbrook
436ff5c757ed2bcf7004a70b0675382ef894196558dPaul Westbrook        conversation.id = id;
437ff5c757ed2bcf7004a70b0675382ef894196558dPaul Westbrook        conversation.uri = uri;
438ff5c757ed2bcf7004a70b0675382ef894196558dPaul Westbrook        conversation.subject = subject;
439ff5c757ed2bcf7004a70b0675382ef894196558dPaul Westbrook        conversation.dateMs = dateMs;
440ff5c757ed2bcf7004a70b0675382ef894196558dPaul Westbrook        conversation.snippet = snippet;
441ff5c757ed2bcf7004a70b0675382ef894196558dPaul Westbrook        conversation.hasAttachments = hasAttachment;
442ff5c757ed2bcf7004a70b0675382ef894196558dPaul Westbrook        conversation.messageListUri = messageListUri;
443820f051b37b45b3e3729bda5c4302a879ee6aa4dPaul Westbrook        conversation.senders = emptyIfNull(senders);
444ff5c757ed2bcf7004a70b0675382ef894196558dPaul Westbrook        conversation.numMessages = numMessages;
445ff5c757ed2bcf7004a70b0675382ef894196558dPaul Westbrook        conversation.numDrafts = numDrafts;
446ff5c757ed2bcf7004a70b0675382ef894196558dPaul Westbrook        conversation.sendingState = sendingState;
447ff5c757ed2bcf7004a70b0675382ef894196558dPaul Westbrook        conversation.priority = priority;
448ff5c757ed2bcf7004a70b0675382ef894196558dPaul Westbrook        conversation.read = read;
449d5edd2d02649dffb40065fdb6a16acf91552b800Scott Kennedy        conversation.seen = seen;
450ff5c757ed2bcf7004a70b0675382ef894196558dPaul Westbrook        conversation.starred = starred;
451ff5c757ed2bcf7004a70b0675382ef894196558dPaul Westbrook        conversation.rawFolders = rawFolders;
452ff5c757ed2bcf7004a70b0675382ef894196558dPaul Westbrook        conversation.convFlags = convFlags;
453ff5c757ed2bcf7004a70b0675382ef894196558dPaul Westbrook        conversation.personalLevel = personalLevel;
454863e44160d9175023d30e7e225ecb69ad3892eecMindy Pereira        conversation.spam = spam;
45576b2062b8c6d18a7b3a05292c385b47b0fcbd09fPaul Westbrook        conversation.phishing = phishing;
456863e44160d9175023d30e7e225ecb69ad3892eecMindy Pereira        conversation.muted = muted;
45792939fc7b40a56e17fb0d2fde987133ca1614e29Marc Blank        conversation.color = 0;
458a6b671dd9f5ba358a05888b3ab3bf1c5cb5cf493Marc Blank        conversation.accountUri = accountUri;
4597e854f52f0890b9621846ac7fe201a5681e65666Andy Huang        conversation.conversationInfo = conversationInfo;
46041dca185f7683b36bdafd9520c0648c897a95834Paul Westbrook        conversation.conversationBaseUri = conversationBase;
461f98bc898cbc7014a203c35a13427d3f949bce705Andy Huang        conversation.isRemote = isRemote;
462479505d71969e26b0785d8e0e1b81108731cf827Mark Wei        conversation.attachmentPreviews = null;
463479505d71969e26b0785d8e0e1b81108731cf827Mark Wei        conversation.attachmentPreviewUri0 = attachmentPreviewUri0;
464479505d71969e26b0785d8e0e1b81108731cf827Mark Wei        conversation.attachmentPreviewUri1 = attachmentPreviewUri1;
465479505d71969e26b0785d8e0e1b81108731cf827Mark Wei        conversation.attachmentPreviewStates = attachmentPreviewStates;
466479505d71969e26b0785d8e0e1b81108731cf827Mark Wei        conversation.attachmentPreviewsCount = attachmentPreviewsCount;
467479505d71969e26b0785d8e0e1b81108731cf827Mark Wei        conversation.attachmentPreviewsListUri = attachmentPreviewsListUri;
468ff5c757ed2bcf7004a70b0675382ef894196558dPaul Westbrook        return conversation;
469ff5c757ed2bcf7004a70b0675382ef894196558dPaul Westbrook    }
470ff5c757ed2bcf7004a70b0675382ef894196558dPaul Westbrook
4717f39bbd358f7003a72ae2b480dfe38a84e830e5fAndy Huang    private static final Bundle sConversationInfoRequest = new Bundle(1);
4727f39bbd358f7003a72ae2b480dfe38a84e830e5fAndy Huang    private static final Bundle sRawFoldersRequest = new Bundle(1);
4737f39bbd358f7003a72ae2b480dfe38a84e830e5fAndy Huang
4747f39bbd358f7003a72ae2b480dfe38a84e830e5fAndy Huang    private static ConversationInfo readConversationInfo(Cursor cursor) {
4757f39bbd358f7003a72ae2b480dfe38a84e830e5fAndy Huang        final ConversationInfo ci;
4767f39bbd358f7003a72ae2b480dfe38a84e830e5fAndy Huang
477f8b613c1103952ae5cc1f8a5e6ae60aa62d73decAndy Huang        if (cursor instanceof ConversationCursor) {
478f8b613c1103952ae5cc1f8a5e6ae60aa62d73decAndy Huang            final byte[] blob = ((ConversationCursor) cursor).getCachedBlob(
479f8b613c1103952ae5cc1f8a5e6ae60aa62d73decAndy Huang                    UIProvider.CONVERSATION_INFO_COLUMN);
480f8b613c1103952ae5cc1f8a5e6ae60aa62d73decAndy Huang            if (blob != null && blob.length > 0) {
481f8b613c1103952ae5cc1f8a5e6ae60aa62d73decAndy Huang                return ConversationInfo.fromBlob(blob);
482f8b613c1103952ae5cc1f8a5e6ae60aa62d73decAndy Huang            }
483f8b613c1103952ae5cc1f8a5e6ae60aa62d73decAndy Huang        }
484f8b613c1103952ae5cc1f8a5e6ae60aa62d73decAndy Huang
4857f39bbd358f7003a72ae2b480dfe38a84e830e5fAndy Huang        final String key = UIProvider.ConversationCursorCommand.COMMAND_GET_CONVERSATION_INFO;
4867f39bbd358f7003a72ae2b480dfe38a84e830e5fAndy Huang        if (sConversationInfoRequest.isEmpty()) {
4877f39bbd358f7003a72ae2b480dfe38a84e830e5fAndy Huang            sConversationInfoRequest.putBoolean(key, true);
488d521baf3a51c9fc1306bd55e027ce57d0a1d18aaAndy Huang            sConversationInfoRequest.putInt(
489d521baf3a51c9fc1306bd55e027ce57d0a1d18aaAndy Huang                    UIProvider.ConversationCursorCommand.COMMAND_KEY_OPTIONS,
490d521baf3a51c9fc1306bd55e027ce57d0a1d18aaAndy Huang                    UIProvider.ConversationCursorCommand.OPTION_MOVE_POSITION);
4917f39bbd358f7003a72ae2b480dfe38a84e830e5fAndy Huang        }
4927f39bbd358f7003a72ae2b480dfe38a84e830e5fAndy Huang        final Bundle response = cursor.respond(sConversationInfoRequest);
4937f39bbd358f7003a72ae2b480dfe38a84e830e5fAndy Huang        if (response.containsKey(key)) {
4947f39bbd358f7003a72ae2b480dfe38a84e830e5fAndy Huang            ci = response.getParcelable(key);
4957f39bbd358f7003a72ae2b480dfe38a84e830e5fAndy Huang        } else {
4967f39bbd358f7003a72ae2b480dfe38a84e830e5fAndy Huang            // legacy fallback
4977f39bbd358f7003a72ae2b480dfe38a84e830e5fAndy Huang            ci = ConversationInfo.fromBlob(cursor.getBlob(UIProvider.CONVERSATION_INFO_COLUMN));
4987f39bbd358f7003a72ae2b480dfe38a84e830e5fAndy Huang        }
4997f39bbd358f7003a72ae2b480dfe38a84e830e5fAndy Huang        return ci;
5007f39bbd358f7003a72ae2b480dfe38a84e830e5fAndy Huang    }
5017f39bbd358f7003a72ae2b480dfe38a84e830e5fAndy Huang
5027f39bbd358f7003a72ae2b480dfe38a84e830e5fAndy Huang    private static FolderList readRawFolders(Cursor cursor) {
5037f39bbd358f7003a72ae2b480dfe38a84e830e5fAndy Huang        final FolderList fl;
5047f39bbd358f7003a72ae2b480dfe38a84e830e5fAndy Huang
505f8b613c1103952ae5cc1f8a5e6ae60aa62d73decAndy Huang        if (cursor instanceof ConversationCursor) {
506f8b613c1103952ae5cc1f8a5e6ae60aa62d73decAndy Huang            final byte[] blob = ((ConversationCursor) cursor).getCachedBlob(
507f8b613c1103952ae5cc1f8a5e6ae60aa62d73decAndy Huang                    UIProvider.CONVERSATION_RAW_FOLDERS_COLUMN);
508f8b613c1103952ae5cc1f8a5e6ae60aa62d73decAndy Huang            if (blob != null && blob.length > 0) {
509f8b613c1103952ae5cc1f8a5e6ae60aa62d73decAndy Huang                return FolderList.fromBlob(blob);
510f8b613c1103952ae5cc1f8a5e6ae60aa62d73decAndy Huang            }
511f8b613c1103952ae5cc1f8a5e6ae60aa62d73decAndy Huang        }
512f8b613c1103952ae5cc1f8a5e6ae60aa62d73decAndy Huang
5137f39bbd358f7003a72ae2b480dfe38a84e830e5fAndy Huang        final String key = UIProvider.ConversationCursorCommand.COMMAND_GET_RAW_FOLDERS;
5147f39bbd358f7003a72ae2b480dfe38a84e830e5fAndy Huang        if (sRawFoldersRequest.isEmpty()) {
5157f39bbd358f7003a72ae2b480dfe38a84e830e5fAndy Huang            sRawFoldersRequest.putBoolean(key, true);
516d521baf3a51c9fc1306bd55e027ce57d0a1d18aaAndy Huang            sRawFoldersRequest.putInt(
517d521baf3a51c9fc1306bd55e027ce57d0a1d18aaAndy Huang                    UIProvider.ConversationCursorCommand.COMMAND_KEY_OPTIONS,
518d521baf3a51c9fc1306bd55e027ce57d0a1d18aaAndy Huang                    UIProvider.ConversationCursorCommand.OPTION_MOVE_POSITION);
5197f39bbd358f7003a72ae2b480dfe38a84e830e5fAndy Huang        }
5207f39bbd358f7003a72ae2b480dfe38a84e830e5fAndy Huang        final Bundle response = cursor.respond(sRawFoldersRequest);
5217f39bbd358f7003a72ae2b480dfe38a84e830e5fAndy Huang        if (response.containsKey(key)) {
5227f39bbd358f7003a72ae2b480dfe38a84e830e5fAndy Huang            fl = response.getParcelable(key);
5237f39bbd358f7003a72ae2b480dfe38a84e830e5fAndy Huang        } else {
5247f39bbd358f7003a72ae2b480dfe38a84e830e5fAndy Huang            // legacy fallback
525db5356a92ebc593e9eb564aaadad8dac8cd83554Paul Westbrook            // TODO: delete this once Email supports the respond call
5267f39bbd358f7003a72ae2b480dfe38a84e830e5fAndy Huang            fl = FolderList.fromBlob(
5277f39bbd358f7003a72ae2b480dfe38a84e830e5fAndy Huang                    cursor.getBlob(UIProvider.CONVERSATION_RAW_FOLDERS_COLUMN));
5287f39bbd358f7003a72ae2b480dfe38a84e830e5fAndy Huang        }
5297f39bbd358f7003a72ae2b480dfe38a84e830e5fAndy Huang        return fl;
5307f39bbd358f7003a72ae2b480dfe38a84e830e5fAndy Huang    }
5317f39bbd358f7003a72ae2b480dfe38a84e830e5fAndy Huang
532b2033d855ab0f13e253e5403ce25989bcbc49488Andy Huang    /**
5331bca265b7a8a3f9ea08e0ae51eeb145f0883a266Andy Huang     * Apply any column values from the given {@link ContentValues} (where column names are the
5341bca265b7a8a3f9ea08e0ae51eeb145f0883a266Andy Huang     * keys) to this conversation.
5351bca265b7a8a3f9ea08e0ae51eeb145f0883a266Andy Huang     *
5361bca265b7a8a3f9ea08e0ae51eeb145f0883a266Andy Huang     */
5371bca265b7a8a3f9ea08e0ae51eeb145f0883a266Andy Huang    public void applyCachedValues(ContentValues values) {
5381bca265b7a8a3f9ea08e0ae51eeb145f0883a266Andy Huang        if (values == null) {
5391bca265b7a8a3f9ea08e0ae51eeb145f0883a266Andy Huang            return;
5401bca265b7a8a3f9ea08e0ae51eeb145f0883a266Andy Huang        }
5411bca265b7a8a3f9ea08e0ae51eeb145f0883a266Andy Huang        for (String key : values.keySet()) {
5421bca265b7a8a3f9ea08e0ae51eeb145f0883a266Andy Huang            final Object val = values.get(key);
5431bca265b7a8a3f9ea08e0ae51eeb145f0883a266Andy Huang            LogUtils.i(LOG_TAG, "Conversation: applying cached value to col=%s val=%s", key,
5441bca265b7a8a3f9ea08e0ae51eeb145f0883a266Andy Huang                    val);
5451bca265b7a8a3f9ea08e0ae51eeb145f0883a266Andy Huang            if (ConversationColumns.READ.equals(key)) {
5461bca265b7a8a3f9ea08e0ae51eeb145f0883a266Andy Huang                read = (Integer) val != 0;
5471bca265b7a8a3f9ea08e0ae51eeb145f0883a266Andy Huang            } else if (ConversationColumns.CONVERSATION_INFO.equals(key)) {
5481bca265b7a8a3f9ea08e0ae51eeb145f0883a266Andy Huang                conversationInfo = ConversationInfo.fromBlob((byte[]) val);
5491bca265b7a8a3f9ea08e0ae51eeb145f0883a266Andy Huang            } else if (ConversationColumns.FLAGS.equals(key)) {
5501bca265b7a8a3f9ea08e0ae51eeb145f0883a266Andy Huang                convFlags = (Integer) val;
5511bca265b7a8a3f9ea08e0ae51eeb145f0883a266Andy Huang            } else if (ConversationColumns.STARRED.equals(key)) {
5521bca265b7a8a3f9ea08e0ae51eeb145f0883a266Andy Huang                starred = (Integer) val != 0;
5537f4b6140b40c1d1d2624ca1dabe229fbb5c6959aAndy Huang            } else if (ConversationColumns.SEEN.equals(key)) {
5547f4b6140b40c1d1d2624ca1dabe229fbb5c6959aAndy Huang                seen = (Integer) val != 0;
5558ebc2ce34ed7d979662cf88b1c9fa60d63142fe4Andy Huang            } else if (ConversationColumns.RAW_FOLDERS.equals(key)) {
5568ebc2ce34ed7d979662cf88b1c9fa60d63142fe4Andy Huang                rawFolders = FolderList.fromBlob((byte[]) val);
5571bca265b7a8a3f9ea08e0ae51eeb145f0883a266Andy Huang            } else if (ConversationColumns.VIEWED.equals(key)) {
5581bca265b7a8a3f9ea08e0ae51eeb145f0883a266Andy Huang                // ignore. this is not read from the cursor, either.
5591bca265b7a8a3f9ea08e0ae51eeb145f0883a266Andy Huang            } else {
5601bca265b7a8a3f9ea08e0ae51eeb145f0883a266Andy Huang                LogUtils.e(LOG_TAG, new UnsupportedOperationException(),
5611bca265b7a8a3f9ea08e0ae51eeb145f0883a266Andy Huang                        "unsupported cached conv value in col=%s", key);
5621bca265b7a8a3f9ea08e0ae51eeb145f0883a266Andy Huang            }
5631bca265b7a8a3f9ea08e0ae51eeb145f0883a266Andy Huang        }
5641bca265b7a8a3f9ea08e0ae51eeb145f0883a266Andy Huang    }
5651bca265b7a8a3f9ea08e0ae51eeb145f0883a266Andy Huang
5661bca265b7a8a3f9ea08e0ae51eeb145f0883a266Andy Huang    /**
567b2033d855ab0f13e253e5403ce25989bcbc49488Andy Huang     * Get the <strong>immutable</strong> list of {@link Folder}s for this conversation. To modify
568b2033d855ab0f13e253e5403ce25989bcbc49488Andy Huang     * this list, make a new {@link FolderList} and use {@link #setRawFolders(FolderList)}.
569b2033d855ab0f13e253e5403ce25989bcbc49488Andy Huang     *
570b2033d855ab0f13e253e5403ce25989bcbc49488Andy Huang     * @return <strong>Immutable</strong> list of {@link Folder}s.
571b2033d855ab0f13e253e5403ce25989bcbc49488Andy Huang     */
572b2033d855ab0f13e253e5403ce25989bcbc49488Andy Huang    public List<Folder> getRawFolders() {
573b2033d855ab0f13e253e5403ce25989bcbc49488Andy Huang        return rawFolders.folders;
57400ffece08e94ff5774b2a53c0adeb2f3d0815d66Mindy Pereira    }
57500ffece08e94ff5774b2a53c0adeb2f3d0815d66Mindy Pereira
576b2033d855ab0f13e253e5403ce25989bcbc49488Andy Huang    public void setRawFolders(FolderList folders) {
577b2033d855ab0f13e253e5403ce25989bcbc49488Andy Huang        rawFolders = folders;
57885c4a77abd849f5f3f0236d51554bb1bb99fe8f6Mindy Pereira    }
57985c4a77abd849f5f3f0236d51554bb1bb99fe8f6Mindy Pereira
580e1d1b07cdb0026097eb80f6c2912a16353aacec1Marc Blank    @Override
581e1d1b07cdb0026097eb80f6c2912a16353aacec1Marc Blank    public boolean equals(Object o) {
5823c9bcef43b4f103697034abbf2eab99111e8d987Marc Blank        if (o instanceof Conversation) {
583648df3f0b0ebcd3c4adf907d70ff0938e5dfc78fMindy Pereira            Conversation conv = (Conversation) o;
5843c9bcef43b4f103697034abbf2eab99111e8d987Marc Blank            return conv.uri.equals(uri);
5853c9bcef43b4f103697034abbf2eab99111e8d987Marc Blank        }
5863c9bcef43b4f103697034abbf2eab99111e8d987Marc Blank        return false;
587e1d1b07cdb0026097eb80f6c2912a16353aacec1Marc Blank    }
588e1d1b07cdb0026097eb80f6c2912a16353aacec1Marc Blank
589e1d1b07cdb0026097eb80f6c2912a16353aacec1Marc Blank    @Override
590e1d1b07cdb0026097eb80f6c2912a16353aacec1Marc Blank    public int hashCode() {
591e1d1b07cdb0026097eb80f6c2912a16353aacec1Marc Blank        return uri.hashCode();
592e1d1b07cdb0026097eb80f6c2912a16353aacec1Marc Blank    }
593e1d1b07cdb0026097eb80f6c2912a16353aacec1Marc Blank
5947f0a962513503cb01aec093b14c1b48dfae08f12Mindy Pereira    /**
5957f0a962513503cb01aec093b14c1b48dfae08f12Mindy Pereira     * Get if this conversation is marked as high priority.
5967f0a962513503cb01aec093b14c1b48dfae08f12Mindy Pereira     */
5977f0a962513503cb01aec093b14c1b48dfae08f12Mindy Pereira    public boolean isImportant() {
59822657529437c160dec072115c5982409306c1313Mindy Pereira        return priority == UIProvider.ConversationPriority.IMPORTANT;
5997f0a962513503cb01aec093b14c1b48dfae08f12Mindy Pereira    }
6007f0a962513503cb01aec093b14c1b48dfae08f12Mindy Pereira
601e1d1b07cdb0026097eb80f6c2912a16353aacec1Marc Blank    /**
602e1d1b07cdb0026097eb80f6c2912a16353aacec1Marc Blank     * Get if this conversation is mostly dead
603e1d1b07cdb0026097eb80f6c2912a16353aacec1Marc Blank     */
604e1d1b07cdb0026097eb80f6c2912a16353aacec1Marc Blank    public boolean isMostlyDead() {
605e1d1b07cdb0026097eb80f6c2912a16353aacec1Marc Blank        return (convFlags & FLAG_MOSTLY_DEAD) != 0;
606e1d1b07cdb0026097eb80f6c2912a16353aacec1Marc Blank    }
607440fe79194314b25ef5829702494735ce2f1e2e8Vikram Aggarwal
608440fe79194314b25ef5829702494735ce2f1e2e8Vikram Aggarwal    /**
609648df3f0b0ebcd3c4adf907d70ff0938e5dfc78fMindy Pereira     * Returns true if the URI of the conversation specified as the needle was
610648df3f0b0ebcd3c4adf907d70ff0938e5dfc78fMindy Pereira     * found in the collection of conversations specified as the haystack. False
611192fac189e6aed434556a4e37bd3c5c29ef02f29Vikram Aggarwal     * otherwise. This method is safe to call with null arguments.
612f98bc898cbc7014a203c35a13427d3f949bce705Andy Huang     *
613d503df4f0c31bbf842c6a1d3cba18df8c074bf67Vikram Aggarwal     * @param haystack
614d503df4f0c31bbf842c6a1d3cba18df8c074bf67Vikram Aggarwal     * @param needle
615d503df4f0c31bbf842c6a1d3cba18df8c074bf67Vikram Aggarwal     * @return true if the needle was found in the haystack, false otherwise.
616d503df4f0c31bbf842c6a1d3cba18df8c074bf67Vikram Aggarwal     */
617d503df4f0c31bbf842c6a1d3cba18df8c074bf67Vikram Aggarwal    public final static boolean contains(Collection<Conversation> haystack, Conversation needle) {
618d503df4f0c31bbf842c6a1d3cba18df8c074bf67Vikram Aggarwal        // If the haystack is empty, it cannot contain anything.
619d503df4f0c31bbf842c6a1d3cba18df8c074bf67Vikram Aggarwal        if (haystack == null || haystack.size() <= 0) {
620d503df4f0c31bbf842c6a1d3cba18df8c074bf67Vikram Aggarwal            return false;
621d503df4f0c31bbf842c6a1d3cba18df8c074bf67Vikram Aggarwal        }
622d503df4f0c31bbf842c6a1d3cba18df8c074bf67Vikram Aggarwal        // The null folder exists everywhere.
623d503df4f0c31bbf842c6a1d3cba18df8c074bf67Vikram Aggarwal        if (needle == null) {
624d503df4f0c31bbf842c6a1d3cba18df8c074bf67Vikram Aggarwal            return true;
625d503df4f0c31bbf842c6a1d3cba18df8c074bf67Vikram Aggarwal        }
6267dd054e39986de84a213c56a3c11ac94731402e6Vikram Aggarwal        final long toFind = needle.id;
627d503df4f0c31bbf842c6a1d3cba18df8c074bf67Vikram Aggarwal        for (final Conversation c : haystack) {
6287dd054e39986de84a213c56a3c11ac94731402e6Vikram Aggarwal            if (toFind == c.id) {
629d503df4f0c31bbf842c6a1d3cba18df8c074bf67Vikram Aggarwal                return true;
630d503df4f0c31bbf842c6a1d3cba18df8c074bf67Vikram Aggarwal            }
631d503df4f0c31bbf842c6a1d3cba18df8c074bf67Vikram Aggarwal        }
632d503df4f0c31bbf842c6a1d3cba18df8c074bf67Vikram Aggarwal        return false;
633d503df4f0c31bbf842c6a1d3cba18df8c074bf67Vikram Aggarwal    }
634d503df4f0c31bbf842c6a1d3cba18df8c074bf67Vikram Aggarwal
635d503df4f0c31bbf842c6a1d3cba18df8c074bf67Vikram Aggarwal    /**
636648df3f0b0ebcd3c4adf907d70ff0938e5dfc78fMindy Pereira     * Returns a collection of a single conversation. This method always returns
637648df3f0b0ebcd3c4adf907d70ff0938e5dfc78fMindy Pereira     * a valid collection even if the input conversation is null.
638f98bc898cbc7014a203c35a13427d3f949bce705Andy Huang     *
639440fe79194314b25ef5829702494735ce2f1e2e8Vikram Aggarwal     * @param in a conversation, possibly null.
640440fe79194314b25ef5829702494735ce2f1e2e8Vikram Aggarwal     * @return a collection of the conversation.
641440fe79194314b25ef5829702494735ce2f1e2e8Vikram Aggarwal     */
642440fe79194314b25ef5829702494735ce2f1e2e8Vikram Aggarwal    public static Collection<Conversation> listOf(Conversation in) {
643440fe79194314b25ef5829702494735ce2f1e2e8Vikram Aggarwal        final Collection<Conversation> target = (in == null) ? EMPTY : ImmutableList.of(in);
644440fe79194314b25ef5829702494735ce2f1e2e8Vikram Aggarwal        return target;
645440fe79194314b25ef5829702494735ce2f1e2e8Vikram Aggarwal    }
6467dd054e39986de84a213c56a3c11ac94731402e6Vikram Aggarwal
6477dd054e39986de84a213c56a3c11ac94731402e6Vikram Aggarwal    /**
648aa1f945612847bc4cf5c8909b8acfab4b5ecf54eMindy Pereira     * Get the snippet for this conversation. Masks that it may come from
649aa1f945612847bc4cf5c8909b8acfab4b5ecf54eMindy Pereira     * conversation info or the original deprecated snippet string.
650aa1f945612847bc4cf5c8909b8acfab4b5ecf54eMindy Pereira     */
651aa1f945612847bc4cf5c8909b8acfab4b5ecf54eMindy Pereira    public String getSnippet() {
652d97782206889a5508279b75cce19d7c0fb8a3bcaMindy Pereira        return conversationInfo != null && !TextUtils.isEmpty(conversationInfo.firstSnippet) ?
653d97782206889a5508279b75cce19d7c0fb8a3bcaMindy Pereira                conversationInfo.firstSnippet : snippet;
654aa1f945612847bc4cf5c8909b8acfab4b5ecf54eMindy Pereira    }
655aa1f945612847bc4cf5c8909b8acfab4b5ecf54eMindy Pereira
656aa1f945612847bc4cf5c8909b8acfab4b5ecf54eMindy Pereira    /**
6570972e0793cc321670391d063348aecb5031b2677Mindy Pereira     * Get the number of messages for this conversation.
6580972e0793cc321670391d063348aecb5031b2677Mindy Pereira     */
6590972e0793cc321670391d063348aecb5031b2677Mindy Pereira    public int getNumMessages() {
6600972e0793cc321670391d063348aecb5031b2677Mindy Pereira        return conversationInfo != null ? conversationInfo.messageCount : numMessages;
6610972e0793cc321670391d063348aecb5031b2677Mindy Pereira    }
6620972e0793cc321670391d063348aecb5031b2677Mindy Pereira
6630972e0793cc321670391d063348aecb5031b2677Mindy Pereira    /**
6640972e0793cc321670391d063348aecb5031b2677Mindy Pereira     * Get the number of drafts for this conversation.
6650972e0793cc321670391d063348aecb5031b2677Mindy Pereira     */
6660972e0793cc321670391d063348aecb5031b2677Mindy Pereira    public int numDrafts() {
6670972e0793cc321670391d063348aecb5031b2677Mindy Pereira        return conversationInfo != null ? conversationInfo.draftCount : numDrafts;
6680972e0793cc321670391d063348aecb5031b2677Mindy Pereira    }
6690972e0793cc321670391d063348aecb5031b2677Mindy Pereira
670cd5c5eeae167885ffa2959c200233fea2f39c5f7Andy Huang    public boolean isViewed() {
671cd5c5eeae167885ffa2959c200233fea2f39c5f7Andy Huang        return viewed;
672cd5c5eeae167885ffa2959c200233fea2f39c5f7Andy Huang    }
673cd5c5eeae167885ffa2959c200233fea2f39c5f7Andy Huang
674cd5c5eeae167885ffa2959c200233fea2f39c5f7Andy Huang    public void markViewed() {
675cd5c5eeae167885ffa2959c200233fea2f39c5f7Andy Huang        viewed = true;
676cd5c5eeae167885ffa2959c200233fea2f39c5f7Andy Huang    }
677cd5c5eeae167885ffa2959c200233fea2f39c5f7Andy Huang
678c1fb9a9c2730178105977fca629e80951bfc3cdcAndy Huang    public String getBaseUri(String defaultValue) {
679c1fb9a9c2730178105977fca629e80951bfc3cdcAndy Huang        return conversationBaseUri != null ? conversationBaseUri.toString() : defaultValue;
680c1fb9a9c2730178105977fca629e80951bfc3cdcAndy Huang    }
681c1fb9a9c2730178105977fca629e80951bfc3cdcAndy Huang
682479505d71969e26b0785d8e0e1b81108731cf827Mark Wei    public ArrayList<String> getAttachmentPreviewUris() {
683479505d71969e26b0785d8e0e1b81108731cf827Mark Wei        if (attachmentPreviews == null) {
684479505d71969e26b0785d8e0e1b81108731cf827Mark Wei            attachmentPreviews = Lists.newArrayListWithCapacity(2);
685479505d71969e26b0785d8e0e1b81108731cf827Mark Wei            if (!TextUtils.isEmpty(attachmentPreviewUri0)) {
686479505d71969e26b0785d8e0e1b81108731cf827Mark Wei                attachmentPreviews.add(attachmentPreviewUri0);
687479505d71969e26b0785d8e0e1b81108731cf827Mark Wei            }
688479505d71969e26b0785d8e0e1b81108731cf827Mark Wei            if (!TextUtils.isEmpty(attachmentPreviewUri1)) {
689479505d71969e26b0785d8e0e1b81108731cf827Mark Wei                attachmentPreviews.add(attachmentPreviewUri1);
690479505d71969e26b0785d8e0e1b81108731cf827Mark Wei            }
691479505d71969e26b0785d8e0e1b81108731cf827Mark Wei        }
692479505d71969e26b0785d8e0e1b81108731cf827Mark Wei        return attachmentPreviews;
693d198fa7ddb2d0c730847af34f06aa2e940b2537dMark Wei    }
694d198fa7ddb2d0c730847af34f06aa2e940b2537dMark Wei
6950972e0793cc321670391d063348aecb5031b2677Mindy Pereira    /**
6967dd054e39986de84a213c56a3c11ac94731402e6Vikram Aggarwal     * Create a human-readable string of all the conversations
6977dd054e39986de84a213c56a3c11ac94731402e6Vikram Aggarwal     * @param collection Any collection of conversations
6987dd054e39986de84a213c56a3c11ac94731402e6Vikram Aggarwal     * @return string with a human readable representation of the conversations.
6997dd054e39986de84a213c56a3c11ac94731402e6Vikram Aggarwal     */
7007dd054e39986de84a213c56a3c11ac94731402e6Vikram Aggarwal    public static String toString(Collection<Conversation> collection) {
7017dd054e39986de84a213c56a3c11ac94731402e6Vikram Aggarwal        final StringBuilder out = new StringBuilder(collection.size() + " conversations:");
7027dd054e39986de84a213c56a3c11ac94731402e6Vikram Aggarwal        int count = 0;
7037dd054e39986de84a213c56a3c11ac94731402e6Vikram Aggarwal        for (final Conversation c : collection) {
7047dd054e39986de84a213c56a3c11ac94731402e6Vikram Aggarwal            count++;
705648df3f0b0ebcd3c4adf907d70ff0938e5dfc78fMindy Pereira            // Indent the conversations to make them easy to read in debug
706648df3f0b0ebcd3c4adf907d70ff0938e5dfc78fMindy Pereira            // output.
7077dd054e39986de84a213c56a3c11ac94731402e6Vikram Aggarwal            out.append("      " + count + ": " + c.toString() + "\n");
7087dd054e39986de84a213c56a3c11ac94731402e6Vikram Aggarwal        }
7097dd054e39986de84a213c56a3c11ac94731402e6Vikram Aggarwal        return out.toString();
7107dd054e39986de84a213c56a3c11ac94731402e6Vikram Aggarwal    }
711820f051b37b45b3e3729bda5c4302a879ee6aa4dPaul Westbrook
712820f051b37b45b3e3729bda5c4302a879ee6aa4dPaul Westbrook    /**
713820f051b37b45b3e3729bda5c4302a879ee6aa4dPaul Westbrook     * Returns an empty string if the specified string is null
714820f051b37b45b3e3729bda5c4302a879ee6aa4dPaul Westbrook     */
715820f051b37b45b3e3729bda5c4302a879ee6aa4dPaul Westbrook    private static String emptyIfNull(String in) {
716820f051b37b45b3e3729bda5c4302a879ee6aa4dPaul Westbrook        return in != null ? in : EMPTY_STRING;
717820f051b37b45b3e3729bda5c4302a879ee6aa4dPaul Westbrook    }
718bf9508d3877d05742b2f5d23e1780366d3e1aa2eMindy Pereira
719bf9508d3877d05742b2f5d23e1780366d3e1aa2eMindy Pereira    /**
720f2caf91209e4e2d4182d6b379a3cd79eed81af71mindyp     * Get the properly formatted subject and snippet string for display a
721f2caf91209e4e2d4182d6b379a3cd79eed81af71mindyp     * conversation.
722f2caf91209e4e2d4182d6b379a3cd79eed81af71mindyp     *
723f2caf91209e4e2d4182d6b379a3cd79eed81af71mindyp     * @param context
724f2caf91209e4e2d4182d6b379a3cd79eed81af71mindyp     * @param filteredSubject
725f2caf91209e4e2d4182d6b379a3cd79eed81af71mindyp     * @param snippet
726bf9508d3877d05742b2f5d23e1780366d3e1aa2eMindy Pereira     */
727c046e4a310462aa6998a34ff50439eb5e2508d85mindyp    public static String getSubjectAndSnippetForDisplay(Context context,
728c046e4a310462aa6998a34ff50439eb5e2508d85mindyp            String filteredSubject, String snippet) {
7292909b7442130800d6c6c20c1227d65295262f03emindyp        if (sSubjectAndSnippet == null) {
7302909b7442130800d6c6c20c1227d65295262f03emindyp            sSubjectAndSnippet = context.getString(R.string.subject_and_snippet);
7312909b7442130800d6c6c20c1227d65295262f03emindyp        }
73261bd0e84a3b0545a722bbfe931233b47afdf52e2Scott Kennedy        if (TextUtils.isEmpty(filteredSubject) && TextUtils.isEmpty(snippet)) {
73361bd0e84a3b0545a722bbfe931233b47afdf52e2Scott Kennedy            return "";
73461bd0e84a3b0545a722bbfe931233b47afdf52e2Scott Kennedy        } else if (TextUtils.isEmpty(filteredSubject)) {
73561bd0e84a3b0545a722bbfe931233b47afdf52e2Scott Kennedy            return snippet;
73661bd0e84a3b0545a722bbfe931233b47afdf52e2Scott Kennedy        } else if (TextUtils.isEmpty(snippet)) {
73761bd0e84a3b0545a722bbfe931233b47afdf52e2Scott Kennedy            return filteredSubject;
73861bd0e84a3b0545a722bbfe931233b47afdf52e2Scott Kennedy        }
73961bd0e84a3b0545a722bbfe931233b47afdf52e2Scott Kennedy
74061bd0e84a3b0545a722bbfe931233b47afdf52e2Scott Kennedy        return String.format(sSubjectAndSnippet, filteredSubject, snippet);
741bf9508d3877d05742b2f5d23e1780366d3e1aa2eMindy Pereira    }
7425f578144cc01738d5f9988d61674a643df19fdaeScott Kennedy
7435f578144cc01738d5f9988d61674a643df19fdaeScott Kennedy    /**
7445f578144cc01738d5f9988d61674a643df19fdaeScott Kennedy     * Public object that knows how to construct Conversation given Cursors. This is not used by
7455f578144cc01738d5f9988d61674a643df19fdaeScott Kennedy     * {@link ConversationCursor} or {@link ConversationCursorLoader}.
7465f578144cc01738d5f9988d61674a643df19fdaeScott Kennedy     */
7475f578144cc01738d5f9988d61674a643df19fdaeScott Kennedy    public static final CursorCreator<Conversation> FACTORY = new CursorCreator<Conversation>() {
7485f578144cc01738d5f9988d61674a643df19fdaeScott Kennedy        @Override
7495f578144cc01738d5f9988d61674a643df19fdaeScott Kennedy        public Conversation createFromCursor(final Cursor c) {
7505f578144cc01738d5f9988d61674a643df19fdaeScott Kennedy            return new Conversation(c);
7515f578144cc01738d5f9988d61674a643df19fdaeScott Kennedy        }
7525f578144cc01738d5f9988d61674a643df19fdaeScott Kennedy
7535f578144cc01738d5f9988d61674a643df19fdaeScott Kennedy        @Override
7545f578144cc01738d5f9988d61674a643df19fdaeScott Kennedy        public String toString() {
7555f578144cc01738d5f9988d61674a643df19fdaeScott Kennedy            return "Conversation CursorCreator";
7565f578144cc01738d5f9988d61674a643df19fdaeScott Kennedy        }
7575f578144cc01738d5f9988d61674a643df19fdaeScott Kennedy    };
758648df3f0b0ebcd3c4adf907d70ff0938e5dfc78fMindy Pereira}
759