1/* 2 * Copyright (C) 2013 Google Inc. 3 * Licensed to The Android Open Source Project. 4 * 5 * Licensed under the Apache License, Version 2.0 (the "License"); 6 * you may not use this file except in compliance with the License. 7 * You may obtain a copy of the License at 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 */ 17 18package com.android.mail.browse; 19 20import android.content.Context; 21import android.database.Cursor; 22import android.net.Uri; 23 24import com.android.emailcommon.internet.MimeMessage; 25import com.android.emailcommon.mail.MessagingException; 26import com.android.mail.browse.MessageCursor.ConversationController; 27import com.android.mail.content.CursorCreator; 28import com.android.mail.providers.Account; 29import com.android.mail.providers.Attachment; 30import com.android.mail.providers.Conversation; 31import com.android.mail.providers.Message; 32import com.android.mail.ui.ConversationUpdater; 33import com.google.common.base.Objects; 34 35/** 36 * A message created as part of a conversation view. Sometimes, like during star/unstar, it's 37 * handy to have the owning {@link com.android.mail.providers.Conversation} for context. 38 * 39 * <p>This class must remain separate from the {@link MessageCursor} from whence it came, 40 * because cursors can be closed by their Loaders at any time. The 41 * {@link ConversationController} intermediate is used to obtain the currently opened cursor. 42 * 43 * <p>(N.B. This is a {@link android.os.Parcelable}, so try not to add non-transient fields here. 44 * Parcelable state belongs either in {@link com.android.mail.providers.Message} or 45 * {@link com.android.mail.ui.ConversationViewState.MessageViewState}. The 46 * assumption is that this class never needs the state of its extra context saved.) 47 */ 48public final class ConversationMessage extends Message { 49 50 private transient ConversationController mController; 51 52 private ConversationMessage(Cursor cursor) { 53 super(cursor); 54 } 55 56 public ConversationMessage(Context context, MimeMessage mimeMessage, Uri emlFileUri) 57 throws MessagingException { 58 super(context, mimeMessage, emlFileUri); 59 } 60 61 public void setController(ConversationController controller) { 62 mController = controller; 63 } 64 65 public Conversation getConversation() { 66 return mController != null ? mController.getConversation() : null; 67 } 68 69 public Account getAccount() { 70 return mController != null ? mController.getAccount() : null; 71 } 72 73 /** 74 * Returns a hash code based on this message's identity, contents and current state. 75 * This is a separate method from hashCode() to allow for an instance of this class to be 76 * a functional key in a hash-based data structure. 77 * 78 */ 79 public int getStateHashCode() { 80 return Objects.hashCode(uri, read, starred, getAttachmentsStateHashCode()); 81 } 82 83 private int getAttachmentsStateHashCode() { 84 int hash = 0; 85 for (Attachment a : getAttachments()) { 86 final Uri uri = a.getIdentifierUri(); 87 hash += (uri != null ? uri.hashCode() : 0); 88 } 89 return hash; 90 } 91 92 public boolean isConversationStarred() { 93 final MessageCursor c = mController.getMessageCursor(); 94 return c != null && c.isConversationStarred(); 95 } 96 97 public void star(boolean newStarred) { 98 final ConversationUpdater listController = mController.getListController(); 99 if (listController != null) { 100 listController.starMessage(this, newStarred); 101 } 102 } 103 104 /** 105 * Public object that knows how to construct Messages given Cursors. 106 */ 107 public static final CursorCreator<ConversationMessage> FACTORY = 108 new CursorCreator<ConversationMessage>() { 109 @Override 110 public ConversationMessage createFromCursor(Cursor c) { 111 return new ConversationMessage(c); 112 } 113 114 @Override 115 public String toString() { 116 return "ConversationMessage CursorCreator"; 117 } 118 }; 119 120} 121