Merge pull request #5651 from vector-im/feature/ons/live_location_beacon_info

Live Location Sharing - Beacon Info
This commit is contained in:
Onuray Sahin 2022-04-04 12:55:22 +03:00 committed by GitHub
commit 48d40d8ba2
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 131 additions and 0 deletions

1
changelog.d/5651.feature Normal file
View File

@ -0,0 +1 @@
Send beacon info state event when live location sharing started

View File

@ -49,6 +49,7 @@ object EventType {
const val STATE_ROOM_JOIN_RULES = "m.room.join_rules"
const val STATE_ROOM_GUEST_ACCESS = "m.room.guest_access"
const val STATE_ROOM_POWER_LEVELS = "m.room.power_levels"
private const val STATE_ROOM_BEACON_INFO_PREFIX = "org.matrix.msc3489.beacon_info."
const val STATE_SPACE_CHILD = "m.space.child"
@ -120,4 +121,12 @@ object EventType {
type == CALL_REJECT ||
type == CALL_REPLACES
}
/**
* Returns an event type like org.matrix.msc3489.beacon_info.@userid:matrix.org.1648814272273
*/
fun generateBeaconInfoStateEventType(userId: String): String {
val uniqueId = System.currentTimeMillis()
return "$STATE_ROOM_BEACON_INFO_PREFIX$userId.$uniqueId"
}
}

View File

@ -0,0 +1,33 @@
/*
* Copyright 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.model.livelocation
import com.squareup.moshi.Json
import com.squareup.moshi.JsonClass
@JsonClass(generateAdapter = true)
data class BeaconInfo(
@Json(name = "description") val description: String? = null,
/**
* Beacon should be considered as inactive after this timeout as milliseconds.
*/
@Json(name = "timeout") val timeout: Long? = null,
/**
* Should be set true to start sharing beacon.
*/
@Json(name = "live") val isLive: Boolean? = null
)

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.model.livelocation
import com.squareup.moshi.Json
import com.squareup.moshi.JsonClass
import org.matrix.android.sdk.api.session.room.model.message.LocationAsset
import org.matrix.android.sdk.api.session.room.model.message.LocationAssetType
@JsonClass(generateAdapter = true)
data class LiveLocationBeaconContent(
/**
* Indicates user's intent to share ephemeral location.
*/
@Json(name = "org.matrix.msc3489.beacon_info") val unstableBeaconInfo: BeaconInfo? = null,
@Json(name = "m.beacon_info") val beaconInfo: BeaconInfo? = null,
/**
* Beacon creation timestamp.
*/
@Json(name = "org.matrix.msc3488.ts") val unstableTimestampAsMilliseconds: Long? = null,
@Json(name = "m.ts") val timestampAsMilliseconds: Long? = null,
/**
* Live location asset type.
*/
@Json(name = "org.matrix.msc3488.asset") val unstableLocationAsset: LocationAsset = LocationAsset(LocationAssetType.SELF),
@Json(name = "m.asset") val locationAsset: LocationAsset? = null
) {
fun getBestBeaconInfo() = beaconInfo ?: unstableBeaconInfo
fun getBestTimestampAsMilliseconds() = timestampAsMilliseconds ?: unstableTimestampAsMilliseconds
fun getBestLocationAsset() = locationAsset ?: unstableLocationAsset
}

View File

@ -20,9 +20,18 @@ import android.content.Intent
import android.os.IBinder
import android.os.Parcelable
import dagger.hilt.android.AndroidEntryPoint
import im.vector.app.core.di.ActiveSessionHolder
import im.vector.app.core.services.VectorService
import im.vector.app.core.time.Clock
import im.vector.app.features.notifications.NotificationUtils
import im.vector.app.features.session.coroutineScope
import kotlinx.coroutines.launch
import kotlinx.parcelize.Parcelize
import org.matrix.android.sdk.api.session.Session
import org.matrix.android.sdk.api.session.events.model.EventType.generateBeaconInfoStateEventType
import org.matrix.android.sdk.api.session.events.model.toContent
import org.matrix.android.sdk.api.session.room.model.livelocation.BeaconInfo
import org.matrix.android.sdk.api.session.room.model.livelocation.LiveLocationBeaconContent
import timber.log.Timber
import java.util.Timer
import java.util.TimerTask
@ -40,6 +49,8 @@ class LocationSharingService : VectorService(), LocationTracker.Callback {
@Inject lateinit var notificationUtils: NotificationUtils
@Inject lateinit var locationTracker: LocationTracker
@Inject lateinit var activeSessionHolder: ActiveSessionHolder
@Inject lateinit var clock: Clock
private var roomArgsList = mutableListOf<RoomArgs>()
private var timers = mutableListOf<Timer>()
@ -67,11 +78,40 @@ class LocationSharingService : VectorService(), LocationTracker.Callback {
// Schedule a timer to stop sharing
scheduleTimer(roomArgs.roomId, roomArgs.durationMillis)
// Send beacon info state event
activeSessionHolder
.getSafeActiveSession()
?.let { session ->
session.coroutineScope.launch(session.coroutineDispatchers.io) {
sendBeaconInfo(session, roomArgs)
}
}
}
return START_STICKY
}
private suspend fun sendBeaconInfo(session: Session, roomArgs: RoomArgs) {
val beaconContent = LiveLocationBeaconContent(
unstableBeaconInfo = BeaconInfo(
timeout = roomArgs.durationMillis,
isLive = true
),
unstableTimestampAsMilliseconds = clock.epochMillis()
).toContent()
val eventType = generateBeaconInfoStateEventType(session.myUserId)
val stateKey = session.myUserId
session
.getRoom(roomArgs.roomId)
?.sendStateEvent(
eventType = eventType,
stateKey = stateKey,
body = beaconContent
)
}
private fun scheduleTimer(roomId: String, durationMillis: Long) {
Timer()
.apply {