Clean after benoits review

This commit is contained in:
ganfra 2021-06-21 17:57:47 +02:00
parent 4b6484d317
commit 48fa9e1a5e
7 changed files with 89 additions and 22 deletions

View file

@ -22,7 +22,6 @@ import androidx.lifecycle.OnLifecycleEvent
import arrow.core.Option
import im.vector.app.core.di.ActiveSessionHolder
import im.vector.app.core.utils.BehaviorDataSource
import im.vector.app.features.invite.InvitesAcceptor
import im.vector.app.features.session.coroutineScope
import im.vector.app.features.ui.UiStateRepository
import io.reactivex.disposables.CompositeDisposable
@ -52,8 +51,7 @@ fun RoomGroupingMethod.group() = (this as? RoomGroupingMethod.ByLegacyGroup)?.gr
class AppStateHandler @Inject constructor(
private val sessionDataSource: ActiveSessionDataSource,
private val uiStateRepository: UiStateRepository,
private val activeSessionHolder: ActiveSessionHolder,
private val invitesAcceptor: InvitesAcceptor
private val activeSessionHolder: ActiveSessionHolder
) : LifecycleObserver {
private val compositeDisposable = CompositeDisposable()
@ -63,10 +61,6 @@ class AppStateHandler @Inject constructor(
fun getCurrentRoomGroupingMethod(): RoomGroupingMethod? = selectedSpaceDataSource.currentValue?.orNull()
init {
observeActiveSession()
}
fun setCurrentSpace(spaceId: String?, session: Session? = null) {
val uSession = session ?: activeSessionHolder.getSafeActiveSession() ?: return
if (selectedSpaceDataSource.currentValue?.orNull() is RoomGroupingMethod.BySpace
@ -103,7 +97,6 @@ class AppStateHandler @Inject constructor(
.subscribe {
// sessionDataSource could already return a session while activeSession holder still returns null
it.orNull()?.let { session ->
invitesAcceptor.onSessionActive(session)
if (uiStateRepository.isGroupingMethodSpace(session.sessionId)) {
setCurrentSpace(uiStateRepository.getSelectedSpace(session.sessionId), session)
} else {
@ -123,8 +116,14 @@ class AppStateHandler @Inject constructor(
return (selectedSpaceDataSource.currentValue?.orNull() as? RoomGroupingMethod.ByLegacyGroup)?.groupSummary?.groupId
}
@OnLifecycleEvent(Lifecycle.Event.ON_RESUME)
fun entersForeground() {
observeActiveSession()
}
@OnLifecycleEvent(Lifecycle.Event.ON_PAUSE)
fun entersBackground() {
compositeDisposable.clear()
val session = activeSessionHolder.getSafeActiveSession() ?: return
when (val currentMethod = selectedSpaceDataSource.currentValue?.orNull() ?: RoomGroupingMethod.BySpace(null)) {
is RoomGroupingMethod.BySpace -> {

View file

@ -47,6 +47,7 @@ import im.vector.app.core.rx.RxConfig
import im.vector.app.features.call.webrtc.WebRtcCallManager
import im.vector.app.features.configuration.VectorConfiguration
import im.vector.app.features.disclaimer.doNotShowDisclaimerDialog
import im.vector.app.features.invite.InvitesAcceptor
import im.vector.app.features.lifecycle.VectorActivityLifecycleCallbacks
import im.vector.app.features.notifications.NotificationDrawerManager
import im.vector.app.features.notifications.NotificationUtils
@ -95,6 +96,7 @@ class VectorApplication :
@Inject lateinit var popupAlertManager: PopupAlertManager
@Inject lateinit var pinLocker: PinLocker
@Inject lateinit var callManager: WebRtcCallManager
@Inject lateinit var invitesAcceptor: InvitesAcceptor
lateinit var vectorComponent: VectorComponent
@ -116,6 +118,7 @@ class VectorApplication :
appContext = this
vectorComponent = DaggerVectorComponent.factory().create(this)
vectorComponent.inject(this)
invitesAcceptor.initialize()
vectorUncaughtExceptionHandler.activate(this)
rxConfig.setupRxPlugin()

View file

@ -32,6 +32,7 @@ import im.vector.app.features.call.lookup.CallProtocolsChecker
import im.vector.app.features.call.webrtc.WebRtcCallManager
import im.vector.app.features.createdirect.DirectRoomHelper
import im.vector.app.features.invite.AutoAcceptInvites
import im.vector.app.features.invite.showInvites
import im.vector.app.features.ui.UiStateRepository
import io.reactivex.schedulers.Schedulers
import kotlinx.coroutines.Dispatchers
@ -208,7 +209,7 @@ private val autoAcceptInvites: AutoAcceptInvites)
val activeSpaceRoomId = groupingMethod.spaceSummary?.roomId
var dmInvites = 0
var roomsInvite = 0
if (!autoAcceptInvites.hideInvites) {
if (autoAcceptInvites.showInvites()) {
dmInvites = session.getRoomSummaries(
roomSummaryQueryParams {
memberships = listOf(Membership.INVITE)

View file

@ -23,6 +23,7 @@ import im.vector.app.RoomGroupingMethod
import im.vector.app.core.resources.StringProvider
import im.vector.app.features.home.RoomListDisplayMode
import im.vector.app.features.invite.AutoAcceptInvites
import im.vector.app.features.invite.showInvites
import io.reactivex.disposables.Disposable
import io.reactivex.schedulers.Schedulers
import kotlinx.coroutines.CoroutineScope
@ -75,7 +76,7 @@ class GroupRoomListSectionBuilder(
)
}
RoomListDisplayMode.NOTIFICATIONS -> {
if (!autoAcceptInvites.hideInvites) {
if (autoAcceptInvites.showInvites()) {
addSection(
sections,
activeGroupAwareQueries,
@ -118,7 +119,7 @@ class GroupRoomListSectionBuilder(
private fun buildRoomsSections(sections: MutableList<RoomsSection>,
activeSpaceAwareQueries: MutableList<UpdatableLivePageResult>,
actualGroupId: String?) {
if (!autoAcceptInvites.hideInvites) {
if (autoAcceptInvites.showInvites()) {
addSection(
sections,
activeSpaceAwareQueries,
@ -185,7 +186,7 @@ class GroupRoomListSectionBuilder(
activeSpaceAwareQueries: MutableList<UpdatableLivePageResult>,
actualGroupId: String?
) {
if (!autoAcceptInvites.hideInvites) {
if (autoAcceptInvites.showInvites()) {
addSection(sections,
activeSpaceAwareQueries,
R.string.invitations_header,

View file

@ -27,6 +27,7 @@ import im.vector.app.R
import im.vector.app.core.resources.StringProvider
import im.vector.app.features.home.RoomListDisplayMode
import im.vector.app.features.invite.AutoAcceptInvites
import im.vector.app.features.invite.showInvites
import im.vector.app.space
import io.reactivex.Observable
import io.reactivex.disposables.Disposable
@ -90,7 +91,7 @@ class SpaceRoomListSectionBuilder(
)
}
RoomListDisplayMode.NOTIFICATIONS -> {
if (!autoAcceptInvites.hideInvites) {
if (autoAcceptInvites.showInvites()) {
addSection(
sections = sections,
activeSpaceUpdaters = activeSpaceAwareQueries,
@ -140,7 +141,7 @@ class SpaceRoomListSectionBuilder(
}
private fun buildRoomsSections(sections: MutableList<RoomsSection>, activeSpaceAwareQueries: MutableList<RoomListViewModel.ActiveSpaceQueryUpdater>) {
if (!autoAcceptInvites.hideInvites) {
if (autoAcceptInvites.showInvites()) {
addSection(
sections = sections,
activeSpaceUpdaters = activeSpaceAwareQueries,
@ -259,7 +260,7 @@ class SpaceRoomListSectionBuilder(
}
private fun buildDmSections(sections: MutableList<RoomsSection>, activeSpaceAwareQueries: MutableList<RoomListViewModel.ActiveSpaceQueryUpdater>) {
if (!autoAcceptInvites.hideInvites) {
if (autoAcceptInvites.showInvites()) {
addSection(sections = sections,
activeSpaceUpdaters = activeSpaceAwareQueries,
nameRes = R.string.invitations_header,

View file

@ -18,12 +18,28 @@ package im.vector.app.features.invite
import javax.inject.Inject
/**
* This interface defines 2 flags so you can handle auto accept invites.
* At the moment we only have [CompileTimeAutoAcceptInvites] implementation.
*/
interface AutoAcceptInvites {
/**
* Enable auto-accept invites. It means, as soon as you got an invite from the sync, it will try to join it.
*/
val isEnabled: Boolean
/**
* Hide invites from the UI (from notifications, notification count and room list). By default invites are hidden when [isEnabled] is true
*/
val hideInvites: Boolean
get() = isEnabled
}
fun AutoAcceptInvites.showInvites() = !hideInvites
/**
* Simple compile time implementation of AutoAcceptInvites flags.
*/
class CompileTimeAutoAcceptInvites @Inject constructor() : AutoAcceptInvites {
override val isEnabled = false
override val hideInvites = isEnabled
}

View file

@ -16,6 +16,7 @@
package im.vector.app.features.invite
import im.vector.app.ActiveSessionDataSource
import im.vector.app.features.session.coroutineScope
import io.reactivex.Observable
import io.reactivex.disposables.Disposable
@ -23,7 +24,10 @@ import kotlinx.coroutines.async
import kotlinx.coroutines.launch
import kotlinx.coroutines.sync.Semaphore
import kotlinx.coroutines.sync.withPermit
import org.matrix.android.sdk.api.extensions.orFalse
import org.matrix.android.sdk.api.failure.Failure
import org.matrix.android.sdk.api.session.Session
import org.matrix.android.sdk.api.session.room.Room
import org.matrix.android.sdk.api.session.room.members.ChangeMembershipState
import org.matrix.android.sdk.api.session.room.model.Membership
import org.matrix.android.sdk.api.session.room.roomSummaryQueryParams
@ -39,16 +43,35 @@ import javax.inject.Singleton
* This mechanism will be on only if AutoAcceptInvites.isEnabled is true.
*/
@Singleton
class InvitesAcceptor @Inject constructor(private val autoAcceptInvites: AutoAcceptInvites) : Session.Listener {
class InvitesAcceptor @Inject constructor(
private val sessionDataSource: ActiveSessionDataSource,
private val autoAcceptInvites: AutoAcceptInvites
) : Session.Listener {
private val disposables = HashMap<String, Disposable>()
private lateinit var activeSessionDisposable: Disposable
private val shouldRejectRoomIds = mutableSetOf<String>()
private val invitedRoomDisposables = HashMap<String, Disposable>()
private val semaphore = Semaphore(1)
fun onSessionActive(session: Session) {
fun initialize() {
observeActiveSession()
}
private fun observeActiveSession() {
activeSessionDisposable = sessionDataSource.observe()
.distinctUntilChanged()
.subscribe {
it.orNull()?.let { session ->
onSessionActive(session)
}
}
}
private fun onSessionActive(session: Session) {
if (!autoAcceptInvites.isEnabled) {
return
}
if (disposables.containsKey(session.sessionId)) {
if (invitedRoomDisposables.containsKey(session.sessionId)) {
return
}
session.addListener(this)
@ -74,11 +97,15 @@ class InvitesAcceptor @Inject constructor(private val autoAcceptInvites: AutoAcc
}
}
.also {
disposables[session.sessionId] = it
invitedRoomDisposables[session.sessionId] = it
}
}
private suspend fun Session.joinRoomSafely(roomId: String) {
if (shouldRejectRoomIds.contains(roomId)) {
getRoom(roomId)?.rejectInviteSafely()
return
}
val roomMembershipChanged = getChangeMemberships(roomId)
if (roomMembershipChanged != ChangeMembershipState.Joined && !roomMembershipChanged.isInProgress()) {
try {
@ -86,12 +113,31 @@ class InvitesAcceptor @Inject constructor(private val autoAcceptInvites: AutoAcc
joinRoom(roomId)
} catch (failure: Throwable) {
Timber.v("Failed auto join room: $roomId")
// if we got 404 on invites, the inviting user have left or the hs is off.
if (failure is Failure.ServerError && failure.httpCode == 404) {
val room = getRoom(roomId) ?: return
val inviterId = room.roomSummary()?.inviterId
// if the inviting user is on the same HS, there can only be one cause: they left, so we try to reject the invite.
if (inviterId?.endsWith(sessionParams.credentials.homeServer.orEmpty()).orFalse()) {
shouldRejectRoomIds.add(roomId)
room.rejectInviteSafely()
}
}
}
}
}
private suspend fun Room.rejectInviteSafely() {
try {
leave(null)
shouldRejectRoomIds.remove(roomId)
} catch (failure: Throwable) {
Timber.v("Fail rejecting invite for room: $roomId")
}
}
override fun onSessionStopped(session: Session) {
session.removeListener(this)
disposables.remove(session.sessionId)?.dispose()
invitedRoomDisposables.remove(session.sessionId)?.dispose()
}
}