Rework a bit user account data (and avoid blocking syncs)

This commit is contained in:
ganfra 2020-07-20 19:52:24 +02:00
parent 35fe4f7268
commit 1436477a14
33 changed files with 117 additions and 321 deletions

View file

@ -42,8 +42,7 @@ import im.vector.matrix.android.api.util.toOptional
import im.vector.matrix.android.internal.crypto.model.CryptoDeviceInfo
import im.vector.matrix.android.internal.crypto.model.rest.DeviceInfo
import im.vector.matrix.android.internal.crypto.store.PrivateKeysInfo
import im.vector.matrix.android.internal.session.sync.model.accountdata.UserAccountData
import im.vector.matrix.android.internal.session.sync.model.accountdata.UserAccountDataEvent
import im.vector.matrix.android.api.session.accountdata.UserAccountDataEvent
import io.reactivex.Observable
import io.reactivex.Single
import io.reactivex.functions.Function3
@ -179,7 +178,7 @@ class RxSession(private val session: Session) {
}
fun liveSecretSynchronisationInfo(): Observable<SecretsSynchronisationInfo> {
return Observable.combineLatest<List<UserAccountData>, Optional<MXCrossSigningInfo>, Optional<PrivateKeysInfo>, SecretsSynchronisationInfo>(
return Observable.combineLatest<List<UserAccountDataEvent>, Optional<MXCrossSigningInfo>, Optional<PrivateKeysInfo>, SecretsSynchronisationInfo>(
liveAccountData(setOf(MASTER_KEY_SSSS_NAME, USER_SIGNING_KEY_SSSS_NAME, SELF_SIGNING_KEY_SSSS_NAME, KEYBACKUP_SECRET_SSSS_NAME)),
liveCrossSigningInfo(session.myUserId),
liveCrossSigningPrivateKeys(),

View file

@ -35,7 +35,7 @@ import im.vector.matrix.android.common.TestMatrixCallback
import im.vector.matrix.android.internal.crypto.SSSS_ALGORITHM_AES_HMAC_SHA2
import im.vector.matrix.android.internal.crypto.crosssigning.toBase64NoPadding
import im.vector.matrix.android.internal.crypto.secrets.DefaultSharedSecretStorageService
import im.vector.matrix.android.internal.session.sync.model.accountdata.UserAccountDataEvent
import im.vector.matrix.android.api.session.accountdata.UserAccountDataEvent
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.launch

View file

@ -21,7 +21,6 @@ import im.vector.matrix.android.api.MatrixCallback
import im.vector.matrix.android.api.session.events.model.Content
import im.vector.matrix.android.api.util.Cancelable
import im.vector.matrix.android.api.util.Optional
import im.vector.matrix.android.internal.session.sync.model.accountdata.UserAccountDataEvent
interface AccountDataService {
/**

View file

@ -14,14 +14,18 @@
* limitations under the License.
*/
package im.vector.matrix.android.internal.session.sync.model.accountdata
package im.vector.matrix.android.api.session.accountdata
import com.squareup.moshi.Json
import com.squareup.moshi.JsonClass
import im.vector.matrix.android.internal.session.integrationmanager.AllowedWidgetsContent
import im.vector.matrix.android.api.session.events.model.Content
/**
* This is a simplified Event with just a type and a content.
* Currently used types are defined in [UserAccountDataTypes].
*/
@JsonClass(generateAdapter = true)
internal data class UserAccountDataAllowedWidgets(
@Json(name = "type") override val type: String = TYPE_ALLOWED_WIDGETS,
@Json(name = "content") val content: AllowedWidgetsContent
) : UserAccountData()
data class UserAccountDataEvent(
@Json(name = "type") val type: String,
@Json(name = "content") val content: Content
)

View file

@ -0,0 +1,32 @@
/*
* 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.accountdata
object UserAccountDataTypes {
const val TYPE_IGNORED_USER_LIST = "m.ignored_user_list"
const val TYPE_DIRECT_MESSAGES = "m.direct"
const val TYPE_BREADCRUMBS = "im.vector.setting.breadcrumbs" // Was previously "im.vector.riot.breadcrumb_rooms"
const val TYPE_PREVIEW_URLS = "org.matrix.preview_urls"
const val TYPE_WIDGETS = "m.widgets"
const val TYPE_PUSH_RULES = "m.push_rules"
const val TYPE_INTEGRATION_PROVISIONING = "im.vector.setting.integration_provisioning"
const val TYPE_ALLOWED_WIDGETS = "im.vector.setting.allowed_widgets"
const val TYPE_IDENTITY_SERVER = "m.identity_server"
const val TYPE_ACCEPTED_TERMS = "m.accepted_terms"
}

View file

@ -19,7 +19,7 @@ package im.vector.matrix.android.internal.database.mapper
import com.squareup.moshi.Moshi
import im.vector.matrix.android.api.util.JSON_DICT_PARAMETERIZED_TYPE
import im.vector.matrix.android.internal.database.model.UserAccountDataEntity
import im.vector.matrix.android.internal.session.sync.model.accountdata.UserAccountDataEvent
import im.vector.matrix.android.api.session.accountdata.UserAccountDataEvent
import javax.inject.Inject
internal class AccountDataMapper @Inject constructor(moshi: Moshi) {

View file

@ -34,24 +34,12 @@ import im.vector.matrix.android.api.session.room.model.message.MessageVideoConte
import im.vector.matrix.android.internal.network.parsing.ForceToBooleanJsonAdapter
import im.vector.matrix.android.internal.network.parsing.RuntimeJsonAdapterFactory
import im.vector.matrix.android.internal.network.parsing.UriMoshiAdapter
import im.vector.matrix.android.internal.session.sync.model.accountdata.UserAccountData
import im.vector.matrix.android.internal.session.sync.model.accountdata.UserAccountDataBreadcrumbs
import im.vector.matrix.android.internal.session.sync.model.accountdata.UserAccountDataDirectMessages
import im.vector.matrix.android.internal.session.sync.model.accountdata.UserAccountDataEvent
import im.vector.matrix.android.internal.session.sync.model.accountdata.UserAccountDataIgnoredUsers
import im.vector.matrix.android.internal.session.sync.model.accountdata.UserAccountDataPushRules
object MoshiProvider {
private val moshi: Moshi = Moshi.Builder()
.add(UriMoshiAdapter())
.add(ForceToBooleanJsonAdapter())
.add(RuntimeJsonAdapterFactory.of(UserAccountData::class.java, "type", UserAccountDataEvent::class.java)
.registerSubtype(UserAccountDataDirectMessages::class.java, UserAccountData.TYPE_DIRECT_MESSAGES)
.registerSubtype(UserAccountDataIgnoredUsers::class.java, UserAccountData.TYPE_IGNORED_USER_LIST)
.registerSubtype(UserAccountDataPushRules::class.java, UserAccountData.TYPE_PUSH_RULES)
.registerSubtype(UserAccountDataBreadcrumbs::class.java, UserAccountData.TYPE_BREADCRUMBS)
)
.add(RuntimeJsonAdapterFactory.of(MessageContent::class.java, "msgtype", MessageDefaultContent::class.java)
.registerSubtype(MessageTextContent::class.java, MessageType.MSGTYPE_TEXT)
.registerSubtype(MessageNoticeContent::class.java, MessageType.MSGTYPE_NOTICE)

View file

@ -46,7 +46,7 @@ import im.vector.matrix.android.internal.session.openid.GetOpenIdTokenTask
import im.vector.matrix.android.internal.session.profile.BindThreePidsTask
import im.vector.matrix.android.internal.session.profile.UnbindThreePidsTask
import im.vector.matrix.android.internal.session.sync.model.accountdata.IdentityServerContent
import im.vector.matrix.android.internal.session.sync.model.accountdata.UserAccountData
import im.vector.matrix.android.api.session.accountdata.UserAccountDataTypes
import im.vector.matrix.android.internal.session.user.accountdata.AccountDataDataSource
import im.vector.matrix.android.internal.session.user.accountdata.UpdateUserAccountDataTask
import im.vector.matrix.android.internal.task.TaskExecutor
@ -95,7 +95,7 @@ internal class DefaultIdentityService @Inject constructor(
lifecycleRegistry.currentState = Lifecycle.State.STARTED
// Observe the account data change
accountDataDataSource
.getLiveAccountDataEvent(UserAccountData.TYPE_IDENTITY_SERVER)
.getLiveAccountDataEvent(UserAccountDataTypes.TYPE_IDENTITY_SERVER)
.observeNotNull(lifecycleOwner) {
notifyIdentityServerUrlChange(it.getOrNull()?.content?.toModel<IdentityServerContent>()?.baseUrl)
}

View file

@ -34,8 +34,8 @@ import im.vector.matrix.android.internal.di.SessionDatabase
import im.vector.matrix.android.internal.extensions.observeNotNull
import im.vector.matrix.android.internal.session.SessionLifecycleObserver
import im.vector.matrix.android.internal.session.SessionScope
import im.vector.matrix.android.internal.session.sync.model.accountdata.UserAccountData
import im.vector.matrix.android.internal.session.sync.model.accountdata.UserAccountDataEvent
import im.vector.matrix.android.api.session.accountdata.UserAccountDataTypes
import im.vector.matrix.android.api.session.accountdata.UserAccountDataEvent
import im.vector.matrix.android.internal.session.user.accountdata.AccountDataDataSource
import im.vector.matrix.android.internal.session.user.accountdata.UpdateUserAccountDataTask
import im.vector.matrix.android.internal.session.widgets.helper.WidgetFactory
@ -87,7 +87,7 @@ internal class IntegrationManager @Inject constructor(matrixConfiguration: Matri
lifecycleRegistry.currentState = Lifecycle.State.STARTED
observeWellknownConfig()
accountDataDataSource
.getLiveAccountDataEvent(UserAccountData.TYPE_ALLOWED_WIDGETS)
.getLiveAccountDataEvent(UserAccountDataTypes.TYPE_ALLOWED_WIDGETS)
.observeNotNull(lifecycleOwner) {
val allowedWidgetsContent = it.getOrNull()?.content?.toModel<AllowedWidgetsContent>()
if (allowedWidgetsContent != null) {
@ -95,7 +95,7 @@ internal class IntegrationManager @Inject constructor(matrixConfiguration: Matri
}
}
accountDataDataSource
.getLiveAccountDataEvent(UserAccountData.TYPE_INTEGRATION_PROVISIONING)
.getLiveAccountDataEvent(UserAccountDataTypes.TYPE_INTEGRATION_PROVISIONING)
.observeNotNull(lifecycleOwner) {
val integrationProvisioningContent = it.getOrNull()?.content?.toModel<IntegrationProvisioningContent>()
if (integrationProvisioningContent != null) {
@ -103,7 +103,7 @@ internal class IntegrationManager @Inject constructor(matrixConfiguration: Matri
}
}
accountDataDataSource
.getLiveAccountDataEvent(UserAccountData.TYPE_WIDGETS)
.getLiveAccountDataEvent(UserAccountDataTypes.TYPE_WIDGETS)
.observeNotNull(lifecycleOwner) {
val integrationManagerContent = it.getOrNull()?.asIntegrationManagerWidgetContent()
val config = integrationManagerContent?.extractIntegrationManagerConfig()
@ -132,7 +132,7 @@ internal class IntegrationManager @Inject constructor(matrixConfiguration: Matri
* Returns false if the user as disabled integration manager feature
*/
fun isIntegrationEnabled(): Boolean {
val integrationProvisioningData = accountDataDataSource.getAccountDataEvent(UserAccountData.TYPE_INTEGRATION_PROVISIONING)
val integrationProvisioningData = accountDataDataSource.getAccountDataEvent(UserAccountDataTypes.TYPE_INTEGRATION_PROVISIONING)
val integrationProvisioningContent = integrationProvisioningData?.content?.toModel<IntegrationProvisioningContent>()
return integrationProvisioningContent?.enabled ?: false
}
@ -153,7 +153,7 @@ internal class IntegrationManager @Inject constructor(matrixConfiguration: Matri
}
fun setWidgetAllowed(stateEventId: String, allowed: Boolean, callback: MatrixCallback<Unit>): Cancelable {
val currentAllowedWidgets = accountDataDataSource.getAccountDataEvent(UserAccountData.TYPE_ALLOWED_WIDGETS)
val currentAllowedWidgets = accountDataDataSource.getAccountDataEvent(UserAccountDataTypes.TYPE_ALLOWED_WIDGETS)
val currentContent = currentAllowedWidgets?.content?.toModel<AllowedWidgetsContent>()
val newContent = if (currentContent == null) {
val allowedWidget = mapOf(stateEventId to allowed)
@ -173,13 +173,13 @@ internal class IntegrationManager @Inject constructor(matrixConfiguration: Matri
}
fun isWidgetAllowed(stateEventId: String): Boolean {
val currentAllowedWidgets = accountDataDataSource.getAccountDataEvent(UserAccountData.TYPE_ALLOWED_WIDGETS)
val currentAllowedWidgets = accountDataDataSource.getAccountDataEvent(UserAccountDataTypes.TYPE_ALLOWED_WIDGETS)
val currentContent = currentAllowedWidgets?.content?.toModel<AllowedWidgetsContent>()
return currentContent?.widgets?.get(stateEventId) ?: false
}
fun setNativeWidgetDomainAllowed(widgetType: String, domain: String, allowed: Boolean, callback: MatrixCallback<Unit>): Cancelable {
val currentAllowedWidgets = accountDataDataSource.getAccountDataEvent(UserAccountData.TYPE_ALLOWED_WIDGETS)
val currentAllowedWidgets = accountDataDataSource.getAccountDataEvent(UserAccountDataTypes.TYPE_ALLOWED_WIDGETS)
val currentContent = currentAllowedWidgets?.content?.toModel<AllowedWidgetsContent>()
val newContent = if (currentContent == null) {
val nativeAllowedWidgets = mapOf(widgetType to mapOf(domain to allowed))
@ -203,7 +203,7 @@ internal class IntegrationManager @Inject constructor(matrixConfiguration: Matri
}
fun isNativeWidgetDomainAllowed(widgetType: String, domain: String?): Boolean {
val currentAllowedWidgets = accountDataDataSource.getAccountDataEvent(UserAccountData.TYPE_ALLOWED_WIDGETS)
val currentAllowedWidgets = accountDataDataSource.getAccountDataEvent(UserAccountDataTypes.TYPE_ALLOWED_WIDGETS)
val currentContent = currentAllowedWidgets?.content?.toModel<AllowedWidgetsContent>()
return currentContent?.native?.get(widgetType)?.get(domain) ?: false
}

View file

@ -16,11 +16,14 @@
package im.vector.matrix.android.internal.session.sync
import com.squareup.moshi.Moshi
import com.zhuinden.monarchy.Monarchy
import im.vector.matrix.android.api.pushrules.RuleScope
import im.vector.matrix.android.api.pushrules.RuleSetKey
import im.vector.matrix.android.api.pushrules.rest.GetPushRulesResponse
import im.vector.matrix.android.api.session.accountdata.UserAccountDataEvent
import im.vector.matrix.android.api.session.accountdata.UserAccountDataTypes
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.events.model.toModel
import im.vector.matrix.android.api.session.room.model.RoomMemberContent
import im.vector.matrix.android.api.session.room.model.RoomSummary
@ -37,16 +40,13 @@ import im.vector.matrix.android.internal.database.model.UserAccountDataEntityFie
import im.vector.matrix.android.internal.database.query.getDirectRooms
import im.vector.matrix.android.internal.database.query.getOrCreate
import im.vector.matrix.android.internal.database.query.where
import im.vector.matrix.android.internal.di.MoshiProvider
import im.vector.matrix.android.internal.di.SessionDatabase
import im.vector.matrix.android.internal.di.UserId
import im.vector.matrix.android.internal.session.room.membership.RoomMemberHelper
import im.vector.matrix.android.internal.session.sync.model.InvitedRoomSync
import im.vector.matrix.android.internal.session.sync.model.accountdata.UserAccountData
import im.vector.matrix.android.internal.session.sync.model.accountdata.UserAccountDataBreadcrumbs
import im.vector.matrix.android.internal.session.sync.model.accountdata.UserAccountDataDirectMessages
import im.vector.matrix.android.internal.session.sync.model.accountdata.UserAccountDataIgnoredUsers
import im.vector.matrix.android.internal.session.sync.model.accountdata.UserAccountDataPushRules
import im.vector.matrix.android.internal.session.sync.model.accountdata.BreadcrumbsContent
import im.vector.matrix.android.internal.session.sync.model.accountdata.DirectMessagesContent
import im.vector.matrix.android.internal.session.sync.model.accountdata.IgnoredUsersContent
import im.vector.matrix.android.internal.session.sync.model.accountdata.UserAccountDataSync
import im.vector.matrix.android.internal.session.user.accountdata.DirectChatsHelper
import im.vector.matrix.android.internal.session.user.accountdata.UpdateUserAccountDataTask
@ -60,25 +60,18 @@ internal class UserAccountDataSyncHandler @Inject constructor(
@SessionDatabase private val monarchy: Monarchy,
@UserId private val userId: String,
private val directChatsHelper: DirectChatsHelper,
private val moshi: Moshi,
private val updateUserAccountDataTask: UpdateUserAccountDataTask) {
fun handle(realm: Realm, accountData: UserAccountDataSync?) {
accountData?.list?.forEach {
accountData?.list?.forEach { event ->
// Generic handling, just save in base
handleGenericAccountData(realm, it.type, it.content)
// Didn't want to break too much thing, so i re-serialize to jsonString before reparsing
// TODO would be better to have a mapper?
val toJson = MoshiProvider.providesMoshi().adapter(Event::class.java).toJson(it)
val model = toJson?.let { json ->
MoshiProvider.providesMoshi().adapter(UserAccountData::class.java).fromJson(json)
}
// Specific parsing
when (model) {
is UserAccountDataDirectMessages -> handleDirectChatRooms(realm, model)
is UserAccountDataPushRules -> handlePushRules(realm, model)
is UserAccountDataIgnoredUsers -> handleIgnoredUsers(realm, model)
is UserAccountDataBreadcrumbs -> handleBreadcrumbs(realm, model)
handleGenericAccountData(realm, event.type, event.content)
when (event.type) {
UserAccountDataTypes.TYPE_DIRECT_MESSAGES -> handleDirectChatRooms(realm, event)
UserAccountDataTypes.TYPE_PUSH_RULES -> handlePushRules(realm, event)
UserAccountDataTypes.TYPE_IGNORED_USER_LIST -> handleIgnoredUsers(realm, event)
UserAccountDataTypes.TYPE_BREADCRUMBS -> handleBreadcrumbs(realm, event)
}
}
}
@ -116,8 +109,8 @@ internal class UserAccountDataSyncHandler @Inject constructor(
}
}
private fun handlePushRules(realm: Realm, userAccountDataPushRules: UserAccountDataPushRules) {
val pushRules = userAccountDataPushRules.content
private fun handlePushRules(realm: Realm, event: UserAccountDataEvent) {
val pushRules = event.content.toModel<GetPushRulesResponse>() ?: return
realm.where(PushRulesEntity::class.java)
.findAll()
.deleteAllFromRealm()
@ -158,13 +151,14 @@ internal class UserAccountDataSyncHandler @Inject constructor(
realm.insertOrUpdate(underrides)
}
private fun handleDirectChatRooms(realm: Realm, directMessages: UserAccountDataDirectMessages) {
private fun handleDirectChatRooms(realm: Realm, event: UserAccountDataEvent) {
val oldDirectRooms = RoomSummaryEntity.getDirectRooms(realm)
oldDirectRooms.forEach {
it.isDirect = false
it.directUserId = null
}
directMessages.content.forEach {
val content = event.content.toModel<DirectMessagesContent>() ?: return
content.forEach {
val userId = it.key
it.value.forEach { roomId ->
val roomSummaryEntity = RoomSummaryEntity.where(realm, roomId).findFirst()
@ -177,8 +171,8 @@ internal class UserAccountDataSyncHandler @Inject constructor(
}
}
private fun handleIgnoredUsers(realm: Realm, userAccountDataIgnoredUsers: UserAccountDataIgnoredUsers) {
val userIds = userAccountDataIgnoredUsers.content.ignoredUsers.keys
private fun handleIgnoredUsers(realm: Realm, event: UserAccountDataEvent) {
val userIds = event.content.toModel<IgnoredUsersContent>()?.ignoredUsers?.keys ?: return
realm.where(IgnoredUserEntity::class.java)
.findAll()
.deleteAllFromRealm()
@ -187,8 +181,8 @@ internal class UserAccountDataSyncHandler @Inject constructor(
// TODO If not initial sync, we should execute a init sync
}
private fun handleBreadcrumbs(realm: Realm, userAccountDataBreadcrumbs: UserAccountDataBreadcrumbs) {
val recentRoomIds = userAccountDataBreadcrumbs.content.recentRoomIds
private fun handleBreadcrumbs(realm: Realm, event: UserAccountDataEvent) {
val recentRoomIds = event.content.toModel<BreadcrumbsContent>()?.recentRoomIds ?: return
val entity = BreadcrumbsEntity.getOrCreate(realm)
// And save the new received list

View file

@ -19,12 +19,6 @@ package im.vector.matrix.android.internal.session.sync.model.accountdata
import com.squareup.moshi.Json
import com.squareup.moshi.JsonClass
@JsonClass(generateAdapter = true)
internal data class UserAccountDataAcceptedTerms(
@Json(name = "type") override val type: String = TYPE_ACCEPTED_TERMS,
@Json(name = "content") val content: AcceptedTermsContent
) : UserAccountData()
@JsonClass(generateAdapter = true)
internal data class AcceptedTermsContent(
@Json(name = "accepted") val acceptedTerms: List<String> = emptyList()

View file

@ -19,12 +19,6 @@ package im.vector.matrix.android.internal.session.sync.model.accountdata
import com.squareup.moshi.Json
import com.squareup.moshi.JsonClass
@JsonClass(generateAdapter = true)
internal data class UserAccountDataBreadcrumbs(
@Json(name = "type") override val type: String = TYPE_BREADCRUMBS,
@Json(name = "content") val content: BreadcrumbsContent
) : UserAccountData()
@JsonClass(generateAdapter = true)
internal data class BreadcrumbsContent(
@Json(name = "recent_rooms") val recentRoomIds: List<String> = emptyList()

View file

@ -16,12 +16,4 @@
package im.vector.matrix.android.internal.session.sync.model.accountdata
import com.squareup.moshi.Json
import com.squareup.moshi.JsonClass
import im.vector.matrix.android.api.util.JsonDict
@JsonClass(generateAdapter = true)
data class UserAccountDataEvent(
@Json(name = "type") override val type: String,
@Json(name = "content") val content: JsonDict
) : UserAccountData()
typealias DirectMessagesContent = Map<String, List<String>>

View file

@ -19,12 +19,6 @@ package im.vector.matrix.android.internal.session.sync.model.accountdata
import com.squareup.moshi.Json
import com.squareup.moshi.JsonClass
@JsonClass(generateAdapter = true)
internal data class UserAccountDataIdentityServer(
@Json(name = "type") override val type: String = TYPE_IDENTITY_SERVER,
@Json(name = "content") val content: IdentityServerContent? = null
) : UserAccountData()
@JsonClass(generateAdapter = true)
internal data class IdentityServerContent(
@Json(name = "base_url") val baseUrl: String? = null

View file

@ -1,38 +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.session.sync.model.accountdata
import com.squareup.moshi.Json
import im.vector.matrix.android.internal.session.user.accountdata.AccountDataContent
abstract class UserAccountData : AccountDataContent {
@Json(name = "type") abstract val type: String
companion object {
const val TYPE_IGNORED_USER_LIST = "m.ignored_user_list"
const val TYPE_DIRECT_MESSAGES = "m.direct"
const val TYPE_BREADCRUMBS = "im.vector.setting.breadcrumbs" // Was previously "im.vector.riot.breadcrumb_rooms"
const val TYPE_PREVIEW_URLS = "org.matrix.preview_urls"
const val TYPE_WIDGETS = "m.widgets"
const val TYPE_PUSH_RULES = "m.push_rules"
const val TYPE_INTEGRATION_PROVISIONING = "im.vector.setting.integration_provisioning"
const val TYPE_ALLOWED_WIDGETS = "im.vector.setting.allowed_widgets"
const val TYPE_IDENTITY_SERVER = "m.identity_server"
const val TYPE_ACCEPTED_TERMS = "m.accepted_terms"
}
}

View file

@ -1,26 +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.session.sync.model.accountdata
import com.squareup.moshi.Json
import com.squareup.moshi.JsonClass
@JsonClass(generateAdapter = true)
internal data class UserAccountDataDirectMessages(
@Json(name = "type") override val type: String = TYPE_DIRECT_MESSAGES,
@Json(name = "content") val content: Map<String, List<String>>
) : UserAccountData()

View file

@ -1,26 +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.session.sync.model.accountdata
import com.squareup.moshi.Json
import com.squareup.moshi.JsonClass
@JsonClass(generateAdapter = true)
internal data class UserAccountDataIgnoredUsers(
@Json(name = "type") override val type: String = TYPE_IGNORED_USER_LIST,
@Json(name = "content") val content: IgnoredUsersContent
) : UserAccountData()

View file

@ -1,27 +0,0 @@
/*
* Copyright (c) 2020 New Vector Ltd
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package im.vector.matrix.android.internal.session.sync.model.accountdata
import com.squareup.moshi.Json
import com.squareup.moshi.JsonClass
import im.vector.matrix.android.internal.session.integrationmanager.IntegrationProvisioningContent
@JsonClass(generateAdapter = true)
internal data class UserAccountDataIntegrationProvisioning(
@Json(name = "type") override val type: String = TYPE_INTEGRATION_PROVISIONING,
@Json(name = "content") val content: IntegrationProvisioningContent
) : UserAccountData()

View file

@ -1,27 +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.session.sync.model.accountdata
import com.squareup.moshi.Json
import com.squareup.moshi.JsonClass
import im.vector.matrix.android.api.pushrules.rest.GetPushRulesResponse
@JsonClass(generateAdapter = true)
internal data class UserAccountDataPushRules(
@Json(name = "type") override val type: String = TYPE_PUSH_RULES,
@Json(name = "content") val content: GetPushRulesResponse
) : UserAccountData()

View file

@ -18,9 +18,9 @@ package im.vector.matrix.android.internal.session.sync.model.accountdata
import com.squareup.moshi.Json
import com.squareup.moshi.JsonClass
import im.vector.matrix.android.api.session.events.model.Event
import im.vector.matrix.android.api.session.accountdata.UserAccountDataEvent
@JsonClass(generateAdapter = true)
internal data class UserAccountDataSync(
@Json(name = "events") val list: List<Event> = emptyList()
@Json(name = "events") val list: List<UserAccountDataEvent> = emptyList()
)

View file

@ -1,50 +0,0 @@
/*
* Copyright (c) 2020 New Vector Ltd
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package im.vector.matrix.android.internal.session.sync.model.accountdata
import com.squareup.moshi.Json
import com.squareup.moshi.JsonClass
import im.vector.matrix.android.api.session.events.model.Event
/*
"m.widgets":{
"stickerpicker_@rxl881:matrix.org_1514573757015":{
"content":{
"creatorUserId":"@rxl881:matrix.org",
"data":{
"..."
},
"id":"stickerpicker_@rxl881:matrix.org_1514573757015",
"name":"Stickerpicker",
"type":"m.stickerpicker",
"url":"https://...",
"waitForIframeLoad":true
},
"sender":"@rxl881:matrix.org"
"state_key":"stickerpicker_@rxl881:matrix.org_1514573757015",
"type":"m.widget"
},
{
"..."
}
}
*/
@JsonClass(generateAdapter = true)
internal data class UserAccountDataWidgets(
@Json(name = "type") override val type: String = TYPE_WIDGETS,
@Json(name = "content") val content: Map<String, Event>
) : UserAccountData()

View file

@ -30,7 +30,7 @@ import im.vector.matrix.android.internal.session.identity.IdentityAuthAPI
import im.vector.matrix.android.internal.session.identity.IdentityRegisterTask
import im.vector.matrix.android.internal.session.openid.GetOpenIdTokenTask
import im.vector.matrix.android.internal.session.sync.model.accountdata.AcceptedTermsContent
import im.vector.matrix.android.internal.session.sync.model.accountdata.UserAccountData
import im.vector.matrix.android.api.session.accountdata.UserAccountDataTypes
import im.vector.matrix.android.internal.session.user.accountdata.AccountDataDataSource
import im.vector.matrix.android.internal.session.user.accountdata.UpdateUserAccountDataTask
import im.vector.matrix.android.internal.task.TaskExecutor
@ -109,7 +109,7 @@ internal class DefaultTermsService @Inject constructor(
}
private fun getAlreadyAcceptedTermUrlsFromAccountData(): Set<String> {
return accountDataDataSource.getAccountDataEvent(UserAccountData.TYPE_ACCEPTED_TERMS)
return accountDataDataSource.getAccountDataEvent(UserAccountDataTypes.TYPE_ACCEPTED_TERMS)
?.content
?.toModel<AcceptedTermsContent>()
?.acceptedTerms

View file

@ -25,7 +25,7 @@ import im.vector.matrix.android.internal.database.mapper.AccountDataMapper
import im.vector.matrix.android.internal.database.model.UserAccountDataEntity
import im.vector.matrix.android.internal.database.model.UserAccountDataEntityFields
import im.vector.matrix.android.internal.di.SessionDatabase
import im.vector.matrix.android.internal.session.sync.model.accountdata.UserAccountDataEvent
import im.vector.matrix.android.api.session.accountdata.UserAccountDataEvent
import io.realm.Realm
import io.realm.RealmQuery
import javax.inject.Inject

View file

@ -25,7 +25,7 @@ import im.vector.matrix.android.api.util.Cancelable
import im.vector.matrix.android.api.util.Optional
import im.vector.matrix.android.internal.di.SessionDatabase
import im.vector.matrix.android.internal.session.sync.UserAccountDataSyncHandler
import im.vector.matrix.android.internal.session.sync.model.accountdata.UserAccountDataEvent
import im.vector.matrix.android.api.session.accountdata.UserAccountDataEvent
import im.vector.matrix.android.internal.task.TaskExecutor
import im.vector.matrix.android.internal.task.configureWith
import javax.inject.Inject

View file

@ -22,7 +22,7 @@ import im.vector.matrix.android.internal.di.SessionDatabase
import im.vector.matrix.android.internal.di.UserId
import im.vector.matrix.android.internal.network.executeRequest
import im.vector.matrix.android.internal.session.sync.model.accountdata.IgnoredUsersContent
import im.vector.matrix.android.internal.session.sync.model.accountdata.UserAccountData
import im.vector.matrix.android.api.session.accountdata.UserAccountDataTypes
import im.vector.matrix.android.internal.task.Task
import org.greenrobot.eventbus.EventBus
import javax.inject.Inject
@ -64,7 +64,7 @@ internal class DefaultUpdateIgnoredUserIdsTask @Inject constructor(
val body = IgnoredUsersContent.createWithUserIds(list)
executeRequest<Unit>(eventBus) {
apiCall = accountDataApi.setAccountData(userId, UserAccountData.TYPE_IGNORED_USER_LIST, body)
apiCall = accountDataApi.setAccountData(userId, UserAccountDataTypes.TYPE_IGNORED_USER_LIST, body)
}
// Update the DB right now (do not wait for the sync to come back with updated data, for a faster UI update)

View file

@ -23,7 +23,7 @@ import im.vector.matrix.android.internal.session.integrationmanager.IntegrationP
import im.vector.matrix.android.internal.session.sync.model.accountdata.AcceptedTermsContent
import im.vector.matrix.android.internal.session.sync.model.accountdata.BreadcrumbsContent
import im.vector.matrix.android.internal.session.sync.model.accountdata.IdentityServerContent
import im.vector.matrix.android.internal.session.sync.model.accountdata.UserAccountData
import im.vector.matrix.android.api.session.accountdata.UserAccountDataTypes
import im.vector.matrix.android.internal.task.Task
import org.greenrobot.eventbus.EventBus
import javax.inject.Inject
@ -35,7 +35,7 @@ internal interface UpdateUserAccountDataTask : Task<UpdateUserAccountDataTask.Pa
fun getData(): Any
}
data class IdentityParams(override val type: String = UserAccountData.TYPE_IDENTITY_SERVER,
data class IdentityParams(override val type: String = UserAccountDataTypes.TYPE_IDENTITY_SERVER,
private val identityContent: IdentityServerContent
) : Params {
@ -44,7 +44,7 @@ internal interface UpdateUserAccountDataTask : Task<UpdateUserAccountDataTask.Pa
}
}
data class AcceptedTermsParams(override val type: String = UserAccountData.TYPE_ACCEPTED_TERMS,
data class AcceptedTermsParams(override val type: String = UserAccountDataTypes.TYPE_ACCEPTED_TERMS,
private val acceptedTermsContent: AcceptedTermsContent
) : Params {
@ -54,7 +54,7 @@ internal interface UpdateUserAccountDataTask : Task<UpdateUserAccountDataTask.Pa
}
// TODO Use [UserAccountDataDirectMessages] class?
data class DirectChatParams(override val type: String = UserAccountData.TYPE_DIRECT_MESSAGES,
data class DirectChatParams(override val type: String = UserAccountDataTypes.TYPE_DIRECT_MESSAGES,
private val directMessages: Map<String, List<String>>
) : Params {
@ -63,7 +63,7 @@ internal interface UpdateUserAccountDataTask : Task<UpdateUserAccountDataTask.Pa
}
}
data class BreadcrumbsParams(override val type: String = UserAccountData.TYPE_BREADCRUMBS,
data class BreadcrumbsParams(override val type: String = UserAccountDataTypes.TYPE_BREADCRUMBS,
private val breadcrumbsContent: BreadcrumbsContent
) : Params {
@ -72,7 +72,7 @@ internal interface UpdateUserAccountDataTask : Task<UpdateUserAccountDataTask.Pa
}
}
data class AllowedWidgets(override val type: String = UserAccountData.TYPE_ALLOWED_WIDGETS,
data class AllowedWidgets(override val type: String = UserAccountDataTypes.TYPE_ALLOWED_WIDGETS,
private val allowedWidgetsContent: AllowedWidgetsContent) : Params {
override fun getData(): Any {
@ -80,7 +80,7 @@ internal interface UpdateUserAccountDataTask : Task<UpdateUserAccountDataTask.Pa
}
}
data class IntegrationProvisioning(override val type: String = UserAccountData.TYPE_INTEGRATION_PROVISIONING,
data class IntegrationProvisioning(override val type: String = UserAccountDataTypes.TYPE_INTEGRATION_PROVISIONING,
private val integrationProvisioningContent: IntegrationProvisioningContent) : Params {
override fun getData(): Any {

View file

@ -38,8 +38,8 @@ import im.vector.matrix.android.internal.session.SessionLifecycleObserver
import im.vector.matrix.android.internal.session.SessionScope
import im.vector.matrix.android.internal.session.integrationmanager.IntegrationManager
import im.vector.matrix.android.internal.session.room.state.StateEventDataSource
import im.vector.matrix.android.internal.session.sync.model.accountdata.UserAccountData
import im.vector.matrix.android.internal.session.sync.model.accountdata.UserAccountDataEvent
import im.vector.matrix.android.api.session.accountdata.UserAccountDataTypes
import im.vector.matrix.android.api.session.accountdata.UserAccountDataEvent
import im.vector.matrix.android.internal.session.user.accountdata.AccountDataDataSource
import im.vector.matrix.android.internal.session.widgets.helper.WidgetFactory
import im.vector.matrix.android.internal.session.widgets.helper.extractWidgetSequence
@ -136,7 +136,7 @@ internal class WidgetManager @Inject constructor(private val integrationManager:
widgetTypes: Set<String>? = null,
excludedTypes: Set<String>? = null
): LiveData<List<Widget>> {
val widgetsAccountData = accountDataDataSource.getLiveAccountDataEvent(UserAccountData.TYPE_WIDGETS)
val widgetsAccountData = accountDataDataSource.getLiveAccountDataEvent(UserAccountDataTypes.TYPE_WIDGETS)
return Transformations.map(widgetsAccountData) {
it.getOrNull()?.mapToWidgets(widgetTypes, excludedTypes) ?: emptyList()
}
@ -146,12 +146,12 @@ internal class WidgetManager @Inject constructor(private val integrationManager:
widgetTypes: Set<String>? = null,
excludedTypes: Set<String>? = null
): List<Widget> {
val widgetsAccountData = accountDataDataSource.getAccountDataEvent(UserAccountData.TYPE_WIDGETS) ?: return emptyList()
val widgetsAccountData = accountDataDataSource.getAccountDataEvent(UserAccountDataTypes.TYPE_WIDGETS) ?: return emptyList()
return widgetsAccountData.mapToWidgets(widgetTypes, excludedTypes)
}
private fun UserAccountDataEvent.mapToWidgets(widgetTypes: Set<String>? = null,
excludedTypes: Set<String>? = null): List<Widget> {
excludedTypes: Set<String>? = null): List<Widget> {
return extractWidgetSequence(widgetFactory)
.filter {
val widgetType = it.widgetContent.type ?: return@filter false

View file

@ -19,7 +19,7 @@ package im.vector.matrix.android.internal.session.widgets.helper
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.util.JsonDict
import im.vector.matrix.android.internal.session.sync.model.accountdata.UserAccountDataEvent
import im.vector.matrix.android.api.session.accountdata.UserAccountDataEvent
import im.vector.matrix.android.api.session.widgets.model.Widget
internal fun UserAccountDataEvent.extractWidgetSequence(widgetFactory: WidgetFactory): Sequence<Widget> {

View file

@ -21,7 +21,8 @@ import com.airbnb.epoxy.TypedEpoxyController
import com.airbnb.mvrx.Fail
import com.airbnb.mvrx.Loading
import com.airbnb.mvrx.Success
import im.vector.matrix.android.internal.session.sync.model.accountdata.UserAccountData
import im.vector.matrix.android.api.session.accountdata.UserAccountDataEvent
import im.vector.matrix.android.api.session.accountdata.UserAccountDataTypes
import im.vector.riotx.R
import im.vector.riotx.core.epoxy.loadingItem
import im.vector.riotx.core.resources.StringProvider
@ -35,7 +36,7 @@ class AccountDataEpoxyController @Inject constructor(
) : TypedEpoxyController<AccountDataViewState>() {
interface InteractionListener {
fun didTap(data: UserAccountData)
fun didTap(data: UserAccountDataEvent)
}
var interactionListener: InteractionListener? = null

View file

@ -21,8 +21,8 @@ import android.view.View
import com.airbnb.mvrx.fragmentViewModel
import com.airbnb.mvrx.withState
import im.vector.matrix.android.internal.di.MoshiProvider
import im.vector.matrix.android.internal.session.sync.model.accountdata.UserAccountData
import im.vector.matrix.android.internal.session.sync.model.accountdata.UserAccountDataEvent
import im.vector.matrix.android.api.session.accountdata.UserAccountDataTypes
import im.vector.matrix.android.api.session.accountdata.UserAccountDataEvent
import im.vector.riotx.R
import im.vector.riotx.core.extensions.cleanup
import im.vector.riotx.core.extensions.configureWith
@ -65,11 +65,10 @@ class AccountDataFragment @Inject constructor(
epoxyController.interactionListener = null
}
override fun didTap(data: UserAccountData) {
val fb = data as? UserAccountDataEvent ?: return
override fun didTap(data: UserAccountDataEvent) {
val jsonString = MoshiProvider.providesMoshi()
.adapter(UserAccountDataEvent::class.java)
.toJson(fb)
.toJson(data)
JSonViewerDialog.newInstance(
jsonString,
-1, // open All

View file

@ -25,14 +25,14 @@ import com.airbnb.mvrx.ViewModelContext
import com.squareup.inject.assisted.Assisted
import com.squareup.inject.assisted.AssistedInject
import im.vector.matrix.android.api.session.Session
import im.vector.matrix.android.internal.session.sync.model.accountdata.UserAccountData
import im.vector.matrix.android.api.session.accountdata.UserAccountDataEvent
import im.vector.matrix.rx.rx
import im.vector.riotx.core.platform.EmptyAction
import im.vector.riotx.core.platform.EmptyViewEvents
import im.vector.riotx.core.platform.VectorViewModel
data class AccountDataViewState(
val accountData: Async<List<UserAccountData>> = Uninitialized
val accountData: Async<List<UserAccountDataEvent>> = Uninitialized
) : MvRxState
class AccountDataViewModel @AssistedInject constructor(@Assisted initialState: AccountDataViewState,

View file

@ -31,7 +31,7 @@ import im.vector.matrix.android.api.session.room.model.PowerLevelsContent
import im.vector.matrix.android.api.session.room.powerlevels.PowerLevelsHelper
import im.vector.matrix.android.api.session.widgets.WidgetPostAPIMediator
import im.vector.matrix.android.api.util.JsonDict
import im.vector.matrix.android.internal.session.sync.model.accountdata.UserAccountData
import im.vector.matrix.android.api.session.accountdata.UserAccountDataTypes
import im.vector.riotx.R
import im.vector.riotx.core.resources.StringProvider
import timber.log.Timber
@ -280,7 +280,7 @@ class WidgetPostAPIHandler @AssistedInject constructor(@Assisted private val roo
)
)
session.updateAccountData(
type = UserAccountData.TYPE_WIDGETS,
type = UserAccountDataTypes.TYPE_WIDGETS,
content = addUserWidgetBody,
callback = createWidgetAPICallback(widgetPostAPIMediator, eventData)
)

View file

@ -28,6 +28,7 @@ import com.squareup.inject.assisted.Assisted
import com.squareup.inject.assisted.AssistedInject
import im.vector.matrix.android.api.extensions.orFalse
import im.vector.matrix.android.api.session.Session
import im.vector.matrix.android.api.session.accountdata.UserAccountDataEvent
import im.vector.matrix.android.api.session.crypto.crosssigning.MASTER_KEY_SSSS_NAME
import im.vector.matrix.android.api.session.crypto.crosssigning.MXCrossSigningInfo
import im.vector.matrix.android.api.session.crypto.crosssigning.SELF_SIGNING_KEY_SSSS_NAME
@ -36,7 +37,6 @@ import im.vector.matrix.android.api.session.crypto.keysbackup.KeysBackupState
import im.vector.matrix.android.api.session.crypto.keysbackup.KeysBackupStateListener
import im.vector.matrix.android.api.util.Optional
import im.vector.matrix.android.internal.crypto.store.PrivateKeysInfo
import im.vector.matrix.android.internal.session.sync.model.accountdata.UserAccountData
import im.vector.matrix.rx.rx
import im.vector.riotx.core.platform.EmptyAction
import im.vector.riotx.core.platform.EmptyViewEvents
@ -97,7 +97,7 @@ class ServerBackupStatusViewModel @AssistedInject constructor(@Assisted initialS
keysBackupState.value = session.cryptoService().keysBackupService().state
Observable.combineLatest<List<UserAccountData>, Optional<MXCrossSigningInfo>, KeysBackupState, Optional<PrivateKeysInfo>, BannerState>(
Observable.combineLatest<List<UserAccountDataEvent>, Optional<MXCrossSigningInfo>, KeysBackupState, Optional<PrivateKeysInfo>, BannerState>(
session.rx().liveAccountData(setOf(MASTER_KEY_SSSS_NAME, USER_SIGNING_KEY_SSSS_NAME, SELF_SIGNING_KEY_SSSS_NAME)),
session.rx().liveCrossSigningInfo(session.myUserId),
keyBackupPublishSubject,