mirror of
https://github.com/vector-im/element-android.git
synced 2024-11-15 01:35:07 +08:00
Merge pull request #1611 from vector-im/feature/okhttp_for_glide
Feature/okhttp for glide
This commit is contained in:
commit
4741169cc7
@ -1,5 +1,6 @@
|
||||
Useful links:
|
||||
- https://codelabs.developers.google.com/codelabs/webrtc-web/#0
|
||||
- http://webrtc.github.io/webrtc-org/native-code/android/
|
||||
|
||||
|
||||
╔════════════════════════════════════════════════╗
|
||||
|
@ -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
|
||||
) {
|
||||
|
@ -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.
|
||||
*/
|
||||
|
@ -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<CallSignalingService>)
|
||||
: Session,
|
||||
private val callSignalingService: Lazy<CallSignalingService>,
|
||||
@UnauthenticatedWithCertificate
|
||||
private val unauthenticatedWithCertificateOkHttpClient: Lazy<OkHttpClient>
|
||||
) : 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)
|
||||
}
|
||||
|
@ -22,7 +22,7 @@ import javax.inject.Inject
|
||||
|
||||
internal class SessionListeners @Inject constructor() {
|
||||
|
||||
private val listeners = ArrayList<Session.Listener>()
|
||||
private val listeners = mutableSetOf<Session.Listener>()
|
||||
|
||||
fun addListener(listener: Session.Listener) {
|
||||
synchronized(listeners) {
|
||||
|
@ -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
|
||||
@ -44,15 +42,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 +74,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
|
||||
|
||||
@ -114,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))
|
||||
@ -137,8 +128,7 @@ 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)
|
||||
}
|
||||
ProcessLifecycleOwner.get().lifecycle.addObserver(object : LifecycleObserver {
|
||||
@OnLifecycleEvent(Lifecycle.Event.ON_RESUME)
|
||||
|
@ -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,42 @@ 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 val imageManager: ImageManager
|
||||
) {
|
||||
|
||||
private var activeSession: AtomicReference<Session?> = 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)
|
||||
imageManager.onSessionStarted(session)
|
||||
}
|
||||
|
||||
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 {
|
||||
|
47
vector/src/main/java/im/vector/riotx/core/di/ImageManager.kt
Normal file
47
vector/src/main/java/im/vector/riotx/core/di/ImageManager.kt
Normal file
@ -0,0 +1,47 @@
|
||||
/*
|
||||
* 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.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 activeSessionDataSource: ActiveSessionDataSource
|
||||
) {
|
||||
|
||||
fun onSessionStarted(session: Session) {
|
||||
// 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))
|
||||
}
|
||||
}
|
@ -24,20 +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.notifications.PushRuleTriggerListener
|
||||
import im.vector.riotx.features.session.SessionListener
|
||||
import timber.log.Timber
|
||||
|
||||
fun Session.configureAndStart(context: Context,
|
||||
pushRuleTriggerListener: PushRuleTriggerListener,
|
||||
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)
|
||||
}
|
||||
|
||||
fun Session.startSyncing(context: Context) {
|
||||
|
@ -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<GlideUrl, InputStream> {
|
||||
|
||||
override fun build(multiFactory: MultiModelLoaderFactory): ModelLoader<GlideUrl, InputStream> {
|
||||
val client = activeSessionDataSource.currentValue?.orNull()?.getOkHttpClient() ?: OkHttpClient()
|
||||
return OkHttpUrlLoader(client)
|
||||
}
|
||||
|
||||
override fun teardown() {
|
||||
// Do nothing, this instance doesn't own the client.
|
||||
}
|
||||
}
|
@ -65,7 +65,7 @@ class VectorGlideDataFetcher(private val activeSessionHolder: ActiveSessionHolde
|
||||
private val height: Int)
|
||||
: DataFetcher<InputStream> {
|
||||
|
||||
val client = OkHttpClient()
|
||||
private val client = activeSessionHolder.getSafeActiveSession()?.getOkHttpClient() ?: OkHttpClient()
|
||||
|
||||
override fun getDataClass(): Class<InputStream> {
|
||||
return InputStream::class.java
|
||||
|
@ -36,6 +36,9 @@ open class BehaviorDataSource<T>(private val defaultValue: T? = null) : MutableD
|
||||
|
||||
private val behaviorRelay = createRelay()
|
||||
|
||||
val currentValue: T?
|
||||
get() = behaviorRelay.value
|
||||
|
||||
override fun observe(): Observable<T> {
|
||||
return behaviorRelay.hide().observeOn(AndroidSchedulers.mainThread())
|
||||
}
|
||||
|
@ -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<TurnServerResponse?> {
|
||||
override fun onSuccess(data: TurnServerResponse?) {
|
||||
callback(data)
|
||||
}
|
||||
currentSession?.callSignalingService()
|
||||
?.getTurnServer(object : MatrixCallback<TurnServerResponse?> {
|
||||
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 {
|
||||
|
@ -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<Drawable>) {
|
||||
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<Drawable> {
|
||||
private fun buildGlideRequest(glideRequests: GlideRequests, avatarUrl: String?): GlideRequest<Drawable> {
|
||||
val resolvedUrl = resolvedUrl(avatarUrl)
|
||||
return glideRequest
|
||||
return glideRequests
|
||||
.load(resolvedUrl)
|
||||
.apply(RequestOptions.circleCropTransform())
|
||||
}
|
||||
|
@ -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)
|
||||
|
@ -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<LoginViewState, LoginAction, LoginViewEvents>(initialState) {
|
||||
private val stringProvider: StringProvider
|
||||
) : VectorViewModel<LoginViewState, LoginAction, LoginViewEvents>(initialState) {
|
||||
|
||||
@AssistedInject.Factory
|
||||
interface Factory {
|
||||
@ -667,8 +661,7 @@ class LoginViewModel @AssistedInject constructor(
|
||||
|
||||
private fun onSessionCreated(session: Session) {
|
||||
activeSessionHolder.setActiveSession(session)
|
||||
session.configureAndStart(applicationContext, pushRuleTriggerListener, sessionListener)
|
||||
session.callSignalingService().addCallListener(webRtcPeerConnectionManager)
|
||||
session.configureAndStart(applicationContext)
|
||||
setState {
|
||||
copy(
|
||||
asyncLoginAction = Success(Unit)
|
||||
|
@ -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<NotifiableEvent>? = activeSessionHolder.getSafeActiveSession()?.loadSecureSecret(it, KEY_ALIAS_SECRET_STORAGE)
|
||||
val events: ArrayList<NotifiableEvent>? = currentSession?.loadSecureSecret(it, KEY_ALIAS_SECRET_STORAGE)
|
||||
if (events != null) {
|
||||
return events.toMutableList()
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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<Action>) {
|
||||
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
|
||||
|
Loading…
Reference in New Issue
Block a user