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 ed8cddf2b4..388db98917 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/database/CallTable.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/database/CallTable.kt @@ -110,7 +110,7 @@ class CallTable(context: Context, databaseHelper: SignalDatabase) : DatabaseTabl ) } fun markAllCallEventsRead(timestamp: Long = Long.MAX_VALUE) { - val now = System.currentTimeMillis() + val proposedExpireStarted = if (timestamp == Long.MAX_VALUE) System.currentTimeMillis() else timestamp val allUnreadMissedCalls = readableDatabase .select(MESSAGE_ID) @@ -131,9 +131,9 @@ class CallTable(context: Context, databaseHelper: SignalDatabase) : DatabaseTabl if (expiringCalls.isNotEmpty()) { Log.i(TAG, "Found ${expiringCalls.size} calls that needs expiring.") - SignalDatabase.messages.markExpireStarted(expiringCalls.map { it.key to now }) + SignalDatabase.messages.markExpireStarted(expiringCalls.map { it.key to proposedExpireStarted }) for ((messageId, expiresIn) in expiringCalls) { - AppDependencies.expiringMessageManager.scheduleDeletion(messageId, true, now, expiresIn) + AppDependencies.expiringMessageManager.scheduleDeletion(messageId, true, proposedExpireStarted, expiresIn) } } @@ -143,13 +143,13 @@ class CallTable(context: Context, databaseHelper: SignalDatabase) : DatabaseTabl } fun markAllCallEventsWithPeerBeforeTimestampRead(peer: RecipientId, timestamp: Long): Call? { - val now = System.currentTimeMillis() + val proposedExpireStarted = if (timestamp == Long.MAX_VALUE) System.currentTimeMillis() else timestamp val latestCallAsOfTimestamp = writableDatabase.withinTransaction { db -> val unreadMissedCalls = db .select(MESSAGE_ID) .from(TABLE_NAME) - .where("$PEER = ? AND $TIMESTAMP <= ? AND $READ != ? AND $EVENT = ?", peer.toLong(), timestamp, ReadState.serialize(ReadState.READ), Event.serialize(Event.MISSED)) + .where("$PEER = ? AND $TIMESTAMP <= ? AND $READ != ? AND $EVENT = ? AND $GROUP_CALL_ACTIVE = 0", peer.toLong(), timestamp, ReadState.serialize(ReadState.READ), Event.serialize(Event.MISSED)) .run() .readToList { cursor -> cursor.requireLong(MESSAGE_ID) @@ -164,9 +164,9 @@ class CallTable(context: Context, databaseHelper: SignalDatabase) : DatabaseTabl if (expiring.isNotEmpty()) { Log.i(TAG, "Found ${expiring.size} calls that needs expiring.") - SignalDatabase.messages.markExpireStarted(expiring.map { it.key to now }) + SignalDatabase.messages.markExpireStarted(expiring.map { it.key to proposedExpireStarted }) for ((messageId, expiresIn) in expiring) { - AppDependencies.expiringMessageManager.scheduleDeletion(messageId, true, now, expiresIn) + AppDependencies.expiringMessageManager.scheduleDeletion(messageId, true, proposedExpireStarted, expiresIn) } } @@ -196,11 +196,11 @@ class CallTable(context: Context, databaseHelper: SignalDatabase) : DatabaseTabl .readToSingleLong() } - fun insertOneToOneCall(callId: Long, timestamp: Long, peer: RecipientId, type: Type, direction: Direction, event: Event) { + fun insertOneToOneCall(callId: Long, timestamp: Long, peer: RecipientId, type: Type, direction: Direction, event: Event, fromSync: Boolean = false) { val messageType: Long = Call.getMessageType(type, direction, event) writableDatabase.withinTransaction { - val result = SignalDatabase.messages.insertOneToOneCallLog(peer, messageType, timestamp, direction == Direction.OUTGOING) + val result = SignalDatabase.messages.insertOneToOneCallLog(peer, messageType, timestamp, direction == Direction.OUTGOING, fromSync) val values = contentValuesOf( CALL_ID to callId, MESSAGE_ID to result.messageId, diff --git a/app/src/main/java/org/thoughtcrime/securesms/database/MessageTable.kt b/app/src/main/java/org/thoughtcrime/securesms/database/MessageTable.kt index 20c55e707d..a9a4969939 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/database/MessageTable.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/database/MessageTable.kt @@ -909,7 +909,7 @@ open class MessageTable(context: Context?, databaseHelper: SignalDatabase) : Dat return results } - fun insertOneToOneCallLog(recipientId: RecipientId, type: Long, timestamp: Long, outgoing: Boolean): InsertResult { + fun insertOneToOneCallLog(recipientId: RecipientId, type: Long, timestamp: Long, outgoing: Boolean, fromSync: Boolean = false): InsertResult { val recipient = Recipient.resolved(recipientId) val threadIdResult = threads.getOrCreateThreadIdResultFor(recipient.id, recipient.isGroup) val threadId = threadIdResult.threadId @@ -938,6 +938,13 @@ open class MessageTable(context: Context?, databaseHelper: SignalDatabase) : Dat notifyConversationListeners(threadId) TrimThreadJob.enqueueAsync(threadId) + // If inserting an outgoing call from a sync message, automatically start timer + if (expiresIn != 0L && outgoing && fromSync) { + Log.i(TAG, "Starting expiration timer after inserting a call from a sync message.") + markExpireStarted(messageId, timestamp) + AppDependencies.expiringMessageManager.scheduleDeletion(messageId, true, timestamp, expiresIn) + } + return InsertResult( messageId = messageId, threadId = threadId, diff --git a/app/src/main/java/org/thoughtcrime/securesms/messages/SyncMessageProcessor.kt b/app/src/main/java/org/thoughtcrime/securesms/messages/SyncMessageProcessor.kt index 34b52749fd..7873a49b5b 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/messages/SyncMessageProcessor.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/messages/SyncMessageProcessor.kt @@ -1469,7 +1469,7 @@ object SyncMessageProcessor { } else if (event == CallTable.Event.DELETE) { SignalDatabase.calls.insertDeletedCallFromSyncEvent(callId, recipientId, type, direction, timestamp) } else { - SignalDatabase.calls.insertOneToOneCall(callId, timestamp, recipientId, type, direction, event) + SignalDatabase.calls.insertOneToOneCall(callId, timestamp, recipientId, type, direction, event, fromSync = true) } } diff --git a/app/src/main/java/org/thoughtcrime/securesms/service/webrtc/BeginCallActionProcessorDelegate.java b/app/src/main/java/org/thoughtcrime/securesms/service/webrtc/BeginCallActionProcessorDelegate.java index a1aa7598e2..99f86edf39 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/service/webrtc/BeginCallActionProcessorDelegate.java +++ b/app/src/main/java/org/thoughtcrime/securesms/service/webrtc/BeginCallActionProcessorDelegate.java @@ -60,7 +60,8 @@ public class BeginCallActionProcessorDelegate extends WebRtcActionProcessor { remotePeer.getId(), isVideoOffer ? CallTable.Type.VIDEO_CALL : CallTable.Type.AUDIO_CALL, CallTable.Direction.OUTGOING, - CallTable.Event.ONGOING); + CallTable.Event.ONGOING, + false); webRtcInteractor.insertMissedCall(remotePeer, System.currentTimeMillis(), isVideoOffer, CallTable.Event.NOT_ACCEPTED); webRtcInteractor.postStateUpdate(currentState); diff --git a/app/src/main/java/org/thoughtcrime/securesms/service/webrtc/IncomingCallActionProcessor.java b/app/src/main/java/org/thoughtcrime/securesms/service/webrtc/IncomingCallActionProcessor.java index ff14185dc1..29e0b49a2e 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/service/webrtc/IncomingCallActionProcessor.java +++ b/app/src/main/java/org/thoughtcrime/securesms/service/webrtc/IncomingCallActionProcessor.java @@ -241,9 +241,10 @@ public class IncomingCallActionProcessor extends DeviceAwareActionProcessor { SignalDatabase.calls().insertOneToOneCall(remotePeer.getCallId().longValue(), System.currentTimeMillis(), remotePeer.getId(), - currentState.getCallSetupState(activePeer).isRemoteVideoOffer() ? CallTable.Type.VIDEO_CALL : CallTable.Type.AUDIO_CALL, + currentState.getCallSetupState(activePeer).isRemoteVideoOffer() ? CallTable.Type.VIDEO_CALL : CallTable.Type.AUDIO_CALL, CallTable.Direction.INCOMING, - CallTable.Event.ONGOING); + CallTable.Event.ONGOING, + false); if (!shouldDisturbUserWithCall) { Log.i(TAG, "Silently ignoring call due to mute settings."); diff --git a/app/src/main/java/org/thoughtcrime/securesms/service/webrtc/OutgoingCallActionProcessor.java b/app/src/main/java/org/thoughtcrime/securesms/service/webrtc/OutgoingCallActionProcessor.java index 8c5e694dbe..9f497e935d 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/service/webrtc/OutgoingCallActionProcessor.java +++ b/app/src/main/java/org/thoughtcrime/securesms/service/webrtc/OutgoingCallActionProcessor.java @@ -91,7 +91,8 @@ public class OutgoingCallActionProcessor extends DeviceAwareActionProcessor { remotePeer.getId(), isVideoCall ? CallTable.Type.VIDEO_CALL : CallTable.Type.AUDIO_CALL, CallTable.Direction.OUTGOING, - CallTable.Event.ONGOING); + CallTable.Event.ONGOING, + false); EglBaseWrapper.replaceHolder(EglBaseWrapper.OUTGOING_PLACEHOLDER, remotePeer.getCallId().longValue()); diff --git a/app/src/main/java/org/thoughtcrime/securesms/service/webrtc/SignalCallManager.java b/app/src/main/java/org/thoughtcrime/securesms/service/webrtc/SignalCallManager.java index c1884ade01..3a89dd5b76 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/service/webrtc/SignalCallManager.java +++ b/app/src/main/java/org/thoughtcrime/securesms/service/webrtc/SignalCallManager.java @@ -1127,7 +1127,7 @@ public final class SignalCallManager implements CallManager.Observer, GroupCall. CallTable.Type type = isVideoOffer ? CallTable.Type.VIDEO_CALL : CallTable.Type.AUDIO_CALL; SignalDatabase.calls() - .insertOneToOneCall(remotePeer.getCallId().longValue(), timestamp, remotePeer.getId(), type, CallTable.Direction.INCOMING, missedEvent); + .insertOneToOneCall(remotePeer.getCallId().longValue(), timestamp, remotePeer.getId(), type, CallTable.Direction.INCOMING, missedEvent, false); } } @@ -1139,7 +1139,7 @@ public final class SignalCallManager implements CallManager.Observer, GroupCall. CallTable.Type type = isVideoOffer ? CallTable.Type.VIDEO_CALL : CallTable.Type.AUDIO_CALL; SignalDatabase.calls() - .insertOneToOneCall(remotePeer.getCallId().longValue(), System.currentTimeMillis(), remotePeer.getId(), type, CallTable.Direction.INCOMING, CallTable.Event.ACCEPTED); + .insertOneToOneCall(remotePeer.getCallId().longValue(), System.currentTimeMillis(), remotePeer.getId(), type, CallTable.Direction.INCOMING, CallTable.Event.ACCEPTED, false); } }