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 com.android.internal.telephony.ims; 18 19 import static android.provider.Telephony.RcsColumns.Rcs1To1ThreadColumns.FALLBACK_THREAD_ID_COLUMN; 20 import static android.provider.Telephony.RcsColumns.Rcs1To1ThreadColumns.RCS_1_TO_1_THREAD_URI; 21 import static android.provider.Telephony.RcsColumns.RcsEventTypes.ICON_CHANGED_EVENT_TYPE; 22 import static android.provider.Telephony.RcsColumns.RcsEventTypes.NAME_CHANGED_EVENT_TYPE; 23 import static android.provider.Telephony.RcsColumns.RcsEventTypes.PARTICIPANT_JOINED_EVENT_TYPE; 24 import static android.provider.Telephony.RcsColumns.RcsEventTypes.PARTICIPANT_LEFT_EVENT_TYPE; 25 import static android.provider.Telephony.RcsColumns.RcsFileTransferColumns.CONTENT_TYPE_COLUMN; 26 import static android.provider.Telephony.RcsColumns.RcsFileTransferColumns.CONTENT_URI_COLUMN; 27 import static android.provider.Telephony.RcsColumns.RcsFileTransferColumns.DURATION_MILLIS_COLUMN; 28 import static android.provider.Telephony.RcsColumns.RcsFileTransferColumns.FILE_SIZE_COLUMN; 29 import static android.provider.Telephony.RcsColumns.RcsFileTransferColumns.FILE_TRANSFER_ID_COLUMN; 30 import static android.provider.Telephony.RcsColumns.RcsFileTransferColumns.FILE_TRANSFER_URI; 31 import static android.provider.Telephony.RcsColumns.RcsFileTransferColumns.HEIGHT_COLUMN; 32 import static android.provider.Telephony.RcsColumns.RcsFileTransferColumns.PREVIEW_TYPE_COLUMN; 33 import static android.provider.Telephony.RcsColumns.RcsFileTransferColumns.PREVIEW_URI_COLUMN; 34 import static android.provider.Telephony.RcsColumns.RcsFileTransferColumns.SESSION_ID_COLUMN; 35 import static android.provider.Telephony.RcsColumns.RcsFileTransferColumns.SUCCESSFULLY_TRANSFERRED_BYTES; 36 import static android.provider.Telephony.RcsColumns.RcsFileTransferColumns.TRANSFER_STATUS_COLUMN; 37 import static android.provider.Telephony.RcsColumns.RcsFileTransferColumns.WIDTH_COLUMN; 38 import static android.provider.Telephony.RcsColumns.RcsGroupThreadColumns.CONFERENCE_URI_COLUMN; 39 import static android.provider.Telephony.RcsColumns.RcsGroupThreadColumns.GROUP_ICON_COLUMN; 40 import static android.provider.Telephony.RcsColumns.RcsGroupThreadColumns.GROUP_NAME_COLUMN; 41 import static android.provider.Telephony.RcsColumns.RcsGroupThreadColumns.OWNER_PARTICIPANT_COLUMN; 42 import static android.provider.Telephony.RcsColumns.RcsGroupThreadColumns.RCS_GROUP_THREAD_URI; 43 import static android.provider.Telephony.RcsColumns.RcsIncomingMessageColumns.ARRIVAL_TIMESTAMP_COLUMN; 44 import static android.provider.Telephony.RcsColumns.RcsIncomingMessageColumns.INCOMING_MESSAGE_URI; 45 import static android.provider.Telephony.RcsColumns.RcsIncomingMessageColumns.SEEN_TIMESTAMP_COLUMN; 46 import static android.provider.Telephony.RcsColumns.RcsIncomingMessageColumns.SENDER_PARTICIPANT_ID_COLUMN; 47 import static android.provider.Telephony.RcsColumns.RcsMessageColumns.GLOBAL_ID_COLUMN; 48 import static android.provider.Telephony.RcsColumns.RcsMessageColumns.LATITUDE_COLUMN; 49 import static android.provider.Telephony.RcsColumns.RcsMessageColumns.LONGITUDE_COLUMN; 50 import static android.provider.Telephony.RcsColumns.RcsMessageColumns.MESSAGE_ID_COLUMN; 51 import static android.provider.Telephony.RcsColumns.RcsMessageColumns.MESSAGE_TEXT_COLUMN; 52 import static android.provider.Telephony.RcsColumns.RcsMessageColumns.ORIGINATION_TIMESTAMP_COLUMN; 53 import static android.provider.Telephony.RcsColumns.RcsMessageColumns.STATUS_COLUMN; 54 import static android.provider.Telephony.RcsColumns.RcsMessageColumns.SUB_ID_COLUMN; 55 import static android.provider.Telephony.RcsColumns.RcsMessageDeliveryColumns.DELIVERED_TIMESTAMP_COLUMN; 56 import static android.provider.Telephony.RcsColumns.RcsParticipantColumns.CANONICAL_ADDRESS_ID_COLUMN; 57 import static android.provider.Telephony.RcsColumns.RcsParticipantColumns.RCS_ALIAS_COLUMN; 58 import static android.provider.Telephony.RcsColumns.RcsParticipantColumns.RCS_PARTICIPANT_ID_COLUMN; 59 import static android.provider.Telephony.RcsColumns.RcsParticipantColumns.RCS_PARTICIPANT_URI; 60 import static android.provider.Telephony.RcsColumns.RcsParticipantEventColumns.NEW_ALIAS_COLUMN; 61 import static android.provider.Telephony.RcsColumns.RcsThreadColumns.RCS_THREAD_ID_COLUMN; 62 import static android.provider.Telephony.RcsColumns.RcsThreadEventColumns.DESTINATION_PARTICIPANT_ID_COLUMN; 63 import static android.provider.Telephony.RcsColumns.RcsThreadEventColumns.NEW_ICON_URI_COLUMN; 64 import static android.provider.Telephony.RcsColumns.RcsThreadEventColumns.NEW_NAME_COLUMN; 65 import static android.provider.Telephony.RcsColumns.RcsThreadEventColumns.SOURCE_PARTICIPANT_ID_COLUMN; 66 import static android.provider.Telephony.RcsColumns.RcsThreadEventColumns.TIMESTAMP_COLUMN; 67 import static android.provider.Telephony.RcsColumns.RcsUnifiedThreadColumns.THREAD_TYPE_GROUP; 68 import static android.provider.Telephony.RcsColumns.TRANSACTION_FAILED; 69 import static android.telephony.ims.RcsEventQueryParams.EVENT_QUERY_PARAMETERS_KEY; 70 import static android.telephony.ims.RcsMessageQueryParams.MESSAGE_QUERY_PARAMETERS_KEY; 71 import static android.telephony.ims.RcsParticipantQueryParams.PARTICIPANT_QUERY_PARAMETERS_KEY; 72 import static android.telephony.ims.RcsQueryContinuationToken.QUERY_CONTINUATION_TOKEN; 73 import static android.telephony.ims.RcsThreadQueryParams.THREAD_QUERY_PARAMETERS_KEY; 74 75 import static com.android.internal.telephony.ims.RcsMessageStoreUtil.getMessageTableUri; 76 import static com.android.internal.telephony.ims.RcsParticipantQueryHelper.getUriForParticipant; 77 import static com.android.internal.telephony.ims.RcsThreadQueryHelper.get1To1ThreadUri; 78 import static com.android.internal.telephony.ims.RcsThreadQueryHelper.getAllParticipantsInThreadUri; 79 import static com.android.internal.telephony.ims.RcsThreadQueryHelper.getGroupThreadUri; 80 import static com.android.internal.telephony.ims.RcsThreadQueryHelper.getParticipantInThreadUri; 81 82 import android.content.ContentResolver; 83 import android.content.ContentValues; 84 import android.content.Context; 85 import android.database.Cursor; 86 import android.net.Uri; 87 import android.os.Bundle; 88 import android.os.RemoteException; 89 import android.os.ServiceManager; 90 import android.provider.Telephony; 91 import android.telephony.Rlog; 92 import android.telephony.ims.RcsEventQueryParams; 93 import android.telephony.ims.RcsEventQueryResultDescriptor; 94 import android.telephony.ims.RcsFileTransferCreationParams; 95 import android.telephony.ims.RcsIncomingMessageCreationParams; 96 import android.telephony.ims.RcsMessageQueryParams; 97 import android.telephony.ims.RcsMessageQueryResultParcelable; 98 import android.telephony.ims.RcsMessageSnippet; 99 import android.telephony.ims.RcsMessageStore; 100 import android.telephony.ims.RcsOutgoingMessageCreationParams; 101 import android.telephony.ims.RcsParticipantQueryParams; 102 import android.telephony.ims.RcsParticipantQueryResultParcelable; 103 import android.telephony.ims.RcsQueryContinuationToken; 104 import android.telephony.ims.RcsThreadQueryParams; 105 import android.telephony.ims.RcsThreadQueryResultParcelable; 106 import android.telephony.ims.aidl.IRcs; 107 108 import com.android.internal.annotations.VisibleForTesting; 109 110 /** 111 * Backing implementation of {@link RcsMessageStore}. 112 */ 113 public class RcsMessageStoreController extends IRcs.Stub { 114 115 static final String TAG = "RcsMsgStoreController"; 116 private static final String RCS_SERVICE_NAME = "ircs"; 117 118 private static RcsMessageStoreController sInstance; 119 120 private final Context mContext; 121 private final ContentResolver mContentResolver; 122 private final RcsParticipantQueryHelper mParticipantQueryHelper; 123 private final RcsMessageQueryHelper mMessageQueryHelper; 124 private final RcsEventQueryHelper mEventQueryHelper; 125 private final RcsThreadQueryHelper mThreadQueryHelper; 126 private final RcsMessageStoreUtil mMessageStoreUtil; 127 128 /** 129 * Initialize the instance. Should only be called once. 130 */ init(Context context)131 public static RcsMessageStoreController init(Context context) { 132 synchronized (RcsMessageStoreController.class) { 133 if (sInstance == null) { 134 sInstance = new RcsMessageStoreController(context); 135 if (ServiceManager.getService(RCS_SERVICE_NAME) == null) { 136 ServiceManager.addService(RCS_SERVICE_NAME, sInstance); 137 } 138 } else { 139 Rlog.e(TAG, "init() called multiple times! sInstance = " + sInstance); 140 } 141 } 142 return sInstance; 143 } 144 145 interface ThrowingSupplier<T> { get()146 T get() throws RemoteException; 147 } 148 149 interface ThrowingRunnable { run()150 void run() throws RemoteException; 151 } 152 performWriteOperation(String callingPackage, ThrowingRunnable fn)153 private void performWriteOperation(String callingPackage, ThrowingRunnable fn) { 154 RcsPermissions.checkWritePermissions(mContext, callingPackage); 155 156 try { 157 fn.run(); 158 } catch (RemoteException e) { 159 throw new RuntimeException(e); 160 } 161 } 162 performCreateOperation(String callingPackage, ThrowingSupplier<T> fn)163 private <T> T performCreateOperation(String callingPackage, ThrowingSupplier<T> fn) { 164 RcsPermissions.checkWritePermissions(mContext, callingPackage); 165 166 try { 167 return fn.get(); 168 } catch (RemoteException e) { 169 throw new RuntimeException(e); 170 } 171 } 172 performReadOperation(String callingPackage, ThrowingSupplier<T> fn)173 private <T> T performReadOperation(String callingPackage, ThrowingSupplier<T> fn) { 174 RcsPermissions.checkReadPermissions(mContext, callingPackage); 175 176 try { 177 return fn.get(); 178 } catch (RemoteException e) { 179 throw new RuntimeException(e); 180 } 181 } 182 183 @VisibleForTesting RcsMessageStoreController(Context context)184 public RcsMessageStoreController(Context context) { 185 mContext = context; 186 mContentResolver = context.getContentResolver(); 187 mParticipantQueryHelper = new RcsParticipantQueryHelper(mContentResolver); 188 mMessageQueryHelper = new RcsMessageQueryHelper(mContentResolver); 189 mThreadQueryHelper = new RcsThreadQueryHelper(mContentResolver, mParticipantQueryHelper); 190 mEventQueryHelper = new RcsEventQueryHelper(mContentResolver); 191 mMessageStoreUtil = new RcsMessageStoreUtil(mContentResolver); 192 } 193 194 @Override deleteThread(int threadId, int threadType, String callingPackage)195 public boolean deleteThread(int threadId, int threadType, String callingPackage) { 196 return performCreateOperation(callingPackage, () -> { 197 int deletionCount = mContentResolver.delete( 198 threadType == THREAD_TYPE_GROUP ? RCS_GROUP_THREAD_URI : RCS_1_TO_1_THREAD_URI, 199 RCS_THREAD_ID_COLUMN + "=?", 200 new String[]{Integer.toString(threadId)}); 201 202 return deletionCount > 0; 203 }); 204 } 205 206 @Override getMessageSnippet(int threadId, String callingPackage)207 public RcsMessageSnippet getMessageSnippet(int threadId, String callingPackage) { 208 return performReadOperation(callingPackage, () -> { 209 // TODO - implement 210 return null; 211 }); 212 } 213 214 @Override 215 public RcsThreadQueryResultParcelable getRcsThreads(RcsThreadQueryParams queryParameters, 216 String callingPackage) { 217 return performReadOperation(callingPackage, () -> { 218 Bundle bundle = new Bundle(); 219 bundle.putParcelable(THREAD_QUERY_PARAMETERS_KEY, queryParameters); 220 return mThreadQueryHelper.performThreadQuery(bundle); 221 }); 222 } 223 224 @Override 225 public RcsThreadQueryResultParcelable getRcsThreadsWithToken( 226 RcsQueryContinuationToken continuationToken, String callingPackage) { 227 return performReadOperation(callingPackage, () -> { 228 Bundle bundle = new Bundle(); 229 bundle.putParcelable(QUERY_CONTINUATION_TOKEN, continuationToken); 230 return mThreadQueryHelper.performThreadQuery(bundle); 231 }); 232 } 233 234 @Override 235 public RcsParticipantQueryResultParcelable getParticipants( 236 RcsParticipantQueryParams queryParameters, String callingPackage) { 237 return performReadOperation(callingPackage, () -> { 238 Bundle bundle = new Bundle(); 239 bundle.putParcelable(PARTICIPANT_QUERY_PARAMETERS_KEY, queryParameters); 240 return mParticipantQueryHelper.performParticipantQuery(bundle); 241 }); 242 } 243 244 @Override 245 public RcsParticipantQueryResultParcelable getParticipantsWithToken( 246 RcsQueryContinuationToken continuationToken, String callingPackage) { 247 return performReadOperation(callingPackage, () -> { 248 Bundle bundle = new Bundle(); 249 bundle.putParcelable(QUERY_CONTINUATION_TOKEN, continuationToken); 250 return mParticipantQueryHelper.performParticipantQuery(bundle); 251 }); 252 } 253 254 @Override 255 public RcsMessageQueryResultParcelable getMessages(RcsMessageQueryParams queryParams, 256 String callingPackage) { 257 return performReadOperation(callingPackage, () -> { 258 Bundle bundle = new Bundle(); 259 bundle.putParcelable(MESSAGE_QUERY_PARAMETERS_KEY, queryParams); 260 return mMessageQueryHelper.performMessageQuery(bundle); 261 }); 262 } 263 264 @Override 265 public RcsMessageQueryResultParcelable getMessagesWithToken( 266 RcsQueryContinuationToken continuationToken, String callingPackage) { 267 return performReadOperation(callingPackage, () -> { 268 Bundle bundle = new Bundle(); 269 bundle.putParcelable(QUERY_CONTINUATION_TOKEN, continuationToken); 270 return mMessageQueryHelper.performMessageQuery(bundle); 271 }); 272 } 273 274 @Override 275 public RcsEventQueryResultDescriptor getEvents(RcsEventQueryParams queryParameters, 276 String callingPackage) { 277 return performReadOperation(callingPackage, () -> { 278 Bundle bundle = new Bundle(); 279 bundle.putParcelable(EVENT_QUERY_PARAMETERS_KEY, queryParameters); 280 return mEventQueryHelper.performEventQuery(bundle); 281 }); 282 } 283 284 @Override 285 public RcsEventQueryResultDescriptor getEventsWithToken( 286 RcsQueryContinuationToken continuationToken, String callingPackage) { 287 return performReadOperation(callingPackage, () -> { 288 Bundle bundle = new Bundle(); 289 bundle.putParcelable(QUERY_CONTINUATION_TOKEN, continuationToken); 290 return mEventQueryHelper.performEventQuery(bundle); 291 }); 292 } 293 294 @Override 295 public int createRcs1To1Thread(int recipientId, String callingPackage) { 296 return performCreateOperation(callingPackage, 297 () -> mThreadQueryHelper.create1To1Thread(recipientId)); 298 } 299 300 @Override 301 public int createGroupThread(int[] participantIds, String groupName, Uri groupIcon, 302 String callingPackage) { 303 return performCreateOperation(callingPackage, () -> { 304 int groupThreadId = mThreadQueryHelper.createGroupThread(groupName, groupIcon); 305 if (groupThreadId <= 0) { 306 throw new RemoteException("Could not create RcsGroupThread."); 307 } 308 309 // Insert participants 310 // TODO(123718879): Instead of adding participants here, add them under RcsProvider 311 // under one transaction 312 if (participantIds != null) { 313 for (int participantId : participantIds) { 314 addParticipantToGroupThread(groupThreadId, participantId, callingPackage); 315 } 316 } 317 318 return groupThreadId; 319 }); 320 } 321 322 /** 323 * TODO(109759350) Instead of sending the update query directly to RcsProvider, this function 324 * orchestrates between RcsProvider and MmsSmsProvider. This is because we are not fully decided 325 * on whether we should have RCS storage in a separate database file. 326 */ 327 @Override 328 public int createRcsParticipant(String canonicalAddress, String alias, String callingPackage) { 329 return performCreateOperation(callingPackage, () -> { 330 ContentValues contentValues = new ContentValues(); 331 332 long canonicalAddressId = Telephony.RcsColumns.RcsCanonicalAddressHelper 333 .getOrCreateCanonicalAddressId(mContentResolver, canonicalAddress); 334 335 if (canonicalAddressId == TRANSACTION_FAILED) { 336 throw new RemoteException("Could not create or make canonical address entry"); 337 } 338 339 contentValues.put(CANONICAL_ADDRESS_ID_COLUMN, canonicalAddressId); 340 contentValues.put(RCS_ALIAS_COLUMN, alias); 341 342 // TODO (123719857) - Disallow creation of duplicate participants 343 Uri newParticipantUri = mContentResolver.insert(RCS_PARTICIPANT_URI, contentValues); 344 int newParticipantRowId; 345 346 if (newParticipantUri == null) { 347 throw new RemoteException("Error inserting new participant into RcsProvider"); 348 } 349 350 try { 351 newParticipantRowId = Integer.parseInt(newParticipantUri.getLastPathSegment()); 352 } catch (NumberFormatException e) { 353 throw new RemoteException( 354 "Uri returned after creating a participant is malformed: " 355 + newParticipantUri); 356 } 357 358 return newParticipantRowId; 359 }); 360 } 361 362 @Override 363 public String getRcsParticipantCanonicalAddress(int participantId, String callingPackage) { 364 return performReadOperation(callingPackage, 365 () -> mMessageStoreUtil.getStringValueFromTableRow(RCS_PARTICIPANT_URI, 366 Telephony.CanonicalAddressesColumns.ADDRESS, RCS_PARTICIPANT_ID_COLUMN, 367 participantId)); 368 } 369 370 @Override 371 public String getRcsParticipantAlias(int participantId, String callingPackage) { 372 return performReadOperation(callingPackage, 373 () -> mMessageStoreUtil.getStringValueFromTableRow(RCS_PARTICIPANT_URI, 374 RCS_ALIAS_COLUMN, 375 RCS_PARTICIPANT_ID_COLUMN, participantId)); 376 } 377 378 @Override 379 public void setRcsParticipantAlias(int id, String alias, String callingPackage) { 380 performWriteOperation(callingPackage, 381 () -> mMessageStoreUtil.updateValueOfProviderUri(getUriForParticipant(id), 382 RCS_ALIAS_COLUMN, 383 alias, "Could not update RCS participant alias")); 384 } 385 386 @Override 387 public String getRcsParticipantContactId(int participantId, String callingPackage) { 388 return performReadOperation(callingPackage, () -> { 389 // TODO - implement 390 return null; 391 }); 392 } 393 394 @Override 395 public void setRcsParticipantContactId(int participantId, String contactId, 396 String callingPackage) { 397 performWriteOperation(callingPackage, () -> { 398 // TODO - implement 399 }); 400 } 401 402 @Override 403 public void set1To1ThreadFallbackThreadId(int rcsThreadId, long fallbackId, 404 String callingPackage) { 405 performWriteOperation(callingPackage, 406 () -> mMessageStoreUtil.updateValueOfProviderUri(get1To1ThreadUri(rcsThreadId), 407 FALLBACK_THREAD_ID_COLUMN, fallbackId, "Could not set fallback thread ID")); 408 } 409 410 @Override 411 public long get1To1ThreadFallbackThreadId(int rcsThreadId, String callingPackage) { 412 return performReadOperation(callingPackage, 413 () -> mMessageStoreUtil.getLongValueFromTableRow(RCS_1_TO_1_THREAD_URI, 414 FALLBACK_THREAD_ID_COLUMN, 415 RCS_THREAD_ID_COLUMN, rcsThreadId)); 416 } 417 418 @Override 419 public int get1To1ThreadOtherParticipantId(int rcsThreadId, String callingPackage) { 420 return performReadOperation(callingPackage, () -> { 421 Uri uri = get1To1ThreadUri(rcsThreadId); 422 String[] projection = new String[]{RCS_PARTICIPANT_ID_COLUMN}; 423 try (Cursor cursor = mContentResolver.query(uri, projection, null, null)) { 424 if (cursor == null || cursor.getCount() != 1) { 425 throw new RemoteException("Could not get the thread recipient"); 426 } 427 cursor.moveToNext(); 428 return cursor.getInt( 429 cursor.getColumnIndex(RCS_PARTICIPANT_ID_COLUMN)); 430 } 431 }); 432 } 433 434 @Override 435 public void setGroupThreadName(int rcsThreadId, String groupName, String callingPackage) { 436 performWriteOperation(callingPackage, 437 () -> mMessageStoreUtil.updateValueOfProviderUri(getGroupThreadUri(rcsThreadId), 438 GROUP_NAME_COLUMN, groupName, "Could not update group name")); 439 } 440 441 @Override 442 public String getGroupThreadName(int rcsThreadId, String callingPackage) { 443 return performReadOperation(callingPackage, 444 () -> mMessageStoreUtil.getStringValueFromTableRow(RCS_GROUP_THREAD_URI, 445 GROUP_NAME_COLUMN, 446 RCS_THREAD_ID_COLUMN, rcsThreadId)); 447 } 448 449 @Override 450 public void setGroupThreadIcon(int rcsThreadId, Uri groupIcon, String callingPackage) { 451 performWriteOperation(callingPackage, 452 () -> mMessageStoreUtil.updateValueOfProviderUri(getGroupThreadUri(rcsThreadId), 453 GROUP_ICON_COLUMN, groupIcon, "Could not update group icon")); 454 } 455 456 @Override 457 public Uri getGroupThreadIcon(int rcsThreadId, String callingPackage) { 458 return performReadOperation(callingPackage, 459 () -> mMessageStoreUtil.getUriValueFromTableRow(RCS_GROUP_THREAD_URI, 460 GROUP_ICON_COLUMN, 461 RCS_THREAD_ID_COLUMN, rcsThreadId)); 462 } 463 464 @Override 465 public void setGroupThreadOwner(int rcsThreadId, int participantId, String callingPackage) { 466 performWriteOperation(callingPackage, 467 () -> mMessageStoreUtil.updateValueOfProviderUri(getGroupThreadUri(rcsThreadId), 468 OWNER_PARTICIPANT_COLUMN, participantId, "Could not set the group owner")); 469 } 470 471 @Override 472 public int getGroupThreadOwner(int rcsThreadId, String callingPackage) { 473 return performReadOperation(callingPackage, 474 () -> mMessageStoreUtil.getIntValueFromTableRow(RCS_GROUP_THREAD_URI, 475 OWNER_PARTICIPANT_COLUMN, 476 RCS_THREAD_ID_COLUMN, rcsThreadId)); 477 } 478 479 @Override 480 public void setGroupThreadConferenceUri(int rcsThreadId, Uri uri, String callingPackage) { 481 performWriteOperation(callingPackage, 482 () -> mMessageStoreUtil.updateValueOfProviderUri(getGroupThreadUri(rcsThreadId), 483 CONFERENCE_URI_COLUMN, uri, "Could not set the conference URI for group")); 484 } 485 486 @Override 487 public Uri getGroupThreadConferenceUri(int rcsThreadId, String callingPackage) { 488 return performReadOperation(callingPackage, 489 () -> mMessageStoreUtil.getUriValueFromTableRow(RCS_GROUP_THREAD_URI, 490 CONFERENCE_URI_COLUMN, RCS_THREAD_ID_COLUMN, rcsThreadId)); 491 } 492 493 @Override 494 public void addParticipantToGroupThread(int rcsThreadId, int participantId, 495 String callingPackage) { 496 performWriteOperation(callingPackage, () -> { 497 ContentValues contentValues = new ContentValues(2); 498 contentValues.put(RCS_THREAD_ID_COLUMN, rcsThreadId); 499 contentValues.put(RCS_PARTICIPANT_ID_COLUMN, participantId); 500 501 mContentResolver.insert(getAllParticipantsInThreadUri(rcsThreadId), contentValues); 502 }); 503 } 504 505 @Override 506 public void removeParticipantFromGroupThread(int rcsThreadId, int participantId, 507 String callingPackage) { 508 performWriteOperation(callingPackage, 509 () -> mContentResolver.delete(getParticipantInThreadUri(rcsThreadId, participantId), 510 null, 511 null)); 512 } 513 514 @Override 515 public int addIncomingMessage(int rcsThreadId, 516 RcsIncomingMessageCreationParams rcsIncomingMessageCreationParams, 517 String callingPackage) { 518 return performCreateOperation(callingPackage, () -> { 519 ContentValues contentValues = new ContentValues(); 520 521 contentValues.put(ARRIVAL_TIMESTAMP_COLUMN, 522 rcsIncomingMessageCreationParams.getArrivalTimestamp()); 523 contentValues.put(SEEN_TIMESTAMP_COLUMN, 524 rcsIncomingMessageCreationParams.getSeenTimestamp()); 525 contentValues.put(SENDER_PARTICIPANT_ID_COLUMN, 526 rcsIncomingMessageCreationParams.getSenderParticipantId()); 527 528 mMessageQueryHelper.createContentValuesForGenericMessage(contentValues, rcsThreadId, 529 rcsIncomingMessageCreationParams); 530 531 return addMessage(rcsThreadId, true, contentValues); 532 }); 533 } 534 535 @Override 536 public int addOutgoingMessage(int rcsThreadId, 537 RcsOutgoingMessageCreationParams rcsOutgoingMessageCreationParameters, 538 String callingPackage) { 539 return performCreateOperation(callingPackage, () -> { 540 ContentValues contentValues = new ContentValues(); 541 542 mMessageQueryHelper.createContentValuesForGenericMessage(contentValues, rcsThreadId, 543 rcsOutgoingMessageCreationParameters); 544 545 return addMessage(rcsThreadId, false, contentValues); 546 }); 547 } 548 549 private int addMessage(int rcsThreadId, boolean isIncoming, ContentValues contentValues) 550 throws RemoteException { 551 Uri uri = mContentResolver.insert(mMessageQueryHelper.getMessageInsertionUri(isIncoming), 552 contentValues); 553 554 if (uri == null) { 555 throw new RemoteException( 556 "Could not create message on thread, threadId: " + rcsThreadId); 557 } 558 559 return Integer.parseInt(uri.getLastPathSegment()); 560 } 561 562 @Override 563 public void deleteMessage(int messageId, boolean isIncoming, int rcsThreadId, boolean isGroup, 564 String callingPackage) { 565 performWriteOperation(callingPackage, () -> mContentResolver.delete( 566 mMessageQueryHelper.getMessageDeletionUri(messageId, isIncoming, rcsThreadId, 567 isGroup), 568 null, null)); 569 } 570 571 @Override 572 public void setMessageSubId(int messageId, boolean isIncoming, int subId, 573 String callingPackage) { 574 performWriteOperation(callingPackage, () -> mMessageStoreUtil.updateValueOfProviderUri( 575 mMessageQueryHelper.getMessageUpdateUri(messageId, isIncoming), SUB_ID_COLUMN, 576 subId, "Could not set subscription ID for message")); 577 } 578 579 @Override 580 public int getMessageSubId(int messageId, boolean isIncoming, String callingPackage) { 581 return performReadOperation(callingPackage, 582 () -> mMessageStoreUtil.getIntValueFromTableRow(getMessageTableUri(isIncoming), 583 SUB_ID_COLUMN, MESSAGE_ID_COLUMN, messageId)); 584 } 585 586 @Override 587 public void setMessageStatus(int messageId, boolean isIncoming, int status, 588 String callingPackage) { 589 performWriteOperation(callingPackage, () -> mMessageStoreUtil.updateValueOfProviderUri( 590 mMessageQueryHelper.getMessageUpdateUri(messageId, isIncoming), STATUS_COLUMN, 591 status, "Could not set the status for message")); 592 } 593 594 @Override 595 public int getMessageStatus(int messageId, boolean isIncoming, String callingPackage) { 596 return performReadOperation(callingPackage, 597 () -> mMessageStoreUtil.getIntValueFromTableRow(getMessageTableUri(isIncoming), 598 STATUS_COLUMN, MESSAGE_ID_COLUMN, messageId)); 599 } 600 601 @Override 602 public void setMessageOriginationTimestamp(int messageId, boolean isIncoming, 603 long originationTimestamp, String callingPackage) { 604 performWriteOperation(callingPackage, () -> mMessageStoreUtil.updateValueOfProviderUri( 605 mMessageQueryHelper.getMessageUpdateUri(messageId, isIncoming), 606 ORIGINATION_TIMESTAMP_COLUMN, originationTimestamp, 607 "Could not set the origination timestamp for message")); 608 } 609 610 @Override 611 public long getMessageOriginationTimestamp(int messageId, boolean isIncoming, 612 String callingPackage) { 613 return performReadOperation(callingPackage, 614 () -> mMessageStoreUtil.getLongValueFromTableRow(getMessageTableUri(isIncoming), 615 ORIGINATION_TIMESTAMP_COLUMN, MESSAGE_ID_COLUMN, messageId)); 616 } 617 618 @Override 619 public void setGlobalMessageIdForMessage(int messageId, boolean isIncoming, String globalId, 620 String callingPackage) { 621 performWriteOperation(callingPackage, () -> mMessageStoreUtil.updateValueOfProviderUri( 622 mMessageQueryHelper.getMessageUpdateUri(messageId, isIncoming), 623 GLOBAL_ID_COLUMN, 624 globalId, "Could not set the global ID for message")); 625 } 626 627 @Override 628 public String getGlobalMessageIdForMessage(int messageId, boolean isIncoming, 629 String callingPackage) { 630 return performReadOperation(callingPackage, 631 () -> mMessageStoreUtil.getStringValueFromTableRow(getMessageTableUri(isIncoming), 632 GLOBAL_ID_COLUMN, MESSAGE_ID_COLUMN, messageId)); 633 } 634 635 @Override 636 public void setMessageArrivalTimestamp(int messageId, boolean isIncoming, 637 long arrivalTimestamp, String callingPackage) { 638 performWriteOperation(callingPackage, () -> mMessageStoreUtil.updateValueOfProviderUri( 639 mMessageQueryHelper.getMessageUpdateUri(messageId, isIncoming), 640 ARRIVAL_TIMESTAMP_COLUMN, arrivalTimestamp, 641 "Could not update the arrival timestamp for message")); 642 } 643 644 @Override 645 public long getMessageArrivalTimestamp(int messageId, boolean isIncoming, 646 String callingPackage) { 647 return performReadOperation(callingPackage, 648 () -> mMessageStoreUtil.getLongValueFromTableRow(getMessageTableUri(isIncoming), 649 ARRIVAL_TIMESTAMP_COLUMN, MESSAGE_ID_COLUMN, messageId)); 650 } 651 652 @Override 653 public void setMessageSeenTimestamp(int messageId, boolean isIncoming, 654 long notifiedTimestamp, String callingPackage) { 655 performWriteOperation(callingPackage, () -> mMessageStoreUtil.updateValueOfProviderUri( 656 mMessageQueryHelper.getMessageUpdateUri(messageId, isIncoming), 657 SEEN_TIMESTAMP_COLUMN, notifiedTimestamp, 658 "Could not set the notified timestamp for message")); 659 } 660 661 @Override 662 public long getMessageSeenTimestamp(int messageId, boolean isIncoming, String callingPackage) { 663 return performReadOperation(callingPackage, 664 () -> mMessageStoreUtil.getLongValueFromTableRow(getMessageTableUri(isIncoming), 665 SEEN_TIMESTAMP_COLUMN, MESSAGE_ID_COLUMN, messageId)); 666 } 667 668 @Override 669 public int[] getMessageRecipients(int messageId, String callingPackage) { 670 return performReadOperation(callingPackage, 671 () -> mMessageQueryHelper.getDeliveryParticipantsForMessage(messageId)); 672 } 673 674 @Override 675 public long getOutgoingDeliveryDeliveredTimestamp(int messageId, int participantId, 676 String callingPackage) { 677 return performReadOperation(callingPackage, 678 () -> mMessageQueryHelper.getLongValueFromDelivery(messageId, participantId, 679 DELIVERED_TIMESTAMP_COLUMN)); 680 } 681 682 @Override 683 public void setOutgoingDeliveryDeliveredTimestamp(int messageId, int participantId, 684 long deliveredTimestamp, String callingPackage) { 685 performWriteOperation(callingPackage, () -> mMessageStoreUtil.updateValueOfProviderUri( 686 mMessageQueryHelper.getMessageDeliveryUri(messageId, participantId), 687 DELIVERED_TIMESTAMP_COLUMN, deliveredTimestamp, 688 "Could not update the delivered timestamp for outgoing delivery")); 689 } 690 691 @Override 692 public long getOutgoingDeliverySeenTimestamp(int messageId, int participantId, 693 String callingPackage) { 694 return performReadOperation(callingPackage, 695 () -> mMessageQueryHelper.getLongValueFromDelivery(messageId, participantId, 696 SEEN_TIMESTAMP_COLUMN)); 697 } 698 699 @Override 700 public void setOutgoingDeliverySeenTimestamp(int messageId, int participantId, 701 long seenTimestamp, String callingPackage) { 702 performWriteOperation(callingPackage, () -> mMessageStoreUtil.updateValueOfProviderUri( 703 mMessageQueryHelper.getMessageDeliveryUri(messageId, participantId), 704 SEEN_TIMESTAMP_COLUMN, seenTimestamp, 705 "Could not update the seen timestamp for outgoing delivery")); 706 } 707 708 @Override 709 public int getOutgoingDeliveryStatus(int messageId, int participantId, String callingPackage) { 710 return performReadOperation(callingPackage, () -> { 711 // TODO - implement 712 return 0; 713 }); 714 } 715 716 @Override 717 public void setOutgoingDeliveryStatus(int messageId, int participantId, int status, 718 String callingPackage) { 719 performWriteOperation(callingPackage, () -> { 720 // TODO - implement 721 }); 722 } 723 724 @Override 725 public void setTextForMessage(int messageId, boolean isIncoming, String text, 726 String callingPackage) { 727 performWriteOperation(callingPackage, () -> mMessageStoreUtil.updateValueOfProviderUri( 728 mMessageQueryHelper.getMessageUpdateUri(messageId, isIncoming), 729 MESSAGE_TEXT_COLUMN, 730 text, "Could not set the text for message")); 731 } 732 733 @Override 734 public String getTextForMessage(int messageId, boolean isIncoming, String callingPackage) { 735 return performReadOperation(callingPackage, 736 () -> mMessageStoreUtil.getStringValueFromTableRow(getMessageTableUri(isIncoming), 737 MESSAGE_TEXT_COLUMN, MESSAGE_ID_COLUMN, messageId)); 738 } 739 740 @Override 741 public void setLatitudeForMessage(int messageId, boolean isIncoming, double latitude, 742 String callingPackage) { 743 performWriteOperation(callingPackage, () -> mMessageStoreUtil.updateValueOfProviderUri( 744 mMessageQueryHelper.getMessageUpdateUri(messageId, isIncoming), LATITUDE_COLUMN, 745 latitude, "Could not update latitude for message")); 746 } 747 748 @Override 749 public double getLatitudeForMessage(int messageId, boolean isIncoming, String callingPackage) { 750 return performReadOperation(callingPackage, 751 () -> mMessageStoreUtil.getDoubleValueFromTableRow(getMessageTableUri(isIncoming), 752 LATITUDE_COLUMN, MESSAGE_ID_COLUMN, messageId)); 753 } 754 755 @Override 756 public void setLongitudeForMessage(int messageId, boolean isIncoming, double longitude, 757 String callingPackage) { 758 performWriteOperation(callingPackage, () -> mMessageStoreUtil.updateValueOfProviderUri( 759 mMessageQueryHelper.getMessageUpdateUri(messageId, isIncoming), 760 LONGITUDE_COLUMN, 761 longitude, "Could not set longitude for message")); 762 } 763 764 @Override 765 public double getLongitudeForMessage(int messageId, boolean isIncoming, String callingPackage) { 766 return performReadOperation(callingPackage, 767 () -> mMessageStoreUtil.getDoubleValueFromTableRow(getMessageTableUri(isIncoming), 768 LONGITUDE_COLUMN, MESSAGE_ID_COLUMN, messageId)); 769 } 770 771 @Override 772 public int[] getFileTransfersAttachedToMessage(int messageId, boolean isIncoming, 773 String callingPackage) { 774 return performReadOperation(callingPackage, () -> { 775 // TODO - implement 776 return new int[0]; 777 }); 778 } 779 780 @Override 781 public int getSenderParticipant(int messageId, String callingPackage) { 782 return performReadOperation(callingPackage, 783 () -> mMessageStoreUtil.getIntValueFromTableRow(INCOMING_MESSAGE_URI, 784 SENDER_PARTICIPANT_ID_COLUMN, MESSAGE_ID_COLUMN, messageId)); 785 } 786 787 @Override 788 public void deleteFileTransfer(int partId, String callingPackage) { 789 performWriteOperation(callingPackage, 790 () -> mContentResolver.delete(mMessageQueryHelper.getFileTransferUpdateUri(partId), 791 null, 792 null)); 793 } 794 795 @Override 796 public int storeFileTransfer(int messageId, boolean isIncoming, 797 RcsFileTransferCreationParams fileTransferCreationParameters, String callingPackage) { 798 return performCreateOperation(callingPackage, () -> { 799 ContentValues contentValues = mMessageQueryHelper.getContentValuesForFileTransfer( 800 fileTransferCreationParameters); 801 Uri uri = mContentResolver.insert( 802 mMessageQueryHelper.getFileTransferInsertionUri(messageId), contentValues); 803 804 if (uri != null) { 805 return Integer.parseInt(uri.getLastPathSegment()); 806 } 807 808 return TRANSACTION_FAILED; 809 }); 810 } 811 812 @Override 813 public void setFileTransferSessionId(int partId, String sessionId, String callingPackage) { 814 performWriteOperation(callingPackage, () -> mMessageStoreUtil.updateValueOfProviderUri( 815 mMessageQueryHelper.getFileTransferUpdateUri(partId), SESSION_ID_COLUMN, 816 sessionId, 817 "Could not set session ID for file transfer")); 818 } 819 820 @Override 821 public String getFileTransferSessionId(int partId, String callingPackage) { 822 return performReadOperation(callingPackage, 823 () -> mMessageStoreUtil.getStringValueFromTableRow(FILE_TRANSFER_URI, 824 SESSION_ID_COLUMN, 825 FILE_TRANSFER_ID_COLUMN, partId)); 826 } 827 828 @Override 829 public void setFileTransferContentUri(int partId, Uri contentUri, String callingPackage) { 830 performWriteOperation(callingPackage, () -> mMessageStoreUtil.updateValueOfProviderUri( 831 mMessageQueryHelper.getFileTransferUpdateUri(partId), CONTENT_URI_COLUMN, 832 contentUri, "Could not set content URI for file transfer")); 833 } 834 835 @Override 836 public Uri getFileTransferContentUri(int partId, String callingPackage) { 837 return performReadOperation(callingPackage, 838 () -> mMessageStoreUtil.getUriValueFromTableRow(FILE_TRANSFER_URI, 839 CONTENT_URI_COLUMN, 840 FILE_TRANSFER_ID_COLUMN, partId)); 841 } 842 843 @Override 844 public void setFileTransferContentType(int partId, String contentType, String callingPackage) { 845 performWriteOperation(callingPackage, () -> mMessageStoreUtil.updateValueOfProviderUri( 846 mMessageQueryHelper.getFileTransferUpdateUri(partId), CONTENT_TYPE_COLUMN, 847 contentType, "Could not set content type for file transfer")); 848 } 849 850 @Override 851 public String getFileTransferContentType(int partId, String callingPackage) { 852 return performReadOperation(callingPackage, 853 () -> mMessageStoreUtil.getStringValueFromTableRow(FILE_TRANSFER_URI, 854 CONTENT_TYPE_COLUMN, 855 FILE_TRANSFER_ID_COLUMN, partId)); 856 } 857 858 @Override 859 public void setFileTransferFileSize(int partId, long fileSize, String callingPackage) { 860 performWriteOperation(callingPackage, () -> mMessageStoreUtil.updateValueOfProviderUri( 861 mMessageQueryHelper.getFileTransferUpdateUri(partId), FILE_SIZE_COLUMN, 862 fileSize, 863 "Could not set file size for file transfer")); 864 } 865 866 @Override 867 public long getFileTransferFileSize(int partId, String callingPackage) { 868 return performReadOperation(callingPackage, 869 () -> mMessageStoreUtil.getLongValueFromTableRow(FILE_TRANSFER_URI, 870 FILE_SIZE_COLUMN, 871 FILE_TRANSFER_ID_COLUMN, partId)); 872 } 873 874 @Override 875 public void setFileTransferTransferOffset(int partId, long transferOffset, 876 String callingPackage) { 877 performWriteOperation(callingPackage, () -> mMessageStoreUtil.updateValueOfProviderUri( 878 mMessageQueryHelper.getFileTransferUpdateUri(partId), 879 SUCCESSFULLY_TRANSFERRED_BYTES, 880 transferOffset, "Could not set transfer offset for file transfer")); 881 } 882 883 @Override 884 public long getFileTransferTransferOffset(int partId, String callingPackage) { 885 return performReadOperation(callingPackage, 886 () -> mMessageStoreUtil.getLongValueFromTableRow(FILE_TRANSFER_URI, 887 SUCCESSFULLY_TRANSFERRED_BYTES, 888 FILE_TRANSFER_ID_COLUMN, partId)); 889 } 890 891 @Override 892 public void setFileTransferStatus(int partId, int transferStatus, String callingPackage) { 893 performWriteOperation(callingPackage, () -> mMessageStoreUtil.updateValueOfProviderUri( 894 mMessageQueryHelper.getFileTransferUpdateUri(partId), TRANSFER_STATUS_COLUMN, 895 transferStatus, "Could not set transfer status for file transfer")); 896 } 897 898 @Override 899 public int getFileTransferStatus(int partId, String callingPackage) { 900 return performReadOperation(callingPackage, 901 () -> mMessageStoreUtil.getIntValueFromTableRow(FILE_TRANSFER_URI, STATUS_COLUMN, 902 FILE_TRANSFER_ID_COLUMN, partId)); 903 } 904 905 @Override 906 public void setFileTransferWidth(int partId, int width, String callingPackage) { 907 performWriteOperation(callingPackage, () -> mMessageStoreUtil.updateValueOfProviderUri( 908 mMessageQueryHelper.getFileTransferUpdateUri(partId), WIDTH_COLUMN, width, 909 "Could not set width of file transfer")); 910 } 911 912 @Override 913 public int getFileTransferWidth(int partId, String callingPackage) { 914 return performReadOperation(callingPackage, 915 () -> mMessageStoreUtil.getIntValueFromTableRow(FILE_TRANSFER_URI, WIDTH_COLUMN, 916 FILE_TRANSFER_ID_COLUMN, partId)); 917 } 918 919 @Override 920 public void setFileTransferHeight(int partId, int height, String callingPackage) { 921 performWriteOperation(callingPackage, () -> mMessageStoreUtil.updateValueOfProviderUri( 922 mMessageQueryHelper.getFileTransferUpdateUri(partId), HEIGHT_COLUMN, height, 923 "Could not set height of file transfer")); 924 } 925 926 @Override 927 public int getFileTransferHeight(int partId, String callingPackage) { 928 return performReadOperation(callingPackage, 929 () -> mMessageStoreUtil.getIntValueFromTableRow(FILE_TRANSFER_URI, HEIGHT_COLUMN, 930 FILE_TRANSFER_ID_COLUMN, partId)); 931 } 932 933 @Override 934 public void setFileTransferLength(int partId, long length, String callingPackage) { 935 performWriteOperation(callingPackage, () -> mMessageStoreUtil.updateValueOfProviderUri( 936 mMessageQueryHelper.getFileTransferUpdateUri(partId), DURATION_MILLIS_COLUMN, 937 length, 938 "Could not set length of file transfer")); 939 } 940 941 @Override 942 public long getFileTransferLength(int partId, String callingPackage) { 943 return performReadOperation(callingPackage, 944 () -> mMessageStoreUtil.getLongValueFromTableRow(FILE_TRANSFER_URI, 945 DURATION_MILLIS_COLUMN, 946 FILE_TRANSFER_ID_COLUMN, partId)); 947 } 948 949 @Override 950 public void setFileTransferPreviewUri(int partId, Uri uri, String callingPackage) { 951 performWriteOperation(callingPackage, () -> mMessageStoreUtil.updateValueOfProviderUri( 952 mMessageQueryHelper.getFileTransferUpdateUri(partId), PREVIEW_URI_COLUMN, uri, 953 "Could not set preview URI of file transfer")); 954 } 955 956 @Override 957 public Uri getFileTransferPreviewUri(int partId, String callingPackage) { 958 return performReadOperation(callingPackage, 959 () -> mMessageStoreUtil.getUriValueFromTableRow(FILE_TRANSFER_URI, 960 DURATION_MILLIS_COLUMN, 961 FILE_TRANSFER_ID_COLUMN, partId)); 962 } 963 964 @Override 965 public void setFileTransferPreviewType(int partId, String type, String callingPackage) { 966 performWriteOperation(callingPackage, () -> mMessageStoreUtil.updateValueOfProviderUri( 967 mMessageQueryHelper.getFileTransferUpdateUri(partId), PREVIEW_TYPE_COLUMN, type, 968 "Could not set preview type of file transfer")); 969 } 970 971 @Override 972 public String getFileTransferPreviewType(int partId, String callingPackage) { 973 return performReadOperation(callingPackage, 974 () -> mMessageStoreUtil.getStringValueFromTableRow(FILE_TRANSFER_URI, 975 PREVIEW_TYPE_COLUMN, 976 FILE_TRANSFER_ID_COLUMN, partId)); 977 } 978 979 @Override 980 public int createGroupThreadNameChangedEvent(long timestamp, int threadId, 981 int originationParticipantId, String newName, String callingPackage) { 982 return performCreateOperation(callingPackage, () -> { 983 ContentValues eventSpecificValues = new ContentValues(); 984 eventSpecificValues.put(NEW_NAME_COLUMN, newName); 985 986 return mEventQueryHelper.createGroupThreadEvent(NAME_CHANGED_EVENT_TYPE, timestamp, 987 threadId, originationParticipantId, eventSpecificValues); 988 }); 989 } 990 991 @Override 992 public int createGroupThreadIconChangedEvent(long timestamp, int threadId, 993 int originationParticipantId, Uri newIcon, String callingPackage) { 994 return performCreateOperation(callingPackage, () -> { 995 ContentValues eventSpecificValues = new ContentValues(); 996 eventSpecificValues.put(NEW_ICON_URI_COLUMN, 997 newIcon == null ? null : newIcon.toString()); 998 999 return mEventQueryHelper.createGroupThreadEvent(ICON_CHANGED_EVENT_TYPE, timestamp, 1000 threadId, originationParticipantId, eventSpecificValues); 1001 }); 1002 } 1003 1004 @Override 1005 public int createGroupThreadParticipantJoinedEvent(long timestamp, int threadId, 1006 int originationParticipantId, int participantId, String callingPackage) { 1007 return performCreateOperation(callingPackage, () -> { 1008 ContentValues eventSpecificValues = new ContentValues(); 1009 eventSpecificValues.put(DESTINATION_PARTICIPANT_ID_COLUMN, participantId); 1010 1011 return mEventQueryHelper.createGroupThreadEvent(PARTICIPANT_JOINED_EVENT_TYPE, 1012 timestamp, 1013 threadId, originationParticipantId, eventSpecificValues); 1014 }); 1015 } 1016 1017 @Override 1018 public int createGroupThreadParticipantLeftEvent(long timestamp, int threadId, 1019 int originationParticipantId, int participantId, String callingPackage) { 1020 return performCreateOperation(callingPackage, () -> { 1021 ContentValues eventSpecificValues = new ContentValues(); 1022 eventSpecificValues.put(DESTINATION_PARTICIPANT_ID_COLUMN, participantId); 1023 1024 return mEventQueryHelper.createGroupThreadEvent(PARTICIPANT_LEFT_EVENT_TYPE, timestamp, 1025 threadId, originationParticipantId, eventSpecificValues); 1026 }); 1027 } 1028 1029 @Override 1030 public int createParticipantAliasChangedEvent(long timestamp, int participantId, 1031 String newAlias, String callingPackage) { 1032 return performCreateOperation(callingPackage, () -> { 1033 ContentValues contentValues = new ContentValues(4); 1034 contentValues.put(TIMESTAMP_COLUMN, timestamp); 1035 contentValues.put(SOURCE_PARTICIPANT_ID_COLUMN, participantId); 1036 contentValues.put(NEW_ALIAS_COLUMN, newAlias); 1037 1038 Uri uri = mContentResolver.insert( 1039 mEventQueryHelper.getParticipantEventInsertionUri(participantId), 1040 contentValues); 1041 1042 if (uri == null) { 1043 throw new RemoteException( 1044 "Could not create RcsParticipantAliasChangedEvent with participant id: " 1045 + participantId); 1046 } 1047 1048 return Integer.parseInt(uri.getLastPathSegment()); 1049 }); 1050 } 1051 } 1052