Merge pull request #239 from vector-im/feature/dagger

Feature/dagger
This commit is contained in:
Benoit Marty 2019-06-28 10:02:20 +02:00 committed by GitHub
commit 22c005d05a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
386 changed files with 4946 additions and 3722 deletions

View File

@ -37,10 +37,7 @@ dependencies {
implementation project(":matrix-sdk-android")
implementation 'androidx.appcompat:appcompat:1.1.0-alpha01'
implementation 'io.reactivex.rxjava2:rxkotlin:2.3.0'
implementation 'io.reactivex.rxjava2:rxandroid:2.0.2'

// Paging
implementation 'androidx.paging:paging-runtime:2.0.0'
implementation 'io.reactivex.rxjava2:rxandroid:2.1.0'

testImplementation 'junit:junit:4.12'
androidTestImplementation 'androidx.test:runner:1.1.1'

View File

@ -17,6 +17,7 @@
package im.vector.matrix.rx

import im.vector.matrix.android.api.session.room.Room
import im.vector.matrix.android.api.session.room.model.EventAnnotationsSummary
import im.vector.matrix.android.api.session.room.model.RoomSummary
import io.reactivex.Observable

@ -30,6 +31,10 @@ class RxRoom(private val room: Room) {
return room.getRoomMemberIdsLive().asObservable()
}

fun liveAnnotationSummary(eventId: String): Observable<List<EventAnnotationsSummary>> {
return room.getEventSummaryLive(eventId).asObservable()
}

}

fun Room.rx(): RxRoom {

View File

@ -18,6 +18,7 @@ package im.vector.matrix.rx

import im.vector.matrix.android.api.session.Session
import im.vector.matrix.android.api.session.group.model.GroupSummary
import im.vector.matrix.android.api.session.pushers.Pusher
import im.vector.matrix.android.api.session.room.model.RoomSummary
import im.vector.matrix.android.api.session.sync.SyncState
import io.reactivex.Observable
@ -36,6 +37,10 @@ class RxSession(private val session: Session) {
return session.syncState().asObservable()
}

fun livePushers(): Observable<List<Pusher>> {
return session.livePushers().asObservable()
}

}

fun Session.rx(): RxSession {

View File

@ -92,6 +92,7 @@ dependencies {
def lifecycle_version = '2.0.0'
def coroutines_version = "1.0.1"
def markwon_version = '3.0.0'
def daggerVersion = '2.23.1'

implementation fileTree(dir: 'libs', include: ['*.aar'])
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
@ -120,7 +121,7 @@ dependencies {
kapt 'dk.ilios:realmfieldnameshelper:1.1.1'

// Work
implementation "android.arch.work:work-runtime-ktx:1.0.0"
implementation "androidx.work:work-runtime-ktx:2.1.0-beta01"

// FP
implementation "io.arrow-kt:arrow-core:$arrow_version"
@ -133,8 +134,10 @@ dependencies {
implementation 'org.matrix.gitlab.matrix-org:olm:3.1.2'

// DI
implementation "org.koin:koin-core:$koin_version"
implementation "org.koin:koin-core-ext:$koin_version"
implementation "com.google.dagger:dagger:$daggerVersion"
kapt "com.google.dagger:dagger-compiler:$daggerVersion"
compileOnly 'com.squareup.inject:assisted-inject-annotations-dagger2:0.4.0'
kapt 'com.squareup.inject:assisted-inject-processor-dagger2:0.4.0'

// Logging
implementation 'com.jakewharton.timber:timber:4.7.1'

View File

@ -39,16 +39,8 @@ import org.koin.test.KoinTest
@RunWith(AndroidJUnit4::class)
internal class AuthenticatorTest : InstrumentedTest, KoinTest {

init {
Monarchy.init(context())
val matrixModule = MatrixModule(context()).definition
val networkModule = NetworkModule().definition
val authModule = AuthModule().definition
loadKoinModules(listOf(matrixModule, networkModule, authModule))
}

private val authenticator: Authenticator by inject()
private val okReplayInterceptor: OkReplayInterceptor by inject()
lateinit var authenticator: Authenticator
lateinit var okReplayInterceptor: OkReplayInterceptor

private val okReplayConfig = OkReplayConfig.Builder()
.tapeRoot(AndroidTapeRoot(

View File

@ -23,7 +23,7 @@ import im.vector.matrix.android.internal.session.room.timeline.TokenChunkEvent
import im.vector.matrix.android.internal.session.room.timeline.TokenChunkEventPersistor
import kotlin.random.Random

internal class FakeGetContextOfEventTask(private val tokenChunkEventPersistor: TokenChunkEventPersistor) : GetContextOfEventTask {
internal class FakeGetContextOfEventTask @Inject constructor(private val tokenChunkEventPersistor: TokenChunkEventPersistor) : GetContextOfEventTask {

override suspend fun execute(params: GetContextOfEventTask.Params): Try<TokenChunkEventPersistor.Result> {
val fakeEvents = RoomDataHelper.createFakeListOfEvents(30)

View File

@ -21,7 +21,7 @@ import im.vector.matrix.android.internal.session.room.timeline.PaginationTask
import im.vector.matrix.android.internal.session.room.timeline.TokenChunkEventPersistor
import kotlin.random.Random

internal class FakePaginationTask(private val tokenChunkEventPersistor: TokenChunkEventPersistor) : PaginationTask {
internal class FakePaginationTask @Inject constructor(private val tokenChunkEventPersistor: TokenChunkEventPersistor) : PaginationTask {

override suspend fun execute(params: PaginationTask.Params): Try<TokenChunkEventPersistor.Result> {
val fakeEvents = RoomDataHelper.createFakeListOfEvents(30)

View File

@ -59,8 +59,8 @@ internal class TimelineTest : InstrumentedTest {
private fun createTimeline(initialEventId: String? = null): Timeline {
val taskExecutor = TaskExecutor(testCoroutineDispatchers)
val tokenChunkEventPersistor = TokenChunkEventPersistor(monarchy)
val paginationTask = FakePaginationTask(tokenChunkEventPersistor)
val getContextOfEventTask = FakeGetContextOfEventTask(tokenChunkEventPersistor)
val paginationTask = FakePaginationTask @Inject constructor(tokenChunkEventPersistor)
val getContextOfEventTask = FakeGetContextOfEventTask @Inject constructor(tokenChunkEventPersistor)
val roomMemberExtractor = SenderRoomMemberExtractor(ROOM_ID)
val timelineEventFactory = TimelineEventFactory(roomMemberExtractor, EventRelationExtractor())
return DefaultTimeline(

View File

@ -17,12 +17,14 @@

package im.vector.matrix.android.internal.network.interceptors

import im.vector.matrix.android.internal.di.MatrixScope
import okhttp3.Interceptor
import okhttp3.Response
import okhttp3.logging.HttpLoggingInterceptor
import okio.Buffer
import java.io.IOException
import java.nio.charset.Charset
import javax.inject.Inject

/**
* An OkHttp interceptor that logs requests as curl shell commands. They can then
@ -33,7 +35,8 @@ import java.nio.charset.Charset
* information. It should only be used in a controlled manner or in a
* non-production environment.
*/
internal class CurlLoggingInterceptor(private val logger: HttpLoggingInterceptor.Logger = HttpLoggingInterceptor.Logger.DEFAULT)
@MatrixScope
internal class CurlLoggingInterceptor @Inject constructor(private val logger: HttpLoggingInterceptor.Logger)
: Interceptor {

/**

View File

@ -1,4 +1,5 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
package="im.vector.matrix.android">

<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
@ -7,9 +8,10 @@

<application>

<provider
android:name=".internal.MatrixInitProvider"
android:authorities="im.vector.matrix.android.MatrixInitProvider" />
<provider android:name="androidx.work.impl.WorkManagerInitializer"
android:authorities="${applicationId}.workmanager-init"
android:exported="false"
tools:node="remove" />

</application>


View File

@ -18,77 +18,78 @@ package im.vector.matrix.android.api

import android.content.Context
import androidx.lifecycle.ProcessLifecycleOwner
import androidx.work.Configuration
import androidx.work.WorkManager
import com.zhuinden.monarchy.Monarchy
import im.vector.matrix.android.BuildConfig
import im.vector.matrix.android.api.auth.Authenticator
import im.vector.matrix.android.api.pushrules.Action
import im.vector.matrix.android.api.pushrules.PushRuleService
import im.vector.matrix.android.api.session.Session
import im.vector.matrix.android.api.session.events.model.Event
import im.vector.matrix.android.api.session.sync.FilterService
import im.vector.matrix.android.internal.auth.AuthModule
import im.vector.matrix.android.internal.di.MatrixKoinComponent
import im.vector.matrix.android.internal.di.MatrixKoinHolder
import im.vector.matrix.android.internal.di.MatrixModule
import im.vector.matrix.android.internal.di.NetworkModule
import im.vector.matrix.android.internal.SessionManager
import im.vector.matrix.android.internal.di.DaggerMatrixComponent
import im.vector.matrix.android.internal.network.UserAgentHolder
import im.vector.matrix.android.internal.util.BackgroundDetectionObserver
import org.koin.standalone.get
import org.koin.standalone.inject
import timber.log.Timber
import org.matrix.olm.OlmManager
import java.util.concurrent.atomic.AtomicBoolean
import javax.inject.Inject

data class MatrixConfiguration(
val applicationFlavor: String = "Default-application-flavor"
) {

interface Provider {
fun providesMatrixConfiguration(): MatrixConfiguration
}

}

/**
* This is the main entry point to the matrix sdk.
* This class is automatically init by a provider.
* To get the singleton instance, use getInstance static method.
*/
class Matrix private constructor(context: Context) : MatrixKoinComponent {
class Matrix private constructor(context: Context, matrixConfiguration: MatrixConfiguration) {

private val authenticator by inject<Authenticator>()
private val userAgentHolder by inject<UserAgentHolder>()
private val backgroundDetectionObserver by inject<BackgroundDetectionObserver>()
var currentSession: Session? = null
@Inject internal lateinit var authenticator: Authenticator
@Inject internal lateinit var userAgentHolder: UserAgentHolder
@Inject internal lateinit var backgroundDetectionObserver: BackgroundDetectionObserver
@Inject internal lateinit var olmManager: OlmManager
@Inject internal lateinit var sessionManager: SessionManager

init {
Monarchy.init(context)
val matrixModule = MatrixModule(context).definition
val networkModule = NetworkModule().definition
val authModule = AuthModule().definition
MatrixKoinHolder.instance.loadModules(listOf(matrixModule, networkModule, authModule))
ProcessLifecycleOwner.get().lifecycle.addObserver(backgroundDetectionObserver)
authenticator.getLastActiveSession()?.also {
currentSession = it
it.open()
it.setFilter(FilterService.FilterPreset.RiotFilter)
it.startSync()
DaggerMatrixComponent.factory().create(context).inject(this)
if (context.applicationContext !is Configuration.Provider) {
WorkManager.initialize(context, Configuration.Builder().build())
}
ProcessLifecycleOwner.get().lifecycle.addObserver(backgroundDetectionObserver)
userAgentHolder.setApplicationFlavor(matrixConfiguration.applicationFlavor)
}

fun getUserAgent() = userAgentHolder.userAgent

fun authenticator(): Authenticator {
return authenticator
}

/**
* Set application flavor, to alter user agent.
*/
fun setApplicationFlavor(flavor: String) {
userAgentHolder.setApplicationFlavor(flavor)
}

fun getUserAgent() = userAgentHolder.userAgent

companion object {

private lateinit var instance: Matrix
private val isInit = AtomicBoolean(false)

internal fun initialize(context: Context) {
fun initialize(context: Context, matrixConfiguration: MatrixConfiguration) {
if (isInit.compareAndSet(false, true)) {
instance = Matrix(context.applicationContext)
instance = Matrix(context.applicationContext, matrixConfiguration)
}
}

fun getInstance(): Matrix {
fun getInstance(context: Context): Matrix {
if (isInit.compareAndSet(false, true)) {
val appContext = context.applicationContext
if (appContext is MatrixConfiguration.Provider) {
val matrixConfiguration = (appContext as MatrixConfiguration.Provider).providesMatrixConfiguration()
instance = Matrix(appContext, matrixConfiguration)
} else {
throw IllegalStateException("Matrix is not initialized properly. You should call Matrix.initialize or let your application implements MatrixConfiguration.Provider.")
}
}
return instance
}


View File

@ -18,6 +18,7 @@ package im.vector.matrix.android.api.auth

import im.vector.matrix.android.api.MatrixCallback
import im.vector.matrix.android.api.auth.data.HomeServerConnectionConfig
import im.vector.matrix.android.api.auth.data.SessionParams
import im.vector.matrix.android.api.session.Session
import im.vector.matrix.android.api.util.Cancelable

@ -40,14 +41,24 @@ interface Authenticator {
* Check if there is an active [Session].
* @return true if there is at least one active session.
*/
fun hasActiveSessions(): Boolean
fun hasAuthenticatedSessions(): Boolean

//TODO remove this method. Shouldn't be managed like that.
/**
* Get the last active [Session], if there is an active session.
* @return the lastActive session if any, or null
*/
fun getLastActiveSession(): Session?
fun getLastAuthenticatedSession(): Session?

/**
* Get an authenticated session. You should at least call authenticate one time before.
* If you logout, this session will no longer be valid.
*
* @param sessionParams the sessionParams to open with.
* @return the associated session if any, or null
*/
fun getSession(sessionParams: SessionParams): Session?



}

View File

@ -54,6 +54,10 @@ interface Session :
*/
val sessionParams: SessionParams

val myUserId : String
get() = sessionParams.credentials.userId


/**
* This method allow to open a session. It does start some service on the background.
*/

View File

@ -1,52 +0,0 @@
/*
* Copyright 2019 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.matrix.android.internal

import android.content.ContentProvider
import android.content.ContentValues
import android.database.Cursor
import android.net.Uri
import im.vector.matrix.android.api.Matrix

internal class MatrixInitProvider : ContentProvider() {

override fun onCreate(): Boolean {
Matrix.initialize(context!!)
return true
}

override fun insert(uri: Uri, values: ContentValues?): Uri? {
return null
}

override fun query(uri: Uri, projection: Array<String>?, selection: String?, selectionArgs: Array<String>?, sortOrder: String?): Cursor? {
return null
}

override fun update(uri: Uri, values: ContentValues?, selection: String?, selectionArgs: Array<String>?): Int {
return 0
}

override fun delete(uri: Uri, selection: String?, selectionArgs: Array<String>?): Int {
return 0
}

override fun getType(uri: Uri): String? {
return null
}

}

View File

@ -0,0 +1,67 @@
/*
*
* * Copyright 2019 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.matrix.android.internal

import im.vector.matrix.android.api.auth.data.SessionParams
import im.vector.matrix.android.api.session.Session
import im.vector.matrix.android.internal.auth.SessionParamsStore
import im.vector.matrix.android.internal.di.MatrixComponent
import im.vector.matrix.android.internal.di.MatrixScope
import im.vector.matrix.android.internal.session.DaggerSessionComponent
import im.vector.matrix.android.internal.session.SessionComponent
import javax.inject.Inject

@MatrixScope
internal class SessionManager @Inject constructor(private val matrixComponent: MatrixComponent,
private val sessionParamsStore: SessionParamsStore) {

private val sessionComponents = HashMap<String, SessionComponent>()

fun getSessionComponent(userId: String): SessionComponent? {
val sessionParams = sessionParamsStore.get(userId) ?: return null
return getOrCreateSessionComponent(sessionParams)
}

fun getOrCreateSession(sessionParams: SessionParams): Session {
return getOrCreateSessionComponent(sessionParams).session()
}

fun releaseSession(userId: String) {
if (sessionComponents.containsKey(userId).not()) {
throw RuntimeException("You don't have a session for the user $userId")
}
sessionComponents.remove(userId)?.also {
it.session().close()
}
}

private fun getOrCreateSessionComponent(sessionParams: SessionParams): SessionComponent {
val userId = sessionParams.credentials.userId
if (sessionComponents.containsKey(userId)) {
return sessionComponents[userId]!!
}
return DaggerSessionComponent
.factory()
.create(matrixComponent, sessionParams)
.also {
sessionComponents[sessionParams.credentials.userId] = it
}
}

}

View File

@ -17,38 +17,44 @@
package im.vector.matrix.android.internal.auth

import android.content.Context
import dagger.Binds
import dagger.Module
import dagger.Provides
import im.vector.matrix.android.api.auth.Authenticator
import im.vector.matrix.android.internal.auth.db.AuthRealmModule
import im.vector.matrix.android.internal.auth.db.RealmSessionParamsStore
import im.vector.matrix.android.internal.auth.db.SessionParamsMapper
import im.vector.matrix.android.internal.di.AuthDatabase
import im.vector.matrix.android.internal.di.MatrixScope
import io.realm.RealmConfiguration
import org.koin.dsl.module.module
import java.io.File

class AuthModule {
@Module
internal abstract class AuthModule {

val definition = module {

single {
DefaultAuthenticator(get(), get(), get()) as Authenticator
}

single {
val context: Context = get()
@Module
companion object {
@JvmStatic
@Provides
@AuthDatabase
fun providesRealmConfiguration(context: Context): RealmConfiguration {
val old = File(context.filesDir, "matrix-sdk-auth")

if (old.exists()) {
old.renameTo(File(context.filesDir, "matrix-sdk-auth.realm"))
}

val mapper = SessionParamsMapper((get()))
val realmConfiguration = RealmConfiguration.Builder()
return RealmConfiguration.Builder()
.name("matrix-sdk-auth.realm")
.modules(AuthRealmModule())
.deleteRealmIfMigrationNeeded()
.build()
RealmSessionParamsStore(mapper, realmConfiguration) as SessionParamsStore
}

}



@Binds
abstract fun bindSessionParamsStore(sessionParamsStore: RealmSessionParamsStore): SessionParamsStore

@Binds
abstract fun bindAuthenticator(authenticator: DefaultAuthenticator): Authenticator

}

View File

@ -19,38 +19,49 @@ package im.vector.matrix.android.internal.auth
import android.util.Patterns
import im.vector.matrix.android.api.MatrixCallback
import im.vector.matrix.android.api.auth.Authenticator
import im.vector.matrix.android.api.auth.data.Credentials
import im.vector.matrix.android.api.auth.data.HomeServerConnectionConfig
import im.vector.matrix.android.api.auth.data.SessionParams
import im.vector.matrix.android.api.session.Session
import im.vector.matrix.android.api.util.Cancelable
import im.vector.matrix.android.api.auth.data.Credentials
import im.vector.matrix.android.internal.SessionManager
import im.vector.matrix.android.internal.auth.data.PasswordLoginParams
import im.vector.matrix.android.api.auth.data.SessionParams
import im.vector.matrix.android.internal.auth.data.ThreePidMedium
import im.vector.matrix.android.internal.di.Unauthenticated
import im.vector.matrix.android.internal.extensions.foldToCallback
import im.vector.matrix.android.internal.network.RetrofitFactory
import im.vector.matrix.android.internal.network.executeRequest
import im.vector.matrix.android.internal.session.DefaultSession
import im.vector.matrix.android.internal.util.CancelableCoroutine
import im.vector.matrix.android.internal.util.MatrixCoroutineDispatchers
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import retrofit2.Retrofit
import okhttp3.OkHttpClient
import javax.inject.Inject

internal class DefaultAuthenticator(private val retrofitBuilder: Retrofit.Builder,
private val coroutineDispatchers: MatrixCoroutineDispatchers,
private val sessionParamsStore: SessionParamsStore) : Authenticator {
internal class DefaultAuthenticator @Inject constructor(@Unauthenticated
private val okHttpClient: OkHttpClient,
private val retrofitFactory: RetrofitFactory,
private val coroutineDispatchers: MatrixCoroutineDispatchers,
private val sessionParamsStore: SessionParamsStore,
private val sessionManager: SessionManager
) : Authenticator {

override fun hasActiveSessions(): Boolean {
return sessionParamsStore.get() != null
override fun hasAuthenticatedSessions(): Boolean {
return sessionParamsStore.getLast() != null
}

override fun getLastActiveSession(): Session? {
val sessionParams = sessionParamsStore.get()
override fun getLastAuthenticatedSession(): Session? {
val sessionParams = sessionParamsStore.getLast()
return sessionParams?.let {
DefaultSession(it)
sessionManager.getOrCreateSession(it)
}
}

override fun getSession(sessionParams: SessionParams): Session? {
return sessionManager.getOrCreateSession(sessionParams)
}

override fun authenticate(homeServerConnectionConfig: HomeServerConnectionConfig,
login: String,
password: String,
@ -81,13 +92,13 @@ internal class DefaultAuthenticator(private val retrofitBuilder: Retrofit.Builde
sessionParamsStore.save(sessionParams)
sessionParams
}.map {
DefaultSession(it)
sessionManager.getOrCreateSession(it)
}

}

private fun buildAuthAPI(homeServerConnectionConfig: HomeServerConnectionConfig): AuthAPI {
val retrofit = retrofitBuilder.baseUrl(homeServerConnectionConfig.homeServerUri.toString()).build()
val retrofit = retrofitFactory.create(okHttpClient, homeServerConnectionConfig.homeServerUri.toString())
return retrofit.create(AuthAPI::class.java)
}


View File

@ -21,9 +21,15 @@ import im.vector.matrix.android.api.auth.data.SessionParams

internal interface SessionParamsStore {

fun get(): SessionParams?
fun get(userId: String): SessionParams?

fun getLast(): SessionParams?

fun getAll(): List<SessionParams>

fun save(sessionParams: SessionParams): Try<SessionParams>

fun delete(): Try<Unit>
fun delete(userId: String): Try<Unit>

fun deleteAll(): Try<Unit>
}

View File

@ -19,11 +19,48 @@ package im.vector.matrix.android.internal.auth.db
import arrow.core.Try
import im.vector.matrix.android.api.auth.data.SessionParams
import im.vector.matrix.android.internal.auth.SessionParamsStore
import im.vector.matrix.android.internal.di.AuthDatabase
import io.realm.Realm
import io.realm.RealmConfiguration
import javax.inject.Inject

internal class RealmSessionParamsStore(private val mapper: SessionParamsMapper,
private val realmConfiguration: RealmConfiguration) : SessionParamsStore {
internal class RealmSessionParamsStore @Inject constructor(private val mapper: SessionParamsMapper,
@AuthDatabase
private val realmConfiguration: RealmConfiguration
) : SessionParamsStore {

override fun getLast(): SessionParams? {
val realm = Realm.getInstance(realmConfiguration)
val sessionParams = realm
.where(SessionParamsEntity::class.java)
.findAll()
.map { mapper.map(it) }
.lastOrNull()
realm.close()
return sessionParams
}

override fun get(userId: String): SessionParams? {
val realm = Realm.getInstance(realmConfiguration)
val sessionParams = realm
.where(SessionParamsEntity::class.java)
.equalTo(SessionParamsEntityFields.USER_ID, userId)
.findAll()
.map { mapper.map(it) }
.firstOrNull()
realm.close()
return sessionParams
}

override fun getAll(): List<SessionParams> {
val realm = Realm.getInstance(realmConfiguration)
val sessionParams = realm
.where(SessionParamsEntity::class.java)
.findAll()
.mapNotNull { mapper.map(it) }
realm.close()
return sessionParams
}

override fun save(sessionParams: SessionParams): Try<SessionParams> {
return Try {
@ -39,18 +76,20 @@ internal class RealmSessionParamsStore(private val mapper: SessionParamsMapper,
}
}

override fun get(): SessionParams? {
val realm = Realm.getInstance(realmConfiguration)
val sessionParams = realm
.where(SessionParamsEntity::class.java)
.findAll()
.map { mapper.map(it) }
.lastOrNull()
realm.close()
return sessionParams
override fun delete(userId: String): Try<Unit> {
return Try {
val realm = Realm.getInstance(realmConfiguration)
realm.executeTransaction {
it.where(SessionParamsEntity::class.java)
.equalTo(SessionParamsEntityFields.USER_ID, userId)
.findAll()
.deleteAllFromRealm()
}
realm.close()
}
}

override fun delete(): Try<Unit> {
override fun deleteAll(): Try<Unit> {
return Try {
val realm = Realm.getInstance(realmConfiguration)
realm.executeTransaction {

View File

@ -17,8 +17,10 @@
package im.vector.matrix.android.internal.auth.db

import io.realm.RealmObject
import io.realm.annotations.PrimaryKey

internal open class SessionParamsEntity(
@PrimaryKey var userId: String = "",
var credentialsJson: String = "",
var homeServerConnectionConfigJson: String = ""
) : RealmObject()

View File

@ -17,11 +17,13 @@
package im.vector.matrix.android.internal.auth.db

import com.squareup.moshi.Moshi
import im.vector.matrix.android.api.auth.data.HomeServerConnectionConfig
import im.vector.matrix.android.api.auth.data.Credentials
import im.vector.matrix.android.api.auth.data.HomeServerConnectionConfig
import im.vector.matrix.android.api.auth.data.SessionParams
import im.vector.matrix.android.internal.di.MatrixScope
import javax.inject.Inject

internal class SessionParamsMapper(moshi: Moshi) {
internal class SessionParamsMapper @Inject constructor(moshi: Moshi) {

private val credentialsAdapter = moshi.adapter(Credentials::class.java)
private val homeServerConnectionConfigAdapter = moshi.adapter(HomeServerConnectionConfig::class.java)
@ -47,7 +49,7 @@ internal class SessionParamsMapper(moshi: Moshi) {
if (credentialsJson == null || homeServerConnectionConfigJson == null) {
return null
}
return SessionParamsEntity(credentialsJson, homeServerConnectionConfigJson)
return SessionParamsEntity(sessionParams.credentials.userId, credentialsJson, homeServerConnectionConfigJson)
}



View File

@ -59,15 +59,13 @@ import im.vector.matrix.android.internal.crypto.model.rest.RoomKeyRequestBody
import im.vector.matrix.android.internal.crypto.repository.WarnOnUnknownDeviceRepository
import im.vector.matrix.android.internal.crypto.store.IMXCryptoStore
import im.vector.matrix.android.internal.crypto.tasks.*
import im.vector.matrix.android.internal.crypto.tasks.DeleteDeviceTask
import im.vector.matrix.android.internal.crypto.tasks.GetDevicesTask
import im.vector.matrix.android.internal.crypto.tasks.SetDeviceNameTask
import im.vector.matrix.android.internal.crypto.tasks.UploadKeysTask
import im.vector.matrix.android.internal.crypto.verification.DefaultSasVerificationService
import im.vector.matrix.android.internal.database.model.EventEntity
import im.vector.matrix.android.internal.database.query.where
import im.vector.matrix.android.internal.di.CryptoDatabase
import im.vector.matrix.android.internal.di.MoshiProvider
import im.vector.matrix.android.internal.extensions.foldToCallback
import im.vector.matrix.android.internal.session.SessionScope
import im.vector.matrix.android.internal.session.cache.ClearCacheTask
import im.vector.matrix.android.internal.session.room.membership.LoadRoomMembersTask
import im.vector.matrix.android.internal.session.room.membership.RoomMembers
@ -81,6 +79,7 @@ import org.matrix.olm.OlmManager
import timber.log.Timber
import java.util.*
import java.util.concurrent.atomic.AtomicBoolean
import javax.inject.Inject
import kotlin.coroutines.EmptyCoroutineContext

/**
@ -93,7 +92,10 @@ import kotlin.coroutines.EmptyCoroutineContext
* CryptoService maintains all necessary keys and their sharing with other devices required for the crypto.
* Specially, it tracks all room membership changes events in order to do keys updates.
*/
internal class CryptoManager(
@SessionScope
internal class CryptoManager @Inject constructor(
// Olm Manager
private val olmManager: OlmManager,
// The credentials,
private val credentials: Credentials,
private val myDeviceInfoHolder: MyDeviceInfoHolder,
@ -119,8 +121,6 @@ internal class CryptoManager(
private val incomingRoomKeyRequestManager: IncomingRoomKeyRequestManager,
//
private val outgoingRoomKeyRequestManager: OutgoingRoomKeyRequestManager,
// Olm Manager
private val olmManager: OlmManager,
// Actions
private val setDeviceVerificationAction: SetDeviceVerificationAction,
private val megolmSessionDataImporter: MegolmSessionDataImporter,
@ -135,7 +135,7 @@ internal class CryptoManager(
private val setDeviceNameTask: SetDeviceNameTask,
private val uploadKeysTask: UploadKeysTask,
private val loadRoomMembersTask: LoadRoomMembersTask,
private val clearCryptoDataTask: ClearCacheTask,
@CryptoDatabase private val clearCryptoDataTask: ClearCacheTask,
private val monarchy: Monarchy,
private val coroutineDispatchers: MatrixCoroutineDispatchers,
private val taskExecutor: TaskExecutor

View File

@ -17,49 +17,41 @@
package im.vector.matrix.android.internal.crypto

import android.content.Context
import dagger.Binds
import dagger.Module
import dagger.Provides
import im.vector.matrix.android.api.auth.data.Credentials
import im.vector.matrix.android.api.session.crypto.CryptoService
import im.vector.matrix.android.internal.crypto.actions.*
import im.vector.matrix.android.internal.crypto.algorithms.megolm.MXMegolmDecryptionFactory
import im.vector.matrix.android.internal.crypto.algorithms.megolm.MXMegolmEncryptionFactory
import im.vector.matrix.android.internal.crypto.algorithms.olm.MXOlmDecryptionFactory
import im.vector.matrix.android.internal.crypto.algorithms.olm.MXOlmEncryptionFactory
import im.vector.matrix.android.internal.crypto.api.CryptoApi
import im.vector.matrix.android.internal.crypto.keysbackup.KeysBackup
import im.vector.matrix.android.internal.crypto.keysbackup.api.RoomKeysApi
import im.vector.matrix.android.internal.crypto.keysbackup.tasks.*
import im.vector.matrix.android.internal.crypto.repository.WarnOnUnknownDeviceRepository
import im.vector.matrix.android.internal.crypto.store.IMXCryptoStore
import im.vector.matrix.android.internal.crypto.store.db.RealmCryptoStore
import im.vector.matrix.android.internal.crypto.store.db.RealmCryptoStoreMigration
import im.vector.matrix.android.internal.crypto.store.db.RealmCryptoStoreModule
import im.vector.matrix.android.internal.crypto.store.db.hash
import im.vector.matrix.android.internal.crypto.tasks.*
import im.vector.matrix.android.internal.crypto.verification.DefaultSasVerificationService
import im.vector.matrix.android.internal.session.DefaultSession
import im.vector.matrix.android.internal.di.CryptoDatabase
import im.vector.matrix.android.internal.session.SessionScope
import im.vector.matrix.android.internal.session.cache.ClearCacheTask
import im.vector.matrix.android.internal.session.cache.RealmClearCacheTask
import io.realm.RealmConfiguration
import org.koin.dsl.module.module
import org.matrix.olm.OlmManager
import retrofit2.Retrofit
import java.io.File

internal class CryptoModule {
@Module
internal abstract class CryptoModule {

val definition = module(override = true) {

/* ==========================================================================================
* Crypto Main
* ========================================================================================== */
@Module
companion object {

// Realm configuration, named to avoid clash with main cache realm configuration
scope(DefaultSession.SCOPE, name = "CryptoRealmConfiguration") {
val context: Context = get()

val credentials: Credentials = get()

RealmConfiguration.Builder()
@JvmStatic
@Provides
@CryptoDatabase
@SessionScope
fun providesRealmConfiguration(context: Context, credentials: Credentials): RealmConfiguration {
return RealmConfiguration.Builder()
.directory(File(context.filesDir, credentials.userId.hash()))
.name("crypto_store.realm")
.modules(RealmCryptoStoreModule())
@ -68,270 +60,115 @@ internal class CryptoModule {
.build()
}

// CryptoStore
scope(DefaultSession.SCOPE) {
RealmCryptoStore(false /* TODO*/,
get("CryptoRealmConfiguration"),
get()) as IMXCryptoStore
}

scope(DefaultSession.SCOPE) {
val retrofit: Retrofit = get()
retrofit.create(CryptoApi::class.java)
}

// CryptoService
scope(DefaultSession.SCOPE) {
get<CryptoManager>() as CryptoService
}

//
scope(DefaultSession.SCOPE) {
OutgoingRoomKeyRequestManager(get(), get(), get())
}

scope(DefaultSession.SCOPE) {
IncomingRoomKeyRequestManager(get(), get(), get())
}

scope(DefaultSession.SCOPE) {
RoomDecryptorProvider(get(), get())
}

scope(DefaultSession.SCOPE) {
// Ensure OlmManager is loaded first
get<OlmManager>()
MXOlmDevice(get())
}

// ObjectSigner
scope(DefaultSession.SCOPE) {
ObjectSigner(get(), get())
}

// OneTimeKeysUploader
scope(DefaultSession.SCOPE) {
OneTimeKeysUploader(get(), get(), get(), get())
}

// Actions
scope(DefaultSession.SCOPE) {
SetDeviceVerificationAction(get(), get(), get())
}

// Device info
scope(DefaultSession.SCOPE) {
MyDeviceInfoHolder(get(), get(), get())
}

scope(DefaultSession.SCOPE) {
EnsureOlmSessionsForDevicesAction(get(), get())
}

scope(DefaultSession.SCOPE) {
EnsureOlmSessionsForUsersAction(get(), get(), get())
}

scope(DefaultSession.SCOPE) {
MegolmSessionDataImporter(get(), get(), get(), get())
}

scope(DefaultSession.SCOPE) {
MessageEncrypter(get(), get())
@JvmStatic
@Provides
@CryptoDatabase
fun providesClearCacheTask(@CryptoDatabase
realmConfiguration: RealmConfiguration): ClearCacheTask {
return RealmClearCacheTask(realmConfiguration)
}


scope(DefaultSession.SCOPE) {
WarnOnUnknownDeviceRepository()
@JvmStatic
@Provides
fun providesCryptoStore(@CryptoDatabase
realmConfiguration: RealmConfiguration, credentials: Credentials): IMXCryptoStore {
return RealmCryptoStore(false /* TODO*/,
realmConfiguration,
credentials)
}

// Factories
scope(DefaultSession.SCOPE) {
MXMegolmDecryptionFactory(
get(), get(), get(), get(), get(), get(), get(), get(), get()
)
@JvmStatic
@Provides
@SessionScope
fun providesCryptoAPI(retrofit: Retrofit): CryptoApi {
return retrofit.create(CryptoApi::class.java)
}

scope(DefaultSession.SCOPE) {
MXMegolmEncryptionFactory(
get(), get(), get(), get(), get(), get(), get(), get(), get(), get()
)
@JvmStatic
@Provides
@SessionScope
fun providesRoomKeysAPI(retrofit: Retrofit): RoomKeysApi {
return retrofit.create(RoomKeysApi::class.java)
}

scope(DefaultSession.SCOPE) {
MXOlmDecryptionFactory(
get(), get()
)
}

scope(DefaultSession.SCOPE) {
MXOlmEncryptionFactory(
get(), get(), get(), get(), get(), get()
)
}

// CryptoManager
scope(DefaultSession.SCOPE) {
CryptoManager(
credentials = get(),
myDeviceInfoHolder = get(),
cryptoStore = get(),
olmDevice = get(),
cryptoConfig = get(),
deviceListManager = get(),
keysBackup = get(),
objectSigner = get(),
oneTimeKeysUploader = get(),
roomDecryptorProvider = get(),
sasVerificationService = get(),
incomingRoomKeyRequestManager = get(),
outgoingRoomKeyRequestManager = get(),
olmManager = get(),
setDeviceVerificationAction = get(),
megolmSessionDataImporter = get(),
warnOnUnknownDevicesRepository = get(),
megolmEncryptionFactory = get(),
olmEncryptionFactory = get(),
deleteDeviceTask = get(),
deleteDeviceWithUserPasswordTask = get(),
// Tasks
getDevicesTask = get(),
setDeviceNameTask = get(),
uploadKeysTask = get(),
loadRoomMembersTask = get(),
clearCryptoDataTask = get("ClearTaskCryptoCache"),
monarchy = get(),
coroutineDispatchers = get(),
taskExecutor = get()
)
}

// Olm manager
single {
// load the crypto libs.
OlmManager()
}


// Crypto config
scope(DefaultSession.SCOPE) {
MXCryptoConfig()
}

// Device list
scope(DefaultSession.SCOPE) {
DeviceListManager(get(), get(), get(), get(), get())
}

// Crypto tasks
scope(DefaultSession.SCOPE) {
DefaultClaimOneTimeKeysForUsersDevice(get()) as ClaimOneTimeKeysForUsersDeviceTask
}
scope(DefaultSession.SCOPE) {
DefaultDeleteDeviceTask(get()) as DeleteDeviceTask
}
scope(DefaultSession.SCOPE) {
DefaultDeleteDeviceWithUserPasswordTask(get(), get()) as DeleteDeviceWithUserPasswordTask
}
scope(DefaultSession.SCOPE) {
DefaultDownloadKeysForUsers(get()) as DownloadKeysForUsersTask
}
scope(DefaultSession.SCOPE) {
DefaultGetDevicesTask(get()) as GetDevicesTask
}
scope(DefaultSession.SCOPE) {
DefaultGetKeyChangesTask(get()) as GetKeyChangesTask
}
scope(DefaultSession.SCOPE) {
DefaultSendToDeviceTask(get()) as SendToDeviceTask
}
scope(DefaultSession.SCOPE) {
DefaultSetDeviceNameTask(get()) as SetDeviceNameTask
}
scope(DefaultSession.SCOPE) {
DefaultUploadKeysTask(get()) as UploadKeysTask
}

scope(DefaultSession.SCOPE, name = "ClearTaskCryptoCache") {
RealmClearCacheTask(get("CryptoRealmConfiguration")) as ClearCacheTask
}

/* ==========================================================================================
* Keys backup
* ========================================================================================== */

scope(DefaultSession.SCOPE) {
val retrofit: Retrofit = get()
retrofit.create(RoomKeysApi::class.java)
}

scope(DefaultSession.SCOPE) {
KeysBackup(
// Credentials
get(),
// CryptoStore
get(),
get(),
get(),
get(),
// Task
get(), get(), get(), get(), get(), get(), get(), get(), get(), get(), get(), get(), get(), get(),
// Task executor
get(),
get())
}

// Key backup tasks
scope(DefaultSession.SCOPE) {
DefaultCreateKeysBackupVersionTask(get()) as CreateKeysBackupVersionTask
}
scope(DefaultSession.SCOPE) {
DefaultDeleteBackupTask(get()) as DeleteBackupTask
}
scope(DefaultSession.SCOPE) {
DefaultDeleteRoomSessionDataTask(get()) as DeleteRoomSessionDataTask
}
scope(DefaultSession.SCOPE) {
DefaultDeleteRoomSessionsDataTask(get()) as DeleteRoomSessionsDataTask
}
scope(DefaultSession.SCOPE) {
DefaultDeleteSessionsDataTask(get()) as DeleteSessionsDataTask
}
scope(DefaultSession.SCOPE) {
DefaultGetKeysBackupLastVersionTask(get()) as GetKeysBackupLastVersionTask
}
scope(DefaultSession.SCOPE) {
DefaultGetKeysBackupVersionTask(get()) as GetKeysBackupVersionTask
}
scope(DefaultSession.SCOPE) {
DefaultGetRoomSessionDataTask(get()) as GetRoomSessionDataTask
}
scope(DefaultSession.SCOPE) {
DefaultGetRoomSessionsDataTask(get()) as GetRoomSessionsDataTask
}
scope(DefaultSession.SCOPE) {
DefaultGetSessionsDataTask(get()) as GetSessionsDataTask
}
scope(DefaultSession.SCOPE) {
DefaultStoreRoomSessionDataTask(get()) as StoreRoomSessionDataTask
}
scope(DefaultSession.SCOPE) {
DefaultStoreRoomSessionsDataTask(get()) as StoreRoomSessionsDataTask
}
scope(DefaultSession.SCOPE) {
DefaultStoreSessionsDataTask(get()) as StoreSessionsDataTask
}
scope(DefaultSession.SCOPE) {
DefaultUpdateKeysBackupVersionTask(get()) as UpdateKeysBackupVersionTask
}

/* ==========================================================================================
* SAS Verification
* ========================================================================================== */

scope(DefaultSession.SCOPE) {
DefaultSasVerificationService(get(), get(), get(), get(), get(), get(), get(), get())
@JvmStatic
@Provides
@SessionScope
fun providesCryptoConfig(): MXCryptoConfig {
return MXCryptoConfig()
}

}

@Binds
abstract fun bindCryptoService(cryptoManager: CryptoManager): CryptoService

@Binds
abstract fun bindDeleteDeviceTask(deleteDeviceTask: DefaultDeleteDeviceTask): DeleteDeviceTask

@Binds
abstract fun bindGetDevicesTask(getDevicesTask: DefaultGetDevicesTask): GetDevicesTask

@Binds
abstract fun bindSetDeviceNameTask(getDevicesTask: DefaultSetDeviceNameTask): SetDeviceNameTask

@Binds
abstract fun bindUploadKeysTask(getDevicesTask: DefaultUploadKeysTask): UploadKeysTask

@Binds
abstract fun bindDownloadKeysForUsersTask(downloadKeysForUsers: DefaultDownloadKeysForUsers): DownloadKeysForUsersTask

@Binds
abstract fun bindCreateKeysBackupVersionTask(createKeysBackupVersionTask: DefaultCreateKeysBackupVersionTask): CreateKeysBackupVersionTask

@Binds
abstract fun bindDeleteBackupTask(deleteBackupTask: DefaultDeleteBackupTask): DeleteBackupTask

@Binds
abstract fun bindDeleteRoomSessionDataTask(deleteRoomSessionDataTask: DefaultDeleteRoomSessionDataTask): DeleteRoomSessionDataTask

@Binds
abstract fun bindDeleteRoomSessionsDataTask(deleteRoomSessionDataTask: DefaultDeleteRoomSessionsDataTask): DeleteRoomSessionsDataTask

@Binds
abstract fun bindDeleteSessionsDataTask(deleteRoomSessionDataTask: DefaultDeleteSessionsDataTask): DeleteSessionsDataTask

@Binds
abstract fun bindGetKeysBackupLastVersionTask(getKeysBackupLastVersionTask: DefaultGetKeysBackupLastVersionTask): GetKeysBackupLastVersionTask

@Binds
abstract fun bindGetKeysBackupVersionTask(getKeysBackupVersionTask: DefaultGetKeysBackupVersionTask): GetKeysBackupVersionTask

@Binds
abstract fun bindGetRoomSessionDataTask(getRoomSessionDataTask: DefaultGetRoomSessionDataTask): GetRoomSessionDataTask

@Binds
abstract fun bindGetRoomSessionsDataTask(getRoomSessionDataTask: DefaultGetRoomSessionsDataTask): GetRoomSessionsDataTask

@Binds
abstract fun bindGetSessionsDataTask(getRoomSessionDataTask: DefaultGetSessionsDataTask): GetSessionsDataTask

@Binds
abstract fun bindStoreRoomSessionDataTask(storeRoomSessionDataTask: DefaultStoreRoomSessionDataTask): StoreRoomSessionDataTask

@Binds
abstract fun bindStoreRoomSessionsDataTask(storeRoomSessionDataTask: DefaultStoreRoomSessionsDataTask): StoreRoomSessionsDataTask

@Binds
abstract fun bindStoreSessionsDataTask(storeRoomSessionDataTask: DefaultStoreSessionsDataTask): StoreSessionsDataTask

@Binds
abstract fun bindUpdateKeysBackupVersionTask(updateKeysBackupVersionTask: DefaultUpdateKeysBackupVersionTask): UpdateKeysBackupVersionTask

@Binds
abstract fun bindSendToDeviceTask(sendToDeviceTask: DefaultSendToDeviceTask): SendToDeviceTask

@Binds
abstract fun bindClaimOneTimeKeysForUsersDeviceTask(claimOneTimeKeysForUsersDevice: DefaultClaimOneTimeKeysForUsersDevice): ClaimOneTimeKeysForUsersDeviceTask

@Binds
abstract fun bindDeleteDeviceWithUserPasswordTask(deleteDeviceWithUserPasswordTask: DefaultDeleteDeviceWithUserPasswordTask): DeleteDeviceWithUserPasswordTask


}

View File

@ -26,16 +26,19 @@ import im.vector.matrix.android.internal.crypto.model.MXDeviceInfo
import im.vector.matrix.android.internal.crypto.model.MXUsersDevicesMap
import im.vector.matrix.android.internal.crypto.store.IMXCryptoStore
import im.vector.matrix.android.internal.crypto.tasks.DownloadKeysForUsersTask
import im.vector.matrix.android.internal.session.SessionScope
import im.vector.matrix.android.internal.session.sync.SyncTokenStore
import timber.log.Timber
import java.util.*
import javax.inject.Inject

// Legacy name: MXDeviceList
internal class DeviceListManager(private val cryptoStore: IMXCryptoStore,
private val olmDevice: MXOlmDevice,
private val syncTokenStore: SyncTokenStore,
private val credentials: Credentials,
private val downloadKeysForUsersTask: DownloadKeysForUsersTask) {
@SessionScope
internal class DeviceListManager @Inject constructor(private val cryptoStore: IMXCryptoStore,
private val olmDevice: MXOlmDevice,
private val syncTokenStore: SyncTokenStore,
private val credentials: Credentials,
private val downloadKeysForUsersTask: DownloadKeysForUsersTask) {

// HS not ready for retry
private val notReadyToRetryHS = HashSet<String>()
@ -410,7 +413,7 @@ internal class DeviceListManager(private val cryptoStore: IMXCryptoStore,

if (!isVerified) {
Timber.e("## validateDeviceKeys() : Unable to verify signature on device " + userId + ":"
+ deviceKeys.deviceId + " with error " + errorMessage)
+ deviceKeys.deviceId + " with error " + errorMessage)
return false
}

@ -421,8 +424,8 @@ internal class DeviceListManager(private val cryptoStore: IMXCryptoStore,
//
// Should we warn the user about it somehow?
Timber.e("## validateDeviceKeys() : WARNING:Ed25519 key for device " + userId + ":"
+ deviceKeys.deviceId + " has changed : "
+ previouslyStoredDeviceKeys.fingerprint() + " -> " + signKey)
+ deviceKeys.deviceId + " has changed : "
+ previouslyStoredDeviceKeys.fingerprint() + " -> " + signKey)

Timber.e("## validateDeviceKeys() : $previouslyStoredDeviceKeys -> $deviceKeys")
Timber.e("## validateDeviceKeys() : " + previouslyStoredDeviceKeys.keys + " -> " + deviceKeys.keys)

View File

@ -23,11 +23,14 @@ import im.vector.matrix.android.api.session.events.model.Event
import im.vector.matrix.android.api.session.events.model.toModel
import im.vector.matrix.android.internal.crypto.model.rest.RoomKeyShare
import im.vector.matrix.android.internal.crypto.store.IMXCryptoStore
import im.vector.matrix.android.internal.session.SessionScope
import timber.log.Timber
import java.util.*
import javax.inject.Inject
import kotlin.collections.ArrayList

internal class IncomingRoomKeyRequestManager(
@SessionScope
internal class IncomingRoomKeyRequestManager @Inject constructor(
private val credentials: Credentials,
private val cryptoStore: IMXCryptoStore,
private val roomDecryptorProvider: RoomDecryptorProvider) {

View File

@ -26,15 +26,23 @@ import im.vector.matrix.android.internal.crypto.model.OlmInboundGroupSessionWrap
import im.vector.matrix.android.internal.crypto.model.OlmSessionWrapper
import im.vector.matrix.android.internal.crypto.store.IMXCryptoStore
import im.vector.matrix.android.internal.di.MoshiProvider
import im.vector.matrix.android.internal.session.SessionScope
import im.vector.matrix.android.internal.util.convertFromUTF8
import im.vector.matrix.android.internal.util.convertToUTF8
import org.matrix.olm.*
import org.matrix.olm.OlmAccount
import org.matrix.olm.OlmInboundGroupSession
import org.matrix.olm.OlmMessage
import org.matrix.olm.OlmOutboundGroupSession
import org.matrix.olm.OlmSession
import org.matrix.olm.OlmUtility
import timber.log.Timber
import java.net.URLEncoder
import java.util.*
import javax.inject.Inject

// The libolm wrapper.
internal class MXOlmDevice(
@SessionScope
internal class MXOlmDevice @Inject constructor(
/**
* The store where crypto data is saved.
*/
@ -670,7 +678,7 @@ internal class MXOlmDevice(
val reason = String.format(MXCryptoError.DUPLICATE_MESSAGE_INDEX_REASON, decryptResult.mIndex)
Timber.e("## decryptGroupMessage() : $reason")
throw MXDecryptionException(MXCryptoError(MXCryptoError.DUPLICATED_MESSAGE_INDEX_ERROR_CODE,
MXCryptoError.UNABLE_TO_DECRYPT, reason))
MXCryptoError.UNABLE_TO_DECRYPT, reason))
}

inboundGroupSessionMessageIndexes[timeline]!!.put(messageIndexKey, true)
@ -703,7 +711,7 @@ internal class MXOlmDevice(
val reason = String.format(MXCryptoError.INBOUND_SESSION_MISMATCH_ROOM_ID_REASON, roomId, session.roomId)
Timber.e("## decryptGroupMessage() : $reason")
throw MXDecryptionException(MXCryptoError(MXCryptoError.INBOUND_SESSION_MISMATCH_ROOM_ID_ERROR_CODE,
MXCryptoError.UNABLE_TO_DECRYPT, reason))
MXCryptoError.UNABLE_TO_DECRYPT, reason))
}
} else {
Timber.e("## decryptGroupMessage() : Cannot retrieve inbound group session $sessionId")

View File

@ -20,9 +20,12 @@ import android.text.TextUtils
import im.vector.matrix.android.api.auth.data.Credentials
import im.vector.matrix.android.internal.crypto.model.MXDeviceInfo
import im.vector.matrix.android.internal.crypto.store.IMXCryptoStore
import im.vector.matrix.android.internal.session.SessionScope
import java.util.*
import javax.inject.Inject

internal class MyDeviceInfoHolder(
@SessionScope
internal class MyDeviceInfoHolder @Inject constructor(
// The credentials,
credentials: Credentials,
// the crypto store

View File

@ -17,9 +17,11 @@
package im.vector.matrix.android.internal.crypto

import im.vector.matrix.android.api.auth.data.Credentials
import im.vector.matrix.android.internal.session.SessionScope
import java.util.*
import javax.inject.Inject

internal class ObjectSigner(private val credentials: Credentials,
internal class ObjectSigner @Inject constructor(private val credentials: Credentials,
private val olmDevice: MXOlmDevice) {

/**

View File

@ -23,11 +23,14 @@ import im.vector.matrix.android.internal.crypto.model.MXKey
import im.vector.matrix.android.internal.crypto.model.rest.KeysUploadResponse
import im.vector.matrix.android.internal.crypto.tasks.UploadKeysTask
import im.vector.matrix.android.internal.di.MoshiProvider
import im.vector.matrix.android.internal.session.SessionScope
import org.matrix.olm.OlmAccount
import timber.log.Timber
import java.util.*
import javax.inject.Inject

internal class OneTimeKeysUploader(
@SessionScope
internal class OneTimeKeysUploader @Inject constructor(
private val credentials: Credentials,
private val olmDevice: MXOlmDevice,
private val objectSigner: ObjectSigner,

View File

@ -26,12 +26,15 @@ import im.vector.matrix.android.internal.crypto.model.rest.RoomKeyShareCancellat
import im.vector.matrix.android.internal.crypto.model.rest.RoomKeyShareRequest
import im.vector.matrix.android.internal.crypto.store.IMXCryptoStore
import im.vector.matrix.android.internal.crypto.tasks.SendToDeviceTask
import im.vector.matrix.android.internal.session.SessionScope
import im.vector.matrix.android.internal.task.TaskExecutor
import im.vector.matrix.android.internal.task.configureWith
import timber.log.Timber
import java.util.*
import javax.inject.Inject

internal class OutgoingRoomKeyRequestManager(
@SessionScope
internal class OutgoingRoomKeyRequestManager @Inject constructor(
private val cryptoStore: IMXCryptoStore,
private val sendToDeviceTask: SendToDeviceTask,
private val taskExecutor: TaskExecutor) {

View File

@ -20,10 +20,13 @@ import android.text.TextUtils
import im.vector.matrix.android.internal.crypto.algorithms.IMXDecrypting
import im.vector.matrix.android.internal.crypto.algorithms.megolm.MXMegolmDecryptionFactory
import im.vector.matrix.android.internal.crypto.algorithms.olm.MXOlmDecryptionFactory
import im.vector.matrix.android.internal.session.SessionScope
import timber.log.Timber
import java.util.*
import javax.inject.Inject

internal class RoomDecryptorProvider(
@SessionScope
internal class RoomDecryptorProvider @Inject constructor(
private val olmDecryptionFactory: MXOlmDecryptionFactory,
private val megolmDecryptionFactory: MXMegolmDecryptionFactory
) {

View File

@ -24,11 +24,13 @@ import im.vector.matrix.android.internal.crypto.model.MXKey
import im.vector.matrix.android.internal.crypto.model.MXOlmSessionResult
import im.vector.matrix.android.internal.crypto.model.MXUsersDevicesMap
import im.vector.matrix.android.internal.crypto.tasks.ClaimOneTimeKeysForUsersDeviceTask
import im.vector.matrix.android.internal.session.SessionScope
import timber.log.Timber
import java.util.*
import javax.inject.Inject

internal class EnsureOlmSessionsForDevicesAction(private val olmDevice: MXOlmDevice,
private val oneTimeKeysForUsersDeviceTask: ClaimOneTimeKeysForUsersDeviceTask) {
internal class EnsureOlmSessionsForDevicesAction @Inject constructor(private val olmDevice: MXOlmDevice,
private val oneTimeKeysForUsersDeviceTask: ClaimOneTimeKeysForUsersDeviceTask) {


suspend fun handle(devicesByUser: Map<String, List<MXDeviceInfo>>): Try<MXUsersDevicesMap<MXOlmSessionResult>> {

View File

@ -24,10 +24,12 @@ import im.vector.matrix.android.internal.crypto.model.MXDeviceInfo
import im.vector.matrix.android.internal.crypto.model.MXOlmSessionResult
import im.vector.matrix.android.internal.crypto.model.MXUsersDevicesMap
import im.vector.matrix.android.internal.crypto.store.IMXCryptoStore
import im.vector.matrix.android.internal.session.SessionScope
import timber.log.Timber
import java.util.*
import javax.inject.Inject

internal class EnsureOlmSessionsForUsersAction(private val olmDevice: MXOlmDevice,
internal class EnsureOlmSessionsForUsersAction @Inject constructor(private val olmDevice: MXOlmDevice,
private val cryptoStore: IMXCryptoStore,
private val ensureOlmSessionsForDevicesAction: EnsureOlmSessionsForDevicesAction) {


View File

@ -26,12 +26,14 @@ import im.vector.matrix.android.internal.crypto.RoomDecryptorProvider
import im.vector.matrix.android.internal.crypto.model.ImportRoomKeysResult
import im.vector.matrix.android.internal.crypto.model.rest.RoomKeyRequestBody
import im.vector.matrix.android.internal.crypto.store.IMXCryptoStore
import im.vector.matrix.android.internal.session.SessionScope
import timber.log.Timber
import javax.inject.Inject

internal class MegolmSessionDataImporter(private val olmDevice: MXOlmDevice,
private val roomDecryptorProvider: RoomDecryptorProvider,
private val outgoingRoomKeyRequestManager: OutgoingRoomKeyRequestManager,
private val cryptoStore: IMXCryptoStore) {
internal class MegolmSessionDataImporter @Inject constructor(private val olmDevice: MXOlmDevice,
private val roomDecryptorProvider: RoomDecryptorProvider,
private val outgoingRoomKeyRequestManager: OutgoingRoomKeyRequestManager,
private val cryptoStore: IMXCryptoStore) {

/**
* Import a list of megolm session keys.

View File

@ -23,12 +23,14 @@ import im.vector.matrix.android.internal.crypto.MXOlmDevice
import im.vector.matrix.android.internal.crypto.model.MXDeviceInfo
import im.vector.matrix.android.internal.crypto.model.rest.EncryptedMessage
import im.vector.matrix.android.internal.di.MoshiProvider
import im.vector.matrix.android.internal.session.SessionScope
import im.vector.matrix.android.internal.util.convertToUTF8
import timber.log.Timber
import java.util.*
import javax.inject.Inject

internal class MessageEncrypter(private val credentials: Credentials,
private val olmDevice: MXOlmDevice) {
internal class MessageEncrypter @Inject constructor(private val credentials: Credentials,
private val olmDevice: MXOlmDevice) {

/**
* Encrypt an event payload for a list of devices.

View File

@ -19,9 +19,11 @@ package im.vector.matrix.android.internal.crypto.actions
import im.vector.matrix.android.api.auth.data.Credentials
import im.vector.matrix.android.internal.crypto.keysbackup.KeysBackup
import im.vector.matrix.android.internal.crypto.store.IMXCryptoStore
import im.vector.matrix.android.internal.session.SessionScope
import timber.log.Timber
import javax.inject.Inject

internal class SetDeviceVerificationAction(private val cryptoStore: IMXCryptoStore,
internal class SetDeviceVerificationAction @Inject constructor(private val cryptoStore: IMXCryptoStore,
private val credentials: Credentials,
private val keysBackup: KeysBackup) {


View File

@ -24,9 +24,11 @@ import im.vector.matrix.android.internal.crypto.actions.EnsureOlmSessionsForDevi
import im.vector.matrix.android.internal.crypto.actions.MessageEncrypter
import im.vector.matrix.android.internal.crypto.store.IMXCryptoStore
import im.vector.matrix.android.internal.crypto.tasks.SendToDeviceTask
import im.vector.matrix.android.internal.session.SessionScope
import im.vector.matrix.android.internal.util.MatrixCoroutineDispatchers
import javax.inject.Inject

internal class MXMegolmDecryptionFactory(private val credentials: Credentials,
internal class MXMegolmDecryptionFactory @Inject constructor(private val credentials: Credentials,
private val olmDevice: MXOlmDevice,
private val deviceListManager: DeviceListManager,
private val outgoingRoomKeyRequestManager: OutgoingRoomKeyRequestManager,

View File

@ -25,9 +25,11 @@ import im.vector.matrix.android.internal.crypto.keysbackup.KeysBackup
import im.vector.matrix.android.internal.crypto.repository.WarnOnUnknownDeviceRepository
import im.vector.matrix.android.internal.crypto.store.IMXCryptoStore
import im.vector.matrix.android.internal.crypto.tasks.SendToDeviceTask
import im.vector.matrix.android.internal.session.SessionScope
import im.vector.matrix.android.internal.task.TaskExecutor
import javax.inject.Inject

internal class MXMegolmEncryptionFactory(
internal class MXMegolmEncryptionFactory @Inject constructor(
private val olmDevice: MXOlmDevice,
private val keysBackup: KeysBackup,
private val cryptoStore: IMXCryptoStore,

View File

@ -18,9 +18,11 @@ package im.vector.matrix.android.internal.crypto.algorithms.olm

import im.vector.matrix.android.api.auth.data.Credentials
import im.vector.matrix.android.internal.crypto.MXOlmDevice
import im.vector.matrix.android.internal.session.SessionScope
import javax.inject.Inject

internal class MXOlmDecryptionFactory(private val olmDevice: MXOlmDevice,
private val credentials: Credentials) {
internal class MXOlmDecryptionFactory @Inject constructor(private val olmDevice: MXOlmDevice,
private val credentials: Credentials) {

fun create(): MXOlmDecryption {
return MXOlmDecryption(

View File

@ -21,14 +21,16 @@ import im.vector.matrix.android.internal.crypto.MXOlmDevice
import im.vector.matrix.android.internal.crypto.actions.EnsureOlmSessionsForUsersAction
import im.vector.matrix.android.internal.crypto.actions.MessageEncrypter
import im.vector.matrix.android.internal.crypto.store.IMXCryptoStore
import im.vector.matrix.android.internal.session.SessionScope
import im.vector.matrix.android.internal.util.MatrixCoroutineDispatchers
import javax.inject.Inject

internal class MXOlmEncryptionFactory(private val olmDevice: MXOlmDevice,
private val cryptoStore: IMXCryptoStore,
private val messageEncrypter: MessageEncrypter,
private val deviceListManager: DeviceListManager,
private val coroutineDispatchers: MatrixCoroutineDispatchers,
private val ensureOlmSessionsForUsersAction: EnsureOlmSessionsForUsersAction) {
internal class MXOlmEncryptionFactory @Inject constructor(private val olmDevice: MXOlmDevice,
private val cryptoStore: IMXCryptoStore,
private val messageEncrypter: MessageEncrypter,
private val deviceListManager: DeviceListManager,
private val coroutineDispatchers: MatrixCoroutineDispatchers,
private val ensureOlmSessionsForUsersAction: EnsureOlmSessionsForUsersAction) {

fun create(roomId: String): MXOlmEncryption {
return MXOlmEncryption(

View File

@ -51,6 +51,7 @@ import im.vector.matrix.android.internal.crypto.store.IMXCryptoStore
import im.vector.matrix.android.internal.crypto.store.db.model.KeysBackupDataEntity
import im.vector.matrix.android.internal.di.MoshiProvider
import im.vector.matrix.android.internal.extensions.foldToCallback
import im.vector.matrix.android.internal.session.SessionScope
import im.vector.matrix.android.internal.task.Task
import im.vector.matrix.android.internal.task.TaskExecutor
import im.vector.matrix.android.internal.task.TaskThread
@ -66,13 +67,16 @@ import org.matrix.olm.OlmPkMessage
import timber.log.Timber
import java.security.InvalidParameterException
import java.util.*
import javax.inject.Inject
import kotlin.collections.HashMap

/**
* A KeysBackup class instance manage incremental backup of e2e keys (megolm keys)
* to the user's homeserver.
*/
internal class KeysBackup(

@SessionScope
internal class KeysBackup @Inject constructor(
private val credentials: Credentials,
private val cryptoStore: IMXCryptoStore,
private val olmDevice: MXOlmDevice,
@ -448,7 +452,8 @@ internal class KeysBackup(
val myUserId = credentials.userId

// Get current signatures, or create an empty set
val myUserSignatures = (authData.signatures!![myUserId]?.toMutableMap() ?: HashMap())
val myUserSignatures = (authData.signatures!![myUserId]?.toMutableMap()
?: HashMap())

if (trust) {
// Add current device signature
@ -1309,7 +1314,8 @@ internal class KeysBackup(
"algorithm" to sessionData!!.algorithm,
"sender_key" to sessionData.senderKey,
"sender_claimed_keys" to sessionData.senderClaimedKeys,
"forwarding_curve25519_key_chain" to (sessionData.forwardingCurve25519KeyChain ?: ArrayList<Any>()),
"forwarding_curve25519_key_chain" to (sessionData.forwardingCurve25519KeyChain
?: ArrayList<Any>()),
"session_key" to sessionData.sessionKey)

var encryptedSessionBackupData: OlmPkMessage? = null

View File

@ -22,11 +22,11 @@ import im.vector.matrix.android.internal.crypto.keysbackup.model.rest.CreateKeys
import im.vector.matrix.android.internal.crypto.keysbackup.model.rest.KeysVersion
import im.vector.matrix.android.internal.network.executeRequest
import im.vector.matrix.android.internal.task.Task
import javax.inject.Inject

internal interface CreateKeysBackupVersionTask : Task<CreateKeysBackupVersionBody, KeysVersion>


internal class DefaultCreateKeysBackupVersionTask(private val roomKeysApi: RoomKeysApi)
internal class DefaultCreateKeysBackupVersionTask @Inject constructor(private val roomKeysApi: RoomKeysApi)
: CreateKeysBackupVersionTask {



View File

@ -19,7 +19,9 @@ package im.vector.matrix.android.internal.crypto.keysbackup.tasks
import arrow.core.Try
import im.vector.matrix.android.internal.crypto.keysbackup.api.RoomKeysApi
import im.vector.matrix.android.internal.network.executeRequest
import im.vector.matrix.android.internal.session.SessionScope
import im.vector.matrix.android.internal.task.Task
import javax.inject.Inject


internal interface DeleteBackupTask : Task<DeleteBackupTask.Params, Unit> {
@ -28,8 +30,7 @@ internal interface DeleteBackupTask : Task<DeleteBackupTask.Params, Unit> {
)
}


internal class DefaultDeleteBackupTask(private val roomKeysApi: RoomKeysApi)
internal class DefaultDeleteBackupTask @Inject constructor(private val roomKeysApi: RoomKeysApi)
: DeleteBackupTask {

override suspend fun execute(params: DeleteBackupTask.Params): Try<Unit> {

View File

@ -19,7 +19,9 @@ package im.vector.matrix.android.internal.crypto.keysbackup.tasks
import arrow.core.Try
import im.vector.matrix.android.internal.crypto.keysbackup.api.RoomKeysApi
import im.vector.matrix.android.internal.network.executeRequest
import im.vector.matrix.android.internal.session.SessionScope
import im.vector.matrix.android.internal.task.Task
import javax.inject.Inject

internal interface DeleteRoomSessionDataTask : Task<DeleteRoomSessionDataTask.Params, Unit> {
data class Params(
@ -29,8 +31,7 @@ internal interface DeleteRoomSessionDataTask : Task<DeleteRoomSessionDataTask.Pa
)
}


internal class DefaultDeleteRoomSessionDataTask(private val roomKeysApi: RoomKeysApi)
internal class DefaultDeleteRoomSessionDataTask @Inject constructor(private val roomKeysApi: RoomKeysApi)
: DeleteRoomSessionDataTask {

override suspend fun execute(params: DeleteRoomSessionDataTask.Params): Try<Unit> {

View File

@ -19,7 +19,9 @@ package im.vector.matrix.android.internal.crypto.keysbackup.tasks
import arrow.core.Try
import im.vector.matrix.android.internal.crypto.keysbackup.api.RoomKeysApi
import im.vector.matrix.android.internal.network.executeRequest
import im.vector.matrix.android.internal.session.SessionScope
import im.vector.matrix.android.internal.task.Task
import javax.inject.Inject

internal interface DeleteRoomSessionsDataTask : Task<DeleteRoomSessionsDataTask.Params, Unit> {
data class Params(
@ -28,8 +30,7 @@ internal interface DeleteRoomSessionsDataTask : Task<DeleteRoomSessionsDataTask.
)
}


internal class DefaultDeleteRoomSessionsDataTask(private val roomKeysApi: RoomKeysApi)
internal class DefaultDeleteRoomSessionsDataTask @Inject constructor(private val roomKeysApi: RoomKeysApi)
: DeleteRoomSessionsDataTask {

override suspend fun execute(params: DeleteRoomSessionsDataTask.Params): Try<Unit> {

View File

@ -19,7 +19,9 @@ package im.vector.matrix.android.internal.crypto.keysbackup.tasks
import arrow.core.Try
import im.vector.matrix.android.internal.crypto.keysbackup.api.RoomKeysApi
import im.vector.matrix.android.internal.network.executeRequest
import im.vector.matrix.android.internal.session.SessionScope
import im.vector.matrix.android.internal.task.Task
import javax.inject.Inject

internal interface DeleteSessionsDataTask : Task<DeleteSessionsDataTask.Params, Unit> {
data class Params(
@ -27,8 +29,7 @@ internal interface DeleteSessionsDataTask : Task<DeleteSessionsDataTask.Params,
)
}


internal class DefaultDeleteSessionsDataTask(private val roomKeysApi: RoomKeysApi)
internal class DefaultDeleteSessionsDataTask @Inject constructor(private val roomKeysApi: RoomKeysApi)
: DeleteSessionsDataTask {

override suspend fun execute(params: DeleteSessionsDataTask.Params): Try<Unit> {

View File

@ -21,11 +21,11 @@ import im.vector.matrix.android.internal.crypto.keysbackup.api.RoomKeysApi
import im.vector.matrix.android.internal.crypto.keysbackup.model.rest.KeysVersionResult
import im.vector.matrix.android.internal.network.executeRequest
import im.vector.matrix.android.internal.task.Task
import javax.inject.Inject

internal interface GetKeysBackupLastVersionTask : Task<Unit, KeysVersionResult>


internal class DefaultGetKeysBackupLastVersionTask(private val roomKeysApi: RoomKeysApi)
internal class DefaultGetKeysBackupLastVersionTask @Inject constructor(private val roomKeysApi: RoomKeysApi)
: GetKeysBackupLastVersionTask {



View File

@ -21,11 +21,11 @@ import im.vector.matrix.android.internal.crypto.keysbackup.api.RoomKeysApi
import im.vector.matrix.android.internal.crypto.keysbackup.model.rest.KeysVersionResult
import im.vector.matrix.android.internal.network.executeRequest
import im.vector.matrix.android.internal.task.Task
import javax.inject.Inject

internal interface GetKeysBackupVersionTask : Task<String, KeysVersionResult>


internal class DefaultGetKeysBackupVersionTask(private val roomKeysApi: RoomKeysApi)
internal class DefaultGetKeysBackupVersionTask @Inject constructor(private val roomKeysApi: RoomKeysApi)
: GetKeysBackupVersionTask {



View File

@ -20,7 +20,9 @@ import arrow.core.Try
import im.vector.matrix.android.internal.crypto.keysbackup.api.RoomKeysApi
import im.vector.matrix.android.internal.crypto.keysbackup.model.rest.KeyBackupData
import im.vector.matrix.android.internal.network.executeRequest
import im.vector.matrix.android.internal.session.SessionScope
import im.vector.matrix.android.internal.task.Task
import javax.inject.Inject

internal interface GetRoomSessionDataTask : Task<GetRoomSessionDataTask.Params, KeyBackupData> {
data class Params(
@ -30,8 +32,7 @@ internal interface GetRoomSessionDataTask : Task<GetRoomSessionDataTask.Params,
)
}


internal class DefaultGetRoomSessionDataTask(private val roomKeysApi: RoomKeysApi)
internal class DefaultGetRoomSessionDataTask @Inject constructor(private val roomKeysApi: RoomKeysApi)
: GetRoomSessionDataTask {

override suspend fun execute(params: GetRoomSessionDataTask.Params): Try<KeyBackupData> {

View File

@ -20,7 +20,9 @@ import arrow.core.Try
import im.vector.matrix.android.internal.crypto.keysbackup.api.RoomKeysApi
import im.vector.matrix.android.internal.crypto.keysbackup.model.rest.RoomKeysBackupData
import im.vector.matrix.android.internal.network.executeRequest
import im.vector.matrix.android.internal.session.SessionScope
import im.vector.matrix.android.internal.task.Task
import javax.inject.Inject


internal interface GetRoomSessionsDataTask : Task<GetRoomSessionsDataTask.Params, RoomKeysBackupData> {
@ -30,8 +32,7 @@ internal interface GetRoomSessionsDataTask : Task<GetRoomSessionsDataTask.Params
)
}


internal class DefaultGetRoomSessionsDataTask(private val roomKeysApi: RoomKeysApi)
internal class DefaultGetRoomSessionsDataTask @Inject constructor(private val roomKeysApi: RoomKeysApi)
: GetRoomSessionsDataTask {

override suspend fun execute(params: GetRoomSessionsDataTask.Params): Try<RoomKeysBackupData> {

View File

@ -20,7 +20,9 @@ import arrow.core.Try
import im.vector.matrix.android.internal.crypto.keysbackup.api.RoomKeysApi
import im.vector.matrix.android.internal.crypto.keysbackup.model.rest.KeysBackupData
import im.vector.matrix.android.internal.network.executeRequest
import im.vector.matrix.android.internal.session.SessionScope
import im.vector.matrix.android.internal.task.Task
import javax.inject.Inject

internal interface GetSessionsDataTask : Task<GetSessionsDataTask.Params, KeysBackupData> {
data class Params(
@ -28,8 +30,7 @@ internal interface GetSessionsDataTask : Task<GetSessionsDataTask.Params, KeysBa
)
}


internal class DefaultGetSessionsDataTask(private val roomKeysApi: RoomKeysApi)
internal class DefaultGetSessionsDataTask @Inject constructor(private val roomKeysApi: RoomKeysApi)
: GetSessionsDataTask {

override suspend fun execute(params: GetSessionsDataTask.Params): Try<KeysBackupData> {

View File

@ -21,7 +21,9 @@ import im.vector.matrix.android.internal.crypto.keysbackup.api.RoomKeysApi
import im.vector.matrix.android.internal.crypto.keysbackup.model.rest.KeyBackupData
import im.vector.matrix.android.internal.crypto.keysbackup.model.rest.BackupKeysResult
import im.vector.matrix.android.internal.network.executeRequest
import im.vector.matrix.android.internal.session.SessionScope
import im.vector.matrix.android.internal.task.Task
import javax.inject.Inject

internal interface StoreRoomSessionDataTask : Task<StoreRoomSessionDataTask.Params, BackupKeysResult> {
data class Params(
@ -32,8 +34,7 @@ internal interface StoreRoomSessionDataTask : Task<StoreRoomSessionDataTask.Para
)
}


internal class DefaultStoreRoomSessionDataTask(private val roomKeysApi: RoomKeysApi)
internal class DefaultStoreRoomSessionDataTask @Inject constructor(private val roomKeysApi: RoomKeysApi)
: StoreRoomSessionDataTask {

override suspend fun execute(params: StoreRoomSessionDataTask.Params): Try<BackupKeysResult> {

View File

@ -21,7 +21,9 @@ import im.vector.matrix.android.internal.crypto.keysbackup.api.RoomKeysApi
import im.vector.matrix.android.internal.crypto.keysbackup.model.rest.RoomKeysBackupData
import im.vector.matrix.android.internal.crypto.keysbackup.model.rest.BackupKeysResult
import im.vector.matrix.android.internal.network.executeRequest
import im.vector.matrix.android.internal.session.SessionScope
import im.vector.matrix.android.internal.task.Task
import javax.inject.Inject

internal interface StoreRoomSessionsDataTask : Task<StoreRoomSessionsDataTask.Params, BackupKeysResult> {
data class Params(
@ -31,8 +33,7 @@ internal interface StoreRoomSessionsDataTask : Task<StoreRoomSessionsDataTask.Pa
)
}


internal class DefaultStoreRoomSessionsDataTask(private val roomKeysApi: RoomKeysApi)
internal class DefaultStoreRoomSessionsDataTask @Inject constructor(private val roomKeysApi: RoomKeysApi)
: StoreRoomSessionsDataTask {

override suspend fun execute(params: StoreRoomSessionsDataTask.Params): Try<BackupKeysResult> {

View File

@ -21,7 +21,9 @@ import im.vector.matrix.android.internal.crypto.keysbackup.api.RoomKeysApi
import im.vector.matrix.android.internal.crypto.keysbackup.model.rest.KeysBackupData
import im.vector.matrix.android.internal.crypto.keysbackup.model.rest.BackupKeysResult
import im.vector.matrix.android.internal.network.executeRequest
import im.vector.matrix.android.internal.session.SessionScope
import im.vector.matrix.android.internal.task.Task
import javax.inject.Inject

internal interface StoreSessionsDataTask : Task<StoreSessionsDataTask.Params, BackupKeysResult> {
data class Params(
@ -30,8 +32,7 @@ internal interface StoreSessionsDataTask : Task<StoreSessionsDataTask.Params, Ba
)
}


internal class DefaultStoreSessionsDataTask(private val roomKeysApi: RoomKeysApi)
internal class DefaultStoreSessionsDataTask @Inject constructor(private val roomKeysApi: RoomKeysApi)
: StoreSessionsDataTask {

override suspend fun execute(params: StoreSessionsDataTask.Params): Try<BackupKeysResult> {

View File

@ -21,6 +21,7 @@ import im.vector.matrix.android.internal.crypto.keysbackup.api.RoomKeysApi
import im.vector.matrix.android.internal.crypto.keysbackup.model.rest.UpdateKeysBackupVersionBody
import im.vector.matrix.android.internal.network.executeRequest
import im.vector.matrix.android.internal.task.Task
import javax.inject.Inject

internal interface UpdateKeysBackupVersionTask : Task<UpdateKeysBackupVersionTask.Params, Unit> {
data class Params(
@ -29,8 +30,7 @@ internal interface UpdateKeysBackupVersionTask : Task<UpdateKeysBackupVersionTas
)
}


internal class DefaultUpdateKeysBackupVersionTask(private val roomKeysApi: RoomKeysApi)
internal class DefaultUpdateKeysBackupVersionTask @Inject constructor(private val roomKeysApi: RoomKeysApi)
: UpdateKeysBackupVersionTask {



View File

@ -16,7 +16,11 @@

package im.vector.matrix.android.internal.crypto.repository

internal class WarnOnUnknownDeviceRepository {
import im.vector.matrix.android.internal.session.SessionScope
import javax.inject.Inject

@SessionScope
internal class WarnOnUnknownDeviceRepository @Inject constructor() {

// TODO: set it back to true by default. Need UI
// Warn the user if some new devices are detected while encrypting a message.

View File

@ -29,6 +29,7 @@ import im.vector.matrix.android.internal.crypto.store.db.model.*
import im.vector.matrix.android.internal.crypto.store.db.query.delete
import im.vector.matrix.android.internal.crypto.store.db.query.getById
import im.vector.matrix.android.internal.crypto.store.db.query.getOrCreate
import im.vector.matrix.android.internal.session.SessionScope
import io.realm.RealmConfiguration
import io.realm.Sort
import io.realm.kotlin.where
@ -38,6 +39,7 @@ import timber.log.Timber
import kotlin.collections.set

// enableFileEncryption is used to migrate the previous store
@SessionScope
internal class RealmCryptoStore(private val enableFileEncryption: Boolean = false,
private val realmConfiguration: RealmConfiguration,
private val credentials: Credentials) : IMXCryptoStore {

View File

@ -23,9 +23,11 @@ import im.vector.matrix.android.internal.crypto.model.MXUsersDevicesMap
import im.vector.matrix.android.internal.crypto.model.rest.KeysClaimBody
import im.vector.matrix.android.internal.crypto.model.rest.KeysClaimResponse
import im.vector.matrix.android.internal.network.executeRequest
import im.vector.matrix.android.internal.session.SessionScope
import im.vector.matrix.android.internal.task.Task
import timber.log.Timber
import java.util.*
import javax.inject.Inject

internal interface ClaimOneTimeKeysForUsersDeviceTask : Task<ClaimOneTimeKeysForUsersDeviceTask.Params, MXUsersDevicesMap<MXKey>> {
data class Params(
@ -34,7 +36,7 @@ internal interface ClaimOneTimeKeysForUsersDeviceTask : Task<ClaimOneTimeKeysFor
)
}

internal class DefaultClaimOneTimeKeysForUsersDevice(private val cryptoApi: CryptoApi)
internal class DefaultClaimOneTimeKeysForUsersDevice @Inject constructor(private val cryptoApi: CryptoApi)
: ClaimOneTimeKeysForUsersDeviceTask {

override suspend fun execute(params: ClaimOneTimeKeysForUsersDeviceTask.Params): Try<MXUsersDevicesMap<MXKey>> {

View File

@ -25,7 +25,9 @@ import im.vector.matrix.android.internal.crypto.api.CryptoApi
import im.vector.matrix.android.internal.crypto.model.rest.DeleteDeviceParams
import im.vector.matrix.android.internal.di.MoshiProvider
import im.vector.matrix.android.internal.network.executeRequest
import im.vector.matrix.android.internal.session.SessionScope
import im.vector.matrix.android.internal.task.Task
import javax.inject.Inject

internal interface DeleteDeviceTask : Task<DeleteDeviceTask.Params, Unit> {
data class Params(
@ -33,7 +35,7 @@ internal interface DeleteDeviceTask : Task<DeleteDeviceTask.Params, Unit> {
)
}

internal class DefaultDeleteDeviceTask(private val cryptoApi: CryptoApi)
internal class DefaultDeleteDeviceTask @Inject constructor(private val cryptoApi: CryptoApi)
: DeleteDeviceTask {

override suspend fun execute(params: DeleteDeviceTask.Params): Try<Unit> {

View File

@ -24,6 +24,7 @@ import im.vector.matrix.android.internal.crypto.model.rest.DeleteDeviceAuth
import im.vector.matrix.android.internal.crypto.model.rest.DeleteDeviceParams
import im.vector.matrix.android.internal.network.executeRequest
import im.vector.matrix.android.internal.task.Task
import javax.inject.Inject

internal interface DeleteDeviceWithUserPasswordTask : Task<DeleteDeviceWithUserPasswordTask.Params, Unit> {
data class Params(
@ -33,8 +34,8 @@ internal interface DeleteDeviceWithUserPasswordTask : Task<DeleteDeviceWithUserP
)
}

internal class DefaultDeleteDeviceWithUserPasswordTask(private val cryptoApi: CryptoApi,
private val credentials: Credentials)
internal class DefaultDeleteDeviceWithUserPasswordTask @Inject constructor(private val cryptoApi: CryptoApi,
private val credentials: Credentials)
: DeleteDeviceWithUserPasswordTask {

override suspend fun execute(params: DeleteDeviceWithUserPasswordTask.Params): Try<Unit> {

View File

@ -22,8 +22,10 @@ import im.vector.matrix.android.internal.crypto.api.CryptoApi
import im.vector.matrix.android.internal.crypto.model.rest.KeysQueryBody
import im.vector.matrix.android.internal.crypto.model.rest.KeysQueryResponse
import im.vector.matrix.android.internal.network.executeRequest
import im.vector.matrix.android.internal.session.SessionScope
import im.vector.matrix.android.internal.task.Task
import java.util.*
import javax.inject.Inject

internal interface DownloadKeysForUsersTask : Task<DownloadKeysForUsersTask.Params, KeysQueryResponse> {
data class Params(
@ -33,7 +35,7 @@ internal interface DownloadKeysForUsersTask : Task<DownloadKeysForUsersTask.Para
val token: String?)
}

internal class DefaultDownloadKeysForUsers(private val cryptoApi: CryptoApi)
internal class DefaultDownloadKeysForUsers @Inject constructor(private val cryptoApi: CryptoApi)
: DownloadKeysForUsersTask {

override suspend fun execute(params: DownloadKeysForUsersTask.Params): Try<KeysQueryResponse> {

View File

@ -20,11 +20,13 @@ import arrow.core.Try
import im.vector.matrix.android.internal.crypto.api.CryptoApi
import im.vector.matrix.android.internal.crypto.model.rest.DevicesListResponse
import im.vector.matrix.android.internal.network.executeRequest
import im.vector.matrix.android.internal.session.SessionScope
import im.vector.matrix.android.internal.task.Task
import javax.inject.Inject

internal interface GetDevicesTask : Task<Unit, DevicesListResponse>

internal class DefaultGetDevicesTask(private val cryptoApi: CryptoApi)
internal class DefaultGetDevicesTask @Inject constructor(private val cryptoApi: CryptoApi)
: GetDevicesTask {

override suspend fun execute(params: Unit): Try<DevicesListResponse> {

View File

@ -20,7 +20,9 @@ import arrow.core.Try
import im.vector.matrix.android.internal.crypto.api.CryptoApi
import im.vector.matrix.android.internal.crypto.model.rest.KeyChangesResponse
import im.vector.matrix.android.internal.network.executeRequest
import im.vector.matrix.android.internal.session.SessionScope
import im.vector.matrix.android.internal.task.Task
import javax.inject.Inject

internal interface GetKeyChangesTask : Task<GetKeyChangesTask.Params, KeyChangesResponse> {
data class Params(
@ -31,7 +33,7 @@ internal interface GetKeyChangesTask : Task<GetKeyChangesTask.Params, KeyChanges
)
}

internal class DefaultGetKeyChangesTask(private val cryptoApi: CryptoApi)
internal class DefaultGetKeyChangesTask @Inject constructor(private val cryptoApi: CryptoApi)
: GetKeyChangesTask {

override suspend fun execute(params: GetKeyChangesTask.Params): Try<KeyChangesResponse> {

View File

@ -21,8 +21,10 @@ import im.vector.matrix.android.internal.crypto.api.CryptoApi
import im.vector.matrix.android.internal.crypto.model.MXUsersDevicesMap
import im.vector.matrix.android.internal.crypto.model.rest.SendToDeviceBody
import im.vector.matrix.android.internal.network.executeRequest
import im.vector.matrix.android.internal.session.SessionScope
import im.vector.matrix.android.internal.task.Task
import java.util.*
import javax.inject.Inject

internal interface SendToDeviceTask : Task<SendToDeviceTask.Params, Unit> {
data class Params(
@ -35,7 +37,7 @@ internal interface SendToDeviceTask : Task<SendToDeviceTask.Params, Unit> {
)
}

internal class DefaultSendToDeviceTask(private val cryptoApi: CryptoApi)
internal class DefaultSendToDeviceTask @Inject constructor(private val cryptoApi: CryptoApi)
: SendToDeviceTask {

override suspend fun execute(params: SendToDeviceTask.Params): Try<Unit> {

View File

@ -21,7 +21,9 @@ import arrow.core.Try
import im.vector.matrix.android.internal.crypto.api.CryptoApi
import im.vector.matrix.android.internal.crypto.model.rest.UpdateDeviceInfoBody
import im.vector.matrix.android.internal.network.executeRequest
import im.vector.matrix.android.internal.session.SessionScope
import im.vector.matrix.android.internal.task.Task
import javax.inject.Inject

internal interface SetDeviceNameTask : Task<SetDeviceNameTask.Params, Unit> {
data class Params(
@ -32,7 +34,7 @@ internal interface SetDeviceNameTask : Task<SetDeviceNameTask.Params, Unit> {
)
}

internal class DefaultSetDeviceNameTask(private val cryptoApi: CryptoApi)
internal class DefaultSetDeviceNameTask @Inject constructor(private val cryptoApi: CryptoApi)
: SetDeviceNameTask {

override suspend fun execute(params: SetDeviceNameTask.Params): Try<Unit> {

View File

@ -23,8 +23,10 @@ import im.vector.matrix.android.internal.crypto.model.rest.KeysUploadResponse
import im.vector.matrix.android.internal.crypto.model.rest.DeviceKeys
import im.vector.matrix.android.internal.crypto.model.rest.KeysUploadBody
import im.vector.matrix.android.internal.network.executeRequest
import im.vector.matrix.android.internal.session.SessionScope
import im.vector.matrix.android.internal.task.Task
import im.vector.matrix.android.internal.util.convertToUTF8
import javax.inject.Inject

internal interface UploadKeysTask : Task<UploadKeysTask.Params, KeysUploadResponse> {
data class Params(
@ -36,7 +38,7 @@ internal interface UploadKeysTask : Task<UploadKeysTask.Params, KeysUploadRespon
val deviceId: String)
}

internal class DefaultUploadKeysTask(private val cryptoApi: CryptoApi)
internal class DefaultUploadKeysTask @Inject constructor(private val cryptoApi: CryptoApi)
: UploadKeysTask {

override suspend fun execute(params: UploadKeysTask.Params): Try<KeysUploadResponse> {

View File

@ -35,6 +35,7 @@ import im.vector.matrix.android.internal.crypto.model.MXUsersDevicesMap
import im.vector.matrix.android.internal.crypto.model.rest.*
import im.vector.matrix.android.internal.crypto.store.IMXCryptoStore
import im.vector.matrix.android.internal.crypto.tasks.SendToDeviceTask
import im.vector.matrix.android.internal.session.SessionScope
import im.vector.matrix.android.internal.task.TaskExecutor
import im.vector.matrix.android.internal.task.configureWith
import im.vector.matrix.android.internal.util.MatrixCoroutineDispatchers
@ -42,6 +43,7 @@ import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.launch
import timber.log.Timber
import java.util.*
import javax.inject.Inject
import kotlin.collections.HashMap

/**
@ -49,14 +51,16 @@ import kotlin.collections.HashMap
* Short codes interactive verification is a more user friendly way of verifying devices
* that is still maintaining a good level of security (alternative to the 43-character strings compare method).
*/
internal class DefaultSasVerificationService(private val credentials: Credentials,
private val cryptoStore: IMXCryptoStore,
private val myDeviceInfoHolder: MyDeviceInfoHolder,
private val deviceListManager: DeviceListManager,
private val setDeviceVerificationAction: SetDeviceVerificationAction,
private val sendToDeviceTask: SendToDeviceTask,
private val coroutineDispatchers: MatrixCoroutineDispatchers,
private val taskExecutor: TaskExecutor)

@SessionScope
internal class DefaultSasVerificationService @Inject constructor(private val credentials: Credentials,
private val cryptoStore: IMXCryptoStore,
private val myDeviceInfoHolder: MyDeviceInfoHolder,
private val deviceListManager: DeviceListManager,
private val setDeviceVerificationAction: SetDeviceVerificationAction,
private val sendToDeviceTask: SendToDeviceTask,
private val coroutineDispatchers: MatrixCoroutineDispatchers,
private val taskExecutor: TaskExecutor)
: VerificationTransaction.Listener, SasVerificationService {

private val uiHandler = Handler(Looper.getMainLooper())

View File

@ -0,0 +1,29 @@
/*
*
* * Copyright 2019 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.matrix.android.internal.di

import javax.inject.Qualifier

@Qualifier
@Retention(AnnotationRetention.RUNTIME)
annotation class Authenticated

@Qualifier
@Retention(AnnotationRetention.RUNTIME)
annotation class Unauthenticated

View File

@ -16,22 +16,16 @@

package im.vector.matrix.android.internal.di

import org.koin.core.Koin
import org.koin.core.KoinContext
import org.koin.standalone.KoinComponent
import javax.inject.Qualifier

internal object MatrixKoinHolder {
@Qualifier
@Retention(AnnotationRetention.RUNTIME)
annotation class AuthDatabase

val instance: Koin by lazy {
Koin.create()
}
@Qualifier
@Retention(AnnotationRetention.RUNTIME)
annotation class SessionDatabase

}

internal interface MatrixKoinComponent : KoinComponent {

override fun getKoin(): KoinContext {
return MatrixKoinHolder.instance.koinContext
}

}
@Qualifier
@Retention(AnnotationRetention.RUNTIME)
annotation class CryptoDatabase

View File

@ -0,0 +1,75 @@
/*
* Copyright 2019 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.matrix.android.internal.di

import android.content.Context
import android.content.res.Resources
import com.squareup.moshi.Moshi
import dagger.BindsInstance
import dagger.Component
import im.vector.matrix.android.api.Matrix
import im.vector.matrix.android.api.auth.Authenticator
import im.vector.matrix.android.internal.SessionManager
import im.vector.matrix.android.internal.auth.AuthModule
import im.vector.matrix.android.internal.auth.SessionParamsStore
import im.vector.matrix.android.internal.network.NetworkConnectivityChecker
import im.vector.matrix.android.internal.network.RetrofitFactory
import im.vector.matrix.android.internal.task.TaskExecutor
import im.vector.matrix.android.internal.util.BackgroundDetectionObserver
import im.vector.matrix.android.internal.util.MatrixCoroutineDispatchers
import okhttp3.OkHttpClient
import org.matrix.olm.OlmManager
import retrofit2.Retrofit


@Component(modules = [MatrixModule::class, NetworkModule::class, AuthModule::class])
@MatrixScope
internal interface MatrixComponent {

fun matrixCoroutineDispatchers(): MatrixCoroutineDispatchers

fun moshi(): Moshi

@Unauthenticated
fun okHttpClient(): OkHttpClient

fun authenticator(): Authenticator

fun context(): Context

fun resources(): Resources

fun olmManager(): OlmManager

fun taskExecutor(): TaskExecutor

fun sessionParamsStore(): SessionParamsStore

fun networkConnectivityChecker(): NetworkConnectivityChecker

fun backgroundDetectionObserver(): BackgroundDetectionObserver

fun sessionManager(): SessionManager

fun inject(matrix: Matrix)

@Component.Factory
interface Factory {
fun create(@BindsInstance context: Context): MatrixComponent
}

}

View File

@ -17,47 +17,44 @@
package im.vector.matrix.android.internal.di

import android.content.Context
import android.content.res.Resources
import android.os.Handler
import android.os.HandlerThread
import im.vector.matrix.android.internal.task.TaskExecutor
import im.vector.matrix.android.internal.util.BackgroundDetectionObserver
import dagger.Module
import dagger.Provides
import im.vector.matrix.android.internal.util.MatrixCoroutineDispatchers
import im.vector.matrix.android.internal.util.StringProvider
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.android.asCoroutineDispatcher
import org.koin.dsl.module.module
import org.matrix.olm.OlmManager

@Module
internal object MatrixModule {

class MatrixModule(private val context: Context) {

val definition = module {

single {
context
}

single {
val THREAD_CRYPTO_NAME = "Crypto_Thread"
val handlerThread = HandlerThread(THREAD_CRYPTO_NAME)
handlerThread.start()

MatrixCoroutineDispatchers(io = Dispatchers.IO,
computation = Dispatchers.IO,
main = Dispatchers.Main,
crypto = Handler(handlerThread.looper).asCoroutineDispatcher("crypto")
)
}

single {
TaskExecutor(get())
}
single {
StringProvider(context.resources)
}

single {
BackgroundDetectionObserver()
}
@JvmStatic
@Provides
fun providesMatrixCoroutineDispatchers(): MatrixCoroutineDispatchers {
val THREAD_CRYPTO_NAME = "Crypto_Thread"
val handlerThread = HandlerThread(THREAD_CRYPTO_NAME)
handlerThread.start()

return MatrixCoroutineDispatchers(io = Dispatchers.IO,
computation = Dispatchers.IO,
main = Dispatchers.Main,
crypto = Handler(handlerThread.looper).asCoroutineDispatcher("crypto")
)
}

@JvmStatic
@Provides
fun providesResources(context: Context): Resources {
return context.resources
}

@JvmStatic
@Provides
@MatrixScope
fun providesOlmManager(): OlmManager {
return OlmManager()
}

}

View File

@ -0,0 +1,29 @@
/*
* Copyright 2019 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.matrix.android.internal.di;

import java.lang.annotation.Documented;
import java.lang.annotation.Retention;

import javax.inject.Scope;

import static java.lang.annotation.RetentionPolicy.RUNTIME;

@Scope
@Documented
@Retention(RUNTIME)
public @interface MatrixScope {}

View File

@ -17,85 +17,80 @@
package im.vector.matrix.android.internal.di

import com.facebook.stetho.okhttp3.StethoInterceptor
import com.squareup.moshi.Moshi
import dagger.Module
import dagger.Provides
import im.vector.matrix.android.BuildConfig
import im.vector.matrix.android.internal.network.*
import im.vector.matrix.android.internal.network.AccessTokenInterceptor
import im.vector.matrix.android.internal.network.UnitConverterFactory
import im.vector.matrix.android.internal.network.UserAgentInterceptor
import im.vector.matrix.android.internal.network.interceptors.CurlLoggingInterceptor
import im.vector.matrix.android.internal.network.interceptors.FormattedJsonHttpLogger
import okhttp3.OkHttpClient
import okhttp3.logging.HttpLoggingInterceptor
import okreplay.OkReplayInterceptor
import org.koin.dsl.module.module
import retrofit2.Retrofit
import retrofit2.converter.moshi.MoshiConverterFactory
import java.util.concurrent.TimeUnit

class NetworkModule {
@Module
internal object NetworkModule {

val definition = module {
@Provides
@JvmStatic
fun providesHttpLogingInterceptor(): HttpLoggingInterceptor {
val logger = FormattedJsonHttpLogger()
val interceptor = HttpLoggingInterceptor(logger)
interceptor.level = BuildConfig.OKHTTP_LOGGING_LEVEL
return interceptor
}

single {
UserAgentHolder(get())
}
@Provides
@JvmStatic
fun providesOkReplayInterceptor(): OkReplayInterceptor {
return OkReplayInterceptor()
}

single {
UserAgentInterceptor(get())
}
@Provides
@JvmStatic
fun providesStethoInterceptor(): StethoInterceptor {
return StethoInterceptor()
}

single {
AccessTokenInterceptor(get())
}
@Provides
@JvmStatic
fun providesCurlLoggingInterceptor(): CurlLoggingInterceptor {
return CurlLoggingInterceptor(HttpLoggingInterceptor.Logger.DEFAULT)
}

single {
val logger = FormattedJsonHttpLogger()
val interceptor = HttpLoggingInterceptor(logger)
interceptor.level = BuildConfig.OKHTTP_LOGGING_LEVEL
interceptor
}

single {
CurlLoggingInterceptor()
}

single {
OkReplayInterceptor()
}

single {
StethoInterceptor()
}

single {
OkHttpClient.Builder()
.connectTimeout(1, TimeUnit.MINUTES)
.readTimeout(30, TimeUnit.SECONDS)
.writeTimeout(30, TimeUnit.SECONDS)
.addNetworkInterceptor(get<StethoInterceptor>())
.addInterceptor(get<UserAgentInterceptor>())
.addInterceptor(get<AccessTokenInterceptor>())
.addInterceptor(get<HttpLoggingInterceptor>())
.apply {
if (BuildConfig.LOG_PRIVATE_DATA) {
addInterceptor(get<CurlLoggingInterceptor>())
}
@MatrixScope
@Provides
@JvmStatic
@Unauthenticated
fun providesOkHttpClient(stethoInterceptor: StethoInterceptor,
userAgentInterceptor: UserAgentInterceptor,
httpLoggingInterceptor: HttpLoggingInterceptor,
curlLoggingInterceptor: CurlLoggingInterceptor,
okReplayInterceptor: OkReplayInterceptor): OkHttpClient {
return OkHttpClient.Builder()
.connectTimeout(1, TimeUnit.MINUTES)
.readTimeout(30, TimeUnit.SECONDS)
.writeTimeout(30, TimeUnit.SECONDS)
.addNetworkInterceptor(stethoInterceptor)
.addInterceptor(userAgentInterceptor)
.addInterceptor(httpLoggingInterceptor)
.apply {
if (BuildConfig.LOG_PRIVATE_DATA) {
addInterceptor(curlLoggingInterceptor)
}
.addInterceptor(get<OkReplayInterceptor>())
.build()
}

single {
MoshiProvider.providesMoshi()
}

single {
NetworkConnectivityChecker(get())
}

factory {
Retrofit.Builder()
.client(get())
.addConverterFactory(UnitConverterFactory)
.addConverterFactory(MoshiConverterFactory.create(get()))
}
}
.addInterceptor(okReplayInterceptor)
.build()
}

@Provides
@JvmStatic
fun providesMoshi(): Moshi {
return MoshiProvider.providesMoshi()
}
}

View File

@ -16,20 +16,18 @@

package im.vector.matrix.android.internal.network

import im.vector.matrix.android.internal.auth.SessionParamsStore
import im.vector.matrix.android.api.auth.data.Credentials
import okhttp3.Interceptor
import okhttp3.Response
import javax.inject.Inject

internal class AccessTokenInterceptor(private val sessionParamsStore: SessionParamsStore) : Interceptor {
internal class AccessTokenInterceptor @Inject constructor(private val credentials: Credentials) : Interceptor {

override fun intercept(chain: Interceptor.Chain): Response {
var request = chain.request()
val newRequestBuilder = request.newBuilder()
// Add the access token to all requests if it is set
val sessionParams = sessionParamsStore.get()
sessionParams?.let {
newRequestBuilder.addHeader(HttpHeaders.Authorization, "Bearer " + it.credentials.accessToken)
}
newRequestBuilder.addHeader(HttpHeaders.Authorization, "Bearer " + credentials.accessToken)
request = newRequestBuilder.build()
return chain.proceed(request)
}

View File

@ -20,8 +20,11 @@ import android.content.Context
import com.novoda.merlin.Merlin
import com.novoda.merlin.MerlinsBeard
import com.novoda.merlin.registerable.connection.Connectable
import im.vector.matrix.android.internal.di.MatrixScope
import javax.inject.Inject

internal class NetworkConnectivityChecker(context: Context) {
@MatrixScope
internal class NetworkConnectivityChecker @Inject constructor(context: Context) {

private val merlin = Merlin.Builder().withConnectableCallbacks().build(context)
private val merlinsBeard = MerlinsBeard.from(context)

View File

@ -0,0 +1,39 @@
/*
*
* * Copyright 2019 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.matrix.android.internal.network

import com.squareup.moshi.Moshi
import okhttp3.Interceptor
import okhttp3.OkHttpClient
import retrofit2.Retrofit
import retrofit2.converter.moshi.MoshiConverterFactory
import javax.inject.Inject

class RetrofitFactory @Inject constructor(private val moshi: Moshi) {

fun create(okHttpClient: OkHttpClient, baseUrl: String): Retrofit {
return Retrofit.Builder()
.baseUrl(baseUrl)
.client(okHttpClient)
.addConverterFactory(UnitConverterFactory)
.addConverterFactory(MoshiConverterFactory.create(moshi))
.build()
}

}

View File

@ -19,9 +19,12 @@ package im.vector.matrix.android.internal.network
import android.content.Context
import android.text.TextUtils
import im.vector.matrix.android.BuildConfig
import im.vector.matrix.android.internal.di.MatrixScope
import timber.log.Timber
import javax.inject.Inject

internal class UserAgentHolder(val context: Context) {
@MatrixScope
internal class UserAgentHolder @Inject constructor(val context: Context) {

var userAgent: String = ""
private set

View File

@ -18,8 +18,9 @@ package im.vector.matrix.android.internal.network

import okhttp3.Interceptor
import okhttp3.Response
import javax.inject.Inject

internal class UserAgentInterceptor(private val userAgentHolder: UserAgentHolder) : Interceptor {
internal class UserAgentInterceptor @Inject constructor(private val userAgentHolder: UserAgentHolder) : Interceptor {

override fun intercept(chain: Interceptor.Chain): Response {
var request = chain.request()

View File

@ -23,132 +23,83 @@ import androidx.lifecycle.LiveData
import com.zhuinden.monarchy.Monarchy
import im.vector.matrix.android.api.MatrixCallback
import im.vector.matrix.android.api.auth.data.SessionParams
import im.vector.matrix.android.api.listeners.ProgressListener
import im.vector.matrix.android.api.pushrules.PushRuleService
import im.vector.matrix.android.api.pushrules.rest.PushRule
import im.vector.matrix.android.api.session.Session
import im.vector.matrix.android.api.session.cache.CacheService
import im.vector.matrix.android.api.session.content.ContentUploadStateTracker
import im.vector.matrix.android.api.session.content.ContentUrlResolver
import im.vector.matrix.android.api.session.crypto.keysbackup.KeysBackupService
import im.vector.matrix.android.api.session.crypto.keyshare.RoomKeysRequestListener
import im.vector.matrix.android.api.session.crypto.sas.SasVerificationService
import im.vector.matrix.android.api.session.events.model.Content
import im.vector.matrix.android.api.session.events.model.Event
import im.vector.matrix.android.api.session.group.Group
import im.vector.matrix.android.api.session.crypto.CryptoService
import im.vector.matrix.android.api.session.group.GroupService
import im.vector.matrix.android.api.session.group.model.GroupSummary
import im.vector.matrix.android.api.session.pushers.Pusher
import im.vector.matrix.android.api.session.pushers.PushersService
import im.vector.matrix.android.api.session.room.Room
import im.vector.matrix.android.api.session.room.RoomDirectoryService
import im.vector.matrix.android.api.session.room.RoomService
import im.vector.matrix.android.api.session.room.model.RoomSummary
import im.vector.matrix.android.api.session.room.model.create.CreateRoomParams
import im.vector.matrix.android.api.session.room.model.roomdirectory.PublicRoomsParams
import im.vector.matrix.android.api.session.room.model.roomdirectory.PublicRoomsResponse
import im.vector.matrix.android.api.session.room.model.thirdparty.ThirdPartyProtocol
import im.vector.matrix.android.api.session.signout.SignOutService
import im.vector.matrix.android.api.session.sync.FilterService
import im.vector.matrix.android.api.session.sync.SyncState
import im.vector.matrix.android.api.session.user.UserService
import im.vector.matrix.android.api.session.user.model.User
import im.vector.matrix.android.api.util.Cancelable
import im.vector.matrix.android.api.util.MatrixCallbackDelegate
import im.vector.matrix.android.internal.crypto.CryptoManager
import im.vector.matrix.android.internal.crypto.CryptoModule
import im.vector.matrix.android.internal.crypto.MXEventDecryptionResult
import im.vector.matrix.android.internal.crypto.model.ImportRoomKeysResult
import im.vector.matrix.android.internal.crypto.model.MXDeviceInfo
import im.vector.matrix.android.internal.crypto.model.MXEncryptEventContentResult
import im.vector.matrix.android.internal.crypto.model.MXUsersDevicesMap
import im.vector.matrix.android.internal.crypto.model.rest.DevicesListResponse
import im.vector.matrix.android.internal.crypto.model.rest.RoomKeyRequestBody
import im.vector.matrix.android.internal.database.LiveEntityObserver
import im.vector.matrix.android.internal.di.MatrixKoinComponent
import im.vector.matrix.android.internal.di.MatrixKoinHolder
import im.vector.matrix.android.internal.session.content.ContentModule
import im.vector.matrix.android.internal.session.group.GroupModule
import im.vector.matrix.android.internal.session.notification.BingRuleWatcher
import im.vector.matrix.android.internal.session.room.RoomModule
import im.vector.matrix.android.internal.session.signout.SignOutModule
import im.vector.matrix.android.internal.session.sync.SyncModule
import im.vector.matrix.android.internal.session.sync.job.SyncThread
import im.vector.matrix.android.internal.session.sync.job.SyncWorker
import im.vector.matrix.android.internal.session.user.UserModule
import org.koin.core.scope.Scope
import org.koin.standalone.inject
import timber.log.Timber
import java.util.*
import javax.inject.Inject

@SessionScope
internal class DefaultSession @Inject constructor(override val sessionParams: SessionParams,
private val context: Context,
private val liveEntityObservers: Set<@JvmSuppressWildcards LiveEntityObserver>,
private val monarchy: Monarchy,
private val sessionListeners: SessionListeners,
private val roomService: RoomService,
private val roomDirectoryService: RoomDirectoryService,
private val groupService: GroupService,
private val userService: UserService,
private val filterService: FilterService,
private val cacheService: CacheService,
private val signOutService: SignOutService,
private val pushRuleService: PushRuleService,
private val pushersService: PushersService,
private val cryptoService: CryptoManager,
private val syncThread: SyncThread,
private val contentUrlResolver: ContentUrlResolver,
private val contentUploadProgressTracker: ContentUploadStateTracker)
: Session,
RoomService by roomService,
RoomDirectoryService by roomDirectoryService,
GroupService by groupService,
UserService by userService,
CryptoService by cryptoService,
CacheService by cacheService,
SignOutService by signOutService,
FilterService by filterService,
PushRuleService by pushRuleService,
PushersService by pushersService {

internal class DefaultSession(override val sessionParams: SessionParams) : Session, MatrixKoinComponent {

companion object {
const val SCOPE: String = "session"
}

private lateinit var scope: Scope

private val monarchy by inject<Monarchy>()
private val liveEntityUpdaters by inject<List<LiveEntityObserver>>()
private val sessionListeners by inject<SessionListeners>()
private val roomService by inject<RoomService>()
private val roomDirectoryService by inject<RoomDirectoryService>()
private val groupService by inject<GroupService>()
private val userService by inject<UserService>()
private val filterService by inject<FilterService>()
private val cacheService by inject<CacheService>()
private val signOutService by inject<SignOutService>()
private val cryptoService by inject<CryptoManager>()
private val syncThread by inject<SyncThread>()
private val contentUrlResolver by inject<ContentUrlResolver>()
private val contentUploadProgressTracker by inject<ContentUploadStateTracker>()
private val pushRuleService by inject<PushRuleService>()
private val pushersService by inject<PushersService>()
private var isOpen = false

private val bingRuleWatcher by inject<BingRuleWatcher>()

@MainThread
override fun open() {
assertMainThread()
assert(!isOpen)
isOpen = true
val sessionModule = SessionModule(sessionParams).definition
val syncModule = SyncModule().definition
val roomModule = RoomModule().definition
val groupModule = GroupModule().definition
val signOutModule = SignOutModule().definition
val userModule = UserModule().definition
val contentModule = ContentModule().definition
val cryptoModule = CryptoModule().definition
MatrixKoinHolder.instance.loadModules(listOf(sessionModule,
syncModule,
roomModule,
groupModule,
userModule,
signOutModule,
contentModule,
cryptoModule))
scope = getKoin().getOrCreateScope(SCOPE)
if (!monarchy.isMonarchyThreadOpen) {
monarchy.openManually()
}
liveEntityUpdaters.forEach { it.start() }
bingRuleWatcher.start()
liveEntityObservers.forEach { it.start() }
}

override fun requireBackgroundSync() {
SyncWorker.requireBackgroundSync()
SyncWorker.requireBackgroundSync(context, sessionParams.credentials.userId)
}

override fun startAutomaticBackgroundSync(repeatDelay: Long) {
SyncWorker.automaticallyBackgroundSync(0, repeatDelay)
SyncWorker.automaticallyBackgroundSync(context, sessionParams.credentials.userId, 0, repeatDelay)
}

override fun stopAnyBackgroundSync() {
SyncWorker.stopAnyBackgroundSync()
SyncWorker.stopAnyBackgroundSync(context)
}

@MainThread
@ -172,13 +123,11 @@ internal class DefaultSession(override val sessionParams: SessionParams) : Sessi
override fun close() {
assertMainThread()
assert(isOpen)
liveEntityUpdaters.forEach { it.dispose() }
liveEntityObservers.forEach { it.dispose() }
cryptoService.close()
bingRuleWatcher.dispose()
if (monarchy.isMonarchyThreadOpen) {
monarchy.closeManually()
}
scope.close()
isOpen = false
}

@ -222,13 +171,9 @@ internal class DefaultSession(override val sessionParams: SessionParams) : Sessi
})
}

override fun contentUrlResolver(): ContentUrlResolver {
return contentUrlResolver
}
override fun contentUrlResolver() = contentUrlResolver

override fun contentUploadProgressTracker(): ContentUploadStateTracker {
return contentUploadProgressTracker
}
override fun contentUploadProgressTracker() = contentUploadProgressTracker

override fun addListener(listener: Session.Listener) {
sessionListeners.addListener(listener)
@ -238,235 +183,6 @@ internal class DefaultSession(override val sessionParams: SessionParams) : Sessi
sessionListeners.removeListener(listener)
}

// ROOM SERVICE

override fun createRoom(createRoomParams: CreateRoomParams, callback: MatrixCallback<String>) {
assert(isOpen)
return roomService.createRoom(createRoomParams, callback)
}

override fun getRoom(roomId: String): Room? {
assert(isOpen)
return roomService.getRoom(roomId)
}


override fun liveRoomSummaries(): LiveData<List<RoomSummary>> {
assert(isOpen)
return roomService.liveRoomSummaries()
}

// ROOM DIRECTORY SERVICE

override fun getPublicRooms(server: String?, publicRoomsParams: PublicRoomsParams, callback: MatrixCallback<PublicRoomsResponse>): Cancelable {
assert(isOpen)
return roomDirectoryService.getPublicRooms(server, publicRoomsParams, callback)
}

override fun joinRoom(roomId: String, callback: MatrixCallback<Unit>) {
assert(isOpen)
return roomDirectoryService.joinRoom(roomId, callback)
}

override fun getThirdPartyProtocol(callback: MatrixCallback<Map<String, ThirdPartyProtocol>>) {
assert(isOpen)
return roomDirectoryService.getThirdPartyProtocol(callback)
}

// GROUP SERVICE

override fun getGroup(groupId: String): Group? {
assert(isOpen)
return groupService.getGroup(groupId)
}

override fun liveGroupSummaries(): LiveData<List<GroupSummary>> {
assert(isOpen)
return groupService.liveGroupSummaries()
}

override fun setFilter(filterPreset: FilterService.FilterPreset) {
assert(isOpen)
return filterService.setFilter(filterPreset)
}

override fun clearCache(callback: MatrixCallback<Unit>) {
assert(isOpen)
// syncThread.pause()
cacheService.clearCache(object : MatrixCallbackDelegate<Unit>(callback) {
override fun onSuccess(data: Unit) {
// Restart the sync
// syncThread.restart()

super.onSuccess(data)
}
})
}

// USER SERVICE

override fun getUser(userId: String): User? {
assert(isOpen)
return userService.getUser(userId)
}

override fun observeUser(userId: String): LiveData<User?> {
assert(isOpen)
return userService.observeUser(userId)
}

// CRYPTO SERVICE

override fun setDeviceName(deviceId: String, deviceName: String, callback: MatrixCallback<Unit>) {
cryptoService.setDeviceName(deviceId, deviceName, callback)
}

override fun deleteDevice(deviceId: String, callback: MatrixCallback<Unit>) {
cryptoService.deleteDevice(deviceId, callback)
}

override fun deleteDeviceWithUserPassword(deviceId: String, authSession: String?, password: String, callback: MatrixCallback<Unit>) {
cryptoService.deleteDeviceWithUserPassword(deviceId, authSession, password, callback)
}

override fun getCryptoVersion(context: Context, longFormat: Boolean): String {
return cryptoService.getCryptoVersion(context, longFormat)
}

override fun isCryptoEnabled(): Boolean {
return cryptoService.isCryptoEnabled()
}

override fun getSasVerificationService(): SasVerificationService {
return cryptoService.getSasVerificationService()
}

override fun getKeysBackupService(): KeysBackupService {
return cryptoService.getKeysBackupService()
}

override fun isRoomBlacklistUnverifiedDevices(roomId: String?): Boolean {
return cryptoService.isRoomBlacklistUnverifiedDevices(roomId)
}

override fun setWarnOnUnknownDevices(warn: Boolean) {
cryptoService.setWarnOnUnknownDevices(warn)
}

override fun setDeviceVerification(verificationStatus: Int, deviceId: String, userId: String) {
cryptoService.setDeviceVerification(verificationStatus, deviceId, userId)
}

override fun getUserDevices(userId: String): MutableList<MXDeviceInfo> {
return cryptoService.getUserDevices(userId)
}

override fun setDevicesKnown(devices: List<MXDeviceInfo>, callback: MatrixCallback<Unit>?) {
cryptoService.setDevicesKnown(devices, callback)
}

override fun deviceWithIdentityKey(senderKey: String, algorithm: String): MXDeviceInfo? {
return cryptoService.deviceWithIdentityKey(senderKey, algorithm)
}

override fun getMyDevice(): MXDeviceInfo {
return cryptoService.getMyDevice()
}

override fun getDevicesList(callback: MatrixCallback<DevicesListResponse>) {
cryptoService.getDevicesList(callback)
}

override fun inboundGroupSessionsCount(onlyBackedUp: Boolean): Int {
return cryptoService.inboundGroupSessionsCount(onlyBackedUp)
}

override fun getGlobalBlacklistUnverifiedDevices(): Boolean {
return cryptoService.getGlobalBlacklistUnverifiedDevices()
}

override fun setGlobalBlacklistUnverifiedDevices(block: Boolean) {
cryptoService.setGlobalBlacklistUnverifiedDevices(block)
}

override fun setRoomUnBlacklistUnverifiedDevices(roomId: String) {
cryptoService.setRoomUnBlacklistUnverifiedDevices(roomId)
}

override fun getDeviceTrackingStatus(userId: String): Int {
return cryptoService.getDeviceTrackingStatus(userId)
}

override fun importRoomKeys(roomKeysAsArray: ByteArray, password: String, progressListener: ProgressListener?, callback: MatrixCallback<ImportRoomKeysResult>) {
cryptoService.importRoomKeys(roomKeysAsArray, password, progressListener, callback)
}

override fun exportRoomKeys(password: String, callback: MatrixCallback<ByteArray>) {
cryptoService.exportRoomKeys(password, callback)
}

override fun setRoomBlacklistUnverifiedDevices(roomId: String) {
cryptoService.setRoomBlacklistUnverifiedDevices(roomId)
}

override fun isRoomEncrypted(roomId: String): Boolean {
return cryptoService.isRoomEncrypted(roomId)
}

override fun encryptEventContent(eventContent: Content, eventType: String, roomId: String, callback: MatrixCallback<MXEncryptEventContentResult>) {
cryptoService.encryptEventContent(eventContent, eventType, roomId, callback)
}

override fun getDeviceInfo(userId: String, deviceId: String?): MXDeviceInfo? {
return cryptoService.getDeviceInfo(userId, deviceId)
}

override fun reRequestRoomKeyForEvent(event: Event) {
cryptoService.reRequestRoomKeyForEvent(event)
}

override fun cancelRoomKeyRequest(requestBody: RoomKeyRequestBody) {
cryptoService.cancelRoomKeyRequest(requestBody)
}

override fun addRoomKeysRequestListener(listener: RoomKeysRequestListener) {
cryptoService.addRoomKeysRequestListener(listener)
}

override fun decryptEvent(event: Event, timeline: String): MXEventDecryptionResult? {
return cryptoService.decryptEvent(event, timeline)
}

override fun decryptEventAsync(event: Event, timeline: String, callback: MatrixCallback<MXEventDecryptionResult?>) {
return cryptoService.decryptEventAsync(event, timeline, callback)
}

override fun getEncryptionAlgorithm(roomId: String): String? {
return cryptoService.getEncryptionAlgorithm(roomId)
}

override fun shouldEncryptForInvitedMembers(roomId: String): Boolean {
return cryptoService.shouldEncryptForInvitedMembers(roomId)
}

override fun downloadKeys(userIds: List<String>, forceDownload: Boolean, callback: MatrixCallback<MXUsersDevicesMap<MXDeviceInfo>>) {
cryptoService.downloadKeys(userIds, forceDownload, callback)
}

override fun clearCryptoCache(callback: MatrixCallback<Unit>) {
cryptoService.clearCryptoCache(callback)
}

// PUSH RULE SERVICE

override fun addPushRuleListener(listener: PushRuleService.PushRuleListener) {
pushRuleService.addPushRuleListener(listener)
}

override fun removePushRuleListener(listener: PushRuleService.PushRuleListener) {
pushRuleService.removePushRuleListener(listener)
}

// Private methods *****************************************************************************

private fun assertMainThread() {
@ -475,49 +191,4 @@ internal class DefaultSession(override val sessionParams: SessionParams) : Sessi
}
}

override fun refreshPushers() {
pushersService.refreshPushers()
}

override fun addHttpPusher(
pushkey: String,
appId: String,
profileTag: String,
lang: String,
appDisplayName: String,
deviceDisplayName: String,
url: String,
append: Boolean,
withEventIdOnly: Boolean): UUID {
return pushersService
.addHttpPusher(
pushkey, appId, profileTag, lang, appDisplayName, deviceDisplayName, url, append, withEventIdOnly
)
}

override fun removeHttpPusher(pushkey: String, appId: String, callback: MatrixCallback<Unit>) {
pushersService.removeHttpPusher(pushkey, appId, callback)
}

override fun livePushers(): LiveData<List<Pusher>> {
return pushersService.livePushers()
}

override fun pushers(): List<Pusher> {
return pushersService.pushers()
}

override fun getPushRules(scope: String): List<PushRule> {
return pushRuleService.getPushRules(scope)
}

override fun updatePushRuleEnableStatus(kind: String, pushRule: PushRule, enabled: Boolean, callback: MatrixCallback<Unit>) {
pushRuleService.updatePushRuleEnableStatus(kind, pushRule, enabled, callback)
}

override fun fetchPushRules(scope: String) {
pushRuleService.fetchPushRules(scope)
}


}

View File

@ -0,0 +1,102 @@
/*
* Copyright 2019 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.matrix.android.internal.session

import dagger.BindsInstance
import dagger.Component
import im.vector.matrix.android.api.auth.data.SessionParams
import im.vector.matrix.android.api.session.Session
import im.vector.matrix.android.internal.crypto.CryptoModule
import im.vector.matrix.android.internal.di.MatrixComponent
import im.vector.matrix.android.internal.network.NetworkConnectivityChecker
import im.vector.matrix.android.internal.session.cache.CacheModule
import im.vector.matrix.android.internal.session.content.ContentModule
import im.vector.matrix.android.internal.session.content.UploadContentWorker
import im.vector.matrix.android.internal.session.filter.FilterModule
import im.vector.matrix.android.internal.session.group.GetGroupDataWorker
import im.vector.matrix.android.internal.session.group.GroupModule
import im.vector.matrix.android.internal.session.pushers.AddHttpPusherWorker
import im.vector.matrix.android.internal.session.pushers.PushersModule
import im.vector.matrix.android.internal.session.room.RoomModule
import im.vector.matrix.android.internal.session.room.relation.SendRelationWorker
import im.vector.matrix.android.internal.session.room.send.EncryptEventWorker
import im.vector.matrix.android.internal.session.room.send.RedactEventWorker
import im.vector.matrix.android.internal.session.room.send.SendEventWorker
import im.vector.matrix.android.internal.session.signout.SignOutModule
import im.vector.matrix.android.internal.session.sync.SyncModule
import im.vector.matrix.android.internal.session.sync.SyncTask
import im.vector.matrix.android.internal.session.sync.SyncTokenStore
import im.vector.matrix.android.internal.session.sync.job.SyncWorker
import im.vector.matrix.android.internal.session.user.UserModule
import im.vector.matrix.android.internal.task.TaskExecutor

@Component(dependencies = [MatrixComponent::class],
modules = [
SessionModule::class,
RoomModule::class,
SyncModule::class,
SignOutModule::class,
GroupModule::class,
UserModule::class,
FilterModule::class,
GroupModule::class,
ContentModule::class,
CacheModule::class,
CryptoModule::class,
PushersModule::class
]
)
@SessionScope
internal interface SessionComponent {

fun session(): Session

fun syncTask(): SyncTask

fun syncTokenStore(): SyncTokenStore

fun networkConnectivityChecker(): NetworkConnectivityChecker

fun taskExecutor(): TaskExecutor

fun inject(sendEventWorker: SendEventWorker)

fun inject(sendEventWorker: SendRelationWorker)

fun inject(encryptEventWorker: EncryptEventWorker)

fun inject(redactEventWorker: RedactEventWorker)

fun inject(getGroupDataWorker: GetGroupDataWorker)

fun inject(uploadContentWorker: UploadContentWorker)

fun inject(syncWorker: SyncWorker)

fun inject(addHttpPusherWorker: AddHttpPusherWorker)

@Component.Factory
interface Factory {
fun create(
matrixComponent: MatrixComponent,
@BindsInstance sessionParams: SessionParams): SessionComponent
}


}


View File

@ -17,8 +17,9 @@
package im.vector.matrix.android.internal.session

import im.vector.matrix.android.api.session.Session
import javax.inject.Inject

internal class SessionListeners {
internal class SessionListeners @Inject constructor(){

private val listeners = ArrayList<Session.Listener>()


View File

@ -18,64 +18,60 @@ package im.vector.matrix.android.internal.session

import android.content.Context
import com.zhuinden.monarchy.Monarchy
import dagger.Binds
import dagger.Module
import dagger.Provides
import dagger.multibindings.IntoSet
import im.vector.matrix.android.api.auth.data.Credentials
import im.vector.matrix.android.api.auth.data.HomeServerConnectionConfig
import im.vector.matrix.android.api.auth.data.SessionParams
import im.vector.matrix.android.api.pushrules.PushRuleService
import im.vector.matrix.android.api.session.cache.CacheService
import im.vector.matrix.android.api.session.group.GroupService
import im.vector.matrix.android.api.session.pushers.PushersService
import im.vector.matrix.android.api.session.room.RoomDirectoryService
import im.vector.matrix.android.api.session.room.RoomService
import im.vector.matrix.android.api.session.signout.SignOutService
import im.vector.matrix.android.api.session.sync.FilterService
import im.vector.matrix.android.api.session.user.UserService
import im.vector.matrix.android.api.session.Session
import im.vector.matrix.android.internal.database.LiveEntityObserver
import im.vector.matrix.android.internal.database.model.SessionRealmModule
import im.vector.matrix.android.internal.session.cache.ClearCacheTask
import im.vector.matrix.android.internal.session.cache.RealmCacheService
import im.vector.matrix.android.internal.session.cache.RealmClearCacheTask
import im.vector.matrix.android.internal.session.filter.*
import im.vector.matrix.android.internal.session.group.DefaultGroupService
import im.vector.matrix.android.internal.di.Authenticated
import im.vector.matrix.android.internal.di.SessionDatabase
import im.vector.matrix.android.internal.di.Unauthenticated
import im.vector.matrix.android.internal.network.AccessTokenInterceptor
import im.vector.matrix.android.internal.network.RetrofitFactory
import im.vector.matrix.android.internal.session.group.GroupSummaryUpdater
import im.vector.matrix.android.internal.session.notification.BingRuleWatcher
import im.vector.matrix.android.internal.session.notification.DefaultProcessEventForPushTask
import im.vector.matrix.android.internal.session.notification.DefaultPushRuleService
import im.vector.matrix.android.internal.session.notification.ProcessEventForPushTask
import im.vector.matrix.android.internal.session.pushers.*
import im.vector.matrix.android.internal.session.room.*
import im.vector.matrix.android.internal.session.room.directory.DefaultGetPublicRoomTask
import im.vector.matrix.android.internal.session.room.directory.DefaultGetThirdPartyProtocolsTask
import im.vector.matrix.android.internal.session.room.directory.GetPublicRoomTask
import im.vector.matrix.android.internal.session.room.directory.GetThirdPartyProtocolsTask
import im.vector.matrix.android.internal.session.room.membership.RoomDisplayNameResolver
import im.vector.matrix.android.internal.session.room.membership.RoomMemberDisplayNameResolver
import im.vector.matrix.android.internal.session.room.EventRelationsAggregationUpdater
import im.vector.matrix.android.internal.session.room.prune.EventsPruner
import im.vector.matrix.android.internal.session.signout.DefaultSignOutService
import im.vector.matrix.android.internal.session.user.DefaultUserService
import im.vector.matrix.android.internal.session.user.UserEntityUpdater
import im.vector.matrix.android.internal.util.md5
import io.realm.RealmConfiguration
import org.koin.dsl.module.module
import okhttp3.OkHttpClient
import retrofit2.Retrofit
import java.io.File

internal class SessionModule(private val sessionParams: SessionParams) {
@Module
internal abstract class SessionModule {

val definition = module(override = true) {
@Module
companion object {

scope(DefaultSession.SCOPE) {
sessionParams
@JvmStatic
@Provides
fun providesHomeServerConnectionConfig(sessionParams: SessionParams): HomeServerConnectionConfig {
return sessionParams.homeServerConnectionConfig
}

scope(DefaultSession.SCOPE) {
sessionParams.credentials

@JvmStatic
@Provides
fun providesCredentials(sessionParams: SessionParams): Credentials {
return sessionParams.credentials
}

scope(DefaultSession.SCOPE, name = "SessionRealmConfiguration") {
val context = get<Context>()
@JvmStatic
@Provides
@SessionDatabase
@SessionScope
fun providesRealmConfiguration(sessionParams: SessionParams, context: Context): RealmConfiguration {
val childPath = sessionParams.credentials.userId.md5()
val directory = File(context.filesDir, childPath)

RealmConfiguration.Builder()
return RealmConfiguration.Builder()
.directory(directory)
.name("disk_store.realm")
.modules(SessionRealmModule())
@ -83,147 +79,60 @@ internal class SessionModule(private val sessionParams: SessionParams) {
.build()
}

scope(DefaultSession.SCOPE) {
Monarchy.Builder()
.setRealmConfiguration(get("SessionRealmConfiguration"))
@JvmStatic
@Provides
@SessionScope
fun providesMonarchy(@SessionDatabase
realmConfiguration: RealmConfiguration): Monarchy {
return Monarchy.Builder()
.setRealmConfiguration(realmConfiguration)
.build()
}

scope(DefaultSession.SCOPE) {
val retrofitBuilder = get<Retrofit.Builder>()
retrofitBuilder
.baseUrl(sessionParams.homeServerConnectionConfig.homeServerUri.toString())
@JvmStatic
@Provides
@SessionScope
@Authenticated
fun providesOkHttpClient(@Unauthenticated okHttpClient: OkHttpClient,
accessTokenInterceptor: AccessTokenInterceptor): OkHttpClient {
return okHttpClient.newBuilder()
.addInterceptor(accessTokenInterceptor)
.build()
}

scope(DefaultSession.SCOPE) {
RoomMemberDisplayNameResolver()
@JvmStatic
@Provides
@SessionScope
fun providesRetrofit(@Authenticated okHttpClient: OkHttpClient,
sessionParams: SessionParams,
retrofitFactory: RetrofitFactory): Retrofit {
return retrofitFactory
.create(okHttpClient, sessionParams.homeServerConnectionConfig.homeServerUri.toString())
}

scope(DefaultSession.SCOPE) {
RoomDisplayNameResolver(get(), get(), get(), sessionParams.credentials)
}

scope(DefaultSession.SCOPE) {
RoomAvatarResolver(get(), get())
}

scope(DefaultSession.SCOPE) {
RoomSummaryUpdater(get(), get(), get())
}

scope(DefaultSession.SCOPE) {
DefaultRoomService(get(), get(), get(), get()) as RoomService
}

scope(DefaultSession.SCOPE) {
DefaultGetPublicRoomTask(get()) as GetPublicRoomTask
}

scope(DefaultSession.SCOPE) {
DefaultGetThirdPartyProtocolsTask(get()) as GetThirdPartyProtocolsTask
}

scope(DefaultSession.SCOPE) {
DefaultRoomDirectoryService(get(), get(), get(), get()) as RoomDirectoryService
}

scope(DefaultSession.SCOPE) {
DefaultGroupService(get()) as GroupService
}

scope(DefaultSession.SCOPE) {
DefaultSignOutService(get(), get()) as SignOutService
}

scope(DefaultSession.SCOPE) {
RealmCacheService(get("ClearTaskMainCache"), get()) as CacheService
}

// Give a name, because we have a clear task for crypto store as well
scope(DefaultSession.SCOPE, name = "ClearTaskMainCache") {
RealmClearCacheTask(get("SessionRealmConfiguration")) as ClearCacheTask
}

scope(DefaultSession.SCOPE) {
DefaultUserService(get()) as UserService
}

scope(DefaultSession.SCOPE) {
SessionListeners()
}

scope(DefaultSession.SCOPE) {
DefaultFilterRepository(get("SessionRealmConfiguration")) as FilterRepository
}

scope(DefaultSession.SCOPE) {
DefaultSaveFilterTask(get(), get(), get()) as SaveFilterTask
}

scope(DefaultSession.SCOPE) {
DefaultFilterService(get(), get(), get()) as FilterService
}

scope(DefaultSession.SCOPE) {
val retrofit: Retrofit = get()
retrofit.create(FilterApi::class.java)
}

scope(DefaultSession.SCOPE) {
val retrofit: Retrofit = get()
retrofit.create(PushRulesApi::class.java)
}

scope(DefaultSession.SCOPE) {
get<DefaultPushRuleService>() as PushRuleService
}

scope(DefaultSession.SCOPE) {
DefaultPushRuleService(get(), get(), get(), get(), get())
}

scope(DefaultSession.SCOPE) {
DefaultGetPushRulesTask(get()) as GetPushRulesTask
}

scope(DefaultSession.SCOPE) {
DefaultUpdatePushRuleEnableStatusTask(get()) as UpdatePushRuleEnableStatusTask
}

scope(DefaultSession.SCOPE) {
DefaultProcessEventForPushTask(get()) as ProcessEventForPushTask
}

scope(DefaultSession.SCOPE) {
BingRuleWatcher(get(), get(), get(), get(), get())
}

scope(DefaultSession.SCOPE) {
val groupSummaryUpdater = GroupSummaryUpdater(get())
val userEntityUpdater = UserEntityUpdater(get(), get(), get())
val aggregationUpdater = EventRelationsAggregationUpdater(get(), get(), get(), get())
//Event pruner must be the last one, because it will clear contents
val eventsPruner = EventsPruner(get(), get(), get(), get())
listOf<LiveEntityObserver>(groupSummaryUpdater, userEntityUpdater, aggregationUpdater, eventsPruner)
}

scope(DefaultSession.SCOPE) {
get<Retrofit>().create(PushersAPI::class.java)
}

scope(DefaultSession.SCOPE) {
DefaultGetPusherTask(get()) as GetPushersTask
}
scope(DefaultSession.SCOPE) {
DefaultRemovePusherTask(get(), get()) as RemovePusherTask
}

scope(DefaultSession.SCOPE) {
DefaultPusherService(get(), get(), get(), get(), get()) as PushersService
}

}


@Binds
abstract fun bindSession(session: DefaultSession): Session

@Binds
@IntoSet
abstract fun bindGroupSummaryUpdater(groupSummaryUpdater: GroupSummaryUpdater): LiveEntityObserver

@Binds
@IntoSet
abstract fun bindEventsPruner(eventsPruner: EventsPruner): LiveEntityObserver

@Binds
@IntoSet
abstract fun bindEventRelationsAggregationUpdater(groupSummaryUpdater: EventRelationsAggregationUpdater): LiveEntityObserver

@Binds
@IntoSet
abstract fun bindBingRuleWatcher(bingRuleWatcher: BingRuleWatcher): LiveEntityObserver

@Binds
@IntoSet
abstract fun bindUserEntityUpdater(groupSummaryUpdater: UserEntityUpdater): LiveEntityObserver

}

View File

@ -0,0 +1,29 @@
/*
* Copyright 2019 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.matrix.android.internal.session;

import java.lang.annotation.Documented;
import java.lang.annotation.Retention;

import javax.inject.Scope;

import static java.lang.annotation.RetentionPolicy.RUNTIME;

@Scope
@Documented
@Retention(RUNTIME)
public @interface SessionScope {}

View File

@ -0,0 +1,45 @@
/*
*
* * Copyright 2019 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.matrix.android.internal.session.cache

import dagger.Binds
import dagger.Module
import dagger.Provides
import im.vector.matrix.android.api.session.cache.CacheService
import im.vector.matrix.android.internal.di.SessionDatabase
import im.vector.matrix.android.internal.session.SessionScope
import io.realm.RealmConfiguration

@Module
internal abstract class CacheModule {

@Module
companion object {
@JvmStatic
@Provides
@SessionDatabase
fun providesClearCacheTask(@SessionDatabase realmConfiguration: RealmConfiguration): ClearCacheTask {
return RealmClearCacheTask(realmConfiguration)
}
}

@Binds
abstract fun bindCacheService(cacheService: DefaultCacheService): CacheService

}

View File

@ -17,13 +17,16 @@
package im.vector.matrix.android.internal.session.cache

import arrow.core.Try
import im.vector.matrix.android.internal.session.SessionScope
import im.vector.matrix.android.internal.task.Task
import io.realm.Realm
import io.realm.RealmConfiguration
import javax.inject.Inject
import javax.inject.Named

internal interface ClearCacheTask : Task<Unit, Unit>

internal class RealmClearCacheTask(val realmConfiguration: RealmConfiguration) : ClearCacheTask {
internal class RealmClearCacheTask @Inject constructor(private val realmConfiguration: RealmConfiguration) : ClearCacheTask {

override suspend fun execute(params: Unit): Try<Unit> {
return Try {

View File

@ -18,11 +18,14 @@ package im.vector.matrix.android.internal.session.cache

import im.vector.matrix.android.api.MatrixCallback
import im.vector.matrix.android.api.session.cache.CacheService
import im.vector.matrix.android.internal.di.SessionDatabase
import im.vector.matrix.android.internal.session.SessionScope
import im.vector.matrix.android.internal.task.TaskExecutor
import im.vector.matrix.android.internal.task.configureWith
import javax.inject.Inject

internal class RealmCacheService(private val clearCacheTask: ClearCacheTask,
private val taskExecutor: TaskExecutor) : CacheService {
internal class DefaultCacheService @Inject constructor(@SessionDatabase private val clearCacheTask: ClearCacheTask,
private val taskExecutor: TaskExecutor) : CacheService {

override fun clearCache(callback: MatrixCallback<Unit>) {
clearCacheTask

View File

@ -16,34 +16,17 @@

package im.vector.matrix.android.internal.session.content

import im.vector.matrix.android.api.auth.data.SessionParams
import dagger.Binds
import dagger.Module
import im.vector.matrix.android.api.session.content.ContentUploadStateTracker
import im.vector.matrix.android.api.session.content.ContentUrlResolver
import im.vector.matrix.android.internal.session.DefaultSession
import org.koin.dsl.module.module

internal class ContentModule {

val definition = module(override = true) {

scope(DefaultSession.SCOPE) {
DefaultContentUploadStateTracker()
}

scope(DefaultSession.SCOPE) {
get<DefaultContentUploadStateTracker>() as ContentUploadStateTracker
}

scope(DefaultSession.SCOPE) {
FileUploader(get(), get())
}

scope(DefaultSession.SCOPE) {
val sessionParams = get<SessionParams>()
DefaultContentUrlResolver(sessionParams.homeServerConnectionConfig) as ContentUrlResolver
}

}
@Module
internal abstract class ContentModule {

@Binds
abstract fun bindContentUploadStateTracker(contentUploadStateTracker: DefaultContentUploadStateTracker): ContentUploadStateTracker

@Binds
abstract fun bindContentUrlResolver(contentUrlResolver: DefaultContentUrlResolver): ContentUrlResolver
}

View File

@ -19,8 +19,11 @@ package im.vector.matrix.android.internal.session.content
import android.os.Handler
import android.os.Looper
import im.vector.matrix.android.api.session.content.ContentUploadStateTracker
import im.vector.matrix.android.internal.session.SessionScope
import javax.inject.Inject

internal class DefaultContentUploadStateTracker : ContentUploadStateTracker {
@SessionScope
internal class DefaultContentUploadStateTracker @Inject constructor() : ContentUploadStateTracker {

private val mainHandler = Handler(Looper.getMainLooper())
private val states = mutableMapOf<String, ContentUploadStateTracker.State>()

View File

@ -18,12 +18,13 @@ package im.vector.matrix.android.internal.session.content

import im.vector.matrix.android.api.auth.data.HomeServerConnectionConfig
import im.vector.matrix.android.api.session.content.ContentUrlResolver
import javax.inject.Inject


private const val MATRIX_CONTENT_URI_SCHEME = "mxc://"
private const val URI_PREFIX_CONTENT_API = "_matrix/media/v1/"

internal class DefaultContentUrlResolver(private val homeServerConnectionConfig: HomeServerConnectionConfig) : ContentUrlResolver {
internal class DefaultContentUrlResolver @Inject constructor(private val homeServerConnectionConfig: HomeServerConnectionConfig) : ContentUrlResolver {

companion object {
fun getUploadUrl(homeServerConnectionConfig: HomeServerConnectionConfig): String {

View File

@ -18,20 +18,22 @@ package im.vector.matrix.android.internal.session.content

import arrow.core.Try
import arrow.core.Try.Companion.raise
import com.squareup.moshi.Moshi
import im.vector.matrix.android.api.auth.data.SessionParams
import im.vector.matrix.android.internal.di.MoshiProvider
import im.vector.matrix.android.internal.di.Authenticated
import im.vector.matrix.android.internal.network.ProgressRequestBody
import okhttp3.*
import java.io.File
import java.io.IOException
import javax.inject.Inject


internal class FileUploader(private val okHttpClient: OkHttpClient,
sessionParams: SessionParams) {
internal class FileUploader @Inject constructor(@Authenticated
private val okHttpClient: OkHttpClient,
private val sessionParams: SessionParams,
private val moshi: Moshi) {

private val uploadUrl = DefaultContentUrlResolver.getUploadUrl(sessionParams.homeServerConnectionConfig)

private val moshi = MoshiProvider.providesMoshi()
private val responseAdapter = moshi.adapter(ContentUploadResponse::class.java)



View File

@ -25,31 +25,35 @@ import im.vector.matrix.android.api.session.events.model.Event
import im.vector.matrix.android.api.session.events.model.toContent
import im.vector.matrix.android.api.session.events.model.toModel
import im.vector.matrix.android.api.session.room.model.message.*
import im.vector.matrix.android.internal.di.MatrixKoinComponent
import im.vector.matrix.android.internal.network.ProgressRequestBody
import im.vector.matrix.android.internal.session.room.send.SendEventWorker
import im.vector.matrix.android.internal.util.WorkerParamsFactory
import org.koin.standalone.inject
import im.vector.matrix.android.internal.worker.SessionWorkerParams
import im.vector.matrix.android.internal.worker.WorkerParamsFactory
import im.vector.matrix.android.internal.worker.getSessionComponent
import timber.log.Timber
import java.io.File
import javax.inject.Inject


internal class UploadContentWorker(context: Context, params: WorkerParameters)
: CoroutineWorker(context, params), MatrixKoinComponent {

private val fileUploader by inject<FileUploader>()
private val contentUploadProgressTracker by inject<DefaultContentUploadStateTracker>()
internal class UploadContentWorker(context: Context, params: WorkerParameters) : CoroutineWorker(context, params) {

@JsonClass(generateAdapter = true)
internal data class Params(
override val userId: String,
val roomId: String,
val event: Event,
val attachment: ContentAttachmentData
)
) : SessionWorkerParams

@Inject lateinit var fileUploader: FileUploader
@Inject lateinit var contentUploadStateTracker: DefaultContentUploadStateTracker

override suspend fun doWork(): Result {
val params = WorkerParamsFactory.fromData<Params>(inputData)
?: return Result.success()
?: return Result.success()

val sessionComponent = getSessionComponent(params.userId) ?: return Result.success()
sessionComponent.inject(this)

val eventId = params.event.eventId ?: return Result.success()
val attachment = params.attachment
@ -69,7 +73,7 @@ internal class UploadContentWorker(context: Context, params: WorkerParameters)

val progressListener = object : ProgressRequestBody.Listener {
override fun onProgress(current: Long, total: Long) {
contentUploadProgressTracker.setProgress(eventId, current, total)
contentUploadStateTracker.setProgress(eventId, current, total)
}
}
return fileUploader
@ -90,16 +94,16 @@ internal class UploadContentWorker(context: Context, params: WorkerParameters)
}

private fun handleFailure(params: Params): Result {
contentUploadProgressTracker.setFailure(params.event.eventId!!)
contentUploadStateTracker.setFailure(params.event.eventId!!)
return Result.success()
}

private fun handleSuccess(params: Params,
attachmentUrl: String,
thumbnailUrl: String?): Result {
contentUploadProgressTracker.setFailure(params.event.eventId!!)
contentUploadStateTracker.setSuccess(params.event.eventId!!)
val event = updateEvent(params.event, attachmentUrl, thumbnailUrl)
val sendParams = SendEventWorker.Params(params.roomId, event)
val sendParams = SendEventWorker.Params(params.userId, params.roomId, event)
return Result.success(WorkerParamsFactory.toData(sendParams))
}

@ -131,6 +135,5 @@ internal class UploadContentWorker(context: Context, params: WorkerParameters)
return copy(url = url)
}


}


View File

@ -19,11 +19,15 @@ package im.vector.matrix.android.internal.session.filter
import im.vector.matrix.android.internal.database.model.FilterEntity
import im.vector.matrix.android.internal.database.model.FilterEntityFields
import im.vector.matrix.android.internal.database.query.getFilter
import im.vector.matrix.android.internal.di.SessionDatabase
import io.realm.Realm
import io.realm.RealmConfiguration
import io.realm.kotlin.where
import javax.inject.Inject

internal class DefaultFilterRepository(val realmConfiguration: RealmConfiguration) : FilterRepository {
internal class DefaultFilterRepository @Inject constructor(
@SessionDatabase private val realmConfiguration: RealmConfiguration
) : FilterRepository {

override fun storeFilter(filterBody: FilterBody, roomEventFilter: RoomEventFilter): Boolean {
val result: Boolean

View File

@ -19,10 +19,11 @@ package im.vector.matrix.android.internal.session.filter
import im.vector.matrix.android.api.session.sync.FilterService
import im.vector.matrix.android.internal.task.TaskExecutor
import im.vector.matrix.android.internal.task.configureWith
import javax.inject.Inject

internal class DefaultFilterService(private val filterRepository: FilterRepository,
private val saveFilterTask: SaveFilterTask,
private val taskExecutor: TaskExecutor) : FilterService {
internal class DefaultFilterService @Inject constructor(private val filterRepository: FilterRepository,
private val saveFilterTask: SaveFilterTask,
private val taskExecutor: TaskExecutor) : FilterService {

// TODO Pass a list of support events instead
override fun setFilter(filterPreset: FilterService.FilterPreset) {
@ -30,7 +31,7 @@ internal class DefaultFilterService(private val filterRepository: FilterReposito
FilterService.FilterPreset.RiotFilter -> {
FilterFactory.createRiotFilterBody()
}
FilterService.FilterPreset.NoFilter -> {
FilterService.FilterPreset.NoFilter -> {
FilterFactory.createDefaultFilterBody()
}
}
@ -39,7 +40,7 @@ internal class DefaultFilterService(private val filterRepository: FilterReposito
FilterService.FilterPreset.RiotFilter -> {
FilterFactory.createRiotRoomFilter()
}
FilterService.FilterPreset.NoFilter -> {
FilterService.FilterPreset.NoFilter -> {
FilterFactory.createDefaultRoomFilter()
}
}

View File

@ -20,6 +20,7 @@ import arrow.core.Try
import im.vector.matrix.android.api.auth.data.SessionParams
import im.vector.matrix.android.internal.network.executeRequest
import im.vector.matrix.android.internal.task.Task
import javax.inject.Inject


/**
@ -33,9 +34,9 @@ internal interface SaveFilterTask : Task<SaveFilterTask.Params, Unit> {

}

internal class DefaultSaveFilterTask(private val sessionParams: SessionParams,
private val filterAPI: FilterApi,
private val filterRepository: FilterRepository
internal class DefaultSaveFilterTask @Inject constructor(private val sessionParams: SessionParams,
private val filterAPI: FilterApi,
private val filterRepository: FilterRepository
) : SaveFilterTask {

override suspend fun execute(params: SaveFilterTask.Params): Try<Unit> {

View File

@ -42,5 +42,6 @@ internal interface FilterApi {
* @return Filter
*/
@GET(NetworkConstants.URI_API_PREFIX_PATH_R0 + "user/{userId}/filter/{filterId}")
fun getFilterById(@Path("userId") userId: String, @Path("filterId") filterId: String): Call<FilterBody>
fun getFilterById(@Path("userId") userId: String, @Path("filterId")
filterId: String): Call<FilterBody>
}

View File

@ -0,0 +1,51 @@
/*
*
* * Copyright 2019 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.matrix.android.internal.session.filter

import dagger.Binds
import dagger.Module
import dagger.Provides
import im.vector.matrix.android.api.session.sync.FilterService
import im.vector.matrix.android.internal.session.SessionScope
import retrofit2.Retrofit

@Module
internal abstract class FilterModule {

@Module
companion object {
@Provides
@JvmStatic
@SessionScope
fun providesFilterApi(retrofit: Retrofit): FilterApi {
return retrofit.create(FilterApi::class.java)
}
}

@Binds
abstract fun bindFilterRepository(filterRepository: DefaultFilterRepository): FilterRepository

@Binds
abstract fun bindFilterService(filterService: DefaultFilterService): FilterService

@Binds
abstract fun bindSaveFilterTask(saveFilterTask_Factory: DefaultSaveFilterTask): SaveFilterTask


}

View File

@ -30,6 +30,7 @@ import im.vector.matrix.android.internal.session.group.model.GroupUsers
import im.vector.matrix.android.internal.task.Task
import im.vector.matrix.android.internal.util.tryTransactionSync
import io.realm.kotlin.createObject
import javax.inject.Inject

internal interface GetGroupDataTask : Task<GetGroupDataTask.Params, Unit> {

@ -37,8 +38,7 @@ internal interface GetGroupDataTask : Task<GetGroupDataTask.Params, Unit> {

}


internal class DefaultGetGroupDataTask(
internal class DefaultGetGroupDataTask @Inject constructor(
private val groupAPI: GroupAPI,
private val monarchy: Monarchy
) : GetGroupDataTask {

View File

@ -25,8 +25,10 @@ import im.vector.matrix.android.internal.database.mapper.asDomain
import im.vector.matrix.android.internal.database.model.GroupSummaryEntity
import im.vector.matrix.android.internal.database.model.GroupSummaryEntityFields
import im.vector.matrix.android.internal.database.query.where
import im.vector.matrix.android.internal.session.SessionScope
import javax.inject.Inject

internal class DefaultGroupService(private val monarchy: Monarchy) : GroupService {
internal class DefaultGroupService @Inject constructor(private val monarchy: Monarchy) : GroupService {

override fun getGroup(groupId: String): Group? {
return null

View File

@ -18,29 +18,34 @@ package im.vector.matrix.android.internal.session.group

import android.content.Context
import androidx.work.CoroutineWorker
import androidx.work.Worker
import androidx.work.WorkerParameters
import arrow.core.Try
import com.squareup.inject.assisted.Assisted
import com.squareup.inject.assisted.AssistedInject
import com.squareup.moshi.JsonClass
import im.vector.matrix.android.internal.di.MatrixKoinComponent
import im.vector.matrix.android.internal.util.WorkerParamsFactory
import org.koin.standalone.inject
import im.vector.matrix.android.internal.worker.DelegateWorkerFactory
import im.vector.matrix.android.internal.worker.SessionWorkerParams
import im.vector.matrix.android.internal.worker.WorkerParamsFactory
import im.vector.matrix.android.internal.worker.getSessionComponent
import javax.inject.Inject

internal class GetGroupDataWorker(context: Context,
workerParameters: WorkerParameters
) : CoroutineWorker(context, workerParameters), MatrixKoinComponent {
internal class GetGroupDataWorker (context: Context, params: WorkerParameters) : CoroutineWorker(context, params) {

@JsonClass(generateAdapter = true)
internal data class Params(
override val userId: String,
val groupIds: List<String>
)
): SessionWorkerParams

private val getGroupDataTask by inject<GetGroupDataTask>()
@Inject lateinit var getGroupDataTask: GetGroupDataTask

override suspend fun doWork(): Result {
val params = WorkerParamsFactory.fromData<Params>(inputData)
?: return Result.failure()

val sessionComponent = getSessionComponent(params.userId) ?: return Result.success()
sessionComponent.inject(this)

val results = params.groupIds.map { groupId ->
fetchGroupData(groupId)
}

View File

@ -16,22 +16,29 @@

package im.vector.matrix.android.internal.session.group

import im.vector.matrix.android.internal.session.DefaultSession
import org.koin.dsl.module.module
import dagger.Binds
import dagger.Module
import dagger.Provides
import im.vector.matrix.android.api.session.group.GroupService
import im.vector.matrix.android.internal.session.SessionScope
import retrofit2.Retrofit

class GroupModule {
@Module
internal abstract class GroupModule {

val definition = module(override = true) {

scope(DefaultSession.SCOPE) {
val retrofit: Retrofit = get()
retrofit.create(GroupAPI::class.java)
@Module
companion object {
@Provides
@JvmStatic
@SessionScope
fun providesGroupAPI(retrofit: Retrofit): GroupAPI {
return retrofit.create(GroupAPI::class.java)
}

scope(DefaultSession.SCOPE) {
DefaultGetGroupDataTask(get(), get()) as GetGroupDataTask
}

}

@Binds
abstract fun bindGetGroupDataTask(getGroupDataTask: DefaultGetGroupDataTask): GetGroupDataTask

@Binds
abstract fun bindGroupService(groupService: DefaultGroupService): GroupService
}

Some files were not shown because too many files have changed in this diff Show More