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.support.v4.util.SimpleArrayMap;
21 
22 import com.android.messaging.util.Assert;
23 
24 import com.google.common.annotations.VisibleForTesting;
25 
26 import java.util.ArrayList;
27 import java.util.Iterator;
28 import java.util.NoSuchElementException;
29 
30 /**
31  * A class that contains the list of all participants potentially involved in a conversation.
32  * Includes both the participant records for each participant referenced in conversation
33  * participants table (i.e. "other" phone numbers) plus all participants representing self
34  * (i.e. one per sim recorded in the subscription manager db).
35  */
36 public class ConversationParticipantsData implements Iterable<ParticipantData> {
37     // A map from a participant id to a participant
38     private final SimpleArrayMap<String, ParticipantData> mConversationParticipantsMap;
39     private int mParticipantCountExcludingSelf = 0;
40 
ConversationParticipantsData()41     public ConversationParticipantsData() {
42         mConversationParticipantsMap = new SimpleArrayMap<String, ParticipantData>();
43     }
44 
bind(final Cursor cursor)45     public void bind(final Cursor cursor) {
46         mConversationParticipantsMap.clear();
47         mParticipantCountExcludingSelf = 0;
48         if (cursor != null) {
49             while (cursor.moveToNext()) {
50                 final ParticipantData newParticipant = ParticipantData.getFromCursor(cursor);
51                 if (!newParticipant.isSelf()) {
52                     mParticipantCountExcludingSelf++;
53                 }
54                 mConversationParticipantsMap.put(newParticipant.getId(), newParticipant);
55             }
56         }
57     }
58 
59     @VisibleForTesting
getParticipantById(final String participantId)60     ParticipantData getParticipantById(final String participantId) {
61         return mConversationParticipantsMap.get(participantId);
62     }
63 
getParticipantListExcludingSelf()64     ArrayList<ParticipantData> getParticipantListExcludingSelf() {
65         final ArrayList<ParticipantData> retList =
66                 new ArrayList<ParticipantData>(mConversationParticipantsMap.size());
67         for (int i = 0; i < mConversationParticipantsMap.size(); i++) {
68             final ParticipantData participant = mConversationParticipantsMap.valueAt(i);
69             if (!participant.isSelf()) {
70                 retList.add(participant);
71             }
72         }
73         return retList;
74     }
75 
76     /**
77      * For a 1:1 conversation return the other (not self) participant
78      */
getOtherParticipant()79     public ParticipantData getOtherParticipant() {
80         if (mParticipantCountExcludingSelf == 1) {
81             for (int i = 0; i < mConversationParticipantsMap.size(); i++) {
82                 final ParticipantData participant = mConversationParticipantsMap.valueAt(i);
83                 if (!participant.isSelf()) {
84                     return participant;
85                 }
86             }
87             Assert.fail("Could not find other participant");
88         }
89         return null;
90     }
91 
getNumberOfParticipantsExcludingSelf()92     public int getNumberOfParticipantsExcludingSelf() {
93         return mParticipantCountExcludingSelf;
94     }
95 
isLoaded()96     public boolean isLoaded() {
97         return !mConversationParticipantsMap.isEmpty();
98     }
99 
100     @Override
iterator()101     public Iterator<ParticipantData> iterator() {
102         return new Iterator<ParticipantData>() {
103             private int mCurrentIndex = -1;
104 
105             @Override
106             public boolean hasNext() {
107                 return mCurrentIndex < mConversationParticipantsMap.size() - 1;
108             }
109 
110             @Override
111             public ParticipantData next() {
112                 mCurrentIndex++;
113                 if (mCurrentIndex >= mConversationParticipantsMap.size()) {
114                     throw new NoSuchElementException();
115                 }
116                 return mConversationParticipantsMap.valueAt(mCurrentIndex);
117             }
118 
119             @Override
120             public void remove() {
121                 throw new UnsupportedOperationException();
122             }
123         };
124     }
125 }
126