Skip to content

Commit

Permalink
Merge branch 'develop' into allow_http_call_when_checking_crl
Browse files Browse the repository at this point in the history
  • Loading branch information
ohassine authored Feb 13, 2024
2 parents 357ae68 + a0bc84c commit bfab931
Show file tree
Hide file tree
Showing 12 changed files with 170 additions and 37 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/codestyle.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ jobs:
distribution: 'temurin'
cache: gradle
- name: Validate Gradle wrapper
uses: gradle/wrapper-validation-action@56b90f209b02bf6d1deae490e9ef18b21a389cd4
uses: gradle/wrapper-validation-action@699bb18358f12c5b78b37bb0111d3a0e2276e0e2
- name: Run Detekt
run: |
./gradlew detektAll
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/gradle-run-ui-tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ jobs:
cache: gradle

- name: Validate Gradle wrapper
uses: gradle/wrapper-validation-action@56b90f209b02bf6d1deae490e9ef18b21a389cd4
uses: gradle/wrapper-validation-action@699bb18358f12c5b78b37bb0111d3a0e2276e0e2

- name: AVD cache
uses: buildjet/cache@v3
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/gradle-run-unit-tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ jobs:
cache: gradle

- name: Validate Gradle wrapper
uses: gradle/wrapper-validation-action@56b90f209b02bf6d1deae490e9ef18b21a389cd4
uses: gradle/wrapper-validation-action@699bb18358f12c5b78b37bb0111d3a0e2276e0e2

- name: Test Build Logic
run: |
Expand Down
24 changes: 18 additions & 6 deletions app/src/main/kotlin/com/wire/android/GlobalObserversManager.kt
Original file line number Diff line number Diff line change
Expand Up @@ -91,14 +91,26 @@ class GlobalObserversManager @Inject constructor(
}

coreLogic.getGlobalScope().observeValidAccounts()
.combine(persistentStatusesFlow) { list, persistentStatuses ->
val persistentStatusesMap = persistentStatuses.associate { it.userId to it.isPersistentWebSocketEnabled }
/*
Intersect both lists as they can be slightly out of sync because both lists can be updated at slightly different times.
When user is logged out, at this time one of them can still contain this invalid user - make sure that it's ignored.
When user is logged in, at this time one of them can still not contain this new user - ignore for now,
the user will be handled correctly in the next iteration when the second list becomes updated as well.
*/
list.map { (selfUser, _) -> selfUser }
.filter { persistentStatusesMap.containsKey(it.id) }
.map { it to persistentStatusesMap.getValue(it.id) }
}
.distinctUntilChanged()
.combine(persistentStatusesFlow, ::Pair)
.collect { (list, persistentStatuses) ->
notificationChannelsManager.createUserNotificationChannels(list.map { it.first })
.collectLatest {
// create notification channels for all valid users
notificationChannelsManager.createUserNotificationChannels(it.map { it.first })

list.map { it.first.id }
// do not observe notifications for users with PersistentWebSocketEnabled, it will be done in PersistentWebSocketService
.filter { userId -> persistentStatuses.none { it.userId == userId && it.isPersistentWebSocketEnabled } }
// do not observe notifications for users with PersistentWebSocketEnabled, it will be done in PersistentWebSocketService
it.filter { (_, isPersistentWebSocketEnabled) -> !isPersistentWebSocketEnabled }
.map { (selfUser, _) -> selfUser.id }
.run {
notificationManager.observeNotificationsAndCallsWhileRunning(this, scope)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,12 +37,8 @@ class ObserveAppLockConfigUseCase @Inject constructor(
) {
operator fun invoke(): Flow<AppLockConfig> = channelFlow {
coreLogic.getGlobalScope().session.currentSessionFlow().collectLatest { sessionResult ->
when (sessionResult) {
is CurrentSessionResult.Failure -> {
send(AppLockConfig.Disabled(DEFAULT_APP_LOCK_TIMEOUT))
}

is CurrentSessionResult.Success -> {
when {
sessionResult is CurrentSessionResult.Success && sessionResult.accountInfo.isValid() -> {
val userId = sessionResult.accountInfo.userId
val appLockTeamFeatureConfigFlow =
coreLogic.getSessionScope(userId).appLockTeamFeatureConfigObserver
Expand All @@ -67,6 +63,10 @@ class ObserveAppLockConfigUseCase @Inject constructor(
send(it)
}
}

else -> {
send(AppLockConfig.Disabled(DEFAULT_APP_LOCK_TIMEOUT))
}
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@

package com.wire.android.notification

import androidx.annotation.VisibleForTesting
import com.wire.android.R
import com.wire.android.appLogger
import com.wire.android.di.KaliumCoreLogic
Expand All @@ -36,6 +37,7 @@ import com.wire.kalium.logic.data.notification.LocalNotificationMessage
import com.wire.kalium.logic.data.user.UserId
import com.wire.kalium.logic.feature.message.MarkMessagesAsNotifiedUseCase
import com.wire.kalium.logic.feature.session.CurrentSessionResult
import com.wire.kalium.logic.feature.session.DoesValidSessionExistResult
import com.wire.kalium.logic.feature.session.GetAllSessionsResult
import com.wire.kalium.logic.feature.user.E2EIRequiredResult
import kotlinx.coroutines.CoroutineScope
Expand Down Expand Up @@ -244,9 +246,8 @@ class WireNotificationManager @Inject constructor(
return
}

// start observing notifications only for new users
userIds
.filter { observingJobs.userJobs[it]?.isAllActive() != true }
// start observing notifications only for new users with valid session and without active jobs
newUsersWithValidSessionAndWithoutActiveJobs(userIds) { observingJobs.userJobs[it]?.isAllActive() == true }
.forEach { userId ->
val jobs = UserObservingJobs(
currentScreenJob = scope.launch(dispatcherProvider.default()) {
Expand All @@ -271,6 +272,20 @@ class WireNotificationManager @Inject constructor(
}
}

@VisibleForTesting
internal suspend fun newUsersWithValidSessionAndWithoutActiveJobs(
userIds: List<UserId>,
hasActiveJobs: (UserId) -> Boolean
): List<UserId> = userIds
.filter { !hasActiveJobs(it) }
.filter {
// double check if the valid session for the given user still exists
when (val result = coreLogic.getGlobalScope().doesValidSessionExist(it)) {
is DoesValidSessionExistResult.Success -> result.doesValidSessionExist
else -> false
}
}

private fun stopObservingForUser(userId: UserId, observingJobs: ObservingJobs) {
messagesNotificationManager.hideAllNotificationsForUser(userId)
observingJobs.userJobs[userId]?.cancelAll()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@ fun DeviceItem(
device: Device,
placeholder: Boolean,
shouldShowVerifyLabel: Boolean,
isCurrentClient: Boolean = false,
background: Color? = null,
icon: @Composable (() -> Unit),
isWholeItemClickable: Boolean = false,
Expand All @@ -85,7 +86,8 @@ fun DeviceItem(
icon = icon,
onClickAction = onClickAction,
isWholeItemClickable = isWholeItemClickable,
shouldShowVerifyLabel = shouldShowVerifyLabel
shouldShowVerifyLabel = shouldShowVerifyLabel,
isCurrentClient = isCurrentClient
)
}

Expand All @@ -97,7 +99,8 @@ private fun DeviceItemContent(
icon: @Composable (() -> Unit),
onClickAction: ((Device) -> Unit)?,
isWholeItemClickable: Boolean,
shouldShowVerifyLabel: Boolean
shouldShowVerifyLabel: Boolean,
isCurrentClient: Boolean
) {
Row(
verticalAlignment = Alignment.Top,
Expand All @@ -123,7 +126,7 @@ private fun DeviceItemContent(
modifier = Modifier
.padding(start = MaterialTheme.wireDimensions.removeDeviceItemPadding)
.weight(1f)
) { DeviceItemTexts(device, placeholder, shouldShowVerifyLabel) }
) { DeviceItemTexts(device, placeholder, shouldShowVerifyLabel, isCurrentClient) }
}
if (!placeholder) {
if (onClickAction != null && !isWholeItemClickable) {
Expand Down Expand Up @@ -154,6 +157,7 @@ private fun DeviceItemTexts(
device: Device,
placeholder: Boolean,
shouldShowVerifyLabel: Boolean,
isCurrentClient: Boolean = false,
isDebug: Boolean = BuildConfig.DEBUG
) {
val displayZombieIndicator = remember {
Expand All @@ -173,10 +177,10 @@ private fun DeviceItemTexts(
.wrapContentWidth()
.shimmerPlaceholder(visible = placeholder)
)
MLSVerificationIcon(device.e2eiCertificateStatus)
if (shouldShowVerifyLabel) {
MLSVerificationIcon(device.e2eiCertificateStatus)
Spacer(modifier = Modifier.width(MaterialTheme.wireDimensions.spacing8x))
if (device.isVerifiedProteus) ProteusVerifiedIcon(
if (device.isVerifiedProteus && !isCurrentClient) ProteusVerifiedIcon(
Modifier
.wrapContentWidth()
.align(Alignment.CenterVertically))
Expand Down Expand Up @@ -251,6 +255,7 @@ fun PreviewDeviceItemWithActionIcon() {
device = Device(name = UIText.DynamicString("name"), isVerifiedProteus = true),
placeholder = false,
shouldShowVerifyLabel = true,
isCurrentClient = true,
background = null,
{ Icon(painter = painterResource(id = R.drawable.ic_remove), contentDescription = "") }
) {}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -71,8 +71,9 @@ class ProximitySensorManager @Inject constructor(
override fun onSensorChanged(event: SensorEvent) {
appCoroutineScope.launch {
coreLogic.get().globalScope {
when (val currentSession = currentSession.get().invoke()) {
is CurrentSessionResult.Success -> {
val currentSession = currentSession.get().invoke()
when {
currentSession is CurrentSessionResult.Success && currentSession.accountInfo.isValid() -> {
val userId = currentSession.accountInfo.userId
val isCallRunning = coreLogic.get().getSessionScope(userId).calls.isCallRunning()
val distance = event.values.first()
Expand All @@ -92,8 +93,10 @@ class ProximitySensorManager @Inject constructor(
}
}

else -> {
// NO SESSION - Nothing to do
else -> { // NO SESSION - just release in case it's still held
if (wakeLock.isHeld) {
wakeLock.release()
}
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -90,17 +90,20 @@ fun SelfDevicesScreenContent(
false -> {
state.currentDevice?.let { currentDevice ->
folderDeviceItems(
context.getString(R.string.current_device_label),
listOf(currentDevice),
false,
onDeviceClick
header = context.getString(R.string.current_device_label),
items = listOf(currentDevice),
shouldShowVerifyLabel = true,
isCurrentClient = true,
onDeviceClick = onDeviceClick,

)
}
folderDeviceItems(
context.getString(R.string.other_devices_label),
state.deviceList,
true,
onDeviceClick
header = context.getString(R.string.other_devices_label),
items = state.deviceList,
shouldShowVerifyLabel = true,
isCurrentClient = false,
onDeviceClick = onDeviceClick
)
}
}
Expand All @@ -113,6 +116,7 @@ private fun LazyListScope.folderDeviceItems(
header: String,
items: List<Device>,
shouldShowVerifyLabel: Boolean,
isCurrentClient: Boolean,
onDeviceClick: (Device) -> Unit = {}
) {
folderWithElements(
Expand All @@ -132,7 +136,8 @@ private fun LazyListScope.folderDeviceItems(
onClickAction = onDeviceClick,
icon = Icons.Filled.ChevronRight.Icon(),
isWholeItemClickable = true,
shouldShowVerifyLabel = shouldShowVerifyLabel
shouldShowVerifyLabel = shouldShowVerifyLabel,
isCurrentClient = isCurrentClient
)
}
}
Expand Down
17 changes: 17 additions & 0 deletions app/src/test/kotlin/com/wire/android/GlobalObserversManagerTest.kt
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,23 @@ class GlobalObserversManagerTest {
coVerify(exactly = 0) { arrangement.messageScope.deleteEphemeralMessageEndDate() }
}

@Test
fun `given validAccounts and persistentStatuses are out of sync, when setting up notifications, then ignore invalid users`() {
val validAccountsList = listOf(TestUser.SELF_USER)
val persistentStatusesList = listOf(
PersistentWebSocketStatus(TestUser.SELF_USER.id, false),
PersistentWebSocketStatus(TestUser.USER_ID.copy(value = "something else"), true)
)
val (arrangement, manager) = Arrangement()
.withValidAccounts(validAccountsList.map { it to null })
.withPersistentWebSocketConnectionStatuses(persistentStatusesList)
.arrange()
manager.observe()
coVerify(exactly = 1) {
arrangement.notificationChannelsManager.createUserNotificationChannels(listOf(TestUser.SELF_USER))
}
}

private class Arrangement {

@MockK
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import com.wire.android.datastore.GlobalDataStore
import com.wire.kalium.logic.CoreLogic
import com.wire.kalium.logic.configuration.AppLockTeamConfig
import com.wire.kalium.logic.data.auth.AccountInfo
import com.wire.kalium.logic.data.logout.LogoutReason
import com.wire.kalium.logic.data.user.UserId
import com.wire.kalium.logic.feature.UserSessionScope
import com.wire.kalium.logic.feature.applock.AppLockTeamFeatureConfigObserver
Expand Down Expand Up @@ -54,6 +55,22 @@ class ObserveAppLockConfigUseCaseTest {
}
}

@Test
fun givenInvalidSession_whenObservingAppLock_thenSendDisabledStatus() = runTest {
val (_, useCase) = Arrangement()
.withInvalidSession()
.arrange()

val result = useCase.invoke()

result.test {
val appLockStatus = awaitItem()

assertEquals(AppLockConfig.Disabled(timeout), appLockStatus)
awaitComplete()
}
}

@Test
fun givenValidSessionAndAppLockedByTeam_whenObservingAppLock_thenSendEnforcedByTeamStatus() =
runTest {
Expand Down Expand Up @@ -142,6 +159,11 @@ class ObserveAppLockConfigUseCaseTest {
flowOf(CurrentSessionResult.Failure.SessionNotFound)
}

fun withInvalidSession() = apply {
coEvery { coreLogic.getGlobalScope().session.currentSessionFlow() } returns
flowOf(CurrentSessionResult.Success(accountInfoInvalid))
}

fun withValidSession() = apply {
coEvery { coreLogic.getGlobalScope().session.currentSessionFlow() } returns
flowOf(CurrentSessionResult.Success(accountInfo))
Expand Down Expand Up @@ -177,7 +199,9 @@ class ObserveAppLockConfigUseCaseTest {
}

companion object {
private val accountInfo = AccountInfo.Valid(UserId("userId", "domain"))
private val userId = UserId("userId", "domain")
private val accountInfo = AccountInfo.Valid(userId)
private val accountInfoInvalid = AccountInfo.Invalid(userId, LogoutReason.DELETED_ACCOUNT)
private val timeout = 60.seconds
}
}
Loading

0 comments on commit bfab931

Please sign in to comment.