Home | History | Annotate | Download | only in browse
      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 
     18 package com.android.mail.browse;
     19 
     20 import android.content.Context;
     21 import android.database.Cursor;
     22 import android.net.Uri;
     23 
     24 import com.android.emailcommon.internet.MimeMessage;
     25 import com.android.emailcommon.mail.MessagingException;
     26 import com.android.mail.browse.MessageCursor.ConversationController;
     27 import com.android.mail.content.CursorCreator;
     28 import com.android.mail.providers.Attachment;
     29 import com.android.mail.providers.Conversation;
     30 import com.android.mail.providers.Message;
     31 import com.android.mail.ui.ConversationUpdater;
     32 import com.google.common.base.Objects;
     33 
     34 /**
     35  * A message created as part of a conversation view. Sometimes, like during star/unstar, it's
     36  * handy to have the owning {@link com.android.mail.providers.Conversation} for context.
     37  *
     38  * <p>This class must remain separate from the {@link MessageCursor} from whence it came,
     39  * because cursors can be closed by their Loaders at any time. The
     40  * {@link ConversationController} intermediate is used to obtain the currently opened cursor.
     41  *
     42  * <p>(N.B. This is a {@link android.os.Parcelable}, so try not to add non-transient fields here.
     43  * Parcelable state belongs either in {@link com.android.mail.providers.Message} or
     44  * {@link com.android.mail.ui.ConversationViewState.MessageViewState}. The
     45  * assumption is that this class never needs the state of its extra context saved.)
     46  */
     47 public final class ConversationMessage extends Message {
     48 
     49     private transient ConversationController mController;
     50 
     51     private ConversationMessage(Cursor cursor) {
     52         super(cursor);
     53     }
     54 
     55     public ConversationMessage(Context context, MimeMessage mimeMessage, Uri emlFileUri)
     56             throws MessagingException {
     57         super(context, mimeMessage, emlFileUri);
     58     }
     59 
     60     public void setController(ConversationController controller) {
     61         mController = controller;
     62     }
     63 
     64     public Conversation getConversation() {
     65         return mController != null ? mController.getConversation() : null;
     66     }
     67 
     68     /**
     69      * Returns a hash code based on this message's identity, contents and current state.
     70      * This is a separate method from hashCode() to allow for an instance of this class to be
     71      * a functional key in a hash-based data structure.
     72      *
     73      */
     74     public int getStateHashCode() {
     75         return Objects.hashCode(uri, read, starred, getAttachmentsStateHashCode());
     76     }
     77 
     78     private int getAttachmentsStateHashCode() {
     79         int hash = 0;
     80         for (Attachment a : getAttachments()) {
     81             final Uri uri = a.getIdentifierUri();
     82             hash += (uri != null ? uri.hashCode() : 0);
     83         }
     84         return hash;
     85     }
     86 
     87     public boolean isConversationStarred() {
     88         final MessageCursor c = mController.getMessageCursor();
     89         return c != null && c.isConversationStarred();
     90     }
     91 
     92     public void star(boolean newStarred) {
     93         final ConversationUpdater listController = mController.getListController();
     94         if (listController != null) {
     95             listController.starMessage(this, newStarred);
     96         }
     97     }
     98 
     99     /**
    100      * Public object that knows how to construct Messages given Cursors.
    101      */
    102     public static final CursorCreator<ConversationMessage> FACTORY =
    103             new CursorCreator<ConversationMessage>() {
    104                 @Override
    105                 public ConversationMessage createFromCursor(Cursor c) {
    106                     return new ConversationMessage(c);
    107                 }
    108 
    109                 @Override
    110                 public String toString() {
    111                     return "ConversationMessage CursorCreator";
    112                 }
    113             };
    114 
    115 }
    116