Conversation.java revision dd10bc8736282262da0cd9a5f9a0236c10b47028
1/** 2 * Copyright (c) 2012, Google Inc. 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17package com.android.mail.providers; 18 19import android.content.ContentProviderClient; 20import android.content.ContentValues; 21import android.content.Context; 22import android.database.Cursor; 23import android.net.Uri; 24import android.os.Parcel; 25import android.os.Parcelable; 26 27import com.android.mail.browse.ConversationCursor.ConversationOperation; 28import com.android.mail.browse.ConversationCursor.ConversationProvider; 29 30import java.util.ArrayList; 31import java.util.Collection; 32 33public class Conversation implements Parcelable { 34 public static final int NO_POSITION = -1; 35 36 public long id; 37 public String subject; 38 public long dateMs; 39 public String snippet; 40 public boolean hasAttachments; 41 public Uri messageListUri; 42 public String senders; 43 public int numMessages; 44 public int numDrafts; 45 public int sendingState; 46 public int priority; 47 public boolean read; 48 public boolean starred; 49 public transient int position; 50 51 @Override 52 public int describeContents() { 53 return 0; 54 } 55 56 @Override 57 public void writeToParcel(Parcel dest, int flags) { 58 dest.writeLong(id); 59 dest.writeString(subject); 60 dest.writeLong(dateMs); 61 dest.writeString(snippet); 62 dest.writeByte(hasAttachments ? (byte) 1 : 0); 63 dest.writeParcelable(messageListUri, flags); 64 dest.writeString(senders); 65 dest.writeInt(numMessages); 66 dest.writeInt(numDrafts); 67 dest.writeInt(sendingState); 68 dest.writeInt(priority); 69 dest.writeByte(read ? (byte) 1 : 0); 70 dest.writeByte(starred ? (byte) 1 : 0); 71 } 72 73 private Conversation(Parcel in) { 74 id = in.readLong(); 75 subject = in.readString(); 76 dateMs = in.readLong(); 77 snippet = in.readString(); 78 hasAttachments = (in.readByte() != 0); 79 messageListUri = in.readParcelable(null); 80 senders = in.readString(); 81 numMessages = in.readInt(); 82 numDrafts = in.readInt(); 83 sendingState = in.readInt(); 84 priority = in.readInt(); 85 read = (in.readByte() != 0); 86 starred = (in.readByte() != 0); 87 position = NO_POSITION; 88 } 89 90 @Override 91 public String toString() { 92 return "[conversation id=" + id + "]"; 93 } 94 95 public static final Creator<Conversation> CREATOR = new Creator<Conversation>() { 96 97 @Override 98 public Conversation createFromParcel(Parcel source) { 99 return new Conversation(source); 100 } 101 102 @Override 103 public Conversation[] newArray(int size) { 104 return new Conversation[size]; 105 } 106 107 }; 108 109 public static Conversation from(Cursor cursor) { 110 return new Conversation(cursor); 111 } 112 113 private Conversation(Cursor cursor) { 114 if (cursor != null) { 115 id = cursor.getLong(UIProvider.CONVERSATION_ID_COLUMN); 116 dateMs = cursor.getLong(UIProvider.CONVERSATION_DATE_RECEIVED_MS_COLUMN); 117 subject = cursor.getString(UIProvider.CONVERSATION_SUBJECT_COLUMN); 118 // Don't allow null subject 119 if (subject == null) { 120 subject = ""; 121 } 122 snippet = cursor.getString(UIProvider.CONVERSATION_SNIPPET_COLUMN); 123 hasAttachments = cursor.getInt(UIProvider.CONVERSATION_HAS_ATTACHMENTS_COLUMN) == 1; 124 messageListUri = Uri.parse(cursor 125 .getString(UIProvider.CONVERSATION_MESSAGE_LIST_URI_COLUMN)); 126 senders = cursor.getString(UIProvider.CONVERSATION_SENDER_INFO_COLUMN); 127 numMessages = cursor.getInt(UIProvider.CONVERSATION_NUM_MESSAGES_COLUMN); 128 numDrafts = cursor.getInt(UIProvider.CONVERSATION_NUM_DRAFTS_COLUMN); 129 sendingState = cursor.getInt(UIProvider.CONVERSATION_SENDING_STATE_COLUMN); 130 priority = cursor.getInt(UIProvider.CONVERSATION_PRIORITY_COLUMN); 131 read = cursor.getInt(UIProvider.CONVERSATION_READ_COLUMN) == 1; 132 starred = cursor.getInt(UIProvider.CONVERSATION_STARRED_COLUMN) == 1; 133 position = NO_POSITION; 134 } 135 } 136 137 // Below are methods that update Conversation data (update/delete) 138 139 /** 140 * Update a boolean column for a single conversation 141 * @param context the caller's context 142 * @param columnName the column to update 143 * @param value the new value 144 * @return the sequence number of the operation (for undo) 145 */ 146 public int updateBoolean(Context context, String columnName, boolean value) { 147 ArrayList<Conversation> conversations = new ArrayList<Conversation>(); 148 conversations.add(this); 149 return updateBoolean(context, conversations, columnName, value); 150 } 151 152 /** 153 * Update a boolean column for a group of conversations, immediately in the UI and in a single 154 * transaction in the underlying provider 155 * @param conversations a collection of conversations 156 * @param context the caller's context 157 * @param columnName the column to update 158 * @param value the new value 159 * @return the sequence number of the operation (for undo) 160 */ 161 public static int updateBoolean(Context context, Collection<Conversation> conversations, 162 String columnName, boolean value) { 163 ContentValues cv = new ContentValues(); 164 cv.put(columnName, value); 165 ArrayList<ConversationOperation> ops = new ArrayList<ConversationOperation>(); 166 for (Conversation conv: conversations) { 167 ConversationOperation op = 168 new ConversationOperation(ConversationOperation.UPDATE, conv, cv); 169 ops.add(op); 170 } 171 return apply(context, ops); 172 } 173 174 /** 175 * Delete a single conversation 176 * @param context the caller's context 177 * @return the sequence number of the operation (for undo) 178 */ 179 public int delete(Context context) { 180 ArrayList<Conversation> conversations = new ArrayList<Conversation>(); 181 conversations.add(this); 182 return delete(context, conversations); 183 } 184 185 /** 186 * Delete a group of conversations immediately in the UI and in a single transaction in the 187 * underlying provider 188 * @param context the caller's context 189 * @param conversations a collection of conversations 190 * @return the sequence number of the operation (for undo) 191 */ 192 public static int delete(Context context, Collection<Conversation> conversations) { 193 ArrayList<ConversationOperation> ops = new ArrayList<ConversationOperation>(); 194 for (Conversation conv: conversations) { 195 ConversationOperation op = 196 new ConversationOperation(ConversationOperation.DELETE, conv); 197 ops.add(op); 198 } 199 return apply(context, ops); 200 } 201 202 // Convenience methods 203 private static int apply(Context context, ArrayList<ConversationOperation> operations) { 204 ContentProviderClient client = 205 context.getContentResolver().acquireContentProviderClient( 206 ConversationProvider.AUTHORITY); 207 try { 208 ConversationProvider cp = (ConversationProvider)client.getLocalContentProvider(); 209 return cp.apply(operations); 210 } finally { 211 client.release(); 212 } 213 } 214}