ConversationSelectionSet.java revision 866d319dd23ec8b7b7d5476c65f7f83469d55d2d
14a5c530b0a67e22bd74df8f10f29278dc8d86459Vikram Aggarwal/******************************************************************************* 24a5c530b0a67e22bd74df8f10f29278dc8d86459Vikram Aggarwal * Copyright (C) 2012 Google Inc. 34a5c530b0a67e22bd74df8f10f29278dc8d86459Vikram Aggarwal * Licensed to The Android Open Source Project. 44a5c530b0a67e22bd74df8f10f29278dc8d86459Vikram Aggarwal * 54a5c530b0a67e22bd74df8f10f29278dc8d86459Vikram Aggarwal * Licensed under the Apache License, Version 2.0 (the "License"); 64a5c530b0a67e22bd74df8f10f29278dc8d86459Vikram Aggarwal * you may not use this file except in compliance with the License. 74a5c530b0a67e22bd74df8f10f29278dc8d86459Vikram Aggarwal * You may obtain a copy of the License at 84a5c530b0a67e22bd74df8f10f29278dc8d86459Vikram Aggarwal * 94a5c530b0a67e22bd74df8f10f29278dc8d86459Vikram Aggarwal * http://www.apache.org/licenses/LICENSE-2.0 104a5c530b0a67e22bd74df8f10f29278dc8d86459Vikram Aggarwal * 114a5c530b0a67e22bd74df8f10f29278dc8d86459Vikram Aggarwal * Unless required by applicable law or agreed to in writing, software 124a5c530b0a67e22bd74df8f10f29278dc8d86459Vikram Aggarwal * distributed under the License is distributed on an "AS IS" BASIS, 134a5c530b0a67e22bd74df8f10f29278dc8d86459Vikram Aggarwal * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 144a5c530b0a67e22bd74df8f10f29278dc8d86459Vikram Aggarwal * See the License for the specific language governing permissions and 154a5c530b0a67e22bd74df8f10f29278dc8d86459Vikram Aggarwal * limitations under the License. 164a5c530b0a67e22bd74df8f10f29278dc8d86459Vikram Aggarwal *******************************************************************************/ 174a5c530b0a67e22bd74df8f10f29278dc8d86459Vikram Aggarwal 184a5c530b0a67e22bd74df8f10f29278dc8d86459Vikram Aggarwalpackage com.android.mail.ui; 194a5c530b0a67e22bd74df8f10f29278dc8d86459Vikram Aggarwal 204a5c530b0a67e22bd74df8f10f29278dc8d86459Vikram Aggarwalimport com.google.common.annotations.VisibleForTesting; 214a5c530b0a67e22bd74df8f10f29278dc8d86459Vikram Aggarwalimport com.google.common.collect.Lists; 224a5c530b0a67e22bd74df8f10f29278dc8d86459Vikram Aggarwal 234a5c530b0a67e22bd74df8f10f29278dc8d86459Vikram Aggarwalimport android.os.Parcel; 244a5c530b0a67e22bd74df8f10f29278dc8d86459Vikram Aggarwalimport android.os.Parcelable; 254a5c530b0a67e22bd74df8f10f29278dc8d86459Vikram Aggarwal 26866d319dd23ec8b7b7d5476c65f7f83469d55d2dMindy Pereiraimport com.android.mail.browse.ConversationItemView; 271ddcf0f2bf44d3c9db89112ef52510d9b2433ac4Vikram Aggarwalimport com.android.mail.providers.Conversation; 284a5c530b0a67e22bd74df8f10f29278dc8d86459Vikram Aggarwalimport java.util.ArrayList; 294a5c530b0a67e22bd74df8f10f29278dc8d86459Vikram Aggarwalimport java.util.Collection; 304a5c530b0a67e22bd74df8f10f29278dc8d86459Vikram Aggarwalimport java.util.HashMap; 314a5c530b0a67e22bd74df8f10f29278dc8d86459Vikram Aggarwal 324a5c530b0a67e22bd74df8f10f29278dc8d86459Vikram Aggarwal/** 334a5c530b0a67e22bd74df8f10f29278dc8d86459Vikram Aggarwal * A simple thread-safe wrapper over a set of conversations representing a 344a5c530b0a67e22bd74df8f10f29278dc8d86459Vikram Aggarwal * selection set (e.g. in a conversation list). This class dispatches changes 354a5c530b0a67e22bd74df8f10f29278dc8d86459Vikram Aggarwal * when the set goes empty, and when it becomes unempty. For simplicity, this 364a5c530b0a67e22bd74df8f10f29278dc8d86459Vikram Aggarwal * class <b>does not allow modifications</b> to the collection in observers when 374a5c530b0a67e22bd74df8f10f29278dc8d86459Vikram Aggarwal * responding to change events. 384a5c530b0a67e22bd74df8f10f29278dc8d86459Vikram Aggarwal */ 394a5c530b0a67e22bd74df8f10f29278dc8d86459Vikram Aggarwalpublic class ConversationSelectionSet implements Parcelable { 401ddcf0f2bf44d3c9db89112ef52510d9b2433ac4Vikram Aggarwal public static final Parcelable.Creator<ConversationSelectionSet> CREATOR = 411ddcf0f2bf44d3c9db89112ef52510d9b2433ac4Vikram Aggarwal new Parcelable.Creator<ConversationSelectionSet>() { 421ddcf0f2bf44d3c9db89112ef52510d9b2433ac4Vikram Aggarwal 431ddcf0f2bf44d3c9db89112ef52510d9b2433ac4Vikram Aggarwal @Override 441ddcf0f2bf44d3c9db89112ef52510d9b2433ac4Vikram Aggarwal public ConversationSelectionSet createFromParcel(Parcel source) { 451ddcf0f2bf44d3c9db89112ef52510d9b2433ac4Vikram Aggarwal ConversationSelectionSet result = new ConversationSelectionSet(); 461ddcf0f2bf44d3c9db89112ef52510d9b2433ac4Vikram Aggarwal Parcelable[] conversations = source.readParcelableArray( 471ddcf0f2bf44d3c9db89112ef52510d9b2433ac4Vikram Aggarwal Conversation.class.getClassLoader()); 481ddcf0f2bf44d3c9db89112ef52510d9b2433ac4Vikram Aggarwal for (Parcelable parceled : conversations) { 49866d319dd23ec8b7b7d5476c65f7f83469d55d2dMindy Pereira Conversation conversation = (Conversation) parceled; 50866d319dd23ec8b7b7d5476c65f7f83469d55d2dMindy Pereira result.put(conversation.id, conversation); 511ddcf0f2bf44d3c9db89112ef52510d9b2433ac4Vikram Aggarwal } 521ddcf0f2bf44d3c9db89112ef52510d9b2433ac4Vikram Aggarwal return result; 531ddcf0f2bf44d3c9db89112ef52510d9b2433ac4Vikram Aggarwal } 541ddcf0f2bf44d3c9db89112ef52510d9b2433ac4Vikram Aggarwal 551ddcf0f2bf44d3c9db89112ef52510d9b2433ac4Vikram Aggarwal @Override 561ddcf0f2bf44d3c9db89112ef52510d9b2433ac4Vikram Aggarwal public ConversationSelectionSet[] newArray(int size) { 571ddcf0f2bf44d3c9db89112ef52510d9b2433ac4Vikram Aggarwal return new ConversationSelectionSet[size]; 581ddcf0f2bf44d3c9db89112ef52510d9b2433ac4Vikram Aggarwal } 591ddcf0f2bf44d3c9db89112ef52510d9b2433ac4Vikram Aggarwal }; 601ddcf0f2bf44d3c9db89112ef52510d9b2433ac4Vikram Aggarwal 611ddcf0f2bf44d3c9db89112ef52510d9b2433ac4Vikram Aggarwal private final HashMap<Long, Conversation> mInternalMap = 621ddcf0f2bf44d3c9db89112ef52510d9b2433ac4Vikram Aggarwal new HashMap<Long, Conversation>(); 634a5c530b0a67e22bd74df8f10f29278dc8d86459Vikram Aggarwal 64866d319dd23ec8b7b7d5476c65f7f83469d55d2dMindy Pereira private final HashMap<Long, ConversationItemView> mInternalViewMap = 65866d319dd23ec8b7b7d5476c65f7f83469d55d2dMindy Pereira new HashMap<Long, ConversationItemView>(); 66866d319dd23ec8b7b7d5476c65f7f83469d55d2dMindy Pereira 674a5c530b0a67e22bd74df8f10f29278dc8d86459Vikram Aggarwal @VisibleForTesting 684a5c530b0a67e22bd74df8f10f29278dc8d86459Vikram Aggarwal final ArrayList<ConversationSetObserver> mObservers = new ArrayList<ConversationSetObserver>(); 694a5c530b0a67e22bd74df8f10f29278dc8d86459Vikram Aggarwal 704a5c530b0a67e22bd74df8f10f29278dc8d86459Vikram Aggarwal /** 714a5c530b0a67e22bd74df8f10f29278dc8d86459Vikram Aggarwal * Registers an observer to listen for interesting changes on this set. 724a5c530b0a67e22bd74df8f10f29278dc8d86459Vikram Aggarwal * 734a5c530b0a67e22bd74df8f10f29278dc8d86459Vikram Aggarwal * @param observer the observer to register. 744a5c530b0a67e22bd74df8f10f29278dc8d86459Vikram Aggarwal */ 754a5c530b0a67e22bd74df8f10f29278dc8d86459Vikram Aggarwal public synchronized void addObserver(ConversationSetObserver observer) { 764a5c530b0a67e22bd74df8f10f29278dc8d86459Vikram Aggarwal mObservers.add(observer); 774a5c530b0a67e22bd74df8f10f29278dc8d86459Vikram Aggarwal } 784a5c530b0a67e22bd74df8f10f29278dc8d86459Vikram Aggarwal 79d247dc966bca1ed303039c2893c54979d448a336Vikram Aggarwal /** 80d247dc966bca1ed303039c2893c54979d448a336Vikram Aggarwal * Clear the selected set entirely. 81d247dc966bca1ed303039c2893c54979d448a336Vikram Aggarwal */ 821ddcf0f2bf44d3c9db89112ef52510d9b2433ac4Vikram Aggarwal public synchronized void clear() { 831ddcf0f2bf44d3c9db89112ef52510d9b2433ac4Vikram Aggarwal boolean initiallyNotEmpty = !mInternalMap.isEmpty(); 84866d319dd23ec8b7b7d5476c65f7f83469d55d2dMindy Pereira mInternalViewMap.clear(); 851ddcf0f2bf44d3c9db89112ef52510d9b2433ac4Vikram Aggarwal mInternalMap.clear(); 861ddcf0f2bf44d3c9db89112ef52510d9b2433ac4Vikram Aggarwal 871ddcf0f2bf44d3c9db89112ef52510d9b2433ac4Vikram Aggarwal if (mInternalMap.isEmpty() && initiallyNotEmpty) { 881ddcf0f2bf44d3c9db89112ef52510d9b2433ac4Vikram Aggarwal ArrayList<ConversationSetObserver> observersCopy = Lists.newArrayList(mObservers); 891ddcf0f2bf44d3c9db89112ef52510d9b2433ac4Vikram Aggarwal dispatchOnChange(observersCopy); 901ddcf0f2bf44d3c9db89112ef52510d9b2433ac4Vikram Aggarwal dispatchOnEmpty(observersCopy); 911ddcf0f2bf44d3c9db89112ef52510d9b2433ac4Vikram Aggarwal } 921ddcf0f2bf44d3c9db89112ef52510d9b2433ac4Vikram Aggarwal } 931ddcf0f2bf44d3c9db89112ef52510d9b2433ac4Vikram Aggarwal 94d247dc966bca1ed303039c2893c54979d448a336Vikram Aggarwal /** 95d247dc966bca1ed303039c2893c54979d448a336Vikram Aggarwal * Returns true if the given key exists in the conversation selection set. This assumes 96d247dc966bca1ed303039c2893c54979d448a336Vikram Aggarwal * the internal representation holds conversation.id values. 97d247dc966bca1ed303039c2893c54979d448a336Vikram Aggarwal * @param key the id of the conversation 98d247dc966bca1ed303039c2893c54979d448a336Vikram Aggarwal * @return true if the key exists in this selected set. 99d247dc966bca1ed303039c2893c54979d448a336Vikram Aggarwal */ 100d3818654c103802704fc788cf9c6775d25b65bffMindy Pereira public synchronized boolean containsKey(Long key) { 1011ddcf0f2bf44d3c9db89112ef52510d9b2433ac4Vikram Aggarwal return mInternalMap.containsKey(key); 1021ddcf0f2bf44d3c9db89112ef52510d9b2433ac4Vikram Aggarwal } 1031ddcf0f2bf44d3c9db89112ef52510d9b2433ac4Vikram Aggarwal 104d247dc966bca1ed303039c2893c54979d448a336Vikram Aggarwal /** 105d247dc966bca1ed303039c2893c54979d448a336Vikram Aggarwal * Returns true if the given conversation is stored in the selection set. 106d247dc966bca1ed303039c2893c54979d448a336Vikram Aggarwal * @param conversation 107d247dc966bca1ed303039c2893c54979d448a336Vikram Aggarwal * @return true if the conversation exists in the selected set. 108d247dc966bca1ed303039c2893c54979d448a336Vikram Aggarwal */ 109d247dc966bca1ed303039c2893c54979d448a336Vikram Aggarwal public synchronized boolean contains(Conversation conversation) { 110d247dc966bca1ed303039c2893c54979d448a336Vikram Aggarwal return mInternalMap.containsKey(conversation.id); 111d247dc966bca1ed303039c2893c54979d448a336Vikram Aggarwal } 112d247dc966bca1ed303039c2893c54979d448a336Vikram Aggarwal 1131ddcf0f2bf44d3c9db89112ef52510d9b2433ac4Vikram Aggarwal @Override 1141ddcf0f2bf44d3c9db89112ef52510d9b2433ac4Vikram Aggarwal public int describeContents() { 1151ddcf0f2bf44d3c9db89112ef52510d9b2433ac4Vikram Aggarwal return 0; 1161ddcf0f2bf44d3c9db89112ef52510d9b2433ac4Vikram Aggarwal } 1171ddcf0f2bf44d3c9db89112ef52510d9b2433ac4Vikram Aggarwal 1181ddcf0f2bf44d3c9db89112ef52510d9b2433ac4Vikram Aggarwal private synchronized void dispatchOnBecomeUnempty( 1191ddcf0f2bf44d3c9db89112ef52510d9b2433ac4Vikram Aggarwal ArrayList<ConversationSetObserver> observers) { 1201ddcf0f2bf44d3c9db89112ef52510d9b2433ac4Vikram Aggarwal for (ConversationSetObserver observer : observers) { 1211ddcf0f2bf44d3c9db89112ef52510d9b2433ac4Vikram Aggarwal observer.onSetPopulated(this); 1221ddcf0f2bf44d3c9db89112ef52510d9b2433ac4Vikram Aggarwal } 1234a5c530b0a67e22bd74df8f10f29278dc8d86459Vikram Aggarwal } 1244a5c530b0a67e22bd74df8f10f29278dc8d86459Vikram Aggarwal 1254a5c530b0a67e22bd74df8f10f29278dc8d86459Vikram Aggarwal private synchronized void dispatchOnChange(ArrayList<ConversationSetObserver> observers) { 1264a5c530b0a67e22bd74df8f10f29278dc8d86459Vikram Aggarwal // Copy observers so that they may unregister themselves as listeners on 1274a5c530b0a67e22bd74df8f10f29278dc8d86459Vikram Aggarwal // event handling. 1284a5c530b0a67e22bd74df8f10f29278dc8d86459Vikram Aggarwal for (ConversationSetObserver observer : observers) { 1294a5c530b0a67e22bd74df8f10f29278dc8d86459Vikram Aggarwal observer.onSetChanged(this); 1304a5c530b0a67e22bd74df8f10f29278dc8d86459Vikram Aggarwal } 1314a5c530b0a67e22bd74df8f10f29278dc8d86459Vikram Aggarwal } 1324a5c530b0a67e22bd74df8f10f29278dc8d86459Vikram Aggarwal 1334a5c530b0a67e22bd74df8f10f29278dc8d86459Vikram Aggarwal private synchronized void dispatchOnEmpty(ArrayList<ConversationSetObserver> observers) { 1344a5c530b0a67e22bd74df8f10f29278dc8d86459Vikram Aggarwal for (ConversationSetObserver observer : observers) { 1351ddcf0f2bf44d3c9db89112ef52510d9b2433ac4Vikram Aggarwal observer.onSetEmpty(); 1364a5c530b0a67e22bd74df8f10f29278dc8d86459Vikram Aggarwal } 1374a5c530b0a67e22bd74df8f10f29278dc8d86459Vikram Aggarwal } 1384a5c530b0a67e22bd74df8f10f29278dc8d86459Vikram Aggarwal 1391ddcf0f2bf44d3c9db89112ef52510d9b2433ac4Vikram Aggarwal /** 1401ddcf0f2bf44d3c9db89112ef52510d9b2433ac4Vikram Aggarwal * Is this conversation set empty? 1411ddcf0f2bf44d3c9db89112ef52510d9b2433ac4Vikram Aggarwal * @return true if the conversation selection set is empty. False otherwise. 1421ddcf0f2bf44d3c9db89112ef52510d9b2433ac4Vikram Aggarwal */ 1431ddcf0f2bf44d3c9db89112ef52510d9b2433ac4Vikram Aggarwal public synchronized boolean isEmpty() { 1441ddcf0f2bf44d3c9db89112ef52510d9b2433ac4Vikram Aggarwal return mInternalMap.isEmpty(); 1451ddcf0f2bf44d3c9db89112ef52510d9b2433ac4Vikram Aggarwal } 1461ddcf0f2bf44d3c9db89112ef52510d9b2433ac4Vikram Aggarwal 1471ddcf0f2bf44d3c9db89112ef52510d9b2433ac4Vikram Aggarwal private synchronized void put(Long id, Conversation info) { 1484556a44bef944b90e140d2ba67cc723e0ad5da3aAndy Huang final boolean initiallyEmpty = mInternalMap.isEmpty(); 1494a5c530b0a67e22bd74df8f10f29278dc8d86459Vikram Aggarwal mInternalMap.put(id, info); 150866d319dd23ec8b7b7d5476c65f7f83469d55d2dMindy Pereira // Fill out the view map with null. The sizes will match, but 151866d319dd23ec8b7b7d5476c65f7f83469d55d2dMindy Pereira // we won't have any views available yet to store. 152866d319dd23ec8b7b7d5476c65f7f83469d55d2dMindy Pereira mInternalViewMap.put(id, null); 153866d319dd23ec8b7b7d5476c65f7f83469d55d2dMindy Pereira 154866d319dd23ec8b7b7d5476c65f7f83469d55d2dMindy Pereira ArrayList<ConversationSetObserver> observersCopy = Lists.newArrayList(mObservers); 155866d319dd23ec8b7b7d5476c65f7f83469d55d2dMindy Pereira dispatchOnChange(observersCopy); 156866d319dd23ec8b7b7d5476c65f7f83469d55d2dMindy Pereira if (initiallyEmpty) { 157866d319dd23ec8b7b7d5476c65f7f83469d55d2dMindy Pereira dispatchOnBecomeUnempty(observersCopy); 158866d319dd23ec8b7b7d5476c65f7f83469d55d2dMindy Pereira } 159866d319dd23ec8b7b7d5476c65f7f83469d55d2dMindy Pereira } 160866d319dd23ec8b7b7d5476c65f7f83469d55d2dMindy Pereira 161866d319dd23ec8b7b7d5476c65f7f83469d55d2dMindy Pereira /** @see java.util.HashMap#put */ 162866d319dd23ec8b7b7d5476c65f7f83469d55d2dMindy Pereira private synchronized void put(Long id, ConversationItemView info) { 163866d319dd23ec8b7b7d5476c65f7f83469d55d2dMindy Pereira boolean initiallyEmpty = mInternalMap.isEmpty(); 164866d319dd23ec8b7b7d5476c65f7f83469d55d2dMindy Pereira mInternalViewMap.put(id, info); 165866d319dd23ec8b7b7d5476c65f7f83469d55d2dMindy Pereira mInternalMap.put(id, info.mHeader.conversation); 1664a5c530b0a67e22bd74df8f10f29278dc8d86459Vikram Aggarwal 1674a5c530b0a67e22bd74df8f10f29278dc8d86459Vikram Aggarwal ArrayList<ConversationSetObserver> observersCopy = Lists.newArrayList(mObservers); 1684a5c530b0a67e22bd74df8f10f29278dc8d86459Vikram Aggarwal dispatchOnChange(observersCopy); 1694a5c530b0a67e22bd74df8f10f29278dc8d86459Vikram Aggarwal if (initiallyEmpty) { 1704a5c530b0a67e22bd74df8f10f29278dc8d86459Vikram Aggarwal dispatchOnBecomeUnempty(observersCopy); 1714a5c530b0a67e22bd74df8f10f29278dc8d86459Vikram Aggarwal } 1724a5c530b0a67e22bd74df8f10f29278dc8d86459Vikram Aggarwal } 1734a5c530b0a67e22bd74df8f10f29278dc8d86459Vikram Aggarwal 1744a5c530b0a67e22bd74df8f10f29278dc8d86459Vikram Aggarwal /** @see java.util.HashMap#remove */ 1754a5c530b0a67e22bd74df8f10f29278dc8d86459Vikram Aggarwal private synchronized void remove(Long id) { 1764556a44bef944b90e140d2ba67cc723e0ad5da3aAndy Huang final boolean initiallyNotEmpty = !mInternalMap.isEmpty(); 177866d319dd23ec8b7b7d5476c65f7f83469d55d2dMindy Pereira 178866d319dd23ec8b7b7d5476c65f7f83469d55d2dMindy Pereira mInternalViewMap.remove(id); 1794a5c530b0a67e22bd74df8f10f29278dc8d86459Vikram Aggarwal mInternalMap.remove(id); 1804a5c530b0a67e22bd74df8f10f29278dc8d86459Vikram Aggarwal 1814a5c530b0a67e22bd74df8f10f29278dc8d86459Vikram Aggarwal ArrayList<ConversationSetObserver> observersCopy = Lists.newArrayList(mObservers); 1824a5c530b0a67e22bd74df8f10f29278dc8d86459Vikram Aggarwal dispatchOnChange(observersCopy); 1834a5c530b0a67e22bd74df8f10f29278dc8d86459Vikram Aggarwal if (mInternalMap.isEmpty() && initiallyNotEmpty) { 1844a5c530b0a67e22bd74df8f10f29278dc8d86459Vikram Aggarwal dispatchOnEmpty(observersCopy); 1854a5c530b0a67e22bd74df8f10f29278dc8d86459Vikram Aggarwal } 1864a5c530b0a67e22bd74df8f10f29278dc8d86459Vikram Aggarwal } 1874a5c530b0a67e22bd74df8f10f29278dc8d86459Vikram Aggarwal 1881ddcf0f2bf44d3c9db89112ef52510d9b2433ac4Vikram Aggarwal /** 1891ddcf0f2bf44d3c9db89112ef52510d9b2433ac4Vikram Aggarwal * Unregisters an observer for change events. 1901ddcf0f2bf44d3c9db89112ef52510d9b2433ac4Vikram Aggarwal * 1911ddcf0f2bf44d3c9db89112ef52510d9b2433ac4Vikram Aggarwal * @param observer the observer to unregister. 1921ddcf0f2bf44d3c9db89112ef52510d9b2433ac4Vikram Aggarwal */ 1931ddcf0f2bf44d3c9db89112ef52510d9b2433ac4Vikram Aggarwal public synchronized void removeObserver(ConversationSetObserver observer) { 1941ddcf0f2bf44d3c9db89112ef52510d9b2433ac4Vikram Aggarwal mObservers.remove(observer); 1954a5c530b0a67e22bd74df8f10f29278dc8d86459Vikram Aggarwal } 1964a5c530b0a67e22bd74df8f10f29278dc8d86459Vikram Aggarwal 197d247dc966bca1ed303039c2893c54979d448a336Vikram Aggarwal /** 198d247dc966bca1ed303039c2893c54979d448a336Vikram Aggarwal * Returns the number of conversations that are currently selected 199d247dc966bca1ed303039c2893c54979d448a336Vikram Aggarwal * @return the number of selected conversations. 200d247dc966bca1ed303039c2893c54979d448a336Vikram Aggarwal */ 2011ddcf0f2bf44d3c9db89112ef52510d9b2433ac4Vikram Aggarwal public synchronized int size() { 2021ddcf0f2bf44d3c9db89112ef52510d9b2433ac4Vikram Aggarwal return mInternalMap.size(); 2034a5c530b0a67e22bd74df8f10f29278dc8d86459Vikram Aggarwal } 2044a5c530b0a67e22bd74df8f10f29278dc8d86459Vikram Aggarwal 2054a5c530b0a67e22bd74df8f10f29278dc8d86459Vikram Aggarwal /** 206d247dc966bca1ed303039c2893c54979d448a336Vikram Aggarwal * Toggles the existence of the given conversation in the selection set. If the conversation is 207d247dc966bca1ed303039c2893c54979d448a336Vikram Aggarwal * currently selected, it is deselected. If it doesn't exist in the selection set, then it is 208d247dc966bca1ed303039c2893c54979d448a336Vikram Aggarwal * selected. 2091ddcf0f2bf44d3c9db89112ef52510d9b2433ac4Vikram Aggarwal * @param conversation 2104a5c530b0a67e22bd74df8f10f29278dc8d86459Vikram Aggarwal */ 211866d319dd23ec8b7b7d5476c65f7f83469d55d2dMindy Pereira public void toggle(ConversationItemView view, Conversation conversation) { 2121ddcf0f2bf44d3c9db89112ef52510d9b2433ac4Vikram Aggarwal long conversationId = conversation.id; 2131ddcf0f2bf44d3c9db89112ef52510d9b2433ac4Vikram Aggarwal if (containsKey(conversationId)) { 2141ddcf0f2bf44d3c9db89112ef52510d9b2433ac4Vikram Aggarwal remove(conversationId); 2154a5c530b0a67e22bd74df8f10f29278dc8d86459Vikram Aggarwal } else { 216866d319dd23ec8b7b7d5476c65f7f83469d55d2dMindy Pereira put(conversationId, view); 2174a5c530b0a67e22bd74df8f10f29278dc8d86459Vikram Aggarwal } 2184a5c530b0a67e22bd74df8f10f29278dc8d86459Vikram Aggarwal } 2194a5c530b0a67e22bd74df8f10f29278dc8d86459Vikram Aggarwal 2201ddcf0f2bf44d3c9db89112ef52510d9b2433ac4Vikram Aggarwal /** @see java.util.HashMap#values */ 2211ddcf0f2bf44d3c9db89112ef52510d9b2433ac4Vikram Aggarwal public synchronized Collection<Conversation> values() { 2221ddcf0f2bf44d3c9db89112ef52510d9b2433ac4Vikram Aggarwal return mInternalMap.values(); 2234a5c530b0a67e22bd74df8f10f29278dc8d86459Vikram Aggarwal } 2244a5c530b0a67e22bd74df8f10f29278dc8d86459Vikram Aggarwal 2254556a44bef944b90e140d2ba67cc723e0ad5da3aAndy Huang /** @see java.util.HashMap#putAll(java.util.Map) */ 2264556a44bef944b90e140d2ba67cc723e0ad5da3aAndy Huang public void putAll(ConversationSelectionSet other) { 2274556a44bef944b90e140d2ba67cc723e0ad5da3aAndy Huang if (other == null) { 2284556a44bef944b90e140d2ba67cc723e0ad5da3aAndy Huang return; 2294556a44bef944b90e140d2ba67cc723e0ad5da3aAndy Huang } 2304556a44bef944b90e140d2ba67cc723e0ad5da3aAndy Huang 2314556a44bef944b90e140d2ba67cc723e0ad5da3aAndy Huang final boolean initiallyEmpty = mInternalMap.isEmpty(); 2324556a44bef944b90e140d2ba67cc723e0ad5da3aAndy Huang mInternalMap.putAll(other.mInternalMap); 2334556a44bef944b90e140d2ba67cc723e0ad5da3aAndy Huang 2344556a44bef944b90e140d2ba67cc723e0ad5da3aAndy Huang ArrayList<ConversationSetObserver> observersCopy = Lists.newArrayList(mObservers); 2354556a44bef944b90e140d2ba67cc723e0ad5da3aAndy Huang dispatchOnChange(observersCopy); 2364556a44bef944b90e140d2ba67cc723e0ad5da3aAndy Huang if (initiallyEmpty) { 2374556a44bef944b90e140d2ba67cc723e0ad5da3aAndy Huang dispatchOnBecomeUnempty(observersCopy); 2384556a44bef944b90e140d2ba67cc723e0ad5da3aAndy Huang } 2394556a44bef944b90e140d2ba67cc723e0ad5da3aAndy Huang } 2404556a44bef944b90e140d2ba67cc723e0ad5da3aAndy Huang 2414a5c530b0a67e22bd74df8f10f29278dc8d86459Vikram Aggarwal @Override 2424a5c530b0a67e22bd74df8f10f29278dc8d86459Vikram Aggarwal public void writeToParcel(Parcel dest, int flags) { 2431ddcf0f2bf44d3c9db89112ef52510d9b2433ac4Vikram Aggarwal Conversation[] values = values().toArray(new Conversation[size()]); 2444a5c530b0a67e22bd74df8f10f29278dc8d86459Vikram Aggarwal dest.writeParcelableArray(values, flags); 2454a5c530b0a67e22bd74df8f10f29278dc8d86459Vikram Aggarwal } 246866d319dd23ec8b7b7d5476c65f7f83469d55d2dMindy Pereira 247866d319dd23ec8b7b7d5476c65f7f83469d55d2dMindy Pereira public Collection<ConversationItemView> views() { 248866d319dd23ec8b7b7d5476c65f7f83469d55d2dMindy Pereira return mInternalViewMap.values(); 249866d319dd23ec8b7b7d5476c65f7f83469d55d2dMindy Pereira } 2504a5c530b0a67e22bd74df8f10f29278dc8d86459Vikram Aggarwal} 251