Skip to content

Commit 96153fe

Browse files
committed
Get Event after a Push for a faster notification display in some conditions
1 parent af02366 commit 96153fe

File tree

14 files changed

+234
-41
lines changed

14 files changed

+234
-41
lines changed

CHANGES.md

+1
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ Improvements 🙌:
1717
- Add better support for empty room name fallback (#3106)
1818
- Room list improvements (paging)
1919
- Fix quick click action (#3127)
20+
- Get Event after a Push for a faster notification display in some conditions
2021

2122
Bugfix 🐛:
2223
- Fix bad theme change for the MainActivity

matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/Session.kt

+2
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ import org.matrix.android.sdk.api.session.call.CallSignalingService
3030
import org.matrix.android.sdk.api.session.content.ContentUploadStateTracker
3131
import org.matrix.android.sdk.api.session.content.ContentUrlResolver
3232
import org.matrix.android.sdk.api.session.crypto.CryptoService
33+
import org.matrix.android.sdk.api.session.events.EventService
3334
import org.matrix.android.sdk.api.session.file.ContentDownloadStateTracker
3435
import org.matrix.android.sdk.api.session.file.FileService
3536
import org.matrix.android.sdk.api.session.group.GroupService
@@ -68,6 +69,7 @@ interface Session :
6869
SignOutService,
6970
FilterService,
7071
TermsService,
72+
EventService,
7173
ProfileService,
7274
PushRuleService,
7375
PushersService,
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
/*
2+
* Copyright (c) 2021 The Matrix.org Foundation C.I.C.
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 org.matrix.android.sdk.api.session.events
18+
19+
import org.matrix.android.sdk.api.session.events.model.Event
20+
21+
interface EventService {
22+
23+
/**
24+
* Ask the homeserver for an event content. The SDK will try to decrypt it if it is possible
25+
* The result will not be stored into cache
26+
*/
27+
suspend fun getEvent(roomId: String, eventId: String): Event
28+
}

matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/query/ReadQueries.kt

+14-9
Original file line numberDiff line numberDiff line change
@@ -38,16 +38,21 @@ internal fun isEventRead(realmConfiguration: RealmConfiguration,
3838
Realm.getInstance(realmConfiguration).use { realm ->
3939
val liveChunk = ChunkEntity.findLastForwardChunkOfRoom(realm, roomId) ?: return@use
4040
val eventToCheck = liveChunk.timelineEvents.find(eventId)
41-
isEventRead = if (eventToCheck == null || eventToCheck.root?.sender == userId) {
42-
true
43-
} else {
44-
val readReceipt = ReadReceiptEntity.where(realm, roomId, userId).findFirst()
45-
?: return@use
46-
val readReceiptIndex = liveChunk.timelineEvents.find(readReceipt.eventId)?.displayIndex
47-
?: Int.MIN_VALUE
48-
val eventToCheckIndex = eventToCheck.displayIndex
41+
isEventRead = when {
42+
eventToCheck == null -> {
43+
// This can happen in case of fast lane Event
44+
false
45+
}
46+
eventToCheck.root?.sender == userId -> true
47+
else -> {
48+
val readReceipt = ReadReceiptEntity.where(realm, roomId, userId).findFirst()
49+
?: return@use
50+
val readReceiptIndex = liveChunk.timelineEvents.find(readReceipt.eventId)?.displayIndex
51+
?: Int.MIN_VALUE
52+
val eventToCheckIndex = eventToCheck.displayIndex
4953

50-
eventToCheckIndex <= readReceiptIndex
54+
eventToCheckIndex <= readReceiptIndex
55+
}
5156
}
5257
}
5358

matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/DefaultSession.kt

+3
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ import org.matrix.android.sdk.api.session.call.CallSignalingService
3333
import org.matrix.android.sdk.api.session.content.ContentUploadStateTracker
3434
import org.matrix.android.sdk.api.session.content.ContentUrlResolver
3535
import org.matrix.android.sdk.api.session.crypto.CryptoService
36+
import org.matrix.android.sdk.api.session.events.EventService
3637
import org.matrix.android.sdk.api.session.file.ContentDownloadStateTracker
3738
import org.matrix.android.sdk.api.session.file.FileService
3839
import org.matrix.android.sdk.api.session.group.GroupService
@@ -114,6 +115,7 @@ internal class DefaultSession @Inject constructor(
114115
private val accountDataService: Lazy<AccountDataService>,
115116
private val _sharedSecretStorageService: Lazy<SharedSecretStorageService>,
116117
private val accountService: Lazy<AccountService>,
118+
private val eventService: Lazy<EventService>,
117119
private val defaultIdentityService: DefaultIdentityService,
118120
private val integrationManagerService: IntegrationManagerService,
119121
private val thirdPartyService: Lazy<ThirdPartyService>,
@@ -129,6 +131,7 @@ internal class DefaultSession @Inject constructor(
129131
FilterService by filterService.get(),
130132
PushRuleService by pushRuleService.get(),
131133
PushersService by pushersService.get(),
134+
EventService by eventService.get(),
132135
TermsService by termsService.get(),
133136
InitialSyncProgressService by initialSyncProgressService.get(),
134137
SecureStorageService by secureStorageService.get(),

matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/SessionModule.kt

+6-1
Original file line numberDiff line numberDiff line change
@@ -32,10 +32,11 @@ import org.matrix.android.sdk.api.auth.data.HomeServerConnectionConfig
3232
import org.matrix.android.sdk.api.auth.data.SessionParams
3333
import org.matrix.android.sdk.api.auth.data.sessionId
3434
import org.matrix.android.sdk.api.crypto.MXCryptoConfig
35-
import org.matrix.android.sdk.api.session.initsync.InitialSyncProgressService
3635
import org.matrix.android.sdk.api.session.Session
3736
import org.matrix.android.sdk.api.session.accountdata.AccountDataService
37+
import org.matrix.android.sdk.api.session.events.EventService
3838
import org.matrix.android.sdk.api.session.homeserver.HomeServerCapabilitiesService
39+
import org.matrix.android.sdk.api.session.initsync.InitialSyncProgressService
3940
import org.matrix.android.sdk.api.session.permalinks.PermalinkService
4041
import org.matrix.android.sdk.api.session.securestorage.SecureStorageService
4142
import org.matrix.android.sdk.api.session.securestorage.SharedSecretStorageService
@@ -75,6 +76,7 @@ import org.matrix.android.sdk.internal.network.token.AccessTokenProvider
7576
import org.matrix.android.sdk.internal.network.token.HomeserverAccessTokenProvider
7677
import org.matrix.android.sdk.internal.session.call.CallEventProcessor
7778
import org.matrix.android.sdk.internal.session.download.DownloadProgressInterceptor
79+
import org.matrix.android.sdk.internal.session.events.DefaultEventService
7880
import org.matrix.android.sdk.internal.session.homeserver.DefaultHomeServerCapabilitiesService
7981
import org.matrix.android.sdk.internal.session.identity.DefaultIdentityService
8082
import org.matrix.android.sdk.internal.session.initsync.DefaultInitialSyncProgressService
@@ -357,6 +359,9 @@ internal abstract class SessionModule {
357359
@Binds
358360
abstract fun bindAccountDataService(service: DefaultAccountDataService): AccountDataService
359361

362+
@Binds
363+
abstract fun bindEventService(service: DefaultEventService): EventService
364+
360365
@Binds
361366
abstract fun bindSharedSecretStorageService(service: DefaultSharedSecretStorageService): SharedSecretStorageService
362367

matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/call/CallEventProcessor.kt

+12-1
Original file line numberDiff line numberDiff line change
@@ -21,9 +21,11 @@ import org.matrix.android.sdk.api.session.events.model.Event
2121
import org.matrix.android.sdk.api.session.events.model.EventType
2222
import org.matrix.android.sdk.internal.database.model.EventInsertType
2323
import org.matrix.android.sdk.internal.session.EventInsertLiveProcessor
24+
import org.matrix.android.sdk.internal.session.SessionScope
2425
import timber.log.Timber
2526
import javax.inject.Inject
2627

28+
@SessionScope
2729
internal class CallEventProcessor @Inject constructor(private val callSignalingHandler: CallSignalingHandler)
2830
: EventInsertLiveProcessor {
2931

@@ -51,6 +53,15 @@ internal class CallEventProcessor @Inject constructor(private val callSignalingH
5153
eventsToPostProcess.add(event)
5254
}
5355

56+
fun shouldProcessFastLane(eventType: String): Boolean {
57+
return eventType == EventType.CALL_INVITE
58+
}
59+
60+
suspend fun processFastLane(event: Event) {
61+
eventsToPostProcess.add(event)
62+
onPostProcess()
63+
}
64+
5465
override suspend fun onPostProcess() {
5566
eventsToPostProcess.forEach {
5667
dispatchToCallSignalingHandlerIfNeeded(it)
@@ -60,7 +71,7 @@ internal class CallEventProcessor @Inject constructor(private val callSignalingH
6071

6172
private fun dispatchToCallSignalingHandlerIfNeeded(event: Event) {
6273
val now = System.currentTimeMillis()
63-
// TODO might check if an invite is not closed (hangup/answsered) in the same event batch?
74+
// TODO might check if an invite is not closed (hangup/answered) in the same event batch?
6475
event.roomId ?: return Unit.also {
6576
Timber.w("Event with no room id ${event.eventId}")
6677
}

matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/call/CallSignalingHandler.kt

+14-6
Original file line numberDiff line numberDiff line change
@@ -56,25 +56,25 @@ internal class CallSignalingHandler @Inject constructor(private val activeCallHa
5656

5757
fun onCallEvent(event: Event) {
5858
when (event.getClearType()) {
59-
EventType.CALL_ANSWER -> {
59+
EventType.CALL_ANSWER -> {
6060
handleCallAnswerEvent(event)
6161
}
62-
EventType.CALL_INVITE -> {
62+
EventType.CALL_INVITE -> {
6363
handleCallInviteEvent(event)
6464
}
65-
EventType.CALL_HANGUP -> {
65+
EventType.CALL_HANGUP -> {
6666
handleCallHangupEvent(event)
6767
}
68-
EventType.CALL_REJECT -> {
68+
EventType.CALL_REJECT -> {
6969
handleCallRejectEvent(event)
7070
}
71-
EventType.CALL_CANDIDATES -> {
71+
EventType.CALL_CANDIDATES -> {
7272
handleCallCandidatesEvent(event)
7373
}
7474
EventType.CALL_SELECT_ANSWER -> {
7575
handleCallSelectAnswerEvent(event)
7676
}
77-
EventType.CALL_NEGOTIATE -> {
77+
EventType.CALL_NEGOTIATE -> {
7878
handleCallNegotiateEvent(event)
7979
}
8080
}
@@ -168,6 +168,14 @@ internal class CallSignalingHandler @Inject constructor(private val activeCallHa
168168
return
169169
}
170170
val content = event.getClearContent().toModel<CallInviteContent>() ?: return
171+
172+
content.callId ?: return
173+
if (activeCallHandler.getCallWithId(content.callId) != null) {
174+
// Call is already known, maybe due to fast lane. Ignore
175+
Timber.d("Ignoring already known call invite")
176+
return
177+
}
178+
171179
val incomingCall = mxCallFactory.createIncomingCall(
172180
roomId = event.roomId,
173181
opponentUserId = event.senderId,
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
/*
2+
* Copyright (c) 2021 The Matrix.org Foundation C.I.C.
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 org.matrix.android.sdk.internal.session.events
18+
19+
import org.matrix.android.sdk.api.session.events.EventService
20+
import org.matrix.android.sdk.api.session.events.model.Event
21+
import org.matrix.android.sdk.internal.session.call.CallEventProcessor
22+
import org.matrix.android.sdk.internal.session.room.timeline.GetEventTask
23+
import javax.inject.Inject
24+
25+
internal class DefaultEventService @Inject constructor(
26+
private val getEventTask: GetEventTask,
27+
private val callEventProcessor: CallEventProcessor
28+
) : EventService {
29+
30+
override suspend fun getEvent(roomId: String, eventId: String): Event {
31+
val event = getEventTask.execute(GetEventTask.Params(roomId, eventId))
32+
33+
// Fast lane to the call event processors: try to make the incoming call ring faster
34+
if (callEventProcessor.shouldProcessFastLane(event.getClearType())) {
35+
callEventProcessor.processFastLane(event)
36+
}
37+
38+
return event
39+
}
40+
}

matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/RoomModule.kt

+5
Original file line numberDiff line numberDiff line change
@@ -79,9 +79,11 @@ import org.matrix.android.sdk.internal.session.room.tags.DefaultDeleteTagFromRoo
7979
import org.matrix.android.sdk.internal.session.room.tags.DeleteTagFromRoomTask
8080
import org.matrix.android.sdk.internal.session.room.timeline.DefaultFetchTokenAndPaginateTask
8181
import org.matrix.android.sdk.internal.session.room.timeline.DefaultGetContextOfEventTask
82+
import org.matrix.android.sdk.internal.session.room.timeline.DefaultGetEventTask
8283
import org.matrix.android.sdk.internal.session.room.timeline.DefaultPaginationTask
8384
import org.matrix.android.sdk.internal.session.room.timeline.FetchTokenAndPaginateTask
8485
import org.matrix.android.sdk.internal.session.room.timeline.GetContextOfEventTask
86+
import org.matrix.android.sdk.internal.session.room.timeline.GetEventTask
8587
import org.matrix.android.sdk.internal.session.room.timeline.PaginationTask
8688
import org.matrix.android.sdk.internal.session.room.typing.DefaultSendTypingTask
8789
import org.matrix.android.sdk.internal.session.room.typing.SendTypingTask
@@ -228,4 +230,7 @@ internal abstract class RoomModule {
228230

229231
@Binds
230232
abstract fun bindPeekRoomTask(task: DefaultPeekRoomTask): PeekRoomTask
233+
234+
@Binds
235+
abstract fun bindGetEventTask(task: DefaultGetEventTask): GetEventTask
231236
}

matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/timeline/GetEventTask.kt

+32-11
Original file line numberDiff line numberDiff line change
@@ -16,28 +16,49 @@
1616

1717
package org.matrix.android.sdk.internal.session.room.timeline
1818

19+
import org.matrix.android.sdk.api.extensions.tryOrNull
1920
import org.matrix.android.sdk.api.session.events.model.Event
21+
import org.matrix.android.sdk.internal.crypto.EventDecryptor
22+
import org.matrix.android.sdk.internal.crypto.algorithms.olm.OlmDecryptionResult
2023
import org.matrix.android.sdk.internal.network.GlobalErrorReceiver
2124
import org.matrix.android.sdk.internal.network.executeRequest
2225
import org.matrix.android.sdk.internal.session.room.RoomAPI
2326
import org.matrix.android.sdk.internal.task.Task
2427
import javax.inject.Inject
2528

26-
// TODO Add parent task
27-
28-
internal class GetEventTask @Inject constructor(
29-
private val roomAPI: RoomAPI,
30-
private val globalErrorReceiver: GlobalErrorReceiver
31-
) : Task<GetEventTask.Params, Event> {
32-
33-
internal data class Params(
29+
internal interface GetEventTask : Task<GetEventTask.Params, Event> {
30+
data class Params(
3431
val roomId: String,
35-
val eventId: String
32+
val eventId: String,
3633
)
34+
}
3735

38-
override suspend fun execute(params: Params): Event {
39-
return executeRequest(globalErrorReceiver) {
36+
internal class DefaultGetEventTask @Inject constructor(
37+
private val roomAPI: RoomAPI,
38+
private val globalErrorReceiver: GlobalErrorReceiver,
39+
private val eventDecryptor: EventDecryptor
40+
) : GetEventTask {
41+
42+
override suspend fun execute(params: GetEventTask.Params): Event {
43+
val event = executeRequest(globalErrorReceiver) {
4044
roomAPI.getEvent(params.roomId, params.eventId)
4145
}
46+
47+
// Try to decrypt the Event
48+
if (event.isEncrypted()) {
49+
tryOrNull(message = "Unable to decrypt the event") {
50+
eventDecryptor.decryptEvent(event, "")
51+
}
52+
?.let { result ->
53+
event.mxDecryptionResult = OlmDecryptionResult(
54+
payload = result.clearEvent,
55+
senderKey = result.senderCurve25519Key,
56+
keysClaimed = result.claimedEd25519Key?.let { mapOf("ed25519" to it) },
57+
forwardingCurve25519KeyChain = result.forwardingCurve25519KeyChain
58+
)
59+
}
60+
}
61+
62+
return event
4263
}
4364
}

0 commit comments

Comments
 (0)