ConversationViewState.java revision 47aa9c991b33c722a6ba1946fc02e0aba17bc1c9
1/* 2 * Copyright (C) 2012 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.ui; 19 20import android.net.Uri; 21import android.os.Bundle; 22import android.os.Parcel; 23import android.os.Parcelable; 24 25import com.android.mail.providers.Conversation; 26import com.android.mail.providers.ConversationInfo; 27import com.android.mail.providers.Message; 28import com.google.common.collect.Maps; 29import com.google.common.collect.Sets; 30 31import org.json.JSONException; 32 33import java.util.Map; 34import java.util.Set; 35 36/** 37 * A small class to keep state for conversation view when restoring. 38 * 39 */ 40class ConversationViewState implements Parcelable { 41 42 // N.B. don't serialize entire Messages because they contain body HTML/text 43 44 private final Map<Uri, MessageViewState> mMessageViewStates = Maps.newHashMap(); 45 46 private String mConversationInfo; 47 48 public ConversationViewState() {} 49 50 /** 51 * Copy constructor that will copy overall conversation state, but NOT individual message state. 52 */ 53 public ConversationViewState(ConversationViewState other) { 54 mConversationInfo = other.mConversationInfo; 55 } 56 57 public boolean isUnread(Message m) { 58 final MessageViewState mvs = mMessageViewStates.get(m.uri); 59 return (mvs != null && !mvs.read); 60 } 61 62 public void setReadState(Message m, boolean read) { 63 MessageViewState mvs = mMessageViewStates.get(m.uri); 64 if (mvs == null) { 65 mvs = new MessageViewState(); 66 } 67 mvs.read = read; 68 mMessageViewStates.put(m.uri, mvs); 69 } 70 71 /** 72 * Returns the expansion state of a message in a conversation view. Expansion state only refers 73 * to the user action of expanding or collapsing a message view, and not any messages that 74 * are expanded by default (e.g. last message, starred messages). 75 * 76 * @param m a Message in the conversation 77 * @return true if the user expanded it, false if the user collapsed it, or null otherwise. 78 */ 79 public Boolean getExpandedState(Message m) { 80 final MessageViewState mvs = mMessageViewStates.get(m.uri); 81 return (mvs == null ? null : mvs.expanded); 82 } 83 84 public void setExpandedState(Message m, boolean expanded) { 85 MessageViewState mvs = mMessageViewStates.get(m.uri); 86 if (mvs == null) { 87 mvs = new MessageViewState(); 88 } 89 mvs.expanded = expanded; 90 mMessageViewStates.put(m.uri, mvs); 91 } 92 93 public String getConversationInfo() { 94 return mConversationInfo; 95 } 96 97 public void setInfoForConversation(Conversation conv) throws JSONException { 98 mConversationInfo = ConversationInfo.toString(conv.conversationInfo); 99 } 100 101 /** 102 * Returns URIs of all unread messages in the conversation per 103 * {@link #setReadState(Message, boolean)}. Returns an empty set for read conversations. 104 * 105 */ 106 public Set<Uri> getUnreadMessageUris() { 107 final Set<Uri> result = Sets.newHashSet(); 108 for (Uri uri : mMessageViewStates.keySet()) { 109 final MessageViewState mvs = mMessageViewStates.get(uri); 110 if (mvs != null && !mvs.read) { 111 result.add(uri); 112 } 113 } 114 return result; 115 } 116 117 public boolean contains(Message m) { 118 return mMessageViewStates.containsKey(m.uri); 119 } 120 121 @Override 122 public int describeContents() { 123 return 0; 124 } 125 126 @Override 127 public void writeToParcel(Parcel dest, int flags) { 128 final Bundle states = new Bundle(); 129 for (Uri uri : mMessageViewStates.keySet()) { 130 final MessageViewState mvs = mMessageViewStates.get(uri); 131 states.putParcelable(uri.toString(), mvs); 132 } 133 dest.writeBundle(states); 134 dest.writeString(mConversationInfo); 135 } 136 137 private ConversationViewState(Parcel source) { 138 final Bundle states = source.readBundle(MessageViewState.class.getClassLoader()); 139 for (String key : states.keySet()) { 140 final MessageViewState state = states.getParcelable(key); 141 mMessageViewStates.put(Uri.parse(key), state); 142 } 143 mConversationInfo = source.readString(); 144 } 145 146 public static Parcelable.Creator<ConversationViewState> CREATOR = 147 new Parcelable.Creator<ConversationViewState>() { 148 149 @Override 150 public ConversationViewState createFromParcel(Parcel source) { 151 return new ConversationViewState(source); 152 } 153 154 @Override 155 public ConversationViewState[] newArray(int size) { 156 return new ConversationViewState[size]; 157 } 158 159 }; 160 161 // Keep per-message state in an inner Parcelable. 162 // This is a semi-private implementation detail. 163 static class MessageViewState implements Parcelable { 164 165 public boolean read; 166 /** 167 * null = default, false = collapsed, true = expanded 168 */ 169 public Boolean expanded; 170 171 public MessageViewState() {} 172 173 @Override 174 public int describeContents() { 175 return 0; 176 } 177 178 @Override 179 public void writeToParcel(Parcel dest, int flags) { 180 dest.writeInt(read ? 1 : 0); 181 dest.writeInt(expanded == null ? -1 : (expanded ? 1 : 0)); 182 } 183 184 private MessageViewState(Parcel source) { 185 read = (source.readInt() != 0); 186 final int expandedVal = source.readInt(); 187 expanded = (expandedVal == -1) ? null : (expandedVal != 0); 188 } 189 190 @SuppressWarnings("hiding") 191 public static Parcelable.Creator<MessageViewState> CREATOR = 192 new Parcelable.Creator<MessageViewState>() { 193 194 @Override 195 public MessageViewState createFromParcel(Parcel source) { 196 return new MessageViewState(source); 197 } 198 199 @Override 200 public MessageViewState[] newArray(int size) { 201 return new MessageViewState[size]; 202 } 203 204 }; 205 206 } 207 208} 209