mirror of
https://github.com/SchildiChat/SchildiChat-android.git
synced 2024-11-29 06:28:45 +03:00
Merge pull request #1611 from vector-im/feature/okhttp_for_glide
Feature/okhttp for glide
This commit is contained in:
commit
4741169cc7
19 changed files with 204 additions and 83 deletions
|
@ -1,5 +1,6 @@
|
||||||
Useful links:
|
Useful links:
|
||||||
- https://codelabs.developers.google.com/codelabs/webrtc-web/#0
|
- 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
|
* 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
|
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.typing.TypingUsersTracker
|
||||||
import im.vector.matrix.android.api.session.user.UserService
|
import im.vector.matrix.android.api.session.user.UserService
|
||||||
import im.vector.matrix.android.api.session.widgets.WidgetService
|
import im.vector.matrix.android.api.session.widgets.WidgetService
|
||||||
|
import okhttp3.OkHttpClient
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This interface defines interactions with a session.
|
* This interface defines interactions with a session.
|
||||||
|
@ -205,6 +206,13 @@ interface Session :
|
||||||
*/
|
*/
|
||||||
fun removeListener(listener: Listener)
|
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.
|
* 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.crypto.DefaultCryptoService
|
||||||
import im.vector.matrix.android.internal.di.SessionDatabase
|
import im.vector.matrix.android.internal.di.SessionDatabase
|
||||||
import im.vector.matrix.android.internal.di.SessionId
|
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.di.WorkManagerProvider
|
||||||
import im.vector.matrix.android.internal.session.identity.DefaultIdentityService
|
import im.vector.matrix.android.internal.session.identity.DefaultIdentityService
|
||||||
import im.vector.matrix.android.internal.session.room.timeline.TimelineEventDecryptor
|
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 io.realm.RealmConfiguration
|
||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
|
import okhttp3.OkHttpClient
|
||||||
import org.greenrobot.eventbus.EventBus
|
import org.greenrobot.eventbus.EventBus
|
||||||
import org.greenrobot.eventbus.Subscribe
|
import org.greenrobot.eventbus.Subscribe
|
||||||
import org.greenrobot.eventbus.ThreadMode
|
import org.greenrobot.eventbus.ThreadMode
|
||||||
|
@ -113,8 +115,10 @@ internal class DefaultSession @Inject constructor(
|
||||||
private val defaultIdentityService: DefaultIdentityService,
|
private val defaultIdentityService: DefaultIdentityService,
|
||||||
private val integrationManagerService: IntegrationManagerService,
|
private val integrationManagerService: IntegrationManagerService,
|
||||||
private val taskExecutor: TaskExecutor,
|
private val taskExecutor: TaskExecutor,
|
||||||
private val callSignalingService: Lazy<CallSignalingService>)
|
private val callSignalingService: Lazy<CallSignalingService>,
|
||||||
: Session,
|
@UnauthenticatedWithCertificate
|
||||||
|
private val unauthenticatedWithCertificateOkHttpClient: Lazy<OkHttpClient>
|
||||||
|
) : Session,
|
||||||
RoomService by roomService.get(),
|
RoomService by roomService.get(),
|
||||||
RoomDirectoryService by roomDirectoryService.get(),
|
RoomDirectoryService by roomDirectoryService.get(),
|
||||||
GroupService by groupService.get(),
|
GroupService by groupService.get(),
|
||||||
|
@ -255,6 +259,10 @@ internal class DefaultSession @Inject constructor(
|
||||||
|
|
||||||
override fun callSignalingService(): CallSignalingService = callSignalingService.get()
|
override fun callSignalingService(): CallSignalingService = callSignalingService.get()
|
||||||
|
|
||||||
|
override fun getOkHttpClient(): OkHttpClient {
|
||||||
|
return unauthenticatedWithCertificateOkHttpClient.get()
|
||||||
|
}
|
||||||
|
|
||||||
override fun addListener(listener: Session.Listener) {
|
override fun addListener(listener: Session.Listener) {
|
||||||
sessionListeners.addListener(listener)
|
sessionListeners.addListener(listener)
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,7 +22,7 @@ import javax.inject.Inject
|
||||||
|
|
||||||
internal class SessionListeners @Inject constructor() {
|
internal class SessionListeners @Inject constructor() {
|
||||||
|
|
||||||
private val listeners = ArrayList<Session.Listener>()
|
private val listeners = mutableSetOf<Session.Listener>()
|
||||||
|
|
||||||
fun addListener(listener: Session.Listener) {
|
fun addListener(listener: Session.Listener) {
|
||||||
synchronized(listeners) {
|
synchronized(listeners) {
|
||||||
|
|
|
@ -32,8 +32,6 @@ import com.airbnb.epoxy.EpoxyAsyncUtil
|
||||||
import com.airbnb.epoxy.EpoxyController
|
import com.airbnb.epoxy.EpoxyController
|
||||||
import com.facebook.stetho.Stetho
|
import com.facebook.stetho.Stetho
|
||||||
import com.gabrielittner.threetenbp.LazyThreeTen
|
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.Matrix
|
||||||
import im.vector.matrix.android.api.MatrixConfiguration
|
import im.vector.matrix.android.api.MatrixConfiguration
|
||||||
import im.vector.matrix.android.api.auth.AuthenticationService
|
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.di.VectorComponent
|
||||||
import im.vector.riotx.core.extensions.configureAndStart
|
import im.vector.riotx.core.extensions.configureAndStart
|
||||||
import im.vector.riotx.core.rx.RxConfig
|
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.configuration.VectorConfiguration
|
||||||
import im.vector.riotx.features.lifecycle.VectorActivityLifecycleCallbacks
|
import im.vector.riotx.features.lifecycle.VectorActivityLifecycleCallbacks
|
||||||
import im.vector.riotx.features.notifications.NotificationDrawerManager
|
import im.vector.riotx.features.notifications.NotificationDrawerManager
|
||||||
import im.vector.riotx.features.notifications.NotificationUtils
|
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.popup.PopupAlertManager
|
||||||
import im.vector.riotx.features.rageshake.VectorUncaughtExceptionHandler
|
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.settings.VectorPreferences
|
||||||
import im.vector.riotx.features.version.VersionProvider
|
import im.vector.riotx.features.version.VersionProvider
|
||||||
import im.vector.riotx.push.fcm.FcmHelper
|
import im.vector.riotx.push.fcm.FcmHelper
|
||||||
|
@ -79,16 +74,13 @@ class VectorApplication :
|
||||||
@Inject lateinit var emojiCompatWrapper: EmojiCompatWrapper
|
@Inject lateinit var emojiCompatWrapper: EmojiCompatWrapper
|
||||||
@Inject lateinit var vectorUncaughtExceptionHandler: VectorUncaughtExceptionHandler
|
@Inject lateinit var vectorUncaughtExceptionHandler: VectorUncaughtExceptionHandler
|
||||||
@Inject lateinit var activeSessionHolder: ActiveSessionHolder
|
@Inject lateinit var activeSessionHolder: ActiveSessionHolder
|
||||||
@Inject lateinit var sessionListener: SessionListener
|
|
||||||
@Inject lateinit var notificationDrawerManager: NotificationDrawerManager
|
@Inject lateinit var notificationDrawerManager: NotificationDrawerManager
|
||||||
@Inject lateinit var pushRuleTriggerListener: PushRuleTriggerListener
|
|
||||||
@Inject lateinit var vectorPreferences: VectorPreferences
|
@Inject lateinit var vectorPreferences: VectorPreferences
|
||||||
@Inject lateinit var versionProvider: VersionProvider
|
@Inject lateinit var versionProvider: VersionProvider
|
||||||
@Inject lateinit var notificationUtils: NotificationUtils
|
@Inject lateinit var notificationUtils: NotificationUtils
|
||||||
@Inject lateinit var appStateHandler: AppStateHandler
|
@Inject lateinit var appStateHandler: AppStateHandler
|
||||||
@Inject lateinit var rxConfig: RxConfig
|
@Inject lateinit var rxConfig: RxConfig
|
||||||
@Inject lateinit var popupAlertManager: PopupAlertManager
|
@Inject lateinit var popupAlertManager: PopupAlertManager
|
||||||
@Inject lateinit var webRtcPeerConnectionManager: WebRtcPeerConnectionManager
|
|
||||||
|
|
||||||
lateinit var vectorComponent: VectorComponent
|
lateinit var vectorComponent: VectorComponent
|
||||||
|
|
||||||
|
@ -114,7 +106,6 @@ class VectorApplication :
|
||||||
logInfo()
|
logInfo()
|
||||||
LazyThreeTen.init(this)
|
LazyThreeTen.init(this)
|
||||||
|
|
||||||
BigImageViewer.initialize(GlideImageLoader.with(applicationContext))
|
|
||||||
EpoxyController.defaultDiffingHandler = EpoxyAsyncUtil.getAsyncBackgroundHandler()
|
EpoxyController.defaultDiffingHandler = EpoxyAsyncUtil.getAsyncBackgroundHandler()
|
||||||
EpoxyController.defaultModelBuildingHandler = EpoxyAsyncUtil.getAsyncBackgroundHandler()
|
EpoxyController.defaultModelBuildingHandler = EpoxyAsyncUtil.getAsyncBackgroundHandler()
|
||||||
registerActivityLifecycleCallbacks(VectorActivityLifecycleCallbacks(popupAlertManager))
|
registerActivityLifecycleCallbacks(VectorActivityLifecycleCallbacks(popupAlertManager))
|
||||||
|
@ -137,8 +128,7 @@ class VectorApplication :
|
||||||
if (authenticationService.hasAuthenticatedSessions() && !activeSessionHolder.hasActiveSession()) {
|
if (authenticationService.hasAuthenticatedSessions() && !activeSessionHolder.hasActiveSession()) {
|
||||||
val lastAuthenticatedSession = authenticationService.getLastAuthenticatedSession()!!
|
val lastAuthenticatedSession = authenticationService.getLastAuthenticatedSession()!!
|
||||||
activeSessionHolder.setActiveSession(lastAuthenticatedSession)
|
activeSessionHolder.setActiveSession(lastAuthenticatedSession)
|
||||||
lastAuthenticatedSession.configureAndStart(applicationContext, pushRuleTriggerListener, sessionListener)
|
lastAuthenticatedSession.configureAndStart(applicationContext)
|
||||||
lastAuthenticatedSession.callSignalingService().addCallListener(webRtcPeerConnectionManager)
|
|
||||||
}
|
}
|
||||||
ProcessLifecycleOwner.get().lifecycle.addObserver(object : LifecycleObserver {
|
ProcessLifecycleOwner.get().lifecycle.addObserver(object : LifecycleObserver {
|
||||||
@OnLifecycleEvent(Lifecycle.Event.ON_RESUME)
|
@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.auth.AuthenticationService
|
||||||
import im.vector.matrix.android.api.session.Session
|
import im.vector.matrix.android.api.session.Session
|
||||||
import im.vector.riotx.ActiveSessionDataSource
|
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.keysrequest.KeyRequestHandler
|
||||||
import im.vector.riotx.features.crypto.verification.IncomingVerificationRequestHandler
|
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 java.util.concurrent.atomic.AtomicReference
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
import javax.inject.Singleton
|
import javax.inject.Singleton
|
||||||
|
@ -30,23 +34,42 @@ import javax.inject.Singleton
|
||||||
class ActiveSessionHolder @Inject constructor(private val authenticationService: AuthenticationService,
|
class ActiveSessionHolder @Inject constructor(private val authenticationService: AuthenticationService,
|
||||||
private val sessionObservableStore: ActiveSessionDataSource,
|
private val sessionObservableStore: ActiveSessionDataSource,
|
||||||
private val keyRequestHandler: KeyRequestHandler,
|
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()
|
private var activeSession: AtomicReference<Session?> = AtomicReference()
|
||||||
|
|
||||||
fun setActiveSession(session: Session) {
|
fun setActiveSession(session: Session) {
|
||||||
|
Timber.w("setActiveSession of ${session.myUserId}")
|
||||||
activeSession.set(session)
|
activeSession.set(session)
|
||||||
sessionObservableStore.post(Option.just(session))
|
sessionObservableStore.post(Option.just(session))
|
||||||
|
|
||||||
keyRequestHandler.start(session)
|
keyRequestHandler.start(session)
|
||||||
incomingVerificationRequestHandler.start(session)
|
incomingVerificationRequestHandler.start(session)
|
||||||
|
session.addListener(sessionListener)
|
||||||
|
pushRuleTriggerListener.startWithSession(session)
|
||||||
|
session.callSignalingService().addCallListener(webRtcPeerConnectionManager)
|
||||||
|
imageManager.onSessionStarted(session)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun clearActiveSession() {
|
fun clearActiveSession() {
|
||||||
|
// Do some cleanup first
|
||||||
|
getSafeActiveSession()?.let {
|
||||||
|
Timber.w("clearActiveSession of ${it.myUserId}")
|
||||||
|
it.callSignalingService().removeCallListener(webRtcPeerConnectionManager)
|
||||||
|
it.removeListener(sessionListener)
|
||||||
|
}
|
||||||
|
|
||||||
activeSession.set(null)
|
activeSession.set(null)
|
||||||
sessionObservableStore.post(Option.empty())
|
sessionObservableStore.post(Option.empty())
|
||||||
|
|
||||||
keyRequestHandler.stop()
|
keyRequestHandler.stop()
|
||||||
incomingVerificationRequestHandler.stop()
|
incomingVerificationRequestHandler.stop()
|
||||||
|
pushRuleTriggerListener.stop()
|
||||||
}
|
}
|
||||||
|
|
||||||
fun hasActiveSession(): Boolean {
|
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.crypto.keysbackup.KeysBackupState
|
||||||
import im.vector.matrix.android.api.session.sync.FilterService
|
import im.vector.matrix.android.api.session.sync.FilterService
|
||||||
import im.vector.riotx.core.services.VectorSyncService
|
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
|
import timber.log.Timber
|
||||||
|
|
||||||
fun Session.configureAndStart(context: Context,
|
fun Session.configureAndStart(context: Context) {
|
||||||
pushRuleTriggerListener: PushRuleTriggerListener,
|
Timber.i("Configure and start session for $myUserId")
|
||||||
sessionListener: SessionListener) {
|
|
||||||
open()
|
open()
|
||||||
addListener(sessionListener)
|
|
||||||
setFilter(FilterService.FilterPreset.RiotFilter)
|
setFilter(FilterService.FilterPreset.RiotFilter)
|
||||||
Timber.i("Configure and start session for ${this.myUserId}")
|
|
||||||
startSyncing(context)
|
startSyncing(context)
|
||||||
refreshPushers()
|
refreshPushers()
|
||||||
pushRuleTriggerListener.startWithSession(this)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fun Session.startSyncing(context: Context) {
|
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)
|
private val height: Int)
|
||||||
: DataFetcher<InputStream> {
|
: DataFetcher<InputStream> {
|
||||||
|
|
||||||
val client = OkHttpClient()
|
private val client = activeSessionHolder.getSafeActiveSession()?.getOkHttpClient() ?: OkHttpClient()
|
||||||
|
|
||||||
override fun getDataClass(): Class<InputStream> {
|
override fun getDataClass(): Class<InputStream> {
|
||||||
return InputStream::class.java
|
return InputStream::class.java
|
||||||
|
|
|
@ -36,6 +36,9 @@ open class BehaviorDataSource<T>(private val defaultValue: T? = null) : MutableD
|
||||||
|
|
||||||
private val behaviorRelay = createRelay()
|
private val behaviorRelay = createRelay()
|
||||||
|
|
||||||
|
val currentValue: T?
|
||||||
|
get() = behaviorRelay.value
|
||||||
|
|
||||||
override fun observe(): Observable<T> {
|
override fun observe(): Observable<T> {
|
||||||
return behaviorRelay.hide().observeOn(AndroidSchedulers.mainThread())
|
return behaviorRelay.hide().observeOn(AndroidSchedulers.mainThread())
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,6 +22,7 @@ import android.os.Build
|
||||||
import androidx.annotation.RequiresApi
|
import androidx.annotation.RequiresApi
|
||||||
import im.vector.matrix.android.api.MatrixCallback
|
import im.vector.matrix.android.api.MatrixCallback
|
||||||
import im.vector.matrix.android.api.extensions.tryThis
|
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.CallState
|
||||||
import im.vector.matrix.android.api.session.call.CallsListener
|
import im.vector.matrix.android.api.session.call.CallsListener
|
||||||
import im.vector.matrix.android.api.session.call.EglUtils
|
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.CallCandidatesContent
|
||||||
import im.vector.matrix.android.api.session.room.model.call.CallHangupContent
|
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.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.BluetoothHeadsetReceiver
|
||||||
import im.vector.riotx.core.services.CallService
|
import im.vector.riotx.core.services.CallService
|
||||||
import im.vector.riotx.core.services.WiredHeadsetStateReceiver
|
import im.vector.riotx.core.services.WiredHeadsetStateReceiver
|
||||||
|
@ -71,9 +72,12 @@ import javax.inject.Singleton
|
||||||
@Singleton
|
@Singleton
|
||||||
class WebRtcPeerConnectionManager @Inject constructor(
|
class WebRtcPeerConnectionManager @Inject constructor(
|
||||||
private val context: Context,
|
private val context: Context,
|
||||||
private val sessionHolder: ActiveSessionHolder
|
private val activeSessionDataSource: ActiveSessionDataSource
|
||||||
) : CallsListener {
|
) : CallsListener {
|
||||||
|
|
||||||
|
private val currentSession: Session?
|
||||||
|
get() = activeSessionDataSource.currentValue?.orNull()
|
||||||
|
|
||||||
interface CurrentCallListener {
|
interface CurrentCallListener {
|
||||||
fun onCurrentCallChange(call: MxCall?)
|
fun onCurrentCallChange(call: MxCall?)
|
||||||
fun onCaptureStateChanged(mgr: WebRtcPeerConnectionManager) {}
|
fun onCaptureStateChanged(mgr: WebRtcPeerConnectionManager) {}
|
||||||
|
@ -288,15 +292,16 @@ class WebRtcPeerConnectionManager @Inject constructor(
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun getTurnServer(callback: ((TurnServerResponse?) -> Unit)) {
|
private fun getTurnServer(callback: ((TurnServerResponse?) -> Unit)) {
|
||||||
sessionHolder.getActiveSession().callSignalingService().getTurnServer(object : MatrixCallback<TurnServerResponse?> {
|
currentSession?.callSignalingService()
|
||||||
override fun onSuccess(data: TurnServerResponse?) {
|
?.getTurnServer(object : MatrixCallback<TurnServerResponse?> {
|
||||||
callback(data)
|
override fun onSuccess(data: TurnServerResponse?) {
|
||||||
}
|
callback(data)
|
||||||
|
}
|
||||||
|
|
||||||
override fun onFailure(failure: Throwable) {
|
override fun onFailure(failure: Throwable) {
|
||||||
callback(null)
|
callback(null)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
fun attachViewRenderers(localViewRenderer: SurfaceViewRenderer?, remoteViewRenderer: SurfaceViewRenderer, mode: String?) {
|
fun attachViewRenderers(localViewRenderer: SurfaceViewRenderer?, remoteViewRenderer: SurfaceViewRenderer, mode: String?) {
|
||||||
|
@ -310,7 +315,7 @@ class WebRtcPeerConnectionManager @Inject constructor(
|
||||||
currentCall?.mxCall
|
currentCall?.mxCall
|
||||||
?.takeIf { it.state is CallState.Connected }
|
?.takeIf { it.state is CallState.Connected }
|
||||||
?.let { mxCall ->
|
?.let { mxCall ->
|
||||||
val name = sessionHolder.getSafeActiveSession()?.getUser(mxCall.otherUserId)?.getBestName()
|
val name = currentSession?.getUser(mxCall.otherUserId)?.getBestName()
|
||||||
?: mxCall.roomId
|
?: mxCall.roomId
|
||||||
// Start background service with notification
|
// Start background service with notification
|
||||||
CallService.onPendingCall(
|
CallService.onPendingCall(
|
||||||
|
@ -318,7 +323,7 @@ class WebRtcPeerConnectionManager @Inject constructor(
|
||||||
isVideo = mxCall.isVideoCall,
|
isVideo = mxCall.isVideoCall,
|
||||||
roomName = name,
|
roomName = name,
|
||||||
roomId = mxCall.roomId,
|
roomId = mxCall.roomId,
|
||||||
matrixId = sessionHolder.getSafeActiveSession()?.myUserId ?: "",
|
matrixId = currentSession?.myUserId ?: "",
|
||||||
callId = mxCall.callId)
|
callId = mxCall.callId)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -373,14 +378,14 @@ class WebRtcPeerConnectionManager @Inject constructor(
|
||||||
val mxCall = callContext.mxCall
|
val mxCall = callContext.mxCall
|
||||||
// Update service state
|
// Update service state
|
||||||
|
|
||||||
val name = sessionHolder.getSafeActiveSession()?.getUser(mxCall.otherUserId)?.getBestName()
|
val name = currentSession?.getUser(mxCall.otherUserId)?.getBestName()
|
||||||
?: mxCall.roomId
|
?: mxCall.roomId
|
||||||
CallService.onPendingCall(
|
CallService.onPendingCall(
|
||||||
context = context,
|
context = context,
|
||||||
isVideo = mxCall.isVideoCall,
|
isVideo = mxCall.isVideoCall,
|
||||||
roomName = name,
|
roomName = name,
|
||||||
roomId = mxCall.roomId,
|
roomId = mxCall.roomId,
|
||||||
matrixId = sessionHolder.getSafeActiveSession()?.myUserId ?: "",
|
matrixId = currentSession?.myUserId ?: "",
|
||||||
callId = mxCall.callId
|
callId = mxCall.callId
|
||||||
)
|
)
|
||||||
executor.execute {
|
executor.execute {
|
||||||
|
@ -563,14 +568,14 @@ class WebRtcPeerConnectionManager @Inject constructor(
|
||||||
?.let { mxCall ->
|
?.let { mxCall ->
|
||||||
// Start background service with notification
|
// Start background service with notification
|
||||||
|
|
||||||
val name = sessionHolder.getSafeActiveSession()?.getUser(mxCall.otherUserId)?.getBestName()
|
val name = currentSession?.getUser(mxCall.otherUserId)?.getBestName()
|
||||||
?: mxCall.otherUserId
|
?: mxCall.otherUserId
|
||||||
CallService.onOnGoingCallBackground(
|
CallService.onOnGoingCallBackground(
|
||||||
context = context,
|
context = context,
|
||||||
isVideo = mxCall.isVideoCall,
|
isVideo = mxCall.isVideoCall,
|
||||||
roomName = name,
|
roomName = name,
|
||||||
roomId = mxCall.roomId,
|
roomId = mxCall.roomId,
|
||||||
matrixId = sessionHolder.getSafeActiveSession()?.myUserId ?: "",
|
matrixId = currentSession?.myUserId ?: "",
|
||||||
callId = mxCall.callId
|
callId = mxCall.callId
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -631,20 +636,20 @@ class WebRtcPeerConnectionManager @Inject constructor(
|
||||||
}
|
}
|
||||||
|
|
||||||
Timber.v("## VOIP startOutgoingCall in room $signalingRoomId to $otherUserId isVideo $isVideoCall")
|
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)
|
val callContext = CallContext(createdCall)
|
||||||
|
|
||||||
audioManager.startForCall(createdCall)
|
audioManager.startForCall(createdCall)
|
||||||
currentCall = callContext
|
currentCall = callContext
|
||||||
|
|
||||||
val name = sessionHolder.getSafeActiveSession()?.getUser(createdCall.otherUserId)?.getBestName()
|
val name = currentSession?.getUser(createdCall.otherUserId)?.getBestName()
|
||||||
?: createdCall.otherUserId
|
?: createdCall.otherUserId
|
||||||
CallService.onOutgoingCallRinging(
|
CallService.onOutgoingCallRinging(
|
||||||
context = context.applicationContext,
|
context = context.applicationContext,
|
||||||
isVideo = createdCall.isVideoCall,
|
isVideo = createdCall.isVideoCall,
|
||||||
roomName = name,
|
roomName = name,
|
||||||
roomId = createdCall.roomId,
|
roomId = createdCall.roomId,
|
||||||
matrixId = sessionHolder.getSafeActiveSession()?.myUserId ?: "",
|
matrixId = currentSession?.myUserId ?: "",
|
||||||
callId = createdCall.callId)
|
callId = createdCall.callId)
|
||||||
|
|
||||||
executor.execute {
|
executor.execute {
|
||||||
|
@ -693,14 +698,14 @@ class WebRtcPeerConnectionManager @Inject constructor(
|
||||||
}
|
}
|
||||||
|
|
||||||
// Start background service with notification
|
// Start background service with notification
|
||||||
val name = sessionHolder.getSafeActiveSession()?.getUser(mxCall.otherUserId)?.getBestName()
|
val name = currentSession?.getUser(mxCall.otherUserId)?.getBestName()
|
||||||
?: mxCall.otherUserId
|
?: mxCall.otherUserId
|
||||||
CallService.onIncomingCallRinging(
|
CallService.onIncomingCallRinging(
|
||||||
context = context,
|
context = context,
|
||||||
isVideo = mxCall.isVideoCall,
|
isVideo = mxCall.isVideoCall,
|
||||||
roomName = name,
|
roomName = name,
|
||||||
roomId = mxCall.roomId,
|
roomId = mxCall.roomId,
|
||||||
matrixId = sessionHolder.getSafeActiveSession()?.myUserId ?: "",
|
matrixId = currentSession?.myUserId ?: "",
|
||||||
callId = mxCall.callId
|
callId = mxCall.callId
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -818,14 +823,14 @@ class WebRtcPeerConnectionManager @Inject constructor(
|
||||||
}
|
}
|
||||||
val mxCall = call.mxCall
|
val mxCall = call.mxCall
|
||||||
// Update service state
|
// Update service state
|
||||||
val name = sessionHolder.getSafeActiveSession()?.getUser(mxCall.otherUserId)?.getBestName()
|
val name = currentSession?.getUser(mxCall.otherUserId)?.getBestName()
|
||||||
?: mxCall.otherUserId
|
?: mxCall.otherUserId
|
||||||
CallService.onPendingCall(
|
CallService.onPendingCall(
|
||||||
context = context,
|
context = context,
|
||||||
isVideo = mxCall.isVideoCall,
|
isVideo = mxCall.isVideoCall,
|
||||||
roomName = name,
|
roomName = name,
|
||||||
roomId = mxCall.roomId,
|
roomId = mxCall.roomId,
|
||||||
matrixId = sessionHolder.getSafeActiveSession()?.myUserId ?: "",
|
matrixId = currentSession?.myUserId ?: "",
|
||||||
callId = mxCall.callId
|
callId = mxCall.callId
|
||||||
)
|
)
|
||||||
executor.execute {
|
executor.execute {
|
||||||
|
|
|
@ -65,19 +65,19 @@ class AvatarRenderer @Inject constructor(private val activeSessionHolder: Active
|
||||||
|
|
||||||
@UiThread
|
@UiThread
|
||||||
fun render(context: Context,
|
fun render(context: Context,
|
||||||
glideRequest: GlideRequests,
|
glideRequests: GlideRequests,
|
||||||
matrixItem: MatrixItem,
|
matrixItem: MatrixItem,
|
||||||
target: Target<Drawable>) {
|
target: Target<Drawable>) {
|
||||||
val placeholder = getPlaceholderDrawable(context, matrixItem)
|
val placeholder = getPlaceholderDrawable(context, matrixItem)
|
||||||
buildGlideRequest(glideRequest, matrixItem.avatarUrl)
|
buildGlideRequest(glideRequests, matrixItem.avatarUrl)
|
||||||
.placeholder(placeholder)
|
.placeholder(placeholder)
|
||||||
.into(target)
|
.into(target)
|
||||||
}
|
}
|
||||||
|
|
||||||
@AnyThread
|
@AnyThread
|
||||||
@Throws
|
@Throws
|
||||||
fun shortcutDrawable(context: Context, glideRequest: GlideRequests, matrixItem: MatrixItem, iconSize: Int): Bitmap {
|
fun shortcutDrawable(context: Context, glideRequests: GlideRequests, matrixItem: MatrixItem, iconSize: Int): Bitmap {
|
||||||
return glideRequest
|
return glideRequests
|
||||||
.asBitmap()
|
.asBitmap()
|
||||||
.apply {
|
.apply {
|
||||||
val resolvedUrl = resolvedUrl(matrixItem.avatarUrl)
|
val resolvedUrl = resolvedUrl(matrixItem.avatarUrl)
|
||||||
|
@ -98,8 +98,8 @@ class AvatarRenderer @Inject constructor(private val activeSessionHolder: Active
|
||||||
}
|
}
|
||||||
|
|
||||||
@AnyThread
|
@AnyThread
|
||||||
fun getCachedDrawable(glideRequest: GlideRequests, matrixItem: MatrixItem): Drawable {
|
fun getCachedDrawable(glideRequests: GlideRequests, matrixItem: MatrixItem): Drawable {
|
||||||
return buildGlideRequest(glideRequest, matrixItem.avatarUrl)
|
return buildGlideRequest(glideRequests, matrixItem.avatarUrl)
|
||||||
.onlyRetrieveFromCache(true)
|
.onlyRetrieveFromCache(true)
|
||||||
.submit()
|
.submit()
|
||||||
.get()
|
.get()
|
||||||
|
@ -117,9 +117,9 @@ class AvatarRenderer @Inject constructor(private val activeSessionHolder: Active
|
||||||
|
|
||||||
// PRIVATE API *********************************************************************************
|
// PRIVATE API *********************************************************************************
|
||||||
|
|
||||||
private fun buildGlideRequest(glideRequest: GlideRequests, avatarUrl: String?): GlideRequest<Drawable> {
|
private fun buildGlideRequest(glideRequests: GlideRequests, avatarUrl: String?): GlideRequest<Drawable> {
|
||||||
val resolvedUrl = resolvedUrl(avatarUrl)
|
val resolvedUrl = resolvedUrl(avatarUrl)
|
||||||
return glideRequest
|
return glideRequests
|
||||||
.load(resolvedUrl)
|
.load(resolvedUrl)
|
||||||
.apply(RequestOptions.circleCropTransform())
|
.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.api.session.widgets.model.WidgetContent
|
||||||
import im.vector.matrix.android.internal.crypto.MXCRYPTO_ALGORITHM_MEGOLM
|
import im.vector.matrix.android.internal.crypto.MXCRYPTO_ALGORITHM_MEGOLM
|
||||||
import im.vector.matrix.android.internal.crypto.model.event.EncryptionEventContent
|
import im.vector.matrix.android.internal.crypto.model.event.EncryptionEventContent
|
||||||
|
import im.vector.riotx.ActiveSessionDataSource
|
||||||
import im.vector.riotx.R
|
import im.vector.riotx.R
|
||||||
import im.vector.riotx.core.di.ActiveSessionHolder
|
|
||||||
import im.vector.riotx.core.resources.StringProvider
|
import im.vector.riotx.core.resources.StringProvider
|
||||||
import timber.log.Timber
|
import timber.log.Timber
|
||||||
import javax.inject.Inject
|
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 roomHistoryVisibilityFormatter: RoomHistoryVisibilityFormatter,
|
||||||
private val sp: StringProvider) {
|
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? {
|
fun format(timelineEvent: TimelineEvent): CharSequence? {
|
||||||
return when (val type = timelineEvent.root.getClearType()) {
|
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 ?: ""
|
val targetDisplayName = eventContent?.displayName ?: prevEventContent?.displayName ?: event.stateKey ?: ""
|
||||||
return when (eventContent?.membership) {
|
return when (eventContent?.membership) {
|
||||||
Membership.INVITE -> {
|
Membership.INVITE -> {
|
||||||
val selfUserId = sessionHolder.getSafeActiveSession()?.myUserId
|
|
||||||
when {
|
when {
|
||||||
eventContent.thirdPartyInvite != null -> {
|
eventContent.thirdPartyInvite != null -> {
|
||||||
val userWhoHasAccepted = eventContent.thirdPartyInvite?.signed?.mxid ?: event.stateKey
|
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)
|
sp.getString(R.string.notice_room_third_party_registered_invite, userWhoHasAccepted, threePidDisplayName)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
event.stateKey == selfUserId ->
|
event.stateKey == currentUserId ->
|
||||||
eventContent.safeReason?.let { reason ->
|
eventContent.safeReason?.let { reason ->
|
||||||
sp.getString(R.string.notice_room_invite_you_with_reason, senderDisplayName, reason)
|
sp.getString(R.string.notice_room_invite_you_with_reason, senderDisplayName, reason)
|
||||||
} ?: sp.getString(R.string.notice_room_invite_you, senderDisplayName)
|
} ?: 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.platform.VectorViewModel
|
||||||
import im.vector.riotx.core.resources.StringProvider
|
import im.vector.riotx.core.resources.StringProvider
|
||||||
import im.vector.riotx.core.utils.ensureTrailingSlash
|
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 im.vector.riotx.features.signout.soft.SoftLogoutActivity
|
||||||
import timber.log.Timber
|
import timber.log.Timber
|
||||||
import java.util.concurrent.CancellationException
|
import java.util.concurrent.CancellationException
|
||||||
|
@ -64,13 +61,10 @@ class LoginViewModel @AssistedInject constructor(
|
||||||
private val applicationContext: Context,
|
private val applicationContext: Context,
|
||||||
private val authenticationService: AuthenticationService,
|
private val authenticationService: AuthenticationService,
|
||||||
private val activeSessionHolder: ActiveSessionHolder,
|
private val activeSessionHolder: ActiveSessionHolder,
|
||||||
private val pushRuleTriggerListener: PushRuleTriggerListener,
|
|
||||||
private val homeServerConnectionConfigFactory: HomeServerConnectionConfigFactory,
|
private val homeServerConnectionConfigFactory: HomeServerConnectionConfigFactory,
|
||||||
private val sessionListener: SessionListener,
|
|
||||||
private val reAuthHelper: ReAuthHelper,
|
private val reAuthHelper: ReAuthHelper,
|
||||||
private val stringProvider: StringProvider,
|
private val stringProvider: StringProvider
|
||||||
private val webRtcPeerConnectionManager: WebRtcPeerConnectionManager)
|
) : VectorViewModel<LoginViewState, LoginAction, LoginViewEvents>(initialState) {
|
||||||
: VectorViewModel<LoginViewState, LoginAction, LoginViewEvents>(initialState) {
|
|
||||||
|
|
||||||
@AssistedInject.Factory
|
@AssistedInject.Factory
|
||||||
interface Factory {
|
interface Factory {
|
||||||
|
@ -667,8 +661,7 @@ class LoginViewModel @AssistedInject constructor(
|
||||||
|
|
||||||
private fun onSessionCreated(session: Session) {
|
private fun onSessionCreated(session: Session) {
|
||||||
activeSessionHolder.setActiveSession(session)
|
activeSessionHolder.setActiveSession(session)
|
||||||
session.configureAndStart(applicationContext, pushRuleTriggerListener, sessionListener)
|
session.configureAndStart(applicationContext)
|
||||||
session.callSignalingService().addCallListener(webRtcPeerConnectionManager)
|
|
||||||
setState {
|
setState {
|
||||||
copy(
|
copy(
|
||||||
asyncLoginAction = Success(Unit)
|
asyncLoginAction = Success(Unit)
|
||||||
|
|
|
@ -22,10 +22,11 @@ import android.os.HandlerThread
|
||||||
import androidx.annotation.WorkerThread
|
import androidx.annotation.WorkerThread
|
||||||
import androidx.core.app.NotificationCompat
|
import androidx.core.app.NotificationCompat
|
||||||
import androidx.core.app.Person
|
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.matrix.android.api.session.content.ContentUrlResolver
|
||||||
|
import im.vector.riotx.ActiveSessionDataSource
|
||||||
import im.vector.riotx.BuildConfig
|
import im.vector.riotx.BuildConfig
|
||||||
import im.vector.riotx.R
|
import im.vector.riotx.R
|
||||||
import im.vector.riotx.core.di.ActiveSessionHolder
|
|
||||||
import im.vector.riotx.core.resources.StringProvider
|
import im.vector.riotx.core.resources.StringProvider
|
||||||
import im.vector.riotx.features.settings.VectorPreferences
|
import im.vector.riotx.features.settings.VectorPreferences
|
||||||
import me.gujun.android.span.span
|
import me.gujun.android.span.span
|
||||||
|
@ -46,7 +47,7 @@ class NotificationDrawerManager @Inject constructor(private val context: Context
|
||||||
private val notificationUtils: NotificationUtils,
|
private val notificationUtils: NotificationUtils,
|
||||||
private val vectorPreferences: VectorPreferences,
|
private val vectorPreferences: VectorPreferences,
|
||||||
private val stringProvider: StringProvider,
|
private val stringProvider: StringProvider,
|
||||||
private val activeSessionHolder: ActiveSessionHolder,
|
private val activeSessionDataSource: ActiveSessionDataSource,
|
||||||
private val iconLoader: IconLoader,
|
private val iconLoader: IconLoader,
|
||||||
private val bitmapLoader: BitmapLoader,
|
private val bitmapLoader: BitmapLoader,
|
||||||
private val outdatedDetector: OutdatedEventDetector?) {
|
private val outdatedDetector: OutdatedEventDetector?) {
|
||||||
|
@ -68,6 +69,10 @@ class NotificationDrawerManager @Inject constructor(private val context: Context
|
||||||
|
|
||||||
private var currentRoomId: String? = null
|
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.
|
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
|
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() {
|
private fun refreshNotificationDrawerBg() {
|
||||||
Timber.v("refreshNotificationDrawerBg()")
|
Timber.v("refreshNotificationDrawerBg()")
|
||||||
|
|
||||||
val session = activeSessionHolder.getSafeActiveSession() ?: return
|
val session = currentSession ?: return
|
||||||
|
|
||||||
val user = session.getUser(session.myUserId)
|
val user = session.getUser(session.myUserId)
|
||||||
// myUserDisplayName cannot be empty else NotificationCompat.MessagingStyle() will crash
|
// 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)
|
val file = File(context.applicationContext.cacheDir, ROOMS_NOTIFICATIONS_FILE_NAME)
|
||||||
if (!file.exists()) file.createNewFile()
|
if (!file.exists()) file.createNewFile()
|
||||||
FileOutputStream(file).use {
|
FileOutputStream(file).use {
|
||||||
activeSessionHolder.getSafeActiveSession()?.securelyStoreObject(eventList, KEY_ALIAS_SECRET_STORAGE, it)
|
currentSession?.securelyStoreObject(eventList, KEY_ALIAS_SECRET_STORAGE, it)
|
||||||
}
|
}
|
||||||
} catch (e: Throwable) {
|
} catch (e: Throwable) {
|
||||||
Timber.e(e, "## Failed to save cached notification info")
|
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)
|
val file = File(context.applicationContext.cacheDir, ROOMS_NOTIFICATIONS_FILE_NAME)
|
||||||
if (file.exists()) {
|
if (file.exists()) {
|
||||||
FileInputStream(file).use {
|
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) {
|
if (events != null) {
|
||||||
return events.toMutableList()
|
return events.toMutableList()
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,10 +15,12 @@
|
||||||
*/
|
*/
|
||||||
package im.vector.riotx.features.notifications
|
package im.vector.riotx.features.notifications
|
||||||
|
|
||||||
import im.vector.riotx.core.di.ActiveSessionHolder
|
import im.vector.riotx.ActiveSessionDataSource
|
||||||
import javax.inject.Inject
|
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.
|
* Returns true if the given event is outdated.
|
||||||
|
@ -26,10 +28,12 @@ class OutdatedEventDetector @Inject constructor(private val activeSessionHolder:
|
||||||
* other device.
|
* other device.
|
||||||
*/
|
*/
|
||||||
fun isMessageOutdated(notifiableEvent: NotifiableEvent): Boolean {
|
fun isMessageOutdated(notifiableEvent: NotifiableEvent): Boolean {
|
||||||
|
val session = activeSessionDataSource.currentValue?.orNull() ?: return false
|
||||||
|
|
||||||
if (notifiableEvent is NotifiableMessageEvent) {
|
if (notifiableEvent is NotifiableMessageEvent) {
|
||||||
val eventID = notifiableEvent.eventId
|
val eventID = notifiableEvent.eventId
|
||||||
val roomID = notifiableEvent.roomId
|
val roomID = notifiableEvent.roomId
|
||||||
val room = activeSessionHolder.getSafeActiveSession()?.getRoom(roomID) ?: return false
|
val room = session.getRoom(roomID) ?: return false
|
||||||
return room.isEventRead(eventID)
|
return room.isEventRead(eventID)
|
||||||
}
|
}
|
||||||
return false
|
return false
|
||||||
|
|
|
@ -30,17 +30,17 @@ class PushRuleTriggerListener @Inject constructor(
|
||||||
private val notificationDrawerManager: NotificationDrawerManager
|
private val notificationDrawerManager: NotificationDrawerManager
|
||||||
) : PushRuleService.PushRuleListener {
|
) : PushRuleService.PushRuleListener {
|
||||||
|
|
||||||
var session: Session? = null
|
private var session: Session? = null
|
||||||
|
|
||||||
override fun onMatchRule(event: Event, actions: List<Action>) {
|
override fun onMatchRule(event: Event, actions: List<Action>) {
|
||||||
Timber.v("Push rule match for event ${event.eventId}")
|
Timber.v("Push rule match for event ${event.eventId}")
|
||||||
if (session == null) {
|
val safeSession = session ?: return Unit.also {
|
||||||
Timber.e("Called without active session")
|
Timber.e("Called without active session")
|
||||||
return
|
|
||||||
}
|
}
|
||||||
|
|
||||||
val notificationAction = actions.toNotificationAction()
|
val notificationAction = actions.toNotificationAction()
|
||||||
if (notificationAction.shouldNotify) {
|
if (notificationAction.shouldNotify) {
|
||||||
val notifiableEvent = resolver.resolveEvent(event, session!!)
|
val notifiableEvent = resolver.resolveEvent(event, safeSession)
|
||||||
if (notifiableEvent == null) {
|
if (notifiableEvent == null) {
|
||||||
Timber.v("## Failed to resolve event")
|
Timber.v("## Failed to resolve event")
|
||||||
// TODO
|
// TODO
|
||||||
|
|
Loading…
Reference in a new issue