Creation of LocationSharingService to get current users sharing their live locations

This commit is contained in:
Maxime NATUREL 2022-05-16 17:44:54 +02:00
parent 5410b61ae3
commit 7a7af40d61
12 changed files with 154 additions and 5 deletions

View File

@ -22,6 +22,7 @@ import org.matrix.android.sdk.api.session.room.accountdata.RoomAccountDataServic
import org.matrix.android.sdk.api.session.room.alias.AliasService import org.matrix.android.sdk.api.session.room.alias.AliasService
import org.matrix.android.sdk.api.session.room.call.RoomCallService import org.matrix.android.sdk.api.session.room.call.RoomCallService
import org.matrix.android.sdk.api.session.room.crypto.RoomCryptoService import org.matrix.android.sdk.api.session.room.crypto.RoomCryptoService
import org.matrix.android.sdk.api.session.room.location.LocationSharingService
import org.matrix.android.sdk.api.session.room.members.MembershipService import org.matrix.android.sdk.api.session.room.members.MembershipService
import org.matrix.android.sdk.api.session.room.model.RoomSummary import org.matrix.android.sdk.api.session.room.model.RoomSummary
import org.matrix.android.sdk.api.session.room.model.relation.RelationService import org.matrix.android.sdk.api.session.room.model.relation.RelationService
@ -163,4 +164,9 @@ interface Room {
* Get the RoomVersionService associated to this Room. * Get the RoomVersionService associated to this Room.
*/ */
fun roomVersionService(): RoomVersionService fun roomVersionService(): RoomVersionService
/**
* Get the LocationSharingService associated to this Room
*/
fun locationSharingService(): LocationSharingService
} }

View File

@ -0,0 +1,48 @@
/*
* Copyright (c) 2022 The Matrix.org Foundation C.I.C.
*
* 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 org.matrix.android.sdk.api.session.room.location
import androidx.lifecycle.LiveData
import com.zhuinden.monarchy.Monarchy
import dagger.assisted.Assisted
import dagger.assisted.AssistedFactory
import dagger.assisted.AssistedInject
import org.matrix.android.sdk.api.session.room.model.livelocation.LiveLocationShareAggregatedSummary
import org.matrix.android.sdk.internal.database.mapper.LiveLocationShareAggregatedSummaryMapper
import org.matrix.android.sdk.internal.database.model.livelocation.LiveLocationShareAggregatedSummaryEntity
import org.matrix.android.sdk.internal.database.query.findRunningLiveLocationShareInRoom
import org.matrix.android.sdk.internal.di.SessionDatabase
// TODO add unit tests
internal class DefaultLocationSharingService @AssistedInject constructor(
@Assisted private val roomId: String,
@SessionDatabase private val monarchy: Monarchy,
private val liveLocationShareAggregatedSummaryMapper: LiveLocationShareAggregatedSummaryMapper,
) : LocationSharingService {
@AssistedFactory
interface Factory {
fun create(roomId: String): DefaultLocationSharingService
}
override fun getRunningLiveLocationShareSummaries(): LiveData<List<LiveLocationShareAggregatedSummary>> {
return monarchy.findAllMappedWithChanges(
{ LiveLocationShareAggregatedSummaryEntity.findRunningLiveLocationShareInRoom(it, roomId = roomId) },
{ liveLocationShareAggregatedSummaryMapper.map(it) }
)
}
}

View File

@ -0,0 +1,27 @@
/*
* Copyright (c) 2022 The Matrix.org Foundation C.I.C.
*
* 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 org.matrix.android.sdk.api.session.room.location
import androidx.lifecycle.LiveData
import org.matrix.android.sdk.api.session.room.model.livelocation.LiveLocationShareAggregatedSummary
/**
* Manage all location sharing related features.
*/
interface LocationSharingService {
fun getRunningLiveLocationShareSummaries(): LiveData<List<LiveLocationShareAggregatedSummary>>
}

View File

@ -22,6 +22,7 @@ import org.matrix.android.sdk.api.session.room.model.message.MessageBeaconLocati
* Aggregation info concerning a live location share. * Aggregation info concerning a live location share.
*/ */
data class LiveLocationShareAggregatedSummary( data class LiveLocationShareAggregatedSummary(
val userId: String?,
/** /**
* Indicate whether the live is currently running. * Indicate whether the live is currently running.
*/ */

View File

@ -46,6 +46,7 @@ import org.matrix.android.sdk.internal.database.migration.MigrateSessionTo025
import org.matrix.android.sdk.internal.database.migration.MigrateSessionTo026 import org.matrix.android.sdk.internal.database.migration.MigrateSessionTo026
import org.matrix.android.sdk.internal.database.migration.MigrateSessionTo027 import org.matrix.android.sdk.internal.database.migration.MigrateSessionTo027
import org.matrix.android.sdk.internal.database.migration.MigrateSessionTo028 import org.matrix.android.sdk.internal.database.migration.MigrateSessionTo028
import org.matrix.android.sdk.internal.database.migration.MigrateSessionTo029
import org.matrix.android.sdk.internal.util.Normalizer import org.matrix.android.sdk.internal.util.Normalizer
import timber.log.Timber import timber.log.Timber
import javax.inject.Inject import javax.inject.Inject
@ -60,7 +61,7 @@ internal class RealmSessionStoreMigration @Inject constructor(
override fun equals(other: Any?) = other is RealmSessionStoreMigration override fun equals(other: Any?) = other is RealmSessionStoreMigration
override fun hashCode() = 1000 override fun hashCode() = 1000
val schemaVersion = 28L val schemaVersion = 29L
override fun migrate(realm: DynamicRealm, oldVersion: Long, newVersion: Long) { override fun migrate(realm: DynamicRealm, oldVersion: Long, newVersion: Long) {
Timber.d("Migrating Realm Session from $oldVersion to $newVersion") Timber.d("Migrating Realm Session from $oldVersion to $newVersion")
@ -93,5 +94,6 @@ internal class RealmSessionStoreMigration @Inject constructor(
if (oldVersion < 26) MigrateSessionTo026(realm).perform() if (oldVersion < 26) MigrateSessionTo026(realm).perform()
if (oldVersion < 27) MigrateSessionTo027(realm).perform() if (oldVersion < 27) MigrateSessionTo027(realm).perform()
if (oldVersion < 28) MigrateSessionTo028(realm).perform() if (oldVersion < 28) MigrateSessionTo028(realm).perform()
if (oldVersion < 29) MigrateSessionTo029(realm).perform()
} }
} }

View File

@ -58,7 +58,7 @@ internal object EventAnnotationsSummaryMapper {
PollResponseAggregatedSummaryEntityMapper.map(it) PollResponseAggregatedSummaryEntityMapper.map(it)
}, },
liveLocationShareAggregatedSummary = annotationsSummary.liveLocationShareAggregatedSummary?.let { liveLocationShareAggregatedSummary = annotationsSummary.liveLocationShareAggregatedSummary?.let {
LiveLocationShareAggregatedSummaryMapper.map(it) LiveLocationShareAggregatedSummaryMapper().map(it)
} }
) )
} }

View File

@ -20,11 +20,14 @@ import org.matrix.android.sdk.api.session.events.model.toModel
import org.matrix.android.sdk.api.session.room.model.livelocation.LiveLocationShareAggregatedSummary import org.matrix.android.sdk.api.session.room.model.livelocation.LiveLocationShareAggregatedSummary
import org.matrix.android.sdk.api.session.room.model.message.MessageBeaconLocationDataContent import org.matrix.android.sdk.api.session.room.model.message.MessageBeaconLocationDataContent
import org.matrix.android.sdk.internal.database.model.livelocation.LiveLocationShareAggregatedSummaryEntity import org.matrix.android.sdk.internal.database.model.livelocation.LiveLocationShareAggregatedSummaryEntity
import javax.inject.Inject
internal object LiveLocationShareAggregatedSummaryMapper { // TODO add unit tests
internal class LiveLocationShareAggregatedSummaryMapper @Inject constructor() {
fun map(entity: LiveLocationShareAggregatedSummaryEntity): LiveLocationShareAggregatedSummary { fun map(entity: LiveLocationShareAggregatedSummaryEntity): LiveLocationShareAggregatedSummary {
return LiveLocationShareAggregatedSummary( return LiveLocationShareAggregatedSummary(
userId = entity.userId,
isActive = entity.isActive, isActive = entity.isActive,
endOfLiveTimestampMillis = entity.endOfLiveTimestampMillis, endOfLiveTimestampMillis = entity.endOfLiveTimestampMillis,
lastLocationDataContent = ContentMapper.map(entity.lastLocationContent).toModel<MessageBeaconLocationDataContent>() lastLocationDataContent = ContentMapper.map(entity.lastLocationContent).toModel<MessageBeaconLocationDataContent>()

View File

@ -0,0 +1,38 @@
/*
* Copyright (c) 2022 The Matrix.org Foundation C.I.C.
*
* 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 org.matrix.android.sdk.internal.database.migration
import io.realm.DynamicRealm
import io.realm.FieldAttribute
import org.matrix.android.sdk.internal.database.model.RoomSummaryEntityFields
import org.matrix.android.sdk.internal.database.model.livelocation.LiveLocationShareAggregatedSummaryEntityFields
import org.matrix.android.sdk.internal.util.database.RealmMigrator
/**
* Migrating to:
* Live location sharing aggregated summary: adding new field userId
*/
internal class MigrateSessionTo029(realm: DynamicRealm) : RealmMigrator(realm, 28) {
override fun doMigrate(realm: DynamicRealm) {
realm.schema.get("LiveLocationShareAggregatedSummaryEntity")
?.addField(LiveLocationShareAggregatedSummaryEntityFields.USER_ID, String::class.java, FieldAttribute.REQUIRED)
?.transform { obj ->
obj.setString(LiveLocationShareAggregatedSummaryEntityFields.USER_ID, "")
}
}
}

View File

@ -31,6 +31,8 @@ internal open class LiveLocationShareAggregatedSummaryEntity(
var roomId: String = "", var roomId: String = "",
var userId: String = "",
/** /**
* Indicate whether the live is currently running. * Indicate whether the live is currently running.
*/ */

View File

@ -20,6 +20,7 @@ import io.realm.Realm
import io.realm.RealmQuery import io.realm.RealmQuery
import io.realm.kotlin.where import io.realm.kotlin.where
import org.matrix.android.sdk.internal.database.model.EventAnnotationsSummaryEntity import org.matrix.android.sdk.internal.database.model.EventAnnotationsSummaryEntity
import org.matrix.android.sdk.internal.database.model.TimelineEventEntityFields
import org.matrix.android.sdk.internal.database.model.livelocation.LiveLocationShareAggregatedSummaryEntity import org.matrix.android.sdk.internal.database.model.livelocation.LiveLocationShareAggregatedSummaryEntity
import org.matrix.android.sdk.internal.database.model.livelocation.LiveLocationShareAggregatedSummaryEntityFields import org.matrix.android.sdk.internal.database.model.livelocation.LiveLocationShareAggregatedSummaryEntityFields
@ -28,11 +29,17 @@ internal fun LiveLocationShareAggregatedSummaryEntity.Companion.where(
roomId: String, roomId: String,
eventId: String, eventId: String,
): RealmQuery<LiveLocationShareAggregatedSummaryEntity> { ): RealmQuery<LiveLocationShareAggregatedSummaryEntity> {
return realm.where<LiveLocationShareAggregatedSummaryEntity>() return LiveLocationShareAggregatedSummaryEntity
.equalTo(LiveLocationShareAggregatedSummaryEntityFields.ROOM_ID, roomId) .whereRoomId(realm, roomId = roomId)
.equalTo(LiveLocationShareAggregatedSummaryEntityFields.EVENT_ID, eventId) .equalTo(LiveLocationShareAggregatedSummaryEntityFields.EVENT_ID, eventId)
} }
internal fun LiveLocationShareAggregatedSummaryEntity.Companion.whereRoomId(realm: Realm,
roomId: String): RealmQuery<LiveLocationShareAggregatedSummaryEntity> {
return realm.where<LiveLocationShareAggregatedSummaryEntity>()
.equalTo(TimelineEventEntityFields.ROOM_ID, roomId)
}
internal fun LiveLocationShareAggregatedSummaryEntity.Companion.create( internal fun LiveLocationShareAggregatedSummaryEntity.Companion.create(
realm: Realm, realm: Realm,
roomId: String, roomId: String,
@ -63,3 +70,12 @@ internal fun LiveLocationShareAggregatedSummaryEntity.Companion.get(
): LiveLocationShareAggregatedSummaryEntity? { ): LiveLocationShareAggregatedSummaryEntity? {
return LiveLocationShareAggregatedSummaryEntity.where(realm, roomId, eventId).findFirst() return LiveLocationShareAggregatedSummaryEntity.where(realm, roomId, eventId).findFirst()
} }
internal fun LiveLocationShareAggregatedSummaryEntity.Companion.findRunningLiveLocationShareInRoom(
realm: Realm,
roomId: String,
): RealmQuery<LiveLocationShareAggregatedSummaryEntity> {
return LiveLocationShareAggregatedSummaryEntity
.whereRoomId(realm, roomId = roomId)
.equalTo(LiveLocationShareAggregatedSummaryEntityFields.IS_ACTIVE, true)
}

View File

@ -23,6 +23,7 @@ import org.matrix.android.sdk.api.session.room.accountdata.RoomAccountDataServic
import org.matrix.android.sdk.api.session.room.alias.AliasService import org.matrix.android.sdk.api.session.room.alias.AliasService
import org.matrix.android.sdk.api.session.room.call.RoomCallService import org.matrix.android.sdk.api.session.room.call.RoomCallService
import org.matrix.android.sdk.api.session.room.crypto.RoomCryptoService import org.matrix.android.sdk.api.session.room.crypto.RoomCryptoService
import org.matrix.android.sdk.api.session.room.location.LocationSharingService
import org.matrix.android.sdk.api.session.room.members.MembershipService import org.matrix.android.sdk.api.session.room.members.MembershipService
import org.matrix.android.sdk.api.session.room.model.RoomSummary import org.matrix.android.sdk.api.session.room.model.RoomSummary
import org.matrix.android.sdk.api.session.room.model.RoomType import org.matrix.android.sdk.api.session.room.model.RoomType
@ -69,6 +70,7 @@ internal class DefaultRoom(
private val roomAccountDataService: RoomAccountDataService, private val roomAccountDataService: RoomAccountDataService,
private val roomVersionService: RoomVersionService, private val roomVersionService: RoomVersionService,
private val viaParameterFinder: ViaParameterFinder, private val viaParameterFinder: ViaParameterFinder,
private val locationSharingService: LocationSharingService,
override val coroutineDispatchers: MatrixCoroutineDispatchers override val coroutineDispatchers: MatrixCoroutineDispatchers
) : Room { ) : Room {
@ -104,4 +106,5 @@ internal class DefaultRoom(
override fun roomPushRuleService() = roomPushRuleService override fun roomPushRuleService() = roomPushRuleService
override fun roomAccountDataService() = roomAccountDataService override fun roomAccountDataService() = roomAccountDataService
override fun roomVersionService() = roomVersionService override fun roomVersionService() = roomVersionService
override fun locationSharingService() = locationSharingService
} }

View File

@ -18,6 +18,7 @@ package org.matrix.android.sdk.internal.session.room
import org.matrix.android.sdk.api.MatrixCoroutineDispatchers import org.matrix.android.sdk.api.MatrixCoroutineDispatchers
import org.matrix.android.sdk.api.session.room.Room import org.matrix.android.sdk.api.session.room.Room
import org.matrix.android.sdk.api.session.room.location.DefaultLocationSharingService
import org.matrix.android.sdk.internal.session.SessionScope import org.matrix.android.sdk.internal.session.SessionScope
import org.matrix.android.sdk.internal.session.permalinks.ViaParameterFinder import org.matrix.android.sdk.internal.session.permalinks.ViaParameterFinder
import org.matrix.android.sdk.internal.session.room.accountdata.DefaultRoomAccountDataService import org.matrix.android.sdk.internal.session.room.accountdata.DefaultRoomAccountDataService
@ -69,6 +70,7 @@ internal class DefaultRoomFactory @Inject constructor(
private val roomVersionServiceFactory: DefaultRoomVersionService.Factory, private val roomVersionServiceFactory: DefaultRoomVersionService.Factory,
private val roomAccountDataServiceFactory: DefaultRoomAccountDataService.Factory, private val roomAccountDataServiceFactory: DefaultRoomAccountDataService.Factory,
private val viaParameterFinder: ViaParameterFinder, private val viaParameterFinder: ViaParameterFinder,
private val locationSharingServiceFactory: DefaultLocationSharingService.Factory,
private val coroutineDispatchers: MatrixCoroutineDispatchers private val coroutineDispatchers: MatrixCoroutineDispatchers
) : RoomFactory { ) : RoomFactory {
@ -96,6 +98,7 @@ internal class DefaultRoomFactory @Inject constructor(
roomAccountDataService = roomAccountDataServiceFactory.create(roomId), roomAccountDataService = roomAccountDataServiceFactory.create(roomId),
roomVersionService = roomVersionServiceFactory.create(roomId), roomVersionService = roomVersionServiceFactory.create(roomId),
viaParameterFinder = viaParameterFinder, viaParameterFinder = viaParameterFinder,
locationSharingService = locationSharingServiceFactory.create(roomId),
coroutineDispatchers = coroutineDispatchers coroutineDispatchers = coroutineDispatchers
) )
} }