Skip to content

Commit 56df011

Browse files
authored
Merge branch 'develop' into renovate/kotlin
2 parents 96286e7 + 86afffb commit 56df011

File tree

450 files changed

+4049
-1907
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

450 files changed

+4049
-1907
lines changed

.github/workflows/danger.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ jobs:
2020
- run: |
2121
npm install --save-dev @babel/plugin-transform-flow-strip-types
2222
- name: Danger
23-
uses: danger/[email protected].3
23+
uses: danger/[email protected].4
2424
with:
2525
args: "--dangerfile ./tools/danger/dangerfile.js"
2626
env:

.github/workflows/quality.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -294,7 +294,7 @@ jobs:
294294
yarn add danger-plugin-lint-report --dev
295295
- name: Danger lint
296296
if: always()
297-
uses: danger/[email protected].3
297+
uses: danger/[email protected].4
298298
with:
299299
args: "--dangerfile ./tools/danger/dangerfile-lint.js"
300300
env:

app/src/main/res/xml/locales_config.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
<locale android:name="ru"/>
2626
<locale android:name="sk"/>
2727
<locale android:name="sv"/>
28+
<locale android:name="tr"/>
2829
<locale android:name="uk"/>
2930
<locale android:name="uz"/>
3031
<locale android:name="zh-CN"/>

app/src/main/res/xml/network_security_config.xml

Lines changed: 9 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,15 @@
11
<?xml version="1.0" encoding="utf-8"?>
2-
<network-security-config>
2+
<network-security-config xmlns:tools="http://schemas.android.com/tools">
33
<!-- Ref: https://developer.android.com/training/articles/security-config.html -->
44
<!-- By default, do not allow clearText traffic -->
5-
<base-config cleartextTrafficPermitted="false" />
5+
<base-config cleartextTrafficPermitted="false">
6+
<trust-anchors>
7+
<certificates src="system" />
8+
<certificates
9+
src="user"
10+
tools:ignore="AcceptsUserCertificates" />
11+
</trust-anchors>
12+
</base-config>
613

714
<!-- Allow clearText traffic on some specified host -->
815
<domain-config cleartextTrafficPermitted="true">
@@ -24,12 +31,4 @@
2431
<domain includeSubdomains="true">lan</domain>
2532
<domain includeSubdomains="true">localdomain</domain>
2633
</domain-config>
27-
28-
<debug-overrides>
29-
<trust-anchors>
30-
<certificates src="system" />
31-
<certificates src="user" />
32-
</trust-anchors>
33-
</debug-overrides>
34-
3534
</network-security-config>

appnav/src/main/kotlin/io/element/android/appnav/LoggedInFlowNode.kt

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,6 @@ import io.element.android.libraries.matrix.api.core.toRoomIdOrAlias
7575
import io.element.android.libraries.matrix.api.permalink.PermalinkData
7676
import io.element.android.libraries.matrix.api.verification.SessionVerificationRequestDetails
7777
import io.element.android.libraries.matrix.api.verification.SessionVerificationServiceListener
78-
import io.element.android.libraries.preferences.api.store.EnableNativeSlidingSyncUseCase
7978
import io.element.android.services.appnavstate.api.AppNavigationStateService
8079
import kotlinx.coroutines.CoroutineScope
8180
import kotlinx.coroutines.flow.launchIn
@@ -105,7 +104,6 @@ class LoggedInFlowNode @AssistedInject constructor(
105104
private val sendingQueue: SendQueues,
106105
private val logoutEntryPoint: LogoutEntryPoint,
107106
private val incomingVerificationEntryPoint: IncomingVerificationEntryPoint,
108-
private val enableNativeSlidingSyncUseCase: EnableNativeSlidingSyncUseCase,
109107
snackbarDispatcher: SnackbarDispatcher,
110108
) : BaseFlowNode<LoggedInFlowNode.NavTarget>(
111109
backstack = BackStack(
@@ -420,9 +418,6 @@ class LoggedInFlowNode @AssistedInject constructor(
420418
}
421419

422420
logoutEntryPoint.nodeBuilder(this, buildContext)
423-
.onSuccessfulLogoutPendingAction {
424-
enableNativeSlidingSyncUseCase()
425-
}
426421
.callback(callback)
427422
.build()
428423
}

appnav/src/main/kotlin/io/element/android/appnav/di/SyncOrchestrator.kt

Lines changed: 24 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77

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

10+
import androidx.annotation.VisibleForTesting
1011
import dagger.assisted.Assisted
1112
import dagger.assisted.AssistedFactory
1213
import dagger.assisted.AssistedInject
@@ -21,9 +22,9 @@ import kotlinx.coroutines.FlowPreview
2122
import kotlinx.coroutines.flow.combine
2223
import kotlinx.coroutines.flow.debounce
2324
import kotlinx.coroutines.flow.distinctUntilChanged
24-
import kotlinx.coroutines.flow.launchIn
25+
import kotlinx.coroutines.flow.first
2526
import kotlinx.coroutines.flow.onCompletion
26-
import kotlinx.coroutines.flow.onEach
27+
import kotlinx.coroutines.launch
2728
import timber.log.Timber
2829
import java.util.concurrent.atomic.AtomicBoolean
2930
import kotlin.time.Duration.Companion.milliseconds
@@ -53,13 +54,28 @@ class SyncOrchestrator @AssistedInject constructor(
5354
*
5455
* Before observing the state, a first attempt at starting the sync service will happen if it's not already running.
5556
*/
56-
@OptIn(FlowPreview::class)
5757
fun start() {
5858
if (!started.compareAndSet(false, true)) {
5959
Timber.tag(tag).d("already started, exiting early")
6060
return
6161
}
6262

63+
coroutineScope.launch {
64+
// Perform an initial sync if the sync service is not running, to check whether the homeserver is accessible
65+
// Otherwise, if the device is offline the sync service will never start and the SyncState will be Idle, not Offline
66+
Timber.tag(tag).d("performing initial sync attempt")
67+
syncService.startSync()
68+
69+
// Wait until the sync service is not idle, either it will be running or in error/offline state
70+
syncService.syncState.first { it != SyncState.Idle }
71+
72+
observeStates()
73+
}
74+
}
75+
76+
@OptIn(FlowPreview::class)
77+
@VisibleForTesting(otherwise = VisibleForTesting.PRIVATE)
78+
internal fun observeStates() = coroutineScope.launch {
6379
Timber.tag(tag).d("start observing the app and network state")
6480

6581
combine(
@@ -76,7 +92,7 @@ class SyncOrchestrator @AssistedInject constructor(
7692
Timber.tag(tag).d("isAppActive=$isAppActive, isNetworkAvailable=$isNetworkAvailable")
7793
if (syncState == SyncState.Running && !isAppActive) {
7894
SyncStateAction.StopSync
79-
} else if (syncState != SyncState.Running && isAppActive && isNetworkAvailable) {
95+
} else if (syncState == SyncState.Idle && isAppActive && isNetworkAvailable) {
8096
SyncStateAction.StartSync
8197
} else {
8298
SyncStateAction.NoOp
@@ -87,7 +103,10 @@ class SyncOrchestrator @AssistedInject constructor(
87103
// Don't stop the sync immediately, wait a bit to avoid starting/stopping the sync too often
88104
if (action == SyncStateAction.StopSync) 3.seconds else 0.seconds
89105
}
90-
.onEach { action ->
106+
.onCompletion {
107+
Timber.tag(tag).d("has been stopped")
108+
}
109+
.collect { action ->
91110
when (action) {
92111
SyncStateAction.StartSync -> {
93112
syncService.startSync()
@@ -98,10 +117,6 @@ class SyncOrchestrator @AssistedInject constructor(
98117
SyncStateAction.NoOp -> Unit
99118
}
100119
}
101-
.onCompletion {
102-
Timber.tag(tag).d("has been stopped")
103-
}
104-
.launchIn(coroutineScope)
105120
}
106121
}
107122

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

Lines changed: 8 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ import im.vector.app.features.analytics.plan.UserProperties
2222
import io.element.android.libraries.architecture.AsyncData
2323
import io.element.android.libraries.architecture.Presenter
2424
import io.element.android.libraries.core.log.logger.LoggerTag
25+
import io.element.android.libraries.core.meta.BuildMeta
2526
import io.element.android.libraries.matrix.api.MatrixClient
2627
import io.element.android.libraries.matrix.api.encryption.EncryptionService
2728
import io.element.android.libraries.matrix.api.encryption.RecoveryState
@@ -31,7 +32,6 @@ import io.element.android.libraries.matrix.api.sync.SyncService
3132
import io.element.android.libraries.matrix.api.sync.isOnline
3233
import io.element.android.libraries.matrix.api.verification.SessionVerificationService
3334
import io.element.android.libraries.matrix.api.verification.SessionVerifiedStatus
34-
import io.element.android.libraries.preferences.api.store.EnableNativeSlidingSyncUseCase
3535
import io.element.android.libraries.push.api.PushService
3636
import io.element.android.libraries.pushproviders.api.RegistrationFailure
3737
import io.element.android.services.analytics.api.AnalyticsService
@@ -51,7 +51,7 @@ class LoggedInPresenter @Inject constructor(
5151
private val sessionVerificationService: SessionVerificationService,
5252
private val analyticsService: AnalyticsService,
5353
private val encryptionService: EncryptionService,
54-
private val enableNativeSlidingSyncUseCase: EnableNativeSlidingSyncUseCase,
54+
private val buildMeta: BuildMeta,
5555
) : Presenter<LoggedInState> {
5656
@Composable
5757
override fun present(): LoggedInState {
@@ -103,12 +103,10 @@ class LoggedInPresenter @Inject constructor(
103103
}
104104
}
105105
LoggedInEvents.CheckSlidingSyncProxyAvailability -> coroutineScope.launch {
106-
forceNativeSlidingSyncMigration = matrixClient.forceNativeSlidingSyncMigration().getOrDefault(false)
106+
forceNativeSlidingSyncMigration = matrixClient.needsForcedNativeSlidingSyncMigration().getOrDefault(false)
107107
}
108108
LoggedInEvents.LogoutAndMigrateToNativeSlidingSync -> coroutineScope.launch {
109-
// Enable native sliding sync if it wasn't already the case
110-
enableNativeSlidingSyncUseCase()
111-
// Then force the logout
109+
// Force the logout since Native Sliding Sync is already enforced by the SDK
112110
matrixClient.logout(userInitiated = true, ignoreSdkError = true)
113111
}
114112
}
@@ -119,20 +117,15 @@ class LoggedInPresenter @Inject constructor(
119117
pusherRegistrationState = pusherRegistrationState.value,
120118
ignoreRegistrationError = ignoreRegistrationError,
121119
forceNativeSlidingSyncMigration = forceNativeSlidingSyncMigration,
120+
appName = buildMeta.applicationName,
122121
eventSink = ::handleEvent
123122
)
124123
}
125124

126-
// Force the user to log out if they were using the proxy sliding sync and it's no longer available, but native sliding sync is.
127-
private suspend fun MatrixClient.forceNativeSlidingSyncMigration(): Result<Boolean> = runCatching {
125+
// Force the user to log out if they were using the proxy sliding sync as it's no longer supported by the SDK
126+
private suspend fun MatrixClient.needsForcedNativeSlidingSyncMigration(): Result<Boolean> = runCatching {
128127
val currentSlidingSyncVersion = currentSlidingSyncVersion().getOrThrow()
129-
if (currentSlidingSyncVersion == SlidingSyncVersion.Proxy) {
130-
val availableSlidingSyncVersions = availableSlidingSyncVersions().getOrThrow()
131-
availableSlidingSyncVersions.contains(SlidingSyncVersion.Native) &&
132-
!availableSlidingSyncVersions.contains(SlidingSyncVersion.Proxy)
133-
} else {
134-
false
135-
}
128+
currentSlidingSyncVersion == SlidingSyncVersion.Proxy
136129
}
137130

138131
private suspend fun ensurePusherIsRegistered(pusherRegistrationState: MutableState<AsyncData<Unit>>) {

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,5 +14,6 @@ data class LoggedInState(
1414
val pusherRegistrationState: AsyncData<Unit>,
1515
val ignoreRegistrationError: Boolean,
1616
val forceNativeSlidingSyncMigration: Boolean,
17+
val appName: String,
1718
val eventSink: (LoggedInEvents) -> Unit,
1819
)

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

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,10 +24,12 @@ fun aLoggedInState(
2424
showSyncSpinner: Boolean = false,
2525
pusherRegistrationState: AsyncData<Unit> = AsyncData.Uninitialized,
2626
forceNativeSlidingSyncMigration: Boolean = false,
27+
appName: String = "Element X",
2728
) = LoggedInState(
2829
showSyncSpinner = showSyncSpinner,
2930
pusherRegistrationState = pusherRegistrationState,
3031
ignoreRegistrationError = false,
3132
forceNativeSlidingSyncMigration = forceNativeSlidingSyncMigration,
33+
appName = appName,
3234
eventSink = {},
3335
)

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

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -73,9 +73,12 @@ fun LoggedInView(
7373

7474
// Set the force migration dialog here so it's always displayed over every screen
7575
if (state.forceNativeSlidingSyncMigration) {
76-
ForceNativeSlidingSyncMigrationDialog(onSubmit = {
77-
state.eventSink(LoggedInEvents.LogoutAndMigrateToNativeSlidingSync)
78-
})
76+
ForceNativeSlidingSyncMigrationDialog(
77+
appName = state.appName,
78+
onSubmit = {
79+
state.eventSink(LoggedInEvents.LogoutAndMigrateToNativeSlidingSync)
80+
}
81+
)
7982
}
8083
}
8184

@@ -98,11 +101,12 @@ private fun Throwable.getReason(): String? {
98101

99102
@Composable
100103
private fun ForceNativeSlidingSyncMigrationDialog(
104+
appName: String,
101105
onSubmit: () -> Unit,
102106
) {
103107
ErrorDialog(
104108
title = null,
105-
content = stringResource(R.string.banner_migrate_to_native_sliding_sync_force_logout_title),
109+
content = stringResource(R.string.banner_migrate_to_native_sliding_sync_app_force_logout_title, appName),
106110
submitText = stringResource(R.string.banner_migrate_to_native_sliding_sync_action),
107111
onSubmit = onSubmit,
108112
canDismiss = false,

0 commit comments

Comments
 (0)