This commit is contained in:
Benoit Marty
2019-04-03 16:36:45 +02:00
parent 3091a337c9
commit 08dacacdda
20 changed files with 883 additions and 19 deletions

View File

@ -24,7 +24,7 @@ interface MatrixCallback<in T> {
/**
* On success method, default to no-op
* @param data the data successfuly returned from the async function
* @param data the data successfully returned from the async function
*/
fun onSuccess(data: T) {
//no-op

View File

@ -22,13 +22,19 @@ import im.vector.matrix.android.api.session.content.ContentUrlResolver
import im.vector.matrix.android.api.session.crypto.CryptoService
import im.vector.matrix.android.api.session.group.GroupService
import im.vector.matrix.android.api.session.room.RoomService
import im.vector.matrix.android.api.session.signout.SignOutService
import im.vector.matrix.android.api.session.user.UserService
/**
* This interface defines interactions with a session.
* An instance of a session will be provided by the SDK.
*/
interface Session : RoomService, GroupService, UserService, CryptoService {
interface Session :
RoomService,
GroupService,
UserService,
CryptoService,
SignOutService {
/**
* The params associated to the session

View File

@ -26,16 +26,16 @@ interface ReadService {
/**
* Force the read marker to be set on the latest event.
*/
fun markAllAsRead(callback: MatrixCallback<Void>)
fun markAllAsRead(callback: MatrixCallback<Unit>)
/**
* Set the read receipt on the event with provided eventId.
*/
fun setReadReceipt(eventId: String, callback: MatrixCallback<Void>)
fun setReadReceipt(eventId: String, callback: MatrixCallback<Unit>)
/**
* Set the read marker on the event with provided eventId.
*/
fun setReadMarker(fullyReadEventId: String, callback: MatrixCallback<Void>)
fun setReadMarker(fullyReadEventId: String, callback: MatrixCallback<Unit>)
}

View File

@ -0,0 +1,31 @@
/*
* 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.api.session.signout
import im.vector.matrix.android.api.MatrixCallback
/**
* This interface defines a method to sign out. It's implemented at the session level.
*/
interface SignOutService {
/**
* Sign out
*/
fun signOut(callback: MatrixCallback<Unit>)
}

View File

@ -25,4 +25,5 @@ internal interface SessionParamsStore {
fun save(sessionParams: SessionParams): Try<SessionParams>
fun delete()
}

View File

@ -17,13 +17,13 @@
package im.vector.matrix.android.internal.auth.db
import arrow.core.Try
import im.vector.matrix.android.internal.auth.SessionParamsStore
import im.vector.matrix.android.api.auth.data.SessionParams
import im.vector.matrix.android.internal.auth.SessionParamsStore
import io.realm.Realm
import io.realm.RealmConfiguration
internal class RealmSessionParamsStore(private val mapper: SessionParamsMapper,
private val realmConfiguration: RealmConfiguration) : SessionParamsStore {
private val realmConfiguration: RealmConfiguration) : SessionParamsStore {
override fun save(sessionParams: SessionParams): Try<SessionParams> {
return Try {
@ -50,4 +50,14 @@ internal class RealmSessionParamsStore(private val mapper: SessionParamsMapper,
return sessionParams
}
override fun delete() {
val realm = Realm.getInstance(realmConfiguration)
realm.executeTransaction {
it.where(SessionParamsEntity::class.java)
.findAll()
.deleteAllFromRealm()
}
realm.close()
}
}

View File

@ -20,6 +20,7 @@ import android.os.Looper
import androidx.annotation.MainThread
import androidx.lifecycle.LiveData
import com.zhuinden.monarchy.Monarchy
import im.vector.matrix.android.api.MatrixCallback
import im.vector.matrix.android.api.auth.data.SessionParams
import im.vector.matrix.android.api.session.Session
import im.vector.matrix.android.api.session.content.ContentUrlResolver
@ -29,13 +30,16 @@ import im.vector.matrix.android.api.session.group.model.GroupSummary
import im.vector.matrix.android.api.session.room.Room
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.signout.SignOutService
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.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.group.GroupModule
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.user.UserModule
@ -57,6 +61,7 @@ internal class DefaultSession(override val sessionParams: SessionParams) : Sessi
private val roomService by inject<RoomService>()
private val groupService by inject<GroupService>()
private val userService by inject<UserService>()
private val signOutService by inject<SignOutService>()
private val syncThread by inject<SyncThread>()
private val contentUrlResolver by inject<ContentUrlResolver>()
private var isOpen = false
@ -70,8 +75,9 @@ internal class DefaultSession(override val sessionParams: SessionParams) : Sessi
val syncModule = SyncModule().definition
val roomModule = RoomModule().definition
val groupModule = GroupModule().definition
val signOutModule = SignOutModule().definition
val userModule = UserModule().definition
MatrixKoinHolder.instance.loadModules(listOf(sessionModule, syncModule, roomModule, groupModule, userModule))
MatrixKoinHolder.instance.loadModules(listOf(sessionModule, syncModule, roomModule, groupModule, signOutModule, userModule))
scope = getKoin().getOrCreateScope(SCOPE)
if (!monarchy.isMonarchyThreadOpen) {
monarchy.openManually()
@ -94,6 +100,23 @@ internal class DefaultSession(override val sessionParams: SessionParams) : Sessi
isOpen = false
}
@MainThread
override fun signOut(callback: MatrixCallback<Unit>) {
assert(isOpen)
return signOutService.signOut(object : MatrixCallback<Unit> {
override fun onSuccess(data: Unit) {
// Close the session
close()
callback.onSuccess(data)
}
override fun onFailure(failure: Throwable) {
callback.onFailure(failure)
}
})
}
override fun contentUrlResolver(): ContentUrlResolver {
return contentUrlResolver
}

View File

@ -22,6 +22,7 @@ import im.vector.matrix.android.api.auth.data.SessionParams
import im.vector.matrix.android.api.session.content.ContentUrlResolver
import im.vector.matrix.android.api.session.group.GroupService
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.user.UserService
import im.vector.matrix.android.internal.database.LiveEntityObserver
import im.vector.matrix.android.internal.session.content.DefaultContentUrlResolver
@ -33,6 +34,7 @@ import im.vector.matrix.android.internal.session.room.RoomSummaryUpdater
import im.vector.matrix.android.internal.session.room.members.RoomDisplayNameResolver
import im.vector.matrix.android.internal.session.room.members.RoomMemberDisplayNameResolver
import im.vector.matrix.android.internal.session.room.prune.EventsPruner
import im.vector.matrix.android.internal.session.signout.DefaultSignOutService
import im.vector.matrix.android.internal.session.user.DefaultUserService
import im.vector.matrix.android.internal.session.user.UserEntityUpdater
import im.vector.matrix.android.internal.util.md5
@ -102,6 +104,10 @@ internal class SessionModule(private val sessionParams: SessionParams) {
DefaultGroupService(get()) as GroupService
}
scope(DefaultSession.SCOPE) {
DefaultSignOutService(get(), get()) as SignOutService
}
scope(DefaultSession.SCOPE) {
DefaultUserService(get()) as UserService
}

View File

@ -30,20 +30,20 @@ internal class DefaultReadService(private val roomId: String,
private val setReadMarkersTask: SetReadMarkersTask,
private val taskExecutor: TaskExecutor) : ReadService {
override fun markAllAsRead(callback: MatrixCallback<Void>) {
override fun markAllAsRead(callback: MatrixCallback<Unit>) {
val latestEvent = getLatestEvent()
val params = SetReadMarkersTask.Params(roomId, fullyReadEventId = latestEvent?.eventId, readReceiptEventId = latestEvent?.eventId)
setReadMarkersTask.configureWith(params).executeBy(taskExecutor)
setReadMarkersTask.configureWith(params).dispatchTo(callback).executeBy(taskExecutor)
}
override fun setReadReceipt(eventId: String, callback: MatrixCallback<Void>) {
override fun setReadReceipt(eventId: String, callback: MatrixCallback<Unit>) {
val params = SetReadMarkersTask.Params(roomId, fullyReadEventId = null, readReceiptEventId = eventId)
setReadMarkersTask.configureWith(params).executeBy(taskExecutor)
setReadMarkersTask.configureWith(params).dispatchTo(callback).executeBy(taskExecutor)
}
override fun setReadMarker(fullyReadEventId: String, callback: MatrixCallback<Void>) {
override fun setReadMarker(fullyReadEventId: String, callback: MatrixCallback<Unit>) {
val params = SetReadMarkersTask.Params(roomId, fullyReadEventId = fullyReadEventId, readReceiptEventId = null)
setReadMarkersTask.configureWith(params).executeBy(taskExecutor)
setReadMarkersTask.configureWith(params).dispatchTo(callback).executeBy(taskExecutor)
}
private fun getLatestEvent(): EventEntity? {

View File

@ -0,0 +1,34 @@
/*
* 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.signout
import im.vector.matrix.android.api.MatrixCallback
import im.vector.matrix.android.api.session.signout.SignOutService
import im.vector.matrix.android.internal.task.TaskExecutor
import im.vector.matrix.android.internal.task.configureWith
internal class DefaultSignOutService(private val signOutTask: SignOutTask,
private val taskExecutor: TaskExecutor) : SignOutService {
override fun signOut(callback: MatrixCallback<Unit>) {
signOutTask
.configureWith(Unit)
.dispatchTo(callback)
.executeBy(taskExecutor)
}
}

View File

@ -0,0 +1,31 @@
/*
* 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.signout
import im.vector.matrix.android.internal.network.NetworkConstants
import retrofit2.Call
import retrofit2.http.POST
internal interface SignOutAPI {
/**
* Invalidate the access token, so that it can no longer be used for authorization.
*/
@POST(NetworkConstants.URI_API_PREFIX_PATH_R0 + "logout")
fun signOut(): Call<Unit>
}

View File

@ -0,0 +1,37 @@
/*
* 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.signout
import im.vector.matrix.android.internal.session.DefaultSession
import org.koin.dsl.module.module
import retrofit2.Retrofit
class SignOutModule {
val definition = module(override = true) {
scope(DefaultSession.SCOPE) {
val retrofit: Retrofit = get()
retrofit.create(SignOutAPI::class.java)
}
scope(DefaultSession.SCOPE) {
DefaultSignOutTask(get(), get()) as SignOutTask
}
}
}

View File

@ -0,0 +1,38 @@
/*
* 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.signout
import arrow.core.Try
import im.vector.matrix.android.internal.auth.SessionParamsStore
import im.vector.matrix.android.internal.network.executeRequest
import im.vector.matrix.android.internal.task.Task
internal interface SignOutTask : Task<Unit, Unit>
internal class DefaultSignOutTask(private val signOutAPI: SignOutAPI,
private val sessionParamsStore: SessionParamsStore) : SignOutTask {
override fun execute(params: Unit): Try<Unit> {
return executeRequest<Unit> {
apiCall = signOutAPI.signOut()
}.map {
// TODO Clear DB, media cache, etc.
sessionParamsStore.delete()
}
}
}