Conversation.java revision f8b613c1103952ae5cc1f8a5e6ae60aa62d73dec
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    /**
77e623a0f6e3caa9cafec913cf826e946628833517Andy Huang     * @see UIProvider.ConversationColumns#MESSAGE_LIST_URI
78e623a0f6e3caa9cafec913cf826e946628833517Andy Huang     */
79cfb7f33ff8ef9dc60b9143af32de64c7a3d71f36Mindy Pereira    public Uri messageListUri;
80e623a0f6e3caa9cafec913cf826e946628833517Andy Huang    /**
81e623a0f6e3caa9cafec913cf826e946628833517Andy Huang     * @see UIProvider.ConversationColumns#SENDER_INFO
82e623a0f6e3caa9cafec913cf826e946628833517Andy Huang     */
83648df3f0b0ebcd3c4adf907d70ff0938e5dfc78fMindy Pereira    @Deprecated
844db59c58c0af9f44d95a12dbe21322bed58cc518Mindy Pereira    public String senders;
85e623a0f6e3caa9cafec913cf826e946628833517Andy Huang    /**
86e623a0f6e3caa9cafec913cf826e946628833517Andy Huang     * @see UIProvider.ConversationColumns#NUM_MESSAGES
87e623a0f6e3caa9cafec913cf826e946628833517Andy Huang     */
880972e0793cc321670391d063348aecb5031b2677Mindy Pereira    private int numMessages;
89e623a0f6e3caa9cafec913cf826e946628833517Andy Huang    /**
90e623a0f6e3caa9cafec913cf826e946628833517Andy Huang     * @see UIProvider.ConversationColumns#NUM_DRAFTS
91e623a0f6e3caa9cafec913cf826e946628833517Andy Huang     */
920972e0793cc321670391d063348aecb5031b2677Mindy Pereira    private int numDrafts;
93e623a0f6e3caa9cafec913cf826e946628833517Andy Huang    /**
94e623a0f6e3caa9cafec913cf826e946628833517Andy Huang     * @see UIProvider.ConversationColumns#SENDING_STATE
95e623a0f6e3caa9cafec913cf826e946628833517Andy Huang     */
964db59c58c0af9f44d95a12dbe21322bed58cc518Mindy Pereira    public int sendingState;
97e623a0f6e3caa9cafec913cf826e946628833517Andy Huang    /**
98e623a0f6e3caa9cafec913cf826e946628833517Andy Huang     * @see UIProvider.ConversationColumns#PRIORITY
99e623a0f6e3caa9cafec913cf826e946628833517Andy Huang     */
1004db59c58c0af9f44d95a12dbe21322bed58cc518Mindy Pereira    public int priority;
101e623a0f6e3caa9cafec913cf826e946628833517Andy Huang    /**
102e623a0f6e3caa9cafec913cf826e946628833517Andy Huang     * @see UIProvider.ConversationColumns#READ
103e623a0f6e3caa9cafec913cf826e946628833517Andy Huang     */
104c8a994227b9c686d88ee05840544162711a85712Marc Blank    public boolean read;
105e623a0f6e3caa9cafec913cf826e946628833517Andy Huang    /**
106d5edd2d02649dffb40065fdb6a16acf91552b800Scott Kennedy     * @see UIProvider.ConversationColumns#SEEN
107d5edd2d02649dffb40065fdb6a16acf91552b800Scott Kennedy     */
108d5edd2d02649dffb40065fdb6a16acf91552b800Scott Kennedy    public boolean seen;
109d5edd2d02649dffb40065fdb6a16acf91552b800Scott Kennedy    /**
110e623a0f6e3caa9cafec913cf826e946628833517Andy Huang     * @see UIProvider.ConversationColumns#STARRED
111e623a0f6e3caa9cafec913cf826e946628833517Andy Huang     */
112c8a994227b9c686d88ee05840544162711a85712Marc Blank    public boolean starred;
113e623a0f6e3caa9cafec913cf826e946628833517Andy Huang    /**
114e623a0f6e3caa9cafec913cf826e946628833517Andy Huang     * @see UIProvider.ConversationColumns#RAW_FOLDERS
115e623a0f6e3caa9cafec913cf826e946628833517Andy Huang     */
116b2033d855ab0f13e253e5403ce25989bcbc49488Andy Huang    private FolderList rawFolders;
117e623a0f6e3caa9cafec913cf826e946628833517Andy Huang    /**
118e623a0f6e3caa9cafec913cf826e946628833517Andy Huang     * @see UIProvider.ConversationColumns#FLAGS
119e623a0f6e3caa9cafec913cf826e946628833517Andy Huang     */
12022657529437c160dec072115c5982409306c1313Mindy Pereira    public int convFlags;
121e623a0f6e3caa9cafec913cf826e946628833517Andy Huang    /**
122e623a0f6e3caa9cafec913cf826e946628833517Andy Huang     * @see UIProvider.ConversationColumns#PERSONAL_LEVEL
123e623a0f6e3caa9cafec913cf826e946628833517Andy Huang     */
12422657529437c160dec072115c5982409306c1313Mindy Pereira    public int personalLevel;
125e623a0f6e3caa9cafec913cf826e946628833517Andy Huang    /**
126e623a0f6e3caa9cafec913cf826e946628833517Andy Huang     * @see UIProvider.ConversationColumns#SPAM
127e623a0f6e3caa9cafec913cf826e946628833517Andy Huang     */
128863e44160d9175023d30e7e225ecb69ad3892eecMindy Pereira    public boolean spam;
129e623a0f6e3caa9cafec913cf826e946628833517Andy Huang    /**
130e623a0f6e3caa9cafec913cf826e946628833517Andy Huang     * @see UIProvider.ConversationColumns#MUTED
131e623a0f6e3caa9cafec913cf826e946628833517Andy Huang     */
132863e44160d9175023d30e7e225ecb69ad3892eecMindy Pereira    public boolean muted;
133e623a0f6e3caa9cafec913cf826e946628833517Andy Huang    /**
13476b2062b8c6d18a7b3a05292c385b47b0fcbd09fPaul Westbrook     * @see UIProvider.ConversationColumns#PHISHING
13576b2062b8c6d18a7b3a05292c385b47b0fcbd09fPaul Westbrook     */
13676b2062b8c6d18a7b3a05292c385b47b0fcbd09fPaul Westbrook    public boolean phishing;
13776b2062b8c6d18a7b3a05292c385b47b0fcbd09fPaul Westbrook    /**
138e623a0f6e3caa9cafec913cf826e946628833517Andy Huang     * @see UIProvider.ConversationColumns#COLOR
139e623a0f6e3caa9cafec913cf826e946628833517Andy Huang     */
14092939fc7b40a56e17fb0d2fde987133ca1614e29Marc Blank    public int color;
141e623a0f6e3caa9cafec913cf826e946628833517Andy Huang    /**
142e623a0f6e3caa9cafec913cf826e946628833517Andy Huang     * @see UIProvider.ConversationColumns#ACCOUNT_URI
143e623a0f6e3caa9cafec913cf826e946628833517Andy Huang     */
144a6b671dd9f5ba358a05888b3ab3bf1c5cb5cf493Marc Blank    public Uri accountUri;
145648df3f0b0ebcd3c4adf907d70ff0938e5dfc78fMindy Pereira    /**
146648df3f0b0ebcd3c4adf907d70ff0938e5dfc78fMindy Pereira     * @see UIProvider.ConversationColumns#CONVERSATION_INFO
147648df3f0b0ebcd3c4adf907d70ff0938e5dfc78fMindy Pereira     */
148648df3f0b0ebcd3c4adf907d70ff0938e5dfc78fMindy Pereira    public ConversationInfo conversationInfo;
14941dca185f7683b36bdafd9520c0648c897a95834Paul Westbrook    /**
150cebcc64fbd69618ff89f9fac0bfe9b9e7d7ce104Paul Westbrook     * @see UIProvider.ConversationColumns#CONVERSATION_BASE_URI
15141dca185f7683b36bdafd9520c0648c897a95834Paul Westbrook     */
15241dca185f7683b36bdafd9520c0648c897a95834Paul Westbrook    public Uri conversationBaseUri;
153f98bc898cbc7014a203c35a13427d3f949bce705Andy Huang    /**
154f98bc898cbc7014a203c35a13427d3f949bce705Andy Huang     * @see UIProvider.ConversationColumns#REMOTE
155f98bc898cbc7014a203c35a13427d3f949bce705Andy Huang     */
156f98bc898cbc7014a203c35a13427d3f949bce705Andy Huang    public boolean isRemote;
15722657529437c160dec072115c5982409306c1313Mindy Pereira
158dbb587f15c723ae80edb33f65c29cc2b6c15eba0Scott Kennedy    /**
159dbb587f15c723ae80edb33f65c29cc2b6c15eba0Scott Kennedy     * Used within the UI to indicate the adapter position of this conversation
160dbb587f15c723ae80edb33f65c29cc2b6c15eba0Scott Kennedy     *
161dbb587f15c723ae80edb33f65c29cc2b6c15eba0Scott Kennedy     * @deprecated Keeping this in sync with the desired value is a not always done properly, is a
162dbb587f15c723ae80edb33f65c29cc2b6c15eba0Scott Kennedy     *             source of bugs, and is a bad idea in general. Do not trust this value. Try to
163dbb587f15c723ae80edb33f65c29cc2b6c15eba0Scott Kennedy     *             migrate code away from using it.
164dbb587f15c723ae80edb33f65c29cc2b6c15eba0Scott Kennedy     */
165dbb587f15c723ae80edb33f65c29cc2b6c15eba0Scott Kennedy    @Deprecated
166f892f0a57d5c24b09fdc805f0fe2007ecd0d0e91Marc Blank    public transient int position;
167648df3f0b0ebcd3c4adf907d70ff0938e5dfc78fMindy Pereira    // Used within the UI to indicate that a Conversation should be removed from
168648df3f0b0ebcd3c4adf907d70ff0938e5dfc78fMindy Pereira    // the ConversationCursor when executing an update, e.g. the the
169648df3f0b0ebcd3c4adf907d70ff0938e5dfc78fMindy Pereira    // Conversation is no longer in the ConversationList for the current folder,
170648df3f0b0ebcd3c4adf907d70ff0938e5dfc78fMindy Pereira    // that is it's now in some other folder(s)
171ce53818e1e185a845bd2f7f601c20e7085b40725Marc Blank    public transient boolean localDeleteOnUpdate;
172732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang
173cd5c5eeae167885ffa2959c200233fea2f39c5f7Andy Huang    private transient boolean viewed;
174cd5c5eeae167885ffa2959c200233fea2f39c5f7Andy Huang
17585c4a77abd849f5f3f0236d51554bb1bb99fe8f6Mindy Pereira    private ArrayList<Folder> cachedDisplayableFolders;
17600ffece08e94ff5774b2a53c0adeb2f3d0815d66Mindy Pereira
1772909b7442130800d6c6c20c1227d65295262f03emindyp    private static String sSubjectAndSnippet;
1782909b7442130800d6c6c20c1227d65295262f03emindyp
179e1d1b07cdb0026097eb80f6c2912a16353aacec1Marc Blank    // Constituents of convFlags below
180648df3f0b0ebcd3c4adf907d70ff0938e5dfc78fMindy Pereira    // Flag indicating that the item has been deleted, but will continue being
181648df3f0b0ebcd3c4adf907d70ff0938e5dfc78fMindy Pereira    // shown in the list Delete/Archive of a mostly-dead item will NOT propagate
182648df3f0b0ebcd3c4adf907d70ff0938e5dfc78fMindy Pereira    // the delete/archive, but WILL remove the item from the cursor
183e1d1b07cdb0026097eb80f6c2912a16353aacec1Marc Blank    public static final int FLAG_MOSTLY_DEAD = 1 << 0;
184e1d1b07cdb0026097eb80f6c2912a16353aacec1Marc Blank
185440fe79194314b25ef5829702494735ce2f1e2e8Vikram Aggarwal    /** An immutable, empty conversation list */
186440fe79194314b25ef5829702494735ce2f1e2e8Vikram Aggarwal    public static final Collection<Conversation> EMPTY = Collections.emptyList();
187440fe79194314b25ef5829702494735ce2f1e2e8Vikram Aggarwal
188732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang    @Override
189732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang    public int describeContents() {
190732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang        return 0;
191732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang    }
192732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang
193732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang    @Override
194732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang    public void writeToParcel(Parcel dest, int flags) {
195732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang        dest.writeLong(id);
196c43bc0a606e41144a780c4f873b5450e0ede0c91Marc Blank        dest.writeParcelable(uri, flags);
197732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang        dest.writeString(subject);
198732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang        dest.writeLong(dateMs);
199732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang        dest.writeString(snippet);
200f98bc898cbc7014a203c35a13427d3f949bce705Andy Huang        dest.writeInt(hasAttachments ? 1 : 0);
201cfb7f33ff8ef9dc60b9143af32de64c7a3d71f36Mindy Pereira        dest.writeParcelable(messageListUri, 0);
2024db59c58c0af9f44d95a12dbe21322bed58cc518Mindy Pereira        dest.writeString(senders);
2034db59c58c0af9f44d95a12dbe21322bed58cc518Mindy Pereira        dest.writeInt(numMessages);
2044db59c58c0af9f44d95a12dbe21322bed58cc518Mindy Pereira        dest.writeInt(numDrafts);
2054db59c58c0af9f44d95a12dbe21322bed58cc518Mindy Pereira        dest.writeInt(sendingState);
2064db59c58c0af9f44d95a12dbe21322bed58cc518Mindy Pereira        dest.writeInt(priority);
207f98bc898cbc7014a203c35a13427d3f949bce705Andy Huang        dest.writeInt(read ? 1 : 0);
208d5edd2d02649dffb40065fdb6a16acf91552b800Scott Kennedy        dest.writeInt(seen ? 1 : 0);
209f98bc898cbc7014a203c35a13427d3f949bce705Andy Huang        dest.writeInt(starred ? 1 : 0);
210b2033d855ab0f13e253e5403ce25989bcbc49488Andy Huang        dest.writeParcelable(rawFolders, 0);
21122657529437c160dec072115c5982409306c1313Mindy Pereira        dest.writeInt(convFlags);
21222657529437c160dec072115c5982409306c1313Mindy Pereira        dest.writeInt(personalLevel);
213863e44160d9175023d30e7e225ecb69ad3892eecMindy Pereira        dest.writeInt(spam ? 1 : 0);
21476b2062b8c6d18a7b3a05292c385b47b0fcbd09fPaul Westbrook        dest.writeInt(phishing ? 1 : 0);
215863e44160d9175023d30e7e225ecb69ad3892eecMindy Pereira        dest.writeInt(muted ? 1 : 0);
21692939fc7b40a56e17fb0d2fde987133ca1614e29Marc Blank        dest.writeInt(color);
217a6b671dd9f5ba358a05888b3ab3bf1c5cb5cf493Marc Blank        dest.writeParcelable(accountUri, 0);
218351ad4e87e0b0b98df9ca88266a8a63541dc5a81Andy Huang        dest.writeParcelable(conversationInfo, 0);
21941dca185f7683b36bdafd9520c0648c897a95834Paul Westbrook        dest.writeParcelable(conversationBaseUri, 0);
220f98bc898cbc7014a203c35a13427d3f949bce705Andy Huang        dest.writeInt(isRemote ? 1 : 0);
221732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang    }
222732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang
223351ad4e87e0b0b98df9ca88266a8a63541dc5a81Andy Huang    private Conversation(Parcel in, ClassLoader loader) {
224732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang        id = in.readLong();
225c43bc0a606e41144a780c4f873b5450e0ede0c91Marc Blank        uri = in.readParcelable(null);
226732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang        subject = in.readString();
227732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang        dateMs = in.readLong();
228732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang        snippet = in.readString();
229f98bc898cbc7014a203c35a13427d3f949bce705Andy Huang        hasAttachments = (in.readInt() != 0);
230cfb7f33ff8ef9dc60b9143af32de64c7a3d71f36Mindy Pereira        messageListUri = in.readParcelable(null);
231820f051b37b45b3e3729bda5c4302a879ee6aa4dPaul Westbrook        senders = emptyIfNull(in.readString());
2324db59c58c0af9f44d95a12dbe21322bed58cc518Mindy Pereira        numMessages = in.readInt();
2334db59c58c0af9f44d95a12dbe21322bed58cc518Mindy Pereira        numDrafts = in.readInt();
2344db59c58c0af9f44d95a12dbe21322bed58cc518Mindy Pereira        sendingState = in.readInt();
2354db59c58c0af9f44d95a12dbe21322bed58cc518Mindy Pereira        priority = in.readInt();
236f98bc898cbc7014a203c35a13427d3f949bce705Andy Huang        read = (in.readInt() != 0);
237d5edd2d02649dffb40065fdb6a16acf91552b800Scott Kennedy        seen = (in.readInt() != 0);
238f98bc898cbc7014a203c35a13427d3f949bce705Andy Huang        starred = (in.readInt() != 0);
239b2033d855ab0f13e253e5403ce25989bcbc49488Andy Huang        rawFolders = in.readParcelable(loader);
24022657529437c160dec072115c5982409306c1313Mindy Pereira        convFlags = in.readInt();
24122657529437c160dec072115c5982409306c1313Mindy Pereira        personalLevel = in.readInt();
242863e44160d9175023d30e7e225ecb69ad3892eecMindy Pereira        spam = in.readInt() != 0;
24376b2062b8c6d18a7b3a05292c385b47b0fcbd09fPaul Westbrook        phishing = in.readInt() != 0;
244863e44160d9175023d30e7e225ecb69ad3892eecMindy Pereira        muted = in.readInt() != 0;
24592939fc7b40a56e17fb0d2fde987133ca1614e29Marc Blank        color = in.readInt();
246a6b671dd9f5ba358a05888b3ab3bf1c5cb5cf493Marc Blank        accountUri = in.readParcelable(null);
247f892f0a57d5c24b09fdc805f0fe2007ecd0d0e91Marc Blank        position = NO_POSITION;
248ce53818e1e185a845bd2f7f601c20e7085b40725Marc Blank        localDeleteOnUpdate = false;
249351ad4e87e0b0b98df9ca88266a8a63541dc5a81Andy Huang        conversationInfo = in.readParcelable(loader);
25041dca185f7683b36bdafd9520c0648c897a95834Paul Westbrook        conversationBaseUri = in.readParcelable(null);
251f98bc898cbc7014a203c35a13427d3f949bce705Andy Huang        isRemote = in.readInt() != 0;
252732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang    }
253732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang
254732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang    @Override
255732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang    public String toString() {
2569e4ca7993213d296043d20fe9cf4e166b5d595e8Andy Huang        // log extra info at DEBUG level or finer
2579e4ca7993213d296043d20fe9cf4e166b5d595e8Andy Huang        final StringBuilder sb = new StringBuilder("[conversation id=");
2589e4ca7993213d296043d20fe9cf4e166b5d595e8Andy Huang        sb.append(id);
2599e4ca7993213d296043d20fe9cf4e166b5d595e8Andy Huang        if (LogUtils.isLoggable(LOG_TAG, LogUtils.DEBUG)) {
2609e4ca7993213d296043d20fe9cf4e166b5d595e8Andy Huang            sb.append(", subject=");
2619e4ca7993213d296043d20fe9cf4e166b5d595e8Andy Huang            sb.append(subject);
2629e4ca7993213d296043d20fe9cf4e166b5d595e8Andy Huang        }
2639e4ca7993213d296043d20fe9cf4e166b5d595e8Andy Huang        sb.append("]");
2649e4ca7993213d296043d20fe9cf4e166b5d595e8Andy Huang        return sb.toString();
265732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang    }
266732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang
267351ad4e87e0b0b98df9ca88266a8a63541dc5a81Andy Huang    public static final ClassLoaderCreator<Conversation> CREATOR =
268351ad4e87e0b0b98df9ca88266a8a63541dc5a81Andy Huang            new ClassLoaderCreator<Conversation>() {
269732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang
270732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang        @Override
271732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang        public Conversation createFromParcel(Parcel source) {
272351ad4e87e0b0b98df9ca88266a8a63541dc5a81Andy Huang            return new Conversation(source, null);
273351ad4e87e0b0b98df9ca88266a8a63541dc5a81Andy Huang        }
274351ad4e87e0b0b98df9ca88266a8a63541dc5a81Andy Huang
275351ad4e87e0b0b98df9ca88266a8a63541dc5a81Andy Huang        @Override
276351ad4e87e0b0b98df9ca88266a8a63541dc5a81Andy Huang        public Conversation createFromParcel(Parcel source, ClassLoader loader) {
277351ad4e87e0b0b98df9ca88266a8a63541dc5a81Andy Huang            return new Conversation(source, loader);
278732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang        }
279732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang
280732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang        @Override
281732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang        public Conversation[] newArray(int size) {
282732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang            return new Conversation[size];
283732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang        }
284732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang
285732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang    };
286732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang
287acf6039a23382f18c35f6b487d90d53cb67b5858Mindy Pereira    public static final Uri MOVE_CONVERSATIONS_URI = Uri.parse("content://moveconversations");
288acf6039a23382f18c35f6b487d90d53cb67b5858Mindy Pereira
289ebdfd98264104cb5a6888acd663970b7c0b31382Mindy Pereira    /**
290ae7e6a0786a2d890b77c783d7ac39a90523b8154mindyp     * The column that needs to be updated to change the folders for a conversation.
291ebdfd98264104cb5a6888acd663970b7c0b31382Mindy Pereira     */
29200ffece08e94ff5774b2a53c0adeb2f3d0815d66Mindy Pereira    public static final String UPDATE_FOLDER_COLUMN = ConversationColumns.RAW_FOLDERS;
293ebdfd98264104cb5a6888acd663970b7c0b31382Mindy Pereira
294a831b2f1ba6d3c18d5e54563df8bae1f589c4257Mindy Pereira    public Conversation(Cursor cursor) {
295732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang        if (cursor != null) {
296732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang            id = cursor.getLong(UIProvider.CONVERSATION_ID_COLUMN);
297c43bc0a606e41144a780c4f873b5450e0ede0c91Marc Blank            uri = Uri.parse(cursor.getString(UIProvider.CONVERSATION_URI_COLUMN));
298732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang            dateMs = cursor.getLong(UIProvider.CONVERSATION_DATE_RECEIVED_MS_COLUMN);
299732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang            subject = cursor.getString(UIProvider.CONVERSATION_SUBJECT_COLUMN);
300374863eeb0ee37f1ca7d57840e6f02aaa052e284Marc Blank            // Don't allow null subject
301374863eeb0ee37f1ca7d57840e6f02aaa052e284Marc Blank            if (subject == null) {
302374863eeb0ee37f1ca7d57840e6f02aaa052e284Marc Blank                subject = "";
303374863eeb0ee37f1ca7d57840e6f02aaa052e284Marc Blank            }
30487d535fe423d782c3a0343c649330d309976f655Mindy Pereira            hasAttachments = cursor.getInt(UIProvider.CONVERSATION_HAS_ATTACHMENTS_COLUMN) != 0;
305648df3f0b0ebcd3c4adf907d70ff0938e5dfc78fMindy Pereira            String messageList = cursor.getString(UIProvider.CONVERSATION_MESSAGE_LIST_URI_COLUMN);
3065c765b9c5dd8a9a9421260ba8b46d06073391c73Mindy Pereira            messageListUri = !TextUtils.isEmpty(messageList) ? Uri.parse(messageList) : null;
3074db59c58c0af9f44d95a12dbe21322bed58cc518Mindy Pereira            sendingState = cursor.getInt(UIProvider.CONVERSATION_SENDING_STATE_COLUMN);
3084db59c58c0af9f44d95a12dbe21322bed58cc518Mindy Pereira            priority = cursor.getInt(UIProvider.CONVERSATION_PRIORITY_COLUMN);
30987d535fe423d782c3a0343c649330d309976f655Mindy Pereira            read = cursor.getInt(UIProvider.CONVERSATION_READ_COLUMN) != 0;
310d5edd2d02649dffb40065fdb6a16acf91552b800Scott Kennedy            seen = cursor.getInt(UIProvider.CONVERSATION_SEEN_COLUMN) != 0;
31187d535fe423d782c3a0343c649330d309976f655Mindy Pereira            starred = cursor.getInt(UIProvider.CONVERSATION_STARRED_COLUMN) != 0;
3127f39bbd358f7003a72ae2b480dfe38a84e830e5fAndy Huang            rawFolders = readRawFolders(cursor);
31322657529437c160dec072115c5982409306c1313Mindy Pereira            convFlags = cursor.getInt(UIProvider.CONVERSATION_FLAGS_COLUMN);
31422657529437c160dec072115c5982409306c1313Mindy Pereira            personalLevel = cursor.getInt(UIProvider.CONVERSATION_PERSONAL_LEVEL_COLUMN);
315863e44160d9175023d30e7e225ecb69ad3892eecMindy Pereira            spam = cursor.getInt(UIProvider.CONVERSATION_IS_SPAM_COLUMN) != 0;
31676b2062b8c6d18a7b3a05292c385b47b0fcbd09fPaul Westbrook            phishing = cursor.getInt(UIProvider.CONVERSATION_IS_PHISHING_COLUMN) != 0;
317863e44160d9175023d30e7e225ecb69ad3892eecMindy Pereira            muted = cursor.getInt(UIProvider.CONVERSATION_MUTED_COLUMN) != 0;
31892939fc7b40a56e17fb0d2fde987133ca1614e29Marc Blank            color = cursor.getInt(UIProvider.CONVERSATION_COLOR_COLUMN);
319a6b671dd9f5ba358a05888b3ab3bf1c5cb5cf493Marc Blank            String account = cursor.getString(UIProvider.CONVERSATION_ACCOUNT_URI_COLUMN);
320a6b671dd9f5ba358a05888b3ab3bf1c5cb5cf493Marc Blank            accountUri = !TextUtils.isEmpty(account) ? Uri.parse(account) : null;
321f892f0a57d5c24b09fdc805f0fe2007ecd0d0e91Marc Blank            position = NO_POSITION;
322ce53818e1e185a845bd2f7f601c20e7085b40725Marc Blank            localDeleteOnUpdate = false;
3237f39bbd358f7003a72ae2b480dfe38a84e830e5fAndy Huang            conversationInfo = readConversationInfo(cursor);
32441dca185f7683b36bdafd9520c0648c897a95834Paul Westbrook            final String conversationBase =
32541dca185f7683b36bdafd9520c0648c897a95834Paul Westbrook                    cursor.getString(UIProvider.CONVERSATION_BASE_URI_COLUMN);
32641dca185f7683b36bdafd9520c0648c897a95834Paul Westbrook            conversationBaseUri = !TextUtils.isEmpty(conversationBase) ?
32741dca185f7683b36bdafd9520c0648c897a95834Paul Westbrook                    Uri.parse(conversationBase) : null;
328e8a3eecf0a481665c5e886ebfb4a6184b5125f78Mindy Pereira            if (conversationInfo == null) {
329e8a3eecf0a481665c5e886ebfb4a6184b5125f78Mindy Pereira                snippet = cursor.getString(UIProvider.CONVERSATION_SNIPPET_COLUMN);
330820f051b37b45b3e3729bda5c4302a879ee6aa4dPaul Westbrook                senders = emptyIfNull(cursor.getString(UIProvider.CONVERSATION_SENDER_INFO_COLUMN));
3310972e0793cc321670391d063348aecb5031b2677Mindy Pereira                numMessages = cursor.getInt(UIProvider.CONVERSATION_NUM_MESSAGES_COLUMN);
3320972e0793cc321670391d063348aecb5031b2677Mindy Pereira                numDrafts = cursor.getInt(UIProvider.CONVERSATION_NUM_DRAFTS_COLUMN);
333e8a3eecf0a481665c5e886ebfb4a6184b5125f78Mindy Pereira            }
334f98bc898cbc7014a203c35a13427d3f949bce705Andy Huang            isRemote = cursor.getInt(UIProvider.CONVERSATION_REMOTE_COLUMN) != 0;
335732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang        }
336732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang    }
337732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang
3381bca265b7a8a3f9ea08e0ae51eeb145f0883a266Andy Huang    public Conversation(Conversation other) {
3391bca265b7a8a3f9ea08e0ae51eeb145f0883a266Andy Huang        if (other == null) {
3401bca265b7a8a3f9ea08e0ae51eeb145f0883a266Andy Huang            return;
3411bca265b7a8a3f9ea08e0ae51eeb145f0883a266Andy Huang        }
3421bca265b7a8a3f9ea08e0ae51eeb145f0883a266Andy Huang
3431bca265b7a8a3f9ea08e0ae51eeb145f0883a266Andy Huang        id = other.id;
3441bca265b7a8a3f9ea08e0ae51eeb145f0883a266Andy Huang        uri = other.uri;
3451bca265b7a8a3f9ea08e0ae51eeb145f0883a266Andy Huang        dateMs = other.dateMs;
3461bca265b7a8a3f9ea08e0ae51eeb145f0883a266Andy Huang        subject = other.subject;
3471bca265b7a8a3f9ea08e0ae51eeb145f0883a266Andy Huang        hasAttachments = other.hasAttachments;
3481bca265b7a8a3f9ea08e0ae51eeb145f0883a266Andy Huang        messageListUri = other.messageListUri;
3491bca265b7a8a3f9ea08e0ae51eeb145f0883a266Andy Huang        sendingState = other.sendingState;
3501bca265b7a8a3f9ea08e0ae51eeb145f0883a266Andy Huang        priority = other.priority;
3511bca265b7a8a3f9ea08e0ae51eeb145f0883a266Andy Huang        read = other.read;
3521bca265b7a8a3f9ea08e0ae51eeb145f0883a266Andy Huang        seen = other.seen;
3531bca265b7a8a3f9ea08e0ae51eeb145f0883a266Andy Huang        starred = other.starred;
3541bca265b7a8a3f9ea08e0ae51eeb145f0883a266Andy Huang        rawFolders = other.rawFolders; // FolderList is immutable, shallow copy is OK
3551bca265b7a8a3f9ea08e0ae51eeb145f0883a266Andy Huang        convFlags = other.convFlags;
3561bca265b7a8a3f9ea08e0ae51eeb145f0883a266Andy Huang        personalLevel = other.personalLevel;
3571bca265b7a8a3f9ea08e0ae51eeb145f0883a266Andy Huang        spam = other.spam;
3581bca265b7a8a3f9ea08e0ae51eeb145f0883a266Andy Huang        phishing = other.phishing;
3591bca265b7a8a3f9ea08e0ae51eeb145f0883a266Andy Huang        muted = other.muted;
3601bca265b7a8a3f9ea08e0ae51eeb145f0883a266Andy Huang        color = other.color;
3611bca265b7a8a3f9ea08e0ae51eeb145f0883a266Andy Huang        accountUri = other.accountUri;
3621bca265b7a8a3f9ea08e0ae51eeb145f0883a266Andy Huang        position = other.position;
3631bca265b7a8a3f9ea08e0ae51eeb145f0883a266Andy Huang        localDeleteOnUpdate = other.localDeleteOnUpdate;
3641bca265b7a8a3f9ea08e0ae51eeb145f0883a266Andy Huang        // although ConversationInfo is mutable (see ConversationInfo.markRead), applyCachedValues
3651bca265b7a8a3f9ea08e0ae51eeb145f0883a266Andy Huang        // will overwrite this if cached changes exist anyway, so a shallow copy is OK
3661bca265b7a8a3f9ea08e0ae51eeb145f0883a266Andy Huang        conversationInfo = other.conversationInfo;
3671bca265b7a8a3f9ea08e0ae51eeb145f0883a266Andy Huang        conversationBaseUri = other.conversationBaseUri;
3681bca265b7a8a3f9ea08e0ae51eeb145f0883a266Andy Huang        snippet = other.snippet;
3691bca265b7a8a3f9ea08e0ae51eeb145f0883a266Andy Huang        senders = other.senders;
3701bca265b7a8a3f9ea08e0ae51eeb145f0883a266Andy Huang        numMessages = other.numMessages;
3711bca265b7a8a3f9ea08e0ae51eeb145f0883a266Andy Huang        numDrafts = other.numDrafts;
3721bca265b7a8a3f9ea08e0ae51eeb145f0883a266Andy Huang        isRemote = other.isRemote;
3731bca265b7a8a3f9ea08e0ae51eeb145f0883a266Andy Huang    }
3741bca265b7a8a3f9ea08e0ae51eeb145f0883a266Andy Huang
375bf232c3735f65b1a4746943e4a134e59e36f0bdePaul Westbrook    public Conversation() {
376ff5c757ed2bcf7004a70b0675382ef894196558dPaul Westbrook    }
377ff5c757ed2bcf7004a70b0675382ef894196558dPaul Westbrook
378863e44160d9175023d30e7e225ecb69ad3892eecMindy Pereira    public static Conversation create(long id, Uri uri, String subject, long dateMs,
379863e44160d9175023d30e7e225ecb69ad3892eecMindy Pereira            String snippet, boolean hasAttachment, Uri messageListUri, String senders,
380863e44160d9175023d30e7e225ecb69ad3892eecMindy Pereira            int numMessages, int numDrafts, int sendingState, int priority, boolean read,
381d5edd2d02649dffb40065fdb6a16acf91552b800Scott Kennedy            boolean seen, boolean starred, FolderList rawFolders, int convFlags, int personalLevel,
382d5edd2d02649dffb40065fdb6a16acf91552b800Scott Kennedy            boolean spam, boolean phishing, boolean muted, Uri accountUri,
383d5edd2d02649dffb40065fdb6a16acf91552b800Scott Kennedy            ConversationInfo conversationInfo, Uri conversationBase, boolean isRemote) {
384ff5c757ed2bcf7004a70b0675382ef894196558dPaul Westbrook
385ff5c757ed2bcf7004a70b0675382ef894196558dPaul Westbrook        final Conversation conversation = new Conversation();
386ff5c757ed2bcf7004a70b0675382ef894196558dPaul Westbrook
387ff5c757ed2bcf7004a70b0675382ef894196558dPaul Westbrook        conversation.id = id;
388ff5c757ed2bcf7004a70b0675382ef894196558dPaul Westbrook        conversation.uri = uri;
389ff5c757ed2bcf7004a70b0675382ef894196558dPaul Westbrook        conversation.subject = subject;
390ff5c757ed2bcf7004a70b0675382ef894196558dPaul Westbrook        conversation.dateMs = dateMs;
391ff5c757ed2bcf7004a70b0675382ef894196558dPaul Westbrook        conversation.snippet = snippet;
392ff5c757ed2bcf7004a70b0675382ef894196558dPaul Westbrook        conversation.hasAttachments = hasAttachment;
393ff5c757ed2bcf7004a70b0675382ef894196558dPaul Westbrook        conversation.messageListUri = messageListUri;
394820f051b37b45b3e3729bda5c4302a879ee6aa4dPaul Westbrook        conversation.senders = emptyIfNull(senders);
395ff5c757ed2bcf7004a70b0675382ef894196558dPaul Westbrook        conversation.numMessages = numMessages;
396ff5c757ed2bcf7004a70b0675382ef894196558dPaul Westbrook        conversation.numDrafts = numDrafts;
397ff5c757ed2bcf7004a70b0675382ef894196558dPaul Westbrook        conversation.sendingState = sendingState;
398ff5c757ed2bcf7004a70b0675382ef894196558dPaul Westbrook        conversation.priority = priority;
399ff5c757ed2bcf7004a70b0675382ef894196558dPaul Westbrook        conversation.read = read;
400d5edd2d02649dffb40065fdb6a16acf91552b800Scott Kennedy        conversation.seen = seen;
401ff5c757ed2bcf7004a70b0675382ef894196558dPaul Westbrook        conversation.starred = starred;
402ff5c757ed2bcf7004a70b0675382ef894196558dPaul Westbrook        conversation.rawFolders = rawFolders;
403ff5c757ed2bcf7004a70b0675382ef894196558dPaul Westbrook        conversation.convFlags = convFlags;
404ff5c757ed2bcf7004a70b0675382ef894196558dPaul Westbrook        conversation.personalLevel = personalLevel;
405863e44160d9175023d30e7e225ecb69ad3892eecMindy Pereira        conversation.spam = spam;
40676b2062b8c6d18a7b3a05292c385b47b0fcbd09fPaul Westbrook        conversation.phishing = phishing;
407863e44160d9175023d30e7e225ecb69ad3892eecMindy Pereira        conversation.muted = muted;
40892939fc7b40a56e17fb0d2fde987133ca1614e29Marc Blank        conversation.color = 0;
409a6b671dd9f5ba358a05888b3ab3bf1c5cb5cf493Marc Blank        conversation.accountUri = accountUri;
4107e854f52f0890b9621846ac7fe201a5681e65666Andy Huang        conversation.conversationInfo = conversationInfo;
41141dca185f7683b36bdafd9520c0648c897a95834Paul Westbrook        conversation.conversationBaseUri = conversationBase;
412f98bc898cbc7014a203c35a13427d3f949bce705Andy Huang        conversation.isRemote = isRemote;
413ff5c757ed2bcf7004a70b0675382ef894196558dPaul Westbrook        return conversation;
414ff5c757ed2bcf7004a70b0675382ef894196558dPaul Westbrook    }
415ff5c757ed2bcf7004a70b0675382ef894196558dPaul Westbrook
4167f39bbd358f7003a72ae2b480dfe38a84e830e5fAndy Huang    private static final Bundle sConversationInfoRequest = new Bundle(1);
4177f39bbd358f7003a72ae2b480dfe38a84e830e5fAndy Huang    private static final Bundle sRawFoldersRequest = new Bundle(1);
4187f39bbd358f7003a72ae2b480dfe38a84e830e5fAndy Huang
4197f39bbd358f7003a72ae2b480dfe38a84e830e5fAndy Huang    private static ConversationInfo readConversationInfo(Cursor cursor) {
4207f39bbd358f7003a72ae2b480dfe38a84e830e5fAndy Huang        final ConversationInfo ci;
4217f39bbd358f7003a72ae2b480dfe38a84e830e5fAndy Huang
422f8b613c1103952ae5cc1f8a5e6ae60aa62d73decAndy Huang        if (cursor instanceof ConversationCursor) {
423f8b613c1103952ae5cc1f8a5e6ae60aa62d73decAndy Huang            final byte[] blob = ((ConversationCursor) cursor).getCachedBlob(
424f8b613c1103952ae5cc1f8a5e6ae60aa62d73decAndy Huang                    UIProvider.CONVERSATION_INFO_COLUMN);
425f8b613c1103952ae5cc1f8a5e6ae60aa62d73decAndy Huang            if (blob != null && blob.length > 0) {
426f8b613c1103952ae5cc1f8a5e6ae60aa62d73decAndy Huang                return ConversationInfo.fromBlob(blob);
427f8b613c1103952ae5cc1f8a5e6ae60aa62d73decAndy Huang            }
428f8b613c1103952ae5cc1f8a5e6ae60aa62d73decAndy Huang        }
429f8b613c1103952ae5cc1f8a5e6ae60aa62d73decAndy Huang
4307f39bbd358f7003a72ae2b480dfe38a84e830e5fAndy Huang        final String key = UIProvider.ConversationCursorCommand.COMMAND_GET_CONVERSATION_INFO;
4317f39bbd358f7003a72ae2b480dfe38a84e830e5fAndy Huang        if (sConversationInfoRequest.isEmpty()) {
4327f39bbd358f7003a72ae2b480dfe38a84e830e5fAndy Huang            sConversationInfoRequest.putBoolean(key, true);
433d521baf3a51c9fc1306bd55e027ce57d0a1d18aaAndy Huang            sConversationInfoRequest.putInt(
434d521baf3a51c9fc1306bd55e027ce57d0a1d18aaAndy Huang                    UIProvider.ConversationCursorCommand.COMMAND_KEY_OPTIONS,
435d521baf3a51c9fc1306bd55e027ce57d0a1d18aaAndy Huang                    UIProvider.ConversationCursorCommand.OPTION_MOVE_POSITION);
4367f39bbd358f7003a72ae2b480dfe38a84e830e5fAndy Huang        }
4377f39bbd358f7003a72ae2b480dfe38a84e830e5fAndy Huang        final Bundle response = cursor.respond(sConversationInfoRequest);
4387f39bbd358f7003a72ae2b480dfe38a84e830e5fAndy Huang        if (response.containsKey(key)) {
4397f39bbd358f7003a72ae2b480dfe38a84e830e5fAndy Huang            ci = response.getParcelable(key);
4407f39bbd358f7003a72ae2b480dfe38a84e830e5fAndy Huang        } else {
4417f39bbd358f7003a72ae2b480dfe38a84e830e5fAndy Huang            // legacy fallback
4427f39bbd358f7003a72ae2b480dfe38a84e830e5fAndy Huang            ci = ConversationInfo.fromBlob(cursor.getBlob(UIProvider.CONVERSATION_INFO_COLUMN));
4437f39bbd358f7003a72ae2b480dfe38a84e830e5fAndy Huang        }
4447f39bbd358f7003a72ae2b480dfe38a84e830e5fAndy Huang        return ci;
4457f39bbd358f7003a72ae2b480dfe38a84e830e5fAndy Huang    }
4467f39bbd358f7003a72ae2b480dfe38a84e830e5fAndy Huang
4477f39bbd358f7003a72ae2b480dfe38a84e830e5fAndy Huang    private static FolderList readRawFolders(Cursor cursor) {
4487f39bbd358f7003a72ae2b480dfe38a84e830e5fAndy Huang        final FolderList fl;
4497f39bbd358f7003a72ae2b480dfe38a84e830e5fAndy Huang
450f8b613c1103952ae5cc1f8a5e6ae60aa62d73decAndy Huang        if (cursor instanceof ConversationCursor) {
451f8b613c1103952ae5cc1f8a5e6ae60aa62d73decAndy Huang            final byte[] blob = ((ConversationCursor) cursor).getCachedBlob(
452f8b613c1103952ae5cc1f8a5e6ae60aa62d73decAndy Huang                    UIProvider.CONVERSATION_RAW_FOLDERS_COLUMN);
453f8b613c1103952ae5cc1f8a5e6ae60aa62d73decAndy Huang            if (blob != null && blob.length > 0) {
454f8b613c1103952ae5cc1f8a5e6ae60aa62d73decAndy Huang                return FolderList.fromBlob(blob);
455f8b613c1103952ae5cc1f8a5e6ae60aa62d73decAndy Huang            }
456f8b613c1103952ae5cc1f8a5e6ae60aa62d73decAndy Huang        }
457f8b613c1103952ae5cc1f8a5e6ae60aa62d73decAndy Huang
4587f39bbd358f7003a72ae2b480dfe38a84e830e5fAndy Huang        final String key = UIProvider.ConversationCursorCommand.COMMAND_GET_RAW_FOLDERS;
4597f39bbd358f7003a72ae2b480dfe38a84e830e5fAndy Huang        if (sRawFoldersRequest.isEmpty()) {
4607f39bbd358f7003a72ae2b480dfe38a84e830e5fAndy Huang            sRawFoldersRequest.putBoolean(key, true);
461d521baf3a51c9fc1306bd55e027ce57d0a1d18aaAndy Huang            sRawFoldersRequest.putInt(
462d521baf3a51c9fc1306bd55e027ce57d0a1d18aaAndy Huang                    UIProvider.ConversationCursorCommand.COMMAND_KEY_OPTIONS,
463d521baf3a51c9fc1306bd55e027ce57d0a1d18aaAndy Huang                    UIProvider.ConversationCursorCommand.OPTION_MOVE_POSITION);
4647f39bbd358f7003a72ae2b480dfe38a84e830e5fAndy Huang        }
4657f39bbd358f7003a72ae2b480dfe38a84e830e5fAndy Huang        final Bundle response = cursor.respond(sRawFoldersRequest);
4667f39bbd358f7003a72ae2b480dfe38a84e830e5fAndy Huang        if (response.containsKey(key)) {
4677f39bbd358f7003a72ae2b480dfe38a84e830e5fAndy Huang            fl = response.getParcelable(key);
4687f39bbd358f7003a72ae2b480dfe38a84e830e5fAndy Huang        } else {
4697f39bbd358f7003a72ae2b480dfe38a84e830e5fAndy Huang            // legacy fallback
4707f39bbd358f7003a72ae2b480dfe38a84e830e5fAndy Huang            fl = FolderList.fromBlob(
4717f39bbd358f7003a72ae2b480dfe38a84e830e5fAndy Huang                    cursor.getBlob(UIProvider.CONVERSATION_RAW_FOLDERS_COLUMN));
4727f39bbd358f7003a72ae2b480dfe38a84e830e5fAndy Huang        }
4737f39bbd358f7003a72ae2b480dfe38a84e830e5fAndy Huang        return fl;
4747f39bbd358f7003a72ae2b480dfe38a84e830e5fAndy Huang    }
4757f39bbd358f7003a72ae2b480dfe38a84e830e5fAndy Huang
476b2033d855ab0f13e253e5403ce25989bcbc49488Andy Huang    /**
4771bca265b7a8a3f9ea08e0ae51eeb145f0883a266Andy Huang     * Apply any column values from the given {@link ContentValues} (where column names are the
4781bca265b7a8a3f9ea08e0ae51eeb145f0883a266Andy Huang     * keys) to this conversation.
4791bca265b7a8a3f9ea08e0ae51eeb145f0883a266Andy Huang     *
4801bca265b7a8a3f9ea08e0ae51eeb145f0883a266Andy Huang     */
4811bca265b7a8a3f9ea08e0ae51eeb145f0883a266Andy Huang    public void applyCachedValues(ContentValues values) {
4821bca265b7a8a3f9ea08e0ae51eeb145f0883a266Andy Huang        if (values == null) {
4831bca265b7a8a3f9ea08e0ae51eeb145f0883a266Andy Huang            return;
4841bca265b7a8a3f9ea08e0ae51eeb145f0883a266Andy Huang        }
4851bca265b7a8a3f9ea08e0ae51eeb145f0883a266Andy Huang        for (String key : values.keySet()) {
4861bca265b7a8a3f9ea08e0ae51eeb145f0883a266Andy Huang            final Object val = values.get(key);
4871bca265b7a8a3f9ea08e0ae51eeb145f0883a266Andy Huang            LogUtils.i(LOG_TAG, "Conversation: applying cached value to col=%s val=%s", key,
4881bca265b7a8a3f9ea08e0ae51eeb145f0883a266Andy Huang                    val);
4891bca265b7a8a3f9ea08e0ae51eeb145f0883a266Andy Huang            if (ConversationColumns.READ.equals(key)) {
4901bca265b7a8a3f9ea08e0ae51eeb145f0883a266Andy Huang                read = (Integer) val != 0;
4911bca265b7a8a3f9ea08e0ae51eeb145f0883a266Andy Huang            } else if (ConversationColumns.CONVERSATION_INFO.equals(key)) {
4921bca265b7a8a3f9ea08e0ae51eeb145f0883a266Andy Huang                conversationInfo = ConversationInfo.fromBlob((byte[]) val);
4931bca265b7a8a3f9ea08e0ae51eeb145f0883a266Andy Huang            } else if (ConversationColumns.FLAGS.equals(key)) {
4941bca265b7a8a3f9ea08e0ae51eeb145f0883a266Andy Huang                convFlags = (Integer) val;
4951bca265b7a8a3f9ea08e0ae51eeb145f0883a266Andy Huang            } else if (ConversationColumns.STARRED.equals(key)) {
4961bca265b7a8a3f9ea08e0ae51eeb145f0883a266Andy Huang                starred = (Integer) val != 0;
4977f4b6140b40c1d1d2624ca1dabe229fbb5c6959aAndy Huang            } else if (ConversationColumns.SEEN.equals(key)) {
4987f4b6140b40c1d1d2624ca1dabe229fbb5c6959aAndy Huang                seen = (Integer) val != 0;
4998ebc2ce34ed7d979662cf88b1c9fa60d63142fe4Andy Huang            } else if (ConversationColumns.RAW_FOLDERS.equals(key)) {
5008ebc2ce34ed7d979662cf88b1c9fa60d63142fe4Andy Huang                rawFolders = FolderList.fromBlob((byte[]) val);
5011bca265b7a8a3f9ea08e0ae51eeb145f0883a266Andy Huang            } else if (ConversationColumns.VIEWED.equals(key)) {
5021bca265b7a8a3f9ea08e0ae51eeb145f0883a266Andy Huang                // ignore. this is not read from the cursor, either.
5031bca265b7a8a3f9ea08e0ae51eeb145f0883a266Andy Huang            } else {
5041bca265b7a8a3f9ea08e0ae51eeb145f0883a266Andy Huang                LogUtils.e(LOG_TAG, new UnsupportedOperationException(),
5051bca265b7a8a3f9ea08e0ae51eeb145f0883a266Andy Huang                        "unsupported cached conv value in col=%s", key);
5061bca265b7a8a3f9ea08e0ae51eeb145f0883a266Andy Huang            }
5071bca265b7a8a3f9ea08e0ae51eeb145f0883a266Andy Huang        }
5081bca265b7a8a3f9ea08e0ae51eeb145f0883a266Andy Huang    }
5091bca265b7a8a3f9ea08e0ae51eeb145f0883a266Andy Huang
5101bca265b7a8a3f9ea08e0ae51eeb145f0883a266Andy Huang    /**
511b2033d855ab0f13e253e5403ce25989bcbc49488Andy Huang     * Get the <strong>immutable</strong> list of {@link Folder}s for this conversation. To modify
512b2033d855ab0f13e253e5403ce25989bcbc49488Andy Huang     * this list, make a new {@link FolderList} and use {@link #setRawFolders(FolderList)}.
513b2033d855ab0f13e253e5403ce25989bcbc49488Andy Huang     *
514b2033d855ab0f13e253e5403ce25989bcbc49488Andy Huang     * @return <strong>Immutable</strong> list of {@link Folder}s.
515b2033d855ab0f13e253e5403ce25989bcbc49488Andy Huang     */
516b2033d855ab0f13e253e5403ce25989bcbc49488Andy Huang    public List<Folder> getRawFolders() {
517b2033d855ab0f13e253e5403ce25989bcbc49488Andy Huang        return rawFolders.folders;
51800ffece08e94ff5774b2a53c0adeb2f3d0815d66Mindy Pereira    }
51900ffece08e94ff5774b2a53c0adeb2f3d0815d66Mindy Pereira
520b2033d855ab0f13e253e5403ce25989bcbc49488Andy Huang    public void setRawFolders(FolderList folders) {
52185c4a77abd849f5f3f0236d51554bb1bb99fe8f6Mindy Pereira        clearCachedFolders();
522b2033d855ab0f13e253e5403ce25989bcbc49488Andy Huang        rawFolders = folders;
52385c4a77abd849f5f3f0236d51554bb1bb99fe8f6Mindy Pereira    }
52485c4a77abd849f5f3f0236d51554bb1bb99fe8f6Mindy Pereira
52585c4a77abd849f5f3f0236d51554bb1bb99fe8f6Mindy Pereira    private void clearCachedFolders() {
52685c4a77abd849f5f3f0236d51554bb1bb99fe8f6Mindy Pereira        cachedDisplayableFolders = null;
52785c4a77abd849f5f3f0236d51554bb1bb99fe8f6Mindy Pereira    }
52885c4a77abd849f5f3f0236d51554bb1bb99fe8f6Mindy Pereira
52967aa9e5162a15fb8b46b4113ac627cd20668f095Scott Kennedy    public ArrayList<Folder> getRawFoldersForDisplay(final Uri ignoreFolderUri,
53067aa9e5162a15fb8b46b4113ac627cd20668f095Scott Kennedy            final int ignoreFolderType) {
53185c4a77abd849f5f3f0236d51554bb1bb99fe8f6Mindy Pereira        if (cachedDisplayableFolders == null) {
53285c4a77abd849f5f3f0236d51554bb1bb99fe8f6Mindy Pereira            cachedDisplayableFolders = new ArrayList<Folder>();
533b2033d855ab0f13e253e5403ce25989bcbc49488Andy Huang            for (Folder folder : rawFolders.folders) {
5348eca4db9069941d2b8afbe6f75e3af75a4310f27Andy Huang                // skip the ignoreFolder
535b39aaf53a555c1046ef31b3fecf15d086acca013Scott Kennedy                if (ignoreFolderUri != null && ignoreFolderUri.equals(folder.uri)) {
53685c4a77abd849f5f3f0236d51554bb1bb99fe8f6Mindy Pereira                    continue;
53785c4a77abd849f5f3f0236d51554bb1bb99fe8f6Mindy Pereira                }
53867aa9e5162a15fb8b46b4113ac627cd20668f095Scott Kennedy                // Skip the ignoreFolderType
53967aa9e5162a15fb8b46b4113ac627cd20668f095Scott Kennedy                if (ignoreFolderType >= 0 && folder.isType(ignoreFolderType)) {
54067aa9e5162a15fb8b46b4113ac627cd20668f095Scott Kennedy                    continue;
54167aa9e5162a15fb8b46b4113ac627cd20668f095Scott Kennedy                }
54285c4a77abd849f5f3f0236d51554bb1bb99fe8f6Mindy Pereira                cachedDisplayableFolders.add(folder);
54385c4a77abd849f5f3f0236d51554bb1bb99fe8f6Mindy Pereira            }
54485c4a77abd849f5f3f0236d51554bb1bb99fe8f6Mindy Pereira        }
54585c4a77abd849f5f3f0236d51554bb1bb99fe8f6Mindy Pereira        return cachedDisplayableFolders;
54685c4a77abd849f5f3f0236d51554bb1bb99fe8f6Mindy Pereira    }
54785c4a77abd849f5f3f0236d51554bb1bb99fe8f6Mindy Pereira
548e1d1b07cdb0026097eb80f6c2912a16353aacec1Marc Blank    @Override
549e1d1b07cdb0026097eb80f6c2912a16353aacec1Marc Blank    public boolean equals(Object o) {
5503c9bcef43b4f103697034abbf2eab99111e8d987Marc Blank        if (o instanceof Conversation) {
551648df3f0b0ebcd3c4adf907d70ff0938e5dfc78fMindy Pereira            Conversation conv = (Conversation) o;
5523c9bcef43b4f103697034abbf2eab99111e8d987Marc Blank            return conv.uri.equals(uri);
5533c9bcef43b4f103697034abbf2eab99111e8d987Marc Blank        }
5543c9bcef43b4f103697034abbf2eab99111e8d987Marc Blank        return false;
555e1d1b07cdb0026097eb80f6c2912a16353aacec1Marc Blank    }
556e1d1b07cdb0026097eb80f6c2912a16353aacec1Marc Blank
557e1d1b07cdb0026097eb80f6c2912a16353aacec1Marc Blank    @Override
558e1d1b07cdb0026097eb80f6c2912a16353aacec1Marc Blank    public int hashCode() {
559e1d1b07cdb0026097eb80f6c2912a16353aacec1Marc Blank        return uri.hashCode();
560e1d1b07cdb0026097eb80f6c2912a16353aacec1Marc Blank    }
561e1d1b07cdb0026097eb80f6c2912a16353aacec1Marc Blank
5627f0a962513503cb01aec093b14c1b48dfae08f12Mindy Pereira    /**
5637f0a962513503cb01aec093b14c1b48dfae08f12Mindy Pereira     * Get if this conversation is marked as high priority.
5647f0a962513503cb01aec093b14c1b48dfae08f12Mindy Pereira     */
5657f0a962513503cb01aec093b14c1b48dfae08f12Mindy Pereira    public boolean isImportant() {
56622657529437c160dec072115c5982409306c1313Mindy Pereira        return priority == UIProvider.ConversationPriority.IMPORTANT;
5677f0a962513503cb01aec093b14c1b48dfae08f12Mindy Pereira    }
5687f0a962513503cb01aec093b14c1b48dfae08f12Mindy Pereira
569e1d1b07cdb0026097eb80f6c2912a16353aacec1Marc Blank    /**
570e1d1b07cdb0026097eb80f6c2912a16353aacec1Marc Blank     * Get if this conversation is mostly dead
571e1d1b07cdb0026097eb80f6c2912a16353aacec1Marc Blank     */
572e1d1b07cdb0026097eb80f6c2912a16353aacec1Marc Blank    public boolean isMostlyDead() {
573e1d1b07cdb0026097eb80f6c2912a16353aacec1Marc Blank        return (convFlags & FLAG_MOSTLY_DEAD) != 0;
574e1d1b07cdb0026097eb80f6c2912a16353aacec1Marc Blank    }
575440fe79194314b25ef5829702494735ce2f1e2e8Vikram Aggarwal
576440fe79194314b25ef5829702494735ce2f1e2e8Vikram Aggarwal    /**
577648df3f0b0ebcd3c4adf907d70ff0938e5dfc78fMindy Pereira     * Returns true if the URI of the conversation specified as the needle was
578648df3f0b0ebcd3c4adf907d70ff0938e5dfc78fMindy Pereira     * found in the collection of conversations specified as the haystack. False
579192fac189e6aed434556a4e37bd3c5c29ef02f29Vikram Aggarwal     * otherwise. This method is safe to call with null arguments.
580f98bc898cbc7014a203c35a13427d3f949bce705Andy Huang     *
581d503df4f0c31bbf842c6a1d3cba18df8c074bf67Vikram Aggarwal     * @param haystack
582d503df4f0c31bbf842c6a1d3cba18df8c074bf67Vikram Aggarwal     * @param needle
583d503df4f0c31bbf842c6a1d3cba18df8c074bf67Vikram Aggarwal     * @return true if the needle was found in the haystack, false otherwise.
584d503df4f0c31bbf842c6a1d3cba18df8c074bf67Vikram Aggarwal     */
585d503df4f0c31bbf842c6a1d3cba18df8c074bf67Vikram Aggarwal    public final static boolean contains(Collection<Conversation> haystack, Conversation needle) {
586d503df4f0c31bbf842c6a1d3cba18df8c074bf67Vikram Aggarwal        // If the haystack is empty, it cannot contain anything.
587d503df4f0c31bbf842c6a1d3cba18df8c074bf67Vikram Aggarwal        if (haystack == null || haystack.size() <= 0) {
588d503df4f0c31bbf842c6a1d3cba18df8c074bf67Vikram Aggarwal            return false;
589d503df4f0c31bbf842c6a1d3cba18df8c074bf67Vikram Aggarwal        }
590d503df4f0c31bbf842c6a1d3cba18df8c074bf67Vikram Aggarwal        // The null folder exists everywhere.
591d503df4f0c31bbf842c6a1d3cba18df8c074bf67Vikram Aggarwal        if (needle == null) {
592d503df4f0c31bbf842c6a1d3cba18df8c074bf67Vikram Aggarwal            return true;
593d503df4f0c31bbf842c6a1d3cba18df8c074bf67Vikram Aggarwal        }
5947dd054e39986de84a213c56a3c11ac94731402e6Vikram Aggarwal        final long toFind = needle.id;
595d503df4f0c31bbf842c6a1d3cba18df8c074bf67Vikram Aggarwal        for (final Conversation c : haystack) {
5967dd054e39986de84a213c56a3c11ac94731402e6Vikram Aggarwal            if (toFind == c.id) {
597d503df4f0c31bbf842c6a1d3cba18df8c074bf67Vikram Aggarwal                return true;
598d503df4f0c31bbf842c6a1d3cba18df8c074bf67Vikram Aggarwal            }
599d503df4f0c31bbf842c6a1d3cba18df8c074bf67Vikram Aggarwal        }
600d503df4f0c31bbf842c6a1d3cba18df8c074bf67Vikram Aggarwal        return false;
601d503df4f0c31bbf842c6a1d3cba18df8c074bf67Vikram Aggarwal    }
602d503df4f0c31bbf842c6a1d3cba18df8c074bf67Vikram Aggarwal
603d503df4f0c31bbf842c6a1d3cba18df8c074bf67Vikram Aggarwal    /**
604648df3f0b0ebcd3c4adf907d70ff0938e5dfc78fMindy Pereira     * Returns a collection of a single conversation. This method always returns
605648df3f0b0ebcd3c4adf907d70ff0938e5dfc78fMindy Pereira     * a valid collection even if the input conversation is null.
606f98bc898cbc7014a203c35a13427d3f949bce705Andy Huang     *
607440fe79194314b25ef5829702494735ce2f1e2e8Vikram Aggarwal     * @param in a conversation, possibly null.
608440fe79194314b25ef5829702494735ce2f1e2e8Vikram Aggarwal     * @return a collection of the conversation.
609440fe79194314b25ef5829702494735ce2f1e2e8Vikram Aggarwal     */
610440fe79194314b25ef5829702494735ce2f1e2e8Vikram Aggarwal    public static Collection<Conversation> listOf(Conversation in) {
611440fe79194314b25ef5829702494735ce2f1e2e8Vikram Aggarwal        final Collection<Conversation> target = (in == null) ? EMPTY : ImmutableList.of(in);
612440fe79194314b25ef5829702494735ce2f1e2e8Vikram Aggarwal        return target;
613440fe79194314b25ef5829702494735ce2f1e2e8Vikram Aggarwal    }
6147dd054e39986de84a213c56a3c11ac94731402e6Vikram Aggarwal
6157dd054e39986de84a213c56a3c11ac94731402e6Vikram Aggarwal    /**
616aa1f945612847bc4cf5c8909b8acfab4b5ecf54eMindy Pereira     * Get the snippet for this conversation. Masks that it may come from
617aa1f945612847bc4cf5c8909b8acfab4b5ecf54eMindy Pereira     * conversation info or the original deprecated snippet string.
618aa1f945612847bc4cf5c8909b8acfab4b5ecf54eMindy Pereira     */
619aa1f945612847bc4cf5c8909b8acfab4b5ecf54eMindy Pereira    public String getSnippet() {
620d97782206889a5508279b75cce19d7c0fb8a3bcaMindy Pereira        return conversationInfo != null && !TextUtils.isEmpty(conversationInfo.firstSnippet) ?
621d97782206889a5508279b75cce19d7c0fb8a3bcaMindy Pereira                conversationInfo.firstSnippet : snippet;
622aa1f945612847bc4cf5c8909b8acfab4b5ecf54eMindy Pereira    }
623aa1f945612847bc4cf5c8909b8acfab4b5ecf54eMindy Pereira
624aa1f945612847bc4cf5c8909b8acfab4b5ecf54eMindy Pereira    /**
6250972e0793cc321670391d063348aecb5031b2677Mindy Pereira     * Get the number of messages for this conversation.
6260972e0793cc321670391d063348aecb5031b2677Mindy Pereira     */
6270972e0793cc321670391d063348aecb5031b2677Mindy Pereira    public int getNumMessages() {
6280972e0793cc321670391d063348aecb5031b2677Mindy Pereira        return conversationInfo != null ? conversationInfo.messageCount : numMessages;
6290972e0793cc321670391d063348aecb5031b2677Mindy Pereira    }
6300972e0793cc321670391d063348aecb5031b2677Mindy Pereira
6310972e0793cc321670391d063348aecb5031b2677Mindy Pereira    /**
6320972e0793cc321670391d063348aecb5031b2677Mindy Pereira     * Get the number of drafts for this conversation.
6330972e0793cc321670391d063348aecb5031b2677Mindy Pereira     */
6340972e0793cc321670391d063348aecb5031b2677Mindy Pereira    public int numDrafts() {
6350972e0793cc321670391d063348aecb5031b2677Mindy Pereira        return conversationInfo != null ? conversationInfo.draftCount : numDrafts;
6360972e0793cc321670391d063348aecb5031b2677Mindy Pereira    }
6370972e0793cc321670391d063348aecb5031b2677Mindy Pereira
638cd5c5eeae167885ffa2959c200233fea2f39c5f7Andy Huang    public boolean isViewed() {
639cd5c5eeae167885ffa2959c200233fea2f39c5f7Andy Huang        return viewed;
640cd5c5eeae167885ffa2959c200233fea2f39c5f7Andy Huang    }
641cd5c5eeae167885ffa2959c200233fea2f39c5f7Andy Huang
642cd5c5eeae167885ffa2959c200233fea2f39c5f7Andy Huang    public void markViewed() {
643cd5c5eeae167885ffa2959c200233fea2f39c5f7Andy Huang        viewed = true;
644cd5c5eeae167885ffa2959c200233fea2f39c5f7Andy Huang    }
645cd5c5eeae167885ffa2959c200233fea2f39c5f7Andy Huang
646c1fb9a9c2730178105977fca629e80951bfc3cdcAndy Huang    public String getBaseUri(String defaultValue) {
647c1fb9a9c2730178105977fca629e80951bfc3cdcAndy Huang        return conversationBaseUri != null ? conversationBaseUri.toString() : defaultValue;
648c1fb9a9c2730178105977fca629e80951bfc3cdcAndy Huang    }
649c1fb9a9c2730178105977fca629e80951bfc3cdcAndy Huang
650d198fa7ddb2d0c730847af34f06aa2e940b2537dMark Wei    public int getAttachmentsCount() {
651d198fa7ddb2d0c730847af34f06aa2e940b2537dMark Wei        return getAttachments().size();
652d198fa7ddb2d0c730847af34f06aa2e940b2537dMark Wei    }
653d198fa7ddb2d0c730847af34f06aa2e940b2537dMark Wei
654d198fa7ddb2d0c730847af34f06aa2e940b2537dMark Wei    public ArrayList<String> getAttachments() {
655d198fa7ddb2d0c730847af34f06aa2e940b2537dMark Wei        return Lists.newArrayList();
656d198fa7ddb2d0c730847af34f06aa2e940b2537dMark Wei    }
657d198fa7ddb2d0c730847af34f06aa2e940b2537dMark Wei
6580972e0793cc321670391d063348aecb5031b2677Mindy Pereira    /**
6597dd054e39986de84a213c56a3c11ac94731402e6Vikram Aggarwal     * Create a human-readable string of all the conversations
6607dd054e39986de84a213c56a3c11ac94731402e6Vikram Aggarwal     * @param collection Any collection of conversations
6617dd054e39986de84a213c56a3c11ac94731402e6Vikram Aggarwal     * @return string with a human readable representation of the conversations.
6627dd054e39986de84a213c56a3c11ac94731402e6Vikram Aggarwal     */
6637dd054e39986de84a213c56a3c11ac94731402e6Vikram Aggarwal    public static String toString(Collection<Conversation> collection) {
6647dd054e39986de84a213c56a3c11ac94731402e6Vikram Aggarwal        final StringBuilder out = new StringBuilder(collection.size() + " conversations:");
6657dd054e39986de84a213c56a3c11ac94731402e6Vikram Aggarwal        int count = 0;
6667dd054e39986de84a213c56a3c11ac94731402e6Vikram Aggarwal        for (final Conversation c : collection) {
6677dd054e39986de84a213c56a3c11ac94731402e6Vikram Aggarwal            count++;
668648df3f0b0ebcd3c4adf907d70ff0938e5dfc78fMindy Pereira            // Indent the conversations to make them easy to read in debug
669648df3f0b0ebcd3c4adf907d70ff0938e5dfc78fMindy Pereira            // output.
6707dd054e39986de84a213c56a3c11ac94731402e6Vikram Aggarwal            out.append("      " + count + ": " + c.toString() + "\n");
6717dd054e39986de84a213c56a3c11ac94731402e6Vikram Aggarwal        }
6727dd054e39986de84a213c56a3c11ac94731402e6Vikram Aggarwal        return out.toString();
6737dd054e39986de84a213c56a3c11ac94731402e6Vikram Aggarwal    }
674820f051b37b45b3e3729bda5c4302a879ee6aa4dPaul Westbrook
675820f051b37b45b3e3729bda5c4302a879ee6aa4dPaul Westbrook    /**
676820f051b37b45b3e3729bda5c4302a879ee6aa4dPaul Westbrook     * Returns an empty string if the specified string is null
677820f051b37b45b3e3729bda5c4302a879ee6aa4dPaul Westbrook     */
678820f051b37b45b3e3729bda5c4302a879ee6aa4dPaul Westbrook    private static String emptyIfNull(String in) {
679820f051b37b45b3e3729bda5c4302a879ee6aa4dPaul Westbrook        return in != null ? in : EMPTY_STRING;
680820f051b37b45b3e3729bda5c4302a879ee6aa4dPaul Westbrook    }
681bf9508d3877d05742b2f5d23e1780366d3e1aa2eMindy Pereira
682bf9508d3877d05742b2f5d23e1780366d3e1aa2eMindy Pereira    /**
683f2caf91209e4e2d4182d6b379a3cd79eed81af71mindyp     * Get the properly formatted subject and snippet string for display a
684f2caf91209e4e2d4182d6b379a3cd79eed81af71mindyp     * conversation.
685f2caf91209e4e2d4182d6b379a3cd79eed81af71mindyp     *
686f2caf91209e4e2d4182d6b379a3cd79eed81af71mindyp     * @param context
687f2caf91209e4e2d4182d6b379a3cd79eed81af71mindyp     * @param filteredSubject
688f2caf91209e4e2d4182d6b379a3cd79eed81af71mindyp     * @param snippet
689bf9508d3877d05742b2f5d23e1780366d3e1aa2eMindy Pereira     */
690c046e4a310462aa6998a34ff50439eb5e2508d85mindyp    public static String getSubjectAndSnippetForDisplay(Context context,
691c046e4a310462aa6998a34ff50439eb5e2508d85mindyp            String filteredSubject, String snippet) {
6922909b7442130800d6c6c20c1227d65295262f03emindyp        if (sSubjectAndSnippet == null) {
6932909b7442130800d6c6c20c1227d65295262f03emindyp            sSubjectAndSnippet = context.getString(R.string.subject_and_snippet);
6942909b7442130800d6c6c20c1227d65295262f03emindyp        }
69561bd0e84a3b0545a722bbfe931233b47afdf52e2Scott Kennedy        if (TextUtils.isEmpty(filteredSubject) && TextUtils.isEmpty(snippet)) {
69661bd0e84a3b0545a722bbfe931233b47afdf52e2Scott Kennedy            return "";
69761bd0e84a3b0545a722bbfe931233b47afdf52e2Scott Kennedy        } else if (TextUtils.isEmpty(filteredSubject)) {
69861bd0e84a3b0545a722bbfe931233b47afdf52e2Scott Kennedy            return snippet;
69961bd0e84a3b0545a722bbfe931233b47afdf52e2Scott Kennedy        } else if (TextUtils.isEmpty(snippet)) {
70061bd0e84a3b0545a722bbfe931233b47afdf52e2Scott Kennedy            return filteredSubject;
70161bd0e84a3b0545a722bbfe931233b47afdf52e2Scott Kennedy        }
70261bd0e84a3b0545a722bbfe931233b47afdf52e2Scott Kennedy
70361bd0e84a3b0545a722bbfe931233b47afdf52e2Scott Kennedy        return String.format(sSubjectAndSnippet, filteredSubject, snippet);
704bf9508d3877d05742b2f5d23e1780366d3e1aa2eMindy Pereira    }
7055f578144cc01738d5f9988d61674a643df19fdaeScott Kennedy
7065f578144cc01738d5f9988d61674a643df19fdaeScott Kennedy    /**
7075f578144cc01738d5f9988d61674a643df19fdaeScott Kennedy     * Public object that knows how to construct Conversation given Cursors. This is not used by
7085f578144cc01738d5f9988d61674a643df19fdaeScott Kennedy     * {@link ConversationCursor} or {@link ConversationCursorLoader}.
7095f578144cc01738d5f9988d61674a643df19fdaeScott Kennedy     */
7105f578144cc01738d5f9988d61674a643df19fdaeScott Kennedy    public static final CursorCreator<Conversation> FACTORY = new CursorCreator<Conversation>() {
7115f578144cc01738d5f9988d61674a643df19fdaeScott Kennedy        @Override
7125f578144cc01738d5f9988d61674a643df19fdaeScott Kennedy        public Conversation createFromCursor(final Cursor c) {
7135f578144cc01738d5f9988d61674a643df19fdaeScott Kennedy            return new Conversation(c);
7145f578144cc01738d5f9988d61674a643df19fdaeScott Kennedy        }
7155f578144cc01738d5f9988d61674a643df19fdaeScott Kennedy
7165f578144cc01738d5f9988d61674a643df19fdaeScott Kennedy        @Override
7175f578144cc01738d5f9988d61674a643df19fdaeScott Kennedy        public String toString() {
7185f578144cc01738d5f9988d61674a643df19fdaeScott Kennedy            return "Conversation CursorCreator";
7195f578144cc01738d5f9988d61674a643df19fdaeScott Kennedy        }
7205f578144cc01738d5f9988d61674a643df19fdaeScott Kennedy    };
721648df3f0b0ebcd3c4adf907d70ff0938e5dfc78fMindy Pereira}
722