From 10f8aebde25b190ca2b74e50939c76cb0109fb73 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Fri, 3 Jul 2020 11:14:41 +0200 Subject: [PATCH 1/8] Update comment --- .../java/im/vector/matrix/android/api/MatrixConfiguration.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/MatrixConfiguration.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/MatrixConfiguration.kt index e7c24fadc8..d80a940675 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/MatrixConfiguration.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/MatrixConfiguration.kt @@ -33,7 +33,7 @@ data class MatrixConfiguration( ), /** * Optional proxy to connect to the matrix servers - * You can create one using for instance Proxy(proxyType, InetSocketAddress(hostname, port) + * You can create one using for instance Proxy(proxyType, InetSocketAddress.createUnresolved(hostname, port) */ val proxy: Proxy? = null ) { From 5f60d7fd3bf9ca683fe7875516763d72f0e18c44 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Fri, 3 Jul 2020 11:16:58 +0200 Subject: [PATCH 2/8] Session.configureAndStart now handle registering to webRtcPeerConnectionManager... --- vector/src/main/java/im/vector/riotx/VectorApplication.kt | 8 ++++++-- .../main/java/im/vector/riotx/core/extensions/Session.kt | 3 +++ .../java/im/vector/riotx/features/login/LoginViewModel.kt | 7 +++++-- 3 files changed, 14 insertions(+), 4 deletions(-) diff --git a/vector/src/main/java/im/vector/riotx/VectorApplication.kt b/vector/src/main/java/im/vector/riotx/VectorApplication.kt index ab7c3e1bf7..d49c7a4c7b 100644 --- a/vector/src/main/java/im/vector/riotx/VectorApplication.kt +++ b/vector/src/main/java/im/vector/riotx/VectorApplication.kt @@ -137,8 +137,12 @@ class VectorApplication : if (authenticationService.hasAuthenticatedSessions() && !activeSessionHolder.hasActiveSession()) { val lastAuthenticatedSession = authenticationService.getLastAuthenticatedSession()!! activeSessionHolder.setActiveSession(lastAuthenticatedSession) - lastAuthenticatedSession.configureAndStart(applicationContext, pushRuleTriggerListener, sessionListener) - lastAuthenticatedSession.callSignalingService().addCallListener(webRtcPeerConnectionManager) + lastAuthenticatedSession.configureAndStart( + applicationContext, + pushRuleTriggerListener, + webRtcPeerConnectionManager, + sessionListener + ) } ProcessLifecycleOwner.get().lifecycle.addObserver(object : LifecycleObserver { @OnLifecycleEvent(Lifecycle.Event.ON_RESUME) diff --git a/vector/src/main/java/im/vector/riotx/core/extensions/Session.kt b/vector/src/main/java/im/vector/riotx/core/extensions/Session.kt index 29b169ffd4..788ab01c4d 100644 --- a/vector/src/main/java/im/vector/riotx/core/extensions/Session.kt +++ b/vector/src/main/java/im/vector/riotx/core/extensions/Session.kt @@ -24,12 +24,14 @@ import im.vector.matrix.android.api.session.Session import im.vector.matrix.android.api.session.crypto.keysbackup.KeysBackupState import im.vector.matrix.android.api.session.sync.FilterService import im.vector.riotx.core.services.VectorSyncService +import im.vector.riotx.features.call.WebRtcPeerConnectionManager import im.vector.riotx.features.notifications.PushRuleTriggerListener import im.vector.riotx.features.session.SessionListener import timber.log.Timber fun Session.configureAndStart(context: Context, pushRuleTriggerListener: PushRuleTriggerListener, + webRtcPeerConnectionManager: WebRtcPeerConnectionManager, sessionListener: SessionListener) { open() addListener(sessionListener) @@ -38,6 +40,7 @@ fun Session.configureAndStart(context: Context, startSyncing(context) refreshPushers() pushRuleTriggerListener.startWithSession(this) + callSignalingService().addCallListener(webRtcPeerConnectionManager) } fun Session.startSyncing(context: Context) { diff --git a/vector/src/main/java/im/vector/riotx/features/login/LoginViewModel.kt b/vector/src/main/java/im/vector/riotx/features/login/LoginViewModel.kt index 7edc674b11..f85d91d9c5 100644 --- a/vector/src/main/java/im/vector/riotx/features/login/LoginViewModel.kt +++ b/vector/src/main/java/im/vector/riotx/features/login/LoginViewModel.kt @@ -667,8 +667,11 @@ class LoginViewModel @AssistedInject constructor( private fun onSessionCreated(session: Session) { activeSessionHolder.setActiveSession(session) - session.configureAndStart(applicationContext, pushRuleTriggerListener, sessionListener) - session.callSignalingService().addCallListener(webRtcPeerConnectionManager) + session.configureAndStart( + applicationContext, + pushRuleTriggerListener, + webRtcPeerConnectionManager, + sessionListener) setState { copy( asyncLoginAction = Success(Unit) From 6569ee5d109189513d3c19b1d5e8a57a1adbd332 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Fri, 3 Jul 2020 15:36:04 +0200 Subject: [PATCH 3/8] Use Set instead of List --- .../vector/matrix/android/internal/session/SessionListeners.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/SessionListeners.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/SessionListeners.kt index ff3bc0b073..83b90b16b9 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/SessionListeners.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/SessionListeners.kt @@ -22,7 +22,7 @@ import javax.inject.Inject internal class SessionListeners @Inject constructor() { - private val listeners = ArrayList() + private val listeners = mutableSetOf() fun addListener(listener: Session.Listener) { synchronized(listeners) { From 811cbb2e201318f1b964ac136e2e1fce05e33b05 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Fri, 3 Jul 2020 15:42:31 +0200 Subject: [PATCH 4/8] ActiveSessionHolder to more things related to other @Singleton, and especially some missing cleanup Such as calling `removeListener()` and `callSignalingService().removeCallListener()` `Session.configureAndStart()` do less thing now --- .../java/im/vector/riotx/VectorApplication.kt | 13 +---- .../riotx/core/di/ActiveSessionHolder.kt | 23 ++++++++- .../vector/riotx/core/extensions/Session.kt | 13 +---- .../im/vector/riotx/core/utils/DataSource.kt | 3 ++ .../call/WebRtcPeerConnectionManager.kt | 51 ++++++++++--------- .../timeline/format/NoticeEventFormatter.kt | 12 +++-- .../riotx/features/login/LoginViewModel.kt | 16 ++---- .../NotificationDrawerManager.kt | 15 ++++-- .../notifications/OutdatedEventDetector.kt | 10 ++-- .../notifications/PushRuleTriggerListener.kt | 8 +-- 10 files changed, 87 insertions(+), 77 deletions(-) diff --git a/vector/src/main/java/im/vector/riotx/VectorApplication.kt b/vector/src/main/java/im/vector/riotx/VectorApplication.kt index d49c7a4c7b..d7fe2a054d 100644 --- a/vector/src/main/java/im/vector/riotx/VectorApplication.kt +++ b/vector/src/main/java/im/vector/riotx/VectorApplication.kt @@ -44,15 +44,12 @@ import im.vector.riotx.core.di.HasVectorInjector import im.vector.riotx.core.di.VectorComponent import im.vector.riotx.core.extensions.configureAndStart import im.vector.riotx.core.rx.RxConfig -import im.vector.riotx.features.call.WebRtcPeerConnectionManager import im.vector.riotx.features.configuration.VectorConfiguration import im.vector.riotx.features.lifecycle.VectorActivityLifecycleCallbacks import im.vector.riotx.features.notifications.NotificationDrawerManager import im.vector.riotx.features.notifications.NotificationUtils -import im.vector.riotx.features.notifications.PushRuleTriggerListener import im.vector.riotx.features.popup.PopupAlertManager import im.vector.riotx.features.rageshake.VectorUncaughtExceptionHandler -import im.vector.riotx.features.session.SessionListener import im.vector.riotx.features.settings.VectorPreferences import im.vector.riotx.features.version.VersionProvider import im.vector.riotx.push.fcm.FcmHelper @@ -79,16 +76,13 @@ class VectorApplication : @Inject lateinit var emojiCompatWrapper: EmojiCompatWrapper @Inject lateinit var vectorUncaughtExceptionHandler: VectorUncaughtExceptionHandler @Inject lateinit var activeSessionHolder: ActiveSessionHolder - @Inject lateinit var sessionListener: SessionListener @Inject lateinit var notificationDrawerManager: NotificationDrawerManager - @Inject lateinit var pushRuleTriggerListener: PushRuleTriggerListener @Inject lateinit var vectorPreferences: VectorPreferences @Inject lateinit var versionProvider: VersionProvider @Inject lateinit var notificationUtils: NotificationUtils @Inject lateinit var appStateHandler: AppStateHandler @Inject lateinit var rxConfig: RxConfig @Inject lateinit var popupAlertManager: PopupAlertManager - @Inject lateinit var webRtcPeerConnectionManager: WebRtcPeerConnectionManager lateinit var vectorComponent: VectorComponent @@ -137,12 +131,7 @@ class VectorApplication : if (authenticationService.hasAuthenticatedSessions() && !activeSessionHolder.hasActiveSession()) { val lastAuthenticatedSession = authenticationService.getLastAuthenticatedSession()!! activeSessionHolder.setActiveSession(lastAuthenticatedSession) - lastAuthenticatedSession.configureAndStart( - applicationContext, - pushRuleTriggerListener, - webRtcPeerConnectionManager, - sessionListener - ) + lastAuthenticatedSession.configureAndStart(applicationContext) } ProcessLifecycleOwner.get().lifecycle.addObserver(object : LifecycleObserver { @OnLifecycleEvent(Lifecycle.Event.ON_RESUME) diff --git a/vector/src/main/java/im/vector/riotx/core/di/ActiveSessionHolder.kt b/vector/src/main/java/im/vector/riotx/core/di/ActiveSessionHolder.kt index ff9865c3ea..9fbd51984f 100644 --- a/vector/src/main/java/im/vector/riotx/core/di/ActiveSessionHolder.kt +++ b/vector/src/main/java/im/vector/riotx/core/di/ActiveSessionHolder.kt @@ -20,8 +20,12 @@ import arrow.core.Option import im.vector.matrix.android.api.auth.AuthenticationService import im.vector.matrix.android.api.session.Session import im.vector.riotx.ActiveSessionDataSource +import im.vector.riotx.features.call.WebRtcPeerConnectionManager import im.vector.riotx.features.crypto.keysrequest.KeyRequestHandler import im.vector.riotx.features.crypto.verification.IncomingVerificationRequestHandler +import im.vector.riotx.features.notifications.PushRuleTriggerListener +import im.vector.riotx.features.session.SessionListener +import timber.log.Timber import java.util.concurrent.atomic.AtomicReference import javax.inject.Inject import javax.inject.Singleton @@ -30,23 +34,40 @@ import javax.inject.Singleton class ActiveSessionHolder @Inject constructor(private val authenticationService: AuthenticationService, private val sessionObservableStore: ActiveSessionDataSource, private val keyRequestHandler: KeyRequestHandler, - private val incomingVerificationRequestHandler: IncomingVerificationRequestHandler + private val incomingVerificationRequestHandler: IncomingVerificationRequestHandler, + private val webRtcPeerConnectionManager: WebRtcPeerConnectionManager, + private val pushRuleTriggerListener: PushRuleTriggerListener, + private val sessionListener: SessionListener ) { private var activeSession: AtomicReference = AtomicReference() fun setActiveSession(session: Session) { + Timber.w("setActiveSession of ${session.myUserId}") activeSession.set(session) sessionObservableStore.post(Option.just(session)) + keyRequestHandler.start(session) incomingVerificationRequestHandler.start(session) + session.addListener(sessionListener) + pushRuleTriggerListener.startWithSession(session) + session.callSignalingService().addCallListener(webRtcPeerConnectionManager) } fun clearActiveSession() { + // Do some cleanup first + getSafeActiveSession()?.let { + Timber.w("clearActiveSession of ${it.myUserId}") + it.callSignalingService().removeCallListener(webRtcPeerConnectionManager) + it.removeListener(sessionListener) + } + activeSession.set(null) sessionObservableStore.post(Option.empty()) + keyRequestHandler.stop() incomingVerificationRequestHandler.stop() + pushRuleTriggerListener.stop() } fun hasActiveSession(): Boolean { diff --git a/vector/src/main/java/im/vector/riotx/core/extensions/Session.kt b/vector/src/main/java/im/vector/riotx/core/extensions/Session.kt index 788ab01c4d..d212380da4 100644 --- a/vector/src/main/java/im/vector/riotx/core/extensions/Session.kt +++ b/vector/src/main/java/im/vector/riotx/core/extensions/Session.kt @@ -24,23 +24,14 @@ import im.vector.matrix.android.api.session.Session import im.vector.matrix.android.api.session.crypto.keysbackup.KeysBackupState import im.vector.matrix.android.api.session.sync.FilterService import im.vector.riotx.core.services.VectorSyncService -import im.vector.riotx.features.call.WebRtcPeerConnectionManager -import im.vector.riotx.features.notifications.PushRuleTriggerListener -import im.vector.riotx.features.session.SessionListener import timber.log.Timber -fun Session.configureAndStart(context: Context, - pushRuleTriggerListener: PushRuleTriggerListener, - webRtcPeerConnectionManager: WebRtcPeerConnectionManager, - sessionListener: SessionListener) { +fun Session.configureAndStart(context: Context) { + Timber.i("Configure and start session for $myUserId") open() - addListener(sessionListener) setFilter(FilterService.FilterPreset.RiotFilter) - Timber.i("Configure and start session for ${this.myUserId}") startSyncing(context) refreshPushers() - pushRuleTriggerListener.startWithSession(this) - callSignalingService().addCallListener(webRtcPeerConnectionManager) } fun Session.startSyncing(context: Context) { diff --git a/vector/src/main/java/im/vector/riotx/core/utils/DataSource.kt b/vector/src/main/java/im/vector/riotx/core/utils/DataSource.kt index 4c4a553e5c..6f6057cb43 100644 --- a/vector/src/main/java/im/vector/riotx/core/utils/DataSource.kt +++ b/vector/src/main/java/im/vector/riotx/core/utils/DataSource.kt @@ -36,6 +36,9 @@ open class BehaviorDataSource(private val defaultValue: T? = null) : MutableD private val behaviorRelay = createRelay() + val currentValue: T? + get() = behaviorRelay.value + override fun observe(): Observable { return behaviorRelay.hide().observeOn(AndroidSchedulers.mainThread()) } diff --git a/vector/src/main/java/im/vector/riotx/features/call/WebRtcPeerConnectionManager.kt b/vector/src/main/java/im/vector/riotx/features/call/WebRtcPeerConnectionManager.kt index 05f14ae4f2..070375d201 100644 --- a/vector/src/main/java/im/vector/riotx/features/call/WebRtcPeerConnectionManager.kt +++ b/vector/src/main/java/im/vector/riotx/features/call/WebRtcPeerConnectionManager.kt @@ -22,6 +22,7 @@ import android.os.Build import androidx.annotation.RequiresApi import im.vector.matrix.android.api.MatrixCallback import im.vector.matrix.android.api.extensions.tryThis +import im.vector.matrix.android.api.session.Session import im.vector.matrix.android.api.session.call.CallState import im.vector.matrix.android.api.session.call.CallsListener import im.vector.matrix.android.api.session.call.EglUtils @@ -31,7 +32,7 @@ import im.vector.matrix.android.api.session.room.model.call.CallAnswerContent import im.vector.matrix.android.api.session.room.model.call.CallCandidatesContent import im.vector.matrix.android.api.session.room.model.call.CallHangupContent import im.vector.matrix.android.api.session.room.model.call.CallInviteContent -import im.vector.riotx.core.di.ActiveSessionHolder +import im.vector.riotx.ActiveSessionDataSource import im.vector.riotx.core.services.BluetoothHeadsetReceiver import im.vector.riotx.core.services.CallService import im.vector.riotx.core.services.WiredHeadsetStateReceiver @@ -71,9 +72,12 @@ import javax.inject.Singleton @Singleton class WebRtcPeerConnectionManager @Inject constructor( private val context: Context, - private val sessionHolder: ActiveSessionHolder + private val activeSessionDataSource: ActiveSessionDataSource ) : CallsListener { + private val currentSession: Session? + get() = activeSessionDataSource.currentValue?.orNull() + interface CurrentCallListener { fun onCurrentCallChange(call: MxCall?) fun onCaptureStateChanged(mgr: WebRtcPeerConnectionManager) {} @@ -288,15 +292,16 @@ class WebRtcPeerConnectionManager @Inject constructor( } private fun getTurnServer(callback: ((TurnServerResponse?) -> Unit)) { - sessionHolder.getActiveSession().callSignalingService().getTurnServer(object : MatrixCallback { - override fun onSuccess(data: TurnServerResponse?) { - callback(data) - } + currentSession?.callSignalingService() + ?.getTurnServer(object : MatrixCallback { + override fun onSuccess(data: TurnServerResponse?) { + callback(data) + } - override fun onFailure(failure: Throwable) { - callback(null) - } - }) + override fun onFailure(failure: Throwable) { + callback(null) + } + }) } fun attachViewRenderers(localViewRenderer: SurfaceViewRenderer?, remoteViewRenderer: SurfaceViewRenderer, mode: String?) { @@ -310,7 +315,7 @@ class WebRtcPeerConnectionManager @Inject constructor( currentCall?.mxCall ?.takeIf { it.state is CallState.Connected } ?.let { mxCall -> - val name = sessionHolder.getSafeActiveSession()?.getUser(mxCall.otherUserId)?.getBestName() + val name = currentSession?.getUser(mxCall.otherUserId)?.getBestName() ?: mxCall.roomId // Start background service with notification CallService.onPendingCall( @@ -318,7 +323,7 @@ class WebRtcPeerConnectionManager @Inject constructor( isVideo = mxCall.isVideoCall, roomName = name, roomId = mxCall.roomId, - matrixId = sessionHolder.getSafeActiveSession()?.myUserId ?: "", + matrixId = currentSession?.myUserId ?: "", callId = mxCall.callId) } @@ -373,14 +378,14 @@ class WebRtcPeerConnectionManager @Inject constructor( val mxCall = callContext.mxCall // Update service state - val name = sessionHolder.getSafeActiveSession()?.getUser(mxCall.otherUserId)?.getBestName() + val name = currentSession?.getUser(mxCall.otherUserId)?.getBestName() ?: mxCall.roomId CallService.onPendingCall( context = context, isVideo = mxCall.isVideoCall, roomName = name, roomId = mxCall.roomId, - matrixId = sessionHolder.getSafeActiveSession()?.myUserId ?: "", + matrixId = currentSession?.myUserId ?: "", callId = mxCall.callId ) executor.execute { @@ -563,14 +568,14 @@ class WebRtcPeerConnectionManager @Inject constructor( ?.let { mxCall -> // Start background service with notification - val name = sessionHolder.getSafeActiveSession()?.getUser(mxCall.otherUserId)?.getBestName() + val name = currentSession?.getUser(mxCall.otherUserId)?.getBestName() ?: mxCall.otherUserId CallService.onOnGoingCallBackground( context = context, isVideo = mxCall.isVideoCall, roomName = name, roomId = mxCall.roomId, - matrixId = sessionHolder.getSafeActiveSession()?.myUserId ?: "", + matrixId = currentSession?.myUserId ?: "", callId = mxCall.callId ) } @@ -631,20 +636,20 @@ class WebRtcPeerConnectionManager @Inject constructor( } Timber.v("## VOIP startOutgoingCall in room $signalingRoomId to $otherUserId isVideo $isVideoCall") - val createdCall = sessionHolder.getSafeActiveSession()?.callSignalingService()?.createOutgoingCall(signalingRoomId, otherUserId, isVideoCall) ?: return + val createdCall = currentSession?.callSignalingService()?.createOutgoingCall(signalingRoomId, otherUserId, isVideoCall) ?: return val callContext = CallContext(createdCall) audioManager.startForCall(createdCall) currentCall = callContext - val name = sessionHolder.getSafeActiveSession()?.getUser(createdCall.otherUserId)?.getBestName() + val name = currentSession?.getUser(createdCall.otherUserId)?.getBestName() ?: createdCall.otherUserId CallService.onOutgoingCallRinging( context = context.applicationContext, isVideo = createdCall.isVideoCall, roomName = name, roomId = createdCall.roomId, - matrixId = sessionHolder.getSafeActiveSession()?.myUserId ?: "", + matrixId = currentSession?.myUserId ?: "", callId = createdCall.callId) executor.execute { @@ -693,14 +698,14 @@ class WebRtcPeerConnectionManager @Inject constructor( } // Start background service with notification - val name = sessionHolder.getSafeActiveSession()?.getUser(mxCall.otherUserId)?.getBestName() + val name = currentSession?.getUser(mxCall.otherUserId)?.getBestName() ?: mxCall.otherUserId CallService.onIncomingCallRinging( context = context, isVideo = mxCall.isVideoCall, roomName = name, roomId = mxCall.roomId, - matrixId = sessionHolder.getSafeActiveSession()?.myUserId ?: "", + matrixId = currentSession?.myUserId ?: "", callId = mxCall.callId ) @@ -818,14 +823,14 @@ class WebRtcPeerConnectionManager @Inject constructor( } val mxCall = call.mxCall // Update service state - val name = sessionHolder.getSafeActiveSession()?.getUser(mxCall.otherUserId)?.getBestName() + val name = currentSession?.getUser(mxCall.otherUserId)?.getBestName() ?: mxCall.otherUserId CallService.onPendingCall( context = context, isVideo = mxCall.isVideoCall, roomName = name, roomId = mxCall.roomId, - matrixId = sessionHolder.getSafeActiveSession()?.myUserId ?: "", + matrixId = currentSession?.myUserId ?: "", callId = mxCall.callId ) executor.execute { diff --git a/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/format/NoticeEventFormatter.kt b/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/format/NoticeEventFormatter.kt index c1f4187e0b..655621f9ad 100644 --- a/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/format/NoticeEventFormatter.kt +++ b/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/format/NoticeEventFormatter.kt @@ -40,17 +40,20 @@ import im.vector.matrix.android.api.session.room.timeline.TimelineEvent import im.vector.matrix.android.api.session.widgets.model.WidgetContent import im.vector.matrix.android.internal.crypto.MXCRYPTO_ALGORITHM_MEGOLM import im.vector.matrix.android.internal.crypto.model.event.EncryptionEventContent +import im.vector.riotx.ActiveSessionDataSource import im.vector.riotx.R -import im.vector.riotx.core.di.ActiveSessionHolder import im.vector.riotx.core.resources.StringProvider import timber.log.Timber import javax.inject.Inject -class NoticeEventFormatter @Inject constructor(private val sessionHolder: ActiveSessionHolder, +class NoticeEventFormatter @Inject constructor(private val activeSessionDataSource: ActiveSessionDataSource, private val roomHistoryVisibilityFormatter: RoomHistoryVisibilityFormatter, private val sp: StringProvider) { - private fun Event.isSentByCurrentUser() = senderId != null && senderId == sessionHolder.getSafeActiveSession()?.myUserId + private val currentUserId: String? + get() = activeSessionDataSource.currentValue?.orNull()?.myUserId + + private fun Event.isSentByCurrentUser() = senderId != null && senderId == currentUserId fun format(timelineEvent: TimelineEvent): CharSequence? { return when (val type = timelineEvent.root.getClearType()) { @@ -449,7 +452,6 @@ class NoticeEventFormatter @Inject constructor(private val sessionHolder: Active val targetDisplayName = eventContent?.displayName ?: prevEventContent?.displayName ?: event.stateKey ?: "" return when (eventContent?.membership) { Membership.INVITE -> { - val selfUserId = sessionHolder.getSafeActiveSession()?.myUserId when { eventContent.thirdPartyInvite != null -> { val userWhoHasAccepted = eventContent.thirdPartyInvite?.signed?.mxid ?: event.stateKey @@ -466,7 +468,7 @@ class NoticeEventFormatter @Inject constructor(private val sessionHolder: Active sp.getString(R.string.notice_room_third_party_registered_invite, userWhoHasAccepted, threePidDisplayName) } } - event.stateKey == selfUserId -> + event.stateKey == currentUserId -> eventContent.safeReason?.let { reason -> sp.getString(R.string.notice_room_invite_you_with_reason, senderDisplayName, reason) } ?: sp.getString(R.string.notice_room_invite_you, senderDisplayName) diff --git a/vector/src/main/java/im/vector/riotx/features/login/LoginViewModel.kt b/vector/src/main/java/im/vector/riotx/features/login/LoginViewModel.kt index f85d91d9c5..071e23c252 100644 --- a/vector/src/main/java/im/vector/riotx/features/login/LoginViewModel.kt +++ b/vector/src/main/java/im/vector/riotx/features/login/LoginViewModel.kt @@ -49,9 +49,6 @@ import im.vector.riotx.core.extensions.exhaustive import im.vector.riotx.core.platform.VectorViewModel import im.vector.riotx.core.resources.StringProvider import im.vector.riotx.core.utils.ensureTrailingSlash -import im.vector.riotx.features.call.WebRtcPeerConnectionManager -import im.vector.riotx.features.notifications.PushRuleTriggerListener -import im.vector.riotx.features.session.SessionListener import im.vector.riotx.features.signout.soft.SoftLogoutActivity import timber.log.Timber import java.util.concurrent.CancellationException @@ -64,13 +61,10 @@ class LoginViewModel @AssistedInject constructor( private val applicationContext: Context, private val authenticationService: AuthenticationService, private val activeSessionHolder: ActiveSessionHolder, - private val pushRuleTriggerListener: PushRuleTriggerListener, private val homeServerConnectionConfigFactory: HomeServerConnectionConfigFactory, - private val sessionListener: SessionListener, private val reAuthHelper: ReAuthHelper, - private val stringProvider: StringProvider, - private val webRtcPeerConnectionManager: WebRtcPeerConnectionManager) - : VectorViewModel(initialState) { + private val stringProvider: StringProvider +) : VectorViewModel(initialState) { @AssistedInject.Factory interface Factory { @@ -667,11 +661,7 @@ class LoginViewModel @AssistedInject constructor( private fun onSessionCreated(session: Session) { activeSessionHolder.setActiveSession(session) - session.configureAndStart( - applicationContext, - pushRuleTriggerListener, - webRtcPeerConnectionManager, - sessionListener) + session.configureAndStart(applicationContext) setState { copy( asyncLoginAction = Success(Unit) diff --git a/vector/src/main/java/im/vector/riotx/features/notifications/NotificationDrawerManager.kt b/vector/src/main/java/im/vector/riotx/features/notifications/NotificationDrawerManager.kt index 6fc396b264..d0839795dd 100644 --- a/vector/src/main/java/im/vector/riotx/features/notifications/NotificationDrawerManager.kt +++ b/vector/src/main/java/im/vector/riotx/features/notifications/NotificationDrawerManager.kt @@ -22,10 +22,11 @@ import android.os.HandlerThread import androidx.annotation.WorkerThread import androidx.core.app.NotificationCompat import androidx.core.app.Person +import im.vector.matrix.android.api.session.Session import im.vector.matrix.android.api.session.content.ContentUrlResolver +import im.vector.riotx.ActiveSessionDataSource import im.vector.riotx.BuildConfig import im.vector.riotx.R -import im.vector.riotx.core.di.ActiveSessionHolder import im.vector.riotx.core.resources.StringProvider import im.vector.riotx.features.settings.VectorPreferences import me.gujun.android.span.span @@ -46,7 +47,7 @@ class NotificationDrawerManager @Inject constructor(private val context: Context private val notificationUtils: NotificationUtils, private val vectorPreferences: VectorPreferences, private val stringProvider: StringProvider, - private val activeSessionHolder: ActiveSessionHolder, + private val activeSessionDataSource: ActiveSessionDataSource, private val iconLoader: IconLoader, private val bitmapLoader: BitmapLoader, private val outdatedDetector: OutdatedEventDetector?) { @@ -68,6 +69,10 @@ class NotificationDrawerManager @Inject constructor(private val context: Context private var currentRoomId: String? = null + // TODO Multi-session: this will have to be improved + private val currentSession: Session? + get() = activeSessionDataSource.currentValue?.orNull() + /** Should be called as soon as a new event is ready to be displayed. The notification corresponding to this event will not be displayed until @@ -204,7 +209,7 @@ class NotificationDrawerManager @Inject constructor(private val context: Context private fun refreshNotificationDrawerBg() { Timber.v("refreshNotificationDrawerBg()") - val session = activeSessionHolder.getSafeActiveSession() ?: return + val session = currentSession ?: return val user = session.getUser(session.myUserId) // myUserDisplayName cannot be empty else NotificationCompat.MessagingStyle() will crash @@ -474,7 +479,7 @@ class NotificationDrawerManager @Inject constructor(private val context: Context val file = File(context.applicationContext.cacheDir, ROOMS_NOTIFICATIONS_FILE_NAME) if (!file.exists()) file.createNewFile() FileOutputStream(file).use { - activeSessionHolder.getSafeActiveSession()?.securelyStoreObject(eventList, KEY_ALIAS_SECRET_STORAGE, it) + currentSession?.securelyStoreObject(eventList, KEY_ALIAS_SECRET_STORAGE, it) } } catch (e: Throwable) { Timber.e(e, "## Failed to save cached notification info") @@ -487,7 +492,7 @@ class NotificationDrawerManager @Inject constructor(private val context: Context val file = File(context.applicationContext.cacheDir, ROOMS_NOTIFICATIONS_FILE_NAME) if (file.exists()) { FileInputStream(file).use { - val events: ArrayList? = activeSessionHolder.getSafeActiveSession()?.loadSecureSecret(it, KEY_ALIAS_SECRET_STORAGE) + val events: ArrayList? = currentSession?.loadSecureSecret(it, KEY_ALIAS_SECRET_STORAGE) if (events != null) { return events.toMutableList() } diff --git a/vector/src/main/java/im/vector/riotx/features/notifications/OutdatedEventDetector.kt b/vector/src/main/java/im/vector/riotx/features/notifications/OutdatedEventDetector.kt index 6b8d3dae49..d2b939bc99 100644 --- a/vector/src/main/java/im/vector/riotx/features/notifications/OutdatedEventDetector.kt +++ b/vector/src/main/java/im/vector/riotx/features/notifications/OutdatedEventDetector.kt @@ -15,10 +15,12 @@ */ package im.vector.riotx.features.notifications -import im.vector.riotx.core.di.ActiveSessionHolder +import im.vector.riotx.ActiveSessionDataSource import javax.inject.Inject -class OutdatedEventDetector @Inject constructor(private val activeSessionHolder: ActiveSessionHolder) { +class OutdatedEventDetector @Inject constructor( + private val activeSessionDataSource: ActiveSessionDataSource +) { /** * Returns true if the given event is outdated. @@ -26,10 +28,12 @@ class OutdatedEventDetector @Inject constructor(private val activeSessionHolder: * other device. */ fun isMessageOutdated(notifiableEvent: NotifiableEvent): Boolean { + val session = activeSessionDataSource.currentValue?.orNull() ?: return false + if (notifiableEvent is NotifiableMessageEvent) { val eventID = notifiableEvent.eventId val roomID = notifiableEvent.roomId - val room = activeSessionHolder.getSafeActiveSession()?.getRoom(roomID) ?: return false + val room = session.getRoom(roomID) ?: return false return room.isEventRead(eventID) } return false diff --git a/vector/src/main/java/im/vector/riotx/features/notifications/PushRuleTriggerListener.kt b/vector/src/main/java/im/vector/riotx/features/notifications/PushRuleTriggerListener.kt index 4ba89c02e2..adef246151 100644 --- a/vector/src/main/java/im/vector/riotx/features/notifications/PushRuleTriggerListener.kt +++ b/vector/src/main/java/im/vector/riotx/features/notifications/PushRuleTriggerListener.kt @@ -30,17 +30,17 @@ class PushRuleTriggerListener @Inject constructor( private val notificationDrawerManager: NotificationDrawerManager ) : PushRuleService.PushRuleListener { - var session: Session? = null + private var session: Session? = null override fun onMatchRule(event: Event, actions: List) { Timber.v("Push rule match for event ${event.eventId}") - if (session == null) { + val safeSession = session ?: return Unit.also { Timber.e("Called without active session") - return } + val notificationAction = actions.toNotificationAction() if (notificationAction.shouldNotify) { - val notifiableEvent = resolver.resolveEvent(event, session!!) + val notifiableEvent = resolver.resolveEvent(event, safeSession) if (notifiableEvent == null) { Timber.v("## Failed to resolve event") // TODO From 633548f190696507fc3ffdd27c380367c78827fc Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Fri, 3 Jul 2020 16:00:39 +0200 Subject: [PATCH 5/8] Create ImageManager to be able to (re-)configure the lib --- .../java/im/vector/riotx/VectorApplication.kt | 3 -- .../riotx/core/di/ActiveSessionHolder.kt | 4 ++- .../im/vector/riotx/core/di/ImageManager.kt | 35 +++++++++++++++++++ 3 files changed, 38 insertions(+), 4 deletions(-) create mode 100644 vector/src/main/java/im/vector/riotx/core/di/ImageManager.kt diff --git a/vector/src/main/java/im/vector/riotx/VectorApplication.kt b/vector/src/main/java/im/vector/riotx/VectorApplication.kt index d7fe2a054d..db14dba93d 100644 --- a/vector/src/main/java/im/vector/riotx/VectorApplication.kt +++ b/vector/src/main/java/im/vector/riotx/VectorApplication.kt @@ -32,8 +32,6 @@ import com.airbnb.epoxy.EpoxyAsyncUtil import com.airbnb.epoxy.EpoxyController import com.facebook.stetho.Stetho import com.gabrielittner.threetenbp.LazyThreeTen -import com.github.piasy.biv.BigImageViewer -import com.github.piasy.biv.loader.glide.GlideImageLoader import im.vector.matrix.android.api.Matrix import im.vector.matrix.android.api.MatrixConfiguration import im.vector.matrix.android.api.auth.AuthenticationService @@ -108,7 +106,6 @@ class VectorApplication : logInfo() LazyThreeTen.init(this) - BigImageViewer.initialize(GlideImageLoader.with(applicationContext)) EpoxyController.defaultDiffingHandler = EpoxyAsyncUtil.getAsyncBackgroundHandler() EpoxyController.defaultModelBuildingHandler = EpoxyAsyncUtil.getAsyncBackgroundHandler() registerActivityLifecycleCallbacks(VectorActivityLifecycleCallbacks(popupAlertManager)) diff --git a/vector/src/main/java/im/vector/riotx/core/di/ActiveSessionHolder.kt b/vector/src/main/java/im/vector/riotx/core/di/ActiveSessionHolder.kt index 9fbd51984f..2dc7b24ebf 100644 --- a/vector/src/main/java/im/vector/riotx/core/di/ActiveSessionHolder.kt +++ b/vector/src/main/java/im/vector/riotx/core/di/ActiveSessionHolder.kt @@ -37,7 +37,8 @@ class ActiveSessionHolder @Inject constructor(private val authenticationService: private val incomingVerificationRequestHandler: IncomingVerificationRequestHandler, private val webRtcPeerConnectionManager: WebRtcPeerConnectionManager, private val pushRuleTriggerListener: PushRuleTriggerListener, - private val sessionListener: SessionListener + private val sessionListener: SessionListener, + private val imageManager: ImageManager ) { private var activeSession: AtomicReference = AtomicReference() @@ -52,6 +53,7 @@ class ActiveSessionHolder @Inject constructor(private val authenticationService: session.addListener(sessionListener) pushRuleTriggerListener.startWithSession(session) session.callSignalingService().addCallListener(webRtcPeerConnectionManager) + imageManager.onSessionStarted(session) } fun clearActiveSession() { diff --git a/vector/src/main/java/im/vector/riotx/core/di/ImageManager.kt b/vector/src/main/java/im/vector/riotx/core/di/ImageManager.kt new file mode 100644 index 0000000000..7972ebb163 --- /dev/null +++ b/vector/src/main/java/im/vector/riotx/core/di/ImageManager.kt @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2020 New Vector Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package im.vector.riotx.core.di + +import android.content.Context +import com.github.piasy.biv.BigImageViewer +import com.github.piasy.biv.loader.glide.GlideImageLoader +import im.vector.matrix.android.api.session.Session +import javax.inject.Inject + +/** + * This class is used to configure the library we use for images + */ +class ImageManager @Inject constructor( + private val context: Context +) { + + fun onSessionStarted(session: Session) { + BigImageViewer.initialize(GlideImageLoader.with(context)) + } +} From eda29e3fefb9388cafd06374011ba54ad29e591a Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Fri, 3 Jul 2020 17:27:00 +0200 Subject: [PATCH 6/8] Add link for WebRTC --- docs/voip_signaling.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/voip_signaling.md b/docs/voip_signaling.md index c80cdd6b96..e055b4cd35 100644 --- a/docs/voip_signaling.md +++ b/docs/voip_signaling.md @@ -1,5 +1,6 @@ Useful links: - https://codelabs.developers.google.com/codelabs/webrtc-web/#0 +- http://webrtc.github.io/webrtc-org/native-code/android/ ╔════════════════════════════════════════════════╗ From f179fc523d8bcbfd4e0006379ed4fc1f5f8291eb Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Fri, 3 Jul 2020 18:35:59 +0200 Subject: [PATCH 7/8] Give configured OkHttpClient to Glide and BigImageViewer --- .../matrix/android/api/session/Session.kt | 8 ++++ .../internal/session/DefaultSession.kt | 12 +++++- .../im/vector/riotx/core/di/ImageManager.kt | 16 +++++++- .../im/vector/riotx/core/glide/FactoryUrl.kt | 38 +++++++++++++++++++ .../core/glide/VectorGlideModelLoader.kt | 2 +- 5 files changed, 71 insertions(+), 5 deletions(-) create mode 100644 vector/src/main/java/im/vector/riotx/core/glide/FactoryUrl.kt diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/Session.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/Session.kt index 5b0f24aed7..8d97dfc01b 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/Session.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/Session.kt @@ -47,6 +47,7 @@ import im.vector.matrix.android.api.session.terms.TermsService import im.vector.matrix.android.api.session.typing.TypingUsersTracker import im.vector.matrix.android.api.session.user.UserService import im.vector.matrix.android.api.session.widgets.WidgetService +import okhttp3.OkHttpClient /** * This interface defines interactions with a session. @@ -205,6 +206,13 @@ interface Session : */ fun removeListener(listener: Listener) + /** + * Will return a OkHttpClient which will manage pinned certificates and Proxy if configured. + * It will not add any access-token to the request. + * So it is exposed to let the app be able to download image with Glide or any other libraries which accept an OkHttp client. + */ + fun getOkHttpClient(): OkHttpClient + /** * A global session listener to get notified for some events. */ diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/DefaultSession.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/DefaultSession.kt index 83ba76d5b8..16179dd64a 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/DefaultSession.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/DefaultSession.kt @@ -52,6 +52,7 @@ import im.vector.matrix.android.internal.auth.SessionParamsStore import im.vector.matrix.android.internal.crypto.DefaultCryptoService import im.vector.matrix.android.internal.di.SessionDatabase import im.vector.matrix.android.internal.di.SessionId +import im.vector.matrix.android.internal.di.UnauthenticatedWithCertificate import im.vector.matrix.android.internal.di.WorkManagerProvider import im.vector.matrix.android.internal.session.identity.DefaultIdentityService import im.vector.matrix.android.internal.session.room.timeline.TimelineEventDecryptor @@ -64,6 +65,7 @@ import im.vector.matrix.android.internal.util.createUIHandler import io.realm.RealmConfiguration import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.launch +import okhttp3.OkHttpClient import org.greenrobot.eventbus.EventBus import org.greenrobot.eventbus.Subscribe import org.greenrobot.eventbus.ThreadMode @@ -113,8 +115,10 @@ internal class DefaultSession @Inject constructor( private val defaultIdentityService: DefaultIdentityService, private val integrationManagerService: IntegrationManagerService, private val taskExecutor: TaskExecutor, - private val callSignalingService: Lazy) - : Session, + private val callSignalingService: Lazy, + @UnauthenticatedWithCertificate + private val unauthenticatedWithCertificateOkHttpClient: Lazy +) : Session, RoomService by roomService.get(), RoomDirectoryService by roomDirectoryService.get(), GroupService by groupService.get(), @@ -255,6 +259,10 @@ internal class DefaultSession @Inject constructor( override fun callSignalingService(): CallSignalingService = callSignalingService.get() + override fun getOkHttpClient(): OkHttpClient { + return unauthenticatedWithCertificateOkHttpClient.get() + } + override fun addListener(listener: Session.Listener) { sessionListeners.addListener(listener) } diff --git a/vector/src/main/java/im/vector/riotx/core/di/ImageManager.kt b/vector/src/main/java/im/vector/riotx/core/di/ImageManager.kt index 7972ebb163..74a01e76ec 100644 --- a/vector/src/main/java/im/vector/riotx/core/di/ImageManager.kt +++ b/vector/src/main/java/im/vector/riotx/core/di/ImageManager.kt @@ -17,19 +17,31 @@ package im.vector.riotx.core.di import android.content.Context +import com.bumptech.glide.Glide +import com.bumptech.glide.load.model.GlideUrl import com.github.piasy.biv.BigImageViewer import com.github.piasy.biv.loader.glide.GlideImageLoader import im.vector.matrix.android.api.session.Session +import im.vector.riotx.ActiveSessionDataSource +import im.vector.riotx.core.glide.FactoryUrl +import java.io.InputStream import javax.inject.Inject /** * This class is used to configure the library we use for images */ class ImageManager @Inject constructor( - private val context: Context + private val context: Context, + private val activeSessionDataSource: ActiveSessionDataSource ) { fun onSessionStarted(session: Session) { - BigImageViewer.initialize(GlideImageLoader.with(context)) + // Do this call first + BigImageViewer.initialize(GlideImageLoader.with(context, session.getOkHttpClient())) + + val glide = Glide.get(context) + + // And this one. FIXME But are losing what BigImageViewer has done to add a Progress listener + glide.registry.replace(GlideUrl::class.java, InputStream::class.java, FactoryUrl(activeSessionDataSource)) } } diff --git a/vector/src/main/java/im/vector/riotx/core/glide/FactoryUrl.kt b/vector/src/main/java/im/vector/riotx/core/glide/FactoryUrl.kt new file mode 100644 index 0000000000..fc037894db --- /dev/null +++ b/vector/src/main/java/im/vector/riotx/core/glide/FactoryUrl.kt @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2020 New Vector Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package im.vector.riotx.core.glide + +import com.bumptech.glide.integration.okhttp3.OkHttpUrlLoader +import com.bumptech.glide.load.model.GlideUrl +import com.bumptech.glide.load.model.ModelLoader +import com.bumptech.glide.load.model.ModelLoaderFactory +import com.bumptech.glide.load.model.MultiModelLoaderFactory +import im.vector.riotx.ActiveSessionDataSource +import okhttp3.OkHttpClient +import java.io.InputStream + +class FactoryUrl(private val activeSessionDataSource: ActiveSessionDataSource) : ModelLoaderFactory { + + override fun build(multiFactory: MultiModelLoaderFactory): ModelLoader { + val client = activeSessionDataSource.currentValue?.orNull()?.getOkHttpClient() ?: OkHttpClient() + return OkHttpUrlLoader(client) + } + + override fun teardown() { + // Do nothing, this instance doesn't own the client. + } +} diff --git a/vector/src/main/java/im/vector/riotx/core/glide/VectorGlideModelLoader.kt b/vector/src/main/java/im/vector/riotx/core/glide/VectorGlideModelLoader.kt index 191ab6d972..510eef71e1 100644 --- a/vector/src/main/java/im/vector/riotx/core/glide/VectorGlideModelLoader.kt +++ b/vector/src/main/java/im/vector/riotx/core/glide/VectorGlideModelLoader.kt @@ -65,7 +65,7 @@ class VectorGlideDataFetcher(private val activeSessionHolder: ActiveSessionHolde private val height: Int) : DataFetcher { - val client = OkHttpClient() + private val client = activeSessionHolder.getSafeActiveSession()?.getOkHttpClient() ?: OkHttpClient() override fun getDataClass(): Class { return InputStream::class.java From d63f00851a26a88b7b6cced6aeb4b4ee94ee587b Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Fri, 3 Jul 2020 21:17:47 +0200 Subject: [PATCH 8/8] Rename parameters --- .../vector/riotx/features/home/AvatarRenderer.kt | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/vector/src/main/java/im/vector/riotx/features/home/AvatarRenderer.kt b/vector/src/main/java/im/vector/riotx/features/home/AvatarRenderer.kt index 687c280910..f917b5a9f9 100644 --- a/vector/src/main/java/im/vector/riotx/features/home/AvatarRenderer.kt +++ b/vector/src/main/java/im/vector/riotx/features/home/AvatarRenderer.kt @@ -65,19 +65,19 @@ class AvatarRenderer @Inject constructor(private val activeSessionHolder: Active @UiThread fun render(context: Context, - glideRequest: GlideRequests, + glideRequests: GlideRequests, matrixItem: MatrixItem, target: Target) { val placeholder = getPlaceholderDrawable(context, matrixItem) - buildGlideRequest(glideRequest, matrixItem.avatarUrl) + buildGlideRequest(glideRequests, matrixItem.avatarUrl) .placeholder(placeholder) .into(target) } @AnyThread @Throws - fun shortcutDrawable(context: Context, glideRequest: GlideRequests, matrixItem: MatrixItem, iconSize: Int): Bitmap { - return glideRequest + fun shortcutDrawable(context: Context, glideRequests: GlideRequests, matrixItem: MatrixItem, iconSize: Int): Bitmap { + return glideRequests .asBitmap() .apply { val resolvedUrl = resolvedUrl(matrixItem.avatarUrl) @@ -98,8 +98,8 @@ class AvatarRenderer @Inject constructor(private val activeSessionHolder: Active } @AnyThread - fun getCachedDrawable(glideRequest: GlideRequests, matrixItem: MatrixItem): Drawable { - return buildGlideRequest(glideRequest, matrixItem.avatarUrl) + fun getCachedDrawable(glideRequests: GlideRequests, matrixItem: MatrixItem): Drawable { + return buildGlideRequest(glideRequests, matrixItem.avatarUrl) .onlyRetrieveFromCache(true) .submit() .get() @@ -117,9 +117,9 @@ class AvatarRenderer @Inject constructor(private val activeSessionHolder: Active // PRIVATE API ********************************************************************************* - private fun buildGlideRequest(glideRequest: GlideRequests, avatarUrl: String?): GlideRequest { + private fun buildGlideRequest(glideRequests: GlideRequests, avatarUrl: String?): GlideRequest { val resolvedUrl = resolvedUrl(avatarUrl) - return glideRequest + return glideRequests .load(resolvedUrl) .apply(RequestOptions.circleCropTransform()) }