Skip to content

Commit ccfccbb

Browse files
authored
Merge pull request #4215 from element-hq/feature/bma/airGappedSdk
Let the SDK provide the "network is available information"
2 parents 19e57d4 + c8f4268 commit ccfccbb

File tree

20 files changed

+86
-74
lines changed

20 files changed

+86
-74
lines changed

appnav/src/main/kotlin/io/element/android/appnav/loggedin/LoggedInPresenter.kt

+5-5
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,6 @@ import androidx.compose.runtime.rememberCoroutineScope
1919
import androidx.compose.runtime.setValue
2020
import im.vector.app.features.analytics.plan.CryptoSessionStateChange
2121
import im.vector.app.features.analytics.plan.UserProperties
22-
import io.element.android.features.networkmonitor.api.NetworkMonitor
23-
import io.element.android.features.networkmonitor.api.NetworkStatus
2422
import io.element.android.libraries.architecture.AsyncData
2523
import io.element.android.libraries.architecture.Presenter
2624
import io.element.android.libraries.core.log.logger.LoggerTag
@@ -29,6 +27,8 @@ import io.element.android.libraries.matrix.api.encryption.EncryptionService
2927
import io.element.android.libraries.matrix.api.encryption.RecoveryState
3028
import io.element.android.libraries.matrix.api.roomlist.RoomListService
3129
import io.element.android.libraries.matrix.api.sync.SlidingSyncVersion
30+
import io.element.android.libraries.matrix.api.sync.SyncService
31+
import io.element.android.libraries.matrix.api.sync.isOnline
3232
import io.element.android.libraries.matrix.api.verification.SessionVerificationService
3333
import io.element.android.libraries.matrix.api.verification.SessionVerifiedStatus
3434
import io.element.android.libraries.preferences.api.store.EnableNativeSlidingSyncUseCase
@@ -46,7 +46,7 @@ private val pusherTag = LoggerTag("Pusher", LoggerTag.PushLoggerTag)
4646

4747
class LoggedInPresenter @Inject constructor(
4848
private val matrixClient: MatrixClient,
49-
private val networkMonitor: NetworkMonitor,
49+
private val syncService: SyncService,
5050
private val pushService: PushService,
5151
private val sessionVerificationService: SessionVerificationService,
5252
private val analyticsService: AnalyticsService,
@@ -76,10 +76,10 @@ class LoggedInPresenter @Inject constructor(
7676
.launchIn(this)
7777
}
7878
val syncIndicator by matrixClient.roomListService.syncIndicator.collectAsState()
79-
val networkStatus by networkMonitor.connectivity.collectAsState()
79+
val isOnline by syncService.isOnline().collectAsState()
8080
val showSyncSpinner by remember {
8181
derivedStateOf {
82-
networkStatus == NetworkStatus.Online && syncIndicator == RoomListService.SyncIndicator.Show
82+
isOnline && syncIndicator == RoomListService.SyncIndicator.Show
8383
}
8484
}
8585
var forceNativeSlidingSyncMigration by remember { mutableStateOf(false) }

appnav/src/main/kotlin/io/element/android/appnav/loggedin/SendQueues.kt

+7-6
Original file line numberDiff line numberDiff line change
@@ -8,11 +8,12 @@
88
package io.element.android.appnav.loggedin
99

1010
import androidx.annotation.VisibleForTesting
11-
import io.element.android.features.networkmonitor.api.NetworkMonitor
1211
import io.element.android.features.networkmonitor.api.NetworkStatus
1312
import io.element.android.libraries.di.SessionScope
1413
import io.element.android.libraries.di.SingleIn
1514
import io.element.android.libraries.matrix.api.MatrixClient
15+
import io.element.android.libraries.matrix.api.sync.SyncService
16+
import io.element.android.libraries.matrix.api.sync.SyncState
1617
import kotlinx.coroutines.CoroutineScope
1718
import kotlinx.coroutines.FlowPreview
1819
import kotlinx.coroutines.flow.combine
@@ -27,7 +28,7 @@ const val SEND_QUEUES_RETRY_DELAY_MILLIS = 500L
2728
@SingleIn(SessionScope::class)
2829
class SendQueues @Inject constructor(
2930
private val matrixClient: MatrixClient,
30-
private val networkMonitor: NetworkMonitor,
31+
private val syncService: SyncService,
3132
) {
3233
/**
3334
* Launches the send queues retry mechanism in the given [coroutineScope].
@@ -36,12 +37,12 @@ class SendQueues @Inject constructor(
3637
@OptIn(FlowPreview::class)
3738
fun launchIn(coroutineScope: CoroutineScope) {
3839
combine(
39-
networkMonitor.connectivity,
40+
syncService.syncState,
4041
matrixClient.sendQueueDisabledFlow(),
41-
) { networkStatus, _ -> networkStatus }
42+
) { syncState, _ -> syncState }
4243
.debounce(SEND_QUEUES_RETRY_DELAY_MILLIS)
43-
.onEach { networkStatus ->
44-
if (networkStatus == NetworkStatus.Online) {
44+
.onEach { syncState ->
45+
if (syncState == SyncState.Running) {
4546
matrixClient.setAllSendQueuesEnabled(enabled = true)
4647
}
4748
}

appnav/src/main/kotlin/io/element/android/appnav/room/RoomFlowNode.kt

+5-5
Original file line numberDiff line numberDiff line change
@@ -30,8 +30,6 @@ import io.element.android.appnav.room.joined.JoinedRoomLoadedFlowNode
3030
import io.element.android.appnav.room.joined.LoadingRoomNodeView
3131
import io.element.android.appnav.room.joined.LoadingRoomState
3232
import io.element.android.features.joinroom.api.JoinRoomEntryPoint
33-
import io.element.android.features.networkmonitor.api.NetworkMonitor
34-
import io.element.android.features.networkmonitor.api.NetworkStatus
3533
import io.element.android.features.roomaliasesolver.api.RoomAliasResolverEntryPoint
3634
import io.element.android.features.roomdirectory.api.RoomDescription
3735
import io.element.android.libraries.architecture.BackstackView
@@ -50,6 +48,8 @@ import io.element.android.libraries.matrix.api.getRoomInfoFlow
5048
import io.element.android.libraries.matrix.api.room.CurrentUserMembership
5149
import io.element.android.libraries.matrix.api.room.RoomMembershipObserver
5250
import io.element.android.libraries.matrix.api.room.alias.ResolvedRoomAlias
51+
import io.element.android.libraries.matrix.api.sync.SyncService
52+
import io.element.android.libraries.matrix.api.sync.isOnline
5353
import kotlinx.coroutines.flow.combine
5454
import kotlinx.coroutines.flow.distinctUntilChanged
5555
import kotlinx.coroutines.flow.first
@@ -68,7 +68,7 @@ class RoomFlowNode @AssistedInject constructor(
6868
private val client: MatrixClient,
6969
private val joinRoomEntryPoint: JoinRoomEntryPoint,
7070
private val roomAliasResolverEntryPoint: RoomAliasResolverEntryPoint,
71-
private val networkMonitor: NetworkMonitor,
71+
private val syncService: SyncService,
7272
private val membershipObserver: RoomMembershipObserver,
7373
) : BaseFlowNode<RoomFlowNode.NavTarget>(
7474
backstack = BackStack(
@@ -211,10 +211,10 @@ class RoomFlowNode @AssistedInject constructor(
211211
}
212212

213213
private fun loadingNode(buildContext: BuildContext) = node(buildContext) { modifier ->
214-
val networkStatus by networkMonitor.connectivity.collectAsState()
214+
val isOnline by syncService.isOnline().collectAsState()
215215
LoadingRoomNodeView(
216216
state = LoadingRoomState.Loading,
217-
hasNetworkConnection = networkStatus == NetworkStatus.Online,
217+
hasNetworkConnection = isOnline,
218218
onBackClick = { navigateUp() },
219219
modifier = modifier,
220220
)

appnav/src/main/kotlin/io/element/android/appnav/room/joined/JoinedRoomFlowNode.kt

+5-5
Original file line numberDiff line numberDiff line change
@@ -28,15 +28,15 @@ import dagger.assisted.Assisted
2828
import dagger.assisted.AssistedInject
2929
import io.element.android.anvilannotations.ContributesNode
3030
import io.element.android.appnav.room.RoomNavigationTarget
31-
import io.element.android.features.networkmonitor.api.NetworkMonitor
32-
import io.element.android.features.networkmonitor.api.NetworkStatus
3331
import io.element.android.libraries.architecture.BackstackView
3432
import io.element.android.libraries.architecture.BaseFlowNode
3533
import io.element.android.libraries.architecture.NodeInputs
3634
import io.element.android.libraries.architecture.createNode
3735
import io.element.android.libraries.architecture.inputs
3836
import io.element.android.libraries.di.SessionScope
3937
import io.element.android.libraries.matrix.api.core.RoomId
38+
import io.element.android.libraries.matrix.api.sync.SyncService
39+
import io.element.android.libraries.matrix.api.sync.isOnline
4040
import kotlinx.coroutines.flow.distinctUntilChanged
4141
import kotlinx.coroutines.flow.launchIn
4242
import kotlinx.coroutines.flow.map
@@ -48,7 +48,7 @@ class JoinedRoomFlowNode @AssistedInject constructor(
4848
@Assisted val buildContext: BuildContext,
4949
@Assisted plugins: List<Plugin>,
5050
loadingRoomStateFlowFactory: LoadingRoomStateFlowFactory,
51-
private val networkMonitor: NetworkMonitor,
51+
private val syncService: SyncService,
5252
) :
5353
BaseFlowNode<JoinedRoomFlowNode.NavTarget>(
5454
backstack = BackStack(
@@ -114,10 +114,10 @@ class JoinedRoomFlowNode @AssistedInject constructor(
114114

115115
private fun loadingNode(buildContext: BuildContext, onBackClick: () -> Unit) = node(buildContext) { modifier ->
116116
val loadingRoomState by loadingRoomStateStateFlow.collectAsState()
117-
val networkStatus by networkMonitor.connectivity.collectAsState()
117+
val isOnline by syncService.isOnline().collectAsState()
118118
LoadingRoomNodeView(
119119
state = loadingRoomState,
120-
hasNetworkConnection = networkStatus == NetworkStatus.Online,
120+
hasNetworkConnection = isOnline,
121121
modifier = modifier,
122122
onBackClick = onBackClick
123123
)

appnav/src/test/kotlin/io/element/android/appnav/loggedin/LoggedInPresenterTest.kt

+6-6
Original file line numberDiff line numberDiff line change
@@ -14,21 +14,21 @@ import app.cash.turbine.test
1414
import com.google.common.truth.Truth.assertThat
1515
import im.vector.app.features.analytics.plan.CryptoSessionStateChange
1616
import im.vector.app.features.analytics.plan.UserProperties
17-
import io.element.android.features.networkmonitor.api.NetworkStatus
18-
import io.element.android.features.networkmonitor.test.FakeNetworkMonitor
1917
import io.element.android.libraries.matrix.api.MatrixClient
2018
import io.element.android.libraries.matrix.api.core.SessionId
2119
import io.element.android.libraries.matrix.api.encryption.EncryptionService
2220
import io.element.android.libraries.matrix.api.encryption.RecoveryState
2321
import io.element.android.libraries.matrix.api.roomlist.RoomListService
2422
import io.element.android.libraries.matrix.api.sync.SlidingSyncVersion
23+
import io.element.android.libraries.matrix.api.sync.SyncState
2524
import io.element.android.libraries.matrix.api.verification.SessionVerificationService
2625
import io.element.android.libraries.matrix.api.verification.SessionVerifiedStatus
2726
import io.element.android.libraries.matrix.test.AN_EXCEPTION
2827
import io.element.android.libraries.matrix.test.A_SESSION_ID
2928
import io.element.android.libraries.matrix.test.FakeMatrixClient
3029
import io.element.android.libraries.matrix.test.encryption.FakeEncryptionService
3130
import io.element.android.libraries.matrix.test.roomlist.FakeRoomListService
31+
import io.element.android.libraries.matrix.test.sync.FakeSyncService
3232
import io.element.android.libraries.matrix.test.verification.FakeSessionVerificationService
3333
import io.element.android.libraries.preferences.api.store.EnableNativeSlidingSyncUseCase
3434
import io.element.android.libraries.preferences.test.InMemoryAppPreferencesStore
@@ -73,7 +73,7 @@ class LoggedInPresenterTest {
7373
@Test
7474
fun `present - show sync spinner`() = runTest {
7575
val roomListService = FakeRoomListService()
76-
val presenter = createLoggedInPresenter(roomListService, NetworkStatus.Online)
76+
val presenter = createLoggedInPresenter(roomListService, SyncState.Running)
7777
moleculeFlow(RecompositionMode.Immediate) {
7878
presenter.present()
7979
}.test {
@@ -94,7 +94,7 @@ class LoggedInPresenterTest {
9494
val encryptionService = FakeEncryptionService()
9595
val presenter = LoggedInPresenter(
9696
matrixClient = FakeMatrixClient(roomListService = roomListService, encryptionService = encryptionService),
97-
networkMonitor = FakeNetworkMonitor(NetworkStatus.Online),
97+
syncService = FakeSyncService(initialSyncState = SyncState.Running),
9898
pushService = FakePushService(),
9999
sessionVerificationService = verificationService,
100100
analyticsService = analyticsService,
@@ -574,7 +574,7 @@ class LoggedInPresenterTest {
574574

575575
private fun TestScope.createLoggedInPresenter(
576576
roomListService: RoomListService = FakeRoomListService(),
577-
networkStatus: NetworkStatus = NetworkStatus.Offline,
577+
syncState: SyncState = SyncState.Running,
578578
analyticsService: AnalyticsService = FakeAnalyticsService(),
579579
sessionVerificationService: SessionVerificationService = FakeSessionVerificationService(),
580580
encryptionService: EncryptionService = FakeEncryptionService(),
@@ -584,7 +584,7 @@ class LoggedInPresenterTest {
584584
): LoggedInPresenter {
585585
return LoggedInPresenter(
586586
matrixClient = matrixClient,
587-
networkMonitor = FakeNetworkMonitor(networkStatus),
587+
syncService = FakeSyncService(initialSyncState = syncState),
588588
pushService = pushService,
589589
sessionVerificationService = sessionVerificationService,
590590
analyticsService = analyticsService,

appnav/src/test/kotlin/io/element/android/appnav/loggedin/SendQueuesTest.kt

+6-6
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,11 @@
77

88
package io.element.android.appnav.loggedin
99

10-
import io.element.android.features.networkmonitor.api.NetworkStatus
11-
import io.element.android.features.networkmonitor.test.FakeNetworkMonitor
1210
import io.element.android.libraries.matrix.api.core.RoomId
11+
import io.element.android.libraries.matrix.api.sync.SyncState
1312
import io.element.android.libraries.matrix.test.FakeMatrixClient
1413
import io.element.android.libraries.matrix.test.room.FakeMatrixRoom
14+
import io.element.android.libraries.matrix.test.sync.FakeSyncService
1515
import io.element.android.tests.testutils.lambda.assert
1616
import io.element.android.tests.testutils.lambda.lambdaRecorder
1717
import io.element.android.tests.testutils.lambda.value
@@ -25,8 +25,8 @@ import org.junit.Test
2525
@OptIn(ExperimentalCoroutinesApi::class)
2626
class SendQueuesTest {
2727
private val matrixClient = FakeMatrixClient()
28-
private val networkMonitor = FakeNetworkMonitor()
29-
private val sut = SendQueues(matrixClient, networkMonitor)
28+
private val syncService = FakeSyncService(initialSyncState = SyncState.Running)
29+
private val sut = SendQueues(matrixClient, syncService)
3030

3131
@Test
3232
fun `test network status online and sending queue failed`() = runTest {
@@ -53,13 +53,13 @@ class SendQueuesTest {
5353
}
5454

5555
@Test
56-
fun `test network status offline and sending queue failed`() = runTest {
56+
fun `test sync state offline and sending queue failed`() = runTest {
5757
val sendQueueDisabledFlow = MutableSharedFlow<RoomId>(replay = 1)
5858

5959
val setAllSendQueuesEnabledLambda = lambdaRecorder { _: Boolean -> }
6060
matrixClient.sendQueueDisabledFlow = sendQueueDisabledFlow
6161
matrixClient.setAllSendQueuesEnabledLambda = setAllSendQueuesEnabledLambda
62-
networkMonitor.connectivity.value = NetworkStatus.Offline
62+
syncService.emitSyncState(SyncState.Offline)
6363
val setRoomSendQueueEnabledLambda = lambdaRecorder { _: Boolean -> }
6464
val room = FakeMatrixRoom(
6565
setSendQueueEnabledLambda = setRoomSendQueueEnabledLambda

features/call/impl/src/test/kotlin/io/element/android/features/call/ui/CallScreenPresenterTest.kt

+3-6
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,6 @@ import io.element.android.tests.testutils.lambda.value
4141
import io.element.android.tests.testutils.testCoroutineDispatchers
4242
import kotlinx.coroutines.ExperimentalCoroutinesApi
4343
import kotlinx.coroutines.cancelAndJoin
44-
import kotlinx.coroutines.flow.MutableStateFlow
4544
import kotlinx.coroutines.launch
4645
import kotlinx.coroutines.sync.Mutex
4746
import kotlinx.coroutines.test.TestScope
@@ -82,7 +81,7 @@ class CallScreenPresenterTest {
8281
@Test
8382
fun `present - with CallType RoomCall sets call as active, loads URL, runs WidgetDriver and notifies the other clients a call started`() = runTest {
8483
val sendCallNotificationIfNeededLambda = lambdaRecorder<Result<Unit>> { Result.success(Unit) }
85-
val syncService = FakeSyncService(MutableStateFlow(SyncState.Running))
84+
val syncService = FakeSyncService(SyncState.Running)
8685
val fakeRoom = FakeMatrixRoom(sendCallNotificationIfNeededResult = sendCallNotificationIfNeededLambda)
8786
val client = FakeMatrixClient(syncService = syncService).apply {
8887
givenGetRoomResult(A_ROOM_ID, fakeRoom)
@@ -247,9 +246,8 @@ class CallScreenPresenterTest {
247246
fun `present - automatically starts the Matrix client sync when on RoomCall`() = runTest {
248247
val navigator = FakeCallScreenNavigator()
249248
val widgetDriver = FakeMatrixWidgetDriver()
250-
val syncStateFlow = MutableStateFlow(SyncState.Idle)
251249
val startSyncLambda = lambdaRecorder<Result<Unit>> { Result.success(Unit) }
252-
val syncService = FakeSyncService(syncStateFlow = syncStateFlow).apply {
250+
val syncService = FakeSyncService(SyncState.Idle).apply {
253251
this.startSyncLambda = startSyncLambda
254252
}
255253
val matrixClient = FakeMatrixClient(syncService = syncService)
@@ -276,9 +274,8 @@ class CallScreenPresenterTest {
276274
fun `present - automatically stops the Matrix client sync on dispose`() = runTest {
277275
val navigator = FakeCallScreenNavigator()
278276
val widgetDriver = FakeMatrixWidgetDriver()
279-
val syncStateFlow = MutableStateFlow(SyncState.Running)
280277
val stopSyncLambda = lambdaRecorder<Result<Unit>> { Result.success(Unit) }
281-
val syncService = FakeSyncService(syncStateFlow = syncStateFlow).apply {
278+
val syncService = FakeSyncService(SyncState.Running).apply {
282279
this.stopSyncLambda = stopSyncLambda
283280
}
284281
val matrixClient = FakeMatrixClient(syncService = syncService)

features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/MessagesPresenter.kt

+5-5
Original file line numberDiff line numberDiff line change
@@ -47,8 +47,6 @@ import io.element.android.features.messages.impl.timeline.model.event.TimelineIt
4747
import io.element.android.features.messages.impl.timeline.model.event.TimelineItemTextBasedContent
4848
import io.element.android.features.messages.impl.timeline.protection.TimelineProtectionState
4949
import io.element.android.features.messages.impl.voicemessages.composer.VoiceMessageComposerState
50-
import io.element.android.features.networkmonitor.api.NetworkMonitor
51-
import io.element.android.features.networkmonitor.api.NetworkStatus
5250
import io.element.android.features.roomcall.api.RoomCallState
5351
import io.element.android.libraries.androidutils.clipboard.ClipboardHelper
5452
import io.element.android.libraries.architecture.AsyncData
@@ -72,6 +70,8 @@ import io.element.android.libraries.matrix.api.room.powerlevels.canPinUnpin
7270
import io.element.android.libraries.matrix.api.room.powerlevels.canRedactOther
7371
import io.element.android.libraries.matrix.api.room.powerlevels.canRedactOwn
7472
import io.element.android.libraries.matrix.api.room.powerlevels.canSendMessage
73+
import io.element.android.libraries.matrix.api.sync.SyncService
74+
import io.element.android.libraries.matrix.api.sync.isOnline
7575
import io.element.android.libraries.matrix.api.timeline.item.event.EventOrTransactionId
7676
import io.element.android.libraries.matrix.ui.messages.reply.map
7777
import io.element.android.libraries.matrix.ui.model.getAvatarData
@@ -98,7 +98,7 @@ class MessagesPresenter @AssistedInject constructor(
9898
private val readReceiptBottomSheetPresenter: Presenter<ReadReceiptBottomSheetState>,
9999
private val pinnedMessagesBannerPresenter: Presenter<PinnedMessagesBannerState>,
100100
private val roomCallStatePresenter: Presenter<RoomCallState>,
101-
private val networkMonitor: NetworkMonitor,
101+
private val syncService: SyncService,
102102
private val snackbarDispatcher: SnackbarDispatcher,
103103
private val dispatchers: CoroutineDispatchers,
104104
private val clipboardHelper: ClipboardHelper,
@@ -170,7 +170,7 @@ class MessagesPresenter @AssistedInject constructor(
170170
showReinvitePrompt = !hasDismissedInviteDialog && composerState.textEditorState.hasFocus() && room.isDm && room.activeMemberCount == 1L
171171
}
172172
}
173-
val networkConnectionStatus by networkMonitor.connectivity.collectAsState()
173+
val isOnline by syncService.isOnline().collectAsState()
174174

175175
val snackbarMessage by snackbarDispatcher.collectSnackbarMessageAsState()
176176

@@ -220,7 +220,7 @@ class MessagesPresenter @AssistedInject constructor(
220220
customReactionState = customReactionState,
221221
reactionSummaryState = reactionSummaryState,
222222
readReceiptBottomSheetState = readReceiptBottomSheetState,
223-
hasNetworkConnection = networkConnectionStatus == NetworkStatus.Online,
223+
hasNetworkConnection = isOnline,
224224
snackbarMessage = snackbarMessage,
225225
showReinvitePrompt = showReinvitePrompt,
226226
inviteProgress = inviteProgress.value,

0 commit comments

Comments
 (0)