Merge branch 'develop' into feature/bma/mediaForward
# Conflicts: # appnav/src/main/kotlin/io/element/android/appnav/room/joined/JoinedRoomLoadedFlowNode.kt
This commit is contained in:
commit
cc050a1f26
43 changed files with 399 additions and 190 deletions
|
|
@ -32,6 +32,11 @@ sealed interface AsyncAction<out T> {
|
|||
|
||||
data object ConfirmingNoParams : Confirming
|
||||
|
||||
/**
|
||||
* User cancels the action, use this object to ask for confirmation.
|
||||
*/
|
||||
data object ConfirmingCancellation : Confirming
|
||||
|
||||
/**
|
||||
* Represents an operation that is currently ongoing.
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -17,4 +17,6 @@ sealed class QrLoginException : Exception() {
|
|||
data object SlidingSyncNotAvailable : QrLoginException()
|
||||
data object OtherDeviceNotSignedIn : QrLoginException()
|
||||
data object Unknown : QrLoginException()
|
||||
data object CheckCodeAlreadySent : QrLoginException()
|
||||
data object CheckCodeCannotBeSent : QrLoginException()
|
||||
}
|
||||
|
|
|
|||
|
|
@ -289,10 +289,13 @@ class RustMatrixAuthenticationService(
|
|||
qrCodeData = sdkQrCodeLoginData,
|
||||
)
|
||||
client.loginWithQrCode(
|
||||
qrCodeData = qrCodeData.rustQrCodeData,
|
||||
oidcConfiguration = oidcConfiguration,
|
||||
progressListener = progressListener,
|
||||
)
|
||||
).use {
|
||||
it.scan(
|
||||
qrCodeData = qrCodeData.rustQrCodeData,
|
||||
progressListener = progressListener,
|
||||
)
|
||||
}
|
||||
// Ensure that the user is not already logged in with the same account
|
||||
ensureNotAlreadyLoggedIn(client)
|
||||
val sessionData = client.session()
|
||||
|
|
|
|||
|
|
@ -42,5 +42,7 @@ object QrErrorMapper {
|
|||
is RustHumanQrLoginException.Unknown -> QrLoginException.Unknown
|
||||
is RustHumanQrLoginException.OidcMetadataInvalid -> QrLoginException.OidcMetadataInvalid
|
||||
is RustHumanQrLoginException.SlidingSyncNotAvailable -> QrLoginException.SlidingSyncNotAvailable
|
||||
is RustHumanQrLoginException.CheckCodeAlreadySent -> QrLoginException.CheckCodeAlreadySent
|
||||
is RustHumanQrLoginException.CheckCodeCannotBeSent -> QrLoginException.CheckCodeCannotBeSent
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -17,7 +17,9 @@ internal fun ComposerDraft.into(): RustComposerDraft {
|
|||
return RustComposerDraft(
|
||||
plainText = plainText,
|
||||
htmlText = htmlText,
|
||||
draftType = draftType.into()
|
||||
draftType = draftType.into(),
|
||||
// TODO add media attachments to the draft
|
||||
attachments = emptyList(),
|
||||
)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -31,10 +31,6 @@ object NotificationIdProvider {
|
|||
return getOffset(sessionId) + FALLBACK_NOTIFICATION_ID
|
||||
}
|
||||
|
||||
fun getCallNotificationId(sessionId: SessionId): Int {
|
||||
return getOffset(sessionId) + ROOM_CALL_NOTIFICATION_ID
|
||||
}
|
||||
|
||||
fun getForegroundServiceNotificationId(type: ForegroundServiceType): Int {
|
||||
return type.id * 10 + FOREGROUND_SERVICE_NOTIFICATION_ID
|
||||
}
|
||||
|
|
@ -49,7 +45,6 @@ object NotificationIdProvider {
|
|||
private const val ROOM_MESSAGES_NOTIFICATION_ID = 1
|
||||
private const val ROOM_EVENT_NOTIFICATION_ID = 2
|
||||
private const val ROOM_INVITATION_NOTIFICATION_ID = 3
|
||||
private const val ROOM_CALL_NOTIFICATION_ID = 3
|
||||
|
||||
private const val FOREGROUND_SERVICE_NOTIFICATION_ID = 4
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,7 +7,6 @@
|
|||
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
|
||||
<uses-permission android:name="android.permission.POST_NOTIFICATIONS" />
|
||||
|
||||
<uses-permission android:name="android.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS" />
|
||||
|
||||
<application>
|
||||
|
|
|
|||
|
|
@ -18,6 +18,7 @@ import io.element.android.libraries.push.impl.notifications.model.ResolvedPushEv
|
|||
import io.element.android.libraries.push.impl.workmanager.SyncNotificationWorkManagerRequest
|
||||
import io.element.android.libraries.push.impl.workmanager.WorkerDataConverter
|
||||
import io.element.android.libraries.workmanager.api.WorkManagerScheduler
|
||||
import io.element.android.services.toolbox.api.sdk.BuildVersionSdkIntProvider
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
||||
import kotlinx.coroutines.Job
|
||||
|
|
@ -49,6 +50,7 @@ class DefaultNotificationResolverQueue(
|
|||
private val workManagerScheduler: WorkManagerScheduler,
|
||||
private val featureFlagService: FeatureFlagService,
|
||||
private val workerDataConverter: WorkerDataConverter,
|
||||
private val buildVersionSdkIntProvider: BuildVersionSdkIntProvider,
|
||||
) : NotificationResolverQueue {
|
||||
companion object {
|
||||
private const val BATCH_WINDOW_MS = 250L
|
||||
|
|
@ -100,6 +102,7 @@ class DefaultNotificationResolverQueue(
|
|||
sessionId = sessionId,
|
||||
notificationEventRequests = requests,
|
||||
workerDataConverter = workerDataConverter,
|
||||
buildVersionSdkIntProvider = buildVersionSdkIntProvider,
|
||||
)
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -29,6 +29,7 @@ import io.element.android.libraries.push.impl.notifications.NotificationResolver
|
|||
import io.element.android.libraries.workmanager.api.WorkManagerScheduler
|
||||
import io.element.android.libraries.workmanager.api.di.MetroWorkerFactory
|
||||
import io.element.android.libraries.workmanager.api.di.WorkerKey
|
||||
import io.element.android.services.toolbox.api.sdk.BuildVersionSdkIntProvider
|
||||
import kotlinx.coroutines.flow.MutableSharedFlow
|
||||
import kotlinx.coroutines.flow.first
|
||||
import kotlinx.coroutines.withContext
|
||||
|
|
@ -39,7 +40,7 @@ import kotlin.time.Duration.Companion.seconds
|
|||
@AssistedInject
|
||||
class FetchNotificationsWorker(
|
||||
@Assisted workerParams: WorkerParameters,
|
||||
@ApplicationContext context: Context,
|
||||
@ApplicationContext private val context: Context,
|
||||
private val networkMonitor: NetworkMonitor,
|
||||
private val eventResolver: NotifiableEventResolver,
|
||||
private val queue: NotificationResolverQueue,
|
||||
|
|
@ -47,6 +48,7 @@ class FetchNotificationsWorker(
|
|||
private val syncOnNotifiableEvent: SyncOnNotifiableEvent,
|
||||
private val coroutineDispatchers: CoroutineDispatchers,
|
||||
private val workerDataConverter: WorkerDataConverter,
|
||||
private val buildVersionSdkIntProvider: BuildVersionSdkIntProvider,
|
||||
) : CoroutineWorker(context, workerParams) {
|
||||
override suspend fun doWork(): Result = withContext(coroutineDispatchers.io) {
|
||||
Timber.d("FetchNotificationsWorker started")
|
||||
|
|
@ -88,6 +90,7 @@ class FetchNotificationsWorker(
|
|||
sessionId = failedSessionId,
|
||||
notificationEventRequests = requestsToRetry,
|
||||
workerDataConverter = workerDataConverter,
|
||||
buildVersionSdkIntProvider = buildVersionSdkIntProvider,
|
||||
)
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@
|
|||
|
||||
package io.element.android.libraries.push.impl.workmanager
|
||||
|
||||
import android.os.Build
|
||||
import androidx.work.OneTimeWorkRequestBuilder
|
||||
import androidx.work.OutOfQuotaPolicy
|
||||
import androidx.work.WorkRequest
|
||||
|
|
@ -15,6 +16,7 @@ import io.element.android.libraries.push.api.push.NotificationEventRequest
|
|||
import io.element.android.libraries.workmanager.api.WorkManagerRequest
|
||||
import io.element.android.libraries.workmanager.api.WorkManagerRequestType
|
||||
import io.element.android.libraries.workmanager.api.workManagerTag
|
||||
import io.element.android.services.toolbox.api.sdk.BuildVersionSdkIntProvider
|
||||
import kotlinx.serialization.SerialName
|
||||
import kotlinx.serialization.Serializable
|
||||
import timber.log.Timber
|
||||
|
|
@ -24,6 +26,7 @@ class SyncNotificationWorkManagerRequest(
|
|||
private val sessionId: SessionId,
|
||||
private val notificationEventRequests: List<NotificationEventRequest>,
|
||||
private val workerDataConverter: WorkerDataConverter,
|
||||
private val buildVersionSdkIntProvider: BuildVersionSdkIntProvider,
|
||||
) : WorkManagerRequest {
|
||||
override fun build(): Result<WorkRequest> {
|
||||
if (notificationEventRequests.isEmpty()) {
|
||||
|
|
@ -36,7 +39,14 @@ class SyncNotificationWorkManagerRequest(
|
|||
return Result.success(
|
||||
OneTimeWorkRequestBuilder<FetchNotificationsWorker>()
|
||||
.setInputData(data)
|
||||
.setExpedited(OutOfQuotaPolicy.RUN_AS_NON_EXPEDITED_WORK_REQUEST)
|
||||
.apply {
|
||||
// Expedited workers aren't needed on Android 12 or lower:
|
||||
// They force displaying a foreground sync notification for no good reason, since they sync almost immediately anyway
|
||||
// See https://developer.android.com/develop/background-work/background-tasks/persistent/getting-started/define-work#backwards-compat
|
||||
if (buildVersionSdkIntProvider.isAtLeast(Build.VERSION_CODES.TIRAMISU)) {
|
||||
setExpedited(OutOfQuotaPolicy.RUN_AS_NON_EXPEDITED_WORK_REQUEST)
|
||||
}
|
||||
}
|
||||
.setTraceTag(workManagerTag(sessionId, WorkManagerRequestType.NOTIFICATION_SYNC))
|
||||
// TODO investigate using this instead of the resolver queue
|
||||
// .setInputMerger()
|
||||
|
|
|
|||
|
|
@ -55,6 +55,7 @@ import io.element.android.libraries.pushstore.test.userpushstore.FakeUserPushSto
|
|||
import io.element.android.libraries.pushstore.test.userpushstore.clientsecret.FakePushClientSecret
|
||||
import io.element.android.libraries.workmanager.api.WorkManagerRequest
|
||||
import io.element.android.libraries.workmanager.test.FakeWorkManagerScheduler
|
||||
import io.element.android.services.toolbox.test.sdk.FakeBuildVersionSdkIntProvider
|
||||
import io.element.android.services.toolbox.test.strings.FakeStringProvider
|
||||
import io.element.android.services.toolbox.test.systemclock.FakeSystemClock
|
||||
import io.element.android.tests.testutils.lambda.any
|
||||
|
|
@ -717,6 +718,7 @@ class DefaultPushHandlerTest {
|
|||
workManagerScheduler = workManagerScheduler,
|
||||
featureFlagService = featureFlagService,
|
||||
workerDataConverter = WorkerDataConverter(DefaultJsonProvider()),
|
||||
buildVersionSdkIntProvider = FakeBuildVersionSdkIntProvider(33),
|
||||
),
|
||||
appCoroutineScope = backgroundScope,
|
||||
fallbackNotificationFactory = FallbackNotificationFactory(
|
||||
|
|
|
|||
|
|
@ -28,6 +28,7 @@ import io.element.android.libraries.push.test.notifications.FakeNotificationReso
|
|||
import io.element.android.libraries.workmanager.api.WorkManagerRequest
|
||||
import io.element.android.libraries.workmanager.api.di.MetroWorkerFactory
|
||||
import io.element.android.libraries.workmanager.test.FakeWorkManagerScheduler
|
||||
import io.element.android.services.toolbox.test.sdk.FakeBuildVersionSdkIntProvider
|
||||
import io.element.android.tests.testutils.lambda.lambdaRecorder
|
||||
import io.element.android.tests.testutils.testCoroutineDispatchers
|
||||
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
||||
|
|
@ -176,6 +177,7 @@ class FetchNotificationWorkerTest {
|
|||
syncOnNotifiableEvent = syncOnNotifiableEvent,
|
||||
coroutineDispatchers = testCoroutineDispatchers(),
|
||||
workerDataConverter = WorkerDataConverter(DefaultJsonProvider()),
|
||||
buildVersionSdkIntProvider = FakeBuildVersionSdkIntProvider(33),
|
||||
)
|
||||
|
||||
private fun TestScope.createWorkerParams(
|
||||
|
|
|
|||
|
|
@ -17,15 +17,17 @@ import io.element.android.libraries.push.api.push.NotificationEventRequest
|
|||
import io.element.android.libraries.push.impl.notifications.fixtures.aNotificationEventRequest
|
||||
import io.element.android.libraries.workmanager.api.WorkManagerRequestType
|
||||
import io.element.android.libraries.workmanager.api.workManagerTag
|
||||
import io.element.android.services.toolbox.test.sdk.FakeBuildVersionSdkIntProvider
|
||||
import kotlinx.coroutines.test.runTest
|
||||
import org.junit.Test
|
||||
|
||||
class SyncNotificationWorkManagerRequestTest {
|
||||
@Test
|
||||
fun `build - success`() = runTest {
|
||||
fun `build - success API 33`() = runTest {
|
||||
val request = createSyncNotificationWorkManagerRequest(
|
||||
sessionId = A_SESSION_ID,
|
||||
notificationEventRequests = listOf(aNotificationEventRequest())
|
||||
notificationEventRequests = listOf(aNotificationEventRequest()),
|
||||
sdkVersion = 33,
|
||||
)
|
||||
|
||||
val result = request.build()
|
||||
|
|
@ -33,11 +35,31 @@ class SyncNotificationWorkManagerRequestTest {
|
|||
result.getOrNull()!!.run {
|
||||
assertThat(this).isInstanceOf(OneTimeWorkRequest::class.java)
|
||||
assertThat(workSpec.input.hasKeyWithValueOfType<String>("requests")).isTrue()
|
||||
// True in API 33+
|
||||
assertThat(workSpec.expedited).isTrue()
|
||||
assertThat(workSpec.traceTag).isEqualTo(workManagerTag(A_SESSION_ID, WorkManagerRequestType.NOTIFICATION_SYNC))
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `build - success API 32 and lower`() = runTest {
|
||||
val request = createSyncNotificationWorkManagerRequest(
|
||||
sessionId = A_SESSION_ID,
|
||||
notificationEventRequests = listOf(aNotificationEventRequest()),
|
||||
sdkVersion = 32,
|
||||
)
|
||||
|
||||
val result = request.build()
|
||||
assertThat(result.isSuccess).isTrue()
|
||||
result.getOrNull()!!.run {
|
||||
assertThat(this).isInstanceOf(OneTimeWorkRequest::class.java)
|
||||
assertThat(workSpec.input.hasKeyWithValueOfType<String>("requests")).isTrue()
|
||||
// False before API 33
|
||||
assertThat(workSpec.expedited).isFalse()
|
||||
assertThat(workSpec.traceTag).isEqualTo(workManagerTag(A_SESSION_ID, WorkManagerRequestType.NOTIFICATION_SYNC))
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `build - empty list of requests fails`() = runTest {
|
||||
val request = createSyncNotificationWorkManagerRequest(
|
||||
|
|
@ -64,9 +86,11 @@ class SyncNotificationWorkManagerRequestTest {
|
|||
private fun createSyncNotificationWorkManagerRequest(
|
||||
sessionId: SessionId,
|
||||
notificationEventRequests: List<NotificationEventRequest>,
|
||||
workerDataConverter: WorkerDataConverter = WorkerDataConverter(DefaultJsonProvider())
|
||||
workerDataConverter: WorkerDataConverter = WorkerDataConverter(DefaultJsonProvider()),
|
||||
sdkVersion: Int = 33,
|
||||
) = SyncNotificationWorkManagerRequest(
|
||||
sessionId = sessionId,
|
||||
notificationEventRequests = notificationEventRequests,
|
||||
workerDataConverter = workerDataConverter,
|
||||
buildVersionSdkIntProvider = FakeBuildVersionSdkIntProvider(sdkVersion),
|
||||
)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue