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 project(":matrix-sdk-android")
implementation 'androidx.appcompat:appcompat:1.1.0-alpha01' implementation 'androidx.appcompat:appcompat:1.1.0-alpha01'
implementation 'io.reactivex.rxjava2:rxkotlin:2.3.0' implementation 'io.reactivex.rxjava2:rxkotlin:2.3.0'
implementation 'io.reactivex.rxjava2:rxandroid:2.0.2' implementation 'io.reactivex.rxjava2:rxandroid:2.1.0'

// Paging
implementation 'androidx.paging:paging-runtime:2.0.0'


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

View File

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


import im.vector.matrix.android.api.session.room.Room 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 im.vector.matrix.android.api.session.room.model.RoomSummary
import io.reactivex.Observable import io.reactivex.Observable


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


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

} }


fun Room.rx(): RxRoom { 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.Session
import im.vector.matrix.android.api.session.group.model.GroupSummary 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.room.model.RoomSummary
import im.vector.matrix.android.api.session.sync.SyncState import im.vector.matrix.android.api.session.sync.SyncState
import io.reactivex.Observable import io.reactivex.Observable
@ -36,6 +37,10 @@ class RxSession(private val session: Session) {
return session.syncState().asObservable() return session.syncState().asObservable()
} }


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

} }


fun Session.rx(): RxSession { fun Session.rx(): RxSession {

View File

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


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


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


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


// DI // DI
implementation "org.koin:koin-core:$koin_version" implementation "com.google.dagger:dagger:$daggerVersion"
implementation "org.koin:koin-core-ext:$koin_version" 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 // Logging
implementation 'com.jakewharton.timber:timber:4.7.1' implementation 'com.jakewharton.timber:timber:4.7.1'

View File

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


init { lateinit var authenticator: Authenticator
Monarchy.init(context()) lateinit var okReplayInterceptor: OkReplayInterceptor
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()


private val okReplayConfig = OkReplayConfig.Builder() private val okReplayConfig = OkReplayConfig.Builder()
.tapeRoot(AndroidTapeRoot( .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 im.vector.matrix.android.internal.session.room.timeline.TokenChunkEventPersistor
import kotlin.random.Random 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> { override suspend fun execute(params: GetContextOfEventTask.Params): Try<TokenChunkEventPersistor.Result> {
val fakeEvents = RoomDataHelper.createFakeListOfEvents(30) 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 im.vector.matrix.android.internal.session.room.timeline.TokenChunkEventPersistor
import kotlin.random.Random 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> { override suspend fun execute(params: PaginationTask.Params): Try<TokenChunkEventPersistor.Result> {
val fakeEvents = RoomDataHelper.createFakeListOfEvents(30) val fakeEvents = RoomDataHelper.createFakeListOfEvents(30)

View File

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

View File

@ -17,12 +17,14 @@


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


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


/** /**
* An OkHttp interceptor that logs requests as curl shell commands. They can then * 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 * information. It should only be used in a controlled manner or in a
* non-production environment. * 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 { : Interceptor {


/** /**

View File

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


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


<application> <application>


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


</application> </application>



View File

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


import android.content.Context import android.content.Context
import androidx.lifecycle.ProcessLifecycleOwner import androidx.lifecycle.ProcessLifecycleOwner
import androidx.work.Configuration
import androidx.work.WorkManager
import com.zhuinden.monarchy.Monarchy import com.zhuinden.monarchy.Monarchy
import im.vector.matrix.android.BuildConfig import im.vector.matrix.android.BuildConfig
import im.vector.matrix.android.api.auth.Authenticator import im.vector.matrix.android.api.auth.Authenticator
import im.vector.matrix.android.api.pushrules.Action import im.vector.matrix.android.internal.SessionManager
import im.vector.matrix.android.api.pushrules.PushRuleService import im.vector.matrix.android.internal.di.DaggerMatrixComponent
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.network.UserAgentHolder import im.vector.matrix.android.internal.network.UserAgentHolder
import im.vector.matrix.android.internal.util.BackgroundDetectionObserver import im.vector.matrix.android.internal.util.BackgroundDetectionObserver
import org.koin.standalone.get import org.matrix.olm.OlmManager
import org.koin.standalone.inject
import timber.log.Timber
import java.util.concurrent.atomic.AtomicBoolean 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 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. * 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>() @Inject internal lateinit var authenticator: Authenticator
private val userAgentHolder by inject<UserAgentHolder>() @Inject internal lateinit var userAgentHolder: UserAgentHolder
private val backgroundDetectionObserver by inject<BackgroundDetectionObserver>() @Inject internal lateinit var backgroundDetectionObserver: BackgroundDetectionObserver
var currentSession: Session? = null @Inject internal lateinit var olmManager: OlmManager
@Inject internal lateinit var sessionManager: SessionManager


init { init {
Monarchy.init(context) Monarchy.init(context)
val matrixModule = MatrixModule(context).definition DaggerMatrixComponent.factory().create(context).inject(this)
val networkModule = NetworkModule().definition if (context.applicationContext !is Configuration.Provider) {
val authModule = AuthModule().definition WorkManager.initialize(context, Configuration.Builder().build())
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()
} }
ProcessLifecycleOwner.get().lifecycle.addObserver(backgroundDetectionObserver)
userAgentHolder.setApplicationFlavor(matrixConfiguration.applicationFlavor)
} }


fun getUserAgent() = userAgentHolder.userAgent

fun authenticator(): Authenticator { fun authenticator(): Authenticator {
return authenticator return authenticator
} }


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

fun getUserAgent() = userAgentHolder.userAgent

companion object { companion object {

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


internal fun initialize(context: Context) { fun initialize(context: Context, matrixConfiguration: MatrixConfiguration) {
if (isInit.compareAndSet(false, true)) { 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 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.MatrixCallback
import im.vector.matrix.android.api.auth.data.HomeServerConnectionConfig 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.session.Session
import im.vector.matrix.android.api.util.Cancelable import im.vector.matrix.android.api.util.Cancelable


@ -40,14 +41,24 @@ interface Authenticator {
* Check if there is an active [Session]. * Check if there is an active [Session].
* @return true if there is at least one 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. //TODO remove this method. Shouldn't be managed like that.
/** /**
* Get the last active [Session], if there is an active session. * Get the last active [Session], if there is an active session.
* @return the lastActive session if any, or null * @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 sessionParams: SessionParams


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


/** /**
* This method allow to open a session. It does start some service on the background. * 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 package im.vector.matrix.android.internal.auth


import android.content.Context 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.api.auth.Authenticator
import im.vector.matrix.android.internal.auth.db.AuthRealmModule 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.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 io.realm.RealmConfiguration
import org.koin.dsl.module.module
import java.io.File import java.io.File


class AuthModule { @Module
internal abstract class AuthModule {


val definition = module { @Module

companion object {
single { @JvmStatic
DefaultAuthenticator(get(), get(), get()) as Authenticator @Provides
} @AuthDatabase

fun providesRealmConfiguration(context: Context): RealmConfiguration {
single {
val context: Context = get()
val old = File(context.filesDir, "matrix-sdk-auth") val old = File(context.filesDir, "matrix-sdk-auth")

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

return RealmConfiguration.Builder()
val mapper = SessionParamsMapper((get()))
val realmConfiguration = RealmConfiguration.Builder()
.name("matrix-sdk-auth.realm") .name("matrix-sdk-auth.realm")
.modules(AuthRealmModule()) .modules(AuthRealmModule())
.deleteRealmIfMigrationNeeded() .deleteRealmIfMigrationNeeded()
.build() .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 android.util.Patterns
import im.vector.matrix.android.api.MatrixCallback import im.vector.matrix.android.api.MatrixCallback
import im.vector.matrix.android.api.auth.Authenticator 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.HomeServerConnectionConfig
import im.vector.matrix.android.api.auth.data.SessionParams
import im.vector.matrix.android.api.session.Session import im.vector.matrix.android.api.session.Session
import im.vector.matrix.android.api.util.Cancelable 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.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.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.extensions.foldToCallback
import im.vector.matrix.android.internal.network.RetrofitFactory
import im.vector.matrix.android.internal.network.executeRequest 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.CancelableCoroutine
import im.vector.matrix.android.internal.util.MatrixCoroutineDispatchers import im.vector.matrix.android.internal.util.MatrixCoroutineDispatchers
import kotlinx.coroutines.GlobalScope import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext import kotlinx.coroutines.withContext
import retrofit2.Retrofit import okhttp3.OkHttpClient
import javax.inject.Inject


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


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


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


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

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


} }


private fun buildAuthAPI(homeServerConnectionConfig: HomeServerConnectionConfig): AuthAPI { 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) return retrofit.create(AuthAPI::class.java)
} }



View File

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


internal interface SessionParamsStore { 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 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 arrow.core.Try
import im.vector.matrix.android.api.auth.data.SessionParams import im.vector.matrix.android.api.auth.data.SessionParams
import im.vector.matrix.android.internal.auth.SessionParamsStore import im.vector.matrix.android.internal.auth.SessionParamsStore
import im.vector.matrix.android.internal.di.AuthDatabase
import io.realm.Realm import io.realm.Realm
import io.realm.RealmConfiguration import io.realm.RealmConfiguration
import javax.inject.Inject


internal class RealmSessionParamsStore(private val mapper: SessionParamsMapper, internal class RealmSessionParamsStore @Inject constructor(private val mapper: SessionParamsMapper,
private val realmConfiguration: RealmConfiguration) : SessionParamsStore { @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> { override fun save(sessionParams: SessionParams): Try<SessionParams> {
return Try { return Try {
@ -39,18 +76,20 @@ internal class RealmSessionParamsStore(private val mapper: SessionParamsMapper,
} }
} }


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


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

View File

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


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


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

View File

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


import com.squareup.moshi.Moshi 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.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.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 credentialsAdapter = moshi.adapter(Credentials::class.java)
private val homeServerConnectionConfigAdapter = moshi.adapter(HomeServerConnectionConfig::class.java) private val homeServerConnectionConfigAdapter = moshi.adapter(HomeServerConnectionConfig::class.java)
@ -47,7 +49,7 @@ internal class SessionParamsMapper(moshi: Moshi) {
if (credentialsJson == null || homeServerConnectionConfigJson == null) { if (credentialsJson == null || homeServerConnectionConfigJson == null) {
return 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.repository.WarnOnUnknownDeviceRepository
import im.vector.matrix.android.internal.crypto.store.IMXCryptoStore 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.*
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.crypto.verification.DefaultSasVerificationService
import im.vector.matrix.android.internal.database.model.EventEntity import im.vector.matrix.android.internal.database.model.EventEntity
import im.vector.matrix.android.internal.database.query.where 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.di.MoshiProvider
import im.vector.matrix.android.internal.extensions.foldToCallback 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.cache.ClearCacheTask
import im.vector.matrix.android.internal.session.room.membership.LoadRoomMembersTask import im.vector.matrix.android.internal.session.room.membership.LoadRoomMembersTask
import im.vector.matrix.android.internal.session.room.membership.RoomMembers import im.vector.matrix.android.internal.session.room.membership.RoomMembers
@ -81,6 +79,7 @@ import org.matrix.olm.OlmManager
import timber.log.Timber import timber.log.Timber
import java.util.* import java.util.*
import java.util.concurrent.atomic.AtomicBoolean import java.util.concurrent.atomic.AtomicBoolean
import javax.inject.Inject
import kotlin.coroutines.EmptyCoroutineContext 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. * 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. * 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, // The credentials,
private val credentials: Credentials, private val credentials: Credentials,
private val myDeviceInfoHolder: MyDeviceInfoHolder, private val myDeviceInfoHolder: MyDeviceInfoHolder,
@ -119,8 +121,6 @@ internal class CryptoManager(
private val incomingRoomKeyRequestManager: IncomingRoomKeyRequestManager, private val incomingRoomKeyRequestManager: IncomingRoomKeyRequestManager,
// //
private val outgoingRoomKeyRequestManager: OutgoingRoomKeyRequestManager, private val outgoingRoomKeyRequestManager: OutgoingRoomKeyRequestManager,
// Olm Manager
private val olmManager: OlmManager,
// Actions // Actions
private val setDeviceVerificationAction: SetDeviceVerificationAction, private val setDeviceVerificationAction: SetDeviceVerificationAction,
private val megolmSessionDataImporter: MegolmSessionDataImporter, private val megolmSessionDataImporter: MegolmSessionDataImporter,
@ -135,7 +135,7 @@ internal class CryptoManager(
private val setDeviceNameTask: SetDeviceNameTask, private val setDeviceNameTask: SetDeviceNameTask,
private val uploadKeysTask: UploadKeysTask, private val uploadKeysTask: UploadKeysTask,
private val loadRoomMembersTask: LoadRoomMembersTask, private val loadRoomMembersTask: LoadRoomMembersTask,
private val clearCryptoDataTask: ClearCacheTask, @CryptoDatabase private val clearCryptoDataTask: ClearCacheTask,
private val monarchy: Monarchy, private val monarchy: Monarchy,
private val coroutineDispatchers: MatrixCoroutineDispatchers, private val coroutineDispatchers: MatrixCoroutineDispatchers,
private val taskExecutor: TaskExecutor private val taskExecutor: TaskExecutor

View File

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


import android.content.Context 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.auth.data.Credentials
import im.vector.matrix.android.api.session.crypto.CryptoService 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.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.api.RoomKeysApi
import im.vector.matrix.android.internal.crypto.keysbackup.tasks.* 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.IMXCryptoStore
import im.vector.matrix.android.internal.crypto.store.db.RealmCryptoStore 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.RealmCryptoStoreMigration
import im.vector.matrix.android.internal.crypto.store.db.RealmCryptoStoreModule 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.store.db.hash
import im.vector.matrix.android.internal.crypto.tasks.* import im.vector.matrix.android.internal.crypto.tasks.*
import im.vector.matrix.android.internal.crypto.verification.DefaultSasVerificationService import im.vector.matrix.android.internal.di.CryptoDatabase
import im.vector.matrix.android.internal.session.DefaultSession 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.ClearCacheTask
import im.vector.matrix.android.internal.session.cache.RealmClearCacheTask import im.vector.matrix.android.internal.session.cache.RealmClearCacheTask
import io.realm.RealmConfiguration import io.realm.RealmConfiguration
import org.koin.dsl.module.module
import org.matrix.olm.OlmManager
import retrofit2.Retrofit import retrofit2.Retrofit
import java.io.File import java.io.File


internal class CryptoModule { @Module
internal abstract class CryptoModule {


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

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


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

@CryptoDatabase
val credentials: Credentials = get() @SessionScope

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


// CryptoStore @JvmStatic
scope(DefaultSession.SCOPE) { @Provides
RealmCryptoStore(false /* TODO*/, @CryptoDatabase
get("CryptoRealmConfiguration"), fun providesClearCacheTask(@CryptoDatabase
get()) as IMXCryptoStore realmConfiguration: RealmConfiguration): ClearCacheTask {
} return RealmClearCacheTask(realmConfiguration)

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())
} }




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


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


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


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

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())
} }


} }

@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.model.MXUsersDevicesMap
import im.vector.matrix.android.internal.crypto.store.IMXCryptoStore import im.vector.matrix.android.internal.crypto.store.IMXCryptoStore
import im.vector.matrix.android.internal.crypto.tasks.DownloadKeysForUsersTask 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 im.vector.matrix.android.internal.session.sync.SyncTokenStore
import timber.log.Timber import timber.log.Timber
import java.util.* import java.util.*
import javax.inject.Inject


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


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


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


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


Timber.e("## validateDeviceKeys() : $previouslyStoredDeviceKeys -> $deviceKeys") Timber.e("## validateDeviceKeys() : $previouslyStoredDeviceKeys -> $deviceKeys")
Timber.e("## validateDeviceKeys() : " + previouslyStoredDeviceKeys.keys + " -> " + deviceKeys.keys) 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.api.session.events.model.toModel
import im.vector.matrix.android.internal.crypto.model.rest.RoomKeyShare 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.crypto.store.IMXCryptoStore
import im.vector.matrix.android.internal.session.SessionScope
import timber.log.Timber import timber.log.Timber
import java.util.* import java.util.*
import javax.inject.Inject
import kotlin.collections.ArrayList import kotlin.collections.ArrayList


internal class IncomingRoomKeyRequestManager( @SessionScope
internal class IncomingRoomKeyRequestManager @Inject constructor(
private val credentials: Credentials, private val credentials: Credentials,
private val cryptoStore: IMXCryptoStore, private val cryptoStore: IMXCryptoStore,
private val roomDecryptorProvider: RoomDecryptorProvider) { 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.model.OlmSessionWrapper
import im.vector.matrix.android.internal.crypto.store.IMXCryptoStore import im.vector.matrix.android.internal.crypto.store.IMXCryptoStore
import im.vector.matrix.android.internal.di.MoshiProvider 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.convertFromUTF8
import im.vector.matrix.android.internal.util.convertToUTF8 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 timber.log.Timber
import java.net.URLEncoder import java.net.URLEncoder
import java.util.* import java.util.*
import javax.inject.Inject


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


inboundGroupSessionMessageIndexes[timeline]!!.put(messageIndexKey, true) 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) val reason = String.format(MXCryptoError.INBOUND_SESSION_MISMATCH_ROOM_ID_REASON, roomId, session.roomId)
Timber.e("## decryptGroupMessage() : $reason") Timber.e("## decryptGroupMessage() : $reason")
throw MXDecryptionException(MXCryptoError(MXCryptoError.INBOUND_SESSION_MISMATCH_ROOM_ID_ERROR_CODE, throw MXDecryptionException(MXCryptoError(MXCryptoError.INBOUND_SESSION_MISMATCH_ROOM_ID_ERROR_CODE,
MXCryptoError.UNABLE_TO_DECRYPT, reason)) MXCryptoError.UNABLE_TO_DECRYPT, reason))
} }
} else { } else {
Timber.e("## decryptGroupMessage() : Cannot retrieve inbound group session $sessionId") 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.api.auth.data.Credentials
import im.vector.matrix.android.internal.crypto.model.MXDeviceInfo import im.vector.matrix.android.internal.crypto.model.MXDeviceInfo
import im.vector.matrix.android.internal.crypto.store.IMXCryptoStore import im.vector.matrix.android.internal.crypto.store.IMXCryptoStore
import im.vector.matrix.android.internal.session.SessionScope
import java.util.* import java.util.*
import javax.inject.Inject


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

View File

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


import im.vector.matrix.android.api.auth.data.Credentials import im.vector.matrix.android.api.auth.data.Credentials
import im.vector.matrix.android.internal.session.SessionScope
import java.util.* 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) { 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.model.rest.KeysUploadResponse
import im.vector.matrix.android.internal.crypto.tasks.UploadKeysTask import im.vector.matrix.android.internal.crypto.tasks.UploadKeysTask
import im.vector.matrix.android.internal.di.MoshiProvider import im.vector.matrix.android.internal.di.MoshiProvider
import im.vector.matrix.android.internal.session.SessionScope
import org.matrix.olm.OlmAccount import org.matrix.olm.OlmAccount
import timber.log.Timber import timber.log.Timber
import java.util.* import java.util.*
import javax.inject.Inject


internal class OneTimeKeysUploader( @SessionScope
internal class OneTimeKeysUploader @Inject constructor(
private val credentials: Credentials, private val credentials: Credentials,
private val olmDevice: MXOlmDevice, private val olmDevice: MXOlmDevice,
private val objectSigner: ObjectSigner, 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.model.rest.RoomKeyShareRequest
import im.vector.matrix.android.internal.crypto.store.IMXCryptoStore import im.vector.matrix.android.internal.crypto.store.IMXCryptoStore
import im.vector.matrix.android.internal.crypto.tasks.SendToDeviceTask 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.TaskExecutor
import im.vector.matrix.android.internal.task.configureWith import im.vector.matrix.android.internal.task.configureWith
import timber.log.Timber import timber.log.Timber
import java.util.* import java.util.*
import javax.inject.Inject


internal class OutgoingRoomKeyRequestManager( @SessionScope
internal class OutgoingRoomKeyRequestManager @Inject constructor(
private val cryptoStore: IMXCryptoStore, private val cryptoStore: IMXCryptoStore,
private val sendToDeviceTask: SendToDeviceTask, private val sendToDeviceTask: SendToDeviceTask,
private val taskExecutor: TaskExecutor) { 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.IMXDecrypting
import im.vector.matrix.android.internal.crypto.algorithms.megolm.MXMegolmDecryptionFactory 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.crypto.algorithms.olm.MXOlmDecryptionFactory
import im.vector.matrix.android.internal.session.SessionScope
import timber.log.Timber import timber.log.Timber
import java.util.* import java.util.*
import javax.inject.Inject


internal class RoomDecryptorProvider( @SessionScope
internal class RoomDecryptorProvider @Inject constructor(
private val olmDecryptionFactory: MXOlmDecryptionFactory, private val olmDecryptionFactory: MXOlmDecryptionFactory,
private val megolmDecryptionFactory: MXMegolmDecryptionFactory 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.MXOlmSessionResult
import im.vector.matrix.android.internal.crypto.model.MXUsersDevicesMap import im.vector.matrix.android.internal.crypto.model.MXUsersDevicesMap
import im.vector.matrix.android.internal.crypto.tasks.ClaimOneTimeKeysForUsersDeviceTask import im.vector.matrix.android.internal.crypto.tasks.ClaimOneTimeKeysForUsersDeviceTask
import im.vector.matrix.android.internal.session.SessionScope
import timber.log.Timber import timber.log.Timber
import java.util.* import java.util.*
import javax.inject.Inject


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




suspend fun handle(devicesByUser: Map<String, List<MXDeviceInfo>>): Try<MXUsersDevicesMap<MXOlmSessionResult>> { 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.MXOlmSessionResult
import im.vector.matrix.android.internal.crypto.model.MXUsersDevicesMap 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.store.IMXCryptoStore
import im.vector.matrix.android.internal.session.SessionScope
import timber.log.Timber import timber.log.Timber
import java.util.* 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 cryptoStore: IMXCryptoStore,
private val ensureOlmSessionsForDevicesAction: EnsureOlmSessionsForDevicesAction) { 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.ImportRoomKeysResult
import im.vector.matrix.android.internal.crypto.model.rest.RoomKeyRequestBody 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.crypto.store.IMXCryptoStore
import im.vector.matrix.android.internal.session.SessionScope
import timber.log.Timber import timber.log.Timber
import javax.inject.Inject


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


/** /**
* Import a list of megolm session keys. * 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.MXDeviceInfo
import im.vector.matrix.android.internal.crypto.model.rest.EncryptedMessage import im.vector.matrix.android.internal.crypto.model.rest.EncryptedMessage
import im.vector.matrix.android.internal.di.MoshiProvider 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 im.vector.matrix.android.internal.util.convertToUTF8
import timber.log.Timber import timber.log.Timber
import java.util.* import java.util.*
import javax.inject.Inject


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


/** /**
* Encrypt an event payload for a list of devices. * 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.api.auth.data.Credentials
import im.vector.matrix.android.internal.crypto.keysbackup.KeysBackup import im.vector.matrix.android.internal.crypto.keysbackup.KeysBackup
import im.vector.matrix.android.internal.crypto.store.IMXCryptoStore import im.vector.matrix.android.internal.crypto.store.IMXCryptoStore
import im.vector.matrix.android.internal.session.SessionScope
import timber.log.Timber 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 credentials: Credentials,
private val keysBackup: KeysBackup) { 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.actions.MessageEncrypter
import im.vector.matrix.android.internal.crypto.store.IMXCryptoStore import im.vector.matrix.android.internal.crypto.store.IMXCryptoStore
import im.vector.matrix.android.internal.crypto.tasks.SendToDeviceTask 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 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 olmDevice: MXOlmDevice,
private val deviceListManager: DeviceListManager, private val deviceListManager: DeviceListManager,
private val outgoingRoomKeyRequestManager: OutgoingRoomKeyRequestManager, 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.repository.WarnOnUnknownDeviceRepository
import im.vector.matrix.android.internal.crypto.store.IMXCryptoStore import im.vector.matrix.android.internal.crypto.store.IMXCryptoStore
import im.vector.matrix.android.internal.crypto.tasks.SendToDeviceTask 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.TaskExecutor
import javax.inject.Inject


internal class MXMegolmEncryptionFactory( internal class MXMegolmEncryptionFactory @Inject constructor(
private val olmDevice: MXOlmDevice, private val olmDevice: MXOlmDevice,
private val keysBackup: KeysBackup, private val keysBackup: KeysBackup,
private val cryptoStore: IMXCryptoStore, 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.api.auth.data.Credentials
import im.vector.matrix.android.internal.crypto.MXOlmDevice 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, internal class MXOlmDecryptionFactory @Inject constructor(private val olmDevice: MXOlmDevice,
private val credentials: Credentials) { private val credentials: Credentials) {


fun create(): MXOlmDecryption { fun create(): MXOlmDecryption {
return 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.EnsureOlmSessionsForUsersAction
import im.vector.matrix.android.internal.crypto.actions.MessageEncrypter 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.store.IMXCryptoStore
import im.vector.matrix.android.internal.session.SessionScope
import im.vector.matrix.android.internal.util.MatrixCoroutineDispatchers import im.vector.matrix.android.internal.util.MatrixCoroutineDispatchers
import javax.inject.Inject


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


fun create(roomId: String): MXOlmEncryption { fun create(roomId: String): MXOlmEncryption {
return 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.crypto.store.db.model.KeysBackupDataEntity
import im.vector.matrix.android.internal.di.MoshiProvider import im.vector.matrix.android.internal.di.MoshiProvider
import im.vector.matrix.android.internal.extensions.foldToCallback 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.Task
import im.vector.matrix.android.internal.task.TaskExecutor import im.vector.matrix.android.internal.task.TaskExecutor
import im.vector.matrix.android.internal.task.TaskThread import im.vector.matrix.android.internal.task.TaskThread
@ -66,13 +67,16 @@ import org.matrix.olm.OlmPkMessage
import timber.log.Timber import timber.log.Timber
import java.security.InvalidParameterException import java.security.InvalidParameterException
import java.util.* import java.util.*
import javax.inject.Inject
import kotlin.collections.HashMap import kotlin.collections.HashMap


/** /**
* A KeysBackup class instance manage incremental backup of e2e keys (megolm keys) * A KeysBackup class instance manage incremental backup of e2e keys (megolm keys)
* to the user's homeserver. * to the user's homeserver.
*/ */
internal class KeysBackup(
@SessionScope
internal class KeysBackup @Inject constructor(
private val credentials: Credentials, private val credentials: Credentials,
private val cryptoStore: IMXCryptoStore, private val cryptoStore: IMXCryptoStore,
private val olmDevice: MXOlmDevice, private val olmDevice: MXOlmDevice,
@ -448,7 +452,8 @@ internal class KeysBackup(
val myUserId = credentials.userId val myUserId = credentials.userId


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


if (trust) { if (trust) {
// Add current device signature // Add current device signature
@ -1309,7 +1314,8 @@ internal class KeysBackup(
"algorithm" to sessionData!!.algorithm, "algorithm" to sessionData!!.algorithm,
"sender_key" to sessionData.senderKey, "sender_key" to sessionData.senderKey,
"sender_claimed_keys" to sessionData.senderClaimedKeys, "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) "session_key" to sessionData.sessionKey)


var encryptedSessionBackupData: OlmPkMessage? = null 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.crypto.keysbackup.model.rest.KeysVersion
import im.vector.matrix.android.internal.network.executeRequest import im.vector.matrix.android.internal.network.executeRequest
import im.vector.matrix.android.internal.task.Task import im.vector.matrix.android.internal.task.Task
import javax.inject.Inject


internal interface CreateKeysBackupVersionTask : Task<CreateKeysBackupVersionBody, KeysVersion> internal interface CreateKeysBackupVersionTask : Task<CreateKeysBackupVersionBody, KeysVersion>



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





View File

@ -19,7 +19,9 @@ package im.vector.matrix.android.internal.crypto.keysbackup.tasks
import arrow.core.Try import arrow.core.Try
import im.vector.matrix.android.internal.crypto.keysbackup.api.RoomKeysApi import im.vector.matrix.android.internal.crypto.keysbackup.api.RoomKeysApi
import im.vector.matrix.android.internal.network.executeRequest 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.task.Task
import javax.inject.Inject




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



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


override suspend fun execute(params: DeleteBackupTask.Params): Try<Unit> { 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 arrow.core.Try
import im.vector.matrix.android.internal.crypto.keysbackup.api.RoomKeysApi import im.vector.matrix.android.internal.crypto.keysbackup.api.RoomKeysApi
import im.vector.matrix.android.internal.network.executeRequest 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.task.Task
import javax.inject.Inject


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



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


override suspend fun execute(params: DeleteRoomSessionDataTask.Params): Try<Unit> { 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 arrow.core.Try
import im.vector.matrix.android.internal.crypto.keysbackup.api.RoomKeysApi import im.vector.matrix.android.internal.crypto.keysbackup.api.RoomKeysApi
import im.vector.matrix.android.internal.network.executeRequest 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.task.Task
import javax.inject.Inject


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



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


override suspend fun execute(params: DeleteRoomSessionsDataTask.Params): Try<Unit> { 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 arrow.core.Try
import im.vector.matrix.android.internal.crypto.keysbackup.api.RoomKeysApi import im.vector.matrix.android.internal.crypto.keysbackup.api.RoomKeysApi
import im.vector.matrix.android.internal.network.executeRequest 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.task.Task
import javax.inject.Inject


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



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


override suspend fun execute(params: DeleteSessionsDataTask.Params): Try<Unit> { 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.crypto.keysbackup.model.rest.KeysVersionResult
import im.vector.matrix.android.internal.network.executeRequest import im.vector.matrix.android.internal.network.executeRequest
import im.vector.matrix.android.internal.task.Task import im.vector.matrix.android.internal.task.Task
import javax.inject.Inject


internal interface GetKeysBackupLastVersionTask : Task<Unit, KeysVersionResult> internal interface GetKeysBackupLastVersionTask : Task<Unit, KeysVersionResult>



internal class DefaultGetKeysBackupLastVersionTask @Inject constructor(private val roomKeysApi: RoomKeysApi)
internal class DefaultGetKeysBackupLastVersionTask(private val roomKeysApi: RoomKeysApi)
: GetKeysBackupLastVersionTask { : 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.crypto.keysbackup.model.rest.KeysVersionResult
import im.vector.matrix.android.internal.network.executeRequest import im.vector.matrix.android.internal.network.executeRequest
import im.vector.matrix.android.internal.task.Task import im.vector.matrix.android.internal.task.Task
import javax.inject.Inject


internal interface GetKeysBackupVersionTask : Task<String, KeysVersionResult> internal interface GetKeysBackupVersionTask : Task<String, KeysVersionResult>



internal class DefaultGetKeysBackupVersionTask @Inject constructor(private val roomKeysApi: RoomKeysApi)
internal class DefaultGetKeysBackupVersionTask(private val roomKeysApi: RoomKeysApi)
: GetKeysBackupVersionTask { : 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.api.RoomKeysApi
import im.vector.matrix.android.internal.crypto.keysbackup.model.rest.KeyBackupData 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.network.executeRequest
import im.vector.matrix.android.internal.session.SessionScope
import im.vector.matrix.android.internal.task.Task import im.vector.matrix.android.internal.task.Task
import javax.inject.Inject


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



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


override suspend fun execute(params: GetRoomSessionDataTask.Params): Try<KeyBackupData> { 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.api.RoomKeysApi
import im.vector.matrix.android.internal.crypto.keysbackup.model.rest.RoomKeysBackupData 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.network.executeRequest
import im.vector.matrix.android.internal.session.SessionScope
import im.vector.matrix.android.internal.task.Task import im.vector.matrix.android.internal.task.Task
import javax.inject.Inject




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



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


override suspend fun execute(params: GetRoomSessionsDataTask.Params): Try<RoomKeysBackupData> { 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.api.RoomKeysApi
import im.vector.matrix.android.internal.crypto.keysbackup.model.rest.KeysBackupData 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.network.executeRequest
import im.vector.matrix.android.internal.session.SessionScope
import im.vector.matrix.android.internal.task.Task import im.vector.matrix.android.internal.task.Task
import javax.inject.Inject


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



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


override suspend fun execute(params: GetSessionsDataTask.Params): Try<KeysBackupData> { 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.KeyBackupData
import im.vector.matrix.android.internal.crypto.keysbackup.model.rest.BackupKeysResult 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.network.executeRequest
import im.vector.matrix.android.internal.session.SessionScope
import im.vector.matrix.android.internal.task.Task import im.vector.matrix.android.internal.task.Task
import javax.inject.Inject


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



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


override suspend fun execute(params: StoreRoomSessionDataTask.Params): Try<BackupKeysResult> { 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.RoomKeysBackupData
import im.vector.matrix.android.internal.crypto.keysbackup.model.rest.BackupKeysResult 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.network.executeRequest
import im.vector.matrix.android.internal.session.SessionScope
import im.vector.matrix.android.internal.task.Task import im.vector.matrix.android.internal.task.Task
import javax.inject.Inject


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



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


override suspend fun execute(params: StoreRoomSessionsDataTask.Params): Try<BackupKeysResult> { 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.KeysBackupData
import im.vector.matrix.android.internal.crypto.keysbackup.model.rest.BackupKeysResult 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.network.executeRequest
import im.vector.matrix.android.internal.session.SessionScope
import im.vector.matrix.android.internal.task.Task import im.vector.matrix.android.internal.task.Task
import javax.inject.Inject


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



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


override suspend fun execute(params: StoreSessionsDataTask.Params): Try<BackupKeysResult> { 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.crypto.keysbackup.model.rest.UpdateKeysBackupVersionBody
import im.vector.matrix.android.internal.network.executeRequest import im.vector.matrix.android.internal.network.executeRequest
import im.vector.matrix.android.internal.task.Task import im.vector.matrix.android.internal.task.Task
import javax.inject.Inject


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



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





View File

@ -16,7 +16,11 @@


package im.vector.matrix.android.internal.crypto.repository 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 // TODO: set it back to true by default. Need UI
// Warn the user if some new devices are detected while encrypting a message. // 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.delete
import im.vector.matrix.android.internal.crypto.store.db.query.getById 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.crypto.store.db.query.getOrCreate
import im.vector.matrix.android.internal.session.SessionScope
import io.realm.RealmConfiguration import io.realm.RealmConfiguration
import io.realm.Sort import io.realm.Sort
import io.realm.kotlin.where import io.realm.kotlin.where
@ -38,6 +39,7 @@ import timber.log.Timber
import kotlin.collections.set import kotlin.collections.set


// enableFileEncryption is used to migrate the previous store // enableFileEncryption is used to migrate the previous store
@SessionScope
internal class RealmCryptoStore(private val enableFileEncryption: Boolean = false, internal class RealmCryptoStore(private val enableFileEncryption: Boolean = false,
private val realmConfiguration: RealmConfiguration, private val realmConfiguration: RealmConfiguration,
private val credentials: Credentials) : IMXCryptoStore { 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.KeysClaimBody
import im.vector.matrix.android.internal.crypto.model.rest.KeysClaimResponse import im.vector.matrix.android.internal.crypto.model.rest.KeysClaimResponse
import im.vector.matrix.android.internal.network.executeRequest 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.task.Task
import timber.log.Timber import timber.log.Timber
import java.util.* import java.util.*
import javax.inject.Inject


internal interface ClaimOneTimeKeysForUsersDeviceTask : Task<ClaimOneTimeKeysForUsersDeviceTask.Params, MXUsersDevicesMap<MXKey>> { internal interface ClaimOneTimeKeysForUsersDeviceTask : Task<ClaimOneTimeKeysForUsersDeviceTask.Params, MXUsersDevicesMap<MXKey>> {
data class Params( 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 { : ClaimOneTimeKeysForUsersDeviceTask {


override suspend fun execute(params: ClaimOneTimeKeysForUsersDeviceTask.Params): Try<MXUsersDevicesMap<MXKey>> { 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.crypto.model.rest.DeleteDeviceParams
import im.vector.matrix.android.internal.di.MoshiProvider import im.vector.matrix.android.internal.di.MoshiProvider
import im.vector.matrix.android.internal.network.executeRequest 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.task.Task
import javax.inject.Inject


internal interface DeleteDeviceTask : Task<DeleteDeviceTask.Params, Unit> { internal interface DeleteDeviceTask : Task<DeleteDeviceTask.Params, Unit> {
data class Params( 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 { : DeleteDeviceTask {


override suspend fun execute(params: DeleteDeviceTask.Params): Try<Unit> { 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.crypto.model.rest.DeleteDeviceParams
import im.vector.matrix.android.internal.network.executeRequest import im.vector.matrix.android.internal.network.executeRequest
import im.vector.matrix.android.internal.task.Task import im.vector.matrix.android.internal.task.Task
import javax.inject.Inject


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


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


override suspend fun execute(params: DeleteDeviceWithUserPasswordTask.Params): Try<Unit> { 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.KeysQueryBody
import im.vector.matrix.android.internal.crypto.model.rest.KeysQueryResponse import im.vector.matrix.android.internal.crypto.model.rest.KeysQueryResponse
import im.vector.matrix.android.internal.network.executeRequest 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.task.Task
import java.util.* import java.util.*
import javax.inject.Inject


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


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


override suspend fun execute(params: DownloadKeysForUsersTask.Params): Try<KeysQueryResponse> { 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.api.CryptoApi
import im.vector.matrix.android.internal.crypto.model.rest.DevicesListResponse import im.vector.matrix.android.internal.crypto.model.rest.DevicesListResponse
import im.vector.matrix.android.internal.network.executeRequest 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.task.Task
import javax.inject.Inject


internal interface GetDevicesTask : Task<Unit, DevicesListResponse> internal interface GetDevicesTask : Task<Unit, DevicesListResponse>


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


override suspend fun execute(params: Unit): Try<DevicesListResponse> { 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.api.CryptoApi
import im.vector.matrix.android.internal.crypto.model.rest.KeyChangesResponse import im.vector.matrix.android.internal.crypto.model.rest.KeyChangesResponse
import im.vector.matrix.android.internal.network.executeRequest 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.task.Task
import javax.inject.Inject


internal interface GetKeyChangesTask : Task<GetKeyChangesTask.Params, KeyChangesResponse> { internal interface GetKeyChangesTask : Task<GetKeyChangesTask.Params, KeyChangesResponse> {
data class Params( 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 { : GetKeyChangesTask {


override suspend fun execute(params: GetKeyChangesTask.Params): Try<KeyChangesResponse> { 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.MXUsersDevicesMap
import im.vector.matrix.android.internal.crypto.model.rest.SendToDeviceBody import im.vector.matrix.android.internal.crypto.model.rest.SendToDeviceBody
import im.vector.matrix.android.internal.network.executeRequest 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.task.Task
import java.util.* import java.util.*
import javax.inject.Inject


internal interface SendToDeviceTask : Task<SendToDeviceTask.Params, Unit> { internal interface SendToDeviceTask : Task<SendToDeviceTask.Params, Unit> {
data class Params( 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 { : SendToDeviceTask {


override suspend fun execute(params: SendToDeviceTask.Params): Try<Unit> { 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.api.CryptoApi
import im.vector.matrix.android.internal.crypto.model.rest.UpdateDeviceInfoBody import im.vector.matrix.android.internal.crypto.model.rest.UpdateDeviceInfoBody
import im.vector.matrix.android.internal.network.executeRequest 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.task.Task
import javax.inject.Inject


internal interface SetDeviceNameTask : Task<SetDeviceNameTask.Params, Unit> { internal interface SetDeviceNameTask : Task<SetDeviceNameTask.Params, Unit> {
data class Params( 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 { : SetDeviceNameTask {


override suspend fun execute(params: SetDeviceNameTask.Params): Try<Unit> { 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.DeviceKeys
import im.vector.matrix.android.internal.crypto.model.rest.KeysUploadBody import im.vector.matrix.android.internal.crypto.model.rest.KeysUploadBody
import im.vector.matrix.android.internal.network.executeRequest 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.task.Task
import im.vector.matrix.android.internal.util.convertToUTF8 import im.vector.matrix.android.internal.util.convertToUTF8
import javax.inject.Inject


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


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


override suspend fun execute(params: UploadKeysTask.Params): Try<KeysUploadResponse> { 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.model.rest.*
import im.vector.matrix.android.internal.crypto.store.IMXCryptoStore import im.vector.matrix.android.internal.crypto.store.IMXCryptoStore
import im.vector.matrix.android.internal.crypto.tasks.SendToDeviceTask 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.TaskExecutor
import im.vector.matrix.android.internal.task.configureWith import im.vector.matrix.android.internal.task.configureWith
import im.vector.matrix.android.internal.util.MatrixCoroutineDispatchers import im.vector.matrix.android.internal.util.MatrixCoroutineDispatchers
@ -42,6 +43,7 @@ import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import timber.log.Timber import timber.log.Timber
import java.util.* import java.util.*
import javax.inject.Inject
import kotlin.collections.HashMap 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 * 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). * 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, @SessionScope
private val myDeviceInfoHolder: MyDeviceInfoHolder, internal class DefaultSasVerificationService @Inject constructor(private val credentials: Credentials,
private val deviceListManager: DeviceListManager, private val cryptoStore: IMXCryptoStore,
private val setDeviceVerificationAction: SetDeviceVerificationAction, private val myDeviceInfoHolder: MyDeviceInfoHolder,
private val sendToDeviceTask: SendToDeviceTask, private val deviceListManager: DeviceListManager,
private val coroutineDispatchers: MatrixCoroutineDispatchers, private val setDeviceVerificationAction: SetDeviceVerificationAction,
private val taskExecutor: TaskExecutor) private val sendToDeviceTask: SendToDeviceTask,
private val coroutineDispatchers: MatrixCoroutineDispatchers,
private val taskExecutor: TaskExecutor)
: VerificationTransaction.Listener, SasVerificationService { : VerificationTransaction.Listener, SasVerificationService {


private val uiHandler = Handler(Looper.getMainLooper()) 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 package im.vector.matrix.android.internal.di


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


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


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


} @Qualifier

@Retention(AnnotationRetention.RUNTIME)
internal interface MatrixKoinComponent : KoinComponent { annotation class CryptoDatabase

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

}

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 package im.vector.matrix.android.internal.di


import android.content.Context import android.content.Context
import android.content.res.Resources
import android.os.Handler import android.os.Handler
import android.os.HandlerThread import android.os.HandlerThread
import im.vector.matrix.android.internal.task.TaskExecutor import dagger.Module
import im.vector.matrix.android.internal.util.BackgroundDetectionObserver import dagger.Provides
import im.vector.matrix.android.internal.util.MatrixCoroutineDispatchers import im.vector.matrix.android.internal.util.MatrixCoroutineDispatchers
import im.vector.matrix.android.internal.util.StringProvider
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.android.asCoroutineDispatcher 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) { @JvmStatic

@Provides
val definition = module { fun providesMatrixCoroutineDispatchers(): MatrixCoroutineDispatchers {

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

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()
}


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 package im.vector.matrix.android.internal.di


import com.facebook.stetho.okhttp3.StethoInterceptor 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.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.CurlLoggingInterceptor
import im.vector.matrix.android.internal.network.interceptors.FormattedJsonHttpLogger import im.vector.matrix.android.internal.network.interceptors.FormattedJsonHttpLogger
import okhttp3.OkHttpClient import okhttp3.OkHttpClient
import okhttp3.logging.HttpLoggingInterceptor import okhttp3.logging.HttpLoggingInterceptor
import okreplay.OkReplayInterceptor import okreplay.OkReplayInterceptor
import org.koin.dsl.module.module
import retrofit2.Retrofit import retrofit2.Retrofit
import retrofit2.converter.moshi.MoshiConverterFactory import retrofit2.converter.moshi.MoshiConverterFactory
import java.util.concurrent.TimeUnit 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 { @Provides
UserAgentHolder(get()) @JvmStatic
} fun providesOkReplayInterceptor(): OkReplayInterceptor {
return OkReplayInterceptor()
}


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


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


single { @MatrixScope
val logger = FormattedJsonHttpLogger() @Provides
val interceptor = HttpLoggingInterceptor(logger) @JvmStatic
interceptor.level = BuildConfig.OKHTTP_LOGGING_LEVEL @Unauthenticated
interceptor fun providesOkHttpClient(stethoInterceptor: StethoInterceptor,
} userAgentInterceptor: UserAgentInterceptor,

httpLoggingInterceptor: HttpLoggingInterceptor,
single { curlLoggingInterceptor: CurlLoggingInterceptor,
CurlLoggingInterceptor() okReplayInterceptor: OkReplayInterceptor): OkHttpClient {
} return OkHttpClient.Builder()

.connectTimeout(1, TimeUnit.MINUTES)
single { .readTimeout(30, TimeUnit.SECONDS)
OkReplayInterceptor() .writeTimeout(30, TimeUnit.SECONDS)
} .addNetworkInterceptor(stethoInterceptor)

.addInterceptor(userAgentInterceptor)
single { .addInterceptor(httpLoggingInterceptor)
StethoInterceptor() .apply {
} if (BuildConfig.LOG_PRIVATE_DATA) {

addInterceptor(curlLoggingInterceptor)
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>())
}
} }
.addInterceptor(get<OkReplayInterceptor>()) }
.build() .addInterceptor(okReplayInterceptor)
} .build()

}
single {
MoshiProvider.providesMoshi()
}

single {
NetworkConnectivityChecker(get())
}

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


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

View File

@ -16,20 +16,18 @@


package im.vector.matrix.android.internal.network 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.Interceptor
import okhttp3.Response 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 { override fun intercept(chain: Interceptor.Chain): Response {
var request = chain.request() var request = chain.request()
val newRequestBuilder = request.newBuilder() val newRequestBuilder = request.newBuilder()
// Add the access token to all requests if it is set // Add the access token to all requests if it is set
val sessionParams = sessionParamsStore.get() newRequestBuilder.addHeader(HttpHeaders.Authorization, "Bearer " + credentials.accessToken)
sessionParams?.let {
newRequestBuilder.addHeader(HttpHeaders.Authorization, "Bearer " + it.credentials.accessToken)
}
request = newRequestBuilder.build() request = newRequestBuilder.build()
return chain.proceed(request) return chain.proceed(request)
} }

View File

@ -20,8 +20,11 @@ import android.content.Context
import com.novoda.merlin.Merlin import com.novoda.merlin.Merlin
import com.novoda.merlin.MerlinsBeard import com.novoda.merlin.MerlinsBeard
import com.novoda.merlin.registerable.connection.Connectable 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 merlin = Merlin.Builder().withConnectableCallbacks().build(context)
private val merlinsBeard = MerlinsBeard.from(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.content.Context
import android.text.TextUtils import android.text.TextUtils
import im.vector.matrix.android.BuildConfig import im.vector.matrix.android.BuildConfig
import im.vector.matrix.android.internal.di.MatrixScope
import timber.log.Timber 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 = "" var userAgent: String = ""
private set private set

View File

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


import okhttp3.Interceptor import okhttp3.Interceptor
import okhttp3.Response 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 { override fun intercept(chain: Interceptor.Chain): Response {
var request = chain.request() var request = chain.request()

View File

@ -23,132 +23,83 @@ import androidx.lifecycle.LiveData
import com.zhuinden.monarchy.Monarchy import com.zhuinden.monarchy.Monarchy
import im.vector.matrix.android.api.MatrixCallback import im.vector.matrix.android.api.MatrixCallback
import im.vector.matrix.android.api.auth.data.SessionParams 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.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.Session
import im.vector.matrix.android.api.session.cache.CacheService 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.ContentUploadStateTracker
import im.vector.matrix.android.api.session.content.ContentUrlResolver 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.CryptoService
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.group.GroupService 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.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.RoomDirectoryService
import im.vector.matrix.android.api.session.room.RoomService 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.signout.SignOutService
import im.vector.matrix.android.api.session.sync.FilterService 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.sync.SyncState
import im.vector.matrix.android.api.session.user.UserService import im.vector.matrix.android.api.session.user.UserService
import im.vector.matrix.android.api.session.user.model.User
import im.vector.matrix.android.api.util.Cancelable
import im.vector.matrix.android.api.util.MatrixCallbackDelegate import im.vector.matrix.android.api.util.MatrixCallbackDelegate
import im.vector.matrix.android.internal.crypto.CryptoManager 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.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.SyncThread
import im.vector.matrix.android.internal.session.sync.job.SyncWorker 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 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 var isOpen = false


private val bingRuleWatcher by inject<BingRuleWatcher>()


@MainThread @MainThread
override fun open() { override fun open() {
assertMainThread() assertMainThread()
assert(!isOpen) assert(!isOpen)
isOpen = true 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) { if (!monarchy.isMonarchyThreadOpen) {
monarchy.openManually() monarchy.openManually()
} }
liveEntityUpdaters.forEach { it.start() } liveEntityObservers.forEach { it.start() }
bingRuleWatcher.start()
} }


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


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


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


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


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


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


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


override fun addListener(listener: Session.Listener) { override fun addListener(listener: Session.Listener) {
sessionListeners.addListener(listener) sessionListeners.addListener(listener)
@ -238,235 +183,6 @@ internal class DefaultSession(override val sessionParams: SessionParams) : Sessi
sessionListeners.removeListener(listener) 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 methods *****************************************************************************


private fun assertMainThread() { 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 package im.vector.matrix.android.internal.session


import im.vector.matrix.android.api.session.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>() private val listeners = ArrayList<Session.Listener>()



View File

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


import android.content.Context import android.content.Context
import com.zhuinden.monarchy.Monarchy 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.auth.data.SessionParams
import im.vector.matrix.android.api.pushrules.PushRuleService import im.vector.matrix.android.api.session.Session
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.internal.database.LiveEntityObserver import im.vector.matrix.android.internal.database.LiveEntityObserver
import im.vector.matrix.android.internal.database.model.SessionRealmModule import im.vector.matrix.android.internal.database.model.SessionRealmModule
import im.vector.matrix.android.internal.session.cache.ClearCacheTask import im.vector.matrix.android.internal.di.Authenticated
import im.vector.matrix.android.internal.session.cache.RealmCacheService import im.vector.matrix.android.internal.di.SessionDatabase
import im.vector.matrix.android.internal.session.cache.RealmClearCacheTask import im.vector.matrix.android.internal.di.Unauthenticated
import im.vector.matrix.android.internal.session.filter.* import im.vector.matrix.android.internal.network.AccessTokenInterceptor
import im.vector.matrix.android.internal.session.group.DefaultGroupService import im.vector.matrix.android.internal.network.RetrofitFactory
import im.vector.matrix.android.internal.session.group.GroupSummaryUpdater 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.BingRuleWatcher
import im.vector.matrix.android.internal.session.notification.DefaultProcessEventForPushTask import im.vector.matrix.android.internal.session.room.EventRelationsAggregationUpdater
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.prune.EventsPruner 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.session.user.UserEntityUpdater
import im.vector.matrix.android.internal.util.md5 import im.vector.matrix.android.internal.util.md5
import io.realm.RealmConfiguration import io.realm.RealmConfiguration
import org.koin.dsl.module.module import okhttp3.OkHttpClient
import retrofit2.Retrofit import retrofit2.Retrofit
import java.io.File 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) { @JvmStatic
sessionParams @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") { @JvmStatic
val context = get<Context>() @Provides
@SessionDatabase
@SessionScope
fun providesRealmConfiguration(sessionParams: SessionParams, context: Context): RealmConfiguration {
val childPath = sessionParams.credentials.userId.md5() val childPath = sessionParams.credentials.userId.md5()
val directory = File(context.filesDir, childPath) val directory = File(context.filesDir, childPath)


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


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


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


scope(DefaultSession.SCOPE) { @JvmStatic
RoomMemberDisplayNameResolver() @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 package im.vector.matrix.android.internal.session.cache


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


internal interface ClearCacheTask : Task<Unit, Unit> 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> { override suspend fun execute(params: Unit): Try<Unit> {
return Try { 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.MatrixCallback
import im.vector.matrix.android.api.session.cache.CacheService 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.TaskExecutor
import im.vector.matrix.android.internal.task.configureWith import im.vector.matrix.android.internal.task.configureWith
import javax.inject.Inject


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


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

View File

@ -16,34 +16,17 @@


package im.vector.matrix.android.internal.session.content 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.ContentUploadStateTracker
import im.vector.matrix.android.api.session.content.ContentUrlResolver 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 { @Module

internal abstract 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
}

}


@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.Handler
import android.os.Looper import android.os.Looper
import im.vector.matrix.android.api.session.content.ContentUploadStateTracker 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 mainHandler = Handler(Looper.getMainLooper())
private val states = mutableMapOf<String, ContentUploadStateTracker.State>() 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.auth.data.HomeServerConnectionConfig
import im.vector.matrix.android.api.session.content.ContentUrlResolver import im.vector.matrix.android.api.session.content.ContentUrlResolver
import javax.inject.Inject




private const val MATRIX_CONTENT_URI_SCHEME = "mxc://" private const val MATRIX_CONTENT_URI_SCHEME = "mxc://"
private const val URI_PREFIX_CONTENT_API = "_matrix/media/v1/" 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 { companion object {
fun getUploadUrl(homeServerConnectionConfig: HomeServerConnectionConfig): String { 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
import arrow.core.Try.Companion.raise 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.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 im.vector.matrix.android.internal.network.ProgressRequestBody
import okhttp3.* import okhttp3.*
import java.io.File import java.io.File
import java.io.IOException import java.io.IOException
import javax.inject.Inject




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


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

private val moshi = MoshiProvider.providesMoshi()
private val responseAdapter = moshi.adapter(ContentUploadResponse::class.java) 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.toContent
import im.vector.matrix.android.api.session.events.model.toModel 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.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.network.ProgressRequestBody
import im.vector.matrix.android.internal.session.room.send.SendEventWorker import im.vector.matrix.android.internal.session.room.send.SendEventWorker
import im.vector.matrix.android.internal.util.WorkerParamsFactory import im.vector.matrix.android.internal.worker.SessionWorkerParams
import org.koin.standalone.inject import im.vector.matrix.android.internal.worker.WorkerParamsFactory
import im.vector.matrix.android.internal.worker.getSessionComponent
import timber.log.Timber import timber.log.Timber
import java.io.File import java.io.File
import javax.inject.Inject




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

private val fileUploader by inject<FileUploader>()
private val contentUploadProgressTracker by inject<DefaultContentUploadStateTracker>()


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

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


override suspend fun doWork(): Result { override suspend fun doWork(): Result {
val params = WorkerParamsFactory.fromData<Params>(inputData) 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 eventId = params.event.eventId ?: return Result.success()
val attachment = params.attachment val attachment = params.attachment
@ -69,7 +73,7 @@ internal class UploadContentWorker(context: Context, params: WorkerParameters)


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


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


private fun handleSuccess(params: Params, private fun handleSuccess(params: Params,
attachmentUrl: String, attachmentUrl: String,
thumbnailUrl: String?): Result { thumbnailUrl: String?): Result {
contentUploadProgressTracker.setFailure(params.event.eventId!!) contentUploadStateTracker.setSuccess(params.event.eventId!!)
val event = updateEvent(params.event, attachmentUrl, thumbnailUrl) 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)) return Result.success(WorkerParamsFactory.toData(sendParams))
} }


@ -131,6 +135,5 @@ internal class UploadContentWorker(context: Context, params: WorkerParameters)
return copy(url = url) 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.FilterEntity
import im.vector.matrix.android.internal.database.model.FilterEntityFields import im.vector.matrix.android.internal.database.model.FilterEntityFields
import im.vector.matrix.android.internal.database.query.getFilter import im.vector.matrix.android.internal.database.query.getFilter
import im.vector.matrix.android.internal.di.SessionDatabase
import io.realm.Realm import io.realm.Realm
import io.realm.RealmConfiguration import io.realm.RealmConfiguration
import io.realm.kotlin.where 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 { override fun storeFilter(filterBody: FilterBody, roomEventFilter: RoomEventFilter): Boolean {
val result: 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.api.session.sync.FilterService
import im.vector.matrix.android.internal.task.TaskExecutor import im.vector.matrix.android.internal.task.TaskExecutor
import im.vector.matrix.android.internal.task.configureWith import im.vector.matrix.android.internal.task.configureWith
import javax.inject.Inject


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


// TODO Pass a list of support events instead // TODO Pass a list of support events instead
override fun setFilter(filterPreset: FilterService.FilterPreset) { override fun setFilter(filterPreset: FilterService.FilterPreset) {
@ -30,7 +31,7 @@ internal class DefaultFilterService(private val filterRepository: FilterReposito
FilterService.FilterPreset.RiotFilter -> { FilterService.FilterPreset.RiotFilter -> {
FilterFactory.createRiotFilterBody() FilterFactory.createRiotFilterBody()
} }
FilterService.FilterPreset.NoFilter -> { FilterService.FilterPreset.NoFilter -> {
FilterFactory.createDefaultFilterBody() FilterFactory.createDefaultFilterBody()
} }
} }
@ -39,7 +40,7 @@ internal class DefaultFilterService(private val filterRepository: FilterReposito
FilterService.FilterPreset.RiotFilter -> { FilterService.FilterPreset.RiotFilter -> {
FilterFactory.createRiotRoomFilter() FilterFactory.createRiotRoomFilter()
} }
FilterService.FilterPreset.NoFilter -> { FilterService.FilterPreset.NoFilter -> {
FilterFactory.createDefaultRoomFilter() 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.api.auth.data.SessionParams
import im.vector.matrix.android.internal.network.executeRequest import im.vector.matrix.android.internal.network.executeRequest
import im.vector.matrix.android.internal.task.Task 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, internal class DefaultSaveFilterTask @Inject constructor(private val sessionParams: SessionParams,
private val filterAPI: FilterApi, private val filterAPI: FilterApi,
private val filterRepository: FilterRepository private val filterRepository: FilterRepository
) : SaveFilterTask { ) : SaveFilterTask {


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

View File

@ -42,5 +42,6 @@ internal interface FilterApi {
* @return Filter * @return Filter
*/ */
@GET(NetworkConstants.URI_API_PREFIX_PATH_R0 + "user/{userId}/filter/{filterId}") @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.task.Task
import im.vector.matrix.android.internal.util.tryTransactionSync import im.vector.matrix.android.internal.util.tryTransactionSync
import io.realm.kotlin.createObject import io.realm.kotlin.createObject
import javax.inject.Inject


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


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


} }



internal class DefaultGetGroupDataTask @Inject constructor(
internal class DefaultGetGroupDataTask(
private val groupAPI: GroupAPI, private val groupAPI: GroupAPI,
private val monarchy: Monarchy private val monarchy: Monarchy
) : GetGroupDataTask { ) : 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.GroupSummaryEntity
import im.vector.matrix.android.internal.database.model.GroupSummaryEntityFields import im.vector.matrix.android.internal.database.model.GroupSummaryEntityFields
import im.vector.matrix.android.internal.database.query.where 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? { override fun getGroup(groupId: String): Group? {
return null return null

View File

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


import android.content.Context import android.content.Context
import androidx.work.CoroutineWorker import androidx.work.CoroutineWorker
import androidx.work.Worker
import androidx.work.WorkerParameters import androidx.work.WorkerParameters
import arrow.core.Try import arrow.core.Try
import com.squareup.inject.assisted.Assisted
import com.squareup.inject.assisted.AssistedInject
import com.squareup.moshi.JsonClass import com.squareup.moshi.JsonClass
import im.vector.matrix.android.internal.di.MatrixKoinComponent import im.vector.matrix.android.internal.worker.DelegateWorkerFactory
import im.vector.matrix.android.internal.util.WorkerParamsFactory import im.vector.matrix.android.internal.worker.SessionWorkerParams
import org.koin.standalone.inject 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, internal class GetGroupDataWorker (context: Context, params: WorkerParameters) : CoroutineWorker(context, params) {
workerParameters: WorkerParameters
) : CoroutineWorker(context, workerParameters), MatrixKoinComponent {


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


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


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


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

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

View File

@ -16,22 +16,29 @@


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


import im.vector.matrix.android.internal.session.DefaultSession import dagger.Binds
import org.koin.dsl.module.module 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 import retrofit2.Retrofit


class GroupModule { @Module
internal abstract class GroupModule {


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

companion object {
scope(DefaultSession.SCOPE) { @Provides
val retrofit: Retrofit = get() @JvmStatic
retrofit.create(GroupAPI::class.java) @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