Conversation.java revision f892f0a57d5c24b09fdc805f0fe2007ecd0d0e91
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 198d69d4e10a9a36ff790babb2f3a098a12d0dc732Marc Blankimport android.content.ContentProviderClient; 20c8a994227b9c686d88ee05840544162711a85712Marc Blankimport android.content.ContentValues; 21c8a994227b9c686d88ee05840544162711a85712Marc Blankimport android.content.Context; 22732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huangimport android.database.Cursor; 23732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huangimport android.net.Uri; 24732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huangimport android.os.Parcel; 25732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huangimport android.os.Parcelable; 26732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang 278d69d4e10a9a36ff790babb2f3a098a12d0dc732Marc Blankimport com.android.mail.browse.ConversationCursor.ConversationOperation; 288d69d4e10a9a36ff790babb2f3a098a12d0dc732Marc Blankimport com.android.mail.browse.ConversationCursor.ConversationProvider; 298d69d4e10a9a36ff790babb2f3a098a12d0dc732Marc Blank 308d69d4e10a9a36ff790babb2f3a098a12d0dc732Marc Blankimport java.util.ArrayList; 318d69d4e10a9a36ff790babb2f3a098a12d0dc732Marc Blankimport java.util.Collection; 328d69d4e10a9a36ff790babb2f3a098a12d0dc732Marc Blank 33732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huangpublic class Conversation implements Parcelable { 34f892f0a57d5c24b09fdc805f0fe2007ecd0d0e91Marc Blank public static final int NO_POSITION = -1; 35732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang 36732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang public long id; 37732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang public String subject; 38732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang public long dateMs; 39732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang public String snippet; 40732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang public boolean hasAttachments; 41732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang public Uri messageListUri; 424db59c58c0af9f44d95a12dbe21322bed58cc518Mindy Pereira public String senders; 434db59c58c0af9f44d95a12dbe21322bed58cc518Mindy Pereira public int numMessages; 444db59c58c0af9f44d95a12dbe21322bed58cc518Mindy Pereira public int numDrafts; 454db59c58c0af9f44d95a12dbe21322bed58cc518Mindy Pereira public int sendingState; 464db59c58c0af9f44d95a12dbe21322bed58cc518Mindy Pereira public int priority; 47c8a994227b9c686d88ee05840544162711a85712Marc Blank public boolean read; 48c8a994227b9c686d88ee05840544162711a85712Marc Blank public boolean starred; 49f892f0a57d5c24b09fdc805f0fe2007ecd0d0e91Marc Blank public transient int position; 50732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang 51732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang @Override 52732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang public int describeContents() { 53732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang return 0; 54732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang } 55732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang 56732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang @Override 57732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang public void writeToParcel(Parcel dest, int flags) { 58732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang dest.writeLong(id); 59732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang dest.writeString(subject); 60732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang dest.writeLong(dateMs); 61732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang dest.writeString(snippet); 62732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang dest.writeByte(hasAttachments ? (byte) 1 : 0); 63732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang dest.writeParcelable(messageListUri, flags); 644db59c58c0af9f44d95a12dbe21322bed58cc518Mindy Pereira dest.writeString(senders); 654db59c58c0af9f44d95a12dbe21322bed58cc518Mindy Pereira dest.writeInt(numMessages); 664db59c58c0af9f44d95a12dbe21322bed58cc518Mindy Pereira dest.writeInt(numDrafts); 674db59c58c0af9f44d95a12dbe21322bed58cc518Mindy Pereira dest.writeInt(sendingState); 684db59c58c0af9f44d95a12dbe21322bed58cc518Mindy Pereira dest.writeInt(priority); 69c8a994227b9c686d88ee05840544162711a85712Marc Blank dest.writeByte(read ? (byte) 1 : 0); 70c8a994227b9c686d88ee05840544162711a85712Marc Blank dest.writeByte(starred ? (byte) 1 : 0); 71732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang } 72732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang 73732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang private Conversation(Parcel in) { 74732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang id = in.readLong(); 75732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang subject = in.readString(); 76732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang dateMs = in.readLong(); 77732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang snippet = in.readString(); 78732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang hasAttachments = (in.readByte() != 0); 79732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang messageListUri = in.readParcelable(null); 804db59c58c0af9f44d95a12dbe21322bed58cc518Mindy Pereira senders = in.readString(); 814db59c58c0af9f44d95a12dbe21322bed58cc518Mindy Pereira numMessages = in.readInt(); 824db59c58c0af9f44d95a12dbe21322bed58cc518Mindy Pereira numDrafts = in.readInt(); 834db59c58c0af9f44d95a12dbe21322bed58cc518Mindy Pereira sendingState = in.readInt(); 844db59c58c0af9f44d95a12dbe21322bed58cc518Mindy Pereira priority = in.readInt(); 85c8a994227b9c686d88ee05840544162711a85712Marc Blank read = (in.readByte() != 0); 86c8a994227b9c686d88ee05840544162711a85712Marc Blank starred = (in.readByte() != 0); 87f892f0a57d5c24b09fdc805f0fe2007ecd0d0e91Marc Blank position = NO_POSITION; 88732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang } 89732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang 90732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang @Override 91732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang public String toString() { 92732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang return "[conversation id=" + id + "]"; 93732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang } 94732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang 95732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang public static final Creator<Conversation> CREATOR = new Creator<Conversation>() { 96732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang 97732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang @Override 98732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang public Conversation createFromParcel(Parcel source) { 99732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang return new Conversation(source); 100732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang } 101732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang 102732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang @Override 103732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang public Conversation[] newArray(int size) { 104732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang return new Conversation[size]; 105732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang } 106732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang 107732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang }; 108732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang 109732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang public static Conversation from(Cursor cursor) { 110732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang return new Conversation(cursor); 111732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang } 112732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang 113732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang private Conversation(Cursor cursor) { 114732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang if (cursor != null) { 115732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang id = cursor.getLong(UIProvider.CONVERSATION_ID_COLUMN); 116732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang dateMs = cursor.getLong(UIProvider.CONVERSATION_DATE_RECEIVED_MS_COLUMN); 117732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang subject = cursor.getString(UIProvider.CONVERSATION_SUBJECT_COLUMN); 118374863eeb0ee37f1ca7d57840e6f02aaa052e284Marc Blank // Don't allow null subject 119374863eeb0ee37f1ca7d57840e6f02aaa052e284Marc Blank if (subject == null) { 120374863eeb0ee37f1ca7d57840e6f02aaa052e284Marc Blank subject = ""; 121374863eeb0ee37f1ca7d57840e6f02aaa052e284Marc Blank } 122732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang snippet = cursor.getString(UIProvider.CONVERSATION_SNIPPET_COLUMN); 123c8a994227b9c686d88ee05840544162711a85712Marc Blank hasAttachments = cursor.getInt(UIProvider.CONVERSATION_HAS_ATTACHMENTS_COLUMN) == 1; 124732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang messageListUri = Uri.parse(cursor 125732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang .getString(UIProvider.CONVERSATION_MESSAGE_LIST_URI_COLUMN)); 1264db59c58c0af9f44d95a12dbe21322bed58cc518Mindy Pereira senders = cursor.getString(UIProvider.CONVERSATION_SENDER_INFO_COLUMN); 1274db59c58c0af9f44d95a12dbe21322bed58cc518Mindy Pereira numMessages = cursor.getInt(UIProvider.CONVERSATION_NUM_MESSAGES_COLUMN); 1284db59c58c0af9f44d95a12dbe21322bed58cc518Mindy Pereira numDrafts = cursor.getInt(UIProvider.CONVERSATION_NUM_DRAFTS_COLUMN); 1294db59c58c0af9f44d95a12dbe21322bed58cc518Mindy Pereira sendingState = cursor.getInt(UIProvider.CONVERSATION_SENDING_STATE_COLUMN); 1304db59c58c0af9f44d95a12dbe21322bed58cc518Mindy Pereira priority = cursor.getInt(UIProvider.CONVERSATION_PRIORITY_COLUMN); 131c8a994227b9c686d88ee05840544162711a85712Marc Blank read = cursor.getInt(UIProvider.CONVERSATION_READ_COLUMN) == 1; 132c8a994227b9c686d88ee05840544162711a85712Marc Blank starred = cursor.getInt(UIProvider.CONVERSATION_STARRED_COLUMN) == 1; 133f892f0a57d5c24b09fdc805f0fe2007ecd0d0e91Marc Blank position = NO_POSITION; 134732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang } 135732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang } 136732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang 137c8a994227b9c686d88ee05840544162711a85712Marc Blank // Below are methods that update Conversation data (update/delete) 138c8a994227b9c686d88ee05840544162711a85712Marc Blank 1398d69d4e10a9a36ff790babb2f3a098a12d0dc732Marc Blank /** 1408d69d4e10a9a36ff790babb2f3a098a12d0dc732Marc Blank * Update a boolean column for a single conversation 1418d69d4e10a9a36ff790babb2f3a098a12d0dc732Marc Blank * @param context the caller's context 1428d69d4e10a9a36ff790babb2f3a098a12d0dc732Marc Blank * @param columnName the column to update 1438d69d4e10a9a36ff790babb2f3a098a12d0dc732Marc Blank * @param value the new value 1448d69d4e10a9a36ff790babb2f3a098a12d0dc732Marc Blank */ 145c8a994227b9c686d88ee05840544162711a85712Marc Blank public void updateBoolean(Context context, String columnName, boolean value) { 146c8a994227b9c686d88ee05840544162711a85712Marc Blank ContentValues cv = new ContentValues(); 147c8a994227b9c686d88ee05840544162711a85712Marc Blank cv.put(columnName, value); 148c8a994227b9c686d88ee05840544162711a85712Marc Blank context.getContentResolver().update(messageListUri, cv, null, null); 149c8a994227b9c686d88ee05840544162711a85712Marc Blank } 150c8a994227b9c686d88ee05840544162711a85712Marc Blank 1518d69d4e10a9a36ff790babb2f3a098a12d0dc732Marc Blank /** 1528d69d4e10a9a36ff790babb2f3a098a12d0dc732Marc Blank * Update a boolean column for a group of conversations, immediately in the UI and in a single 1538d69d4e10a9a36ff790babb2f3a098a12d0dc732Marc Blank * transaction in the underlying provider 1548d69d4e10a9a36ff790babb2f3a098a12d0dc732Marc Blank * @param conversations a collection of conversations 1558d69d4e10a9a36ff790babb2f3a098a12d0dc732Marc Blank * @param context the caller's context 1568d69d4e10a9a36ff790babb2f3a098a12d0dc732Marc Blank * @param columnName the column to update 1578d69d4e10a9a36ff790babb2f3a098a12d0dc732Marc Blank * @param value the new value 1588d69d4e10a9a36ff790babb2f3a098a12d0dc732Marc Blank */ 1598d69d4e10a9a36ff790babb2f3a098a12d0dc732Marc Blank public static void updateBoolean(Context context, Collection<Conversation> conversations, 1608d69d4e10a9a36ff790babb2f3a098a12d0dc732Marc Blank String columnName, boolean value) { 1618d69d4e10a9a36ff790babb2f3a098a12d0dc732Marc Blank ContentValues cv = new ContentValues(); 1628d69d4e10a9a36ff790babb2f3a098a12d0dc732Marc Blank cv.put(columnName, value); 1638d69d4e10a9a36ff790babb2f3a098a12d0dc732Marc Blank ArrayList<ConversationOperation> ops = new ArrayList<ConversationOperation>(); 1648d69d4e10a9a36ff790babb2f3a098a12d0dc732Marc Blank for (Conversation conv: conversations) { 1658d69d4e10a9a36ff790babb2f3a098a12d0dc732Marc Blank ConversationOperation op = 166f892f0a57d5c24b09fdc805f0fe2007ecd0d0e91Marc Blank new ConversationOperation(ConversationOperation.UPDATE, conv, cv); 1678d69d4e10a9a36ff790babb2f3a098a12d0dc732Marc Blank ops.add(op); 1688d69d4e10a9a36ff790babb2f3a098a12d0dc732Marc Blank } 1698d69d4e10a9a36ff790babb2f3a098a12d0dc732Marc Blank apply(context, ops); 1708d69d4e10a9a36ff790babb2f3a098a12d0dc732Marc Blank } 1718d69d4e10a9a36ff790babb2f3a098a12d0dc732Marc Blank 1728d69d4e10a9a36ff790babb2f3a098a12d0dc732Marc Blank /** 1738d69d4e10a9a36ff790babb2f3a098a12d0dc732Marc Blank * Delete a single conversation 1748d69d4e10a9a36ff790babb2f3a098a12d0dc732Marc Blank * @param context the caller's context 1758d69d4e10a9a36ff790babb2f3a098a12d0dc732Marc Blank */ 176c8a994227b9c686d88ee05840544162711a85712Marc Blank public void delete(Context context) { 177c8a994227b9c686d88ee05840544162711a85712Marc Blank context.getContentResolver().delete(messageListUri, null, null); 178c8a994227b9c686d88ee05840544162711a85712Marc Blank } 1798d69d4e10a9a36ff790babb2f3a098a12d0dc732Marc Blank 1808d69d4e10a9a36ff790babb2f3a098a12d0dc732Marc Blank /** 1818d69d4e10a9a36ff790babb2f3a098a12d0dc732Marc Blank * Delete a group of conversations immediately in the UI and in a single transaction in the 1828d69d4e10a9a36ff790babb2f3a098a12d0dc732Marc Blank * underlying provider 1838d69d4e10a9a36ff790babb2f3a098a12d0dc732Marc Blank * @param context the caller's context 1848d69d4e10a9a36ff790babb2f3a098a12d0dc732Marc Blank * @param conversations a collection of conversations 1858d69d4e10a9a36ff790babb2f3a098a12d0dc732Marc Blank */ 1868d69d4e10a9a36ff790babb2f3a098a12d0dc732Marc Blank public static void delete(Context context, Collection<Conversation> conversations) { 1878d69d4e10a9a36ff790babb2f3a098a12d0dc732Marc Blank ArrayList<ConversationOperation> ops = new ArrayList<ConversationOperation>(); 1888d69d4e10a9a36ff790babb2f3a098a12d0dc732Marc Blank for (Conversation conv: conversations) { 1898d69d4e10a9a36ff790babb2f3a098a12d0dc732Marc Blank ConversationOperation op = 190f892f0a57d5c24b09fdc805f0fe2007ecd0d0e91Marc Blank new ConversationOperation(ConversationOperation.DELETE, conv); 1918d69d4e10a9a36ff790babb2f3a098a12d0dc732Marc Blank ops.add(op); 1928d69d4e10a9a36ff790babb2f3a098a12d0dc732Marc Blank } 1938d69d4e10a9a36ff790babb2f3a098a12d0dc732Marc Blank apply(context, ops); 1948d69d4e10a9a36ff790babb2f3a098a12d0dc732Marc Blank } 1958d69d4e10a9a36ff790babb2f3a098a12d0dc732Marc Blank 1968d69d4e10a9a36ff790babb2f3a098a12d0dc732Marc Blank // Convenience methods 1978d69d4e10a9a36ff790babb2f3a098a12d0dc732Marc Blank private static void apply(Context context, ArrayList<ConversationOperation> operations) { 1988d69d4e10a9a36ff790babb2f3a098a12d0dc732Marc Blank ContentProviderClient client = 1998d69d4e10a9a36ff790babb2f3a098a12d0dc732Marc Blank context.getContentResolver().acquireContentProviderClient( 2008d69d4e10a9a36ff790babb2f3a098a12d0dc732Marc Blank ConversationProvider.AUTHORITY); 2018d69d4e10a9a36ff790babb2f3a098a12d0dc732Marc Blank try { 2028d69d4e10a9a36ff790babb2f3a098a12d0dc732Marc Blank ConversationProvider cp = (ConversationProvider)client.getLocalContentProvider(); 2038d69d4e10a9a36ff790babb2f3a098a12d0dc732Marc Blank cp.apply(operations); 2048d69d4e10a9a36ff790babb2f3a098a12d0dc732Marc Blank } finally { 2058d69d4e10a9a36ff790babb2f3a098a12d0dc732Marc Blank client.release(); 2068d69d4e10a9a36ff790babb2f3a098a12d0dc732Marc Blank } 2078d69d4e10a9a36ff790babb2f3a098a12d0dc732Marc Blank } 208732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang} 209