From 6f463317728604a7c25edd7655ce7ed9d47efb1f Mon Sep 17 00:00:00 2001 From: Alex Hart Date: Fri, 15 Mar 2024 11:38:16 -0300 Subject: [PATCH] Add call log event proto updates. --- .../securesms/calls/log/CallLogRepository.kt | 11 ++++++----- .../securesms/database/CallTable.kt | 6 +++--- .../securesms/jobs/CallLogEventSendJob.kt | 19 +++++++++++++++---- .../camerax/SignalCameraController.kt | 6 +++--- .../securesms/recipients/Recipient.java | 12 ++++++++++++ .../src/main/protowire/SignalService.proto | 11 +++++++++-- 6 files changed, 48 insertions(+), 17 deletions(-) diff --git a/app/src/main/java/org/thoughtcrime/securesms/calls/log/CallLogRepository.kt b/app/src/main/java/org/thoughtcrime/securesms/calls/log/CallLogRepository.kt index 81bbf06834..a46805cdce 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/calls/log/CallLogRepository.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/calls/log/CallLogRepository.kt @@ -43,8 +43,9 @@ class CallLogRepository( fun markAllCallEventsRead() { SignalExecutors.BOUNDED_IO.execute { + val latestCall = SignalDatabase.calls.getLatestCall() ?: return@execute SignalDatabase.calls.markAllCallEventsRead() - ApplicationDependencies.getJobManager().add(CallLogEventSendJob.forMarkedAsRead(System.currentTimeMillis())) + ApplicationDependencies.getJobManager().add(CallLogEventSendJob.forMarkedAsRead(latestCall)) } } @@ -95,10 +96,10 @@ class CallLogRepository( fun deleteAllCallLogsOnOrBeforeNow(): Single { return Single.fromCallable { SignalDatabase.rawDatabase.withinTransaction { - val latestTimestamp = SignalDatabase.calls.getLatestTimestamp() - SignalDatabase.calls.deleteNonAdHocCallEventsOnOrBefore(latestTimestamp) - SignalDatabase.callLinks.deleteNonAdminCallLinksOnOrBefore(latestTimestamp) - ApplicationDependencies.getJobManager().add(CallLogEventSendJob.forClearHistory(latestTimestamp)) + val latestCall = SignalDatabase.calls.getLatestCall() ?: return@withinTransaction + SignalDatabase.calls.deleteNonAdHocCallEventsOnOrBefore(latestCall.timestamp) + SignalDatabase.callLinks.deleteNonAdminCallLinksOnOrBefore(latestCall.timestamp) + ApplicationDependencies.getJobManager().add(CallLogEventSendJob.forClearHistory(latestCall)) } SignalDatabase.callLinks.getAllAdminCallLinksExcept(emptySet()) diff --git a/app/src/main/java/org/thoughtcrime/securesms/database/CallTable.kt b/app/src/main/java/org/thoughtcrime/securesms/database/CallTable.kt index 03d04e6cc6..48d8e96154 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/database/CallTable.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/database/CallTable.kt @@ -947,12 +947,12 @@ class CallTable(context: Context, databaseHelper: SignalDatabase) : DatabaseTabl /** * Gets the most recent timestamp from the [TIMESTAMP] column */ - fun getLatestTimestamp(): Long { + fun getLatestCall(): Call? { val statement = """ - SELECT $TIMESTAMP FROM $TABLE_NAME ORDER BY $TIMESTAMP DESC LIMIT 1 + SELECT * FROM $TABLE_NAME ORDER BY $TIMESTAMP DESC LIMIT 1 """.trimIndent() - return readableDatabase.query(statement).readToSingleLong(-1) + return readableDatabase.query(statement).readToSingleObject { Call.deserialize(it) } } fun deleteNonAdHocCallEventsOnOrBefore(timestamp: Long) { diff --git a/app/src/main/java/org/thoughtcrime/securesms/jobs/CallLogEventSendJob.kt b/app/src/main/java/org/thoughtcrime/securesms/jobs/CallLogEventSendJob.kt index 992b76f93f..7c6f6ef754 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/jobs/CallLogEventSendJob.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/jobs/CallLogEventSendJob.kt @@ -5,10 +5,15 @@ package org.thoughtcrime.securesms.jobs +import androidx.annotation.WorkerThread +import okio.ByteString +import okio.ByteString.Companion.toByteString +import org.thoughtcrime.securesms.database.CallTable import org.thoughtcrime.securesms.dependencies.ApplicationDependencies import org.thoughtcrime.securesms.jobmanager.Job import org.thoughtcrime.securesms.jobmanager.impl.NetworkConstraint import org.thoughtcrime.securesms.jobs.protos.CallLogEventSendJobData +import org.thoughtcrime.securesms.recipients.Recipient import org.whispersystems.signalservice.api.messages.multidevice.SignalServiceSyncMessage import org.whispersystems.signalservice.api.push.exceptions.PushNetworkException import org.whispersystems.signalservice.api.push.exceptions.ServerRejectedException @@ -27,8 +32,9 @@ class CallLogEventSendJob private constructor( companion object { const val KEY = "CallLogEventSendJob" + @WorkerThread fun forClearHistory( - timestamp: Long + call: CallTable.Call ) = CallLogEventSendJob( Parameters.Builder() .setQueue("CallLogEventSendJob") @@ -37,13 +43,16 @@ class CallLogEventSendJob private constructor( .addConstraint(NetworkConstraint.KEY) .build(), SyncMessage.CallLogEvent( - timestamp = timestamp, + timestamp = call.timestamp, + callId = call.callId, + conversationId = Recipient.resolved(call.peer).requireCallConversationId().toByteString(), type = SyncMessage.CallLogEvent.Type.CLEAR ) ) + @WorkerThread fun forMarkedAsRead( - timestamp: Long + call: CallTable.Call ) = CallLogEventSendJob( Parameters.Builder() .setQueue("CallLogEventSendJob") @@ -52,7 +61,9 @@ class CallLogEventSendJob private constructor( .addConstraint(NetworkConstraint.KEY) .build(), SyncMessage.CallLogEvent( - timestamp = timestamp, + timestamp = call.timestamp, + callId = call.callId, + conversationId = Recipient.resolved(call.peer).requireCallConversationId().toByteString(), type = SyncMessage.CallLogEvent.Type.MARKED_AS_READ ) ) diff --git a/app/src/main/java/org/thoughtcrime/securesms/mediasend/camerax/SignalCameraController.kt b/app/src/main/java/org/thoughtcrime/securesms/mediasend/camerax/SignalCameraController.kt index 9c37fa1645..5ada5c6291 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/mediasend/camerax/SignalCameraController.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/mediasend/camerax/SignalCameraController.kt @@ -29,6 +29,8 @@ import androidx.camera.core.ZoomState import androidx.camera.core.resolutionselector.AspectRatioStrategy import androidx.camera.core.resolutionselector.ResolutionSelector import androidx.camera.core.resolutionselector.ResolutionStrategy +import androidx.camera.extensions.ExtensionMode +import androidx.camera.extensions.ExtensionsManager import androidx.camera.lifecycle.ProcessCameraProvider import androidx.camera.video.FallbackStrategy import androidx.camera.video.FileDescriptorOutputOptions @@ -56,8 +58,6 @@ import org.thoughtcrime.securesms.util.visible import java.util.concurrent.Executor import kotlin.math.max import kotlin.math.min -import androidx.camera.extensions.ExtensionMode -import androidx.camera.extensions.ExtensionsManager /** * This is a class to manage the camera resource, and relies on the AndroidX CameraX library. @@ -145,7 +145,7 @@ class SignalCameraController( return } - val extCameraSelector = if (extensionsManager.isExtensionAvailable(cameraSelector, ExtensionMode.AUTO)) { + val extCameraSelector = if (extensionsManager.isExtensionAvailable(cameraSelector, ExtensionMode.AUTO)) { Log.d(TAG, "Using CameraX ExtensionMode.AUTO") extensionsManager.getExtensionEnabledCameraSelector( cameraSelector, diff --git a/app/src/main/java/org/thoughtcrime/securesms/recipients/Recipient.java b/app/src/main/java/org/thoughtcrime/securesms/recipients/Recipient.java index 3a1e4aa808..04782bf699 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/recipients/Recipient.java +++ b/app/src/main/java/org/thoughtcrime/securesms/recipients/Recipient.java @@ -1221,6 +1221,18 @@ public class Recipient { return Objects.requireNonNull(callLinkRoomId); } + public @NonNull byte[] requireCallConversationId() { + if (isPushGroup()) { + return requireGroupId().getDecodedId(); + } else if (isCallLink()) { + return requireCallLinkRoomId().encodeForProto().toByteArray(); + } else if (isIndividual()) { + return requireServiceId().toByteArray(); + } else { + throw new IllegalStateException("Recipient does not support conversation id"); + } + } + public PhoneNumberSharingState getPhoneNumberSharing() { return phoneNumberSharing; } diff --git a/libsignal-service/src/main/protowire/SignalService.proto b/libsignal-service/src/main/protowire/SignalService.proto index c087a69e3c..0707e787a7 100644 --- a/libsignal-service/src/main/protowire/SignalService.proto +++ b/libsignal-service/src/main/protowire/SignalService.proto @@ -641,8 +641,15 @@ message SyncMessage { MARKED_AS_READ = 1; } - optional Type type = 1; - optional uint64 timestamp = 2; + optional Type type = 1; + optional uint64 timestamp = 2; + /* Data identifying a conversation. The service ID for 1:1, the group ID for + * group, or the room ID for an ad-hoc call. See also + * `CallEvent/conversationId`. */ + optional bytes conversationId = 3; + /* An identifier for a call. Generated directly for 1:1, or derived from + * the era ID for group and ad-hoc calls. See also `CallEvent/callId`. */ + optional uint64 callId = 4; } optional Sent sent = 1;