Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Enforce query on state event #6319

Merged
merged 3 commits into from
Jun 16, 2022
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ package org.matrix.android.sdk.flow

import androidx.lifecycle.asFlow
import kotlinx.coroutines.flow.Flow
import org.matrix.android.sdk.api.query.QueryStringValue
import org.matrix.android.sdk.api.query.QueryStateEventValue
import org.matrix.android.sdk.api.session.events.model.Event
import org.matrix.android.sdk.api.session.room.Room
import org.matrix.android.sdk.api.session.room.getStateEvent
Expand Down Expand Up @@ -67,17 +67,17 @@ class FlowRoom(private val room: Room) {
}
}

fun liveStateEvent(eventType: String, stateKey: QueryStringValue): Flow<Optional<Event>> {
fun liveStateEvent(eventType: String, stateKey: QueryStateEventValue): Flow<Optional<Event>> {
return room.stateService().getStateEventLive(eventType, stateKey).asFlow()
.startWith(room.coroutineDispatchers.io) {
room.getStateEvent(eventType, stateKey).toOptional()
}
}

fun liveStateEvents(eventTypes: Set<String>): Flow<List<Event>> {
return room.stateService().getStateEventsLive(eventTypes).asFlow()
fun liveStateEvents(eventTypes: Set<String>, stateKey: QueryStateEventValue): Flow<List<Event>> {
return room.stateService().getStateEventsLive(eventTypes, stateKey).asFlow()
.startWith(room.coroutineDispatchers.io) {
room.stateService().getStateEvents(eventTypes)
room.stateService().getStateEvents(eventTypes, stateKey)
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ package org.matrix.android.sdk.flow
import androidx.lifecycle.asFlow
import androidx.paging.PagedList
import kotlinx.coroutines.flow.Flow
import org.matrix.android.sdk.api.query.QueryStringValue
import org.matrix.android.sdk.api.query.QueryStateEventValue
import org.matrix.android.sdk.api.session.Session
import org.matrix.android.sdk.api.session.accountdata.UserAccountDataEvent
import org.matrix.android.sdk.api.session.crypto.crosssigning.MXCrossSigningInfo
Expand Down Expand Up @@ -179,7 +179,7 @@ class FlowSession(private val session: Session) {

fun liveRoomWidgets(
roomId: String,
widgetId: QueryStringValue,
widgetId: QueryStateEventValue,
widgetTypes: Set<String>? = null,
excludedTypes: Set<String>? = null
): Flow<List<Widget>> {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,11 @@

package org.matrix.android.sdk.api.query

/**
* Only a subset of [QueryStringValue] are applicable to query the `stateKey` of a state event.
*/
sealed interface QueryStateEventValue

/**
* Basic query language. All these cases are mutually exclusive.
*/
Expand All @@ -33,22 +38,22 @@ sealed interface QueryStringValue {
/**
* The tested field has to be not null.
*/
object IsNotNull : QueryStringValue
object IsNotNull : QueryStringValue, QueryStateEventValue

/**
* The tested field has to be empty.
*/
object IsEmpty : QueryStringValue
object IsEmpty : QueryStringValue, QueryStateEventValue

/**
* The tested field has to not empty.
* The tested field has to be not empty.
*/
object IsNotEmpty : QueryStringValue
object IsNotEmpty : QueryStringValue, QueryStateEventValue

/**
* Interface to check String content.
*/
sealed interface ContentQueryStringValue : QueryStringValue {
sealed interface ContentQueryStringValue : QueryStringValue, QueryStateEventValue {
val string: String
val case: Case
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,18 +16,21 @@

package org.matrix.android.sdk.api.session.room

import org.matrix.android.sdk.api.query.QueryStringValue
import org.matrix.android.sdk.api.query.QueryStateEventValue
import org.matrix.android.sdk.api.session.events.model.Event
import org.matrix.android.sdk.api.session.room.timeline.TimelineEvent

/**
* Get a TimelineEvent using the TimelineService of a Room.
* @param eventId The id of the event to retrieve
*/
fun Room.getTimelineEvent(eventId: String): TimelineEvent? =
timelineService().getTimelineEvent(eventId)

/**
* Get a StateEvent using the StateService of a Room.
* @param eventType The type of the event, see [org.matrix.android.sdk.api.session.events.model.EventType].
* @param stateKey the query which will be done on the stateKey.
*/
fun Room.getStateEvent(eventType: String, stateKey: QueryStringValue = QueryStringValue.NoCondition): Event? =
fun Room.getStateEvent(eventType: String, stateKey: QueryStateEventValue): Event? =
stateService().getStateEvent(eventType, stateKey)
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ package org.matrix.android.sdk.api.session.room.state

import android.net.Uri
import androidx.lifecycle.LiveData
import org.matrix.android.sdk.api.query.QueryStringValue
import org.matrix.android.sdk.api.query.QueryStateEventValue
import org.matrix.android.sdk.api.session.events.model.Event
import org.matrix.android.sdk.api.session.room.model.GuestAccess
import org.matrix.android.sdk.api.session.room.model.RoomHistoryVisibility
Expand Down Expand Up @@ -93,28 +93,28 @@ interface StateService {
* @param eventType An eventType.
* @param stateKey the query which will be done on the stateKey
*/
fun getStateEvent(eventType: String, stateKey: QueryStringValue = QueryStringValue.NoCondition): Event?
fun getStateEvent(eventType: String, stateKey: QueryStateEventValue): Event?

/**
* Get a live state event of the room.
* @param eventType An eventType.
* @param stateKey the query which will be done on the stateKey
*/
fun getStateEventLive(eventType: String, stateKey: QueryStringValue = QueryStringValue.NoCondition): LiveData<Optional<Event>>
fun getStateEventLive(eventType: String, stateKey: QueryStateEventValue): LiveData<Optional<Event>>

/**
* Get state events of the room.
* @param eventTypes Set of eventType. If empty, all state events will be returned
* @param stateKey the query which will be done on the stateKey
*/
fun getStateEvents(eventTypes: Set<String>, stateKey: QueryStringValue = QueryStringValue.NoCondition): List<Event>
fun getStateEvents(eventTypes: Set<String>, stateKey: QueryStateEventValue): List<Event>

/**
* Get live state events of the room.
* @param eventTypes Set of eventType to observe. If empty, all state events will be observed
* @param stateKey the query which will be done on the stateKey
*/
fun getStateEventsLive(eventTypes: Set<String>, stateKey: QueryStringValue = QueryStringValue.NoCondition): LiveData<List<Event>>
fun getStateEventsLive(eventTypes: Set<String>, stateKey: QueryStateEventValue): LiveData<List<Event>>

suspend fun setJoinRulePublic()
suspend fun setJoinRuleInviteOnly()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ import org.matrix.android.sdk.api.session.room.model.RoomJoinRulesContent
* Return true if a room can be joined by anyone (RoomJoinRules.PUBLIC).
*/
fun StateService.isPublic(): Boolean {
return getStateEvent(EventType.STATE_ROOM_JOIN_RULES, QueryStringValue.NoCondition)
return getStateEvent(EventType.STATE_ROOM_JOIN_RULES, QueryStringValue.IsEmpty)
?.content
?.toModel<RoomJoinRulesContent>()
?.joinRules == RoomJoinRules.PUBLIC
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
package org.matrix.android.sdk.api.session.widgets

import androidx.lifecycle.LiveData
import org.matrix.android.sdk.api.query.QueryStringValue
import org.matrix.android.sdk.api.query.QueryStateEventValue
import org.matrix.android.sdk.api.session.events.model.Content
import org.matrix.android.sdk.api.session.widgets.model.Widget

Expand Down Expand Up @@ -49,7 +49,7 @@ interface WidgetService {
*/
fun getRoomWidgets(
roomId: String,
widgetId: QueryStringValue = QueryStringValue.NoCondition,
widgetId: QueryStateEventValue,
widgetTypes: Set<String>? = null,
excludedTypes: Set<String>? = null
): List<Widget>
Expand All @@ -70,7 +70,7 @@ interface WidgetService {
*/
fun getRoomWidgetsLive(
roomId: String,
widgetId: QueryStringValue = QueryStringValue.NoCondition,
widgetId: QueryStateEventValue,
widgetTypes: Set<String>? = null,
excludedTypes: Set<String>? = null
): LiveData<List<Widget>>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ internal class ViaParameterFinder @Inject constructor(
}

fun userCanInvite(userId: String, roomId: String): Boolean {
val powerLevelsHelper = stateEventDataSource.getStateEvent(roomId, EventType.STATE_ROOM_POWER_LEVELS, QueryStringValue.NoCondition)
val powerLevelsHelper = stateEventDataSource.getStateEvent(roomId, EventType.STATE_ROOM_POWER_LEVELS, QueryStringValue.IsEmpty)
?.content?.toModel<PowerLevelsContent>()
?.let { PowerLevelsHelper(it) }

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
*/
package org.matrix.android.sdk.internal.session.pushers

import org.matrix.android.sdk.api.query.QueryStringValue
import org.matrix.android.sdk.api.session.events.model.Event
import org.matrix.android.sdk.api.session.events.model.EventType
import org.matrix.android.sdk.api.session.events.model.toModel
Expand Down Expand Up @@ -55,7 +56,7 @@ internal class DefaultConditionResolver @Inject constructor(
val roomId = event.roomId ?: return false
val room = roomGetter.getRoom(roomId) ?: return false

val powerLevelsContent = room.getStateEvent(EventType.STATE_ROOM_POWER_LEVELS)
val powerLevelsContent = room.getStateEvent(EventType.STATE_ROOM_POWER_LEVELS, QueryStringValue.IsEmpty)
?.content
?.toModel<PowerLevelsContent>()
?: PowerLevelsContent()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -386,7 +386,7 @@ internal class EventRelationsAggregationProcessor @Inject constructor(
}

private fun getPowerLevelsHelper(roomId: String): PowerLevelsHelper? {
return stateEventDataSource.getStateEvent(roomId, EventType.STATE_ROOM_POWER_LEVELS, QueryStringValue.NoCondition)
return stateEventDataSource.getStateEvent(roomId, EventType.STATE_ROOM_POWER_LEVELS, QueryStringValue.IsEmpty)
?.content?.toModel<PowerLevelsContent>()
?.let { PowerLevelsHelper(it) }
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ internal class DefaultLeaveRoomTask @Inject constructor(
val roomCreateStateEvent = stateEventDataSource.getStateEvent(
roomId = roomId,
eventType = EventType.STATE_ROOM_CREATE,
stateKey = QueryStringValue.NoCondition
stateKey = QueryStringValue.IsEmpty,
)
// Server is not cleaning predecessor rooms, so we also try to left them
val predecessorRoomId = roomCreateStateEvent?.getClearContent()?.toModel<RoomCreateContent>()?.predecessor?.roomId
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import dagger.assisted.Assisted
import dagger.assisted.AssistedFactory
import dagger.assisted.AssistedInject
import org.matrix.android.sdk.api.extensions.orFalse
import org.matrix.android.sdk.api.query.QueryStateEventValue
import org.matrix.android.sdk.api.query.QueryStringValue
import org.matrix.android.sdk.api.session.events.model.Event
import org.matrix.android.sdk.api.session.events.model.EventType
Expand Down Expand Up @@ -54,19 +55,19 @@ internal class DefaultStateService @AssistedInject constructor(
fun create(roomId: String): DefaultStateService
}

override fun getStateEvent(eventType: String, stateKey: QueryStringValue): Event? {
override fun getStateEvent(eventType: String, stateKey: QueryStateEventValue): Event? {
return stateEventDataSource.getStateEvent(roomId, eventType, stateKey)
}

override fun getStateEventLive(eventType: String, stateKey: QueryStringValue): LiveData<Optional<Event>> {
override fun getStateEventLive(eventType: String, stateKey: QueryStateEventValue): LiveData<Optional<Event>> {
return stateEventDataSource.getStateEventLive(roomId, eventType, stateKey)
}

override fun getStateEvents(eventTypes: Set<String>, stateKey: QueryStringValue): List<Event> {
override fun getStateEvents(eventTypes: Set<String>, stateKey: QueryStateEventValue): List<Event> {
return stateEventDataSource.getStateEvents(roomId, eventTypes, stateKey)
}

override fun getStateEventsLive(eventTypes: Set<String>, stateKey: QueryStringValue): LiveData<List<Event>> {
override fun getStateEventsLive(eventTypes: Set<String>, stateKey: QueryStateEventValue): LiveData<List<Event>> {
return stateEventDataSource.getStateEventsLive(roomId, eventTypes, stateKey)
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import com.zhuinden.monarchy.Monarchy
import io.realm.Realm
import io.realm.RealmQuery
import io.realm.kotlin.where
import org.matrix.android.sdk.api.query.QueryStateEventValue
import org.matrix.android.sdk.api.query.QueryStringValue
import org.matrix.android.sdk.api.session.events.model.Event
import org.matrix.android.sdk.api.util.Optional
Expand All @@ -40,13 +41,13 @@ internal class StateEventDataSource @Inject constructor(
private val queryStringValueProcessor: QueryStringValueProcessor
) {

fun getStateEvent(roomId: String, eventType: String, stateKey: QueryStringValue): Event? {
fun getStateEvent(roomId: String, eventType: String, stateKey: QueryStateEventValue): Event? {
return realmSessionProvider.withRealm { realm ->
buildStateEventQuery(realm, roomId, setOf(eventType), stateKey).findFirst()?.root?.asDomain()
}
}

fun getStateEventLive(roomId: String, eventType: String, stateKey: QueryStringValue): LiveData<Optional<Event>> {
fun getStateEventLive(roomId: String, eventType: String, stateKey: QueryStateEventValue): LiveData<Optional<Event>> {
val liveData = monarchy.findAllMappedWithChanges(
{ realm -> buildStateEventQuery(realm, roomId, setOf(eventType), stateKey) },
{ it.root?.asDomain() }
Expand All @@ -56,7 +57,7 @@ internal class StateEventDataSource @Inject constructor(
}
}

fun getStateEvents(roomId: String, eventTypes: Set<String>, stateKey: QueryStringValue): List<Event> {
fun getStateEvents(roomId: String, eventTypes: Set<String>, stateKey: QueryStateEventValue): List<Event> {
return realmSessionProvider.withRealm { realm ->
buildStateEventQuery(realm, roomId, eventTypes, stateKey)
.findAll()
Expand All @@ -66,7 +67,7 @@ internal class StateEventDataSource @Inject constructor(
}
}

fun getStateEventsLive(roomId: String, eventTypes: Set<String>, stateKey: QueryStringValue): LiveData<List<Event>> {
fun getStateEventsLive(roomId: String, eventTypes: Set<String>, stateKey: QueryStateEventValue): LiveData<List<Event>> {
val liveData = monarchy.findAllMappedWithChanges(
{ realm -> buildStateEventQuery(realm, roomId, eventTypes, stateKey) },
{ it.root?.asDomain() }
Expand All @@ -80,7 +81,7 @@ internal class StateEventDataSource @Inject constructor(
realm: Realm,
roomId: String,
eventTypes: Set<String>,
stateKey: QueryStringValue
stateKey: QueryStateEventValue
): RealmQuery<CurrentStateEventEntity> {
return with(queryStringValueProcessor) {
realm.where<CurrentStateEventEntity>()
Expand All @@ -90,7 +91,8 @@ internal class StateEventDataSource @Inject constructor(
`in`(CurrentStateEventEntityFields.TYPE, eventTypes.toTypedArray())
}
}
.process(CurrentStateEventEntityFields.STATE_KEY, stateKey)
// It's OK to cast stateKey as QueryStringValue
.process(CurrentStateEventEntityFields.STATE_KEY, stateKey as QueryStringValue)
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ internal class LiveRoomStateListener(
stateEventDataSource.getStateEventsLive(
roomId = roomId,
eventTypes = setOf(EventType.STATE_ROOM_MEMBER),
stateKey = QueryStringValue.NoCondition,
stateKey = QueryStringValue.IsNotNull,
)
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ internal class DefaultRoomVersionService @AssistedInject constructor(
}

override fun userMayUpgradeRoom(userId: String): Boolean {
val powerLevelsHelper = stateEventDataSource.getStateEvent(roomId, EventType.STATE_ROOM_POWER_LEVELS, QueryStringValue.NoCondition)
val powerLevelsHelper = stateEventDataSource.getStateEvent(roomId, EventType.STATE_ROOM_POWER_LEVELS, QueryStringValue.IsEmpty)
?.content?.toModel<PowerLevelsContent>()
?.let { PowerLevelsHelper(it) }

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -252,7 +252,7 @@ internal class DefaultSpaceService @Inject constructor(
val powerLevelsEvent = stateEventDataSource.getStateEvent(
roomId = parentSpaceId,
eventType = EventType.STATE_ROOM_POWER_LEVELS,
stateKey = QueryStringValue.NoCondition
stateKey = QueryStringValue.IsEmpty
)
val powerLevelsContent = powerLevelsEvent?.content?.toModel<PowerLevelsContent>()
?: throw UnsupportedOperationException("Cannot add canonical child, missing powerlevel")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
package org.matrix.android.sdk.internal.session.widgets

import androidx.lifecycle.LiveData
import org.matrix.android.sdk.api.query.QueryStringValue
import org.matrix.android.sdk.api.query.QueryStateEventValue
import org.matrix.android.sdk.api.session.events.model.Content
import org.matrix.android.sdk.api.session.widgets.WidgetPostAPIMediator
import org.matrix.android.sdk.api.session.widgets.WidgetService
Expand All @@ -43,7 +43,7 @@ internal class DefaultWidgetService @Inject constructor(

override fun getRoomWidgets(
roomId: String,
widgetId: QueryStringValue,
widgetId: QueryStateEventValue,
widgetTypes: Set<String>?,
excludedTypes: Set<String>?
): List<Widget> {
Expand All @@ -56,7 +56,7 @@ internal class DefaultWidgetService @Inject constructor(

override fun getRoomWidgetsLive(
roomId: String,
widgetId: QueryStringValue,
widgetId: QueryStateEventValue,
widgetTypes: Set<String>?,
excludedTypes: Set<String>?
): LiveData<List<Widget>> {
Expand Down
Loading