From 9b332f7a32f0d81126c94c481b5997da24f46724 Mon Sep 17 00:00:00 2001 From: Onuray Sahin Date: Mon, 14 Dec 2020 17:32:54 +0300 Subject: [PATCH 01/41] Test message decryption in a room with 3 members. --- .../timeline/TimelineWithManyMembersTest.kt | 94 +++++++++++++++++++ 1 file changed, 94 insertions(+) create mode 100644 matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/session/room/timeline/TimelineWithManyMembersTest.kt diff --git a/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/session/room/timeline/TimelineWithManyMembersTest.kt b/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/session/room/timeline/TimelineWithManyMembersTest.kt new file mode 100644 index 0000000000..a0271cb5b9 --- /dev/null +++ b/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/session/room/timeline/TimelineWithManyMembersTest.kt @@ -0,0 +1,94 @@ +/* + * Copyright (c) 2020 New Vector Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.matrix.android.sdk.session.room.timeline + +import org.junit.FixMethodOrder +import org.junit.Test +import org.junit.runner.RunWith +import org.junit.runners.JUnit4 +import org.junit.runners.MethodSorters +import org.matrix.android.sdk.InstrumentedTest +import org.matrix.android.sdk.api.extensions.orFalse +import org.matrix.android.sdk.api.session.events.model.toModel +import org.matrix.android.sdk.api.session.room.model.message.MessageContent +import org.matrix.android.sdk.api.session.room.timeline.TimelineSettings +import org.matrix.android.sdk.common.CommonTestHelper +import org.matrix.android.sdk.common.CryptoTestHelper +import java.util.concurrent.CountDownLatch + +@RunWith(JUnit4::class) +@FixMethodOrder(MethodSorters.JVM) +class TimelineWithManyMembersTest : InstrumentedTest { + + private val commonTestHelper = CommonTestHelper(context()) + private val cryptoTestHelper = CryptoTestHelper(commonTestHelper) + + /** + * Ensures when someone sends a message to a crowded room, everyone can decrypt the message. + */ + @Test + fun everyoneShouldDecryptMessage3Members() { + val cryptoTestData = cryptoTestHelper.doE2ETestWithAliceAndBobAndSamInARoom() + + val aliceSession = cryptoTestData.firstSession + val bobSession = cryptoTestData.secondSession!! + val samSession = cryptoTestData.thirdSession!! + + val aliceRoomId = cryptoTestData.roomId + + aliceSession.cryptoService().setWarnOnUnknownDevices(false) + bobSession.cryptoService().setWarnOnUnknownDevices(false) + samSession.cryptoService().setWarnOnUnknownDevices(false) + + val roomFromAlicePOV = aliceSession.getRoom(aliceRoomId)!! + val roomFromBobPOV = bobSession.getRoom(aliceRoomId)!! + val roomFromSamPOV = samSession.getRoom(aliceRoomId)!! + + val bobTimeline = roomFromBobPOV.createTimeline(null, TimelineSettings(30)) + val samTimeline = roomFromSamPOV.createTimeline(null, TimelineSettings(30)) + bobTimeline.start() + samTimeline.start() + + val firstMessage = "First messages from Alice" + commonTestHelper.sendTextMessage( + roomFromAlicePOV, + firstMessage, + 1) + + bobSession.startSync(true) + run { + val lock = CountDownLatch(1) + val eventsListener = commonTestHelper.createEventListener(lock) { snapshot -> + snapshot.firstOrNull()?.root?.getClearContent()?.toModel()?.body?.startsWith(firstMessage).orFalse() + } + bobTimeline.addListener(eventsListener) + commonTestHelper.await(lock) + } + bobSession.stopSync() + + samSession.startSync(true) + run { + val lock = CountDownLatch(1) + val eventsListener = commonTestHelper.createEventListener(lock) { snapshot -> + snapshot.firstOrNull()?.root?.getClearContent()?.toModel()?.body?.startsWith(firstMessage).orFalse() + } + samTimeline.addListener(eventsListener) + commonTestHelper.await(lock) + } + samSession.stopSync() + } +} From 7e4725c091246c3bb97fb7e45863d31a3b637f1c Mon Sep 17 00:00:00 2001 From: Onuray Sahin Date: Mon, 14 Dec 2020 18:07:20 +0300 Subject: [PATCH 02/41] Update CryptoTestData to handle more than 3 sessions. --- .../android/sdk/common/CryptoTestData.kt | 21 ++++++++++++------- .../android/sdk/common/CryptoTestHelper.kt | 6 +++--- 2 files changed, 17 insertions(+), 10 deletions(-) diff --git a/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/common/CryptoTestData.kt b/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/common/CryptoTestData.kt index 76e59d9a90..e01aaef639 100644 --- a/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/common/CryptoTestData.kt +++ b/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/common/CryptoTestData.kt @@ -18,14 +18,21 @@ package org.matrix.android.sdk.common import org.matrix.android.sdk.api.session.Session -data class CryptoTestData(val firstSession: Session, - val roomId: String, - val secondSession: Session? = null, - val thirdSession: Session? = null) { +data class CryptoTestData(val roomId: String, + val sessions: List = emptyList()) { + + val firstSession: Session + get() = sessions.first() + + val secondSession: Session? + get() = sessions.getOrNull(1) + + val thirdSession: Session? + get() = sessions.getOrNull(2) fun cleanUp(testHelper: CommonTestHelper) { - testHelper.signOutAndClose(firstSession) - secondSession?.let { testHelper.signOutAndClose(it) } - thirdSession?.let { testHelper.signOutAndClose(it) } + sessions.forEach { + testHelper.signOutAndClose(it) + } } } diff --git a/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/common/CryptoTestHelper.kt b/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/common/CryptoTestHelper.kt index cbb22daf0f..f108cbb105 100644 --- a/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/common/CryptoTestHelper.kt +++ b/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/common/CryptoTestHelper.kt @@ -73,7 +73,7 @@ class CryptoTestHelper(private val mTestHelper: CommonTestHelper) { } } - return CryptoTestData(aliceSession, roomId) + return CryptoTestData(roomId, listOf(aliceSession)) } /** @@ -139,7 +139,7 @@ class CryptoTestHelper(private val mTestHelper: CommonTestHelper) { // assertNotNull(roomFromBobPOV.powerLevels) // assertTrue(roomFromBobPOV.powerLevels.maySendMessage(bobSession.myUserId)) - return CryptoTestData(aliceSession, aliceRoomId, bobSession) + return CryptoTestData(aliceRoomId, listOf(aliceSession, bobSession)) } /** @@ -157,7 +157,7 @@ class CryptoTestHelper(private val mTestHelper: CommonTestHelper) { // wait the initial sync SystemClock.sleep(1000) - return CryptoTestData(aliceSession, aliceRoomId, cryptoTestData.secondSession, samSession) + return CryptoTestData(aliceRoomId, listOf(aliceSession, cryptoTestData.secondSession!!, samSession)) } /** From 427dc784fe2d1f131be8e29f930efb70fb74a4e6 Mon Sep 17 00:00:00 2001 From: Onuray Sahin Date: Tue, 15 Dec 2020 16:50:49 +0300 Subject: [PATCH 03/41] Support testing a room with many members. --- .../android/sdk/common/CryptoTestData.kt | 2 +- .../android/sdk/common/CryptoTestHelper.kt | 33 ++++++++++++-- .../timeline/TimelineWithManyMembersTest.kt | 43 +++++++++++++++++++ 3 files changed, 74 insertions(+), 4 deletions(-) diff --git a/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/common/CryptoTestData.kt b/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/common/CryptoTestData.kt index e01aaef639..693ab28da1 100644 --- a/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/common/CryptoTestData.kt +++ b/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/common/CryptoTestData.kt @@ -19,7 +19,7 @@ package org.matrix.android.sdk.common import org.matrix.android.sdk.api.session.Session data class CryptoTestData(val roomId: String, - val sessions: List = emptyList()) { + val sessions: MutableList = mutableListOf()) { val firstSession: Session get() = sessions.first() diff --git a/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/common/CryptoTestHelper.kt b/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/common/CryptoTestHelper.kt index f108cbb105..66fc1348d5 100644 --- a/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/common/CryptoTestHelper.kt +++ b/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/common/CryptoTestHelper.kt @@ -73,7 +73,7 @@ class CryptoTestHelper(private val mTestHelper: CommonTestHelper) { } } - return CryptoTestData(roomId, listOf(aliceSession)) + return CryptoTestData(roomId, mutableListOf(aliceSession)) } /** @@ -139,7 +139,7 @@ class CryptoTestHelper(private val mTestHelper: CommonTestHelper) { // assertNotNull(roomFromBobPOV.powerLevels) // assertTrue(roomFromBobPOV.powerLevels.maySendMessage(bobSession.myUserId)) - return CryptoTestData(aliceRoomId, listOf(aliceSession, bobSession)) + return CryptoTestData(aliceRoomId, mutableListOf(aliceSession, bobSession)) } /** @@ -157,7 +157,7 @@ class CryptoTestHelper(private val mTestHelper: CommonTestHelper) { // wait the initial sync SystemClock.sleep(1000) - return CryptoTestData(aliceRoomId, listOf(aliceSession, cryptoTestData.secondSession!!, samSession)) + return CryptoTestData(aliceRoomId, mutableListOf(aliceSession, cryptoTestData.secondSession!!, samSession)) } /** @@ -381,4 +381,31 @@ class CryptoTestHelper(private val mTestHelper: CommonTestHelper) { } } } + + fun doE2ETestWithManyMembers(numberOfMembers: Int): CryptoTestData { + val aliceSession = mTestHelper.createAccount(TestConstants.USER_ALICE, defaultSessionParams) + aliceSession.cryptoService().setWarnOnUnknownDevices(false) + + val roomId = mTestHelper.doSync { + aliceSession.createRoom(CreateRoomParams().apply { name = "MyRoom" }, it) + } + val room = aliceSession.getRoom(roomId)!! + + mTestHelper.runBlockingTest { + room.enableEncryption() + } + + val cryptoTestData = CryptoTestData(roomId, mutableListOf(aliceSession)) + for (index in 1 until numberOfMembers) { + mTestHelper + .createAccount("User_$index", defaultSessionParams) + .also { session -> mTestHelper.doSync { room.invite(session.myUserId, null, it) } } + .also { println("TEST -> " + it.myUserId + " invited") } + .also { session -> mTestHelper.doSync { session.joinRoom(room.roomId, null, emptyList(), it) } } + .also { println("TEST -> " + it.myUserId + " joined") } + .also { session -> cryptoTestData.sessions.add(session) } + } + + return cryptoTestData + } } diff --git a/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/session/room/timeline/TimelineWithManyMembersTest.kt b/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/session/room/timeline/TimelineWithManyMembersTest.kt index a0271cb5b9..1a397c1d1c 100644 --- a/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/session/room/timeline/TimelineWithManyMembersTest.kt +++ b/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/session/room/timeline/TimelineWithManyMembersTest.kt @@ -16,6 +16,8 @@ package org.matrix.android.sdk.session.room.timeline +import android.os.SystemClock +import android.util.Log import org.junit.FixMethodOrder import org.junit.Test import org.junit.runner.RunWith @@ -29,11 +31,14 @@ import org.matrix.android.sdk.api.session.room.timeline.TimelineSettings import org.matrix.android.sdk.common.CommonTestHelper import org.matrix.android.sdk.common.CryptoTestHelper import java.util.concurrent.CountDownLatch +import kotlin.test.assertEquals @RunWith(JUnit4::class) @FixMethodOrder(MethodSorters.JVM) class TimelineWithManyMembersTest : InstrumentedTest { + private val NUMBER_OF_MEMBERS = 5 + private val commonTestHelper = CommonTestHelper(context()) private val cryptoTestHelper = CryptoTestHelper(commonTestHelper) @@ -91,4 +96,42 @@ class TimelineWithManyMembersTest : InstrumentedTest { } samSession.stopSync() } + + /** + * Ensures when someone sends a message to a crowded room, everyone can decrypt the message. + */ + @Test + fun everyone_should_decrypt_message_in_a_crowded_room() { + val cryptoTestData = cryptoTestHelper.doE2ETestWithManyMembers(NUMBER_OF_MEMBERS) + + val sessionForFirstMember = cryptoTestData.firstSession + val roomForFirstMember = sessionForFirstMember.getRoom(cryptoTestData.roomId)!! + + val firstMessage = "First messages from Alice" + commonTestHelper.sendTextMessage( + roomForFirstMember, + firstMessage, + 1) + + for (index in 1 until cryptoTestData.sessions.size) { + val session = cryptoTestData.sessions[index] + val roomForCurrentMember = session.getRoom(cryptoTestData.roomId)!! + val timelineForCurrentMember = roomForCurrentMember.createTimeline(null, TimelineSettings(30)) + timelineForCurrentMember.start() + + session.startSync(true) + + run { + val lock = CountDownLatch(1) + val eventsListener = commonTestHelper.createEventListener(lock) { snapshot -> + val decryptedMessage = snapshot.firstOrNull()?.root?.getClearContent()?.toModel()?.body + println("Decrypted Message: $decryptedMessage") + return@createEventListener decryptedMessage?.startsWith(firstMessage).orFalse() + } + timelineForCurrentMember.addListener(eventsListener) + commonTestHelper.await(lock) + } + session.stopSync() + } + } } From b263273c878806ba3f474380f438349c7f8b70ac Mon Sep 17 00:00:00 2001 From: Onuray Sahin Date: Wed, 16 Dec 2020 13:45:26 +0300 Subject: [PATCH 04/41] Improve test with detailed CryptoError message. --- .../android/sdk/common/CommonTestHelper.kt | 4 ++-- .../android/sdk/common/CryptoTestHelper.kt | 2 +- .../timeline/TimelineWithManyMembersTest.kt | 23 ++++++++++++------- 3 files changed, 18 insertions(+), 11 deletions(-) diff --git a/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/common/CommonTestHelper.kt b/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/common/CommonTestHelper.kt index 0e7088a6a5..7dcf43ba0f 100644 --- a/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/common/CommonTestHelper.kt +++ b/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/common/CommonTestHelper.kt @@ -119,7 +119,7 @@ class CommonTestHelper(context: Context) { * @param message the message to send * @param nbOfMessages the number of time the message will be sent */ - fun sendTextMessage(room: Room, message: String, nbOfMessages: Int): List { + fun sendTextMessage(room: Room, message: String, nbOfMessages: Int, timeout: Long = TestConstants.timeOutMillis): List { val timeline = room.createTimeline(null, TimelineSettings(10)) val sentEvents = ArrayList(nbOfMessages) val latch = CountDownLatch(1) @@ -151,7 +151,7 @@ class CommonTestHelper(context: Context) { room.sendTextMessage(message + " #" + (i + 1)) } // Wait 3 second more per message - await(latch, timeout = TestConstants.timeOutMillis + 3_000L * nbOfMessages) + await(latch, timeout = timeout + 3_000L * nbOfMessages) timeline.dispose() // Check that all events has been created diff --git a/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/common/CryptoTestHelper.kt b/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/common/CryptoTestHelper.kt index 66fc1348d5..5d3407dde1 100644 --- a/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/common/CryptoTestHelper.kt +++ b/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/common/CryptoTestHelper.kt @@ -399,7 +399,7 @@ class CryptoTestHelper(private val mTestHelper: CommonTestHelper) { for (index in 1 until numberOfMembers) { mTestHelper .createAccount("User_$index", defaultSessionParams) - .also { session -> mTestHelper.doSync { room.invite(session.myUserId, null, it) } } + .also { session -> mTestHelper.doSync(timeout = 600_000) { room.invite(session.myUserId, null, it) } } .also { println("TEST -> " + it.myUserId + " invited") } .also { session -> mTestHelper.doSync { session.joinRoom(room.roomId, null, emptyList(), it) } } .also { println("TEST -> " + it.myUserId + " joined") } diff --git a/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/session/room/timeline/TimelineWithManyMembersTest.kt b/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/session/room/timeline/TimelineWithManyMembersTest.kt index 1a397c1d1c..dacde121b3 100644 --- a/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/session/room/timeline/TimelineWithManyMembersTest.kt +++ b/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/session/room/timeline/TimelineWithManyMembersTest.kt @@ -16,8 +16,6 @@ package org.matrix.android.sdk.session.room.timeline -import android.os.SystemClock -import android.util.Log import org.junit.FixMethodOrder import org.junit.Test import org.junit.runner.RunWith @@ -31,7 +29,7 @@ import org.matrix.android.sdk.api.session.room.timeline.TimelineSettings import org.matrix.android.sdk.common.CommonTestHelper import org.matrix.android.sdk.common.CryptoTestHelper import java.util.concurrent.CountDownLatch -import kotlin.test.assertEquals +import kotlin.test.fail @RunWith(JUnit4::class) @FixMethodOrder(MethodSorters.JVM) @@ -111,7 +109,9 @@ class TimelineWithManyMembersTest : InstrumentedTest { commonTestHelper.sendTextMessage( roomForFirstMember, firstMessage, - 1) + 1, + 600_000 + ) for (index in 1 until cryptoTestData.sessions.size) { val session = cryptoTestData.sessions[index] @@ -124,12 +124,19 @@ class TimelineWithManyMembersTest : InstrumentedTest { run { val lock = CountDownLatch(1) val eventsListener = commonTestHelper.createEventListener(lock) { snapshot -> - val decryptedMessage = snapshot.firstOrNull()?.root?.getClearContent()?.toModel()?.body - println("Decrypted Message: $decryptedMessage") - return@createEventListener decryptedMessage?.startsWith(firstMessage).orFalse() + snapshot + .find { it.isEncrypted() } + ?.let { + val body = it.root.getClearContent()?.toModel()?.body + if (body?.startsWith(firstMessage).orFalse()) { + return@createEventListener true + } else { + fail("User " + session.myUserId + " decrypted as " + body + " CryptoError: " + it.root.mCryptoError) + } + } ?: return@createEventListener false } timelineForCurrentMember.addListener(eventsListener) - commonTestHelper.await(lock) + commonTestHelper.await(lock, 600_000) } session.stopSync() } From 7b97981bb57ad7b651700ecacc878f4c1324967f Mon Sep 17 00:00:00 2001 From: Onuray Sahin Date: Wed, 16 Dec 2020 15:45:50 +0300 Subject: [PATCH 05/41] Make sure to load all members in the room before sending the event. --- .../android/sdk/common/CommonTestHelper.kt | 10 ++-- .../timeline/TimelineWithManyMembersTest.kt | 58 +------------------ .../internal/crypto/tasks/SendEventTask.kt | 9 +++ 3 files changed, 16 insertions(+), 61 deletions(-) diff --git a/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/common/CommonTestHelper.kt b/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/common/CommonTestHelper.kt index 7dcf43ba0f..cb49ee8818 100644 --- a/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/common/CommonTestHelper.kt +++ b/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/common/CommonTestHelper.kt @@ -86,7 +86,7 @@ class CommonTestHelper(context: Context) { * * @param session the session to sync */ - fun syncSession(session: Session) { + fun syncSession(session: Session, timeout: Long = TestConstants.timeOutMillis) { val lock = CountDownLatch(1) val job = GlobalScope.launch(Dispatchers.Main) { @@ -109,7 +109,7 @@ class CommonTestHelper(context: Context) { } GlobalScope.launch(Dispatchers.Main) { syncLiveData.observeForever(syncObserver) } - await(lock) + await(lock, timeout) } /** @@ -215,14 +215,14 @@ class CommonTestHelper(context: Context) { .getLoginFlow(hs, it) } - doSync { + doSync(timeout = 60_000) { matrix.authenticationService .getRegistrationWizard() .createAccount(userName, password, null, it) } // Perform dummy step - val registrationResult = doSync { + val registrationResult = doSync(timeout = 60_000) { matrix.authenticationService .getRegistrationWizard() .dummy(it) @@ -231,7 +231,7 @@ class CommonTestHelper(context: Context) { assertTrue(registrationResult is RegistrationResult.Success) val session = (registrationResult as RegistrationResult.Success).session if (sessionTestParams.withInitialSync) { - syncSession(session) + syncSession(session, 60_000) } return session diff --git a/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/session/room/timeline/TimelineWithManyMembersTest.kt b/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/session/room/timeline/TimelineWithManyMembersTest.kt index dacde121b3..ca74acdee7 100644 --- a/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/session/room/timeline/TimelineWithManyMembersTest.kt +++ b/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/session/room/timeline/TimelineWithManyMembersTest.kt @@ -35,66 +35,11 @@ import kotlin.test.fail @FixMethodOrder(MethodSorters.JVM) class TimelineWithManyMembersTest : InstrumentedTest { - private val NUMBER_OF_MEMBERS = 5 + private val NUMBER_OF_MEMBERS = 6 private val commonTestHelper = CommonTestHelper(context()) private val cryptoTestHelper = CryptoTestHelper(commonTestHelper) - /** - * Ensures when someone sends a message to a crowded room, everyone can decrypt the message. - */ - @Test - fun everyoneShouldDecryptMessage3Members() { - val cryptoTestData = cryptoTestHelper.doE2ETestWithAliceAndBobAndSamInARoom() - - val aliceSession = cryptoTestData.firstSession - val bobSession = cryptoTestData.secondSession!! - val samSession = cryptoTestData.thirdSession!! - - val aliceRoomId = cryptoTestData.roomId - - aliceSession.cryptoService().setWarnOnUnknownDevices(false) - bobSession.cryptoService().setWarnOnUnknownDevices(false) - samSession.cryptoService().setWarnOnUnknownDevices(false) - - val roomFromAlicePOV = aliceSession.getRoom(aliceRoomId)!! - val roomFromBobPOV = bobSession.getRoom(aliceRoomId)!! - val roomFromSamPOV = samSession.getRoom(aliceRoomId)!! - - val bobTimeline = roomFromBobPOV.createTimeline(null, TimelineSettings(30)) - val samTimeline = roomFromSamPOV.createTimeline(null, TimelineSettings(30)) - bobTimeline.start() - samTimeline.start() - - val firstMessage = "First messages from Alice" - commonTestHelper.sendTextMessage( - roomFromAlicePOV, - firstMessage, - 1) - - bobSession.startSync(true) - run { - val lock = CountDownLatch(1) - val eventsListener = commonTestHelper.createEventListener(lock) { snapshot -> - snapshot.firstOrNull()?.root?.getClearContent()?.toModel()?.body?.startsWith(firstMessage).orFalse() - } - bobTimeline.addListener(eventsListener) - commonTestHelper.await(lock) - } - bobSession.stopSync() - - samSession.startSync(true) - run { - val lock = CountDownLatch(1) - val eventsListener = commonTestHelper.createEventListener(lock) { snapshot -> - snapshot.firstOrNull()?.root?.getClearContent()?.toModel()?.body?.startsWith(firstMessage).orFalse() - } - samTimeline.addListener(eventsListener) - commonTestHelper.await(lock) - } - samSession.stopSync() - } - /** * Ensures when someone sends a message to a crowded room, everyone can decrypt the message. */ @@ -129,6 +74,7 @@ class TimelineWithManyMembersTest : InstrumentedTest { ?.let { val body = it.root.getClearContent()?.toModel()?.body if (body?.startsWith(firstMessage).orFalse()) { + println("User " + session.myUserId + " decrypted as " + body) return@createEventListener true } else { fail("User " + session.myUserId + " decrypted as " + body + " CryptoError: " + it.root.mCryptoError) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/tasks/SendEventTask.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/tasks/SendEventTask.kt index 8b739c4b64..5c8c7dfb25 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/tasks/SendEventTask.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/tasks/SendEventTask.kt @@ -20,6 +20,7 @@ import org.matrix.android.sdk.api.session.events.model.Event import org.matrix.android.sdk.api.session.room.send.SendState import org.matrix.android.sdk.internal.network.executeRequest import org.matrix.android.sdk.internal.session.room.RoomAPI +import org.matrix.android.sdk.internal.session.room.membership.LoadRoomMembersTask import org.matrix.android.sdk.internal.session.room.send.LocalEchoRepository import org.matrix.android.sdk.internal.session.room.send.SendResponse import org.matrix.android.sdk.internal.task.Task @@ -35,11 +36,19 @@ internal interface SendEventTask : Task { internal class DefaultSendEventTask @Inject constructor( private val localEchoRepository: LocalEchoRepository, private val encryptEventTask: DefaultEncryptEventTask, + private val loadRoomMembersTask: LoadRoomMembersTask, private val roomAPI: RoomAPI, private val eventBus: EventBus) : SendEventTask { override suspend fun execute(params: SendEventTask.Params): String { try { + // Make sure to load all members in the room before sending the event. + params.event.roomId + ?.takeIf { params.encrypt } + ?.let { roomId -> + loadRoomMembersTask.execute(LoadRoomMembersTask.Params(roomId)) + } + val event = handleEncryption(params) val localId = event.eventId!! From 80396fcd391d195be206dedd914115fd6bc8722c Mon Sep 17 00:00:00 2001 From: Onuray Sahin Date: Wed, 16 Dec 2020 15:46:14 +0300 Subject: [PATCH 06/41] Changelog added. --- CHANGES.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGES.md b/CHANGES.md index 0fb7d72c13..9ab5276ff3 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -57,6 +57,7 @@ Bugfix 🐛: - No known servers error is given when joining rooms on new Gitter bridge (#2516) - Show preview when sending attachment from the keyboard (#2440) - Do not compress GIFs (#1616, #1254) + - Wait for all room members to be known before sending a message to a e2e room (#2518) SDK API changes ⚠️: - StateService now exposes suspendable function instead of using MatrixCallback. From 938cd32ddd97a3608a1497d0cf83b97150a33a3a Mon Sep 17 00:00:00 2001 From: Onuray Sahin Date: Thu, 17 Dec 2020 18:25:40 +0300 Subject: [PATCH 07/41] Do not load room members if there is an ongoing request. --- .../database/RealmSessionStoreMigration.kt | 18 ++++++++++++++- .../sdk/internal/database/model/RoomEntity.kt | 10 +++++++- .../model/RoomMembersLoadStatusType.java | 23 +++++++++++++++++++ .../room/membership/LoadRoomMembersTask.kt | 5 ++-- 4 files changed, 52 insertions(+), 4 deletions(-) create mode 100644 matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/model/RoomMembersLoadStatusType.java diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/RealmSessionStoreMigration.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/RealmSessionStoreMigration.kt index b970ec60e2..fd922ef0e5 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/RealmSessionStoreMigration.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/RealmSessionStoreMigration.kt @@ -21,6 +21,7 @@ import io.realm.RealmMigration import org.matrix.android.sdk.internal.database.model.HomeServerCapabilitiesEntityFields import org.matrix.android.sdk.internal.database.model.PendingThreePidEntityFields import org.matrix.android.sdk.internal.database.model.PreviewUrlCacheEntityFields +import org.matrix.android.sdk.internal.database.model.RoomMembersLoadStatusType import org.matrix.android.sdk.internal.database.model.RoomSummaryEntityFields import timber.log.Timber import javax.inject.Inject @@ -28,7 +29,7 @@ import javax.inject.Inject class RealmSessionStoreMigration @Inject constructor() : RealmMigration { companion object { - const val SESSION_STORE_SCHEMA_VERSION = 6L + const val SESSION_STORE_SCHEMA_VERSION = 7L } override fun migrate(realm: DynamicRealm, oldVersion: Long, newVersion: Long) { @@ -40,6 +41,7 @@ class RealmSessionStoreMigration @Inject constructor() : RealmMigration { if (oldVersion <= 3) migrateTo4(realm) if (oldVersion <= 4) migrateTo5(realm) if (oldVersion <= 5) migrateTo6(realm) + if (oldVersion <= 6) migrateTo7(realm) } private fun migrateTo1(realm: DynamicRealm) { @@ -105,4 +107,18 @@ class RealmSessionStoreMigration @Inject constructor() : RealmMigration { .addField(PreviewUrlCacheEntityFields.MXC_URL, String::class.java) .addField(PreviewUrlCacheEntityFields.LAST_UPDATED_TIMESTAMP, Long::class.java) } + + private fun migrateTo7(realm: DynamicRealm) { + Timber.d("Step 6 -> 7") + realm.schema.get("RoomEntity") + ?.addField("membersLoadStatusStr", String::class.java) + ?.transform { obj -> + if (obj.getBoolean("areAllMembersLoaded")) { + obj.setString("membersLoadStatusStr", RoomMembersLoadStatusType.LOADED.name) + } else { + obj.setString("membersLoadStatusStr", RoomMembersLoadStatusType.NONE.name) + } + } + ?.removeField("areAllMembersLoaded") + } } diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/model/RoomEntity.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/model/RoomEntity.kt index 9af1646a4c..a0a6060d36 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/model/RoomEntity.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/model/RoomEntity.kt @@ -24,7 +24,6 @@ import io.realm.annotations.PrimaryKey internal open class RoomEntity(@PrimaryKey var roomId: String = "", var chunks: RealmList = RealmList(), var sendingTimelineEvents: RealmList = RealmList(), - var areAllMembersLoaded: Boolean = false ) : RealmObject() { private var membershipStr: String = Membership.NONE.name @@ -36,5 +35,14 @@ internal open class RoomEntity(@PrimaryKey var roomId: String = "", membershipStr = value.name } + private var membersLoadStatusStr: String = RoomMembersLoadStatusType.NONE.name + var membersLoadStatus: RoomMembersLoadStatusType + get() { + return RoomMembersLoadStatusType.valueOf(membersLoadStatusStr) + } + set(value) { + membersLoadStatusStr = value.name + } + companion object } diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/model/RoomMembersLoadStatusType.java b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/model/RoomMembersLoadStatusType.java new file mode 100644 index 0000000000..d7063082bb --- /dev/null +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/model/RoomMembersLoadStatusType.java @@ -0,0 +1,23 @@ +/* + * Copyright 2020 The Matrix.org Foundation C.I.C. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.matrix.android.sdk.internal.database.model; + +public enum RoomMembersLoadStatusType { + NONE, + LOADING, + LOADED +} diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/membership/LoadRoomMembersTask.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/membership/LoadRoomMembersTask.kt index 627f927ad8..69530c5c0e 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/membership/LoadRoomMembersTask.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/membership/LoadRoomMembersTask.kt @@ -36,6 +36,7 @@ import org.matrix.android.sdk.internal.util.awaitTransaction import io.realm.Realm import io.realm.kotlin.createObject import org.greenrobot.eventbus.EventBus +import org.matrix.android.sdk.internal.database.model.RoomMembersLoadStatusType import javax.inject.Inject internal interface LoadRoomMembersTask : Task { @@ -84,14 +85,14 @@ internal class DefaultLoadRoomMembersTask @Inject constructor( } roomMemberEventHandler.handle(realm, roomId, roomMemberEvent) } - roomEntity.areAllMembersLoaded = true + roomEntity.membersLoadStatus = RoomMembersLoadStatusType.LOADED roomSummaryUpdater.update(realm, roomId, updateMembers = true) } } private fun areAllMembersAlreadyLoaded(roomId: String): Boolean { return Realm.getInstance(monarchy.realmConfiguration).use { - RoomEntity.where(it, roomId).findFirst()?.areAllMembersLoaded ?: false + RoomEntity.where(it, roomId).findFirst()?.membersLoadStatus == RoomMembersLoadStatusType.LOADED } } } From 5d8f365520a0f48d94346d3e13b5fc431738e06c Mon Sep 17 00:00:00 2001 From: Onuray Sahin Date: Thu, 17 Dec 2020 18:55:31 +0300 Subject: [PATCH 08/41] Load room members seamlessly when timeline is starting. --- .../sdk/internal/database/model/RoomEntity.kt | 2 +- .../session/room/timeline/DefaultTimeline.kt | 12 +++++++++++- .../session/room/timeline/DefaultTimelineService.kt | 7 +++++-- .../features/home/room/detail/RoomDetailViewModel.kt | 2 -- 4 files changed, 17 insertions(+), 6 deletions(-) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/model/RoomEntity.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/model/RoomEntity.kt index a0a6060d36..3ff2532604 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/model/RoomEntity.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/model/RoomEntity.kt @@ -23,7 +23,7 @@ import io.realm.annotations.PrimaryKey internal open class RoomEntity(@PrimaryKey var roomId: String = "", var chunks: RealmList = RealmList(), - var sendingTimelineEvents: RealmList = RealmList(), + var sendingTimelineEvents: RealmList = RealmList() ) : RealmObject() { private var membershipStr: String = Membership.NONE.name diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/timeline/DefaultTimeline.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/timeline/DefaultTimeline.kt index 86b0497bd0..dd58529412 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/timeline/DefaultTimeline.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/timeline/DefaultTimeline.kt @@ -27,6 +27,7 @@ import org.greenrobot.eventbus.EventBus import org.greenrobot.eventbus.Subscribe import org.greenrobot.eventbus.ThreadMode import org.matrix.android.sdk.api.MatrixCallback +import org.matrix.android.sdk.api.NoOpMatrixCallback import org.matrix.android.sdk.api.extensions.orFalse import org.matrix.android.sdk.api.extensions.tryOrNull import org.matrix.android.sdk.api.session.events.model.EventType @@ -53,6 +54,7 @@ import org.matrix.android.sdk.internal.database.query.filterEvents import org.matrix.android.sdk.internal.database.query.findAllInRoomWithSendStates import org.matrix.android.sdk.internal.database.query.where import org.matrix.android.sdk.internal.database.query.whereRoomId +import org.matrix.android.sdk.internal.session.room.membership.LoadRoomMembersTask import org.matrix.android.sdk.internal.task.TaskExecutor import org.matrix.android.sdk.internal.task.configureWith import org.matrix.android.sdk.internal.util.Debouncer @@ -81,7 +83,8 @@ internal class DefaultTimeline( private val hiddenReadReceipts: TimelineHiddenReadReceipts, private val eventBus: EventBus, private val eventDecryptor: TimelineEventDecryptor, - private val realmSessionProvider: RealmSessionProvider + private val realmSessionProvider: RealmSessionProvider, + private val loadRoomMembersTask: LoadRoomMembersTask ) : Timeline, TimelineHiddenReadReceipts.Delegate { data class OnNewTimelineEvents(val roomId: String, val eventIds: List) @@ -184,6 +187,13 @@ internal class DefaultTimeline( if (settings.shouldHandleHiddenReadReceipts()) { hiddenReadReceipts.start(realm, filteredEvents, nonFilteredEvents, this) } + + loadRoomMembersTask + .configureWith(LoadRoomMembersTask.Params(roomId)) { + this.callback = NoOpMatrixCallback() + } + .executeBy(taskExecutor) + isReady.set(true) } } diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/timeline/DefaultTimelineService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/timeline/DefaultTimelineService.kt index 783aa53ddf..d02e906d00 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/timeline/DefaultTimelineService.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/timeline/DefaultTimelineService.kt @@ -39,6 +39,7 @@ import org.matrix.android.sdk.internal.database.model.TimelineEventEntity import org.matrix.android.sdk.internal.database.model.TimelineEventEntityFields import org.matrix.android.sdk.internal.database.query.where import org.matrix.android.sdk.internal.di.SessionDatabase +import org.matrix.android.sdk.internal.session.room.membership.LoadRoomMembersTask import org.matrix.android.sdk.internal.task.TaskExecutor internal class DefaultTimelineService @AssistedInject constructor(@Assisted private val roomId: String, @@ -51,7 +52,8 @@ internal class DefaultTimelineService @AssistedInject constructor(@Assisted priv private val paginationTask: PaginationTask, private val fetchTokenAndPaginateTask: FetchTokenAndPaginateTask, private val timelineEventMapper: TimelineEventMapper, - private val readReceiptsSummaryMapper: ReadReceiptsSummaryMapper + private val readReceiptsSummaryMapper: ReadReceiptsSummaryMapper, + private val loadRoomMembersTask: LoadRoomMembersTask ) : TimelineService { @AssistedInject.Factory @@ -73,7 +75,8 @@ internal class DefaultTimelineService @AssistedInject constructor(@Assisted priv eventBus = eventBus, eventDecryptor = eventDecryptor, fetchTokenAndPaginateTask = fetchTokenAndPaginateTask, - realmSessionProvider = realmSessionProvider + realmSessionProvider = realmSessionProvider, + loadRoomMembersTask = loadRoomMembersTask ) } diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/RoomDetailViewModel.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/RoomDetailViewModel.kt index e4e7177e4f..1e6e7c9d14 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/detail/RoomDetailViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/detail/RoomDetailViewModel.kt @@ -31,7 +31,6 @@ import im.vector.app.R import im.vector.app.core.extensions.exhaustive import im.vector.app.core.platform.VectorViewModel import im.vector.app.core.resources.StringProvider -import im.vector.app.core.utils.subscribeLogError import im.vector.app.features.call.WebRtcPeerConnectionManager import im.vector.app.features.command.CommandParser import im.vector.app.features.command.ParsedCommand @@ -168,7 +167,6 @@ class RoomDetailViewModel @AssistedInject constructor( observePowerLevel() room.getRoomSummaryLive() room.markAsRead(ReadService.MarkAsReadParams.READ_RECEIPT, NoOpMatrixCallback()) - room.rx().loadRoomMembersIfNeeded().subscribeLogError().disposeOnClear() // Inform the SDK that the room is displayed session.onRoomDisplayed(initialState.roomId) chatEffectManager.delegate = this From 42a5680374ef8fd8f71ee85b5a9c7c198be970ea Mon Sep 17 00:00:00 2001 From: Onuray Sahin Date: Fri, 18 Dec 2020 12:27:51 +0300 Subject: [PATCH 09/41] Fix copyright. --- .../sdk/session/room/timeline/TimelineWithManyMembersTest.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/session/room/timeline/TimelineWithManyMembersTest.kt b/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/session/room/timeline/TimelineWithManyMembersTest.kt index ca74acdee7..6dd139390c 100644 --- a/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/session/room/timeline/TimelineWithManyMembersTest.kt +++ b/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/session/room/timeline/TimelineWithManyMembersTest.kt @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020 New Vector Ltd + * Copyright 2020 The Matrix.org Foundation C.I.C. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. From 7732bd47cebbcaadb53c84615a491ce271cf25db Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Fri, 18 Dec 2020 16:01:39 +0100 Subject: [PATCH 10/41] Update Changelog after release --- CHANGES.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/CHANGES.md b/CHANGES.md index 9ab5276ff3..38868ed822 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -8,7 +8,7 @@ Improvements 🙌: - Bugfix 🐛: - - + - Wait for all room members to be known before sending a message to a e2e room (#2518) Translations 🗣: - @@ -57,7 +57,6 @@ Bugfix 🐛: - No known servers error is given when joining rooms on new Gitter bridge (#2516) - Show preview when sending attachment from the keyboard (#2440) - Do not compress GIFs (#1616, #1254) - - Wait for all room members to be known before sending a message to a e2e room (#2518) SDK API changes ⚠️: - StateService now exposes suspendable function instead of using MatrixCallback. From ff8a20801253969911f7fde8faba3265cca58cb2 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Fri, 18 Dec 2020 16:04:46 +0100 Subject: [PATCH 11/41] Change to immutable list --- .../org/matrix/android/sdk/common/CryptoTestData.kt | 2 +- .../matrix/android/sdk/common/CryptoTestHelper.kt | 12 ++++++------ 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/common/CryptoTestData.kt b/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/common/CryptoTestData.kt index 693ab28da1..b6bedbd719 100644 --- a/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/common/CryptoTestData.kt +++ b/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/common/CryptoTestData.kt @@ -19,7 +19,7 @@ package org.matrix.android.sdk.common import org.matrix.android.sdk.api.session.Session data class CryptoTestData(val roomId: String, - val sessions: MutableList = mutableListOf()) { + val sessions: List) { val firstSession: Session get() = sessions.first() diff --git a/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/common/CryptoTestHelper.kt b/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/common/CryptoTestHelper.kt index 5d3407dde1..f219986c49 100644 --- a/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/common/CryptoTestHelper.kt +++ b/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/common/CryptoTestHelper.kt @@ -73,7 +73,7 @@ class CryptoTestHelper(private val mTestHelper: CommonTestHelper) { } } - return CryptoTestData(roomId, mutableListOf(aliceSession)) + return CryptoTestData(roomId, listOf(aliceSession)) } /** @@ -139,7 +139,7 @@ class CryptoTestHelper(private val mTestHelper: CommonTestHelper) { // assertNotNull(roomFromBobPOV.powerLevels) // assertTrue(roomFromBobPOV.powerLevels.maySendMessage(bobSession.myUserId)) - return CryptoTestData(aliceRoomId, mutableListOf(aliceSession, bobSession)) + return CryptoTestData(aliceRoomId, listOf(aliceSession, bobSession)) } /** @@ -157,7 +157,7 @@ class CryptoTestHelper(private val mTestHelper: CommonTestHelper) { // wait the initial sync SystemClock.sleep(1000) - return CryptoTestData(aliceRoomId, mutableListOf(aliceSession, cryptoTestData.secondSession!!, samSession)) + return CryptoTestData(aliceRoomId, listOf(aliceSession, cryptoTestData.secondSession!!, samSession)) } /** @@ -395,7 +395,7 @@ class CryptoTestHelper(private val mTestHelper: CommonTestHelper) { room.enableEncryption() } - val cryptoTestData = CryptoTestData(roomId, mutableListOf(aliceSession)) + val sessions = mutableListOf(aliceSession) for (index in 1 until numberOfMembers) { mTestHelper .createAccount("User_$index", defaultSessionParams) @@ -403,9 +403,9 @@ class CryptoTestHelper(private val mTestHelper: CommonTestHelper) { .also { println("TEST -> " + it.myUserId + " invited") } .also { session -> mTestHelper.doSync { session.joinRoom(room.roomId, null, emptyList(), it) } } .also { println("TEST -> " + it.myUserId + " joined") } - .also { session -> cryptoTestData.sessions.add(session) } + .also { session -> sessions.add(session) } } - return cryptoTestData + return CryptoTestData(roomId, sessions) } } From 00b16db7cc823e8ef127fbc3e43d250cb428d03f Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Fri, 18 Dec 2020 16:06:30 +0100 Subject: [PATCH 12/41] Simplification of code --- .../matrix/android/sdk/common/CryptoTestHelper.kt | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/common/CryptoTestHelper.kt b/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/common/CryptoTestHelper.kt index f219986c49..3d5856fc64 100644 --- a/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/common/CryptoTestHelper.kt +++ b/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/common/CryptoTestHelper.kt @@ -397,13 +397,12 @@ class CryptoTestHelper(private val mTestHelper: CommonTestHelper) { val sessions = mutableListOf(aliceSession) for (index in 1 until numberOfMembers) { - mTestHelper - .createAccount("User_$index", defaultSessionParams) - .also { session -> mTestHelper.doSync(timeout = 600_000) { room.invite(session.myUserId, null, it) } } - .also { println("TEST -> " + it.myUserId + " invited") } - .also { session -> mTestHelper.doSync { session.joinRoom(room.roomId, null, emptyList(), it) } } - .also { println("TEST -> " + it.myUserId + " joined") } - .also { session -> sessions.add(session) } + val session = mTestHelper.createAccount("User_$index", defaultSessionParams) + mTestHelper.doSync(timeout = 600_000) { room.invite(session.myUserId, null, it) } + println("TEST -> " + session.myUserId + " invited") + mTestHelper.doSync { session.joinRoom(room.roomId, null, emptyList(), it) } + println("TEST -> " + session.myUserId + " joined") + sessions.add(session) } return CryptoTestData(roomId, sessions) From 15597eb041899df40c582f2d9793fb9bf07d8845 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Fri, 18 Dec 2020 16:10:36 +0100 Subject: [PATCH 13/41] Rename .java to .kt --- ...oomMembersLoadStatusType.java => RoomMembersLoadStatusType.kt} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/model/{RoomMembersLoadStatusType.java => RoomMembersLoadStatusType.kt} (100%) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/model/RoomMembersLoadStatusType.java b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/model/RoomMembersLoadStatusType.kt similarity index 100% rename from matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/model/RoomMembersLoadStatusType.java rename to matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/model/RoomMembersLoadStatusType.kt From abf763f454ac7e89f1d6fe314c112394749c7ac2 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Fri, 18 Dec 2020 16:10:36 +0100 Subject: [PATCH 14/41] Convert to internal Kotlin class --- .../sdk/internal/database/model/RoomMembersLoadStatusType.kt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/model/RoomMembersLoadStatusType.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/model/RoomMembersLoadStatusType.kt index d7063082bb..79fe17253b 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/model/RoomMembersLoadStatusType.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/model/RoomMembersLoadStatusType.kt @@ -14,9 +14,9 @@ * limitations under the License. */ -package org.matrix.android.sdk.internal.database.model; +package org.matrix.android.sdk.internal.database.model -public enum RoomMembersLoadStatusType { +internal enum class RoomMembersLoadStatusType { NONE, LOADING, LOADED From b0ba62aa312c9847277f47489b7e892aa34cba3f Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Fri, 18 Dec 2020 16:12:01 +0100 Subject: [PATCH 15/41] Use const --- .../sdk/internal/database/RealmSessionStoreMigration.kt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/RealmSessionStoreMigration.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/RealmSessionStoreMigration.kt index fd922ef0e5..57002b5a60 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/RealmSessionStoreMigration.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/RealmSessionStoreMigration.kt @@ -21,6 +21,7 @@ import io.realm.RealmMigration import org.matrix.android.sdk.internal.database.model.HomeServerCapabilitiesEntityFields import org.matrix.android.sdk.internal.database.model.PendingThreePidEntityFields import org.matrix.android.sdk.internal.database.model.PreviewUrlCacheEntityFields +import org.matrix.android.sdk.internal.database.model.RoomEntityFields import org.matrix.android.sdk.internal.database.model.RoomMembersLoadStatusType import org.matrix.android.sdk.internal.database.model.RoomSummaryEntityFields import timber.log.Timber @@ -111,7 +112,7 @@ class RealmSessionStoreMigration @Inject constructor() : RealmMigration { private fun migrateTo7(realm: DynamicRealm) { Timber.d("Step 6 -> 7") realm.schema.get("RoomEntity") - ?.addField("membersLoadStatusStr", String::class.java) + ?.addField(RoomEntityFields.MEMBERS_LOAD_STATUS_STR, String::class.java) ?.transform { obj -> if (obj.getBoolean("areAllMembersLoaded")) { obj.setString("membersLoadStatusStr", RoomMembersLoadStatusType.LOADED.name) From ca4b91a98f3086a4ce167d9942023233e039aa0c Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Fri, 18 Dec 2020 16:38:27 +0100 Subject: [PATCH 16/41] Use the new RoomMembersLoadStatusType.LOADING value --- .../room/membership/LoadRoomMembersTask.kt | 48 +++++++++++++++---- 1 file changed, 39 insertions(+), 9 deletions(-) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/membership/LoadRoomMembersTask.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/membership/LoadRoomMembersTask.kt index 69530c5c0e..55dd747fdb 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/membership/LoadRoomMembersTask.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/membership/LoadRoomMembersTask.kt @@ -17,12 +17,19 @@ package org.matrix.android.sdk.internal.session.room.membership import com.zhuinden.monarchy.Monarchy +import io.realm.Realm +import io.realm.kotlin.createObject +import kotlinx.coroutines.TimeoutCancellationException +import org.greenrobot.eventbus.EventBus import org.matrix.android.sdk.api.session.room.model.Membership import org.matrix.android.sdk.api.session.room.send.SendState +import org.matrix.android.sdk.internal.database.awaitNotEmptyResult import org.matrix.android.sdk.internal.database.mapper.toEntity import org.matrix.android.sdk.internal.database.model.CurrentStateEventEntity import org.matrix.android.sdk.internal.database.model.EventInsertType import org.matrix.android.sdk.internal.database.model.RoomEntity +import org.matrix.android.sdk.internal.database.model.RoomEntityFields +import org.matrix.android.sdk.internal.database.model.RoomMembersLoadStatusType import org.matrix.android.sdk.internal.database.query.copyToRealmOrIgnore import org.matrix.android.sdk.internal.database.query.getOrCreate import org.matrix.android.sdk.internal.database.query.where @@ -33,10 +40,7 @@ import org.matrix.android.sdk.internal.session.room.summary.RoomSummaryUpdater import org.matrix.android.sdk.internal.session.sync.SyncTokenStore import org.matrix.android.sdk.internal.task.Task import org.matrix.android.sdk.internal.util.awaitTransaction -import io.realm.Realm -import io.realm.kotlin.createObject -import org.greenrobot.eventbus.EventBus -import org.matrix.android.sdk.internal.database.model.RoomMembersLoadStatusType +import java.util.concurrent.TimeUnit import javax.inject.Inject internal interface LoadRoomMembersTask : Task { @@ -57,9 +61,33 @@ internal class DefaultLoadRoomMembersTask @Inject constructor( ) : LoadRoomMembersTask { override suspend fun execute(params: LoadRoomMembersTask.Params) { - if (areAllMembersAlreadyLoaded(params.roomId)) { - return + when (getRoomMembersLoadStatus(params.roomId)) { + RoomMembersLoadStatusType.NONE -> doRequest(params) + RoomMembersLoadStatusType.LOADING -> waitPreviousRequestToFinish(params) + RoomMembersLoadStatusType.LOADED -> Unit } + } + + private suspend fun waitPreviousRequestToFinish(params: LoadRoomMembersTask.Params) { + try { + awaitNotEmptyResult(monarchy.realmConfiguration, TimeUnit.MINUTES.toMillis(1L)) { realm -> + realm.where(RoomEntity::class.java) + .equalTo(RoomEntityFields.ROOM_ID, params.roomId) + .equalTo(RoomEntityFields.MEMBERS_LOAD_STATUS_STR, RoomMembersLoadStatusType.LOADED.name) + } + } catch (exception: TimeoutCancellationException) { + // Timeout, do the request anyway (?) + doRequest(params) + } + } + + private suspend fun doRequest(params: LoadRoomMembersTask.Params) { + monarchy.awaitTransaction { realm -> + val roomEntity = RoomEntity.where(realm, params.roomId).findFirst() + ?: realm.createObject(params.roomId) + roomEntity.membersLoadStatus = RoomMembersLoadStatusType.LOADING + } + val lastToken = syncTokenStore.getLastToken() val response = executeRequest(eventBus) { apiCall = roomAPI.getMembers(params.roomId, lastToken, null, params.excludeMembership?.value) @@ -90,9 +118,11 @@ internal class DefaultLoadRoomMembersTask @Inject constructor( } } - private fun areAllMembersAlreadyLoaded(roomId: String): Boolean { - return Realm.getInstance(monarchy.realmConfiguration).use { - RoomEntity.where(it, roomId).findFirst()?.membersLoadStatus == RoomMembersLoadStatusType.LOADED + private fun getRoomMembersLoadStatus(roomId: String): RoomMembersLoadStatusType { + var result: RoomMembersLoadStatusType? + Realm.getInstance(monarchy.realmConfiguration).use { + result = RoomEntity.where(it, roomId).findFirst()?.membersLoadStatus } + return result ?: RoomMembersLoadStatusType.NONE } } From 3d291c04c981e6b70336dfe35ea1836190e5bf7e Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Fri, 18 Dec 2020 16:53:26 +0100 Subject: [PATCH 17/41] const -> companion --- .../sdk/session/room/timeline/TimelineWithManyMembersTest.kt | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/session/room/timeline/TimelineWithManyMembersTest.kt b/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/session/room/timeline/TimelineWithManyMembersTest.kt index 6dd139390c..ff07cf1d1d 100644 --- a/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/session/room/timeline/TimelineWithManyMembersTest.kt +++ b/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/session/room/timeline/TimelineWithManyMembersTest.kt @@ -35,7 +35,9 @@ import kotlin.test.fail @FixMethodOrder(MethodSorters.JVM) class TimelineWithManyMembersTest : InstrumentedTest { - private val NUMBER_OF_MEMBERS = 6 + companion object { + private const val NUMBER_OF_MEMBERS = 6 + } private val commonTestHelper = CommonTestHelper(context()) private val cryptoTestHelper = CryptoTestHelper(commonTestHelper) From 13938f2ab3eb02e55e51ee9f924c7a52d047fd4e Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Mon, 21 Dec 2020 11:18:25 +0100 Subject: [PATCH 18/41] Let the Matrix SDK compute the SSO url --- .../sdk/api/auth/AuthenticationService.kt | 5 +++ .../matrix/android/sdk/api/auth/Constants.kt | 6 +-- .../android/sdk/api/util/UrlExtensions.kt | 37 +++++++++++++++++++ .../auth/DefaultAuthenticationService.kt | 26 +++++++++++++ .../app/core/extensions/UrlExtensions.kt | 20 ---------- .../login/AbstractSSOLoginFragment.kt | 7 +++- .../app/features/login/LoginActivity.kt | 3 ++ .../app/features/login/LoginFragment.kt | 7 +++- .../LoginSignUpSignInSelectionFragment.kt | 15 ++++++-- .../app/features/login/LoginViewModel.kt | 4 ++ .../app/features/login/LoginViewState.kt | 27 -------------- .../app/features/login/LoginWebFragment.kt | 2 +- 12 files changed, 103 insertions(+), 56 deletions(-) create mode 100644 matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/util/UrlExtensions.kt diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/auth/AuthenticationService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/auth/AuthenticationService.kt index 360b955869..3314b47ce9 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/auth/AuthenticationService.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/auth/AuthenticationService.kt @@ -41,6 +41,11 @@ interface AuthenticationService { */ fun getLoginFlowOfSession(sessionId: String, callback: MatrixCallback): Cancelable + /** + * Get a SSO url + */ + fun getSsoUrl(redirectUrl: String, deviceId: String?, providerId: String?): String? + /** * Return a LoginWizard, to login to the homeserver. The login flow has to be retrieved first. */ diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/auth/Constants.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/auth/Constants.kt index 7d18aba627..d832caefde 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/auth/Constants.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/auth/Constants.kt @@ -32,7 +32,7 @@ const val REGISTER_FALLBACK_PATH = "/_matrix/static/client/register/" * Path to use when the client want to connect using SSO * Ref: https://matrix.org/docs/spec/client_server/latest#sso-client-login */ -const val SSO_REDIRECT_PATH = "/_matrix/client/r0/login/sso/redirect" -const val MSC2858_SSO_REDIRECT_PATH = "/_matrix/client/unstable/org.matrix.msc2858/login/sso/redirect" +internal const val SSO_REDIRECT_PATH = "/_matrix/client/r0/login/sso/redirect" +internal const val MSC2858_SSO_REDIRECT_PATH = "/_matrix/client/unstable/org.matrix.msc2858/login/sso/redirect" -const val SSO_REDIRECT_URL_PARAM = "redirectUrl" +internal const val SSO_REDIRECT_URL_PARAM = "redirectUrl" diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/util/UrlExtensions.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/util/UrlExtensions.kt new file mode 100644 index 0000000000..beaff2bdda --- /dev/null +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/util/UrlExtensions.kt @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2020 New Vector Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.matrix.android.sdk.api.util + +import java.net.URLEncoder + +/** + * Append param and value to a Url, using "?" or "&". Value parameter will be encoded + * Return this for chaining purpose + */ +fun StringBuilder.appendParamToUrl(param: String, value: String): StringBuilder { + if (contains("?")) { + append("&") + } else { + append("?") + } + + append(param) + append("=") + append(URLEncoder.encode(value, "utf-8")) + + return this +} diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/auth/DefaultAuthenticationService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/auth/DefaultAuthenticationService.kt index 55f053de8d..51f6b6c155 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/auth/DefaultAuthenticationService.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/auth/DefaultAuthenticationService.kt @@ -23,6 +23,9 @@ import kotlinx.coroutines.withContext import okhttp3.OkHttpClient import org.matrix.android.sdk.api.MatrixCallback import org.matrix.android.sdk.api.auth.AuthenticationService +import org.matrix.android.sdk.api.auth.MSC2858_SSO_REDIRECT_PATH +import org.matrix.android.sdk.api.auth.SSO_REDIRECT_PATH +import org.matrix.android.sdk.api.auth.SSO_REDIRECT_URL_PARAM import org.matrix.android.sdk.api.auth.data.Credentials import org.matrix.android.sdk.api.auth.data.HomeServerConnectionConfig import org.matrix.android.sdk.api.auth.data.LoginFlowResult @@ -34,6 +37,7 @@ import org.matrix.android.sdk.api.failure.Failure import org.matrix.android.sdk.api.session.Session import org.matrix.android.sdk.api.util.Cancelable import org.matrix.android.sdk.api.util.NoOpCancellable +import org.matrix.android.sdk.api.util.appendParamToUrl import org.matrix.android.sdk.internal.SessionManager import org.matrix.android.sdk.internal.auth.data.LoginFlowResponse import org.matrix.android.sdk.internal.auth.data.RiotConfig @@ -99,6 +103,28 @@ internal class DefaultAuthenticationService @Inject constructor( } } + override fun getSsoUrl(redirectUrl: String, deviceId: String?, providerId: String?): String? { + return pendingSessionData?.let { safePendingSessionData -> + val homeServerUrl = safePendingSessionData.homeServerConnectionConfig.homeServerUri.toString() + + buildString { + append(homeServerUrl.trim { it == '/' }) + if (providerId != null) { + append(MSC2858_SSO_REDIRECT_PATH) + append("/$providerId") + } else { + append(SSO_REDIRECT_PATH) + } + // Set a redirect url we will intercept later + appendParamToUrl(SSO_REDIRECT_URL_PARAM, redirectUrl) + deviceId?.takeIf { it.isNotBlank() }?.let { + // But https://github.com/matrix-org/synapse/issues/5755 + appendParamToUrl("device_id", it) + } + } + } + } + override fun getLoginFlow(homeServerConnectionConfig: HomeServerConnectionConfig, callback: MatrixCallback): Cancelable { pendingSessionData = null diff --git a/vector/src/main/java/im/vector/app/core/extensions/UrlExtensions.kt b/vector/src/main/java/im/vector/app/core/extensions/UrlExtensions.kt index 38977d33ba..5037f78445 100644 --- a/vector/src/main/java/im/vector/app/core/extensions/UrlExtensions.kt +++ b/vector/src/main/java/im/vector/app/core/extensions/UrlExtensions.kt @@ -16,26 +16,6 @@ package im.vector.app.core.extensions -import java.net.URLEncoder - -/** - * Append param and value to a Url, using "?" or "&". Value parameter will be encoded - * Return this for chaining purpose - */ -fun StringBuilder.appendParamToUrl(param: String, value: String): StringBuilder { - if (contains("?")) { - append("&") - } else { - append("?") - } - - append(param) - append("=") - append(URLEncoder.encode(value, "utf-8")) - - return this -} - /** * Ex: "https://matrix.org/" -> "matrix.org" */ diff --git a/vector/src/main/java/im/vector/app/features/login/AbstractSSOLoginFragment.kt b/vector/src/main/java/im/vector/app/features/login/AbstractSSOLoginFragment.kt index c20f4ddd23..3fc5037ae7 100644 --- a/vector/src/main/java/im/vector/app/features/login/AbstractSSOLoginFragment.kt +++ b/vector/src/main/java/im/vector/app/features/login/AbstractSSOLoginFragment.kt @@ -87,7 +87,12 @@ abstract class AbstractSSOLoginFragment : AbstractLoginFragment withState(loginViewModel) { state -> if (state.loginMode.hasSso() && state.loginMode.ssoIdentityProviders().isNullOrEmpty()) { // in this case we can prefetch (not other cases for privacy concerns) - prefetchUrl(state.getSsoUrl(null)) + loginViewModel.getSsoUrl( + redirectUrl = LoginActivity.VECTOR_REDIRECT_URL, + deviceId = state.deviceId, + providerId = null + ) + ?.let { prefetchUrl(it) } } } } diff --git a/vector/src/main/java/im/vector/app/features/login/LoginActivity.kt b/vector/src/main/java/im/vector/app/features/login/LoginActivity.kt index 503b6d74a6..803fd38983 100644 --- a/vector/src/main/java/im/vector/app/features/login/LoginActivity.kt +++ b/vector/src/main/java/im/vector/app/features/login/LoginActivity.kt @@ -360,6 +360,9 @@ open class LoginActivity : VectorBaseActivity(), ToolbarCo private const val EXTRA_CONFIG = "EXTRA_CONFIG" + // Note that the domain can be displayed to the user for confirmation that he trusts it. So use a human readable string + const val VECTOR_REDIRECT_URL = "element://connect" + fun newIntent(context: Context, loginConfig: LoginConfig?): Intent { return Intent(context, LoginActivity::class.java).apply { putExtra(EXTRA_CONFIG, loginConfig) diff --git a/vector/src/main/java/im/vector/app/features/login/LoginFragment.kt b/vector/src/main/java/im/vector/app/features/login/LoginFragment.kt index c396e61b1a..3b22e0f206 100644 --- a/vector/src/main/java/im/vector/app/features/login/LoginFragment.kt +++ b/vector/src/main/java/im/vector/app/features/login/LoginFragment.kt @@ -193,7 +193,12 @@ class LoginFragment @Inject constructor() : AbstractSSOLoginFragment if (state.loginMode is LoginMode.Sso) { - openInCustomTab(state.getSsoUrl(null)) + loginViewModel.getSsoUrl( + redirectUrl = LoginActivity.VECTOR_REDIRECT_URL, + deviceId = state.deviceId, + providerId = null + ) + ?.let { openInCustomTab(it) } } else { loginViewModel.handle(LoginAction.UpdateSignMode(SignMode.SignUp)) } diff --git a/vector/src/main/java/im/vector/app/features/login/LoginViewModel.kt b/vector/src/main/java/im/vector/app/features/login/LoginViewModel.kt index 0a6dbcaae2..ab79c6ae48 100644 --- a/vector/src/main/java/im/vector/app/features/login/LoginViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/login/LoginViewModel.kt @@ -818,4 +818,8 @@ class LoginViewModel @AssistedInject constructor( fun getInitialHomeServerUrl(): String? { return loginConfig?.homeServerUrl } + + fun getSsoUrl(redirectUrl: String, deviceId: String?, providerId: String?): String? { + return authenticationService.getSsoUrl(redirectUrl, deviceId, providerId) + } } diff --git a/vector/src/main/java/im/vector/app/features/login/LoginViewState.kt b/vector/src/main/java/im/vector/app/features/login/LoginViewState.kt index 5254abf1d9..37ac89794f 100644 --- a/vector/src/main/java/im/vector/app/features/login/LoginViewState.kt +++ b/vector/src/main/java/im/vector/app/features/login/LoginViewState.kt @@ -22,10 +22,6 @@ import com.airbnb.mvrx.MvRxState import com.airbnb.mvrx.PersistState import com.airbnb.mvrx.Success import com.airbnb.mvrx.Uninitialized -import im.vector.app.core.extensions.appendParamToUrl -import org.matrix.android.sdk.api.auth.MSC2858_SSO_REDIRECT_PATH -import org.matrix.android.sdk.api.auth.SSO_REDIRECT_PATH -import org.matrix.android.sdk.api.auth.SSO_REDIRECT_URL_PARAM data class LoginViewState( val asyncLoginAction: Async = Uninitialized, @@ -69,27 +65,4 @@ data class LoginViewState( fun isUserLogged(): Boolean { return asyncLoginAction is Success } - - fun getSsoUrl(providerId: String?): String { - return buildString { - append(homeServerUrl?.trim { it == '/' }) - if (providerId != null) { - append(MSC2858_SSO_REDIRECT_PATH) - append("/$providerId") - } else { - append(SSO_REDIRECT_PATH) - } - // Set a redirect url we will intercept later - appendParamToUrl(SSO_REDIRECT_URL_PARAM, VECTOR_REDIRECT_URL) - deviceId?.takeIf { it.isNotBlank() }?.let { - // But https://github.com/matrix-org/synapse/issues/5755 - appendParamToUrl("device_id", it) - } - } - } - - companion object { - // Note that the domain can be displayed to the user for confirmation that he trusts it. So use a human readable string - private const val VECTOR_REDIRECT_URL = "element://connect" - } } diff --git a/vector/src/main/java/im/vector/app/features/login/LoginWebFragment.kt b/vector/src/main/java/im/vector/app/features/login/LoginWebFragment.kt index acf4f706c5..7ba6626604 100644 --- a/vector/src/main/java/im/vector/app/features/login/LoginWebFragment.kt +++ b/vector/src/main/java/im/vector/app/features/login/LoginWebFragment.kt @@ -33,7 +33,6 @@ import android.webkit.WebViewClient import androidx.appcompat.app.AlertDialog import com.airbnb.mvrx.activityViewModel import im.vector.app.R -import im.vector.app.core.extensions.appendParamToUrl import im.vector.app.core.utils.AssetReader import im.vector.app.databinding.FragmentLoginWebBinding import im.vector.app.features.signout.soft.SoftLogoutAction @@ -42,6 +41,7 @@ import im.vector.app.features.signout.soft.SoftLogoutViewModel import org.matrix.android.sdk.api.auth.LOGIN_FALLBACK_PATH import org.matrix.android.sdk.api.auth.REGISTER_FALLBACK_PATH import org.matrix.android.sdk.api.auth.data.Credentials +import org.matrix.android.sdk.api.util.appendParamToUrl import org.matrix.android.sdk.internal.di.MoshiProvider import timber.log.Timber import java.net.URLDecoder From 36a553a8868c57459994849ad25b9d8c8230b94e Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Mon, 21 Dec 2020 12:08:49 +0100 Subject: [PATCH 19/41] Let the Matrix SDK compute the Fallback urls --- .../sdk/api/auth/AuthenticationService.kt | 5 ++ .../matrix/android/sdk/api/auth/Constants.kt | 4 +- .../auth/DefaultAuthenticationService.kt | 50 ++++++++++++++----- .../app/features/login/LoginViewModel.kt | 4 ++ .../app/features/login/LoginWebFragment.kt | 17 +------ 5 files changed, 50 insertions(+), 30 deletions(-) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/auth/AuthenticationService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/auth/AuthenticationService.kt index 3314b47ce9..bf21941e0c 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/auth/AuthenticationService.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/auth/AuthenticationService.kt @@ -46,6 +46,11 @@ interface AuthenticationService { */ fun getSsoUrl(redirectUrl: String, deviceId: String?, providerId: String?): String? + /** + * Get the sign in or sign up fallback URL + */ + fun getFallbackUrl(forSignIn: Boolean, deviceId: String?): String? + /** * Return a LoginWizard, to login to the homeserver. The login flow has to be retrieved first. */ diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/auth/Constants.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/auth/Constants.kt index d832caefde..35b4a0a8d6 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/auth/Constants.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/auth/Constants.kt @@ -20,13 +20,13 @@ package org.matrix.android.sdk.api.auth * Path to use when the client does not supported any or all login flows * Ref: https://matrix.org/docs/spec/client_server/latest#login-fallback */ -const val LOGIN_FALLBACK_PATH = "/_matrix/static/client/login/" +internal const val LOGIN_FALLBACK_PATH = "/_matrix/static/client/login/" /** * Path to use when the client does not supported any or all registration flows * Not documented */ -const val REGISTER_FALLBACK_PATH = "/_matrix/static/client/register/" +internal const val REGISTER_FALLBACK_PATH = "/_matrix/static/client/register/" /** * Path to use when the client want to connect using SSO diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/auth/DefaultAuthenticationService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/auth/DefaultAuthenticationService.kt index 51f6b6c155..0996011ed0 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/auth/DefaultAuthenticationService.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/auth/DefaultAuthenticationService.kt @@ -23,7 +23,9 @@ import kotlinx.coroutines.withContext import okhttp3.OkHttpClient import org.matrix.android.sdk.api.MatrixCallback import org.matrix.android.sdk.api.auth.AuthenticationService +import org.matrix.android.sdk.api.auth.LOGIN_FALLBACK_PATH import org.matrix.android.sdk.api.auth.MSC2858_SSO_REDIRECT_PATH +import org.matrix.android.sdk.api.auth.REGISTER_FALLBACK_PATH import org.matrix.android.sdk.api.auth.SSO_REDIRECT_PATH import org.matrix.android.sdk.api.auth.SSO_REDIRECT_URL_PARAM import org.matrix.android.sdk.api.auth.data.Credentials @@ -104,27 +106,51 @@ internal class DefaultAuthenticationService @Inject constructor( } override fun getSsoUrl(redirectUrl: String, deviceId: String?, providerId: String?): String? { - return pendingSessionData?.let { safePendingSessionData -> - val homeServerUrl = safePendingSessionData.homeServerConnectionConfig.homeServerUri.toString() + val homeServerUrlBase = getHomeServerUrlBase() ?: return null - buildString { - append(homeServerUrl.trim { it == '/' }) - if (providerId != null) { - append(MSC2858_SSO_REDIRECT_PATH) - append("/$providerId") - } else { - append(SSO_REDIRECT_PATH) - } - // Set a redirect url we will intercept later - appendParamToUrl(SSO_REDIRECT_URL_PARAM, redirectUrl) + return buildString { + append(homeServerUrlBase) + if (providerId != null) { + append(MSC2858_SSO_REDIRECT_PATH) + append("/$providerId") + } else { + append(SSO_REDIRECT_PATH) + } + // Set the redirect url + appendParamToUrl(SSO_REDIRECT_URL_PARAM, redirectUrl) + deviceId?.takeIf { it.isNotBlank() }?.let { + // But https://github.com/matrix-org/synapse/issues/5755 + appendParamToUrl("device_id", it) + } + } + } + + override fun getFallbackUrl(forSignIn: Boolean, deviceId: String?): String? { + val homeServerUrlBase = getHomeServerUrlBase() ?: return null + + return buildString { + append(homeServerUrlBase) + if (forSignIn) { + append(LOGIN_FALLBACK_PATH) deviceId?.takeIf { it.isNotBlank() }?.let { // But https://github.com/matrix-org/synapse/issues/5755 appendParamToUrl("device_id", it) } + } else { + // For sign up + append(REGISTER_FALLBACK_PATH) } } } + private fun getHomeServerUrlBase(): String? { + return pendingSessionData + ?.homeServerConnectionConfig + ?.homeServerUri + ?.toString() + ?.trim { it == '/' } + } + override fun getLoginFlow(homeServerConnectionConfig: HomeServerConnectionConfig, callback: MatrixCallback): Cancelable { pendingSessionData = null diff --git a/vector/src/main/java/im/vector/app/features/login/LoginViewModel.kt b/vector/src/main/java/im/vector/app/features/login/LoginViewModel.kt index ab79c6ae48..666bd21add 100644 --- a/vector/src/main/java/im/vector/app/features/login/LoginViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/login/LoginViewModel.kt @@ -822,4 +822,8 @@ class LoginViewModel @AssistedInject constructor( fun getSsoUrl(redirectUrl: String, deviceId: String?, providerId: String?): String? { return authenticationService.getSsoUrl(redirectUrl, deviceId, providerId) } + + fun getFallbackUrl(forSignIn: Boolean, deviceId: String?): String? { + return authenticationService.getFallbackUrl(forSignIn, deviceId) + } } diff --git a/vector/src/main/java/im/vector/app/features/login/LoginWebFragment.kt b/vector/src/main/java/im/vector/app/features/login/LoginWebFragment.kt index 7ba6626604..4b03c93321 100644 --- a/vector/src/main/java/im/vector/app/features/login/LoginWebFragment.kt +++ b/vector/src/main/java/im/vector/app/features/login/LoginWebFragment.kt @@ -38,10 +38,7 @@ import im.vector.app.databinding.FragmentLoginWebBinding import im.vector.app.features.signout.soft.SoftLogoutAction import im.vector.app.features.signout.soft.SoftLogoutViewModel -import org.matrix.android.sdk.api.auth.LOGIN_FALLBACK_PATH -import org.matrix.android.sdk.api.auth.REGISTER_FALLBACK_PATH import org.matrix.android.sdk.api.auth.data.Credentials -import org.matrix.android.sdk.api.util.appendParamToUrl import org.matrix.android.sdk.internal.di.MoshiProvider import timber.log.Timber import java.net.URLDecoder @@ -119,19 +116,7 @@ class LoginWebFragment @Inject constructor( } private fun launchWebView(state: LoginViewState) { - val url = buildString { - append(state.homeServerUrl?.trim { it == '/' }) - if (state.signMode == SignMode.SignIn) { - append(LOGIN_FALLBACK_PATH) - state.deviceId?.takeIf { it.isNotBlank() }?.let { - // But https://github.com/matrix-org/synapse/issues/5755 - appendParamToUrl("device_id", it) - } - } else { - // MODE_REGISTER - append(REGISTER_FALLBACK_PATH) - } - } + val url = loginViewModel.getFallbackUrl(state.signMode == SignMode.SignIn, state.deviceId) ?: return views.loginWebWebView.loadUrl(url) From 6c4836e27e8ee05cac09a85e9e81f3b5db4e2b1f Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Mon, 21 Dec 2020 12:11:19 +0100 Subject: [PATCH 20/41] Move file to internal --- .../matrix/android/sdk/{api => internal}/auth/Constants.kt | 2 +- .../sdk/internal/auth/DefaultAuthenticationService.kt | 5 ----- 2 files changed, 1 insertion(+), 6 deletions(-) rename matrix-sdk-android/src/main/java/org/matrix/android/sdk/{api => internal}/auth/Constants.kt (96%) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/auth/Constants.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/auth/Constants.kt similarity index 96% rename from matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/auth/Constants.kt rename to matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/auth/Constants.kt index 35b4a0a8d6..642279cc27 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/auth/Constants.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/auth/Constants.kt @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.matrix.android.sdk.api.auth +package org.matrix.android.sdk.internal.auth /** * Path to use when the client does not supported any or all login flows diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/auth/DefaultAuthenticationService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/auth/DefaultAuthenticationService.kt index 0996011ed0..c99e9bd81c 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/auth/DefaultAuthenticationService.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/auth/DefaultAuthenticationService.kt @@ -23,11 +23,6 @@ import kotlinx.coroutines.withContext import okhttp3.OkHttpClient import org.matrix.android.sdk.api.MatrixCallback import org.matrix.android.sdk.api.auth.AuthenticationService -import org.matrix.android.sdk.api.auth.LOGIN_FALLBACK_PATH -import org.matrix.android.sdk.api.auth.MSC2858_SSO_REDIRECT_PATH -import org.matrix.android.sdk.api.auth.REGISTER_FALLBACK_PATH -import org.matrix.android.sdk.api.auth.SSO_REDIRECT_PATH -import org.matrix.android.sdk.api.auth.SSO_REDIRECT_URL_PARAM import org.matrix.android.sdk.api.auth.data.Credentials import org.matrix.android.sdk.api.auth.data.HomeServerConnectionConfig import org.matrix.android.sdk.api.auth.data.LoginFlowResult From 073e6227d62975130a22be864a48f1c979ea49dd Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Mon, 28 Dec 2020 10:59:50 +0100 Subject: [PATCH 21/41] Correct Copyright mention --- .../main/java/org/matrix/android/sdk/api/util/UrlExtensions.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/util/UrlExtensions.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/util/UrlExtensions.kt index beaff2bdda..17f27b2514 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/util/UrlExtensions.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/util/UrlExtensions.kt @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020 New Vector Ltd + * Copyright 2020 The Matrix.org Foundation C.I.C. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. From d1bec21759f2a534bd955972b1adabf825bccbcb Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Mon, 28 Dec 2020 12:23:06 +0100 Subject: [PATCH 22/41] Fix crash after migration to view bindings Also rename some layouts to follow convention --- .../core/ui/views/BottomSheetActionButton.kt | 8 +- .../app/features/call/CallControlsView.kt | 4 +- .../timeline/item/PollResultLineView.kt | 8 +- .../signout/SignOutBottomSheetActionButton.kt | 12 +-- .../main/res/layout/item_signout_action.xml | 36 -------- .../res/layout/item_verification_action.xml | 10 +-- .../view_bottom_sheet_action_button.xml | 84 +++++++++++++++++++ .../main/res/layout/view_call_controls.xml | 35 ++++---- ...ult_item.xml => view_poll_result_line.xml} | 0 ...ew_sign_out_bottom_sheet_action_button.xml | 43 ++++++++++ 10 files changed, 166 insertions(+), 74 deletions(-) delete mode 100644 vector/src/main/res/layout/item_signout_action.xml create mode 100644 vector/src/main/res/layout/view_bottom_sheet_action_button.xml rename vector/src/main/res/layout/{item_timeline_event_poll_result_item.xml => view_poll_result_line.xml} (100%) create mode 100644 vector/src/main/res/layout/view_sign_out_bottom_sheet_action_button.xml diff --git a/vector/src/main/java/im/vector/app/core/ui/views/BottomSheetActionButton.kt b/vector/src/main/java/im/vector/app/core/ui/views/BottomSheetActionButton.kt index 6f261ad717..f86825750a 100644 --- a/vector/src/main/java/im/vector/app/core/ui/views/BottomSheetActionButton.kt +++ b/vector/src/main/java/im/vector/app/core/ui/views/BottomSheetActionButton.kt @@ -28,7 +28,7 @@ import androidx.core.view.isInvisible import androidx.core.view.isVisible import im.vector.app.R import im.vector.app.core.extensions.setTextOrHide -import im.vector.app.databinding.ItemVerificationActionBinding +import im.vector.app.databinding.ViewBottomSheetActionButtonBinding import im.vector.app.features.themes.ThemeUtils class BottomSheetActionButton @JvmOverloads constructor( @@ -36,7 +36,7 @@ class BottomSheetActionButton @JvmOverloads constructor( attrs: AttributeSet? = null, defStyleAttr: Int = 0 ) : FrameLayout(context, attrs, defStyleAttr) { - val views : ItemVerificationActionBinding + val views: ViewBottomSheetActionButtonBinding var title: String? = null set(value) { @@ -97,8 +97,8 @@ class BottomSheetActionButton @JvmOverloads constructor( } init { - inflate(context, R.layout.item_verification_action, this) - views = ItemVerificationActionBinding.bind(this) + inflate(context, R.layout.view_bottom_sheet_action_button, this) + views = ViewBottomSheetActionButtonBinding.bind(this) context.withStyledAttributes(attrs, R.styleable.BottomSheetActionButton) { title = getString(R.styleable.BottomSheetActionButton_actionTitle) ?: "" diff --git a/vector/src/main/java/im/vector/app/features/call/CallControlsView.kt b/vector/src/main/java/im/vector/app/features/call/CallControlsView.kt index 5fdc70c539..9aa6ccd298 100644 --- a/vector/src/main/java/im/vector/app/features/call/CallControlsView.kt +++ b/vector/src/main/java/im/vector/app/features/call/CallControlsView.kt @@ -18,7 +18,7 @@ package im.vector.app.features.call import android.content.Context import android.util.AttributeSet -import android.widget.LinearLayout +import android.widget.FrameLayout import androidx.core.view.isVisible import im.vector.app.R import im.vector.app.databinding.ViewCallControlsBinding @@ -28,7 +28,7 @@ import org.webrtc.PeerConnection class CallControlsView @JvmOverloads constructor( context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0 -) : LinearLayout(context, attrs, defStyleAttr) { +) : FrameLayout(context, attrs, defStyleAttr) { private val views: ViewCallControlsBinding diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/item/PollResultLineView.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/item/PollResultLineView.kt index d5996a65ba..aa864851cd 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/item/PollResultLineView.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/item/PollResultLineView.kt @@ -23,7 +23,7 @@ import android.widget.LinearLayout import androidx.core.content.withStyledAttributes import im.vector.app.R import im.vector.app.core.extensions.setTextOrHide -import im.vector.app.databinding.ItemTimelineEventPollResultItemBinding +import im.vector.app.databinding.ViewPollResultLineBinding class PollResultLineView @JvmOverloads constructor( context: Context, @@ -31,7 +31,7 @@ class PollResultLineView @JvmOverloads constructor( defStyleAttr: Int = 0 ) : LinearLayout(context, attrs, defStyleAttr) { - private val views: ItemTimelineEventPollResultItemBinding + private val views: ViewPollResultLineBinding var label: String? = null set(value) { @@ -60,8 +60,8 @@ class PollResultLineView @JvmOverloads constructor( } init { - inflate(context, R.layout.item_timeline_event_poll_result_item, this) - views = ItemTimelineEventPollResultItemBinding.bind(this) + inflate(context, R.layout.view_poll_result_line, this) + views = ViewPollResultLineBinding.bind(this) orientation = HORIZONTAL context.withStyledAttributes(attrs, R.styleable.PollResultLineView) { diff --git a/vector/src/main/java/im/vector/app/features/workers/signout/SignOutBottomSheetActionButton.kt b/vector/src/main/java/im/vector/app/features/workers/signout/SignOutBottomSheetActionButton.kt index 00df261095..61bef29d54 100644 --- a/vector/src/main/java/im/vector/app/features/workers/signout/SignOutBottomSheetActionButton.kt +++ b/vector/src/main/java/im/vector/app/features/workers/signout/SignOutBottomSheetActionButton.kt @@ -20,19 +20,19 @@ import android.content.Context import android.content.res.ColorStateList import android.graphics.drawable.Drawable import android.util.AttributeSet -import android.widget.LinearLayout +import android.widget.FrameLayout import androidx.core.content.withStyledAttributes import androidx.core.view.isVisible import im.vector.app.R import im.vector.app.core.extensions.setTextOrHide -import im.vector.app.databinding.ItemSignoutActionBinding +import im.vector.app.databinding.ViewSignOutBottomSheetActionButtonBinding import im.vector.app.features.themes.ThemeUtils class SignOutBottomSheetActionButton @JvmOverloads constructor( context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0 -) : LinearLayout(context, attrs, defStyleAttr) { +) : FrameLayout(context, attrs, defStyleAttr) { - private val views: ItemSignoutActionBinding + private val views: ViewSignOutBottomSheetActionButtonBinding var action: (() -> Unit)? = null @@ -67,8 +67,8 @@ class SignOutBottomSheetActionButton @JvmOverloads constructor( } init { - inflate(context, R.layout.item_signout_action, this) - views = ItemSignoutActionBinding.bind(this) + inflate(context, R.layout.view_sign_out_bottom_sheet_action_button, this) + views = ViewSignOutBottomSheetActionButtonBinding.bind(this) context.withStyledAttributes(attrs, R.styleable.SignOutBottomSheetActionButton) { title = getString(R.styleable.SignOutBottomSheetActionButton_actionTitle) ?: "" diff --git a/vector/src/main/res/layout/item_signout_action.xml b/vector/src/main/res/layout/item_signout_action.xml deleted file mode 100644 index b1eb8c1f62..0000000000 --- a/vector/src/main/res/layout/item_signout_action.xml +++ /dev/null @@ -1,36 +0,0 @@ - - - - - - - - \ No newline at end of file diff --git a/vector/src/main/res/layout/item_verification_action.xml b/vector/src/main/res/layout/item_verification_action.xml index ae49893792..68ee392cff 100644 --- a/vector/src/main/res/layout/item_verification_action.xml +++ b/vector/src/main/res/layout/item_verification_action.xml @@ -24,10 +24,10 @@ app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="parent" - tools:src="@drawable/ic_share" - tools:visibility="visible" app:tint="?riotx_text_primary" - tools:ignore="MissingPrefix" /> + tools:ignore="MissingPrefix" + tools:src="@drawable/ic_share" + tools:visibility="visible" /> + tools:ignore="MissingPrefix" + tools:src="@drawable/ic_arrow_right" /> diff --git a/vector/src/main/res/layout/view_bottom_sheet_action_button.xml b/vector/src/main/res/layout/view_bottom_sheet_action_button.xml new file mode 100644 index 0000000000..c0f55df9e6 --- /dev/null +++ b/vector/src/main/res/layout/view_bottom_sheet_action_button.xml @@ -0,0 +1,84 @@ + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/vector/src/main/res/layout/view_call_controls.xml b/vector/src/main/res/layout/view_call_controls.xml index 435520b9ef..2487f131e3 100644 --- a/vector/src/main/res/layout/view_call_controls.xml +++ b/vector/src/main/res/layout/view_call_controls.xml @@ -1,9 +1,10 @@ - + android:layout_height="wrap_content" + tools:parentTag="android.widget.FrameLayout"> + app:tint="@color/white" + tools:ignore="MissingConstraints,MissingPrefix" /> + app:tint="@color/white" + tools:ignore="MissingConstraints,MissingPrefix" /> + app:tint="?attr/riotx_text_primary" + tools:ignore="MissingConstraints,MissingPrefix" /> + tools:src="@drawable/ic_microphone_on" /> + app:tint="@color/white" + tools:ignore="MissingConstraints,MissingPrefix" /> + tools:ignore="MissingConstraints,MissingPrefix" /> + app:tint="?attr/riotx_text_primary" + tools:ignore="MissingConstraints,MissingPrefix" /> - \ No newline at end of file + \ No newline at end of file diff --git a/vector/src/main/res/layout/item_timeline_event_poll_result_item.xml b/vector/src/main/res/layout/view_poll_result_line.xml similarity index 100% rename from vector/src/main/res/layout/item_timeline_event_poll_result_item.xml rename to vector/src/main/res/layout/view_poll_result_line.xml diff --git a/vector/src/main/res/layout/view_sign_out_bottom_sheet_action_button.xml b/vector/src/main/res/layout/view_sign_out_bottom_sheet_action_button.xml new file mode 100644 index 0000000000..6809cfd119 --- /dev/null +++ b/vector/src/main/res/layout/view_sign_out_bottom_sheet_action_button.xml @@ -0,0 +1,43 @@ + + + + + + + + + + + + From 9f3176c49cd3a8b45e4a895e758212a0f4d3e5be Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Mon, 28 Dec 2020 14:41:23 +0100 Subject: [PATCH 23/41] Fix code quality --- tools/check/forbidden_strings_in_code.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/check/forbidden_strings_in_code.txt b/tools/check/forbidden_strings_in_code.txt index b9929dfebe..2306eaed8b 100644 --- a/tools/check/forbidden_strings_in_code.txt +++ b/tools/check/forbidden_strings_in_code.txt @@ -161,7 +161,7 @@ Formatter\.formatShortFileSize===1 # android\.text\.TextUtils ### This is not a rule, but a warning: the number of "enum class" has changed. For Json classes, it is mandatory that they have `@JsonClass(generateAdapter = false)`. If the enum is not used as a Json class, change the value in file forbidden_strings_in_code.txt -enum class===84 +enum class===85 ### Do not import temporary legacy classes import org.matrix.android.sdk.internal.legacy.riot===3 From cc01f25d8f00e6c3cdee9b1cc98155e76413ac24 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Mon, 28 Dec 2020 14:52:49 +0100 Subject: [PATCH 24/41] Revert status to RoomMembersLoadStatusType.NONE) in case of failure --- .../room/membership/LoadRoomMembersTask.kt | 24 +++++++++++++------ 1 file changed, 17 insertions(+), 7 deletions(-) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/membership/LoadRoomMembersTask.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/membership/LoadRoomMembersTask.kt index 55dd747fdb..53fa73c624 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/membership/LoadRoomMembersTask.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/membership/LoadRoomMembersTask.kt @@ -82,16 +82,19 @@ internal class DefaultLoadRoomMembersTask @Inject constructor( } private suspend fun doRequest(params: LoadRoomMembersTask.Params) { - monarchy.awaitTransaction { realm -> - val roomEntity = RoomEntity.where(realm, params.roomId).findFirst() - ?: realm.createObject(params.roomId) - roomEntity.membersLoadStatus = RoomMembersLoadStatusType.LOADING - } + setRoomMembersLoadStatus(params.roomId, RoomMembersLoadStatusType.LOADING) val lastToken = syncTokenStore.getLastToken() - val response = executeRequest(eventBus) { - apiCall = roomAPI.getMembers(params.roomId, lastToken, null, params.excludeMembership?.value) + val response = try { + executeRequest(eventBus) { + apiCall = roomAPI.getMembers(params.roomId, lastToken, null, params.excludeMembership?.value) + } + } catch (throwable: Throwable) { + // Revert status to NONE + setRoomMembersLoadStatus(params.roomId, RoomMembersLoadStatusType.NONE) + throw throwable } + // This will also set the status to LOADED insertInDb(response, params.roomId) } @@ -125,4 +128,11 @@ internal class DefaultLoadRoomMembersTask @Inject constructor( } return result ?: RoomMembersLoadStatusType.NONE } + + private suspend fun setRoomMembersLoadStatus(roomId: String, status: RoomMembersLoadStatusType) { + monarchy.awaitTransaction { realm -> + val roomEntity = RoomEntity.where(realm, roomId).findFirst() ?: realm.createObject(roomId) + roomEntity.membersLoadStatus = status + } + } } From cbdacc199ab08ff93c3d6ee950a278e8ef067ced Mon Sep 17 00:00:00 2001 From: Onuray Sahin Date: Mon, 28 Dec 2020 17:17:01 +0300 Subject: [PATCH 25/41] Disable scroll effect when click to a link in the topic. --- CHANGES.md | 1 + .../app/core/epoxy/ExpandableTextItem.kt | 7 +++-- .../app/core/ui/views/NonScrollingTextView.kt | 31 +++++++++++++++++++ .../roomprofile/RoomProfileController.kt | 13 ++++++++ .../roomprofile/RoomProfileFragment.kt | 4 +++ .../res/layout/item_expandable_textview.xml | 2 +- 6 files changed, 55 insertions(+), 3 deletions(-) create mode 100644 vector/src/main/java/im/vector/app/core/ui/views/NonScrollingTextView.kt diff --git a/CHANGES.md b/CHANGES.md index a028ef6f1e..27229361a7 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -9,6 +9,7 @@ Improvements 🙌: Bugfix 🐛: - Url previews sometimes attached to wrong message (#2561) + - Room Topic not displayed correctly after visiting a link (#2551) Translations 🗣: - diff --git a/vector/src/main/java/im/vector/app/core/epoxy/ExpandableTextItem.kt b/vector/src/main/java/im/vector/app/core/epoxy/ExpandableTextItem.kt index 3dceec48ef..eb8d4a41c4 100644 --- a/vector/src/main/java/im/vector/app/core/epoxy/ExpandableTextItem.kt +++ b/vector/src/main/java/im/vector/app/core/epoxy/ExpandableTextItem.kt @@ -18,6 +18,7 @@ package im.vector.app.core.epoxy import android.animation.ObjectAnimator import android.text.TextUtils +import android.text.method.MovementMethod import android.widget.ImageView import android.widget.TextView import androidx.core.view.doOnPreDraw @@ -25,7 +26,6 @@ import androidx.core.view.isVisible import com.airbnb.epoxy.EpoxyAttribute import com.airbnb.epoxy.EpoxyModelClass import im.vector.app.R -import im.vector.app.core.extensions.copyOnLongClick @EpoxyModelClass(layout = R.layout.item_expandable_textview) abstract class ExpandableTextItem : VectorEpoxyModel() { @@ -36,13 +36,16 @@ abstract class ExpandableTextItem : VectorEpoxyModel( @EpoxyAttribute var maxLines: Int = 3 + @EpoxyAttribute(EpoxyAttribute.Option.DoNotHash) + var movementMethod: MovementMethod? = null + private var isExpanded = false private var expandedLines = 0 override fun bind(holder: Holder) { super.bind(holder) holder.content.text = content - holder.content.copyOnLongClick() + holder.content.movementMethod = movementMethod holder.content.doOnPreDraw { if (holder.content.lineCount > maxLines) { diff --git a/vector/src/main/java/im/vector/app/core/ui/views/NonScrollingTextView.kt b/vector/src/main/java/im/vector/app/core/ui/views/NonScrollingTextView.kt new file mode 100644 index 0000000000..712432abfd --- /dev/null +++ b/vector/src/main/java/im/vector/app/core/ui/views/NonScrollingTextView.kt @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2020 New Vector Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package im.vector.app.core.ui.views + +import android.content.Context +import android.util.AttributeSet +import androidx.appcompat.widget.AppCompatTextView + +class NonScrollingTextView : AppCompatTextView { + constructor(context: Context) : super(context) + constructor(context: Context, attrs: AttributeSet) : super(context, attrs) + constructor(context: Context, attrs: AttributeSet, defStyleAttr: Int) : super(context, attrs, defStyleAttr) + + override fun scrollTo(x: Int, y: Int) { + // NOOP + } +} diff --git a/vector/src/main/java/im/vector/app/features/roomprofile/RoomProfileController.kt b/vector/src/main/java/im/vector/app/features/roomprofile/RoomProfileController.kt index 891d15d04f..6b988df94d 100644 --- a/vector/src/main/java/im/vector/app/features/roomprofile/RoomProfileController.kt +++ b/vector/src/main/java/im/vector/app/features/roomprofile/RoomProfileController.kt @@ -26,6 +26,8 @@ import im.vector.app.core.resources.ColorProvider import im.vector.app.core.resources.StringProvider import im.vector.app.core.ui.list.genericFooterItem import im.vector.app.features.home.ShortcutCreator +import im.vector.app.features.home.room.detail.timeline.TimelineEventController +import im.vector.app.features.home.room.detail.timeline.tools.createLinkMovementMethod import im.vector.app.features.settings.VectorPreferences import org.matrix.android.sdk.api.crypto.RoomEncryptionTrustLevel import org.matrix.android.sdk.api.session.room.model.RoomSummary @@ -53,6 +55,7 @@ class RoomProfileController @Inject constructor( fun onSettingsClicked() fun onLeaveRoomClicked() fun onRoomIdClicked() + fun onUrlInTopicLongClicked(url: String) } override fun buildModels(data: RoomProfileViewState?) { @@ -71,6 +74,16 @@ class RoomProfileController @Inject constructor( id("topic") content(it) maxLines(2) + movementMethod(createLinkMovementMethod(object : TimelineEventController.UrlClickCallback { + override fun onUrlClicked(url: String, title: String): Boolean { + return false + } + + override fun onUrlLongClicked(url: String): Boolean { + callback?.onUrlInTopicLongClicked(url) + return true + } + })) } } diff --git a/vector/src/main/java/im/vector/app/features/roomprofile/RoomProfileFragment.kt b/vector/src/main/java/im/vector/app/features/roomprofile/RoomProfileFragment.kt index 473c1d4324..44e17a1681 100644 --- a/vector/src/main/java/im/vector/app/features/roomprofile/RoomProfileFragment.kt +++ b/vector/src/main/java/im/vector/app/features/roomprofile/RoomProfileFragment.kt @@ -261,6 +261,10 @@ class RoomProfileFragment @Inject constructor( copyToClipboard(requireContext(), roomProfileArgs.roomId) } + override fun onUrlInTopicLongClicked(url: String) { + copyToClipboard(requireContext(), url, true) + } + private fun onShareRoomProfile(permalink: String) { startSharePlainTextIntent( fragment = this, diff --git a/vector/src/main/res/layout/item_expandable_textview.xml b/vector/src/main/res/layout/item_expandable_textview.xml index 9f61a3c4d4..4dc7085737 100644 --- a/vector/src/main/res/layout/item_expandable_textview.xml +++ b/vector/src/main/res/layout/item_expandable_textview.xml @@ -6,7 +6,7 @@ android:layout_height="wrap_content" android:padding="16dp"> - Date: Mon, 28 Dec 2020 23:32:06 -0500 Subject: [PATCH 26/41] Add System theme option and set as default; closes #904, closes #2387 --- CHANGES.md | 2 +- .../vector/app/features/themes/ThemeUtils.kt | 26 +++++++++++++------ vector/src/main/res/values/array.xml | 2 ++ vector/src/main/res/values/strings.xml | 1 + .../res/xml/vector_settings_preferences.xml | 2 +- 5 files changed, 23 insertions(+), 10 deletions(-) diff --git a/CHANGES.md b/CHANGES.md index a028ef6f1e..5ab9ff733d 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -5,7 +5,7 @@ Features ✨: - Enable url previews for notices (#2562) Improvements 🙌: - - + - Add System theme option and set as default (#904) (#2387) Bugfix 🐛: - Url previews sometimes attached to wrong message (#2561) diff --git a/vector/src/main/java/im/vector/app/features/themes/ThemeUtils.kt b/vector/src/main/java/im/vector/app/features/themes/ThemeUtils.kt index bba6b9c253..172303cff7 100644 --- a/vector/src/main/java/im/vector/app/features/themes/ThemeUtils.kt +++ b/vector/src/main/java/im/vector/app/features/themes/ThemeUtils.kt @@ -18,6 +18,8 @@ package im.vector.app.features.themes import android.app.Activity import android.content.Context +import android.content.res.Configuration +import android.content.res.Resources import android.graphics.drawable.Drawable import android.util.TypedValue import android.view.Menu @@ -39,6 +41,7 @@ object ThemeUtils { const val APPLICATION_THEME_KEY = "APPLICATION_THEME_KEY" // the theme possible values + private const val SYSTEM_THEME_VALUE = "system" private const val THEME_DARK_VALUE = "dark" private const val THEME_LIGHT_VALUE = "light" private const val THEME_BLACK_VALUE = "black" @@ -54,13 +57,11 @@ object ThemeUtils { } /** - * @return true if current theme is Light or Status + * @return true if current theme is Light/Status or current theme is System and system theme is light */ fun isLightTheme(context: Context): Boolean { - return when (getApplicationTheme(context)) { - THEME_LIGHT_VALUE -> true - else -> false - } + val theme = getApplicationTheme(context) + return theme == THEME_LIGHT_VALUE || (theme == SYSTEM_THEME_VALUE && !isSystemDarkTheme(context.resources)) } /** @@ -73,11 +74,11 @@ object ThemeUtils { val currentTheme = this.currentTheme.get() return if (currentTheme == null) { val prefs = DefaultSharedPreferences.getInstance(context) - var themeFromPref = prefs.getString(APPLICATION_THEME_KEY, THEME_LIGHT_VALUE) ?: THEME_LIGHT_VALUE + var themeFromPref = prefs.getString(APPLICATION_THEME_KEY, SYSTEM_THEME_VALUE) ?: SYSTEM_THEME_VALUE if (themeFromPref == "status") { // Migrate to light theme, which is the closest theme - themeFromPref = THEME_LIGHT_VALUE - prefs.edit { putString(APPLICATION_THEME_KEY, THEME_LIGHT_VALUE) } + themeFromPref = SYSTEM_THEME_VALUE + prefs.edit { putString(APPLICATION_THEME_KEY, SYSTEM_THEME_VALUE) } } this.currentTheme.set(themeFromPref) themeFromPref @@ -86,6 +87,13 @@ object ThemeUtils { } } + /** + * @return true if system theme is dark + */ + private fun isSystemDarkTheme(resources: Resources): Boolean { + return resources.configuration.uiMode and Configuration.UI_MODE_NIGHT_MASK == Configuration.UI_MODE_NIGHT_YES + } + /** * Update the application theme * @@ -94,6 +102,7 @@ object ThemeUtils { fun setApplicationTheme(context: Context, aTheme: String) { currentTheme.set(aTheme) when (aTheme) { + SYSTEM_THEME_VALUE -> context.setTheme(if(isSystemDarkTheme(context.resources)) R.style.AppTheme_Dark else R.style.AppTheme_Light) THEME_DARK_VALUE -> context.setTheme(R.style.AppTheme_Dark) THEME_BLACK_VALUE -> context.setTheme(R.style.AppTheme_Black) else -> context.setTheme(R.style.AppTheme_Light) @@ -110,6 +119,7 @@ object ThemeUtils { */ fun setActivityTheme(activity: Activity, otherThemes: ActivityOtherThemes) { when (getApplicationTheme(activity)) { + SYSTEM_THEME_VALUE -> if(isSystemDarkTheme(activity.resources)) activity.setTheme(otherThemes.dark) THEME_DARK_VALUE -> activity.setTheme(otherThemes.dark) THEME_BLACK_VALUE -> activity.setTheme(otherThemes.black) } diff --git a/vector/src/main/res/values/array.xml b/vector/src/main/res/values/array.xml index e56844e2e8..2c4bc135e5 100644 --- a/vector/src/main/res/values/array.xml +++ b/vector/src/main/res/values/array.xml @@ -92,12 +92,14 @@ + @string/system_theme @string/light_theme @string/dark_theme @string/black_them + system light dark black diff --git a/vector/src/main/res/values/strings.xml b/vector/src/main/res/values/strings.xml index 76541460d2..355ac4d6d6 100644 --- a/vector/src/main/res/values/strings.xml +++ b/vector/src/main/res/values/strings.xml @@ -8,6 +8,7 @@ Latn + System Default Light Theme Dark Theme Black Theme diff --git a/vector/src/main/res/xml/vector_settings_preferences.xml b/vector/src/main/res/xml/vector_settings_preferences.xml index 74b1f882ee..6297b89e6c 100644 --- a/vector/src/main/res/xml/vector_settings_preferences.xml +++ b/vector/src/main/res/xml/vector_settings_preferences.xml @@ -13,7 +13,7 @@ app:fragment="im.vector.app.features.settings.locale.LocalePickerFragment" /> Date: Tue, 29 Dec 2020 00:22:12 -0500 Subject: [PATCH 27/41] Fix formatting in ThemeUtils --- .../src/main/java/im/vector/app/features/themes/ThemeUtils.kt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/vector/src/main/java/im/vector/app/features/themes/ThemeUtils.kt b/vector/src/main/java/im/vector/app/features/themes/ThemeUtils.kt index 172303cff7..e3ef6a2b0b 100644 --- a/vector/src/main/java/im/vector/app/features/themes/ThemeUtils.kt +++ b/vector/src/main/java/im/vector/app/features/themes/ThemeUtils.kt @@ -102,7 +102,7 @@ object ThemeUtils { fun setApplicationTheme(context: Context, aTheme: String) { currentTheme.set(aTheme) when (aTheme) { - SYSTEM_THEME_VALUE -> context.setTheme(if(isSystemDarkTheme(context.resources)) R.style.AppTheme_Dark else R.style.AppTheme_Light) + SYSTEM_THEME_VALUE -> context.setTheme(if (isSystemDarkTheme(context.resources)) R.style.AppTheme_Dark else R.style.AppTheme_Light) THEME_DARK_VALUE -> context.setTheme(R.style.AppTheme_Dark) THEME_BLACK_VALUE -> context.setTheme(R.style.AppTheme_Black) else -> context.setTheme(R.style.AppTheme_Light) @@ -119,7 +119,7 @@ object ThemeUtils { */ fun setActivityTheme(activity: Activity, otherThemes: ActivityOtherThemes) { when (getApplicationTheme(activity)) { - SYSTEM_THEME_VALUE -> if(isSystemDarkTheme(activity.resources)) activity.setTheme(otherThemes.dark) + SYSTEM_THEME_VALUE -> if (isSystemDarkTheme(activity.resources)) activity.setTheme(otherThemes.dark) THEME_DARK_VALUE -> activity.setTheme(otherThemes.dark) THEME_BLACK_VALUE -> activity.setTheme(otherThemes.black) } From f1f1613f008260079851a369422a60b18a766f2d Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Tue, 29 Dec 2020 09:56:15 +0100 Subject: [PATCH 28/41] Cleanup and format --- .../vector/app/features/themes/ThemeUtils.kt | 64 ++++++------------- 1 file changed, 18 insertions(+), 46 deletions(-) diff --git a/vector/src/main/java/im/vector/app/features/themes/ThemeUtils.kt b/vector/src/main/java/im/vector/app/features/themes/ThemeUtils.kt index e3ef6a2b0b..0856ac4b35 100644 --- a/vector/src/main/java/im/vector/app/features/themes/ThemeUtils.kt +++ b/vector/src/main/java/im/vector/app/features/themes/ThemeUtils.kt @@ -46,6 +46,9 @@ object ThemeUtils { private const val THEME_LIGHT_VALUE = "light" private const val THEME_BLACK_VALUE = "black" + // The default theme + private const val DEFAULT_THEME = SYSTEM_THEME_VALUE + private var currentTheme = AtomicReference(null) private val mColorByAttr = HashMap() @@ -57,11 +60,12 @@ object ThemeUtils { } /** - * @return true if current theme is Light/Status or current theme is System and system theme is light + * @return true if current theme is Light or current theme is System and system theme is light */ fun isLightTheme(context: Context): Boolean { val theme = getApplicationTheme(context) - return theme == THEME_LIGHT_VALUE || (theme == SYSTEM_THEME_VALUE && !isSystemDarkTheme(context.resources)) + return theme == THEME_LIGHT_VALUE + || (theme == SYSTEM_THEME_VALUE && !isSystemDarkTheme(context.resources)) } /** @@ -74,11 +78,11 @@ object ThemeUtils { val currentTheme = this.currentTheme.get() return if (currentTheme == null) { val prefs = DefaultSharedPreferences.getInstance(context) - var themeFromPref = prefs.getString(APPLICATION_THEME_KEY, SYSTEM_THEME_VALUE) ?: SYSTEM_THEME_VALUE + var themeFromPref = prefs.getString(APPLICATION_THEME_KEY, DEFAULT_THEME) ?: DEFAULT_THEME if (themeFromPref == "status") { - // Migrate to light theme, which is the closest theme - themeFromPref = SYSTEM_THEME_VALUE - prefs.edit { putString(APPLICATION_THEME_KEY, SYSTEM_THEME_VALUE) } + // Migrate to the default theme + themeFromPref = DEFAULT_THEME + prefs.edit { putString(APPLICATION_THEME_KEY, DEFAULT_THEME) } } this.currentTheme.set(themeFromPref) themeFromPref @@ -101,12 +105,14 @@ object ThemeUtils { */ fun setApplicationTheme(context: Context, aTheme: String) { currentTheme.set(aTheme) - when (aTheme) { - SYSTEM_THEME_VALUE -> context.setTheme(if (isSystemDarkTheme(context.resources)) R.style.AppTheme_Dark else R.style.AppTheme_Light) - THEME_DARK_VALUE -> context.setTheme(R.style.AppTheme_Dark) - THEME_BLACK_VALUE -> context.setTheme(R.style.AppTheme_Black) - else -> context.setTheme(R.style.AppTheme_Light) - } + context.setTheme( + when (aTheme) { + SYSTEM_THEME_VALUE -> if (isSystemDarkTheme(context.resources)) R.style.AppTheme_Dark else R.style.AppTheme_Light + THEME_DARK_VALUE -> R.style.AppTheme_Dark + THEME_BLACK_VALUE -> R.style.AppTheme_Black + else -> R.style.AppTheme_Light + } + ) // Clear the cache mColorByAttr.clear() @@ -127,40 +133,6 @@ object ThemeUtils { mColorByAttr.clear() } - /** - * Set the TabLayout colors. - * It seems that there is no proper way to manage it with the manifest file. - * - * @param activity the activity - * @param layout the layout - */ - /* - fun setTabLayoutTheme(activity: Activity, layout: TabLayout) { - if (activity is VectorGroupDetailsActivity) { - val textColor: Int - val underlineColor: Int - val backgroundColor: Int - - if (TextUtils.equals(getApplicationTheme(activity), THEME_LIGHT_VALUE)) { - textColor = ContextCompat.getColor(activity, android.R.color.white) - underlineColor = textColor - backgroundColor = ContextCompat.getColor(activity, R.color.tab_groups) - } else if (TextUtils.equals(getApplicationTheme(activity), THEME_STATUS_VALUE)) { - textColor = ContextCompat.getColor(activity, android.R.color.white) - underlineColor = textColor - backgroundColor = getColor(activity, R.attr.colorPrimary) - } else { - textColor = ContextCompat.getColor(activity, R.color.tab_groups) - underlineColor = textColor - backgroundColor = getColor(activity, R.attr.colorPrimary) - } - - layout.setTabTextColors(textColor, textColor) - layout.setSelectedTabIndicatorColor(underlineColor) - layout.setBackgroundColor(backgroundColor) - } - } */ - /** * Translates color attributes to colors * From 3ea3d0fc918e4b213ab9700155d54b2b80c0262a Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Tue, 29 Dec 2020 15:42:12 +0100 Subject: [PATCH 29/41] Unspecced msgType field in m.sticker (#2580) --- CHANGES.md | 1 + .../sdk/api/session/room/model/message/MessageStickerContent.kt | 1 + 2 files changed, 2 insertions(+) diff --git a/CHANGES.md b/CHANGES.md index 373c3aa985..a35c2fdd10 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -8,6 +8,7 @@ Improvements 🙌: - Add System theme option and set as default (#904) (#2387) Bugfix 🐛: + - Unspecced msgType field in m.sticker (#2580) - Wait for all room members to be known before sending a message to a e2e room (#2518) - Url previews sometimes attached to wrong message (#2561) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/model/message/MessageStickerContent.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/model/message/MessageStickerContent.kt index 00fa68c0ac..280316d4b5 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/model/message/MessageStickerContent.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/model/message/MessageStickerContent.kt @@ -27,6 +27,7 @@ data class MessageStickerContent( /** * Set in local, not from server */ + @Transient override val msgType: String = MessageType.MSGTYPE_STICKER_LOCAL, /** From 3240cadb94b3faed6674eb05d8506e7cb9956b46 Mon Sep 17 00:00:00 2001 From: Onuray Sahin Date: Wed, 30 Dec 2020 12:08:27 +0300 Subject: [PATCH 30/41] Fix membership event visibility condition. --- CHANGES.md | 1 + .../home/room/detail/timeline/helper/TimelineSettingsFactory.kt | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/CHANGES.md b/CHANGES.md index 373c3aa985..74710baf48 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -10,6 +10,7 @@ Improvements 🙌: Bugfix 🐛: - Wait for all room members to be known before sending a message to a e2e room (#2518) - Url previews sometimes attached to wrong message (#2561) + - Fix member state filter (#2581) Translations 🗣: - diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/helper/TimelineSettingsFactory.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/helper/TimelineSettingsFactory.kt index 1983b05ed3..01c7ad3986 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/helper/TimelineSettingsFactory.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/helper/TimelineSettingsFactory.kt @@ -57,7 +57,7 @@ class TimelineSettingsFactory @Inject constructor( return map { EventTypeFilter( eventType = it, - stateKey = if (it == EventType.STATE_ROOM_MEMBER && userPreferencesProvider.shouldShowRoomMemberStateEvents()) session.myUserId else null + stateKey = if (it == EventType.STATE_ROOM_MEMBER && !userPreferencesProvider.shouldShowRoomMemberStateEvents()) session.myUserId else null ) } } From 05013d25594ccd14a8a19f058d2b5a2c330da5a7 Mon Sep 17 00:00:00 2001 From: Onuray Sahin Date: Wed, 30 Dec 2020 12:17:25 +0300 Subject: [PATCH 31/41] Fix changelog. --- CHANGES.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGES.md b/CHANGES.md index 74710baf48..1fa3eb8e4b 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -10,7 +10,7 @@ Improvements 🙌: Bugfix 🐛: - Wait for all room members to be known before sending a message to a e2e room (#2518) - Url previews sometimes attached to wrong message (#2561) - - Fix member state filter (#2581) + - Hiding membership events works the exact opposite (#2603) Translations 🗣: - From 11367488e6726012526bd6141ec4d954c419bb86 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Mon, 4 Jan 2021 14:21:57 +0100 Subject: [PATCH 32/41] Fix crash in AttachmentViewerActivity (after ViewBindings) And improve code a bit --- .../AttachmentViewerActivity.kt | 22 ++++++++++--------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/attachment-viewer/src/main/java/im/vector/lib/attachmentviewer/AttachmentViewerActivity.kt b/attachment-viewer/src/main/java/im/vector/lib/attachmentviewer/AttachmentViewerActivity.kt index ae095be41a..9b1345cd39 100644 --- a/attachment-viewer/src/main/java/im/vector/lib/attachmentviewer/AttachmentViewerActivity.kt +++ b/attachment-viewer/src/main/java/im/vector/lib/attachmentviewer/AttachmentViewerActivity.kt @@ -40,13 +40,16 @@ import kotlin.math.abs abstract class AttachmentViewerActivity : AppCompatActivity(), AttachmentEventListener { - lateinit var pager2: ViewPager2 - lateinit var imageTransitionView: ImageView - lateinit var transitionImageContainer: ViewGroup + protected val pager2: ViewPager2 + get() = views.attachmentPager + protected val imageTransitionView: ImageView + get() = views.transitionImageView + protected val transitionImageContainer: ViewGroup + get() = views.transitionImageContainer - var topInset = 0 - var bottomInset = 0 - var systemUiVisibility = true + private var topInset = 0 + private var bottomInset = 0 + private var systemUiVisibility = true private var overlayView: View? = null set(value) { @@ -65,14 +68,16 @@ abstract class AttachmentViewerActivity : AppCompatActivity(), AttachmentEventLi private lateinit var gestureDetector: GestureDetectorCompat var currentPosition = 0 + private set private var swipeDirection: SwipeDirection? = null private fun isScaled() = attachmentsAdapter.isScaled(currentPosition) + private val attachmentsAdapter = AttachmentsAdapter() + private var wasScaled: Boolean = false private var isSwipeToDismissAllowed: Boolean = true - private lateinit var attachmentsAdapter: AttachmentsAdapter private var isOverlayWasClicked = false // private val shouldDismissToBottom: Boolean @@ -101,10 +106,7 @@ abstract class AttachmentViewerActivity : AppCompatActivity(), AttachmentEventLi views = ActivityAttachmentViewerBinding.inflate(layoutInflater) setContentView(views.root) views.attachmentPager.orientation = ViewPager2.ORIENTATION_HORIZONTAL - attachmentsAdapter = AttachmentsAdapter() views.attachmentPager.adapter = attachmentsAdapter - imageTransitionView = views.transitionImageView - pager2 = views.attachmentPager directionDetector = createSwipeDirectionDetector() gestureDetector = createGestureDetector() From c11a50f7ff0748d88d75fbee745338c7ed910a8c Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Mon, 4 Jan 2021 18:07:47 +0100 Subject: [PATCH 33/41] Malformed matrix.to link: display a dialog instead of a toast --- .../main/java/im/vector/app/features/home/HomeActivity.kt | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/vector/src/main/java/im/vector/app/features/home/HomeActivity.kt b/vector/src/main/java/im/vector/app/features/home/HomeActivity.kt index 9d7beb13a3..c4c8da551c 100644 --- a/vector/src/main/java/im/vector/app/features/home/HomeActivity.kt +++ b/vector/src/main/java/im/vector/app/features/home/HomeActivity.kt @@ -39,7 +39,6 @@ import im.vector.app.core.extensions.replaceFragment import im.vector.app.core.platform.ToolbarConfigurable import im.vector.app.core.platform.VectorBaseActivity import im.vector.app.core.pushers.PushersManager -import im.vector.app.core.utils.toast import im.vector.app.databinding.ActivityHomeBinding import im.vector.app.features.disclaimer.showDisclaimerDialog import im.vector.app.features.matrixto.MatrixToBottomSheet @@ -190,7 +189,11 @@ class HomeActivity : .observeOn(AndroidSchedulers.mainThread()) .subscribe { isHandled -> if (!isHandled) { - toast(R.string.permalink_malformed) + AlertDialog.Builder(this) + .setTitle(R.string.dialog_title_error) + .setMessage(R.string.permalink_malformed) + .setPositiveButton(R.string.ok, null) + .show() } } .disposeOnDestroy() From c34fea2932dd9e17a04b9d5196e67e349788d413 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Mon, 4 Jan 2021 18:16:12 +0100 Subject: [PATCH 34/41] Do not defien Element Stuff in the SDK --- .../sdk/api/session/permalinks/PermalinkService.kt | 1 - .../java/im/vector/app/features/home/HomeActivity.kt | 11 ++++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/permalinks/PermalinkService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/permalinks/PermalinkService.kt index aefc086b43..ac1d726d03 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/permalinks/PermalinkService.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/permalinks/PermalinkService.kt @@ -25,7 +25,6 @@ interface PermalinkService { companion object { const val MATRIX_TO_URL_BASE = "https://matrix.to/#/" - const val MATRIX_TO_CUSTOM_SCHEME_URL_BASE = "element://" } /** diff --git a/vector/src/main/java/im/vector/app/features/home/HomeActivity.kt b/vector/src/main/java/im/vector/app/features/home/HomeActivity.kt index c4c8da551c..3d8d8bb961 100644 --- a/vector/src/main/java/im/vector/app/features/home/HomeActivity.kt +++ b/vector/src/main/java/im/vector/app/features/home/HomeActivity.kt @@ -165,8 +165,8 @@ class HomeActivity : private fun handleIntent(intent: Intent?) { intent?.dataString?.let { deepLink -> val resolvedLink = when { - deepLink.startsWith(PermalinkService.MATRIX_TO_URL_BASE) -> deepLink - deepLink.startsWith(PermalinkService.MATRIX_TO_CUSTOM_SCHEME_URL_BASE) -> { + deepLink.startsWith(PermalinkService.MATRIX_TO_URL_BASE) -> deepLink + deepLink.startsWith(MATRIX_TO_CUSTOM_SCHEME_URL_BASE) -> { // This is a bit ugly, but for now just convert to matrix.to link for compatibility when { deepLink.startsWith(USER_LINK_PREFIX) -> deepLink.substring(USER_LINK_PREFIX.length) @@ -176,7 +176,7 @@ class HomeActivity : activeSessionHolder.getSafeActiveSession()?.permalinkService()?.createPermalink(it) } } - else -> null + else -> null } permalinkHandler.launch( @@ -413,7 +413,8 @@ class HomeActivity : } } - private const val ROOM_LINK_PREFIX = "${PermalinkService.MATRIX_TO_CUSTOM_SCHEME_URL_BASE}room/" - private const val USER_LINK_PREFIX = "${PermalinkService.MATRIX_TO_CUSTOM_SCHEME_URL_BASE}user/" + private const val MATRIX_TO_CUSTOM_SCHEME_URL_BASE = "element://" + private const val ROOM_LINK_PREFIX = "${MATRIX_TO_CUSTOM_SCHEME_URL_BASE}room/" + private const val USER_LINK_PREFIX = "${MATRIX_TO_CUSTOM_SCHEME_URL_BASE}user/" } } From 4f59ec37ca37a414d4ce43bf882f726ad4fc5de0 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Mon, 4 Jan 2021 18:18:34 +0100 Subject: [PATCH 35/41] Tapping drawer having more than 1 room in notifications gives "malformed link" error (#2605) --- CHANGES.md | 1 + .../src/main/java/im/vector/app/features/home/HomeActivity.kt | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/CHANGES.md b/CHANGES.md index eaaa4c1b0a..7d4678fe40 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -12,6 +12,7 @@ Bugfix 🐛: - Wait for all room members to be known before sending a message to a e2e room (#2518) - Url previews sometimes attached to wrong message (#2561) - Hiding membership events works the exact opposite (#2603) + - Tapping drawer having more than 1 room in notifications gives "malformed link" error (#2605) Translations 🗣: - diff --git a/vector/src/main/java/im/vector/app/features/home/HomeActivity.kt b/vector/src/main/java/im/vector/app/features/home/HomeActivity.kt index 3d8d8bb961..108e0512a7 100644 --- a/vector/src/main/java/im/vector/app/features/home/HomeActivity.kt +++ b/vector/src/main/java/im/vector/app/features/home/HomeActivity.kt @@ -176,7 +176,7 @@ class HomeActivity : activeSessionHolder.getSafeActiveSession()?.permalinkService()?.createPermalink(it) } } - else -> null + else -> return@let } permalinkHandler.launch( From 3a9b80127f807e263e5143b03fe60ad0cd70d9bb Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Tue, 5 Jan 2021 11:46:59 +0100 Subject: [PATCH 36/41] Warn user when he is leaving a not public room (#1460) --- CHANGES.md | 3 +- .../room/state/StateServiceExtension.kt | 33 +++++++++++++++++ .../home/room/list/RoomListFragment.kt | 36 ++++++++++++++----- .../home/room/list/RoomListViewModel.kt | 5 +++ .../roomprofile/RoomProfileFragment.kt | 17 ++++++++- .../roomprofile/RoomProfileViewModel.kt | 5 +++ vector/src/main/res/values/strings.xml | 1 + 7 files changed, 89 insertions(+), 11 deletions(-) create mode 100644 matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/state/StateServiceExtension.kt diff --git a/CHANGES.md b/CHANGES.md index 7d4678fe40..0ddd9572ea 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -5,7 +5,8 @@ Features ✨: - Enable url previews for notices (#2562) Improvements 🙌: - - Add System theme option and set as default (#904) (#2387) + - Add System theme option and set as default (#904, #2387) + - Warn user when he is leaving a not public room (#1460) Bugfix 🐛: - Unspecced msgType field in m.sticker (#2580) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/state/StateServiceExtension.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/state/StateServiceExtension.kt new file mode 100644 index 0000000000..c625a7f088 --- /dev/null +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/state/StateServiceExtension.kt @@ -0,0 +1,33 @@ +/* + * Copyright 2020 The Matrix.org Foundation C.I.C. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.matrix.android.sdk.api.session.room.state + +import org.matrix.android.sdk.api.query.QueryStringValue +import org.matrix.android.sdk.api.session.events.model.EventType +import org.matrix.android.sdk.api.session.events.model.toModel +import org.matrix.android.sdk.api.session.room.model.RoomJoinRules +import org.matrix.android.sdk.api.session.room.model.RoomJoinRulesContent + +/** + * Return true if a room can be joined by anyone (RoomJoinRules.PUBLIC) + */ +fun StateService.isPublic(): Boolean { + return getStateEvent(EventType.STATE_ROOM_JOIN_RULES, QueryStringValue.NoCondition) + ?.content + ?.toModel() + ?.joinRules == RoomJoinRules.PUBLIC +} diff --git a/vector/src/main/java/im/vector/app/features/home/room/list/RoomListFragment.kt b/vector/src/main/java/im/vector/app/features/home/room/list/RoomListFragment.kt index 02a277f377..30cb360a9d 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/list/RoomListFragment.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/list/RoomListFragment.kt @@ -16,6 +16,7 @@ package im.vector.app.features.home.room.list +import android.content.DialogInterface import android.os.Bundle import android.os.Parcelable import android.view.LayoutInflater @@ -36,6 +37,7 @@ import com.airbnb.mvrx.args import com.airbnb.mvrx.fragmentViewModel import com.airbnb.mvrx.withState import im.vector.app.R +import im.vector.app.core.dialogs.withColoredButton import im.vector.app.core.epoxy.LayoutManagerStateRestorer import im.vector.app.core.extensions.cleanup import im.vector.app.core.extensions.exhaustive @@ -246,19 +248,35 @@ class RoomListFragment @Inject constructor( roomListViewModel.handle(RoomListAction.ToggleTag(quickAction.roomId, RoomTag.ROOM_TAG_LOW_PRIORITY)) } is RoomListQuickActionsSharedAction.Leave -> { - AlertDialog.Builder(requireContext()) - .setTitle(R.string.room_participants_leave_prompt_title) - .setMessage(R.string.room_participants_leave_prompt_msg) - .setPositiveButton(R.string.leave) { _, _ -> - roomListViewModel.handle(RoomListAction.LeaveRoom(quickAction.roomId)) - } - .setNegativeButton(R.string.cancel, null) - .show() - Unit + promptLeaveRoom(quickAction.roomId) } }.exhaustive } + private fun promptLeaveRoom(roomId: String) { + val isPublicRoom = roomListViewModel.isPublicRoom(roomId) + val message = buildString { + append(getString(R.string.room_participants_leave_prompt_msg)) + if (!isPublicRoom) { + append("\n\n") + append(getString(R.string.room_participants_leave_private_warning)) + } + } + AlertDialog.Builder(requireContext()) + .setTitle(R.string.room_participants_leave_prompt_title) + .setMessage(message) + .setPositiveButton(R.string.leave) { _, _ -> + roomListViewModel.handle(RoomListAction.LeaveRoom(roomId)) + } + .setNegativeButton(R.string.cancel, null) + .show() + .apply { + if (!isPublicRoom) { + withColoredButton(DialogInterface.BUTTON_POSITIVE) + } + } + } + override fun invalidate() = withState(roomListViewModel) { state -> when (state.asyncFilteredRooms) { is Incomplete -> renderLoading() diff --git a/vector/src/main/java/im/vector/app/features/home/room/list/RoomListViewModel.kt b/vector/src/main/java/im/vector/app/features/home/room/list/RoomListViewModel.kt index 84652506cd..6e5081a31c 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/list/RoomListViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/list/RoomListViewModel.kt @@ -33,6 +33,7 @@ import org.matrix.android.sdk.api.session.Session import org.matrix.android.sdk.api.session.room.model.Membership import org.matrix.android.sdk.api.session.room.model.RoomSummary import org.matrix.android.sdk.api.session.room.model.tag.RoomTag +import org.matrix.android.sdk.api.session.room.state.isPublic import org.matrix.android.sdk.rx.rx import timber.log.Timber import java.lang.Exception @@ -78,6 +79,10 @@ class RoomListViewModel @Inject constructor(initialState: RoomListViewState, }.exhaustive } + fun isPublicRoom(roomId: String): Boolean { + return session.getRoom(roomId)?.isPublic().orFalse() + } + // PRIVATE METHODS ***************************************************************************** private fun handleSelectRoom(action: RoomListAction.SelectRoom) = withState { diff --git a/vector/src/main/java/im/vector/app/features/roomprofile/RoomProfileFragment.kt b/vector/src/main/java/im/vector/app/features/roomprofile/RoomProfileFragment.kt index 473c1d4324..53c5b25d6d 100644 --- a/vector/src/main/java/im/vector/app/features/roomprofile/RoomProfileFragment.kt +++ b/vector/src/main/java/im/vector/app/features/roomprofile/RoomProfileFragment.kt @@ -17,6 +17,7 @@ package im.vector.app.features.roomprofile +import android.content.DialogInterface import android.os.Bundle import android.os.Parcelable import android.view.LayoutInflater @@ -34,6 +35,7 @@ import com.airbnb.mvrx.withState import im.vector.app.R import im.vector.app.core.animations.AppBarStateChangeListener import im.vector.app.core.animations.MatrixItemAppBarStateChangeListener +import im.vector.app.core.dialogs.withColoredButton import im.vector.app.core.extensions.cleanup import im.vector.app.core.extensions.configureWith import im.vector.app.core.extensions.copyOnLongClick @@ -247,14 +249,27 @@ class RoomProfileFragment @Inject constructor( } override fun onLeaveRoomClicked() { + val isPublicRoom = roomProfileViewModel.isPublicRoom() + val message = buildString { + append(getString(R.string.room_participants_leave_prompt_msg)) + if (!isPublicRoom) { + append("\n\n") + append(getString(R.string.room_participants_leave_private_warning)) + } + } AlertDialog.Builder(requireContext()) .setTitle(R.string.room_participants_leave_prompt_title) - .setMessage(R.string.room_participants_leave_prompt_msg) + .setMessage(message) .setPositiveButton(R.string.leave) { _, _ -> roomProfileViewModel.handle(RoomProfileAction.LeaveRoom) } .setNegativeButton(R.string.cancel, null) .show() + .apply { + if (!isPublicRoom) { + withColoredButton(DialogInterface.BUTTON_POSITIVE) + } + } } override fun onRoomIdClicked() { diff --git a/vector/src/main/java/im/vector/app/features/roomprofile/RoomProfileViewModel.kt b/vector/src/main/java/im/vector/app/features/roomprofile/RoomProfileViewModel.kt index ec772ffcaa..cfdf1d9c0b 100644 --- a/vector/src/main/java/im/vector/app/features/roomprofile/RoomProfileViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/roomprofile/RoomProfileViewModel.kt @@ -37,6 +37,7 @@ import org.matrix.android.sdk.api.session.events.model.EventType import org.matrix.android.sdk.api.session.room.members.roomMemberQueryParams import org.matrix.android.sdk.api.session.room.model.Membership import org.matrix.android.sdk.api.session.room.powerlevels.PowerLevelsHelper +import org.matrix.android.sdk.api.session.room.state.isPublic import org.matrix.android.sdk.rx.RxRoom import org.matrix.android.sdk.rx.rx import org.matrix.android.sdk.rx.unwrap @@ -109,6 +110,10 @@ class RoomProfileViewModel @AssistedInject constructor( }.exhaustive } + fun isPublicRoom(): Boolean { + return room.isPublic() + } + private fun handleEnableEncryption() { postLoading(true) diff --git a/vector/src/main/res/values/strings.xml b/vector/src/main/res/values/strings.xml index 355ac4d6d6..4504febd1a 100644 --- a/vector/src/main/res/values/strings.xml +++ b/vector/src/main/res/values/strings.xml @@ -491,6 +491,7 @@ Leave room Are you sure you want to leave the room? + This room is not public. You will not be able to rejoin without an invite. Are you sure you want to remove %s from this chat? Create From 18d4b66c9779999f572f25750a904e4dfbdbec7f Mon Sep 17 00:00:00 2001 From: Onuray Sahin Date: Tue, 5 Jan 2021 15:06:50 +0300 Subject: [PATCH 37/41] Fix copy topic on long click. --- .../main/java/im/vector/app/core/epoxy/ExpandableTextItem.kt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/vector/src/main/java/im/vector/app/core/epoxy/ExpandableTextItem.kt b/vector/src/main/java/im/vector/app/core/epoxy/ExpandableTextItem.kt index eb8d4a41c4..218a22533a 100644 --- a/vector/src/main/java/im/vector/app/core/epoxy/ExpandableTextItem.kt +++ b/vector/src/main/java/im/vector/app/core/epoxy/ExpandableTextItem.kt @@ -26,6 +26,7 @@ import androidx.core.view.isVisible import com.airbnb.epoxy.EpoxyAttribute import com.airbnb.epoxy.EpoxyModelClass import im.vector.app.R +import im.vector.app.core.extensions.copyOnLongClick @EpoxyModelClass(layout = R.layout.item_expandable_textview) abstract class ExpandableTextItem : VectorEpoxyModel() { @@ -45,6 +46,7 @@ abstract class ExpandableTextItem : VectorEpoxyModel( override fun bind(holder: Holder) { super.bind(holder) holder.content.text = content + holder.content.copyOnLongClick() holder.content.movementMethod = movementMethod holder.content.doOnPreDraw { From 963c30a27562508c401c0f32c5faf5a4ca57bb1d Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Tue, 5 Jan 2021 18:55:09 +0100 Subject: [PATCH 38/41] Remove dependency to org.greenrobot.eventbus library --- CHANGES.md | 2 +- matrix-sdk-android/build.gradle | 3 - matrix-sdk-android/proguard-rules.pro | 8 +-- .../internal/network/GlobalErrorReceiver.kt} | 18 ++---- .../crypto/CancelGossipRequestWorker.kt | 2 - .../crypto/SendGossipRequestWorker.kt | 2 - .../sdk/internal/crypto/SendGossipWorker.kt | 2 - .../tasks/CreateKeysBackupVersionTask.kt | 6 +- .../keysbackup/tasks/DeleteBackupTask.kt | 6 +- .../tasks/DeleteRoomSessionDataTask.kt | 6 +- .../tasks/DeleteRoomSessionsDataTask.kt | 6 +- .../tasks/DeleteSessionsDataTask.kt | 6 +- .../tasks/GetKeysBackupLastVersionTask.kt | 6 +- .../tasks/GetKeysBackupVersionTask.kt | 6 +- .../tasks/GetRoomSessionDataTask.kt | 6 +- .../tasks/GetRoomSessionsDataTask.kt | 6 +- .../keysbackup/tasks/GetSessionsDataTask.kt | 6 +- .../tasks/StoreRoomSessionDataTask.kt | 6 +- .../tasks/StoreRoomSessionsDataTask.kt | 6 +- .../keysbackup/tasks/StoreSessionsDataTask.kt | 6 +- .../tasks/UpdateKeysBackupVersionTask.kt | 6 +- .../ClaimOneTimeKeysForUsersDeviceTask.kt | 6 +- .../internal/crypto/tasks/DeleteDeviceTask.kt | 6 +- .../tasks/DeleteDeviceWithUserPasswordTask.kt | 6 +- .../crypto/tasks/DownloadKeysForUsersTask.kt | 6 +- .../crypto/tasks/GetDeviceInfoTask.kt | 6 +- .../internal/crypto/tasks/GetDevicesTask.kt | 6 +- .../crypto/tasks/GetKeyChangesTask.kt | 6 +- .../internal/crypto/tasks/RedactEventTask.kt | 6 +- .../internal/crypto/tasks/SendEventTask.kt | 6 +- .../internal/crypto/tasks/SendToDeviceTask.kt | 6 +- .../tasks/SendVerificationMessageTask.kt | 6 +- .../crypto/tasks/SetDeviceNameTask.kt | 6 +- .../internal/crypto/tasks/UploadKeysTask.kt | 6 +- .../crypto/tasks/UploadSignaturesTask.kt | 6 +- .../crypto/tasks/UploadSigningKeysTask.kt | 6 +- .../internal/network/GlobalErrorHandler.kt | 54 ++++++++++++++++ .../android/sdk/internal/network/Request.kt | 9 ++- .../internal/network/RetrofitExtensions.kt | 19 +++--- .../sdk/internal/session/DefaultSession.kt | 30 +++------ .../sdk/internal/session/SessionModule.kt | 17 ++--- .../session/account/ChangePasswordTask.kt | 8 +-- .../session/account/DeactivateAccountTask.kt | 6 +- .../session/call/GetTurnServerTask.kt | 6 +- .../internal/session/content/FileUploader.kt | 6 +- .../internal/session/filter/SaveFilterTask.kt | 6 +- .../session/group/GetGroupDataTask.kt | 10 +-- .../GetHomeServerCapabilitiesTask.kt | 8 +-- .../session/media/GetPreviewUrlTask.kt | 6 +- .../session/media/GetRawPreviewUrlTask.kt | 6 +- .../session/openid/GetOpenIdTokenTask.kt | 6 +- .../session/profile/AddThreePidTask.kt | 8 +-- .../session/profile/BindThreePidsTask.kt | 6 +- .../session/profile/DeleteThreePidTask.kt | 6 +- .../profile/FinalizeAddingThreePidTask.kt | 6 +- .../session/profile/GetProfileInfoTask.kt | 6 +- .../profile/RefreshUserThreePidsTask.kt | 6 +- .../session/profile/SetAvatarUrlTask.kt | 6 +- .../session/profile/SetDisplayNameTask.kt | 6 +- .../session/profile/UnbindThreePidsTask.kt | 6 +- .../session/profile/ValidateSmsCodeTask.kt | 6 +- .../session/pushers/AddHttpPusherWorker.kt | 6 +- .../session/pushers/AddPushRuleTask.kt | 6 +- .../session/pushers/GetPushRulesTask.kt | 6 +- .../session/pushers/GetPushersTask.kt | 6 +- .../session/pushers/RemovePushRuleTask.kt | 6 +- .../session/pushers/RemovePusherTask.kt | 6 +- .../pushers/UpdatePushRuleActionsTask.kt | 8 +-- .../pushers/UpdatePushRuleEnableStatusTask.kt | 6 +- .../session/room/alias/AddRoomAliasTask.kt | 6 +- .../session/room/alias/DeleteRoomAliasTask.kt | 6 +- .../room/alias/GetRoomIdByAliasTask.kt | 6 +- .../room/alias/GetRoomLocalAliasesTask.kt | 6 +- .../alias/RoomAliasAvailabilityChecker.kt | 6 +- .../session/room/create/CreateRoomTask.kt | 6 +- .../room/directory/GetPublicRoomTask.kt | 6 +- .../GetRoomDirectoryVisibilityTask.kt | 6 +- .../directory/GetThirdPartyProtocolsTask.kt | 6 +- .../SetRoomDirectoryVisibilityTask.kt | 6 +- .../room/membership/LoadRoomMembersTask.kt | 6 +- .../room/membership/joining/InviteTask.kt | 6 +- .../room/membership/joining/JoinRoomTask.kt | 6 +- .../room/membership/leaving/LeaveRoomTask.kt | 6 +- .../membership/threepid/InviteThreePidTask.kt | 6 +- .../room/peeking/ResolveRoomStateTask.kt | 6 +- .../session/room/read/SetReadMarkersTask.kt | 6 +- .../room/relation/FetchEditHistoryTask.kt | 6 +- .../room/relation/SendRelationWorker.kt | 6 +- .../room/reporting/ReportContentTask.kt | 6 +- .../session/room/send/LocalEchoRepository.kt | 9 ++- .../session/room/send/RedactEventWorker.kt | 6 +- .../session/room/send/SendEventWorker.kt | 2 - .../session/room/state/SendStateTask.kt | 6 +- .../session/room/tags/AddTagToRoomTask.kt | 6 +- .../room/tags/DeleteTagFromRoomTask.kt | 6 +- .../session/room/timeline/DefaultTimeline.kt | 62 ++++++++----------- .../room/timeline/DefaultTimelineService.kt | 5 +- .../timeline/FetchTokenAndPaginateTask.kt | 6 +- .../room/timeline/GetContextOfEventTask.kt | 6 +- .../session/room/timeline/GetEventTask.kt | 6 +- .../session/room/timeline/PaginationTask.kt | 6 +- .../session/room/timeline/TimelineInput.kt | 45 ++++++++++++++ .../session/room/typing/SendTypingTask.kt | 6 +- .../session/room/uploads/GetUploadsTask.kt | 6 +- .../sdk/internal/session/search/SearchTask.kt | 6 +- .../session/signout/SignInAgainTask.kt | 6 +- .../internal/session/signout/SignOutTask.kt | 6 +- .../internal/session/sync/RoomSyncHandler.kt | 7 +-- .../sdk/internal/session/sync/SyncTask.kt | 6 +- .../accountdata/UpdateIgnoredUserIdsTask.kt | 6 +- .../accountdata/UpdateUserAccountDataTask.kt | 6 +- .../session/user/model/SearchUserTask.kt | 6 +- .../session/widgets/CreateWidgetTask.kt | 6 +- .../src/main/assets/open_source_licenses.html | 5 -- 114 files changed, 458 insertions(+), 425 deletions(-) rename matrix-sdk-android/src/{main/java/org/matrix/android/sdk/internal/eventbus/EventBusTimberLogger.kt => debug/java/org/matrix/android/sdk/internal/network/GlobalErrorReceiver.kt} (58%) create mode 100644 matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/network/GlobalErrorHandler.kt create mode 100644 matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/timeline/TimelineInput.kt diff --git a/CHANGES.md b/CHANGES.md index 7d4678fe40..56c7a1c1a8 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -21,7 +21,7 @@ SDK API changes ⚠️: - Build 🧱: - - + - Remove dependency to org.greenrobot.eventbus library Test: - diff --git a/matrix-sdk-android/build.gradle b/matrix-sdk-android/build.gradle index d72e5bda41..6a2f7575e5 100644 --- a/matrix-sdk-android/build.gradle +++ b/matrix-sdk-android/build.gradle @@ -167,9 +167,6 @@ dependencies { implementation 'com.jakewharton.timber:timber:4.7.1' implementation 'com.facebook.stetho:stetho-okhttp3:1.5.1' - // Bus - implementation 'org.greenrobot:eventbus:3.1.1' - // Phone number https://github.com/google/libphonenumber implementation 'com.googlecode.libphonenumber:libphonenumber:8.10.23' diff --git a/matrix-sdk-android/proguard-rules.pro b/matrix-sdk-android/proguard-rules.pro index fa860d8049..182f9473e8 100644 --- a/matrix-sdk-android/proguard-rules.pro +++ b/matrix-sdk-android/proguard-rules.pro @@ -20,14 +20,8 @@ # hide the original source file name. #-renamesourcefileattribute SourceFile - -### EVENT BUS ### - +# BMA: Not sure I can delete this one without side effect -keepattributes *Annotation* --keepclassmembers class * { - @org.greenrobot.eventbus.Subscribe ; -} --keep enum org.greenrobot.eventbus.ThreadMode { *; } ### MOSHI ### diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/eventbus/EventBusTimberLogger.kt b/matrix-sdk-android/src/debug/java/org/matrix/android/sdk/internal/network/GlobalErrorReceiver.kt similarity index 58% rename from matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/eventbus/EventBusTimberLogger.kt rename to matrix-sdk-android/src/debug/java/org/matrix/android/sdk/internal/network/GlobalErrorReceiver.kt index 2cbd7ba7f0..47607ba893 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/eventbus/EventBusTimberLogger.kt +++ b/matrix-sdk-android/src/debug/java/org/matrix/android/sdk/internal/network/GlobalErrorReceiver.kt @@ -1,5 +1,5 @@ /* - * Copyright 2020 The Matrix.org Foundation C.I.C. + * Copyright 2021 The Matrix.org Foundation C.I.C. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -14,18 +14,10 @@ * limitations under the License. */ -package org.matrix.android.sdk.internal.eventbus +package org.matrix.android.sdk.internal.network -import org.greenrobot.eventbus.Logger -import timber.log.Timber -import java.util.logging.Level +import org.matrix.android.sdk.api.failure.GlobalError -class EventBusTimberLogger : Logger { - override fun log(level: Level, msg: String) { - Timber.d(msg) - } - - override fun log(level: Level, msg: String, th: Throwable) { - Timber.e(th, msg) - } +internal interface GlobalErrorReceiver { + fun handleGlobalError(globalError: GlobalError) } diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/CancelGossipRequestWorker.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/CancelGossipRequestWorker.kt index c2c81894fb..7e92ff3e88 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/CancelGossipRequestWorker.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/CancelGossipRequestWorker.kt @@ -19,7 +19,6 @@ package org.matrix.android.sdk.internal.crypto import android.content.Context import androidx.work.WorkerParameters import com.squareup.moshi.JsonClass -import org.greenrobot.eventbus.EventBus import org.matrix.android.sdk.api.auth.data.Credentials import org.matrix.android.sdk.api.failure.shouldBeRetried import org.matrix.android.sdk.api.session.events.model.Event @@ -60,7 +59,6 @@ internal class CancelGossipRequestWorker(context: Context, @Inject lateinit var sendToDeviceTask: SendToDeviceTask @Inject lateinit var cryptoStore: IMXCryptoStore - @Inject lateinit var eventBus: EventBus @Inject lateinit var credentials: Credentials override fun injectWith(injector: SessionComponent) { diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/SendGossipRequestWorker.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/SendGossipRequestWorker.kt index 085469e9d9..e8d567b944 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/SendGossipRequestWorker.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/SendGossipRequestWorker.kt @@ -19,7 +19,6 @@ package org.matrix.android.sdk.internal.crypto import android.content.Context import androidx.work.WorkerParameters import com.squareup.moshi.JsonClass -import org.greenrobot.eventbus.EventBus import org.matrix.android.sdk.api.auth.data.Credentials import org.matrix.android.sdk.api.failure.shouldBeRetried import org.matrix.android.sdk.api.session.events.model.Event @@ -52,7 +51,6 @@ internal class SendGossipRequestWorker(context: Context, @Inject lateinit var sendToDeviceTask: SendToDeviceTask @Inject lateinit var cryptoStore: IMXCryptoStore - @Inject lateinit var eventBus: EventBus @Inject lateinit var credentials: Credentials override fun injectWith(injector: SessionComponent) { diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/SendGossipWorker.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/SendGossipWorker.kt index bcaa16f356..8c68057056 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/SendGossipWorker.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/SendGossipWorker.kt @@ -19,7 +19,6 @@ package org.matrix.android.sdk.internal.crypto import android.content.Context import androidx.work.WorkerParameters import com.squareup.moshi.JsonClass -import org.greenrobot.eventbus.EventBus import org.matrix.android.sdk.api.auth.data.Credentials import org.matrix.android.sdk.api.failure.shouldBeRetried import org.matrix.android.sdk.api.session.events.model.Event @@ -54,7 +53,6 @@ internal class SendGossipWorker(context: Context, @Inject lateinit var sendToDeviceTask: SendToDeviceTask @Inject lateinit var cryptoStore: IMXCryptoStore - @Inject lateinit var eventBus: EventBus @Inject lateinit var credentials: Credentials @Inject lateinit var messageEncrypter: MessageEncrypter @Inject lateinit var ensureOlmSessionsForDevicesAction: EnsureOlmSessionsForDevicesAction diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/keysbackup/tasks/CreateKeysBackupVersionTask.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/keysbackup/tasks/CreateKeysBackupVersionTask.kt index 36b667911d..5c59cfd80e 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/keysbackup/tasks/CreateKeysBackupVersionTask.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/keysbackup/tasks/CreateKeysBackupVersionTask.kt @@ -19,20 +19,20 @@ package org.matrix.android.sdk.internal.crypto.keysbackup.tasks import org.matrix.android.sdk.internal.crypto.keysbackup.api.RoomKeysApi import org.matrix.android.sdk.internal.crypto.keysbackup.model.rest.CreateKeysBackupVersionBody import org.matrix.android.sdk.internal.crypto.keysbackup.model.rest.KeysVersion +import org.matrix.android.sdk.internal.network.GlobalErrorReceiver import org.matrix.android.sdk.internal.network.executeRequest import org.matrix.android.sdk.internal.task.Task -import org.greenrobot.eventbus.EventBus import javax.inject.Inject internal interface CreateKeysBackupVersionTask : Task internal class DefaultCreateKeysBackupVersionTask @Inject constructor( private val roomKeysApi: RoomKeysApi, - private val eventBus: EventBus + private val globalErrorReceiver: GlobalErrorReceiver ) : CreateKeysBackupVersionTask { override suspend fun execute(params: CreateKeysBackupVersionBody): KeysVersion { - return executeRequest(eventBus) { + return executeRequest(globalErrorReceiver) { apiCall = roomKeysApi.createKeysBackupVersion(params) } } diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/keysbackup/tasks/DeleteBackupTask.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/keysbackup/tasks/DeleteBackupTask.kt index d174be20a2..ec09da7240 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/keysbackup/tasks/DeleteBackupTask.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/keysbackup/tasks/DeleteBackupTask.kt @@ -17,9 +17,9 @@ package org.matrix.android.sdk.internal.crypto.keysbackup.tasks import org.matrix.android.sdk.internal.crypto.keysbackup.api.RoomKeysApi +import org.matrix.android.sdk.internal.network.GlobalErrorReceiver import org.matrix.android.sdk.internal.network.executeRequest import org.matrix.android.sdk.internal.task.Task -import org.greenrobot.eventbus.EventBus import javax.inject.Inject internal interface DeleteBackupTask : Task { @@ -30,11 +30,11 @@ internal interface DeleteBackupTask : Task { internal class DefaultDeleteBackupTask @Inject constructor( private val roomKeysApi: RoomKeysApi, - private val eventBus: EventBus + private val globalErrorReceiver: GlobalErrorReceiver ) : DeleteBackupTask { override suspend fun execute(params: DeleteBackupTask.Params) { - return executeRequest(eventBus) { + return executeRequest(globalErrorReceiver) { apiCall = roomKeysApi.deleteBackup(params.version) } } diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/keysbackup/tasks/DeleteRoomSessionDataTask.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/keysbackup/tasks/DeleteRoomSessionDataTask.kt index 6826596ba4..9c477efb78 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/keysbackup/tasks/DeleteRoomSessionDataTask.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/keysbackup/tasks/DeleteRoomSessionDataTask.kt @@ -17,9 +17,9 @@ package org.matrix.android.sdk.internal.crypto.keysbackup.tasks import org.matrix.android.sdk.internal.crypto.keysbackup.api.RoomKeysApi +import org.matrix.android.sdk.internal.network.GlobalErrorReceiver import org.matrix.android.sdk.internal.network.executeRequest import org.matrix.android.sdk.internal.task.Task -import org.greenrobot.eventbus.EventBus import javax.inject.Inject internal interface DeleteRoomSessionDataTask : Task { @@ -32,11 +32,11 @@ internal interface DeleteRoomSessionDataTask : Task { @@ -31,11 +31,11 @@ internal interface DeleteRoomSessionsDataTask : Task { @@ -30,11 +30,11 @@ internal interface DeleteSessionsDataTask : Task internal class DefaultGetKeysBackupLastVersionTask @Inject constructor( private val roomKeysApi: RoomKeysApi, - private val eventBus: EventBus + private val globalErrorReceiver: GlobalErrorReceiver ) : GetKeysBackupLastVersionTask { override suspend fun execute(params: Unit): KeysVersionResult { - return executeRequest(eventBus) { + return executeRequest(globalErrorReceiver) { apiCall = roomKeysApi.getKeysBackupLastVersion() } } diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/keysbackup/tasks/GetKeysBackupVersionTask.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/keysbackup/tasks/GetKeysBackupVersionTask.kt index dd2dd70e4d..13c99fb0f4 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/keysbackup/tasks/GetKeysBackupVersionTask.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/keysbackup/tasks/GetKeysBackupVersionTask.kt @@ -18,20 +18,20 @@ package org.matrix.android.sdk.internal.crypto.keysbackup.tasks import org.matrix.android.sdk.internal.crypto.keysbackup.api.RoomKeysApi import org.matrix.android.sdk.internal.crypto.keysbackup.model.rest.KeysVersionResult +import org.matrix.android.sdk.internal.network.GlobalErrorReceiver import org.matrix.android.sdk.internal.network.executeRequest import org.matrix.android.sdk.internal.task.Task -import org.greenrobot.eventbus.EventBus import javax.inject.Inject internal interface GetKeysBackupVersionTask : Task internal class DefaultGetKeysBackupVersionTask @Inject constructor( private val roomKeysApi: RoomKeysApi, - private val eventBus: EventBus + private val globalErrorReceiver: GlobalErrorReceiver ) : GetKeysBackupVersionTask { override suspend fun execute(params: String): KeysVersionResult { - return executeRequest(eventBus) { + return executeRequest(globalErrorReceiver) { apiCall = roomKeysApi.getKeysBackupVersion(params) } } diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/keysbackup/tasks/GetRoomSessionDataTask.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/keysbackup/tasks/GetRoomSessionDataTask.kt index 8ca03491a1..168020d9cd 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/keysbackup/tasks/GetRoomSessionDataTask.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/keysbackup/tasks/GetRoomSessionDataTask.kt @@ -18,9 +18,9 @@ package org.matrix.android.sdk.internal.crypto.keysbackup.tasks import org.matrix.android.sdk.internal.crypto.keysbackup.api.RoomKeysApi import org.matrix.android.sdk.internal.crypto.keysbackup.model.rest.KeyBackupData +import org.matrix.android.sdk.internal.network.GlobalErrorReceiver import org.matrix.android.sdk.internal.network.executeRequest import org.matrix.android.sdk.internal.task.Task -import org.greenrobot.eventbus.EventBus import javax.inject.Inject internal interface GetRoomSessionDataTask : Task { @@ -33,11 +33,11 @@ internal interface GetRoomSessionDataTask : Task { @@ -32,11 +32,11 @@ internal interface GetRoomSessionsDataTask : Task { @@ -31,11 +31,11 @@ internal interface GetSessionsDataTask : Task { @@ -35,11 +35,11 @@ internal interface StoreRoomSessionDataTask : Task { @@ -34,11 +34,11 @@ internal interface StoreRoomSessionsDataTask : Task { @@ -33,11 +33,11 @@ internal interface StoreSessionsDataTask : Task { @@ -32,11 +32,11 @@ internal interface UpdateKeysBackupVersionTask : Task { val body = KeysClaimBody(oneTimeKeys = params.usersDevicesKeyTypesMap.map) - val keysClaimResponse = executeRequest(eventBus) { + val keysClaimResponse = executeRequest(globalErrorReceiver) { apiCall = cryptoApi.claimOneTimeKeysForUsersDevices(body) } val map = MXUsersDevicesMap() diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/tasks/DeleteDeviceTask.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/tasks/DeleteDeviceTask.kt index e5078d5b4e..8f1569a037 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/tasks/DeleteDeviceTask.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/tasks/DeleteDeviceTask.kt @@ -20,9 +20,9 @@ import org.matrix.android.sdk.api.failure.Failure import org.matrix.android.sdk.api.failure.toRegistrationFlowResponse import org.matrix.android.sdk.internal.crypto.api.CryptoApi import org.matrix.android.sdk.internal.crypto.model.rest.DeleteDeviceParams +import org.matrix.android.sdk.internal.network.GlobalErrorReceiver import org.matrix.android.sdk.internal.network.executeRequest import org.matrix.android.sdk.internal.task.Task -import org.greenrobot.eventbus.EventBus import javax.inject.Inject internal interface DeleteDeviceTask : Task { @@ -33,12 +33,12 @@ internal interface DeleteDeviceTask : Task { internal class DefaultDeleteDeviceTask @Inject constructor( private val cryptoApi: CryptoApi, - private val eventBus: EventBus + private val globalErrorReceiver: GlobalErrorReceiver ) : DeleteDeviceTask { override suspend fun execute(params: DeleteDeviceTask.Params) { try { - executeRequest(eventBus) { + executeRequest(globalErrorReceiver) { apiCall = cryptoApi.deleteDevice(params.deviceId, DeleteDeviceParams()) } } catch (throwable: Throwable) { diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/tasks/DeleteDeviceWithUserPasswordTask.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/tasks/DeleteDeviceWithUserPasswordTask.kt index 38eee7f932..b4c1e6d27c 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/tasks/DeleteDeviceWithUserPasswordTask.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/tasks/DeleteDeviceWithUserPasswordTask.kt @@ -21,9 +21,9 @@ import org.matrix.android.sdk.internal.crypto.api.CryptoApi import org.matrix.android.sdk.internal.crypto.model.rest.DeleteDeviceParams import org.matrix.android.sdk.internal.crypto.model.rest.UserPasswordAuth import org.matrix.android.sdk.internal.di.UserId +import org.matrix.android.sdk.internal.network.GlobalErrorReceiver import org.matrix.android.sdk.internal.network.executeRequest import org.matrix.android.sdk.internal.task.Task -import org.greenrobot.eventbus.EventBus import javax.inject.Inject internal interface DeleteDeviceWithUserPasswordTask : Task { @@ -37,11 +37,11 @@ internal interface DeleteDeviceWithUserPasswordTask : Task { @@ -35,7 +35,7 @@ internal interface DownloadKeysForUsersTask : Task { @@ -29,11 +29,11 @@ internal interface GetDeviceInfoTask : Task internal class DefaultGetDevicesTask @Inject constructor( private val cryptoApi: CryptoApi, - private val eventBus: EventBus + private val globalErrorReceiver: GlobalErrorReceiver ) : GetDevicesTask { override suspend fun execute(params: Unit): DevicesListResponse { - return executeRequest(eventBus) { + return executeRequest(globalErrorReceiver) { apiCall = cryptoApi.getDevices() } } diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/tasks/GetKeyChangesTask.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/tasks/GetKeyChangesTask.kt index 289a5226f5..4cc9ab2fcb 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/tasks/GetKeyChangesTask.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/tasks/GetKeyChangesTask.kt @@ -18,9 +18,9 @@ package org.matrix.android.sdk.internal.crypto.tasks import org.matrix.android.sdk.internal.crypto.api.CryptoApi import org.matrix.android.sdk.internal.crypto.model.rest.KeyChangesResponse +import org.matrix.android.sdk.internal.network.GlobalErrorReceiver import org.matrix.android.sdk.internal.network.executeRequest import org.matrix.android.sdk.internal.task.Task -import org.greenrobot.eventbus.EventBus import javax.inject.Inject internal interface GetKeyChangesTask : Task { @@ -34,11 +34,11 @@ internal interface GetKeyChangesTask : Task { internal class DefaultRedactEventTask @Inject constructor( private val roomAPI: RoomAPI, - private val eventBus: EventBus) : RedactEventTask { + private val globalErrorReceiver: GlobalErrorReceiver) : RedactEventTask { override suspend fun execute(params: RedactEventTask.Params): String { - val executeRequest = executeRequest(eventBus) { + val executeRequest = executeRequest(globalErrorReceiver) { apiCall = roomAPI.redactEvent( txId = params.txID, roomId = params.roomId, diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/tasks/SendEventTask.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/tasks/SendEventTask.kt index 5c8c7dfb25..b772bfbce2 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/tasks/SendEventTask.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/tasks/SendEventTask.kt @@ -15,9 +15,9 @@ */ package org.matrix.android.sdk.internal.crypto.tasks -import org.greenrobot.eventbus.EventBus import org.matrix.android.sdk.api.session.events.model.Event import org.matrix.android.sdk.api.session.room.send.SendState +import org.matrix.android.sdk.internal.network.GlobalErrorReceiver import org.matrix.android.sdk.internal.network.executeRequest import org.matrix.android.sdk.internal.session.room.RoomAPI import org.matrix.android.sdk.internal.session.room.membership.LoadRoomMembersTask @@ -38,7 +38,7 @@ internal class DefaultSendEventTask @Inject constructor( private val encryptEventTask: DefaultEncryptEventTask, private val loadRoomMembersTask: LoadRoomMembersTask, private val roomAPI: RoomAPI, - private val eventBus: EventBus) : SendEventTask { + private val globalErrorReceiver: GlobalErrorReceiver) : SendEventTask { override suspend fun execute(params: SendEventTask.Params): String { try { @@ -53,7 +53,7 @@ internal class DefaultSendEventTask @Inject constructor( val localId = event.eventId!! localEchoRepository.updateSendState(localId, params.event.roomId, SendState.SENDING) - val executeRequest = executeRequest(eventBus) { + val executeRequest = executeRequest(globalErrorReceiver) { apiCall = roomAPI.send( localId, roomId = event.roomId ?: "", diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/tasks/SendToDeviceTask.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/tasks/SendToDeviceTask.kt index 37e0bbc887..d2af91601b 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/tasks/SendToDeviceTask.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/tasks/SendToDeviceTask.kt @@ -19,9 +19,9 @@ package org.matrix.android.sdk.internal.crypto.tasks import org.matrix.android.sdk.internal.crypto.api.CryptoApi import org.matrix.android.sdk.internal.crypto.model.MXUsersDevicesMap import org.matrix.android.sdk.internal.crypto.model.rest.SendToDeviceBody +import org.matrix.android.sdk.internal.network.GlobalErrorReceiver import org.matrix.android.sdk.internal.network.executeRequest import org.matrix.android.sdk.internal.task.Task -import org.greenrobot.eventbus.EventBus import javax.inject.Inject import kotlin.random.Random @@ -38,7 +38,7 @@ internal interface SendToDeviceTask : Task { internal class DefaultSendToDeviceTask @Inject constructor( private val cryptoApi: CryptoApi, - private val eventBus: EventBus + private val globalErrorReceiver: GlobalErrorReceiver ) : SendToDeviceTask { override suspend fun execute(params: SendToDeviceTask.Params) { @@ -46,7 +46,7 @@ internal class DefaultSendToDeviceTask @Inject constructor( messages = params.contentMap.map ) - return executeRequest(eventBus) { + return executeRequest(globalErrorReceiver) { apiCall = cryptoApi.sendToDevice( params.eventType, params.transactionId ?: Random.nextInt(Integer.MAX_VALUE).toString(), diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/tasks/SendVerificationMessageTask.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/tasks/SendVerificationMessageTask.kt index cedb7a6618..c39dfb1016 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/tasks/SendVerificationMessageTask.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/tasks/SendVerificationMessageTask.kt @@ -15,10 +15,10 @@ */ package org.matrix.android.sdk.internal.crypto.tasks -import org.greenrobot.eventbus.EventBus import org.matrix.android.sdk.api.session.events.model.Event import org.matrix.android.sdk.api.session.room.send.SendState import org.matrix.android.sdk.internal.crypto.CryptoSessionInfoProvider +import org.matrix.android.sdk.internal.network.GlobalErrorReceiver import org.matrix.android.sdk.internal.network.executeRequest import org.matrix.android.sdk.internal.session.room.RoomAPI import org.matrix.android.sdk.internal.session.room.send.LocalEchoRepository @@ -37,7 +37,7 @@ internal class DefaultSendVerificationMessageTask @Inject constructor( private val encryptEventTask: DefaultEncryptEventTask, private val roomAPI: RoomAPI, private val cryptoSessionInfoProvider: CryptoSessionInfoProvider, - private val eventBus: EventBus) : SendVerificationMessageTask { + private val globalErrorReceiver: GlobalErrorReceiver) : SendVerificationMessageTask { override suspend fun execute(params: SendVerificationMessageTask.Params): String { val event = handleEncryption(params) @@ -45,7 +45,7 @@ internal class DefaultSendVerificationMessageTask @Inject constructor( try { localEchoRepository.updateSendState(localId, event.roomId, SendState.SENDING) - val executeRequest = executeRequest(eventBus) { + val executeRequest = executeRequest(globalErrorReceiver) { apiCall = roomAPI.send( localId, roomId = event.roomId ?: "", diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/tasks/SetDeviceNameTask.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/tasks/SetDeviceNameTask.kt index 51b9624554..b835d46236 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/tasks/SetDeviceNameTask.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/tasks/SetDeviceNameTask.kt @@ -18,9 +18,9 @@ package org.matrix.android.sdk.internal.crypto.tasks import org.matrix.android.sdk.internal.crypto.api.CryptoApi import org.matrix.android.sdk.internal.crypto.model.rest.UpdateDeviceInfoBody +import org.matrix.android.sdk.internal.network.GlobalErrorReceiver import org.matrix.android.sdk.internal.network.executeRequest import org.matrix.android.sdk.internal.task.Task -import org.greenrobot.eventbus.EventBus import javax.inject.Inject internal interface SetDeviceNameTask : Task { @@ -34,14 +34,14 @@ internal interface SetDeviceNameTask : Task { internal class DefaultSetDeviceNameTask @Inject constructor( private val cryptoApi: CryptoApi, - private val eventBus: EventBus + private val globalErrorReceiver: GlobalErrorReceiver ) : SetDeviceNameTask { override suspend fun execute(params: SetDeviceNameTask.Params) { val body = UpdateDeviceInfoBody( displayName = params.deviceName ) - return executeRequest(eventBus) { + return executeRequest(globalErrorReceiver) { apiCall = cryptoApi.updateDeviceInfo(params.deviceId, body) } } diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/tasks/UploadKeysTask.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/tasks/UploadKeysTask.kt index 6216a3a305..eb53bbbf8d 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/tasks/UploadKeysTask.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/tasks/UploadKeysTask.kt @@ -21,9 +21,9 @@ import org.matrix.android.sdk.internal.crypto.api.CryptoApi import org.matrix.android.sdk.internal.crypto.model.rest.DeviceKeys import org.matrix.android.sdk.internal.crypto.model.rest.KeysUploadBody import org.matrix.android.sdk.internal.crypto.model.rest.KeysUploadResponse +import org.matrix.android.sdk.internal.network.GlobalErrorReceiver import org.matrix.android.sdk.internal.network.executeRequest import org.matrix.android.sdk.internal.task.Task -import org.greenrobot.eventbus.EventBus import timber.log.Timber import javax.inject.Inject @@ -38,7 +38,7 @@ internal interface UploadKeysTask : Task $body") - return executeRequest(eventBus) { + return executeRequest(globalErrorReceiver) { apiCall = cryptoApi.uploadKeys(body) } } diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/tasks/UploadSignaturesTask.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/tasks/UploadSignaturesTask.kt index a4e10ddbfc..c50faf37b1 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/tasks/UploadSignaturesTask.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/tasks/UploadSignaturesTask.kt @@ -18,9 +18,9 @@ package org.matrix.android.sdk.internal.crypto.tasks import org.matrix.android.sdk.api.failure.Failure import org.matrix.android.sdk.internal.crypto.api.CryptoApi import org.matrix.android.sdk.internal.crypto.model.rest.SignatureUploadResponse +import org.matrix.android.sdk.internal.network.GlobalErrorReceiver import org.matrix.android.sdk.internal.network.executeRequest import org.matrix.android.sdk.internal.task.Task -import org.greenrobot.eventbus.EventBus import javax.inject.Inject internal interface UploadSignaturesTask : Task { @@ -31,12 +31,12 @@ internal interface UploadSignaturesTask : Task(eventBus) { + val response = executeRequest(globalErrorReceiver) { this.isRetryable = true this.maxRetryCount = 10 this.apiCall = cryptoApi.uploadSignatures(params.signatures) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/tasks/UploadSigningKeysTask.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/tasks/UploadSigningKeysTask.kt index 038ef9dbd3..cceff355bb 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/tasks/UploadSigningKeysTask.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/tasks/UploadSigningKeysTask.kt @@ -25,9 +25,9 @@ import org.matrix.android.sdk.internal.crypto.model.rest.KeysQueryResponse import org.matrix.android.sdk.internal.crypto.model.rest.UploadSigningKeysBody import org.matrix.android.sdk.internal.crypto.model.rest.UserPasswordAuth import org.matrix.android.sdk.internal.crypto.model.toRest +import org.matrix.android.sdk.internal.network.GlobalErrorReceiver import org.matrix.android.sdk.internal.network.executeRequest import org.matrix.android.sdk.internal.task.Task -import org.greenrobot.eventbus.EventBus import javax.inject.Inject internal interface UploadSigningKeysTask : Task { @@ -55,7 +55,7 @@ data class UploadSigningKeys(val failures: Map?) : Failure.FeatureF internal class DefaultUploadSigningKeysTask @Inject constructor( private val cryptoApi: CryptoApi, - private val eventBus: EventBus + private val globalErrorReceiver: GlobalErrorReceiver ) : UploadSigningKeysTask { override suspend fun execute(params: UploadSigningKeysTask.Params) { @@ -87,7 +87,7 @@ internal class DefaultUploadSigningKeysTask @Inject constructor( } private suspend fun doRequest(uploadQuery: UploadSigningKeysBody) { - val keysQueryResponse = executeRequest(eventBus) { + val keysQueryResponse = executeRequest(globalErrorReceiver) { apiCall = cryptoApi.uploadSigningKeys(uploadQuery) } if (keysQueryResponse.failures?.isNotEmpty() == true) { diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/network/GlobalErrorHandler.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/network/GlobalErrorHandler.kt new file mode 100644 index 0000000000..9afdb40ed1 --- /dev/null +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/network/GlobalErrorHandler.kt @@ -0,0 +1,54 @@ +/* + * Copyright 2021 The Matrix.org Foundation C.I.C. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.matrix.android.sdk.internal.network + +import org.matrix.android.sdk.api.failure.GlobalError +import org.matrix.android.sdk.internal.auth.SessionParamsStore +import org.matrix.android.sdk.internal.di.SessionId +import org.matrix.android.sdk.internal.session.SessionScope +import org.matrix.android.sdk.internal.task.TaskExecutor +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.launch +import timber.log.Timber +import javax.inject.Inject + +@SessionScope +internal class GlobalErrorHandler @Inject constructor( + private val taskExecutor: TaskExecutor, + private val sessionParamsStore: SessionParamsStore, + @SessionId private val sessionId: String +) : GlobalErrorReceiver { + + var listener: Listener? = null + + override fun handleGlobalError(globalError: GlobalError) { + Timber.e("Global error received: $globalError") + + if (globalError is GlobalError.InvalidToken && globalError.softLogout) { + // Mark the token has invalid + taskExecutor.executorScope.launch(Dispatchers.IO) { + sessionParamsStore.setTokenInvalid(sessionId) + } + } + + listener?.onGlobalError(globalError) + } + + internal interface Listener { + fun onGlobalError(globalError: GlobalError) + } +} diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/network/Request.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/network/Request.kt index 2535a5347a..442029127d 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/network/Request.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/network/Request.kt @@ -18,7 +18,6 @@ package org.matrix.android.sdk.internal.network import kotlinx.coroutines.CancellationException import kotlinx.coroutines.delay -import org.greenrobot.eventbus.EventBus import org.matrix.android.sdk.api.failure.Failure import org.matrix.android.sdk.api.failure.shouldBeRetried import org.matrix.android.sdk.internal.network.ssl.CertUtil @@ -27,10 +26,10 @@ import retrofit2.awaitResponse import timber.log.Timber import java.io.IOException -internal suspend inline fun executeRequest(eventBus: EventBus?, - block: Request.() -> Unit) = Request(eventBus).apply(block).execute() +internal suspend inline fun executeRequest(globalErrorReceiver: GlobalErrorReceiver?, + block: Request.() -> Unit) = Request(globalErrorReceiver).apply(block).execute() -internal class Request(private val eventBus: EventBus?) { +internal class Request(private val globalErrorReceiver: GlobalErrorReceiver?) { var isRetryable = false var initialDelay: Long = 100L @@ -47,7 +46,7 @@ internal class Request(private val eventBus: EventBus?) { response.body() ?: throw IllegalStateException("The request returned a null body") } else { - throw response.toFailure(eventBus) + throw response.toFailure(globalErrorReceiver) } } catch (exception: Throwable) { // Log some details about the request which has failed diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/network/RetrofitExtensions.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/network/RetrofitExtensions.kt index c54af571d8..dd5a69dd3c 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/network/RetrofitExtensions.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/network/RetrofitExtensions.kt @@ -25,7 +25,6 @@ import org.matrix.android.sdk.api.failure.MatrixError import org.matrix.android.sdk.internal.di.MoshiProvider import kotlinx.coroutines.suspendCancellableCoroutine import okhttp3.ResponseBody -import org.greenrobot.eventbus.EventBus import retrofit2.Response import timber.log.Timber import java.io.IOException @@ -54,18 +53,18 @@ internal suspend fun okhttp3.Call.awaitResponse(): okhttp3.Response { /** * Convert a retrofit Response to a Failure, and eventually parse errorBody to convert it to a MatrixError */ -internal fun Response.toFailure(eventBus: EventBus?): Failure { - return toFailure(errorBody(), code(), eventBus) +internal fun Response.toFailure(globalErrorReceiver: GlobalErrorReceiver?): Failure { + return toFailure(errorBody(), code(), globalErrorReceiver) } /** * Convert a okhttp3 Response to a Failure, and eventually parse errorBody to convert it to a MatrixError */ -internal fun okhttp3.Response.toFailure(eventBus: EventBus?): Failure { - return toFailure(body, code, eventBus) +internal fun okhttp3.Response.toFailure(globalErrorReceiver: GlobalErrorReceiver?): Failure { + return toFailure(body, code, globalErrorReceiver) } -private fun toFailure(errorBody: ResponseBody?, httpCode: Int, eventBus: EventBus?): Failure { +private fun toFailure(errorBody: ResponseBody?, httpCode: Int, globalErrorReceiver: GlobalErrorReceiver?): Failure { if (errorBody == null) { return Failure.Unknown(RuntimeException("errorBody should not be null")) } @@ -79,12 +78,12 @@ private fun toFailure(errorBody: ResponseBody?, httpCode: Int, eventBus: EventBu if (matrixError != null) { if (matrixError.code == MatrixError.M_CONSENT_NOT_GIVEN && !matrixError.consentUri.isNullOrBlank()) { - // Also send this error to the bus, for a global management - eventBus?.post(GlobalError.ConsentNotGivenError(matrixError.consentUri)) + // Also send this error to the globalErrorReceiver, for a global management + globalErrorReceiver?.handleGlobalError(GlobalError.ConsentNotGivenError(matrixError.consentUri)) } else if (httpCode == HttpURLConnection.HTTP_UNAUTHORIZED /* 401 */ && matrixError.code == MatrixError.M_UNKNOWN_TOKEN) { - // Also send this error to the bus, for a global management - eventBus?.post(GlobalError.InvalidToken(matrixError.isSoftLogout)) + // Also send this error to the globalErrorReceiver, for a global management + globalErrorReceiver?.handleGlobalError(GlobalError.InvalidToken(matrixError.isSoftLogout)) } return Failure.ServerError(matrixError, httpCode) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/DefaultSession.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/DefaultSession.kt index c5f3f65a34..fa07b16c32 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/DefaultSession.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/DefaultSession.kt @@ -19,12 +19,7 @@ package org.matrix.android.sdk.internal.session import androidx.annotation.MainThread import dagger.Lazy import io.realm.RealmConfiguration -import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.launch import okhttp3.OkHttpClient -import org.greenrobot.eventbus.EventBus -import org.greenrobot.eventbus.Subscribe -import org.greenrobot.eventbus.ThreadMode import org.matrix.android.sdk.api.MatrixCallback import org.matrix.android.sdk.api.auth.data.SessionParams import org.matrix.android.sdk.api.failure.GlobalError @@ -65,13 +60,12 @@ import org.matrix.android.sdk.internal.di.SessionDatabase import org.matrix.android.sdk.internal.di.SessionId import org.matrix.android.sdk.internal.di.UnauthenticatedWithCertificate import org.matrix.android.sdk.internal.di.WorkManagerProvider +import org.matrix.android.sdk.internal.network.GlobalErrorHandler import org.matrix.android.sdk.internal.session.identity.DefaultIdentityService import org.matrix.android.sdk.internal.session.room.send.queue.EventSenderProcessor import org.matrix.android.sdk.internal.session.sync.SyncTokenStore import org.matrix.android.sdk.internal.session.sync.job.SyncThread import org.matrix.android.sdk.internal.session.sync.job.SyncWorker -import org.matrix.android.sdk.internal.task.TaskExecutor -import org.matrix.android.sdk.internal.util.MatrixCoroutineDispatchers import org.matrix.android.sdk.internal.util.createUIHandler import timber.log.Timber import javax.inject.Inject @@ -81,7 +75,7 @@ import javax.inject.Provider internal class DefaultSession @Inject constructor( override val sessionParams: SessionParams, private val workManagerProvider: WorkManagerProvider, - private val eventBus: EventBus, + private val globalErrorHandler: GlobalErrorHandler, @SessionId override val sessionId: String, @SessionDatabase private val realmConfiguration: RealmConfiguration, @@ -117,10 +111,8 @@ internal class DefaultSession @Inject constructor( private val accountDataService: Lazy, private val _sharedSecretStorageService: Lazy, private val accountService: Lazy, - private val coroutineDispatchers: MatrixCoroutineDispatchers, private val defaultIdentityService: DefaultIdentityService, private val integrationManagerService: IntegrationManagerService, - private val taskExecutor: TaskExecutor, private val callSignalingService: Lazy, @UnauthenticatedWithCertificate private val unauthenticatedWithCertificateOkHttpClient: Lazy, @@ -140,7 +132,8 @@ internal class DefaultSession @Inject constructor( HomeServerCapabilitiesService by homeServerCapabilitiesService.get(), ProfileService by profileService.get(), AccountDataService by accountDataService.get(), - AccountService by accountService.get() { + AccountService by accountService.get(), + GlobalErrorHandler.Listener { override val sharedSecretStorageService: SharedSecretStorageService get() = _sharedSecretStorageService.get() @@ -162,7 +155,7 @@ internal class DefaultSession @Inject constructor( uiHandler.post { lifecycleObservers.forEach { it.onStart() } } - eventBus.register(this) + globalErrorHandler.listener = this eventSenderProcessor.start() } @@ -206,7 +199,7 @@ internal class DefaultSession @Inject constructor( } cryptoService.get().close() isOpen = false - eventBus.unregister(this) + globalErrorHandler.listener = null eventSenderProcessor.interrupt() } @@ -234,16 +227,7 @@ internal class DefaultSession @Inject constructor( workManagerProvider.cancelAllWorks() } - @Subscribe(threadMode = ThreadMode.MAIN) - fun onGlobalError(globalError: GlobalError) { - if (globalError is GlobalError.InvalidToken - && globalError.softLogout) { - // Mark the token has invalid - taskExecutor.executorScope.launch(Dispatchers.IO) { - sessionParamsStore.setTokenInvalid(sessionId) - } - } - + override fun onGlobalError(globalError: GlobalError) { sessionListeners.dispatchGlobalError(globalError) } diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/SessionModule.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/SessionModule.kt index 96b44917bd..468c193ad3 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/SessionModule.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/SessionModule.kt @@ -26,7 +26,6 @@ import dagger.Provides import dagger.multibindings.IntoSet import io.realm.RealmConfiguration import okhttp3.OkHttpClient -import org.greenrobot.eventbus.EventBus import org.matrix.android.sdk.api.MatrixConfiguration import org.matrix.android.sdk.api.auth.data.Credentials import org.matrix.android.sdk.api.auth.data.HomeServerConnectionConfig @@ -61,9 +60,10 @@ import org.matrix.android.sdk.internal.di.UnauthenticatedWithCertificate import org.matrix.android.sdk.internal.di.UnauthenticatedWithCertificateWithProgress import org.matrix.android.sdk.internal.di.UserId import org.matrix.android.sdk.internal.di.UserMd5 -import org.matrix.android.sdk.internal.eventbus.EventBusTimberLogger import org.matrix.android.sdk.internal.network.DefaultNetworkConnectivityChecker import org.matrix.android.sdk.internal.network.FallbackNetworkCallbackStrategy +import org.matrix.android.sdk.internal.network.GlobalErrorHandler +import org.matrix.android.sdk.internal.network.GlobalErrorReceiver import org.matrix.android.sdk.internal.network.NetworkCallbackStrategy import org.matrix.android.sdk.internal.network.NetworkConnectivityChecker import org.matrix.android.sdk.internal.network.PreferredNetworkCallbackStrategy @@ -256,16 +256,6 @@ internal abstract class SessionModule { .create(okHttpClient, sessionParams.homeServerConnectionConfig.homeServerUri.toString()) } - @JvmStatic - @Provides - @SessionScope - fun providesEventBus(): EventBus { - return EventBus - .builder() - .logger(EventBusTimberLogger()) - .build() - } - @JvmStatic @Provides @SessionScope @@ -294,6 +284,9 @@ internal abstract class SessionModule { @Binds abstract fun bindSession(session: DefaultSession): Session + @Binds + abstract fun bindGlobalErrorReceiver(handler: GlobalErrorHandler): GlobalErrorReceiver + @Binds abstract fun bindNetworkConnectivityChecker(checker: DefaultNetworkConnectivityChecker): NetworkConnectivityChecker diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/account/ChangePasswordTask.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/account/ChangePasswordTask.kt index 869d3f516c..1f043b0a9d 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/account/ChangePasswordTask.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/account/ChangePasswordTask.kt @@ -18,9 +18,9 @@ package org.matrix.android.sdk.internal.session.account import org.matrix.android.sdk.api.failure.toRegistrationFlowResponse import org.matrix.android.sdk.internal.di.UserId +import org.matrix.android.sdk.internal.network.GlobalErrorReceiver import org.matrix.android.sdk.internal.network.executeRequest import org.matrix.android.sdk.internal.task.Task -import org.greenrobot.eventbus.EventBus import javax.inject.Inject internal interface ChangePasswordTask : Task { @@ -32,14 +32,14 @@ internal interface ChangePasswordTask : Task { internal class DefaultChangePasswordTask @Inject constructor( private val accountAPI: AccountAPI, - private val eventBus: EventBus, + private val globalErrorReceiver: GlobalErrorReceiver, @UserId private val userId: String ) : ChangePasswordTask { override suspend fun execute(params: ChangePasswordTask.Params) { val changePasswordParams = ChangePasswordParams.create(userId, params.password, params.newPassword) try { - executeRequest(eventBus) { + executeRequest(globalErrorReceiver) { apiCall = accountAPI.changePassword(changePasswordParams) } } catch (throwable: Throwable) { @@ -49,7 +49,7 @@ internal class DefaultChangePasswordTask @Inject constructor( /* Avoid infinite loop */ && changePasswordParams.auth?.session == null) { // Retry with authentication - executeRequest(eventBus) { + executeRequest(globalErrorReceiver) { apiCall = accountAPI.changePassword( changePasswordParams.copy(auth = changePasswordParams.auth?.copy(session = registrationFlowResponse.session)) ) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/account/DeactivateAccountTask.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/account/DeactivateAccountTask.kt index ac5febcdae..9fb1cbb7d7 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/account/DeactivateAccountTask.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/account/DeactivateAccountTask.kt @@ -17,11 +17,11 @@ package org.matrix.android.sdk.internal.session.account import org.matrix.android.sdk.internal.di.UserId +import org.matrix.android.sdk.internal.network.GlobalErrorReceiver import org.matrix.android.sdk.internal.network.executeRequest import org.matrix.android.sdk.internal.session.cleanup.CleanupSession import org.matrix.android.sdk.internal.session.identity.IdentityDisconnectTask import org.matrix.android.sdk.internal.task.Task -import org.greenrobot.eventbus.EventBus import timber.log.Timber import javax.inject.Inject @@ -34,7 +34,7 @@ internal interface DeactivateAccountTask : Task(eventBus) { + executeRequest(globalErrorReceiver) { apiCall = accountAPI.deactivate(deactivateAccountParams) } diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/call/GetTurnServerTask.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/call/GetTurnServerTask.kt index 1cedee3374..b21ec1113a 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/call/GetTurnServerTask.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/call/GetTurnServerTask.kt @@ -17,9 +17,9 @@ package org.matrix.android.sdk.internal.session.call import org.matrix.android.sdk.api.session.call.TurnServerResponse +import org.matrix.android.sdk.internal.network.GlobalErrorReceiver import org.matrix.android.sdk.internal.network.executeRequest import org.matrix.android.sdk.internal.task.Task -import org.greenrobot.eventbus.EventBus import javax.inject.Inject internal abstract class GetTurnServerTask : Task { @@ -27,10 +27,10 @@ internal abstract class GetTurnServerTask : Task if (!response.isSuccessful) { - throw response.toFailure(eventBus) + throw response.toFailure(globalErrorReceiver) } else { response.body?.source()?.let { responseAdapter.fromJson(it) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/filter/SaveFilterTask.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/filter/SaveFilterTask.kt index 69ced92fe5..da747934e2 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/filter/SaveFilterTask.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/filter/SaveFilterTask.kt @@ -18,9 +18,9 @@ package org.matrix.android.sdk.internal.session.filter import org.matrix.android.sdk.api.session.sync.FilterService import org.matrix.android.sdk.internal.di.UserId +import org.matrix.android.sdk.internal.network.GlobalErrorReceiver import org.matrix.android.sdk.internal.network.executeRequest import org.matrix.android.sdk.internal.task.Task -import org.greenrobot.eventbus.EventBus import javax.inject.Inject /** @@ -37,7 +37,7 @@ internal class DefaultSaveFilterTask @Inject constructor( @UserId private val userId: String, private val filterAPI: FilterApi, private val filterRepository: FilterRepository, - private val eventBus: EventBus + private val globalErrorReceiver: GlobalErrorReceiver ) : SaveFilterTask { override suspend fun execute(params: SaveFilterTask.Params) { @@ -59,7 +59,7 @@ internal class DefaultSaveFilterTask @Inject constructor( } val updated = filterRepository.storeFilter(filterBody, roomFilter) if (updated) { - val filterResponse = executeRequest(eventBus) { + val filterResponse = executeRequest(globalErrorReceiver) { // TODO auto retry apiCall = filterAPI.uploadFilter(userId, filterBody) } diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/group/GetGroupDataTask.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/group/GetGroupDataTask.kt index dd703a5e93..9836164aec 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/group/GetGroupDataTask.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/group/GetGroupDataTask.kt @@ -23,13 +23,13 @@ import org.matrix.android.sdk.internal.database.model.GroupSummaryEntity import org.matrix.android.sdk.internal.database.query.getOrCreate import org.matrix.android.sdk.internal.database.query.where import org.matrix.android.sdk.internal.di.SessionDatabase +import org.matrix.android.sdk.internal.network.GlobalErrorReceiver import org.matrix.android.sdk.internal.network.executeRequest import org.matrix.android.sdk.internal.session.group.model.GroupRooms import org.matrix.android.sdk.internal.session.group.model.GroupSummaryResponse import org.matrix.android.sdk.internal.session.group.model.GroupUsers import org.matrix.android.sdk.internal.task.Task import org.matrix.android.sdk.internal.util.awaitTransaction -import org.greenrobot.eventbus.EventBus import timber.log.Timber import javax.inject.Inject @@ -43,7 +43,7 @@ internal interface GetGroupDataTask : Task { internal class DefaultGetGroupDataTask @Inject constructor( private val groupAPI: GroupAPI, @SessionDatabase private val monarchy: Monarchy, - private val eventBus: EventBus + private val globalErrorReceiver: GlobalErrorReceiver ) : GetGroupDataTask { private data class GroupData( @@ -64,13 +64,13 @@ internal class DefaultGetGroupDataTask @Inject constructor( } Timber.v("Fetch data for group with ids: ${groupIds.joinToString(";")}") val data = groupIds.map { groupId -> - val groupSummary = executeRequest(eventBus) { + val groupSummary = executeRequest(globalErrorReceiver) { apiCall = groupAPI.getSummary(groupId) } - val groupRooms = executeRequest(eventBus) { + val groupRooms = executeRequest(globalErrorReceiver) { apiCall = groupAPI.getRooms(groupId) } - val groupUsers = executeRequest(eventBus) { + val groupUsers = executeRequest(globalErrorReceiver) { apiCall = groupAPI.getUsers(groupId) } GroupData(groupId, groupSummary, groupRooms, groupUsers) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/homeserver/GetHomeServerCapabilitiesTask.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/homeserver/GetHomeServerCapabilitiesTask.kt index f3686b02d3..845cfb392e 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/homeserver/GetHomeServerCapabilitiesTask.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/homeserver/GetHomeServerCapabilitiesTask.kt @@ -17,7 +17,6 @@ package org.matrix.android.sdk.internal.session.homeserver import com.zhuinden.monarchy.Monarchy -import org.greenrobot.eventbus.EventBus import org.matrix.android.sdk.api.auth.data.HomeServerConnectionConfig import org.matrix.android.sdk.api.auth.wellknown.WellknownResult import org.matrix.android.sdk.api.session.homeserver.HomeServerCapabilities @@ -27,6 +26,7 @@ import org.matrix.android.sdk.internal.database.model.HomeServerCapabilitiesEnti import org.matrix.android.sdk.internal.database.query.getOrCreate import org.matrix.android.sdk.internal.di.SessionDatabase import org.matrix.android.sdk.internal.di.UserId +import org.matrix.android.sdk.internal.network.GlobalErrorReceiver import org.matrix.android.sdk.internal.network.executeRequest import org.matrix.android.sdk.internal.session.integrationmanager.IntegrationManagerConfigExtractor import org.matrix.android.sdk.internal.session.media.GetMediaConfigResult @@ -44,7 +44,7 @@ internal class DefaultGetHomeServerCapabilitiesTask @Inject constructor( private val capabilitiesAPI: CapabilitiesAPI, private val mediaAPI: MediaAPI, @SessionDatabase private val monarchy: Monarchy, - private val eventBus: EventBus, + private val globalErrorReceiver: GlobalErrorReceiver, private val getWellknownTask: GetWellknownTask, private val configExtractor: IntegrationManagerConfigExtractor, private val homeServerConnectionConfig: HomeServerConnectionConfig, @@ -65,13 +65,13 @@ internal class DefaultGetHomeServerCapabilitiesTask @Inject constructor( } val capabilities = runCatching { - executeRequest(eventBus) { + executeRequest(globalErrorReceiver) { apiCall = capabilitiesAPI.getCapabilities() } }.getOrNull() val mediaConfig = runCatching { - executeRequest(eventBus) { + executeRequest(globalErrorReceiver) { apiCall = mediaAPI.getMediaConfig() } }.getOrNull() diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/media/GetPreviewUrlTask.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/media/GetPreviewUrlTask.kt index 69cdfa8faa..a218f3f93c 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/media/GetPreviewUrlTask.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/media/GetPreviewUrlTask.kt @@ -17,7 +17,6 @@ package org.matrix.android.sdk.internal.session.media import com.zhuinden.monarchy.Monarchy -import org.greenrobot.eventbus.EventBus import org.matrix.android.sdk.api.cache.CacheStrategy import org.matrix.android.sdk.api.session.media.PreviewUrlData import org.matrix.android.sdk.api.util.JsonDict @@ -25,6 +24,7 @@ import org.matrix.android.sdk.internal.database.model.PreviewUrlCacheEntity import org.matrix.android.sdk.internal.database.query.get import org.matrix.android.sdk.internal.database.query.getOrCreate import org.matrix.android.sdk.internal.di.SessionDatabase +import org.matrix.android.sdk.internal.network.GlobalErrorReceiver import org.matrix.android.sdk.internal.network.executeRequest import org.matrix.android.sdk.internal.task.Task import org.matrix.android.sdk.internal.util.awaitTransaction @@ -41,7 +41,7 @@ internal interface GetPreviewUrlTask : Task(eventBus) { + return executeRequest(globalErrorReceiver) { apiCall = mediaAPI.getPreviewUrlData(url, timestamp) } .toPreviewUrlData(url) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/media/GetRawPreviewUrlTask.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/media/GetRawPreviewUrlTask.kt index 6c5dad2422..32305cd4e4 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/media/GetRawPreviewUrlTask.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/media/GetRawPreviewUrlTask.kt @@ -16,8 +16,8 @@ package org.matrix.android.sdk.internal.session.media -import org.greenrobot.eventbus.EventBus import org.matrix.android.sdk.api.util.JsonDict +import org.matrix.android.sdk.internal.network.GlobalErrorReceiver import org.matrix.android.sdk.internal.network.executeRequest import org.matrix.android.sdk.internal.task.Task import javax.inject.Inject @@ -31,11 +31,11 @@ internal interface GetRawPreviewUrlTask : Task @@ -27,10 +27,10 @@ internal interface GetOpenIdTokenTask : Task internal class DefaultGetOpenIdTokenTask @Inject constructor( @UserId private val userId: String, private val openIdAPI: OpenIdAPI, - private val eventBus: EventBus) : GetOpenIdTokenTask { + private val globalErrorReceiver: GlobalErrorReceiver) : GetOpenIdTokenTask { override suspend fun execute(params: Unit): RequestOpenIdTokenResponse { - return executeRequest(eventBus) { + return executeRequest(globalErrorReceiver) { apiCall = openIdAPI.openIdToken(userId) } } diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/profile/AddThreePidTask.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/profile/AddThreePidTask.kt index 2e8a0b3884..6d6d70bb0d 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/profile/AddThreePidTask.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/profile/AddThreePidTask.kt @@ -18,9 +18,9 @@ package org.matrix.android.sdk.internal.session.profile import com.google.i18n.phonenumbers.PhoneNumberUtil import com.zhuinden.monarchy.Monarchy -import org.greenrobot.eventbus.EventBus import org.matrix.android.sdk.api.session.identity.ThreePid import org.matrix.android.sdk.internal.di.SessionDatabase +import org.matrix.android.sdk.internal.network.GlobalErrorReceiver import org.matrix.android.sdk.internal.network.executeRequest import org.matrix.android.sdk.internal.task.Task import org.matrix.android.sdk.internal.util.awaitTransaction @@ -37,7 +37,7 @@ internal class DefaultAddThreePidTask @Inject constructor( private val profileAPI: ProfileAPI, @SessionDatabase private val monarchy: Monarchy, private val pendingThreePidMapper: PendingThreePidMapper, - private val eventBus: EventBus) : AddThreePidTask() { + private val globalErrorReceiver: GlobalErrorReceiver) : AddThreePidTask() { override suspend fun execute(params: Params) { when (params.threePid) { @@ -50,7 +50,7 @@ internal class DefaultAddThreePidTask @Inject constructor( val clientSecret = UUID.randomUUID().toString() val sendAttempt = 1 - val result = executeRequest(eventBus) { + val result = executeRequest(globalErrorReceiver) { val body = AddEmailBody( clientSecret = clientSecret, email = threePid.email, @@ -84,7 +84,7 @@ internal class DefaultAddThreePidTask @Inject constructor( val countryCode = parsedNumber.countryCode val country = phoneNumberUtil.getRegionCodeForCountryCode(countryCode) - val result = executeRequest(eventBus) { + val result = executeRequest(globalErrorReceiver) { val body = AddMsisdnBody( clientSecret = clientSecret, country = country, diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/profile/BindThreePidsTask.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/profile/BindThreePidsTask.kt index dbe6bff508..a37e5380bc 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/profile/BindThreePidsTask.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/profile/BindThreePidsTask.kt @@ -19,12 +19,12 @@ package org.matrix.android.sdk.internal.session.profile import org.matrix.android.sdk.api.session.identity.IdentityServiceError import org.matrix.android.sdk.api.session.identity.ThreePid import org.matrix.android.sdk.internal.di.AuthenticatedIdentity +import org.matrix.android.sdk.internal.network.GlobalErrorReceiver import org.matrix.android.sdk.internal.network.executeRequest import org.matrix.android.sdk.internal.network.token.AccessTokenProvider import org.matrix.android.sdk.internal.session.identity.data.IdentityStore import org.matrix.android.sdk.internal.session.identity.data.getIdentityServerUrlWithoutProtocol import org.matrix.android.sdk.internal.task.Task -import org.greenrobot.eventbus.EventBus import javax.inject.Inject internal abstract class BindThreePidsTask : Task { @@ -37,13 +37,13 @@ internal class DefaultBindThreePidsTask @Inject constructor(private val profileA private val identityStore: IdentityStore, @AuthenticatedIdentity private val accessTokenProvider: AccessTokenProvider, - private val eventBus: EventBus) : BindThreePidsTask() { + private val globalErrorReceiver: GlobalErrorReceiver) : BindThreePidsTask() { override suspend fun execute(params: Params) { val identityServerUrlWithoutProtocol = identityStore.getIdentityServerUrlWithoutProtocol() ?: throw IdentityServiceError.NoIdentityServerConfigured val identityServerAccessToken = accessTokenProvider.getToken() ?: throw IdentityServiceError.NoIdentityServerConfigured val identityPendingBinding = identityStore.getPendingBinding(params.threePid) ?: throw IdentityServiceError.NoCurrentBindingError - executeRequest(eventBus) { + executeRequest(globalErrorReceiver) { apiCall = profileAPI.bindThreePid( BindThreePidBody( clientSecret = identityPendingBinding.clientSecret, diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/profile/DeleteThreePidTask.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/profile/DeleteThreePidTask.kt index 3f43cbe599..3549f3613f 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/profile/DeleteThreePidTask.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/profile/DeleteThreePidTask.kt @@ -16,9 +16,9 @@ package org.matrix.android.sdk.internal.session.profile -import org.greenrobot.eventbus.EventBus import org.matrix.android.sdk.api.session.identity.ThreePid import org.matrix.android.sdk.api.session.identity.toMedium +import org.matrix.android.sdk.internal.network.GlobalErrorReceiver import org.matrix.android.sdk.internal.network.executeRequest import org.matrix.android.sdk.internal.task.Task import javax.inject.Inject @@ -31,10 +31,10 @@ internal abstract class DeleteThreePidTask : Task(eventBus) { + executeRequest(globalErrorReceiver) { val body = DeleteThreePidBody( medium = params.threePid.toMedium(), address = params.threePid.value diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/profile/FinalizeAddingThreePidTask.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/profile/FinalizeAddingThreePidTask.kt index 0b1bf88280..1e3a2cb501 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/profile/FinalizeAddingThreePidTask.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/profile/FinalizeAddingThreePidTask.kt @@ -17,7 +17,6 @@ package org.matrix.android.sdk.internal.session.profile import com.zhuinden.monarchy.Monarchy -import org.greenrobot.eventbus.EventBus import org.matrix.android.sdk.api.failure.Failure import org.matrix.android.sdk.api.failure.toRegistrationFlowResponse import org.matrix.android.sdk.api.session.identity.ThreePid @@ -26,6 +25,7 @@ import org.matrix.android.sdk.internal.database.model.PendingThreePidEntity import org.matrix.android.sdk.internal.database.model.PendingThreePidEntityFields import org.matrix.android.sdk.internal.di.SessionDatabase import org.matrix.android.sdk.internal.di.UserId +import org.matrix.android.sdk.internal.network.GlobalErrorReceiver import org.matrix.android.sdk.internal.network.executeRequest import org.matrix.android.sdk.internal.task.Task import org.matrix.android.sdk.internal.util.awaitTransaction @@ -45,7 +45,7 @@ internal class DefaultFinalizeAddingThreePidTask @Inject constructor( @SessionDatabase private val monarchy: Monarchy, private val pendingThreePidMapper: PendingThreePidMapper, @UserId private val userId: String, - private val eventBus: EventBus) : FinalizeAddingThreePidTask() { + private val globalErrorReceiver: GlobalErrorReceiver) : FinalizeAddingThreePidTask() { override suspend fun execute(params: Params) { if (params.userWantsToCancel.not()) { @@ -58,7 +58,7 @@ internal class DefaultFinalizeAddingThreePidTask @Inject constructor( ?: throw IllegalArgumentException("unknown threepid") try { - executeRequest(eventBus) { + executeRequest(globalErrorReceiver) { val body = FinalizeAddThreePidBody( clientSecret = pendingThreePids.clientSecret, sid = pendingThreePids.sid, diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/profile/GetProfileInfoTask.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/profile/GetProfileInfoTask.kt index 5f1f621ddb..ed60c4a368 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/profile/GetProfileInfoTask.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/profile/GetProfileInfoTask.kt @@ -18,9 +18,9 @@ package org.matrix.android.sdk.internal.session.profile import org.matrix.android.sdk.api.util.JsonDict +import org.matrix.android.sdk.internal.network.GlobalErrorReceiver import org.matrix.android.sdk.internal.network.executeRequest import org.matrix.android.sdk.internal.task.Task -import org.greenrobot.eventbus.EventBus import javax.inject.Inject internal abstract class GetProfileInfoTask : Task { @@ -30,10 +30,10 @@ internal abstract class GetProfileInfoTask : Task internal class DefaultRefreshUserThreePidsTask @Inject constructor(private val profileAPI: ProfileAPI, @SessionDatabase private val monarchy: Monarchy, - private val eventBus: EventBus) : RefreshUserThreePidsTask() { + private val globalErrorReceiver: GlobalErrorReceiver) : RefreshUserThreePidsTask() { override suspend fun execute(params: Unit) { - val accountThreePidsResponse = executeRequest(eventBus) { + val accountThreePidsResponse = executeRequest(globalErrorReceiver) { apiCall = profileAPI.getThreePIDs() } diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/profile/SetAvatarUrlTask.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/profile/SetAvatarUrlTask.kt index 4b863c2098..b29153d665 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/profile/SetAvatarUrlTask.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/profile/SetAvatarUrlTask.kt @@ -16,9 +16,9 @@ package org.matrix.android.sdk.internal.session.profile +import org.matrix.android.sdk.internal.network.GlobalErrorReceiver import org.matrix.android.sdk.internal.network.executeRequest import org.matrix.android.sdk.internal.task.Task -import org.greenrobot.eventbus.EventBus import javax.inject.Inject internal abstract class SetAvatarUrlTask : Task { @@ -30,10 +30,10 @@ internal abstract class SetAvatarUrlTask : Task { internal class DefaultSetAvatarUrlTask @Inject constructor( private val profileAPI: ProfileAPI, - private val eventBus: EventBus) : SetAvatarUrlTask() { + private val globalErrorReceiver: GlobalErrorReceiver) : SetAvatarUrlTask() { override suspend fun execute(params: Params) { - return executeRequest(eventBus) { + return executeRequest(globalErrorReceiver) { val body = SetAvatarUrlBody( avatarUrl = params.newAvatarUrl ) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/profile/SetDisplayNameTask.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/profile/SetDisplayNameTask.kt index 1fa84f98c1..3f236bc589 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/profile/SetDisplayNameTask.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/profile/SetDisplayNameTask.kt @@ -16,9 +16,9 @@ package org.matrix.android.sdk.internal.session.profile +import org.matrix.android.sdk.internal.network.GlobalErrorReceiver import org.matrix.android.sdk.internal.network.executeRequest import org.matrix.android.sdk.internal.task.Task -import org.greenrobot.eventbus.EventBus import javax.inject.Inject internal abstract class SetDisplayNameTask : Task { @@ -30,10 +30,10 @@ internal abstract class SetDisplayNameTask : Task { @@ -34,12 +34,12 @@ internal abstract class UnbindThreePidsTask : Task(eventBus) { + return executeRequest(globalErrorReceiver) { apiCall = profileAPI.unbindThreePid( UnbindThreePidBody( identityServerUrlWithoutProtocol, diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/profile/ValidateSmsCodeTask.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/profile/ValidateSmsCodeTask.kt index 36804e06fe..efb6c6e836 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/profile/ValidateSmsCodeTask.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/profile/ValidateSmsCodeTask.kt @@ -17,13 +17,13 @@ package org.matrix.android.sdk.internal.session.profile import com.zhuinden.monarchy.Monarchy -import org.greenrobot.eventbus.EventBus import org.matrix.android.sdk.api.failure.Failure import org.matrix.android.sdk.api.session.identity.ThreePid import org.matrix.android.sdk.internal.auth.registration.SuccessResult import org.matrix.android.sdk.internal.auth.registration.ValidationCodeBody import org.matrix.android.sdk.internal.database.model.PendingThreePidEntity import org.matrix.android.sdk.internal.di.SessionDatabase +import org.matrix.android.sdk.internal.network.GlobalErrorReceiver import org.matrix.android.sdk.internal.network.executeRequest import org.matrix.android.sdk.internal.task.Task import javax.inject.Inject @@ -40,7 +40,7 @@ internal class DefaultValidateSmsCodeTask @Inject constructor( @SessionDatabase private val monarchy: Monarchy, private val pendingThreePidMapper: PendingThreePidMapper, - private val eventBus: EventBus + private val globalErrorReceiver: GlobalErrorReceiver ) : ValidateSmsCodeTask { override suspend fun execute(params: ValidateSmsCodeTask.Params) { @@ -58,7 +58,7 @@ internal class DefaultValidateSmsCodeTask @Inject constructor( sid = pendingThreePids.sid, code = params.code ) - val result = executeRequest(eventBus) { + val result = executeRequest(globalErrorReceiver) { apiCall = profileAPI.validateMsisdn(url, body) } diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/pushers/AddHttpPusherWorker.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/pushers/AddHttpPusherWorker.kt index 31c5cda5ec..d0f7cbfca3 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/pushers/AddHttpPusherWorker.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/pushers/AddHttpPusherWorker.kt @@ -19,13 +19,13 @@ import android.content.Context import androidx.work.WorkerParameters import com.squareup.moshi.JsonClass import com.zhuinden.monarchy.Monarchy -import org.greenrobot.eventbus.EventBus import org.matrix.android.sdk.api.failure.Failure import org.matrix.android.sdk.api.session.pushers.PusherState import org.matrix.android.sdk.internal.database.mapper.toEntity import org.matrix.android.sdk.internal.database.model.PusherEntity import org.matrix.android.sdk.internal.database.query.where import org.matrix.android.sdk.internal.di.SessionDatabase +import org.matrix.android.sdk.internal.network.GlobalErrorReceiver import org.matrix.android.sdk.internal.network.executeRequest import org.matrix.android.sdk.internal.session.SessionComponent import org.matrix.android.sdk.internal.util.awaitTransaction @@ -45,7 +45,7 @@ internal class AddHttpPusherWorker(context: Context, params: WorkerParameters) @Inject lateinit var pushersAPI: PushersAPI @Inject @SessionDatabase lateinit var monarchy: Monarchy - @Inject lateinit var eventBus: EventBus + @Inject lateinit var globalErrorReceiver: GlobalErrorReceiver override fun injectWith(injector: SessionComponent) { injector.inject(this) @@ -81,7 +81,7 @@ internal class AddHttpPusherWorker(context: Context, params: WorkerParameters) } private suspend fun setPusher(pusher: JsonPusher) { - executeRequest(eventBus) { + executeRequest(globalErrorReceiver) { apiCall = pushersAPI.setPusher(pusher) } monarchy.awaitTransaction { realm -> diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/pushers/AddPushRuleTask.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/pushers/AddPushRuleTask.kt index 28ac5db52e..03748b1528 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/pushers/AddPushRuleTask.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/pushers/AddPushRuleTask.kt @@ -17,9 +17,9 @@ package org.matrix.android.sdk.internal.session.pushers import org.matrix.android.sdk.api.pushrules.RuleKind import org.matrix.android.sdk.api.pushrules.rest.PushRule +import org.matrix.android.sdk.internal.network.GlobalErrorReceiver import org.matrix.android.sdk.internal.network.executeRequest import org.matrix.android.sdk.internal.task.Task -import org.greenrobot.eventbus.EventBus import javax.inject.Inject internal interface AddPushRuleTask : Task { @@ -31,11 +31,11 @@ internal interface AddPushRuleTask : Task { internal class DefaultAddPushRuleTask @Inject constructor( private val pushRulesApi: PushRulesApi, - private val eventBus: EventBus + private val globalErrorReceiver: GlobalErrorReceiver ) : AddPushRuleTask { override suspend fun execute(params: AddPushRuleTask.Params) { - return executeRequest(eventBus) { + return executeRequest(globalErrorReceiver) { apiCall = pushRulesApi.addRule(params.kind.value, params.pushRule.ruleId, params.pushRule) } } diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/pushers/GetPushRulesTask.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/pushers/GetPushRulesTask.kt index 0c532cedbc..9fb2d51664 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/pushers/GetPushRulesTask.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/pushers/GetPushRulesTask.kt @@ -16,9 +16,9 @@ package org.matrix.android.sdk.internal.session.pushers import org.matrix.android.sdk.api.pushrules.rest.GetPushRulesResponse +import org.matrix.android.sdk.internal.network.GlobalErrorReceiver import org.matrix.android.sdk.internal.network.executeRequest import org.matrix.android.sdk.internal.task.Task -import org.greenrobot.eventbus.EventBus import javax.inject.Inject internal interface GetPushRulesTask : Task { @@ -31,11 +31,11 @@ internal interface GetPushRulesTask : Task { internal class DefaultGetPushRulesTask @Inject constructor( private val pushRulesApi: PushRulesApi, private val savePushRulesTask: SavePushRulesTask, - private val eventBus: EventBus + private val globalErrorReceiver: GlobalErrorReceiver ) : GetPushRulesTask { override suspend fun execute(params: GetPushRulesTask.Params) { - val response = executeRequest(eventBus) { + val response = executeRequest(globalErrorReceiver) { apiCall = pushRulesApi.getAllRules() } diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/pushers/GetPushersTask.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/pushers/GetPushersTask.kt index 39e970f4a8..4c7d370446 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/pushers/GetPushersTask.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/pushers/GetPushersTask.kt @@ -20,10 +20,10 @@ import org.matrix.android.sdk.api.session.pushers.PusherState import org.matrix.android.sdk.internal.database.mapper.toEntity import org.matrix.android.sdk.internal.database.model.PusherEntity import org.matrix.android.sdk.internal.di.SessionDatabase +import org.matrix.android.sdk.internal.network.GlobalErrorReceiver import org.matrix.android.sdk.internal.network.executeRequest import org.matrix.android.sdk.internal.task.Task import org.matrix.android.sdk.internal.util.awaitTransaction -import org.greenrobot.eventbus.EventBus import javax.inject.Inject internal interface GetPushersTask : Task @@ -31,11 +31,11 @@ internal interface GetPushersTask : Task internal class DefaultGetPushersTask @Inject constructor( private val pushersAPI: PushersAPI, @SessionDatabase private val monarchy: Monarchy, - private val eventBus: EventBus + private val globalErrorReceiver: GlobalErrorReceiver ) : GetPushersTask { override suspend fun execute(params: Unit) { - val response = executeRequest(eventBus) { + val response = executeRequest(globalErrorReceiver) { apiCall = pushersAPI.getPushers() } monarchy.awaitTransaction { realm -> diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/pushers/RemovePushRuleTask.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/pushers/RemovePushRuleTask.kt index 2fc97cf023..ff3122f566 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/pushers/RemovePushRuleTask.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/pushers/RemovePushRuleTask.kt @@ -17,9 +17,9 @@ package org.matrix.android.sdk.internal.session.pushers import org.matrix.android.sdk.api.pushrules.RuleKind import org.matrix.android.sdk.api.pushrules.rest.PushRule +import org.matrix.android.sdk.internal.network.GlobalErrorReceiver import org.matrix.android.sdk.internal.network.executeRequest import org.matrix.android.sdk.internal.task.Task -import org.greenrobot.eventbus.EventBus import javax.inject.Inject internal interface RemovePushRuleTask : Task { @@ -31,11 +31,11 @@ internal interface RemovePushRuleTask : Task { internal class DefaultRemovePushRuleTask @Inject constructor( private val pushRulesApi: PushRulesApi, - private val eventBus: EventBus + private val globalErrorReceiver: GlobalErrorReceiver ) : RemovePushRuleTask { override suspend fun execute(params: RemovePushRuleTask.Params) { - return executeRequest(eventBus) { + return executeRequest(globalErrorReceiver) { apiCall = pushRulesApi.deleteRule(params.kind.value, params.pushRule.ruleId) } } diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/pushers/RemovePusherTask.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/pushers/RemovePusherTask.kt index 1f10863799..e3f4fdb789 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/pushers/RemovePusherTask.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/pushers/RemovePusherTask.kt @@ -26,7 +26,7 @@ import org.matrix.android.sdk.internal.network.executeRequest import org.matrix.android.sdk.internal.task.Task import org.matrix.android.sdk.internal.util.awaitTransaction import io.realm.Realm -import org.greenrobot.eventbus.EventBus +import org.matrix.android.sdk.internal.network.GlobalErrorReceiver import javax.inject.Inject internal interface RemovePusherTask : Task { @@ -37,7 +37,7 @@ internal interface RemovePusherTask : Task { internal class DefaultRemovePusherTask @Inject constructor( private val pushersAPI: PushersAPI, @SessionDatabase private val monarchy: Monarchy, - private val eventBus: EventBus + private val globalErrorReceiver: GlobalErrorReceiver ) : RemovePusherTask { override suspend fun execute(params: RemovePusherTask.Params) { @@ -62,7 +62,7 @@ internal class DefaultRemovePusherTask @Inject constructor( data = JsonPusherData(existing.data.url, existing.data.format), append = false ) - executeRequest(eventBus) { + executeRequest(globalErrorReceiver) { apiCall = pushersAPI.setPusher(deleteBody) } monarchy.awaitTransaction { diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/pushers/UpdatePushRuleActionsTask.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/pushers/UpdatePushRuleActionsTask.kt index c2dca8a9a5..a5c220e662 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/pushers/UpdatePushRuleActionsTask.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/pushers/UpdatePushRuleActionsTask.kt @@ -17,9 +17,9 @@ package org.matrix.android.sdk.internal.session.pushers import org.matrix.android.sdk.api.pushrules.RuleKind import org.matrix.android.sdk.api.pushrules.rest.PushRule +import org.matrix.android.sdk.internal.network.GlobalErrorReceiver import org.matrix.android.sdk.internal.network.executeRequest import org.matrix.android.sdk.internal.task.Task -import org.greenrobot.eventbus.EventBus import javax.inject.Inject internal interface UpdatePushRuleActionsTask : Task { @@ -32,13 +32,13 @@ internal interface UpdatePushRuleActionsTask : Task(eventBus) { + executeRequest(globalErrorReceiver) { apiCall = pushRulesApi.updateEnableRuleStatus(params.kind.value, params.newPushRule.ruleId, params.newPushRule.enabled) } } @@ -47,7 +47,7 @@ internal class DefaultUpdatePushRuleActionsTask @Inject constructor( // Also ensure the actions are up to date val body = mapOf("actions" to params.newPushRule.actions) - executeRequest(eventBus) { + executeRequest(globalErrorReceiver) { apiCall = pushRulesApi.updateRuleActions(params.kind.value, params.newPushRule.ruleId, body) } } diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/pushers/UpdatePushRuleEnableStatusTask.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/pushers/UpdatePushRuleEnableStatusTask.kt index 4100071c90..f36b5c55fb 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/pushers/UpdatePushRuleEnableStatusTask.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/pushers/UpdatePushRuleEnableStatusTask.kt @@ -17,9 +17,9 @@ package org.matrix.android.sdk.internal.session.pushers import org.matrix.android.sdk.api.pushrules.RuleKind import org.matrix.android.sdk.api.pushrules.rest.PushRule +import org.matrix.android.sdk.internal.network.GlobalErrorReceiver import org.matrix.android.sdk.internal.network.executeRequest import org.matrix.android.sdk.internal.task.Task -import org.greenrobot.eventbus.EventBus import javax.inject.Inject internal interface UpdatePushRuleEnableStatusTask : Task { @@ -30,11 +30,11 @@ internal interface UpdatePushRuleEnableStatusTask : Task(eventBus) { + executeRequest(globalErrorReceiver) { apiCall = directoryAPI.addRoomAlias( roomAlias = params.aliasLocalPart.toFullLocalAlias(userId), body = AddRoomAliasBody( diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/alias/DeleteRoomAliasTask.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/alias/DeleteRoomAliasTask.kt index 3400fd994c..6ad3db90a9 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/alias/DeleteRoomAliasTask.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/alias/DeleteRoomAliasTask.kt @@ -16,7 +16,7 @@ package org.matrix.android.sdk.internal.session.room.alias -import org.greenrobot.eventbus.EventBus +import org.matrix.android.sdk.internal.network.GlobalErrorReceiver import org.matrix.android.sdk.internal.network.executeRequest import org.matrix.android.sdk.internal.session.directory.DirectoryAPI import org.matrix.android.sdk.internal.task.Task @@ -30,11 +30,11 @@ internal interface DeleteRoomAliasTask : Task internal class DefaultDeleteRoomAliasTask @Inject constructor( private val directoryAPI: DirectoryAPI, - private val eventBus: EventBus + private val globalErrorReceiver: GlobalErrorReceiver ) : DeleteRoomAliasTask { override suspend fun execute(params: DeleteRoomAliasTask.Params) { - executeRequest(eventBus) { + executeRequest(globalErrorReceiver) { apiCall = directoryAPI.deleteRoomAlias( roomAlias = params.roomAlias ) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/alias/GetRoomIdByAliasTask.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/alias/GetRoomIdByAliasTask.kt index 543d605707..a53ffc4fcd 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/alias/GetRoomIdByAliasTask.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/alias/GetRoomIdByAliasTask.kt @@ -18,12 +18,12 @@ package org.matrix.android.sdk.internal.session.room.alias import com.zhuinden.monarchy.Monarchy import io.realm.Realm -import org.greenrobot.eventbus.EventBus import org.matrix.android.sdk.api.extensions.tryOrNull import org.matrix.android.sdk.api.util.Optional import org.matrix.android.sdk.internal.database.model.RoomSummaryEntity import org.matrix.android.sdk.internal.database.query.findByAlias import org.matrix.android.sdk.internal.di.SessionDatabase +import org.matrix.android.sdk.internal.network.GlobalErrorReceiver import org.matrix.android.sdk.internal.network.executeRequest import org.matrix.android.sdk.internal.session.directory.DirectoryAPI import org.matrix.android.sdk.internal.task.Task @@ -39,7 +39,7 @@ internal interface GetRoomIdByAliasTask : Task { @@ -52,7 +52,7 @@ internal class DefaultGetRoomIdByAliasTask @Inject constructor( Optional.from(null) } else { val description = tryOrNull("## Failed to get roomId from alias") { - executeRequest(eventBus) { + executeRequest(globalErrorReceiver) { apiCall = directoryAPI.getRoomIdByAlias(params.roomAlias) } } diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/alias/GetRoomLocalAliasesTask.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/alias/GetRoomLocalAliasesTask.kt index 7cfce4ecdc..202cb1f6de 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/alias/GetRoomLocalAliasesTask.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/alias/GetRoomLocalAliasesTask.kt @@ -16,7 +16,7 @@ package org.matrix.android.sdk.internal.session.room.alias -import org.greenrobot.eventbus.EventBus +import org.matrix.android.sdk.internal.network.GlobalErrorReceiver import org.matrix.android.sdk.internal.network.executeRequest import org.matrix.android.sdk.internal.session.room.RoomAPI import org.matrix.android.sdk.internal.task.Task @@ -30,12 +30,12 @@ internal interface GetRoomLocalAliasesTask : Task { // We do not check for "org.matrix.msc2432", so the API may be missing - val response = executeRequest(eventBus) { + val response = executeRequest(globalErrorReceiver) { apiCall = roomAPI.getAliases(roomId = params.roomId) } diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/alias/RoomAliasAvailabilityChecker.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/alias/RoomAliasAvailabilityChecker.kt index 25ba493891..51a849a35e 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/alias/RoomAliasAvailabilityChecker.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/alias/RoomAliasAvailabilityChecker.kt @@ -16,10 +16,10 @@ package org.matrix.android.sdk.internal.session.room.alias -import org.greenrobot.eventbus.EventBus import org.matrix.android.sdk.api.failure.Failure import org.matrix.android.sdk.api.session.room.alias.RoomAliasError import org.matrix.android.sdk.internal.di.UserId +import org.matrix.android.sdk.internal.network.GlobalErrorReceiver import org.matrix.android.sdk.internal.network.executeRequest import org.matrix.android.sdk.internal.session.directory.DirectoryAPI import javax.inject.Inject @@ -27,7 +27,7 @@ import javax.inject.Inject internal class RoomAliasAvailabilityChecker @Inject constructor( @UserId private val userId: String, private val directoryAPI: DirectoryAPI, - private val eventBus: EventBus + private val globalErrorReceiver: GlobalErrorReceiver ) { /** * @param aliasLocalPart the local part of the alias. @@ -41,7 +41,7 @@ internal class RoomAliasAvailabilityChecker @Inject constructor( // Check alias availability val fullAlias = aliasLocalPart.toFullLocalAlias(userId) try { - executeRequest(eventBus) { + executeRequest(globalErrorReceiver) { apiCall = directoryAPI.getRoomIdByAlias(fullAlias) } } catch (throwable: Throwable) { diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/create/CreateRoomTask.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/create/CreateRoomTask.kt index ef792ab98e..9c16bd1b0f 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/create/CreateRoomTask.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/create/CreateRoomTask.kt @@ -19,7 +19,6 @@ package org.matrix.android.sdk.internal.session.room.create import com.zhuinden.monarchy.Monarchy import io.realm.RealmConfiguration import kotlinx.coroutines.TimeoutCancellationException -import org.greenrobot.eventbus.EventBus import org.matrix.android.sdk.api.failure.Failure import org.matrix.android.sdk.api.failure.MatrixError import org.matrix.android.sdk.api.session.room.alias.RoomAliasError @@ -32,6 +31,7 @@ import org.matrix.android.sdk.internal.database.model.RoomEntityFields import org.matrix.android.sdk.internal.database.model.RoomSummaryEntity import org.matrix.android.sdk.internal.database.query.where import org.matrix.android.sdk.internal.di.SessionDatabase +import org.matrix.android.sdk.internal.network.GlobalErrorReceiver import org.matrix.android.sdk.internal.network.executeRequest import org.matrix.android.sdk.internal.session.room.RoomAPI import org.matrix.android.sdk.internal.session.room.alias.RoomAliasAvailabilityChecker @@ -55,7 +55,7 @@ internal class DefaultCreateRoomTask @Inject constructor( @SessionDatabase private val realmConfiguration: RealmConfiguration, private val createRoomBodyBuilder: CreateRoomBodyBuilder, - private val eventBus: EventBus + private val globalErrorReceiver: GlobalErrorReceiver ) : CreateRoomTask { override suspend fun execute(params: CreateRoomParams): String { @@ -75,7 +75,7 @@ internal class DefaultCreateRoomTask @Inject constructor( val createRoomBody = createRoomBodyBuilder.build(params) val createRoomResponse = try { - executeRequest(eventBus) { + executeRequest(globalErrorReceiver) { apiCall = roomAPI.createRoom(createRoomBody) } } catch (throwable: Throwable) { diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/directory/GetPublicRoomTask.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/directory/GetPublicRoomTask.kt index f2bd0c5f69..edd8ae9b0d 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/directory/GetPublicRoomTask.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/directory/GetPublicRoomTask.kt @@ -18,10 +18,10 @@ package org.matrix.android.sdk.internal.session.room.directory import org.matrix.android.sdk.api.session.room.model.roomdirectory.PublicRoomsParams import org.matrix.android.sdk.api.session.room.model.roomdirectory.PublicRoomsResponse +import org.matrix.android.sdk.internal.network.GlobalErrorReceiver import org.matrix.android.sdk.internal.network.executeRequest import org.matrix.android.sdk.internal.session.room.RoomAPI import org.matrix.android.sdk.internal.task.Task -import org.greenrobot.eventbus.EventBus import javax.inject.Inject internal interface GetPublicRoomTask : Task { @@ -33,11 +33,11 @@ internal interface GetPublicRoomTask : Task(eventBus) { + return executeRequest(globalErrorReceiver) { apiCall = directoryAPI.getRoomDirectoryVisibility(params.roomId) } .visibility diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/directory/GetThirdPartyProtocolsTask.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/directory/GetThirdPartyProtocolsTask.kt index 5e08284706..3477aa671e 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/directory/GetThirdPartyProtocolsTask.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/directory/GetThirdPartyProtocolsTask.kt @@ -17,21 +17,21 @@ package org.matrix.android.sdk.internal.session.room.directory import org.matrix.android.sdk.api.session.room.model.thirdparty.ThirdPartyProtocol +import org.matrix.android.sdk.internal.network.GlobalErrorReceiver import org.matrix.android.sdk.internal.network.executeRequest import org.matrix.android.sdk.internal.session.room.RoomAPI import org.matrix.android.sdk.internal.task.Task -import org.greenrobot.eventbus.EventBus import javax.inject.Inject internal interface GetThirdPartyProtocolsTask : Task> internal class DefaultGetThirdPartyProtocolsTask @Inject constructor( private val roomAPI: RoomAPI, - private val eventBus: EventBus + private val globalErrorReceiver: GlobalErrorReceiver ) : GetThirdPartyProtocolsTask { override suspend fun execute(params: Unit): Map { - return executeRequest(eventBus) { + return executeRequest(globalErrorReceiver) { apiCall = roomAPI.thirdPartyProtocols() } } diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/directory/SetRoomDirectoryVisibilityTask.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/directory/SetRoomDirectoryVisibilityTask.kt index 33b12aa1ca..cbb0b6d5d1 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/directory/SetRoomDirectoryVisibilityTask.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/directory/SetRoomDirectoryVisibilityTask.kt @@ -16,8 +16,8 @@ package org.matrix.android.sdk.internal.session.room.directory -import org.greenrobot.eventbus.EventBus import org.matrix.android.sdk.api.session.room.model.RoomDirectoryVisibility +import org.matrix.android.sdk.internal.network.GlobalErrorReceiver import org.matrix.android.sdk.internal.network.executeRequest import org.matrix.android.sdk.internal.session.directory.DirectoryAPI import org.matrix.android.sdk.internal.session.directory.RoomDirectoryVisibilityJson @@ -33,11 +33,11 @@ internal interface SetRoomDirectoryVisibilityTask : Task(eventBus) { + executeRequest(globalErrorReceiver) { apiCall = directoryAPI.setRoomDirectoryVisibility( params.roomId, RoomDirectoryVisibilityJson(visibility = params.roomDirectoryVisibility) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/membership/LoadRoomMembersTask.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/membership/LoadRoomMembersTask.kt index 53fa73c624..2be90bf8e3 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/membership/LoadRoomMembersTask.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/membership/LoadRoomMembersTask.kt @@ -20,7 +20,6 @@ import com.zhuinden.monarchy.Monarchy import io.realm.Realm import io.realm.kotlin.createObject import kotlinx.coroutines.TimeoutCancellationException -import org.greenrobot.eventbus.EventBus import org.matrix.android.sdk.api.session.room.model.Membership import org.matrix.android.sdk.api.session.room.send.SendState import org.matrix.android.sdk.internal.database.awaitNotEmptyResult @@ -34,6 +33,7 @@ import org.matrix.android.sdk.internal.database.query.copyToRealmOrIgnore import org.matrix.android.sdk.internal.database.query.getOrCreate import org.matrix.android.sdk.internal.database.query.where import org.matrix.android.sdk.internal.di.SessionDatabase +import org.matrix.android.sdk.internal.network.GlobalErrorReceiver import org.matrix.android.sdk.internal.network.executeRequest import org.matrix.android.sdk.internal.session.room.RoomAPI import org.matrix.android.sdk.internal.session.room.summary.RoomSummaryUpdater @@ -57,7 +57,7 @@ internal class DefaultLoadRoomMembersTask @Inject constructor( private val syncTokenStore: SyncTokenStore, private val roomSummaryUpdater: RoomSummaryUpdater, private val roomMemberEventHandler: RoomMemberEventHandler, - private val eventBus: EventBus + private val globalErrorReceiver: GlobalErrorReceiver ) : LoadRoomMembersTask { override suspend fun execute(params: LoadRoomMembersTask.Params) { @@ -86,7 +86,7 @@ internal class DefaultLoadRoomMembersTask @Inject constructor( val lastToken = syncTokenStore.getLastToken() val response = try { - executeRequest(eventBus) { + executeRequest(globalErrorReceiver) { apiCall = roomAPI.getMembers(params.roomId, lastToken, null, params.excludeMembership?.value) } } catch (throwable: Throwable) { diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/membership/joining/InviteTask.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/membership/joining/InviteTask.kt index 854a332679..05503bd643 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/membership/joining/InviteTask.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/membership/joining/InviteTask.kt @@ -16,10 +16,10 @@ package org.matrix.android.sdk.internal.session.room.membership.joining +import org.matrix.android.sdk.internal.network.GlobalErrorReceiver import org.matrix.android.sdk.internal.network.executeRequest import org.matrix.android.sdk.internal.session.room.RoomAPI import org.matrix.android.sdk.internal.task.Task -import org.greenrobot.eventbus.EventBus import javax.inject.Inject internal interface InviteTask : Task { @@ -32,11 +32,11 @@ internal interface InviteTask : Task { internal class DefaultInviteTask @Inject constructor( private val roomAPI: RoomAPI, - private val eventBus: EventBus + private val globalErrorReceiver: GlobalErrorReceiver ) : InviteTask { override suspend fun execute(params: InviteTask.Params) { - return executeRequest(eventBus) { + return executeRequest(globalErrorReceiver) { val body = InviteBody(params.userId, params.reason) apiCall = roomAPI.invite(params.roomId, body) isRetryable = true diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/membership/joining/JoinRoomTask.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/membership/joining/JoinRoomTask.kt index dd1dc5fa8a..140c6841f5 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/membership/joining/JoinRoomTask.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/membership/joining/JoinRoomTask.kt @@ -30,7 +30,7 @@ import org.matrix.android.sdk.internal.session.room.read.SetReadMarkersTask import org.matrix.android.sdk.internal.task.Task import io.realm.RealmConfiguration import kotlinx.coroutines.TimeoutCancellationException -import org.greenrobot.eventbus.EventBus +import org.matrix.android.sdk.internal.network.GlobalErrorReceiver import java.util.concurrent.TimeUnit import javax.inject.Inject @@ -48,13 +48,13 @@ internal class DefaultJoinRoomTask @Inject constructor( @SessionDatabase private val realmConfiguration: RealmConfiguration, private val roomChangeMembershipStateDataSource: RoomChangeMembershipStateDataSource, - private val eventBus: EventBus + private val globalErrorReceiver: GlobalErrorReceiver ) : JoinRoomTask { override suspend fun execute(params: JoinRoomTask.Params) { roomChangeMembershipStateDataSource.updateState(params.roomIdOrAlias, ChangeMembershipState.Joining) val joinRoomResponse = try { - executeRequest(eventBus) { + executeRequest(globalErrorReceiver) { apiCall = roomAPI.join(params.roomIdOrAlias, params.viaServers, mapOf("reason" to params.reason)) } } catch (failure: Throwable) { diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/membership/leaving/LeaveRoomTask.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/membership/leaving/LeaveRoomTask.kt index 58e34a15ec..37bb7570d1 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/membership/leaving/LeaveRoomTask.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/membership/leaving/LeaveRoomTask.kt @@ -21,13 +21,13 @@ import org.matrix.android.sdk.api.session.events.model.EventType import org.matrix.android.sdk.api.session.events.model.toModel import org.matrix.android.sdk.api.session.room.members.ChangeMembershipState import org.matrix.android.sdk.api.session.room.model.create.RoomCreateContent +import org.matrix.android.sdk.internal.network.GlobalErrorReceiver import org.matrix.android.sdk.internal.network.executeRequest import org.matrix.android.sdk.internal.session.room.RoomAPI import org.matrix.android.sdk.internal.session.room.membership.RoomChangeMembershipStateDataSource import org.matrix.android.sdk.internal.session.room.state.StateEventDataSource import org.matrix.android.sdk.internal.session.room.summary.RoomSummaryDataSource import org.matrix.android.sdk.internal.task.Task -import org.greenrobot.eventbus.EventBus import timber.log.Timber import javax.inject.Inject @@ -40,7 +40,7 @@ internal interface LeaveRoomTask : Task { internal class DefaultLeaveRoomTask @Inject constructor( private val roomAPI: RoomAPI, - private val eventBus: EventBus, + private val globalErrorReceiver: GlobalErrorReceiver, private val stateEventDataSource: StateEventDataSource, private val roomSummaryDataSource: RoomSummaryDataSource, private val roomChangeMembershipStateDataSource: RoomChangeMembershipStateDataSource @@ -68,7 +68,7 @@ internal class DefaultLeaveRoomTask @Inject constructor( leaveRoom(predecessorRoomId, reason) } try { - executeRequest(eventBus) { + executeRequest(globalErrorReceiver) { apiCall = roomAPI.leave(roomId, mapOf("reason" to reason)) } } catch (failure: Throwable) { diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/membership/threepid/InviteThreePidTask.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/membership/threepid/InviteThreePidTask.kt index 80af00fc78..d237ec795e 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/membership/threepid/InviteThreePidTask.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/membership/threepid/InviteThreePidTask.kt @@ -16,11 +16,11 @@ package org.matrix.android.sdk.internal.session.room.membership.threepid -import org.greenrobot.eventbus.EventBus import org.matrix.android.sdk.api.session.identity.IdentityServiceError import org.matrix.android.sdk.api.session.identity.ThreePid import org.matrix.android.sdk.api.session.identity.toMedium import org.matrix.android.sdk.internal.di.AuthenticatedIdentity +import org.matrix.android.sdk.internal.network.GlobalErrorReceiver import org.matrix.android.sdk.internal.network.executeRequest import org.matrix.android.sdk.internal.network.token.AccessTokenProvider import org.matrix.android.sdk.internal.session.identity.EnsureIdentityTokenTask @@ -39,7 +39,7 @@ internal interface InviteThreePidTask : Task { internal class DefaultInviteThreePidTask @Inject constructor( private val roomAPI: RoomAPI, - private val eventBus: EventBus, + private val globalErrorReceiver: GlobalErrorReceiver, private val identityStore: IdentityStore, private val ensureIdentityTokenTask: EnsureIdentityTokenTask, @AuthenticatedIdentity @@ -52,7 +52,7 @@ internal class DefaultInviteThreePidTask @Inject constructor( val identityServerUrlWithoutProtocol = identityStore.getIdentityServerUrlWithoutProtocol() ?: throw IdentityServiceError.NoIdentityServerConfigured val identityServerAccessToken = accessTokenProvider.getToken() ?: throw IdentityServiceError.NoIdentityServerConfigured - return executeRequest(eventBus) { + return executeRequest(globalErrorReceiver) { val body = ThreePidInviteBody( idServer = identityServerUrlWithoutProtocol, idAccessToken = identityServerAccessToken, diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/peeking/ResolveRoomStateTask.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/peeking/ResolveRoomStateTask.kt index 03ea2408f0..dbec6b555c 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/peeking/ResolveRoomStateTask.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/peeking/ResolveRoomStateTask.kt @@ -16,8 +16,8 @@ package org.matrix.android.sdk.internal.session.room.peeking -import org.greenrobot.eventbus.EventBus import org.matrix.android.sdk.api.session.events.model.Event +import org.matrix.android.sdk.internal.network.GlobalErrorReceiver import org.matrix.android.sdk.internal.network.executeRequest import org.matrix.android.sdk.internal.session.room.RoomAPI import org.matrix.android.sdk.internal.task.Task @@ -31,11 +31,11 @@ internal interface ResolveRoomStateTask : Task { - return executeRequest(eventBus) { + return executeRequest(globalErrorReceiver) { apiCall = roomAPI.getRoomState(params.roomId) } } diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/read/SetReadMarkersTask.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/read/SetReadMarkersTask.kt index a98bb02c83..c7f962a699 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/read/SetReadMarkersTask.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/read/SetReadMarkersTask.kt @@ -33,7 +33,7 @@ import org.matrix.android.sdk.internal.session.sync.RoomFullyReadHandler import org.matrix.android.sdk.internal.task.Task import org.matrix.android.sdk.internal.util.awaitTransaction import io.realm.Realm -import org.greenrobot.eventbus.EventBus +import org.matrix.android.sdk.internal.network.GlobalErrorReceiver import timber.log.Timber import javax.inject.Inject import kotlin.collections.set @@ -58,7 +58,7 @@ internal class DefaultSetReadMarkersTask @Inject constructor( private val roomFullyReadHandler: RoomFullyReadHandler, private val readReceiptHandler: ReadReceiptHandler, @UserId private val userId: String, - private val eventBus: EventBus + private val globalErrorReceiver: GlobalErrorReceiver ) : SetReadMarkersTask { override suspend fun execute(params: SetReadMarkersTask.Params) { @@ -96,7 +96,7 @@ internal class DefaultSetReadMarkersTask @Inject constructor( updateDatabase(params.roomId, markers, shouldUpdateRoomSummary) } if (markers.isNotEmpty()) { - executeRequest(eventBus) { + executeRequest(globalErrorReceiver) { isRetryable = true apiCall = roomAPI.sendReadMarker(params.roomId, markers) } diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/relation/FetchEditHistoryTask.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/relation/FetchEditHistoryTask.kt index 51eecb8c2a..99d02b50da 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/relation/FetchEditHistoryTask.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/relation/FetchEditHistoryTask.kt @@ -18,10 +18,10 @@ package org.matrix.android.sdk.internal.session.room.relation import org.matrix.android.sdk.api.session.events.model.Event import org.matrix.android.sdk.api.session.events.model.EventType import org.matrix.android.sdk.api.session.events.model.RelationType +import org.matrix.android.sdk.internal.network.GlobalErrorReceiver import org.matrix.android.sdk.internal.network.executeRequest import org.matrix.android.sdk.internal.session.room.RoomAPI import org.matrix.android.sdk.internal.task.Task -import org.greenrobot.eventbus.EventBus import javax.inject.Inject internal interface FetchEditHistoryTask : Task> { @@ -35,11 +35,11 @@ internal interface FetchEditHistoryTask : Task { - val response = executeRequest(eventBus) { + val response = executeRequest(globalErrorReceiver) { apiCall = roomAPI.getRelations(params.roomId, params.eventId, RelationType.REPLACE, diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/relation/SendRelationWorker.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/relation/SendRelationWorker.kt index 25dfe32cbb..c12597bea0 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/relation/SendRelationWorker.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/relation/SendRelationWorker.kt @@ -18,12 +18,12 @@ package org.matrix.android.sdk.internal.session.room.relation import android.content.Context import androidx.work.WorkerParameters import com.squareup.moshi.JsonClass -import org.greenrobot.eventbus.EventBus import org.matrix.android.sdk.api.failure.Failure import org.matrix.android.sdk.api.session.events.model.Event import org.matrix.android.sdk.api.session.events.model.toModel import org.matrix.android.sdk.api.session.room.model.relation.ReactionContent import org.matrix.android.sdk.api.session.room.model.relation.ReactionInfo +import org.matrix.android.sdk.internal.network.GlobalErrorReceiver import org.matrix.android.sdk.internal.network.executeRequest import org.matrix.android.sdk.internal.session.SessionComponent import org.matrix.android.sdk.internal.session.room.RoomAPI @@ -47,7 +47,7 @@ internal class SendRelationWorker(context: Context, params: WorkerParameters) ) : SessionWorkerParams @Inject lateinit var roomAPI: RoomAPI - @Inject lateinit var eventBus: EventBus + @Inject lateinit var globalErrorReceiver: GlobalErrorReceiver @Inject lateinit var localEchoRepository: LocalEchoRepository override fun injectWith(injector: SessionComponent) { @@ -84,7 +84,7 @@ internal class SendRelationWorker(context: Context, params: WorkerParameters) } private suspend fun sendRelation(roomId: String, relationType: String, relatedEventId: String, localEvent: Event) { - executeRequest(eventBus) { + executeRequest(globalErrorReceiver) { apiCall = roomAPI.sendRelation( roomId = roomId, parentId = relatedEventId, diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/reporting/ReportContentTask.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/reporting/ReportContentTask.kt index bd11937676..9c6e9907a4 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/reporting/ReportContentTask.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/reporting/ReportContentTask.kt @@ -16,10 +16,10 @@ package org.matrix.android.sdk.internal.session.room.reporting +import org.matrix.android.sdk.internal.network.GlobalErrorReceiver import org.matrix.android.sdk.internal.network.executeRequest import org.matrix.android.sdk.internal.session.room.RoomAPI import org.matrix.android.sdk.internal.task.Task -import org.greenrobot.eventbus.EventBus import javax.inject.Inject internal interface ReportContentTask : Task { @@ -33,11 +33,11 @@ internal interface ReportContentTask : Task { internal class DefaultReportContentTask @Inject constructor( private val roomAPI: RoomAPI, - private val eventBus: EventBus + private val globalErrorReceiver: GlobalErrorReceiver ) : ReportContentTask { override suspend fun execute(params: ReportContentTask.Params) { - return executeRequest(eventBus) { + return executeRequest(globalErrorReceiver) { apiCall = roomAPI.reportContent(params.roomId, params.eventId, ReportContentBody(params.score, params.reason)) } } diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/send/LocalEchoRepository.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/send/LocalEchoRepository.kt index f4871ab35d..f742271fa7 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/send/LocalEchoRepository.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/send/LocalEchoRepository.kt @@ -18,7 +18,6 @@ package org.matrix.android.sdk.internal.session.room.send import com.zhuinden.monarchy.Monarchy import io.realm.Realm -import org.greenrobot.eventbus.EventBus import org.matrix.android.sdk.api.session.events.model.Event import org.matrix.android.sdk.api.session.events.model.EventType import org.matrix.android.sdk.api.session.events.model.toModel @@ -42,7 +41,7 @@ import org.matrix.android.sdk.internal.database.query.where import org.matrix.android.sdk.internal.di.SessionDatabase import org.matrix.android.sdk.internal.session.room.membership.RoomMemberHelper import org.matrix.android.sdk.internal.session.room.summary.RoomSummaryUpdater -import org.matrix.android.sdk.internal.session.room.timeline.DefaultTimeline +import org.matrix.android.sdk.internal.session.room.timeline.TimelineInput import org.matrix.android.sdk.internal.task.TaskExecutor import org.matrix.android.sdk.internal.util.awaitTransaction import timber.log.Timber @@ -52,7 +51,7 @@ internal class LocalEchoRepository @Inject constructor(@SessionDatabase private private val taskExecutor: TaskExecutor, private val realmSessionProvider: RealmSessionProvider, private val roomSummaryUpdater: RoomSummaryUpdater, - private val eventBus: EventBus, + private val timelineInput: TimelineInput, private val timelineEventMapper: TimelineEventMapper) { fun createLocalEcho(event: Event) { @@ -76,7 +75,7 @@ internal class LocalEchoRepository @Inject constructor(@SessionDatabase private } } val timelineEvent = timelineEventMapper.map(timelineEventEntity) - eventBus.post(DefaultTimeline.OnLocalEchoCreated(roomId = roomId, timelineEvent = timelineEvent)) + timelineInput.onLocalEchoCreated(roomId = roomId, timelineEvent = timelineEvent) taskExecutor.executorScope.asyncTransaction(monarchy) { realm -> val eventInsertEntity = EventInsertEntity(event.eventId, event.type).apply { this.insertType = EventInsertType.LOCAL_ECHO @@ -90,7 +89,7 @@ internal class LocalEchoRepository @Inject constructor(@SessionDatabase private fun updateSendState(eventId: String, roomId: String?, sendState: SendState) { Timber.v("## SendEvent: [${System.currentTimeMillis()}] Update local state of $eventId to ${sendState.name}") - eventBus.post(DefaultTimeline.OnLocalEchoUpdated(roomId ?: "", eventId, sendState)) + timelineInput.onLocalEchoUpdated(roomId = roomId ?: "", eventId = eventId, sendState = sendState) updateEchoAsync(eventId) { realm, sendingEventEntity -> if (sendState == SendState.SENT && sendingEventEntity.sendState == SendState.SYNCED) { // If already synced, do not put as sent diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/send/RedactEventWorker.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/send/RedactEventWorker.kt index 682865eaee..c901c7e18e 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/send/RedactEventWorker.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/send/RedactEventWorker.kt @@ -18,8 +18,8 @@ package org.matrix.android.sdk.internal.session.room.send import android.content.Context import androidx.work.WorkerParameters import com.squareup.moshi.JsonClass -import org.greenrobot.eventbus.EventBus import org.matrix.android.sdk.api.failure.Failure +import org.matrix.android.sdk.internal.network.GlobalErrorReceiver import org.matrix.android.sdk.internal.network.executeRequest import org.matrix.android.sdk.internal.session.SessionComponent import org.matrix.android.sdk.internal.session.room.RoomAPI @@ -46,7 +46,7 @@ internal class RedactEventWorker(context: Context, params: WorkerParameters) ) : SessionWorkerParams @Inject lateinit var roomAPI: RoomAPI - @Inject lateinit var eventBus: EventBus + @Inject lateinit var globalErrorReceiver: GlobalErrorReceiver override fun injectWith(injector: SessionComponent) { injector.inject(this) @@ -55,7 +55,7 @@ internal class RedactEventWorker(context: Context, params: WorkerParameters) override suspend fun doSafeWork(params: Params): Result { val eventId = params.eventId return runCatching { - executeRequest(eventBus) { + executeRequest(globalErrorReceiver) { apiCall = roomAPI.redactEvent( params.txID, params.roomId, diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/send/SendEventWorker.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/send/SendEventWorker.kt index 37a429d242..c1fc2fd9fe 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/send/SendEventWorker.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/send/SendEventWorker.kt @@ -20,7 +20,6 @@ import android.content.Context import androidx.work.WorkerParameters import com.squareup.moshi.JsonClass import io.realm.RealmConfiguration -import org.greenrobot.eventbus.EventBus import org.matrix.android.sdk.api.failure.shouldBeRetried import org.matrix.android.sdk.api.session.crypto.CryptoService import org.matrix.android.sdk.api.session.room.send.SendState @@ -54,7 +53,6 @@ internal class SendEventWorker(context: Context, @Inject lateinit var localEchoRepository: LocalEchoRepository @Inject lateinit var sendEventTask: SendEventTask @Inject lateinit var cryptoService: CryptoService - @Inject lateinit var eventBus: EventBus @Inject lateinit var cancelSendTracker: CancelSendTracker @SessionDatabase @Inject lateinit var realmConfiguration: RealmConfiguration diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/state/SendStateTask.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/state/SendStateTask.kt index 642f68c15b..63691d9207 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/state/SendStateTask.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/state/SendStateTask.kt @@ -17,10 +17,10 @@ package org.matrix.android.sdk.internal.session.room.state import org.matrix.android.sdk.api.util.JsonDict +import org.matrix.android.sdk.internal.network.GlobalErrorReceiver import org.matrix.android.sdk.internal.network.executeRequest import org.matrix.android.sdk.internal.session.room.RoomAPI import org.matrix.android.sdk.internal.task.Task -import org.greenrobot.eventbus.EventBus import javax.inject.Inject internal interface SendStateTask : Task { @@ -34,11 +34,11 @@ internal interface SendStateTask : Task { internal class DefaultSendStateTask @Inject constructor( private val roomAPI: RoomAPI, - private val eventBus: EventBus + private val globalErrorReceiver: GlobalErrorReceiver ) : SendStateTask { override suspend fun execute(params: SendStateTask.Params) { - return executeRequest(eventBus) { + return executeRequest(globalErrorReceiver) { apiCall = if (params.stateKey == null) { roomAPI.sendStateEvent( roomId = params.roomId, diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/tags/AddTagToRoomTask.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/tags/AddTagToRoomTask.kt index 013fc86d5c..c3b5c3f78f 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/tags/AddTagToRoomTask.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/tags/AddTagToRoomTask.kt @@ -17,10 +17,10 @@ package org.matrix.android.sdk.internal.session.room.tags import org.matrix.android.sdk.internal.di.UserId +import org.matrix.android.sdk.internal.network.GlobalErrorReceiver import org.matrix.android.sdk.internal.network.executeRequest import org.matrix.android.sdk.internal.session.room.RoomAPI import org.matrix.android.sdk.internal.task.Task -import org.greenrobot.eventbus.EventBus import javax.inject.Inject internal interface AddTagToRoomTask : Task { @@ -35,11 +35,11 @@ internal interface AddTagToRoomTask : Task { internal class DefaultAddTagToRoomTask @Inject constructor( private val roomAPI: RoomAPI, @UserId private val userId: String, - private val eventBus: EventBus + private val globalErrorReceiver: GlobalErrorReceiver ) : AddTagToRoomTask { override suspend fun execute(params: AddTagToRoomTask.Params) { - executeRequest(eventBus) { + executeRequest(globalErrorReceiver) { apiCall = roomAPI.putTag( userId = userId, roomId = params.roomId, diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/tags/DeleteTagFromRoomTask.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/tags/DeleteTagFromRoomTask.kt index b22355d431..d578d21fde 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/tags/DeleteTagFromRoomTask.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/tags/DeleteTagFromRoomTask.kt @@ -17,10 +17,10 @@ package org.matrix.android.sdk.internal.session.room.tags import org.matrix.android.sdk.internal.di.UserId +import org.matrix.android.sdk.internal.network.GlobalErrorReceiver import org.matrix.android.sdk.internal.network.executeRequest import org.matrix.android.sdk.internal.session.room.RoomAPI import org.matrix.android.sdk.internal.task.Task -import org.greenrobot.eventbus.EventBus import javax.inject.Inject internal interface DeleteTagFromRoomTask : Task { @@ -34,11 +34,11 @@ internal interface DeleteTagFromRoomTask : Task(eventBus) { + executeRequest(globalErrorReceiver) { apiCall = roomAPI.deleteTag( userId = userId, roomId = params.roomId, diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/timeline/DefaultTimeline.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/timeline/DefaultTimeline.kt index dd58529412..ae90282d52 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/timeline/DefaultTimeline.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/timeline/DefaultTimeline.kt @@ -23,9 +23,6 @@ import io.realm.RealmConfiguration import io.realm.RealmQuery import io.realm.RealmResults import io.realm.Sort -import org.greenrobot.eventbus.EventBus -import org.greenrobot.eventbus.Subscribe -import org.greenrobot.eventbus.ThreadMode import org.matrix.android.sdk.api.MatrixCallback import org.matrix.android.sdk.api.NoOpMatrixCallback import org.matrix.android.sdk.api.extensions.orFalse @@ -81,15 +78,13 @@ internal class DefaultTimeline( private val timelineEventMapper: TimelineEventMapper, private val settings: TimelineSettings, private val hiddenReadReceipts: TimelineHiddenReadReceipts, - private val eventBus: EventBus, + private val timelineInput: TimelineInput, private val eventDecryptor: TimelineEventDecryptor, private val realmSessionProvider: RealmSessionProvider, private val loadRoomMembersTask: LoadRoomMembersTask -) : Timeline, TimelineHiddenReadReceipts.Delegate { - - data class OnNewTimelineEvents(val roomId: String, val eventIds: List) - data class OnLocalEchoCreated(val roomId: String, val timelineEvent: TimelineEvent) - data class OnLocalEchoUpdated(val roomId: String, val eventId: String, val sendState: SendState) +) : Timeline, + TimelineHiddenReadReceipts.Delegate, + TimelineInput.Listener { companion object { val BACKGROUND_HANDLER = createBackgroundHandler("TIMELINE_DB_THREAD") @@ -161,7 +156,7 @@ internal class DefaultTimeline( override fun start() { if (isStarted.compareAndSet(false, true)) { Timber.v("Start timeline for roomId: $roomId and eventId: $initialEventId") - eventBus.register(this) + timelineInput.listeners.add(this) BACKGROUND_HANDLER.post { eventDecryptor.start() val realm = Realm.getInstance(realmConfiguration) @@ -206,7 +201,7 @@ internal class DefaultTimeline( override fun dispose() { if (isStarted.compareAndSet(true, false)) { isReady.set(false) - eventBus.unregister(this) + timelineInput.listeners.remove(this) Timber.v("Dispose timeline for roomId: $roomId and eventId: $initialEventId") cancelableBag.cancel() BACKGROUND_HANDLER.removeCallbacksAndMessages(null) @@ -323,25 +318,22 @@ internal class DefaultTimeline( postSnapshot() } - @Subscribe(threadMode = ThreadMode.MAIN) - fun onNewTimelineEvents(onNewTimelineEvents: OnNewTimelineEvents) { - if (isLive && onNewTimelineEvents.roomId == roomId) { + override fun onNewTimelineEvents(roomId: String, eventIds: List) { + if (isLive && this.roomId == roomId) { listeners.forEach { - it.onNewTimelineEvents(onNewTimelineEvents.eventIds) + it.onNewTimelineEvents(eventIds) } } } - @Subscribe(threadMode = ThreadMode.MAIN) - fun onLocalEchoCreated(onLocalEchoCreated: OnLocalEchoCreated) { - if (uiEchoManager.onLocalEchoCreated(onLocalEchoCreated)) { + override fun onLocalEchoCreated(roomId: String, timelineEvent: TimelineEvent) { + if (uiEchoManager.onLocalEchoCreated(roomId, timelineEvent)) { postSnapshot() } } - @Subscribe(threadMode = ThreadMode.MAIN) - fun onLocalEchoUpdated(onLocalEchoUpdated: OnLocalEchoUpdated) { - if (uiEchoManager.onLocalEchoUpdated(onLocalEchoUpdated)) { + override fun onLocalEchoUpdated(roomId: String, eventId: String, sendState: SendState) { + if (uiEchoManager.onLocalEchoUpdated(roomId, eventId, sendState)) { postSnapshot() } } @@ -858,11 +850,11 @@ internal class DefaultTimeline( } } - fun onLocalEchoUpdated(onLocalEchoUpdated: OnLocalEchoUpdated): Boolean { - if (isLive && onLocalEchoUpdated.roomId == roomId) { - val existingState = inMemorySendingStates[onLocalEchoUpdated.eventId] - inMemorySendingStates[onLocalEchoUpdated.eventId] = onLocalEchoUpdated.sendState - if (existingState != onLocalEchoUpdated.sendState) { + fun onLocalEchoUpdated(roomId: String, eventId: String, sendState: SendState): Boolean { + if (isLive && roomId == this@DefaultTimeline.roomId) { + val existingState = inMemorySendingStates[eventId] + inMemorySendingStates[eventId] = sendState + if (existingState != sendState) { return true } } @@ -870,22 +862,22 @@ internal class DefaultTimeline( } // return true if should update - fun onLocalEchoCreated(onLocalEchoCreated: OnLocalEchoCreated): Boolean { + fun onLocalEchoCreated(roomId: String, timelineEvent: TimelineEvent): Boolean { var postSnapshot = false - if (isLive && onLocalEchoCreated.roomId == roomId) { + if (isLive && roomId == this@DefaultTimeline.roomId) { // Manage some ui echos (do it before filter because actual event could be filtered out) - when (onLocalEchoCreated.timelineEvent.root.getClearType()) { + when (timelineEvent.root.getClearType()) { EventType.REDACTION -> { } EventType.REACTION -> { - val content = onLocalEchoCreated.timelineEvent.root.content?.toModel() + val content = timelineEvent.root.content?.toModel() if (RelationType.ANNOTATION == content?.relatesTo?.type) { val reaction = content.relatesTo.key val relatedEventID = content.relatesTo.eventId inMemoryReactions.getOrPut(relatedEventID) { mutableListOf() } .add( ReactionUiEchoData( - localEchoId = onLocalEchoCreated.timelineEvent.eventId, + localEchoId = timelineEvent.eventId, reactedOnEventId = relatedEventID, reaction = reaction ) @@ -898,12 +890,12 @@ internal class DefaultTimeline( } // do not add events that would have been filtered - if (listOf(onLocalEchoCreated.timelineEvent).filterEventsWithSettings().isNotEmpty()) { + if (listOf(timelineEvent).filterEventsWithSettings().isNotEmpty()) { listeners.forEach { - it.onNewTimelineEvents(listOf(onLocalEchoCreated.timelineEvent.eventId)) + it.onNewTimelineEvents(listOf(timelineEvent.eventId)) } - Timber.v("On local echo created: ${onLocalEchoCreated.timelineEvent.eventId}") - inMemorySendingEvents.add(0, onLocalEchoCreated.timelineEvent) + Timber.v("On local echo created: ${timelineEvent.eventId}") + inMemorySendingEvents.add(0, timelineEvent) postSnapshot = true } } diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/timeline/DefaultTimelineService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/timeline/DefaultTimelineService.kt index d02e906d00..fce09cc97c 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/timeline/DefaultTimelineService.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/timeline/DefaultTimelineService.kt @@ -23,7 +23,6 @@ import com.squareup.inject.assisted.AssistedInject import com.zhuinden.monarchy.Monarchy import io.realm.Sort import io.realm.kotlin.where -import org.greenrobot.eventbus.EventBus import org.matrix.android.sdk.api.session.events.model.isImageMessage import org.matrix.android.sdk.api.session.events.model.isVideoMessage import org.matrix.android.sdk.api.session.room.timeline.Timeline @@ -45,7 +44,7 @@ import org.matrix.android.sdk.internal.task.TaskExecutor internal class DefaultTimelineService @AssistedInject constructor(@Assisted private val roomId: String, @SessionDatabase private val monarchy: Monarchy, private val realmSessionProvider: RealmSessionProvider, - private val eventBus: EventBus, + private val timelineInput: TimelineInput, private val taskExecutor: TaskExecutor, private val contextOfEventTask: GetContextOfEventTask, private val eventDecryptor: TimelineEventDecryptor, @@ -72,7 +71,7 @@ internal class DefaultTimelineService @AssistedInject constructor(@Assisted priv timelineEventMapper = timelineEventMapper, settings = settings, hiddenReadReceipts = TimelineHiddenReadReceipts(readReceiptsSummaryMapper, roomId, settings), - eventBus = eventBus, + timelineInput = timelineInput, eventDecryptor = eventDecryptor, fetchTokenAndPaginateTask = fetchTokenAndPaginateTask, realmSessionProvider = realmSessionProvider, diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/timeline/FetchTokenAndPaginateTask.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/timeline/FetchTokenAndPaginateTask.kt index d1bfa1adcb..76c4b3812c 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/timeline/FetchTokenAndPaginateTask.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/timeline/FetchTokenAndPaginateTask.kt @@ -20,12 +20,12 @@ import com.zhuinden.monarchy.Monarchy import org.matrix.android.sdk.internal.database.model.ChunkEntity import org.matrix.android.sdk.internal.database.query.findIncludingEvent import org.matrix.android.sdk.internal.di.SessionDatabase +import org.matrix.android.sdk.internal.network.GlobalErrorReceiver import org.matrix.android.sdk.internal.network.executeRequest import org.matrix.android.sdk.internal.session.filter.FilterRepository import org.matrix.android.sdk.internal.session.room.RoomAPI import org.matrix.android.sdk.internal.task.Task import org.matrix.android.sdk.internal.util.awaitTransaction -import org.greenrobot.eventbus.EventBus import javax.inject.Inject internal interface FetchTokenAndPaginateTask : Task { @@ -43,12 +43,12 @@ internal class DefaultFetchTokenAndPaginateTask @Inject constructor( @SessionDatabase private val monarchy: Monarchy, private val filterRepository: FilterRepository, private val paginationTask: PaginationTask, - private val eventBus: EventBus + private val globalErrorReceiver: GlobalErrorReceiver ) : FetchTokenAndPaginateTask { override suspend fun execute(params: FetchTokenAndPaginateTask.Params): TokenChunkEventPersistor.Result { val filter = filterRepository.getRoomFilter() - val response = executeRequest(eventBus) { + val response = executeRequest(globalErrorReceiver) { apiCall = roomAPI.getContextOfEvent(params.roomId, params.lastKnownEventId, 0, filter) } val fromToken = if (params.direction == PaginationDirection.FORWARDS) { diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/timeline/GetContextOfEventTask.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/timeline/GetContextOfEventTask.kt index 7a611dd350..d02a7bafe9 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/timeline/GetContextOfEventTask.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/timeline/GetContextOfEventTask.kt @@ -16,11 +16,11 @@ package org.matrix.android.sdk.internal.session.room.timeline +import org.matrix.android.sdk.internal.network.GlobalErrorReceiver import org.matrix.android.sdk.internal.network.executeRequest import org.matrix.android.sdk.internal.session.filter.FilterRepository import org.matrix.android.sdk.internal.session.room.RoomAPI import org.matrix.android.sdk.internal.task.Task -import org.greenrobot.eventbus.EventBus import javax.inject.Inject internal interface GetContextOfEventTask : Task { @@ -35,12 +35,12 @@ internal class DefaultGetContextOfEventTask @Inject constructor( private val roomAPI: RoomAPI, private val filterRepository: FilterRepository, private val tokenChunkEventPersistor: TokenChunkEventPersistor, - private val eventBus: EventBus + private val globalErrorReceiver: GlobalErrorReceiver ) : GetContextOfEventTask { override suspend fun execute(params: GetContextOfEventTask.Params): TokenChunkEventPersistor.Result { val filter = filterRepository.getRoomFilter() - val response = executeRequest(eventBus) { + val response = executeRequest(globalErrorReceiver) { // We are limiting the response to the event with eventId to be sure we don't have any issue with potential merging process. apiCall = roomAPI.getContextOfEvent(params.roomId, params.eventId, 0, filter) } diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/timeline/GetEventTask.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/timeline/GetEventTask.kt index acac3929ae..b8585b1e74 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/timeline/GetEventTask.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/timeline/GetEventTask.kt @@ -17,17 +17,17 @@ package org.matrix.android.sdk.internal.session.room.timeline import org.matrix.android.sdk.api.session.events.model.Event +import org.matrix.android.sdk.internal.network.GlobalErrorReceiver import org.matrix.android.sdk.internal.network.executeRequest import org.matrix.android.sdk.internal.session.room.RoomAPI import org.matrix.android.sdk.internal.task.Task -import org.greenrobot.eventbus.EventBus import javax.inject.Inject // TODO Add parent task internal class GetEventTask @Inject constructor( private val roomAPI: RoomAPI, - private val eventBus: EventBus + private val globalErrorReceiver: GlobalErrorReceiver ) : Task { internal data class Params( @@ -36,7 +36,7 @@ internal class GetEventTask @Inject constructor( ) override suspend fun execute(params: Params): Event { - return executeRequest(eventBus) { + return executeRequest(globalErrorReceiver) { apiCall = roomAPI.getEvent(params.roomId, params.eventId) } } diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/timeline/PaginationTask.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/timeline/PaginationTask.kt index b663d03bd7..1f99893e17 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/timeline/PaginationTask.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/timeline/PaginationTask.kt @@ -16,11 +16,11 @@ package org.matrix.android.sdk.internal.session.room.timeline +import org.matrix.android.sdk.internal.network.GlobalErrorReceiver import org.matrix.android.sdk.internal.network.executeRequest import org.matrix.android.sdk.internal.session.filter.FilterRepository import org.matrix.android.sdk.internal.session.room.RoomAPI import org.matrix.android.sdk.internal.task.Task -import org.greenrobot.eventbus.EventBus import javax.inject.Inject internal interface PaginationTask : Task { @@ -37,12 +37,12 @@ internal class DefaultPaginationTask @Inject constructor( private val roomAPI: RoomAPI, private val filterRepository: FilterRepository, private val tokenChunkEventPersistor: TokenChunkEventPersistor, - private val eventBus: EventBus + private val globalErrorReceiver: GlobalErrorReceiver ) : PaginationTask { override suspend fun execute(params: PaginationTask.Params): TokenChunkEventPersistor.Result { val filter = filterRepository.getRoomFilter() - val chunk = executeRequest(eventBus) { + val chunk = executeRequest(globalErrorReceiver) { isRetryable = true apiCall = roomAPI.getRoomMessagesFrom(params.roomId, params.from, params.direction.value, params.limit, filter) } diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/timeline/TimelineInput.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/timeline/TimelineInput.kt new file mode 100644 index 0000000000..002ab1dd8a --- /dev/null +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/timeline/TimelineInput.kt @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2021 The Matrix.org Foundation C.I.C. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.matrix.android.sdk.internal.session.room.timeline + +import org.matrix.android.sdk.api.session.room.send.SendState +import org.matrix.android.sdk.api.session.room.timeline.TimelineEvent +import org.matrix.android.sdk.internal.session.SessionScope +import javax.inject.Inject + +@SessionScope +internal class TimelineInput @Inject constructor() { + fun onLocalEchoCreated(roomId: String, timelineEvent: TimelineEvent) { + listeners.toSet().forEach { it.onLocalEchoCreated(roomId, timelineEvent) } + } + + fun onLocalEchoUpdated(roomId: String, eventId: String, sendState: SendState) { + listeners.toSet().forEach { it.onLocalEchoUpdated(roomId, eventId, sendState) } + } + + fun onNewTimelineEvents(roomId: String, eventIds: List) { + listeners.toSet().forEach { it.onNewTimelineEvents(roomId, eventIds) } + } + + val listeners = mutableSetOf() + + internal interface Listener { + fun onLocalEchoCreated(roomId: String, timelineEvent: TimelineEvent) + fun onLocalEchoUpdated(roomId: String, eventId: String, sendState: SendState) + fun onNewTimelineEvents(roomId: String, eventIds: List) + } +} diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/typing/SendTypingTask.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/typing/SendTypingTask.kt index c8cbb08e2c..3b56d04872 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/typing/SendTypingTask.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/typing/SendTypingTask.kt @@ -21,7 +21,7 @@ import org.matrix.android.sdk.internal.network.executeRequest import org.matrix.android.sdk.internal.session.room.RoomAPI import org.matrix.android.sdk.internal.task.Task import kotlinx.coroutines.delay -import org.greenrobot.eventbus.EventBus +import org.matrix.android.sdk.internal.network.GlobalErrorReceiver import javax.inject.Inject internal interface SendTypingTask : Task { @@ -38,13 +38,13 @@ internal interface SendTypingTask : Task { internal class DefaultSendTypingTask @Inject constructor( private val roomAPI: RoomAPI, @UserId private val userId: String, - private val eventBus: EventBus + private val globalErrorReceiver: GlobalErrorReceiver ) : SendTypingTask { override suspend fun execute(params: SendTypingTask.Params) { delay(params.delay ?: -1) - executeRequest(eventBus) { + executeRequest(globalErrorReceiver) { apiCall = roomAPI.sendTypingState( params.roomId, userId, diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/uploads/GetUploadsTask.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/uploads/GetUploadsTask.kt index d0439ce7f9..0c0e6a8ed0 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/uploads/GetUploadsTask.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/uploads/GetUploadsTask.kt @@ -31,6 +31,7 @@ import org.matrix.android.sdk.internal.database.model.EventEntityFields import org.matrix.android.sdk.internal.database.query.TimelineEventFilter import org.matrix.android.sdk.internal.database.query.whereType import org.matrix.android.sdk.internal.di.SessionDatabase +import org.matrix.android.sdk.internal.network.GlobalErrorReceiver import org.matrix.android.sdk.internal.network.executeRequest import org.matrix.android.sdk.internal.session.filter.FilterFactory import org.matrix.android.sdk.internal.session.room.RoomAPI @@ -39,7 +40,6 @@ import org.matrix.android.sdk.internal.session.room.timeline.PaginationDirection import org.matrix.android.sdk.internal.session.room.timeline.PaginationResponse import org.matrix.android.sdk.internal.session.sync.SyncTokenStore import org.matrix.android.sdk.internal.task.Task -import org.greenrobot.eventbus.EventBus import javax.inject.Inject internal interface GetUploadsTask : Task { @@ -56,7 +56,7 @@ internal class DefaultGetUploadsTask @Inject constructor( private val roomAPI: RoomAPI, private val tokenStore: SyncTokenStore, @SessionDatabase private val monarchy: Monarchy, - private val eventBus: EventBus) + private val globalErrorReceiver: GlobalErrorReceiver) : GetUploadsTask { override suspend fun execute(params: GetUploadsTask.Params): GetUploadsResult { @@ -86,7 +86,7 @@ internal class DefaultGetUploadsTask @Inject constructor( val since = params.since ?: tokenStore.getLastToken() ?: throw IllegalStateException("No token available") val filter = FilterFactory.createUploadsFilter(params.numberOfEvents).toJSONString() - val chunk = executeRequest(eventBus) { + val chunk = executeRequest(globalErrorReceiver) { apiCall = roomAPI.getRoomMessagesFrom(params.roomId, since, PaginationDirection.BACKWARDS.value, params.numberOfEvents, filter) } diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/search/SearchTask.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/search/SearchTask.kt index 4f574e5ead..402602e4d5 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/search/SearchTask.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/search/SearchTask.kt @@ -16,10 +16,10 @@ package org.matrix.android.sdk.internal.session.search -import org.greenrobot.eventbus.EventBus import org.matrix.android.sdk.api.session.search.EventAndSender import org.matrix.android.sdk.api.session.search.SearchResult import org.matrix.android.sdk.api.util.MatrixItem +import org.matrix.android.sdk.internal.network.GlobalErrorReceiver import org.matrix.android.sdk.internal.network.executeRequest import org.matrix.android.sdk.internal.session.search.request.SearchRequestBody import org.matrix.android.sdk.internal.session.search.request.SearchRequestCategories @@ -47,11 +47,11 @@ internal interface SearchTask : Task { internal class DefaultSearchTask @Inject constructor( private val searchAPI: SearchAPI, - private val eventBus: EventBus + private val globalErrorReceiver: GlobalErrorReceiver ) : SearchTask { override suspend fun execute(params: SearchTask.Params): SearchResult { - return executeRequest(eventBus) { + return executeRequest(globalErrorReceiver) { val searchRequestBody = SearchRequestBody( searchCategories = SearchRequestCategories( roomEvents = SearchRequestRoomEvents( diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/signout/SignInAgainTask.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/signout/SignInAgainTask.kt index 3bed0bdbff..2c3cd5d270 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/signout/SignInAgainTask.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/signout/SignInAgainTask.kt @@ -20,9 +20,9 @@ import org.matrix.android.sdk.api.auth.data.Credentials import org.matrix.android.sdk.api.auth.data.SessionParams import org.matrix.android.sdk.internal.auth.SessionParamsStore import org.matrix.android.sdk.internal.auth.data.PasswordLoginParams +import org.matrix.android.sdk.internal.network.GlobalErrorReceiver import org.matrix.android.sdk.internal.network.executeRequest import org.matrix.android.sdk.internal.task.Task -import org.greenrobot.eventbus.EventBus import javax.inject.Inject internal interface SignInAgainTask : Task { @@ -35,11 +35,11 @@ internal class DefaultSignInAgainTask @Inject constructor( private val signOutAPI: SignOutAPI, private val sessionParams: SessionParams, private val sessionParamsStore: SessionParamsStore, - private val eventBus: EventBus + private val globalErrorReceiver: GlobalErrorReceiver ) : SignInAgainTask { override suspend fun execute(params: SignInAgainTask.Params) { - val newCredentials = executeRequest(eventBus) { + val newCredentials = executeRequest(globalErrorReceiver) { apiCall = signOutAPI.loginAgain( PasswordLoginParams.userIdentifier( // Reuse the same userId diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/signout/SignOutTask.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/signout/SignOutTask.kt index 153ea5a6fd..0cb8704782 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/signout/SignOutTask.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/signout/SignOutTask.kt @@ -18,11 +18,11 @@ package org.matrix.android.sdk.internal.session.signout import org.matrix.android.sdk.api.failure.Failure import org.matrix.android.sdk.api.failure.MatrixError +import org.matrix.android.sdk.internal.network.GlobalErrorReceiver import org.matrix.android.sdk.internal.network.executeRequest import org.matrix.android.sdk.internal.session.cleanup.CleanupSession import org.matrix.android.sdk.internal.session.identity.IdentityDisconnectTask import org.matrix.android.sdk.internal.task.Task -import org.greenrobot.eventbus.EventBus import timber.log.Timber import java.net.HttpURLConnection import javax.inject.Inject @@ -35,7 +35,7 @@ internal interface SignOutTask : Task { internal class DefaultSignOutTask @Inject constructor( private val signOutAPI: SignOutAPI, - private val eventBus: EventBus, + private val globalErrorReceiver: GlobalErrorReceiver, private val identityDisconnectTask: IdentityDisconnectTask, private val cleanupSession: CleanupSession ) : SignOutTask { @@ -45,7 +45,7 @@ internal class DefaultSignOutTask @Inject constructor( if (params.signOutFromHomeserver) { Timber.d("SignOut: send request...") try { - executeRequest(eventBus) { + executeRequest(globalErrorReceiver) { apiCall = signOutAPI.signOut() } } catch (throwable: Throwable) { diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/RoomSyncHandler.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/RoomSyncHandler.kt index b1b2f65dc2..456b0f9c26 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/RoomSyncHandler.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/RoomSyncHandler.kt @@ -18,7 +18,6 @@ package org.matrix.android.sdk.internal.session.sync import io.realm.Realm import io.realm.kotlin.createObject -import org.greenrobot.eventbus.EventBus import org.matrix.android.sdk.R import org.matrix.android.sdk.api.session.crypto.MXCryptoError import org.matrix.android.sdk.api.session.events.model.Event @@ -55,8 +54,8 @@ import org.matrix.android.sdk.internal.session.room.membership.RoomChangeMembers import org.matrix.android.sdk.internal.session.room.membership.RoomMemberEventHandler import org.matrix.android.sdk.internal.session.room.read.FullyReadContent import org.matrix.android.sdk.internal.session.room.summary.RoomSummaryUpdater -import org.matrix.android.sdk.internal.session.room.timeline.DefaultTimeline import org.matrix.android.sdk.internal.session.room.timeline.PaginationDirection +import org.matrix.android.sdk.internal.session.room.timeline.TimelineInput import org.matrix.android.sdk.internal.session.room.typing.TypingEventContent import org.matrix.android.sdk.internal.session.sync.model.InvitedRoomSync import org.matrix.android.sdk.internal.session.sync.model.RoomSync @@ -75,7 +74,7 @@ internal class RoomSyncHandler @Inject constructor(private val readReceiptHandle private val roomTypingUsersHandler: RoomTypingUsersHandler, private val roomChangeMembershipStateDataSource: RoomChangeMembershipStateDataSource, @UserId private val userId: String, - private val eventBus: EventBus) { + private val timelineInput: TimelineInput) { sealed class HandlingStrategy { data class JOINED(val data: Map) : HandlingStrategy() @@ -348,7 +347,7 @@ internal class RoomSyncHandler @Inject constructor(private val readReceiptHandle } } // posting new events to timeline if any is registered - eventBus.post(DefaultTimeline.OnNewTimelineEvents(roomId = roomId, eventIds = eventIds)) + timelineInput.onNewTimelineEvents(roomId = roomId, eventIds = eventIds) return chunkEntity } diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/SyncTask.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/SyncTask.kt index b4fd6e7386..7c38230065 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/SyncTask.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/SyncTask.kt @@ -16,9 +16,9 @@ package org.matrix.android.sdk.internal.session.sync -import org.greenrobot.eventbus.EventBus import org.matrix.android.sdk.R import org.matrix.android.sdk.internal.di.UserId +import org.matrix.android.sdk.internal.network.GlobalErrorReceiver import org.matrix.android.sdk.internal.network.TimeOutInterceptor import org.matrix.android.sdk.internal.network.executeRequest import org.matrix.android.sdk.internal.session.DefaultInitialSyncProgressService @@ -48,7 +48,7 @@ internal class DefaultSyncTask @Inject constructor( private val getHomeServerCapabilitiesTask: GetHomeServerCapabilitiesTask, private val userStore: UserStore, private val syncTaskSequencer: SyncTaskSequencer, - private val eventBus: EventBus + private val globalErrorReceiver: GlobalErrorReceiver ) : SyncTask { override suspend fun execute(params: SyncTask.Params) = syncTaskSequencer.post { @@ -81,7 +81,7 @@ internal class DefaultSyncTask @Inject constructor( val readTimeOut = (params.timeout + TIMEOUT_MARGIN).coerceAtLeast(TimeOutInterceptor.DEFAULT_LONG_TIMEOUT) - val syncResponse = executeRequest(eventBus) { + val syncResponse = executeRequest(globalErrorReceiver) { apiCall = syncAPI.sync( params = requestParams, readTimeOut = readTimeOut diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/user/accountdata/UpdateIgnoredUserIdsTask.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/user/accountdata/UpdateIgnoredUserIdsTask.kt index d1393c8b37..26e8d3380a 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/user/accountdata/UpdateIgnoredUserIdsTask.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/user/accountdata/UpdateIgnoredUserIdsTask.kt @@ -17,11 +17,11 @@ package org.matrix.android.sdk.internal.session.user.accountdata import com.zhuinden.monarchy.Monarchy -import org.greenrobot.eventbus.EventBus import org.matrix.android.sdk.api.session.accountdata.UserAccountDataTypes import org.matrix.android.sdk.internal.database.model.IgnoredUserEntity import org.matrix.android.sdk.internal.di.SessionDatabase import org.matrix.android.sdk.internal.di.UserId +import org.matrix.android.sdk.internal.network.GlobalErrorReceiver import org.matrix.android.sdk.internal.network.executeRequest import org.matrix.android.sdk.internal.session.sync.model.accountdata.IgnoredUsersContent import org.matrix.android.sdk.internal.task.Task @@ -40,7 +40,7 @@ internal class DefaultUpdateIgnoredUserIdsTask @Inject constructor( @SessionDatabase private val monarchy: Monarchy, private val saveIgnoredUsersTask: SaveIgnoredUsersTask, @UserId private val userId: String, - private val eventBus: EventBus + private val globalErrorReceiver: GlobalErrorReceiver ) : UpdateIgnoredUserIdsTask { override suspend fun execute(params: UpdateIgnoredUserIdsTask.Params) { @@ -63,7 +63,7 @@ internal class DefaultUpdateIgnoredUserIdsTask @Inject constructor( val list = ignoredUserIds.toList() val body = IgnoredUsersContent.createWithUserIds(list) - executeRequest(eventBus) { + executeRequest(globalErrorReceiver) { apiCall = accountDataApi.setAccountData(userId, UserAccountDataTypes.TYPE_IGNORED_USER_LIST, body) } diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/user/accountdata/UpdateUserAccountDataTask.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/user/accountdata/UpdateUserAccountDataTask.kt index 80ab79b228..dba28253a7 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/user/accountdata/UpdateUserAccountDataTask.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/user/accountdata/UpdateUserAccountDataTask.kt @@ -24,8 +24,8 @@ import org.matrix.android.sdk.internal.session.sync.model.accountdata.AcceptedTe import org.matrix.android.sdk.internal.session.sync.model.accountdata.BreadcrumbsContent import org.matrix.android.sdk.internal.session.sync.model.accountdata.IdentityServerContent import org.matrix.android.sdk.api.session.accountdata.UserAccountDataTypes +import org.matrix.android.sdk.internal.network.GlobalErrorReceiver import org.matrix.android.sdk.internal.task.Task -import org.greenrobot.eventbus.EventBus import javax.inject.Inject internal interface UpdateUserAccountDataTask : Task { @@ -100,11 +100,11 @@ internal interface UpdateUserAccountDataTask : Task> { @@ -34,11 +34,11 @@ internal interface SearchUserTask : Task> { internal class DefaultSearchUserTask @Inject constructor( private val searchUserAPI: SearchUserAPI, - private val eventBus: EventBus + private val globalErrorReceiver: GlobalErrorReceiver ) : SearchUserTask { override suspend fun execute(params: SearchUserTask.Params): List { - val response = executeRequest(eventBus) { + val response = executeRequest(globalErrorReceiver) { apiCall = searchUserAPI.searchUsers(SearchUsersParams(params.search, params.limit)) } return response.users.map { diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/widgets/CreateWidgetTask.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/widgets/CreateWidgetTask.kt index 422615af2d..ae807ce30f 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/widgets/CreateWidgetTask.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/widgets/CreateWidgetTask.kt @@ -25,10 +25,10 @@ import org.matrix.android.sdk.internal.database.model.CurrentStateEventEntityFie import org.matrix.android.sdk.internal.database.query.whereStateKey import org.matrix.android.sdk.internal.di.SessionDatabase import org.matrix.android.sdk.internal.di.UserId +import org.matrix.android.sdk.internal.network.GlobalErrorReceiver import org.matrix.android.sdk.internal.network.executeRequest import org.matrix.android.sdk.internal.session.room.RoomAPI import org.matrix.android.sdk.internal.task.Task -import org.greenrobot.eventbus.EventBus import javax.inject.Inject internal interface CreateWidgetTask : Task { @@ -43,10 +43,10 @@ internal interface CreateWidgetTask : Task { internal class DefaultCreateWidgetTask @Inject constructor(@SessionDatabase private val monarchy: Monarchy, private val roomAPI: RoomAPI, @UserId private val userId: String, - private val eventBus: EventBus) : CreateWidgetTask { + private val globalErrorReceiver: GlobalErrorReceiver) : CreateWidgetTask { override suspend fun execute(params: CreateWidgetTask.Params) { - executeRequest(eventBus) { + executeRequest(globalErrorReceiver) { apiCall = roomAPI.sendStateEvent( roomId = params.roomId, stateEventType = EventType.STATE_ROOM_WIDGET_LEGACY, diff --git a/vector/src/main/assets/open_source_licenses.html b/vector/src/main/assets/open_source_licenses.html index 17d79e3655..4ce4e9a210 100755 --- a/vector/src/main/assets/open_source_licenses.html +++ b/vector/src/main/assets/open_source_licenses.html @@ -332,11 +332,6 @@ SOFTWARE.
Copyright 2018 The diff-match-patch Authors. https://github.com/google/diff-match-patch -
  • - EventBus -
    - Copyright (C) 2012-2017 Markus Junginger, greenrobot (http://greenrobot.org) -
  • LazyThreeTenBp
    From 6e8d93bc6fd699290883de657232e04950c0b2b4 Mon Sep 17 00:00:00 2001 From: Yves Quemener Date: Wed, 6 Jan 2021 11:22:25 +0900 Subject: [PATCH 39/41] Fix in the test homeserver set-up instruction I think I removed a typo. You probably don't want a new virtualenv every time you start a homeserver? --- docs/ui-tests.md | 1 - 1 file changed, 1 deletion(-) diff --git a/docs/ui-tests.md b/docs/ui-tests.md index ff01da0b31..6ebb52abe8 100644 --- a/docs/ui-tests.md +++ b/docs/ui-tests.md @@ -27,7 +27,6 @@ $ source env/bin/activate Every time you want to launch these test homeservers, type: ```shell script -$ virtualenv -p python3 env $ source env/bin/activate (env) $ demo/start.sh --no-rate-limit ``` From 2a365d677653906e6269e8f1d7808a0d32785802 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Thu, 7 Jan 2021 18:28:05 +0100 Subject: [PATCH 40/41] Move interface to correct location --- .../matrix/android/sdk/internal/network/GlobalErrorReceiver.kt | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename matrix-sdk-android/src/{debug => main}/java/org/matrix/android/sdk/internal/network/GlobalErrorReceiver.kt (100%) diff --git a/matrix-sdk-android/src/debug/java/org/matrix/android/sdk/internal/network/GlobalErrorReceiver.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/network/GlobalErrorReceiver.kt similarity index 100% rename from matrix-sdk-android/src/debug/java/org/matrix/android/sdk/internal/network/GlobalErrorReceiver.kt rename to matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/network/GlobalErrorReceiver.kt From d91ed2985d2a0b7c5b03ef0834d4c6ad0cf9c4be Mon Sep 17 00:00:00 2001 From: ganfra Date: Fri, 8 Jan 2021 12:40:20 +0100 Subject: [PATCH 41/41] Sync: fix initial sync is not retried correctly when there is some network error. [#2632] --- CHANGES.md | 2 +- .../internal/session/sync/job/SyncService.kt | 24 ++++--- .../app/core/services/VectorSyncService.kt | 71 ++++++++----------- 3 files changed, 44 insertions(+), 53 deletions(-) diff --git a/CHANGES.md b/CHANGES.md index bff1a7480e..8a69aea6fd 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -15,7 +15,7 @@ Bugfix 🐛: - Room Topic not displayed correctly after visiting a link (#2551) - Hiding membership events works the exact opposite (#2603) - Tapping drawer having more than 1 room in notifications gives "malformed link" error (#2605) - + - Initial sync is not retried correctly when there is some network error. (#2632) Translations 🗣: - diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/job/SyncService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/job/SyncService.kt index 6d100a71f9..9d854229df 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/job/SyncService.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/job/SyncService.kt @@ -36,6 +36,7 @@ import org.matrix.android.sdk.internal.task.TaskExecutor import org.matrix.android.sdk.internal.util.BackgroundDetectionObserver import org.matrix.android.sdk.internal.util.MatrixCoroutineDispatchers import timber.log.Timber +import java.net.SocketTimeoutException import java.util.concurrent.atomic.AtomicBoolean /** @@ -68,14 +69,12 @@ abstract class SyncService : Service() { override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int { Timber.i("## Sync: onStartCommand [$this] $intent with action: ${intent?.action}") - - // We should start we have to ensure we fulfill contract to show notification - // for foreground service (as per design for this service) - // TODO can we check if it's really in foreground - onStart(isInitialSync) when (intent?.action) { ACTION_STOP -> { Timber.i("## Sync: stop command received") + // We should start we have to ensure we fulfill contract to show notification + // for foreground service (as per design for this service) + onStart(isInitialSync) // If it was periodic we ensure that it will not reschedule itself preventReschedule = true // we don't want to cancel initial syncs, let it finish @@ -85,11 +84,12 @@ abstract class SyncService : Service() { } else -> { val isInit = initialize(intent) + onStart(isInitialSync) if (isInit) { periodic = intent?.getBooleanExtra(EXTRA_PERIODIC, false) ?: false val onNetworkBack = intent?.getBooleanExtra(EXTRA_NETWORK_BACK_RESTART, false) ?: false Timber.d("## Sync: command received, periodic: $periodic networkBack: $onNetworkBack") - if (onNetworkBack && !backgroundDetectionObserver.isInBackground) { + if (!isInitialSync && onNetworkBack && !backgroundDetectionObserver.isInBackground) { // the restart after network occurs while the app is in foreground // so just stop. It will be restarted when entering background preventReschedule = true @@ -165,10 +165,16 @@ abstract class SyncService : Service() { preventReschedule = true } if (throwable is Failure.NetworkConnection) { - // Network is off, no need to reschedule endless alarms :/ + // Timeout is not critical, so retry as soon as possible. + val retryDelay = if (isInitialSync || throwable.cause is SocketTimeoutException) { + 0 + } else { + syncDelaySeconds + } + // Network might be off, no need to reschedule endless alarms :/ preventReschedule = true - // Instead start a work to restart background sync when network is back - onNetworkError(sessionId ?: "", isInitialSync, syncTimeoutSeconds, syncDelaySeconds) + // Instead start a work to restart background sync when network is on + onNetworkError(sessionId ?: "", isInitialSync, syncTimeoutSeconds, retryDelay) } // JobCancellation could be caught here when onDestroy cancels the coroutine context if (isRunning.get()) stopMe() diff --git a/vector/src/main/java/im/vector/app/core/services/VectorSyncService.kt b/vector/src/main/java/im/vector/app/core/services/VectorSyncService.kt index bf78d5b7fb..0950bdf121 100644 --- a/vector/src/main/java/im/vector/app/core/services/VectorSyncService.kt +++ b/vector/src/main/java/im/vector/app/core/services/VectorSyncService.kt @@ -21,7 +21,6 @@ import android.app.PendingIntent import android.content.Context import android.content.Intent import android.os.Build -import androidx.core.content.ContextCompat.getSystemService import androidx.core.content.getSystemService import androidx.work.Constraints import androidx.work.Data @@ -49,22 +48,19 @@ class VectorSyncService : SyncService() { } } - fun newPeriodicIntent(context: Context, sessionId: String, timeoutSeconds: Int, delayInSeconds: Int): Intent { + fun newPeriodicIntent( + context: Context, + sessionId: String, + timeoutSeconds: Int, + delayInSeconds: Int, + networkBack: Boolean = false + ): Intent { return Intent(context, VectorSyncService::class.java).also { it.putExtra(EXTRA_SESSION_ID, sessionId) it.putExtra(EXTRA_TIMEOUT_SECONDS, timeoutSeconds) it.putExtra(EXTRA_PERIODIC, true) it.putExtra(EXTRA_DELAY_SECONDS, delayInSeconds) - } - } - - fun newPeriodicNetworkBackIntent(context: Context, sessionId: String, timeoutSeconds: Int, delayInSeconds: Int): Intent { - return Intent(context, VectorSyncService::class.java).also { - it.putExtra(EXTRA_SESSION_ID, sessionId) - it.putExtra(EXTRA_TIMEOUT_SECONDS, timeoutSeconds) - it.putExtra(EXTRA_PERIODIC, true) - it.putExtra(EXTRA_DELAY_SECONDS, delayInSeconds) - it.putExtra(EXTRA_NETWORK_BACK_RESTART, true) + it.putExtra(EXTRA_NETWORK_BACK_RESTART, networkBack) } } @@ -93,12 +89,12 @@ class VectorSyncService : SyncService() { } override fun onRescheduleAsked(sessionId: String, isInitialSync: Boolean, timeout: Int, delay: Int) { - reschedule(sessionId, timeout, delay) + rescheduleSyncService(sessionId, timeout, delay) } override fun onNetworkError(sessionId: String, isInitialSync: Boolean, timeout: Int, delay: Int) { Timber.d("## Sync: A network error occured during sync") - val uploadWorkRequest: WorkRequest = + val rescheduleSyncWorkRequest: WorkRequest = OneTimeWorkRequestBuilder() .setInputData(Data.Builder() .putString("sessionId", sessionId) @@ -115,7 +111,7 @@ class VectorSyncService : SyncService() { Timber.d("## Sync: Schedule a work to restart service when network will be on") WorkManager .getInstance(applicationContext) - .enqueue(uploadWorkRequest) + .enqueue(rescheduleSyncWorkRequest) } override fun onDestroy() { @@ -128,42 +124,31 @@ class VectorSyncService : SyncService() { notificationManager.cancel(NotificationUtils.NOTIFICATION_ID_FOREGROUND_SERVICE) } - private fun reschedule(sessionId: String, timeout: Int, delay: Int) { - val pendingIntent = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { - PendingIntent.getForegroundService(this, 0, newPeriodicIntent(this, sessionId, timeout, delay), 0) - } else { - PendingIntent.getService(this, 0, newPeriodicIntent(this, sessionId, timeout, delay), 0) - } - val firstMillis = System.currentTimeMillis() + delay * 1000L - val alarmMgr = getSystemService()!! - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { - alarmMgr.setAndAllowWhileIdle(AlarmManager.RTC_WAKEUP, firstMillis, pendingIntent) - } else { - alarmMgr.set(AlarmManager.RTC_WAKEUP, firstMillis, pendingIntent) - } - } - class RestartWhenNetworkOn(appContext: Context, workerParams: WorkerParameters) : Worker(appContext, workerParams) { override fun doWork(): Result { val sessionId = inputData.getString("sessionId") ?: return Result.failure() val timeout = inputData.getInt("timeout", 6) val delay = inputData.getInt("delay", 60) - - val pendingIntent = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { - PendingIntent.getForegroundService(applicationContext, 0, newPeriodicNetworkBackIntent(applicationContext, sessionId, timeout, delay), 0) - } else { - PendingIntent.getService(applicationContext, 0, newPeriodicNetworkBackIntent(applicationContext, sessionId, timeout, delay), 0) - } - val firstMillis = System.currentTimeMillis() + delay * 1000L - val alarmMgr = getSystemService(applicationContext, AlarmManager::class.java)!! - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { - alarmMgr.setAndAllowWhileIdle(AlarmManager.RTC_WAKEUP, firstMillis, pendingIntent) - } else { - alarmMgr.set(AlarmManager.RTC_WAKEUP, firstMillis, pendingIntent) - } + applicationContext.rescheduleSyncService(sessionId, timeout, delay, true) // Indicate whether the work finished successfully with the Result return Result.success() } } } + +private fun Context.rescheduleSyncService(sessionId: String, timeout: Int, delay: Int, networkBack: Boolean = false) { + val periodicIntent = VectorSyncService.newPeriodicIntent(this, sessionId, timeout, delay, networkBack) + val pendingIntent = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { + PendingIntent.getForegroundService(this, 0, periodicIntent, 0) + } else { + PendingIntent.getService(this, 0, periodicIntent, 0) + } + val firstMillis = System.currentTimeMillis() + delay * 1000L + val alarmMgr = getSystemService()!! + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { + alarmMgr.setAndAllowWhileIdle(AlarmManager.RTC_WAKEUP, firstMillis, pendingIntent) + } else { + alarmMgr.set(AlarmManager.RTC_WAKEUP, firstMillis, pendingIntent) + } +}