1 /* 2 * Copyright (C) 2019 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 android.telephony.ims.cts; 18 19 import static android.provider.Telephony.RcsColumns.IS_RCS_TABLE_SCHEMA_CODE_COMPLETE; 20 21 import static com.google.common.truth.Truth.assertWithMessage; 22 23 import android.content.Context; 24 import android.net.Uri; 25 import android.telephony.ims.RcsEvent; 26 import android.telephony.ims.RcsEventQueryParams; 27 import android.telephony.ims.RcsEventQueryResult; 28 import android.telephony.ims.RcsGroupThread; 29 import android.telephony.ims.RcsGroupThreadEvent; 30 import android.telephony.ims.RcsGroupThreadIconChangedEvent; 31 import android.telephony.ims.RcsGroupThreadNameChangedEvent; 32 import android.telephony.ims.RcsGroupThreadParticipantJoinedEvent; 33 import android.telephony.ims.RcsGroupThreadParticipantLeftEvent; 34 import android.telephony.ims.RcsManager; 35 import android.telephony.ims.RcsMessageStore; 36 import android.telephony.ims.RcsMessageStoreException; 37 import android.telephony.ims.RcsParticipant; 38 import android.telephony.ims.RcsParticipantAliasChangedEvent; 39 40 import androidx.test.InstrumentationRegistry; 41 42 import com.google.android.collect.Lists; 43 44 import org.junit.AfterClass; 45 import org.junit.Assume; 46 import org.junit.Before; 47 import org.junit.BeforeClass; 48 import org.junit.Test; 49 50 import java.util.function.Predicate; 51 52 public class RcsEventTest { 53 private RcsMessageStore mRcsMessageStore; 54 55 private long mTimestamp; 56 private RcsParticipant mParticipant1; 57 private RcsParticipant mParticipant2; 58 private RcsGroupThread mGroupThread; 59 60 @BeforeClass ensureDefaultSmsApp()61 public static void ensureDefaultSmsApp() { 62 DefaultSmsAppHelper.ensureDefaultSmsApp(); 63 } 64 65 66 @Before setupTestEnvironment()67 public void setupTestEnvironment() throws RcsMessageStoreException { 68 // Used to skip tests for production builds without RCS tables, will be removed when 69 // IS_RCS_TABLE_SCHEMA_CODE_COMPLETE flag is removed. 70 Assume.assumeTrue(IS_RCS_TABLE_SCHEMA_CODE_COMPLETE); 71 72 Context context = InstrumentationRegistry.getTargetContext(); 73 RcsManager rcsManager = context.getSystemService(RcsManager.class); 74 mRcsMessageStore = rcsManager.getRcsMessageStore(); 75 76 cleanup(); 77 78 mTimestamp = 1234567890; 79 mParticipant1 = mRcsMessageStore.createRcsParticipant("403", "p1"); 80 mParticipant2 = mRcsMessageStore.createRcsParticipant("404", "p2"); 81 mGroupThread = mRcsMessageStore.createGroupThread( 82 Lists.newArrayList(mParticipant1, mParticipant2), "groupName", Uri.EMPTY); 83 84 } 85 86 @AfterClass cleanup()87 public static void cleanup() { 88 // TODO(b/123997749) should clean RCS message store here 89 } 90 91 @Test testCreateRcsEvent_canSaveAndQueryGroupThreadParticipantJoinedEvent()92 public void testCreateRcsEvent_canSaveAndQueryGroupThreadParticipantJoinedEvent() 93 throws RcsMessageStoreException { 94 RcsGroupThreadParticipantJoinedEvent rcsGroupThreadParticipantJoinedEvent = 95 new RcsGroupThreadParticipantJoinedEvent( 96 mTimestamp, mGroupThread, mParticipant1, mParticipant2); 97 98 mRcsMessageStore.persistRcsEvent(rcsGroupThreadParticipantJoinedEvent); 99 100 assertMatchingEventInQuery( 101 RcsEventQueryParams.GROUP_THREAD_PARTICIPANT_JOINED_EVENT, 102 event -> matches(rcsGroupThreadParticipantJoinedEvent, event)); 103 } 104 105 @Test testCreateRcsEvent_canSaveAndQueryGroupThreadNameChangedEvent()106 public void testCreateRcsEvent_canSaveAndQueryGroupThreadNameChangedEvent() 107 throws RcsMessageStoreException { 108 RcsGroupThreadNameChangedEvent rcsGroupThreadNameChangedEvent = 109 new RcsGroupThreadNameChangedEvent( 110 mTimestamp, mGroupThread, mParticipant1, "newName"); 111 112 mRcsMessageStore.persistRcsEvent(rcsGroupThreadNameChangedEvent); 113 114 assertMatchingEventInQuery( 115 RcsEventQueryParams.GROUP_THREAD_NAME_CHANGED_EVENT, 116 event -> matches(rcsGroupThreadNameChangedEvent, event)); 117 } 118 119 @Test testCreateRcsEvent_canSaveAndQueryParticipantAliasChangedEvent()120 public void testCreateRcsEvent_canSaveAndQueryParticipantAliasChangedEvent() 121 throws RcsMessageStoreException { 122 RcsParticipantAliasChangedEvent rcsParticipantAliasChangedEvent 123 = new RcsParticipantAliasChangedEvent(mTimestamp, mParticipant1, "newAlias"); 124 125 mRcsMessageStore.persistRcsEvent(rcsParticipantAliasChangedEvent); 126 127 assertMatchingEventInQuery( 128 RcsEventQueryParams.PARTICIPANT_ALIAS_CHANGED_EVENT, 129 event -> matches(rcsParticipantAliasChangedEvent, event)); 130 } 131 132 @Test testCreateRcsEvent_canSaveAndQueryGroupThreadParticipantLeftEvent()133 public void testCreateRcsEvent_canSaveAndQueryGroupThreadParticipantLeftEvent() 134 throws RcsMessageStoreException { 135 RcsGroupThreadParticipantLeftEvent rcsGroupThreadParticipantLeftEvent = 136 new RcsGroupThreadParticipantLeftEvent( 137 mTimestamp, mGroupThread, mParticipant1, mParticipant2); 138 139 mRcsMessageStore.persistRcsEvent(rcsGroupThreadParticipantLeftEvent); 140 141 assertMatchingEventInQuery( 142 RcsEventQueryParams.GROUP_THREAD_PARTICIPANT_LEFT_EVENT, 143 event -> matches(rcsGroupThreadParticipantLeftEvent, event)); 144 } 145 146 @Test testCreateRcsEvent_canSaveAndQueryGroupThreadIconChangedEvent()147 public void testCreateRcsEvent_canSaveAndQueryGroupThreadIconChangedEvent() 148 throws RcsMessageStoreException { 149 Uri newIcon = Uri.parse("cool/new/icon"); 150 151 RcsGroupThreadIconChangedEvent rcsGroupThreadIconChangedEvent = 152 new RcsGroupThreadIconChangedEvent( 153 mTimestamp, mGroupThread, mParticipant1, newIcon); 154 155 mRcsMessageStore.persistRcsEvent(rcsGroupThreadIconChangedEvent); 156 157 assertMatchingEventInQuery( 158 RcsEventQueryParams.GROUP_THREAD_ICON_CHANGED_EVENT, 159 event -> matches(rcsGroupThreadIconChangedEvent, event)); 160 } 161 assertMatchingEventInQuery(int queryMessageType, Predicate<RcsEvent> predicate)162 private void assertMatchingEventInQuery(int queryMessageType, Predicate<RcsEvent> predicate) 163 throws RcsMessageStoreException { 164 RcsEventQueryResult queryResult = mRcsMessageStore.getRcsEvents( 165 new RcsEventQueryParams.Builder() 166 .setEventType(queryMessageType) 167 .build()); 168 169 boolean foundMatch = queryResult.getEvents().stream().anyMatch(predicate); 170 171 assertWithMessage(queryResult.getEvents().toString()).that(foundMatch).isTrue(); 172 } 173 matches(RcsGroupThreadParticipantJoinedEvent expected, RcsEvent actual)174 private boolean matches(RcsGroupThreadParticipantJoinedEvent expected, RcsEvent actual) { 175 if (!(actual instanceof RcsGroupThreadParticipantJoinedEvent)) { 176 return false; 177 } 178 RcsGroupThreadParticipantJoinedEvent actualParticipantJoinedEvent = 179 (RcsGroupThreadParticipantJoinedEvent) actual; 180 181 return matchesGroupThreadEvent(expected, actualParticipantJoinedEvent) 182 && actualParticipantJoinedEvent.getJoinedParticipant().getId() 183 == expected.getJoinedParticipant().getId(); 184 } 185 186 matches(RcsGroupThreadNameChangedEvent expected, RcsEvent actual)187 private boolean matches(RcsGroupThreadNameChangedEvent expected, RcsEvent actual) { 188 if (!(actual instanceof RcsGroupThreadNameChangedEvent)) { 189 return false; 190 } 191 RcsGroupThreadNameChangedEvent actualGroupThreadNameChangedEvent = 192 (RcsGroupThreadNameChangedEvent) actual; 193 194 return matchesGroupThreadEvent(expected, actualGroupThreadNameChangedEvent) 195 && actualGroupThreadNameChangedEvent.getNewName().equals(expected.getNewName()); 196 } 197 matches(RcsGroupThreadParticipantLeftEvent expected, RcsEvent actual)198 private boolean matches(RcsGroupThreadParticipantLeftEvent expected, RcsEvent actual) { 199 if (!(actual instanceof RcsGroupThreadParticipantLeftEvent)) { 200 return false; 201 } 202 RcsGroupThreadParticipantLeftEvent actualParticipantLeftEvent = 203 (RcsGroupThreadParticipantLeftEvent) actual; 204 205 return matchesGroupThreadEvent(expected, actualParticipantLeftEvent) 206 && actualParticipantLeftEvent.getLeavingParticipant().getId() 207 == expected.getLeavingParticipant().getId(); 208 } 209 210 matches(RcsGroupThreadIconChangedEvent expected, RcsEvent actual)211 private boolean matches(RcsGroupThreadIconChangedEvent expected, RcsEvent actual) { 212 if (!(actual instanceof RcsGroupThreadIconChangedEvent)) { 213 return false; 214 } 215 RcsGroupThreadIconChangedEvent actualIconChangedEvent = 216 (RcsGroupThreadIconChangedEvent) actual; 217 218 return matchesGroupThreadEvent(expected, actualIconChangedEvent) 219 && actualIconChangedEvent.getNewIcon().equals(expected.getNewIcon()); 220 } 221 matchesGroupThreadEvent( RcsGroupThreadEvent expected, RcsGroupThreadEvent actual)222 private boolean matchesGroupThreadEvent( 223 RcsGroupThreadEvent expected, RcsGroupThreadEvent actual) { 224 return matchesRcsEventFields(expected, actual) 225 && actual.getOriginatingParticipant().getId() 226 == expected.getOriginatingParticipant().getId() 227 && actual.getRcsGroupThread().getThreadId() 228 == expected.getRcsGroupThread().getThreadId(); 229 } 230 matches(RcsParticipantAliasChangedEvent expected, RcsEvent actual)231 private boolean matches(RcsParticipantAliasChangedEvent expected, RcsEvent actual) { 232 if (!(actual instanceof RcsParticipantAliasChangedEvent)) { 233 return false; 234 } 235 RcsParticipantAliasChangedEvent actualIconChangedEvent = 236 (RcsParticipantAliasChangedEvent) actual; 237 238 return matchesRcsEventFields(expected, actual) 239 && actualIconChangedEvent.getParticipant().getId() 240 == expected.getParticipant().getId() 241 && actualIconChangedEvent.getNewAlias().equals(expected.getNewAlias()); 242 } 243 matchesRcsEventFields(RcsEvent expected, RcsEvent actual)244 private boolean matchesRcsEventFields(RcsEvent expected, RcsEvent actual) { 245 return actual.getTimestamp() == expected.getTimestamp(); 246 } 247 } 248