Merge pull request #5651 from vector-im/feature/ons/live_location_beacon_info
Live Location Sharing - Beacon Info
This commit is contained in:
commit
48d40d8ba2
|
@ -0,0 +1 @@
|
||||||
|
Send beacon info state event when live location sharing started
|
|
@ -49,6 +49,7 @@ object EventType {
|
||||||
const val STATE_ROOM_JOIN_RULES = "m.room.join_rules"
|
const val STATE_ROOM_JOIN_RULES = "m.room.join_rules"
|
||||||
const val STATE_ROOM_GUEST_ACCESS = "m.room.guest_access"
|
const val STATE_ROOM_GUEST_ACCESS = "m.room.guest_access"
|
||||||
const val STATE_ROOM_POWER_LEVELS = "m.room.power_levels"
|
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"
|
const val STATE_SPACE_CHILD = "m.space.child"
|
||||||
|
|
||||||
|
@ -120,4 +121,12 @@ object EventType {
|
||||||
type == CALL_REJECT ||
|
type == CALL_REJECT ||
|
||||||
type == CALL_REPLACES
|
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"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
||||||
|
)
|
|
@ -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
|
||||||
|
}
|
|
@ -20,9 +20,18 @@ import android.content.Intent
|
||||||
import android.os.IBinder
|
import android.os.IBinder
|
||||||
import android.os.Parcelable
|
import android.os.Parcelable
|
||||||
import dagger.hilt.android.AndroidEntryPoint
|
import dagger.hilt.android.AndroidEntryPoint
|
||||||
|
import im.vector.app.core.di.ActiveSessionHolder
|
||||||
import im.vector.app.core.services.VectorService
|
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.notifications.NotificationUtils
|
||||||
|
import im.vector.app.features.session.coroutineScope
|
||||||
|
import kotlinx.coroutines.launch
|
||||||
import kotlinx.parcelize.Parcelize
|
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 timber.log.Timber
|
||||||
import java.util.Timer
|
import java.util.Timer
|
||||||
import java.util.TimerTask
|
import java.util.TimerTask
|
||||||
|
@ -40,6 +49,8 @@ class LocationSharingService : VectorService(), LocationTracker.Callback {
|
||||||
|
|
||||||
@Inject lateinit var notificationUtils: NotificationUtils
|
@Inject lateinit var notificationUtils: NotificationUtils
|
||||||
@Inject lateinit var locationTracker: LocationTracker
|
@Inject lateinit var locationTracker: LocationTracker
|
||||||
|
@Inject lateinit var activeSessionHolder: ActiveSessionHolder
|
||||||
|
@Inject lateinit var clock: Clock
|
||||||
|
|
||||||
private var roomArgsList = mutableListOf<RoomArgs>()
|
private var roomArgsList = mutableListOf<RoomArgs>()
|
||||||
private var timers = mutableListOf<Timer>()
|
private var timers = mutableListOf<Timer>()
|
||||||
|
@ -67,11 +78,40 @@ class LocationSharingService : VectorService(), LocationTracker.Callback {
|
||||||
|
|
||||||
// Schedule a timer to stop sharing
|
// Schedule a timer to stop sharing
|
||||||
scheduleTimer(roomArgs.roomId, roomArgs.durationMillis)
|
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
|
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) {
|
private fun scheduleTimer(roomId: String, durationMillis: Long) {
|
||||||
Timer()
|
Timer()
|
||||||
.apply {
|
.apply {
|
||||||
|
|
Loading…
Reference in New Issue