1 /* 2 * Copyright (C) 2015 The Android Open Source Project 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 17 package com.android.messaging.datamodel.data; 18 19 import android.database.Cursor; 20 import android.net.Uri; 21 import android.provider.BaseColumns; 22 import android.text.TextUtils; 23 24 import com.android.messaging.datamodel.DatabaseHelper; 25 import com.android.messaging.datamodel.DatabaseHelper.ConversationColumns; 26 import com.android.messaging.datamodel.DatabaseHelper.MessageColumns; 27 import com.android.messaging.datamodel.DatabaseHelper.ParticipantColumns; 28 import com.android.messaging.datamodel.DatabaseWrapper; 29 import com.android.messaging.datamodel.action.DeleteConversationAction; 30 import com.android.messaging.util.Assert; 31 import com.android.messaging.util.Dates; 32 import com.google.common.base.Joiner; 33 34 import java.util.ArrayList; 35 import java.util.List; 36 37 /** 38 * Class wrapping the conversation list view used to display each item in conversation list 39 */ 40 public class ConversationListItemData { 41 private String mConversationId; 42 private String mName; 43 private String mIcon; 44 private boolean mIsRead; 45 private long mTimestamp; 46 private String mSnippetText; 47 private Uri mPreviewUri; 48 private String mPreviewContentType; 49 private long mParticipantContactId; 50 private String mParticipantLookupKey; 51 private String mOtherParticipantNormalizedDestination; 52 private String mSelfId; 53 private int mParticipantCount; 54 private boolean mNotificationEnabled; 55 private String mNotificationSoundUri; 56 private boolean mNotificationVibrate; 57 private boolean mIncludeEmailAddress; 58 private int mMessageStatus; 59 private int mMessageRawTelephonyStatus; 60 private boolean mShowDraft; 61 private Uri mDraftPreviewUri; 62 private String mDraftPreviewContentType; 63 private String mDraftSnippetText; 64 private boolean mIsArchived; 65 private String mSubject; 66 private String mDraftSubject; 67 private String mSnippetSenderFirstName; 68 private String mSnippetSenderDisplayDestination; 69 ConversationListItemData()70 public ConversationListItemData() { 71 } 72 bind(final Cursor cursor)73 public void bind(final Cursor cursor) { 74 bind(cursor, false); 75 } 76 bind(final Cursor cursor, final boolean ignoreDraft)77 public void bind(final Cursor cursor, final boolean ignoreDraft) { 78 mConversationId = cursor.getString(INDEX_ID); 79 mName = cursor.getString(INDEX_CONVERSATION_NAME); 80 mIcon = cursor.getString(INDEX_CONVERSATION_ICON); 81 mSnippetText = cursor.getString(INDEX_SNIPPET_TEXT); 82 mTimestamp = cursor.getLong(INDEX_SORT_TIMESTAMP); 83 mIsRead = cursor.getInt(INDEX_READ) == 1; 84 final String previewUriString = cursor.getString(INDEX_PREVIEW_URI); 85 mPreviewUri = TextUtils.isEmpty(previewUriString) ? null : Uri.parse(previewUriString); 86 mPreviewContentType = cursor.getString(INDEX_PREVIEW_CONTENT_TYPE); 87 mParticipantContactId = cursor.getLong(INDEX_PARTICIPANT_CONTACT_ID); 88 mParticipantLookupKey = cursor.getString(INDEX_PARTICIPANT_LOOKUP_KEY); 89 mOtherParticipantNormalizedDestination = cursor.getString( 90 INDEX_OTHER_PARTICIPANT_NORMALIZED_DESTINATION); 91 mSelfId = cursor.getString(INDEX_SELF_ID); 92 mParticipantCount = cursor.getInt(INDEX_PARTICIPANT_COUNT); 93 mNotificationEnabled = cursor.getInt(INDEX_NOTIFICATION_ENABLED) == 1; 94 mNotificationSoundUri = cursor.getString(INDEX_NOTIFICATION_SOUND_URI); 95 mNotificationVibrate = cursor.getInt(INDEX_NOTIFICATION_VIBRATION) == 1; 96 mIncludeEmailAddress = cursor.getInt(INDEX_INCLUDE_EMAIL_ADDRESS) == 1; 97 mMessageStatus = cursor.getInt(INDEX_MESSAGE_STATUS); 98 mMessageRawTelephonyStatus = cursor.getInt(INDEX_MESSAGE_RAW_TELEPHONY_STATUS); 99 if (!ignoreDraft) { 100 mShowDraft = cursor.getInt(INDEX_SHOW_DRAFT) == 1; 101 final String draftPreviewUriString = cursor.getString(INDEX_DRAFT_PREVIEW_URI); 102 mDraftPreviewUri = TextUtils.isEmpty(draftPreviewUriString) ? 103 null : Uri.parse(draftPreviewUriString); 104 mDraftPreviewContentType = cursor.getString(INDEX_DRAFT_PREVIEW_CONTENT_TYPE); 105 mDraftSnippetText = cursor.getString(INDEX_DRAFT_SNIPPET_TEXT); 106 mDraftSubject = cursor.getString(INDEX_DRAFT_SUBJECT_TEXT); 107 } else { 108 mShowDraft = false; 109 mDraftPreviewUri = null; 110 mDraftPreviewContentType = null; 111 mDraftSnippetText = null; 112 mDraftSubject = null; 113 } 114 115 mIsArchived = cursor.getInt(INDEX_ARCHIVE_STATUS) == 1; 116 mSubject = cursor.getString(INDEX_SUBJECT_TEXT); 117 mSnippetSenderFirstName = cursor.getString(INDEX_SNIPPET_SENDER_FIRST_NAME); 118 mSnippetSenderDisplayDestination = 119 cursor.getString(INDEX_SNIPPET_SENDER_DISPLAY_DESTINATION); 120 } 121 getConversationId()122 public String getConversationId() { 123 return mConversationId; 124 } 125 getName()126 public String getName() { 127 return mName; 128 } 129 getIcon()130 public String getIcon() { 131 return mIcon; 132 } 133 getIsRead()134 public boolean getIsRead() { 135 return mIsRead; 136 } 137 getFormattedTimestamp()138 public String getFormattedTimestamp() { 139 return Dates.getConversationTimeString(mTimestamp).toString(); 140 } 141 getTimestamp()142 public long getTimestamp() { 143 return mTimestamp; 144 } 145 getSnippetText()146 public String getSnippetText() { 147 return mSnippetText; 148 } 149 getPreviewUri()150 public Uri getPreviewUri() { 151 return mPreviewUri; 152 } 153 getPreviewContentType()154 public String getPreviewContentType() { 155 return mPreviewContentType; 156 } 157 getParticipantContactId()158 public long getParticipantContactId() { 159 return mParticipantContactId; 160 } 161 getParticipantLookupKey()162 public String getParticipantLookupKey() { 163 return mParticipantLookupKey; 164 } 165 getOtherParticipantNormalizedDestination()166 public String getOtherParticipantNormalizedDestination() { 167 return mOtherParticipantNormalizedDestination; 168 } 169 getSelfId()170 public String getSelfId() { 171 return mSelfId; 172 } 173 getParticipantCount()174 public int getParticipantCount() { 175 return mParticipantCount; 176 } 177 getIsGroup()178 public boolean getIsGroup() { 179 // Participant count excludes self 180 return (mParticipantCount > 1); 181 } 182 getIncludeEmailAddress()183 public boolean getIncludeEmailAddress() { 184 return mIncludeEmailAddress; 185 } 186 getNotificationEnabled()187 public boolean getNotificationEnabled() { 188 return mNotificationEnabled; 189 } 190 getNotificationSoundUri()191 public String getNotificationSoundUri() { 192 return mNotificationSoundUri; 193 } 194 getNotifiationVibrate()195 public boolean getNotifiationVibrate() { 196 return mNotificationVibrate; 197 } 198 getIsFailedStatus()199 public final boolean getIsFailedStatus() { 200 return (mMessageStatus == MessageData.BUGLE_STATUS_OUTGOING_FAILED || 201 mMessageStatus == MessageData.BUGLE_STATUS_OUTGOING_FAILED_EMERGENCY_NUMBER || 202 mMessageStatus == MessageData.BUGLE_STATUS_INCOMING_DOWNLOAD_FAILED || 203 mMessageStatus == MessageData.BUGLE_STATUS_INCOMING_EXPIRED_OR_NOT_AVAILABLE); 204 } 205 getIsSendRequested()206 public final boolean getIsSendRequested() { 207 return (mMessageStatus == MessageData.BUGLE_STATUS_OUTGOING_YET_TO_SEND || 208 mMessageStatus == MessageData.BUGLE_STATUS_OUTGOING_AWAITING_RETRY || 209 mMessageStatus == MessageData.BUGLE_STATUS_OUTGOING_SENDING || 210 mMessageStatus == MessageData.BUGLE_STATUS_OUTGOING_RESENDING); 211 } 212 getIsMessageTypeOutgoing()213 public boolean getIsMessageTypeOutgoing() { 214 return !MessageData.getIsIncoming(mMessageStatus); 215 } 216 getMessageRawTelephonyStatus()217 public int getMessageRawTelephonyStatus() { 218 return mMessageRawTelephonyStatus; 219 } 220 getMessageStatus()221 public int getMessageStatus() { 222 return mMessageStatus; 223 } 224 getShowDraft()225 public boolean getShowDraft() { 226 return mShowDraft; 227 } 228 getDraftSnippetText()229 public String getDraftSnippetText() { 230 return mDraftSnippetText; 231 } 232 getDraftPreviewUri()233 public Uri getDraftPreviewUri() { 234 return mDraftPreviewUri; 235 } 236 getDraftPreviewContentType()237 public String getDraftPreviewContentType() { 238 return mDraftPreviewContentType; 239 } 240 getIsArchived()241 public boolean getIsArchived() { 242 return mIsArchived; 243 } 244 getSubject()245 public String getSubject() { 246 return mSubject; 247 } 248 getDraftSubject()249 public String getDraftSubject() { 250 return mDraftSubject; 251 } 252 getSnippetSenderName()253 public String getSnippetSenderName() { 254 if (!TextUtils.isEmpty(mSnippetSenderFirstName)) { 255 return mSnippetSenderFirstName; 256 } 257 return mSnippetSenderDisplayDestination; 258 } 259 deleteConversation()260 public void deleteConversation() { 261 DeleteConversationAction.deleteConversation(mConversationId, mTimestamp); 262 } 263 264 /** 265 * Get the name of the view for this data item 266 */ getConversationListView()267 public static final String getConversationListView() { 268 return CONVERSATION_LIST_VIEW; 269 } 270 getConversationListViewSql()271 public static final String getConversationListViewSql() { 272 return CONVERSATION_LIST_VIEW_SQL; 273 } 274 275 private static final String CONVERSATION_LIST_VIEW = "conversation_list_view"; 276 277 private static final String CONVERSATION_LIST_VIEW_PROJECTION = 278 DatabaseHelper.CONVERSATIONS_TABLE + '.' + ConversationColumns._ID 279 + " as " + ConversationListViewColumns._ID + ", " 280 + DatabaseHelper.CONVERSATIONS_TABLE + '.' + ConversationColumns.NAME 281 + " as " + ConversationListViewColumns.NAME + ", " 282 + DatabaseHelper.CONVERSATIONS_TABLE + '.' + ConversationColumns.CURRENT_SELF_ID 283 + " as " + ConversationListViewColumns.CURRENT_SELF_ID + ", " 284 + DatabaseHelper.CONVERSATIONS_TABLE + '.' + ConversationColumns.ARCHIVE_STATUS 285 + " as " + ConversationListViewColumns.ARCHIVE_STATUS + ", " 286 + DatabaseHelper.MESSAGES_TABLE + '.' + MessageColumns.READ 287 + " as " + ConversationListViewColumns.READ + ", " 288 + DatabaseHelper.CONVERSATIONS_TABLE + '.' + ConversationColumns.ICON 289 + " as " + ConversationListViewColumns.ICON + ", " 290 + DatabaseHelper.CONVERSATIONS_TABLE + '.' + ConversationColumns.PARTICIPANT_CONTACT_ID 291 + " as " + ConversationListViewColumns.PARTICIPANT_CONTACT_ID + ", " 292 + DatabaseHelper.CONVERSATIONS_TABLE + '.' + ConversationColumns.PARTICIPANT_LOOKUP_KEY 293 + " as " + ConversationListViewColumns.PARTICIPANT_LOOKUP_KEY + ", " 294 + DatabaseHelper.CONVERSATIONS_TABLE + '.' 295 + ConversationColumns.OTHER_PARTICIPANT_NORMALIZED_DESTINATION 296 + " as " + ConversationListViewColumns.OTHER_PARTICIPANT_NORMALIZED_DESTINATION + ", " 297 + DatabaseHelper.CONVERSATIONS_TABLE + '.' + ConversationColumns.SORT_TIMESTAMP 298 + " as " + ConversationListViewColumns.SORT_TIMESTAMP + ", " 299 + DatabaseHelper.CONVERSATIONS_TABLE + '.' + ConversationColumns.SHOW_DRAFT 300 + " as " + ConversationListViewColumns.SHOW_DRAFT + ", " 301 + DatabaseHelper.CONVERSATIONS_TABLE + '.' + ConversationColumns.DRAFT_SNIPPET_TEXT 302 + " as " + ConversationListViewColumns.DRAFT_SNIPPET_TEXT + ", " 303 + DatabaseHelper.CONVERSATIONS_TABLE + '.' + ConversationColumns.DRAFT_PREVIEW_URI 304 + " as " + ConversationListViewColumns.DRAFT_PREVIEW_URI + ", " 305 + DatabaseHelper.CONVERSATIONS_TABLE + '.' + ConversationColumns.DRAFT_SUBJECT_TEXT 306 + " as " + ConversationListViewColumns.DRAFT_SUBJECT_TEXT + ", " 307 + DatabaseHelper.CONVERSATIONS_TABLE + '.' 308 + ConversationColumns.DRAFT_PREVIEW_CONTENT_TYPE 309 + " as " + ConversationListViewColumns.DRAFT_PREVIEW_CONTENT_TYPE + ", " 310 + DatabaseHelper.CONVERSATIONS_TABLE + '.' + ConversationColumns.PREVIEW_URI 311 + " as " + ConversationListViewColumns.PREVIEW_URI + ", " 312 + DatabaseHelper.CONVERSATIONS_TABLE + '.' + ConversationColumns.PREVIEW_CONTENT_TYPE 313 + " as " + ConversationListViewColumns.PREVIEW_CONTENT_TYPE + ", " 314 + DatabaseHelper.CONVERSATIONS_TABLE + '.' + ConversationColumns.PARTICIPANT_COUNT 315 + " as " + ConversationListViewColumns.PARTICIPANT_COUNT + ", " 316 + DatabaseHelper.CONVERSATIONS_TABLE + '.' + ConversationColumns.NOTIFICATION_ENABLED 317 + " as " + ConversationListViewColumns.NOTIFICATION_ENABLED + ", " 318 + DatabaseHelper.CONVERSATIONS_TABLE + '.' + ConversationColumns.NOTIFICATION_SOUND_URI 319 + " as " + ConversationListViewColumns.NOTIFICATION_SOUND_URI + ", " 320 + DatabaseHelper.CONVERSATIONS_TABLE + '.' + ConversationColumns.NOTIFICATION_VIBRATION 321 + " as " + ConversationListViewColumns.NOTIFICATION_VIBRATION + ", " 322 + DatabaseHelper.CONVERSATIONS_TABLE + '.' + 323 ConversationColumns.INCLUDE_EMAIL_ADDRESS 324 + " as " + ConversationListViewColumns.INCLUDE_EMAIL_ADDRESS + ", " 325 + DatabaseHelper.MESSAGES_TABLE + '.' + MessageColumns.STATUS 326 + " as " + ConversationListViewColumns.MESSAGE_STATUS + ", " 327 + DatabaseHelper.MESSAGES_TABLE + '.' + MessageColumns.RAW_TELEPHONY_STATUS 328 + " as " + ConversationListViewColumns.MESSAGE_RAW_TELEPHONY_STATUS + ", " 329 + DatabaseHelper.MESSAGES_TABLE + '.' + MessageColumns._ID 330 + " as " + ConversationListViewColumns.MESSAGE_ID + ", " 331 + DatabaseHelper.PARTICIPANTS_TABLE + '.' + ParticipantColumns.FIRST_NAME 332 + " as " + ConversationListViewColumns.SNIPPET_SENDER_FIRST_NAME + ", " 333 + DatabaseHelper.PARTICIPANTS_TABLE + '.' + ParticipantColumns.DISPLAY_DESTINATION 334 + " as " + ConversationListViewColumns.SNIPPET_SENDER_DISPLAY_DESTINATION; 335 336 private static final String JOIN_PARTICIPANTS = 337 " LEFT JOIN " + DatabaseHelper.PARTICIPANTS_TABLE + " ON (" 338 + DatabaseHelper.MESSAGES_TABLE + '.' + MessageColumns.SENDER_PARTICIPANT_ID 339 + '=' + DatabaseHelper.PARTICIPANTS_TABLE + '.' + DatabaseHelper.ParticipantColumns._ID 340 + ") "; 341 342 // View that makes latest message read flag available with rest of conversation data. 343 private static final String CONVERSATION_LIST_VIEW_SQL = "CREATE VIEW " + 344 CONVERSATION_LIST_VIEW + " AS SELECT " 345 + CONVERSATION_LIST_VIEW_PROJECTION + ", " 346 // Snippet not part of the base projection shared with search view 347 + DatabaseHelper.CONVERSATIONS_TABLE + '.' + ConversationColumns.SNIPPET_TEXT 348 + " as " + ConversationListViewColumns.SNIPPET_TEXT + ", " 349 + DatabaseHelper.CONVERSATIONS_TABLE + '.' + ConversationColumns.SUBJECT_TEXT 350 + " as " + ConversationListViewColumns.SUBJECT_TEXT + " " 351 + " FROM " + DatabaseHelper.CONVERSATIONS_TABLE 352 + " LEFT JOIN " + DatabaseHelper.MESSAGES_TABLE + " ON (" 353 + DatabaseHelper.CONVERSATIONS_TABLE + '.' + ConversationColumns.LATEST_MESSAGE_ID 354 + '=' + DatabaseHelper.MESSAGES_TABLE + '.' + MessageColumns._ID + ") " 355 + JOIN_PARTICIPANTS 356 + "ORDER BY " + DatabaseHelper.CONVERSATIONS_TABLE + '.' 357 + ConversationColumns.SORT_TIMESTAMP + " DESC"; 358 359 public static class ConversationListViewColumns implements BaseColumns { 360 public static final String _ID = ConversationColumns._ID; 361 static final String NAME = ConversationColumns.NAME; 362 static final String ARCHIVE_STATUS = ConversationColumns.ARCHIVE_STATUS; 363 static final String READ = MessageColumns.READ; 364 static final String SORT_TIMESTAMP = ConversationColumns.SORT_TIMESTAMP; 365 static final String PREVIEW_URI = ConversationColumns.PREVIEW_URI; 366 static final String PREVIEW_CONTENT_TYPE = ConversationColumns.PREVIEW_CONTENT_TYPE; 367 static final String SNIPPET_TEXT = ConversationColumns.SNIPPET_TEXT; 368 static final String SUBJECT_TEXT = ConversationColumns.SUBJECT_TEXT; 369 static final String ICON = ConversationColumns.ICON; 370 static final String SHOW_DRAFT = ConversationColumns.SHOW_DRAFT; 371 static final String DRAFT_SUBJECT_TEXT = ConversationColumns.DRAFT_SUBJECT_TEXT; 372 static final String DRAFT_PREVIEW_URI = ConversationColumns.DRAFT_PREVIEW_URI; 373 static final String DRAFT_PREVIEW_CONTENT_TYPE = 374 ConversationColumns.DRAFT_PREVIEW_CONTENT_TYPE; 375 static final String DRAFT_SNIPPET_TEXT = ConversationColumns.DRAFT_SNIPPET_TEXT; 376 static final String PARTICIPANT_CONTACT_ID = ConversationColumns.PARTICIPANT_CONTACT_ID; 377 static final String PARTICIPANT_LOOKUP_KEY = ConversationColumns.PARTICIPANT_LOOKUP_KEY; 378 static final String OTHER_PARTICIPANT_NORMALIZED_DESTINATION = 379 ConversationColumns.OTHER_PARTICIPANT_NORMALIZED_DESTINATION; 380 static final String CURRENT_SELF_ID = ConversationColumns.CURRENT_SELF_ID; 381 static final String PARTICIPANT_COUNT = ConversationColumns.PARTICIPANT_COUNT; 382 static final String NOTIFICATION_ENABLED = ConversationColumns.NOTIFICATION_ENABLED; 383 static final String NOTIFICATION_SOUND_URI = ConversationColumns.NOTIFICATION_SOUND_URI; 384 static final String NOTIFICATION_VIBRATION = ConversationColumns.NOTIFICATION_VIBRATION; 385 static final String INCLUDE_EMAIL_ADDRESS = 386 ConversationColumns.INCLUDE_EMAIL_ADDRESS; 387 static final String MESSAGE_STATUS = MessageColumns.STATUS; 388 static final String MESSAGE_RAW_TELEPHONY_STATUS = MessageColumns.RAW_TELEPHONY_STATUS; 389 static final String MESSAGE_ID = "message_id"; 390 static final String SNIPPET_SENDER_FIRST_NAME = "snippet_sender_first_name"; 391 static final String SNIPPET_SENDER_DISPLAY_DESTINATION = 392 "snippet_sender_display_destination"; 393 } 394 395 public static final String[] PROJECTION = { 396 ConversationListViewColumns._ID, 397 ConversationListViewColumns.NAME, 398 ConversationListViewColumns.ICON, 399 ConversationListViewColumns.SNIPPET_TEXT, 400 ConversationListViewColumns.SORT_TIMESTAMP, 401 ConversationListViewColumns.READ, 402 ConversationListViewColumns.PREVIEW_URI, 403 ConversationListViewColumns.PREVIEW_CONTENT_TYPE, 404 ConversationListViewColumns.PARTICIPANT_CONTACT_ID, 405 ConversationListViewColumns.PARTICIPANT_LOOKUP_KEY, 406 ConversationListViewColumns.OTHER_PARTICIPANT_NORMALIZED_DESTINATION, 407 ConversationListViewColumns.PARTICIPANT_COUNT, 408 ConversationListViewColumns.CURRENT_SELF_ID, 409 ConversationListViewColumns.NOTIFICATION_ENABLED, 410 ConversationListViewColumns.NOTIFICATION_SOUND_URI, 411 ConversationListViewColumns.NOTIFICATION_VIBRATION, 412 ConversationListViewColumns.INCLUDE_EMAIL_ADDRESS, 413 ConversationListViewColumns.MESSAGE_STATUS, 414 ConversationListViewColumns.SHOW_DRAFT, 415 ConversationListViewColumns.DRAFT_PREVIEW_URI, 416 ConversationListViewColumns.DRAFT_PREVIEW_CONTENT_TYPE, 417 ConversationListViewColumns.DRAFT_SNIPPET_TEXT, 418 ConversationListViewColumns.ARCHIVE_STATUS, 419 ConversationListViewColumns.MESSAGE_ID, 420 ConversationListViewColumns.SUBJECT_TEXT, 421 ConversationListViewColumns.DRAFT_SUBJECT_TEXT, 422 ConversationListViewColumns.MESSAGE_RAW_TELEPHONY_STATUS, 423 ConversationListViewColumns.SNIPPET_SENDER_FIRST_NAME, 424 ConversationListViewColumns.SNIPPET_SENDER_DISPLAY_DESTINATION, 425 }; 426 427 private static final int INDEX_ID = 0; 428 private static final int INDEX_CONVERSATION_NAME = 1; 429 private static final int INDEX_CONVERSATION_ICON = 2; 430 private static final int INDEX_SNIPPET_TEXT = 3; 431 private static final int INDEX_SORT_TIMESTAMP = 4; 432 private static final int INDEX_READ = 5; 433 private static final int INDEX_PREVIEW_URI = 6; 434 private static final int INDEX_PREVIEW_CONTENT_TYPE = 7; 435 private static final int INDEX_PARTICIPANT_CONTACT_ID = 8; 436 private static final int INDEX_PARTICIPANT_LOOKUP_KEY = 9; 437 private static final int INDEX_OTHER_PARTICIPANT_NORMALIZED_DESTINATION = 10; 438 private static final int INDEX_PARTICIPANT_COUNT = 11; 439 private static final int INDEX_SELF_ID = 12; 440 private static final int INDEX_NOTIFICATION_ENABLED = 13; 441 private static final int INDEX_NOTIFICATION_SOUND_URI = 14; 442 private static final int INDEX_NOTIFICATION_VIBRATION = 15; 443 private static final int INDEX_INCLUDE_EMAIL_ADDRESS = 16; 444 private static final int INDEX_MESSAGE_STATUS = 17; 445 private static final int INDEX_SHOW_DRAFT = 18; 446 private static final int INDEX_DRAFT_PREVIEW_URI = 19; 447 private static final int INDEX_DRAFT_PREVIEW_CONTENT_TYPE = 20; 448 private static final int INDEX_DRAFT_SNIPPET_TEXT = 21; 449 private static final int INDEX_ARCHIVE_STATUS = 22; 450 private static final int INDEX_MESSAGE_ID = 23; 451 private static final int INDEX_SUBJECT_TEXT = 24; 452 private static final int INDEX_DRAFT_SUBJECT_TEXT = 25; 453 private static final int INDEX_MESSAGE_RAW_TELEPHONY_STATUS = 26; 454 private static final int INDEX_SNIPPET_SENDER_FIRST_NAME = 27; 455 private static final int INDEX_SNIPPET_SENDER_DISPLAY_DESTINATION = 28; 456 457 private static final String DIVIDER_TEXT = ", "; 458 459 /** 460 * Get a conversation from the local DB based on the conversation id. 461 * 462 * @param dbWrapper The database 463 * @param conversationId The conversation Id to read 464 * @return The existing conversation or null 465 */ getExistingConversation(final DatabaseWrapper dbWrapper, final String conversationId)466 public static ConversationListItemData getExistingConversation(final DatabaseWrapper dbWrapper, 467 final String conversationId) { 468 ConversationListItemData conversation = null; 469 470 // Look for an existing conversation in the db with this conversation id 471 Cursor cursor = null; 472 try { 473 // TODO: Should we be able to read a row from just the conversation table? 474 cursor = dbWrapper.query(getConversationListView(), 475 PROJECTION, 476 ConversationColumns._ID + "=?", 477 new String[] { conversationId }, 478 null, null, null); 479 Assert.inRange(cursor.getCount(), 0, 1); 480 if (cursor.moveToFirst()) { 481 conversation = new ConversationListItemData(); 482 conversation.bind(cursor); 483 } 484 } finally { 485 if (cursor != null) { 486 cursor.close(); 487 } 488 } 489 490 return conversation; 491 } 492 generateConversationName(final List<ParticipantData> participants)493 public static String generateConversationName(final List<ParticipantData> 494 participants) { 495 if (participants.size() == 1) { 496 // Prefer full name over first name for 1:1 conversation 497 return participants.get(0).getDisplayName(true); 498 } 499 500 final ArrayList<String> participantNames = new ArrayList<String>(); 501 for (final ParticipantData participant : participants) { 502 // Prefer first name over full name for group conversation 503 participantNames.add(participant.getDisplayName(false)); 504 } 505 506 final Joiner joiner = Joiner.on(DIVIDER_TEXT).skipNulls(); 507 return joiner.join(participantNames); 508 } 509 510 } 511