Skip to content

Commit b194153

Browse files
authored
Merge branch 'develop' into feature/bma/testEntryPoint
2 parents 2d9e9d1 + e980936 commit b194153

File tree

50 files changed

+316
-124
lines changed

Some content is hidden

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

50 files changed

+316
-124
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,7 @@ captures/
6262
# Android Studio 3 in .gitignore file.
6363
.idea/caches
6464
.idea/copilot
65+
.idea/copilot.*
6566
.idea/inspectionProfiles
6667
# Shelved changes in the IDE
6768
.idea/shelf

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

Lines changed: 0 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,6 @@ import io.element.android.features.ftue.api.FtueEntryPoint
5252
import io.element.android.features.ftue.api.state.FtueService
5353
import io.element.android.features.ftue.api.state.FtueState
5454
import io.element.android.features.home.api.HomeEntryPoint
55-
import io.element.android.features.logout.api.LogoutEntryPoint
5655
import io.element.android.features.networkmonitor.api.NetworkMonitor
5756
import io.element.android.features.networkmonitor.api.NetworkStatus
5857
import io.element.android.features.preferences.api.PreferencesEntryPoint
@@ -119,7 +118,6 @@ class LoggedInFlowNode(
119118
private val shareEntryPoint: ShareEntryPoint,
120119
private val matrixClient: MatrixClient,
121120
private val sendingQueue: SendQueues,
122-
private val logoutEntryPoint: LogoutEntryPoint,
123121
private val incomingVerificationEntryPoint: IncomingVerificationEntryPoint,
124122
private val mediaPreviewConfigMigration: MediaPreviewConfigMigration,
125123
private val sessionEnterpriseService: SessionEnterpriseService,
@@ -277,9 +275,6 @@ class LoggedInFlowNode(
277275
@Parcelize
278276
data class IncomingShare(val intent: Intent) : NavTarget
279277

280-
@Parcelize
281-
data object LogoutForNativeSlidingSyncMigrationNeeded : NavTarget
282-
283278
@Parcelize
284279
data class IncomingVerificationRequest(val data: VerificationRequest.Incoming) : NavTarget
285280
}
@@ -324,10 +319,6 @@ class LoggedInFlowNode(
324319
override fun onReportBugClick() {
325320
plugins<Callback>().forEach { it.onOpenBugReport() }
326321
}
327-
328-
override fun onLogoutForNativeSlidingSyncMigrationNeeded() {
329-
backstack.push(NavTarget.LogoutForNativeSlidingSyncMigrationNeeded)
330-
}
331322
}
332323
homeEntryPoint
333324
.nodeBuilder(this, buildContext)
@@ -485,17 +476,6 @@ class LoggedInFlowNode(
485476
.params(ShareEntryPoint.Params(intent = navTarget.intent))
486477
.build()
487478
}
488-
is NavTarget.LogoutForNativeSlidingSyncMigrationNeeded -> {
489-
val callback = object : LogoutEntryPoint.Callback {
490-
override fun onChangeRecoveryKeyClick() {
491-
backstack.push(NavTarget.SecureBackup())
492-
}
493-
}
494-
495-
logoutEntryPoint.nodeBuilder(this, buildContext)
496-
.callback(callback)
497-
.build()
498-
}
499479
is NavTarget.IncomingVerificationRequest -> {
500480
incomingVerificationEntryPoint.nodeBuilder(this, buildContext)
501481
.params(IncomingVerificationEntryPoint.Params(navTarget.data))

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

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -501,22 +501,16 @@ class LoggedInPresenterTest {
501501

502502
@Test
503503
fun `present - CheckSlidingSyncProxyAvailability forces the sliding sync migration under the right circumstances`() = runTest {
504-
// The migration will be forced if:
505-
// - The user is not using the native sliding sync
506-
// - The sliding sync proxy is no longer supported
507-
// - The native sliding sync is supported
504+
// The migration will be forced if the user is not using the native sliding sync
508505
val matrixClient = FakeMatrixClient(
509506
currentSlidingSyncVersionLambda = { Result.success(SlidingSyncVersion.Proxy) },
510-
availableSlidingSyncVersionsLambda = { Result.success(listOf(SlidingSyncVersion.Native)) },
511507
)
512508
createLoggedInPresenter(
513509
matrixClient = matrixClient,
514510
).test {
515511
val initialState = awaitItem()
516512
assertThat(initialState.forceNativeSlidingSyncMigration).isFalse()
517-
518513
initialState.eventSink(LoggedInEvents.CheckSlidingSyncProxyAvailability)
519-
520514
assertThat(awaitItem().forceNativeSlidingSyncMigration).isTrue()
521515
}
522516
}

features/call/api/src/main/kotlin/io/element/android/features/call/api/ElementCallEntryPoint.kt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ interface ElementCallEntryPoint {
2929
* @param senderName The name of the sender of the event that started the call.
3030
* @param avatarUrl The avatar url of the room or DM.
3131
* @param timestamp The timestamp of the event that started the call.
32+
* @param expirationTimestamp The timestamp at which the call should stop ringing.
3233
* @param notificationChannelId The id of the notification channel to use for the call notification.
3334
* @param textContent The text content of the notification. If null the default content from the system will be used.
3435
*/
@@ -40,6 +41,7 @@ interface ElementCallEntryPoint {
4041
senderName: String?,
4142
avatarUrl: String?,
4243
timestamp: Long,
44+
expirationTimestamp: Long,
4345
notificationChannelId: String,
4446
textContent: String?,
4547
)

features/call/impl/build.gradle.kts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,4 +96,5 @@ dependencies {
9696
testImplementation(projects.libraries.push.test)
9797
testImplementation(projects.services.analytics.test)
9898
testImplementation(projects.services.appnavstate.test)
99+
testImplementation(projects.services.toolbox.test)
99100
}

features/call/impl/src/main/kotlin/io/element/android/features/call/impl/DefaultElementCallEntryPoint.kt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ class DefaultElementCallEntryPoint(
4343
senderName: String?,
4444
avatarUrl: String?,
4545
timestamp: Long,
46+
expirationTimestamp: Long,
4647
notificationChannelId: String,
4748
textContent: String?,
4849
) {
@@ -55,6 +56,7 @@ class DefaultElementCallEntryPoint(
5556
senderName = senderName,
5657
avatarUrl = avatarUrl,
5758
timestamp = timestamp,
59+
expirationTimestamp = expirationTimestamp,
5860
notificationChannelId = notificationChannelId,
5961
textContent = textContent,
6062
)

features/call/impl/src/main/kotlin/io/element/android/features/call/impl/notifications/CallNotificationData.kt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,4 +26,6 @@ data class CallNotificationData(
2626
val notificationChannelId: String,
2727
val timestamp: Long,
2828
val textContent: String?,
29+
// Expiration timestamp in millis since epoch
30+
val expirationTimestamp: Long,
2931
) : Parcelable

features/call/impl/src/main/kotlin/io/element/android/features/call/impl/notifications/RingingCallNotificationCreator.kt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,7 @@ class RingingCallNotificationCreator(
6464
roomAvatarUrl: String?,
6565
notificationChannelId: String,
6666
timestamp: Long,
67+
expirationTimestamp: Long,
6768
textContent: String?,
6869
): Notification? {
6970
val matrixClient = matrixClientProvider.getOrRestore(sessionId).getOrNull() ?: return null
@@ -88,6 +89,7 @@ class RingingCallNotificationCreator(
8889
notificationChannelId = notificationChannelId,
8990
timestamp = timestamp,
9091
textContent = textContent,
92+
expirationTimestamp = expirationTimestamp,
9193
)
9294

9395
val declineIntent = PendingIntentCompat.getBroadcast(

features/call/impl/src/main/kotlin/io/element/android/features/call/impl/ui/IncomingCallScreen.kt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -176,6 +176,7 @@ internal fun IncomingCallScreenPreview() = ElementPreview {
176176
notificationChannelId = "incoming_call",
177177
timestamp = 0L,
178178
textContent = null,
179+
expirationTimestamp = 1000L,
179180
),
180181
onAnswer = {},
181182
onCancel = {},

features/call/impl/src/main/kotlin/io/element/android/features/call/impl/utils/ActiveCallManager.kt

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ import io.element.android.libraries.push.api.notifications.ForegroundServiceType
3434
import io.element.android.libraries.push.api.notifications.NotificationIdProvider
3535
import io.element.android.libraries.push.api.notifications.OnMissedCallNotificationHandler
3636
import io.element.android.services.appnavstate.api.AppForegroundStateService
37+
import io.element.android.services.toolbox.api.systemclock.SystemClock
3738
import kotlinx.coroutines.CoroutineScope
3839
import kotlinx.coroutines.ExperimentalCoroutinesApi
3940
import kotlinx.coroutines.Job
@@ -53,7 +54,7 @@ import kotlinx.coroutines.launch
5354
import kotlinx.coroutines.sync.Mutex
5455
import kotlinx.coroutines.sync.withLock
5556
import timber.log.Timber
56-
import kotlin.time.Duration.Companion.seconds
57+
import kotlin.math.min
5758

5859
/**
5960
* Manages the active call state.
@@ -98,6 +99,7 @@ class DefaultActiveCallManager(
9899
private val defaultCurrentCallService: DefaultCurrentCallService,
99100
private val appForegroundStateService: AppForegroundStateService,
100101
private val imageLoaderHolder: ImageLoaderHolder,
102+
private val systemClock: SystemClock,
101103
) : ActiveCallManager {
102104
private val tag = "DefaultActiveCallManager"
103105
private var timedOutCallJob: Job? = null
@@ -118,8 +120,20 @@ class DefaultActiveCallManager(
118120

119121
override suspend fun registerIncomingCall(notificationData: CallNotificationData) {
120122
mutex.withLock {
123+
val ringDuration =
124+
min(
125+
notificationData.expirationTimestamp - systemClock.epochMillis(),
126+
ElementCallConfig.RINGING_CALL_DURATION_SECONDS * 1000L
127+
)
128+
129+
if (ringDuration < 0) {
130+
// Should already have stopped ringing, ignore.
131+
Timber.tag(tag).d("Received timed-out incoming ringing call for room id: ${notificationData.roomId}, cancel ringing")
132+
return
133+
}
134+
121135
appForegroundStateService.updateHasRingingCall(true)
122-
Timber.tag(tag).d("Received incoming call for room id: ${notificationData.roomId}")
136+
Timber.tag(tag).d("Received incoming call for room id: ${notificationData.roomId}, ringDuration(ms): $ringDuration")
123137
if (activeCall.value != null) {
124138
displayMissedCallNotification(notificationData)
125139
Timber.tag(tag).w("Already have an active call, ignoring incoming call: $notificationData")
@@ -138,14 +152,14 @@ class DefaultActiveCallManager(
138152
showIncomingCallNotification(notificationData)
139153

140154
// Wait for the ringing call to time out
141-
delay(ElementCallConfig.RINGING_CALL_DURATION_SECONDS.seconds)
155+
delay(timeMillis = ringDuration)
142156
incomingCallTimedOut(displayMissedCallNotification = true)
143157
}
144158

145159
// Acquire a wake lock to keep the device awake during the incoming call, so we can process the room info data
146160
if (activeWakeLock?.isHeld == false) {
147161
Timber.tag(tag).d("Acquiring partial wakelock")
148-
activeWakeLock.acquire(ElementCallConfig.RINGING_CALL_DURATION_SECONDS * 1000L)
162+
activeWakeLock.acquire(ringDuration)
149163
}
150164
}
151165
}
@@ -236,6 +250,7 @@ class DefaultActiveCallManager(
236250
notificationChannelId = notificationData.notificationChannelId,
237251
timestamp = notificationData.timestamp,
238252
textContent = notificationData.textContent,
253+
expirationTimestamp = notificationData.expirationTimestamp,
239254
) ?: return
240255
runCatchingExceptions {
241256
notificationManagerCompat.notify(

0 commit comments

Comments
 (0)