mirror of
https://gitlab.futo.org/videostreaming/grayjay.git
synced 2025-04-29 22:24:29 +02:00
Implemented sync display names.
This commit is contained in:
parent
b5ac8b3ec6
commit
0006da7385
@ -197,7 +197,7 @@ dependencies {
|
|||||||
implementation 'org.jsoup:jsoup:1.15.3'
|
implementation 'org.jsoup:jsoup:1.15.3'
|
||||||
implementation 'com.google.android.flexbox:flexbox:3.0.0'
|
implementation 'com.google.android.flexbox:flexbox:3.0.0'
|
||||||
implementation 'androidx.swiperefreshlayout:swiperefreshlayout:1.1.0'
|
implementation 'androidx.swiperefreshlayout:swiperefreshlayout:1.1.0'
|
||||||
implementation 'com.arthenica:ffmpeg-kit-full:5.1'
|
implementation 'com.arthenica:ffmpeg-kit-full:6.0-2.LTS'
|
||||||
implementation 'org.jetbrains.kotlin:kotlin-reflect:1.9.0'
|
implementation 'org.jetbrains.kotlin:kotlin-reflect:1.9.0'
|
||||||
implementation 'com.github.dhaval2404:imagepicker:2.1'
|
implementation 'com.github.dhaval2404:imagepicker:2.1'
|
||||||
implementation 'com.google.zxing:core:3.4.1'
|
implementation 'com.google.zxing:core:3.4.1'
|
||||||
|
@ -101,7 +101,8 @@ class SyncHomeActivity : AppCompatActivity() {
|
|||||||
private fun updateDeviceView(syncDeviceView: SyncDeviceView, publicKey: String, session: SyncSession?): SyncDeviceView {
|
private fun updateDeviceView(syncDeviceView: SyncDeviceView, publicKey: String, session: SyncSession?): SyncDeviceView {
|
||||||
val connected = session?.connected ?: false
|
val connected = session?.connected ?: false
|
||||||
syncDeviceView.setLinkType(if (connected) LinkType.Local else LinkType.None)
|
syncDeviceView.setLinkType(if (connected) LinkType.Local else LinkType.None)
|
||||||
.setName(publicKey)
|
.setName(session?.displayName ?: StateSync.instance.getCachedName(publicKey) ?: publicKey)
|
||||||
|
//TODO: also display public key?
|
||||||
.setStatus(if (connected) "Connected" else "Disconnected")
|
.setStatus(if (connected) "Connected" else "Disconnected")
|
||||||
return syncDeviceView
|
return syncDeviceView
|
||||||
}
|
}
|
||||||
|
@ -922,7 +922,7 @@ class VideoDetailView : ConstraintLayout {
|
|||||||
} else if(devices.size == 1){
|
} else if(devices.size == 1){
|
||||||
val device = devices.first();
|
val device = devices.first();
|
||||||
Logger.i(TAG, "Send to device? (public key: ${device.remotePublicKey}): " + videoToSend.url)
|
Logger.i(TAG, "Send to device? (public key: ${device.remotePublicKey}): " + videoToSend.url)
|
||||||
UIDialogs.showConfirmationDialog(context, "Would you like to open\n[${videoToSend.name}]\non ${device.remotePublicKey}" , {
|
UIDialogs.showConfirmationDialog(context, "Would you like to open\n[${videoToSend.name}]\non '${device.displayName}'" , {
|
||||||
Logger.i(TAG, "Send to device confirmed (public key: ${device.remotePublicKey}): " + videoToSend.url)
|
Logger.i(TAG, "Send to device confirmed (public key: ${device.remotePublicKey}): " + videoToSend.url)
|
||||||
|
|
||||||
fragment.lifecycleScope.launch(Dispatchers.IO) {
|
fragment.lifecycleScope.launch(Dispatchers.IO) {
|
||||||
|
@ -44,6 +44,7 @@ import kotlin.system.measureTimeMillis
|
|||||||
|
|
||||||
class StateSync {
|
class StateSync {
|
||||||
private val _authorizedDevices = FragmentedStorage.get<StringArrayStorage>("authorized_devices")
|
private val _authorizedDevices = FragmentedStorage.get<StringArrayStorage>("authorized_devices")
|
||||||
|
private val _nameStorage = FragmentedStorage.get<StringStringMapStorage>("sync_remembered_name_storage")
|
||||||
private val _syncKeyPair = FragmentedStorage.get<StringStorage>("sync_key_pair")
|
private val _syncKeyPair = FragmentedStorage.get<StringStorage>("sync_key_pair")
|
||||||
private val _lastAddressStorage = FragmentedStorage.get<StringStringMapStorage>("sync_last_address_storage")
|
private val _lastAddressStorage = FragmentedStorage.get<StringStringMapStorage>("sync_last_address_storage")
|
||||||
private val _syncSessionData = FragmentedStorage.get<StringTMapStorage<SyncSessionData>>("syncSessionData")
|
private val _syncSessionData = FragmentedStorage.get<StringTMapStorage<SyncSessionData>>("syncSessionData")
|
||||||
@ -305,12 +306,22 @@ class StateSync {
|
|||||||
synchronized(_sessions) {
|
synchronized(_sessions) {
|
||||||
session = _sessions[s.remotePublicKey]
|
session = _sessions[s.remotePublicKey]
|
||||||
if (session == null) {
|
if (session == null) {
|
||||||
|
val remoteDeviceName = synchronized(_nameStorage) {
|
||||||
|
_nameStorage.get(remotePublicKey)
|
||||||
|
}
|
||||||
|
|
||||||
session = SyncSession(remotePublicKey, onAuthorized = { it, isNewlyAuthorized, isNewSession ->
|
session = SyncSession(remotePublicKey, onAuthorized = { it, isNewlyAuthorized, isNewSession ->
|
||||||
if (!isNewSession) {
|
if (!isNewSession) {
|
||||||
return@SyncSession
|
return@SyncSession
|
||||||
}
|
}
|
||||||
|
|
||||||
Logger.i(TAG, "${s.remotePublicKey} authorized")
|
it.remoteDeviceName?.let { remoteDeviceName ->
|
||||||
|
synchronized(_nameStorage) {
|
||||||
|
_nameStorage.setAndSave(remotePublicKey, remoteDeviceName)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Logger.i(TAG, "${s.remotePublicKey} authorized (name: ${it.displayName})")
|
||||||
synchronized(_lastAddressStorage) {
|
synchronized(_lastAddressStorage) {
|
||||||
_lastAddressStorage.setAndSave(remotePublicKey, s.remoteAddress)
|
_lastAddressStorage.setAndSave(remotePublicKey, s.remoteAddress)
|
||||||
}
|
}
|
||||||
@ -341,7 +352,7 @@ class StateSync {
|
|||||||
|
|
||||||
deviceRemoved.emit(it.remotePublicKey)
|
deviceRemoved.emit(it.remotePublicKey)
|
||||||
|
|
||||||
})
|
}, remoteDeviceName)
|
||||||
_sessions[remotePublicKey] = session!!
|
_sessions[remotePublicKey] = session!!
|
||||||
}
|
}
|
||||||
session!!.addSocketSession(s)
|
session!!.addSocketSession(s)
|
||||||
@ -469,6 +480,12 @@ class StateSync {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun getCachedName(publicKey: String): String? {
|
||||||
|
return synchronized(_nameStorage) {
|
||||||
|
_nameStorage.get(publicKey)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
suspend fun delete(publicKey: String) {
|
suspend fun delete(publicKey: String) {
|
||||||
withContext(Dispatchers.IO) {
|
withContext(Dispatchers.IO) {
|
||||||
try {
|
try {
|
||||||
|
@ -6,12 +6,10 @@ import com.futo.platformplayer.api.media.Serializer
|
|||||||
import com.futo.platformplayer.logging.Logger
|
import com.futo.platformplayer.logging.Logger
|
||||||
import com.futo.platformplayer.models.HistoryVideo
|
import com.futo.platformplayer.models.HistoryVideo
|
||||||
import com.futo.platformplayer.models.Subscription
|
import com.futo.platformplayer.models.Subscription
|
||||||
import com.futo.platformplayer.models.SubscriptionGroup
|
|
||||||
import com.futo.platformplayer.smartMerge
|
import com.futo.platformplayer.smartMerge
|
||||||
import com.futo.platformplayer.states.StateApp
|
import com.futo.platformplayer.states.StateApp
|
||||||
import com.futo.platformplayer.states.StateBackup
|
import com.futo.platformplayer.states.StateBackup
|
||||||
import com.futo.platformplayer.states.StateHistory
|
import com.futo.platformplayer.states.StateHistory
|
||||||
import com.futo.platformplayer.states.StatePlayer
|
|
||||||
import com.futo.platformplayer.states.StatePlaylists
|
import com.futo.platformplayer.states.StatePlaylists
|
||||||
import com.futo.platformplayer.states.StateSubscriptionGroups
|
import com.futo.platformplayer.states.StateSubscriptionGroups
|
||||||
import com.futo.platformplayer.states.StateSubscriptions
|
import com.futo.platformplayer.states.StateSubscriptions
|
||||||
@ -30,6 +28,7 @@ import kotlinx.serialization.encodeToString
|
|||||||
import kotlinx.serialization.json.Json
|
import kotlinx.serialization.json.Json
|
||||||
import java.io.ByteArrayInputStream
|
import java.io.ByteArrayInputStream
|
||||||
import java.nio.ByteBuffer
|
import java.nio.ByteBuffer
|
||||||
|
import java.nio.ByteOrder
|
||||||
import java.time.Instant
|
import java.time.Instant
|
||||||
import java.time.OffsetDateTime
|
import java.time.OffsetDateTime
|
||||||
import java.time.ZoneOffset
|
import java.time.ZoneOffset
|
||||||
@ -53,6 +52,9 @@ class SyncSession : IAuthorizable {
|
|||||||
private val _id = UUID.randomUUID()
|
private val _id = UUID.randomUUID()
|
||||||
private var _remoteId: UUID? = null
|
private var _remoteId: UUID? = null
|
||||||
private var _lastAuthorizedRemoteId: UUID? = null
|
private var _lastAuthorizedRemoteId: UUID? = null
|
||||||
|
var remoteDeviceName: String? = null
|
||||||
|
private set
|
||||||
|
val displayName: String get() = remoteDeviceName ?: remotePublicKey
|
||||||
|
|
||||||
var connected: Boolean = false
|
var connected: Boolean = false
|
||||||
private set(v) {
|
private set(v) {
|
||||||
@ -62,7 +64,7 @@ class SyncSession : IAuthorizable {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
constructor(remotePublicKey: String, onAuthorized: (session: SyncSession, isNewlyAuthorized: Boolean, isNewSession: Boolean) -> Unit, onUnauthorized: (session: SyncSession) -> Unit, onConnectedChanged: (session: SyncSession, connected: Boolean) -> Unit, onClose: (session: SyncSession) -> Unit) {
|
constructor(remotePublicKey: String, onAuthorized: (session: SyncSession, isNewlyAuthorized: Boolean, isNewSession: Boolean) -> Unit, onUnauthorized: (session: SyncSession) -> Unit, onConnectedChanged: (session: SyncSession, connected: Boolean) -> Unit, onClose: (session: SyncSession) -> Unit, remoteDeviceName: String?) {
|
||||||
this.remotePublicKey = remotePublicKey
|
this.remotePublicKey = remotePublicKey
|
||||||
_onAuthorized = onAuthorized
|
_onAuthorized = onAuthorized
|
||||||
_onUnauthorized = onUnauthorized
|
_onUnauthorized = onUnauthorized
|
||||||
@ -85,7 +87,20 @@ class SyncSession : IAuthorizable {
|
|||||||
|
|
||||||
fun authorize(socketSession: SyncSocketSession) {
|
fun authorize(socketSession: SyncSocketSession) {
|
||||||
Logger.i(TAG, "Sent AUTHORIZED with session id $_id")
|
Logger.i(TAG, "Sent AUTHORIZED with session id $_id")
|
||||||
socketSession.send(Opcode.NOTIFY_AUTHORIZED.value, 0u, ByteBuffer.wrap(_id.toString().toByteArray()))
|
|
||||||
|
if (socketSession.remoteVersion >= 3) {
|
||||||
|
val idStringBytes = _id.toString().toByteArray()
|
||||||
|
val nameBytes = "${android.os.Build.MANUFACTURER}-${android.os.Build.MODEL}".toByteArray()
|
||||||
|
val buffer = ByteArray(1 + idStringBytes.size + 1 + nameBytes.size)
|
||||||
|
socketSession.send(Opcode.NOTIFY_AUTHORIZED.value, 0u, ByteBuffer.wrap(buffer).order(ByteOrder.LITTLE_ENDIAN).apply {
|
||||||
|
put(idStringBytes.size.toByte())
|
||||||
|
put(idStringBytes)
|
||||||
|
put(nameBytes.size.toByte())
|
||||||
|
put(nameBytes)
|
||||||
|
}.apply { flip() })
|
||||||
|
} else {
|
||||||
|
socketSession.send(Opcode.NOTIFY_AUTHORIZED.value, 0u, ByteBuffer.wrap(_id.toString().toByteArray()))
|
||||||
|
}
|
||||||
_authorized = true
|
_authorized = true
|
||||||
checkAuthorized()
|
checkAuthorized()
|
||||||
}
|
}
|
||||||
@ -138,15 +153,37 @@ class SyncSession : IAuthorizable {
|
|||||||
|
|
||||||
when (opcode) {
|
when (opcode) {
|
||||||
Opcode.NOTIFY_AUTHORIZED.value -> {
|
Opcode.NOTIFY_AUTHORIZED.value -> {
|
||||||
val str = data.toUtf8String()
|
if (socketSession.remoteVersion >= 3) {
|
||||||
_remoteId = if (data.remaining() >= 0) UUID.fromString(str) else UUID.fromString("00000000-0000-0000-0000-000000000000")
|
val idByteCount = data.get().toInt()
|
||||||
|
if (idByteCount > 64)
|
||||||
|
throw Exception("Id should always be smaller than 64 bytes")
|
||||||
|
|
||||||
|
val idBytes = ByteArray(idByteCount)
|
||||||
|
data.get(idBytes)
|
||||||
|
|
||||||
|
val nameByteCount = data.get().toInt()
|
||||||
|
if (nameByteCount > 64)
|
||||||
|
throw Exception("Name should always be smaller than 64 bytes")
|
||||||
|
|
||||||
|
val nameBytes = ByteArray(nameByteCount)
|
||||||
|
data.get(nameBytes)
|
||||||
|
|
||||||
|
_remoteId = UUID.fromString(idBytes.toString(Charsets.UTF_8))
|
||||||
|
remoteDeviceName = nameBytes.toString(Charsets.UTF_8)
|
||||||
|
} else {
|
||||||
|
val str = data.toUtf8String()
|
||||||
|
_remoteId = if (data.remaining() >= 0) UUID.fromString(str) else UUID.fromString("00000000-0000-0000-0000-000000000000")
|
||||||
|
remoteDeviceName = null
|
||||||
|
}
|
||||||
|
|
||||||
_remoteAuthorized = true
|
_remoteAuthorized = true
|
||||||
Logger.i(TAG, "Received AUTHORIZED with session id $_remoteId")
|
Logger.i(TAG, "Received AUTHORIZED with session id $_remoteId (device name: '${remoteDeviceName ?: "not set"}')")
|
||||||
checkAuthorized()
|
checkAuthorized()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
Opcode.NOTIFY_UNAUTHORIZED.value -> {
|
Opcode.NOTIFY_UNAUTHORIZED.value -> {
|
||||||
_remoteId = null
|
_remoteId = null
|
||||||
|
remoteDeviceName = null
|
||||||
_lastAuthorizedRemoteId = null
|
_lastAuthorizedRemoteId = null
|
||||||
_remoteAuthorized = false
|
_remoteAuthorized = false
|
||||||
_onUnauthorized(this)
|
_onUnauthorized(this)
|
||||||
|
@ -46,6 +46,8 @@ class SyncSocketSession {
|
|||||||
val localPublicKey: String get() = _localPublicKey
|
val localPublicKey: String get() = _localPublicKey
|
||||||
private val _onData: (session: SyncSocketSession, opcode: UByte, subOpcode: UByte, data: ByteBuffer) -> Unit
|
private val _onData: (session: SyncSocketSession, opcode: UByte, subOpcode: UByte, data: ByteBuffer) -> Unit
|
||||||
var authorizable: IAuthorizable? = null
|
var authorizable: IAuthorizable? = null
|
||||||
|
var remoteVersion: Int = -1
|
||||||
|
private set
|
||||||
|
|
||||||
val remoteAddress: String
|
val remoteAddress: String
|
||||||
|
|
||||||
@ -162,11 +164,12 @@ class SyncSocketSession {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun performVersionCheck() {
|
private fun performVersionCheck() {
|
||||||
val CURRENT_VERSION = 2
|
val CURRENT_VERSION = 3
|
||||||
|
val MINIMUM_VERSION = 2
|
||||||
_outputStream.writeInt(CURRENT_VERSION)
|
_outputStream.writeInt(CURRENT_VERSION)
|
||||||
val version = _inputStream.readInt()
|
remoteVersion = _inputStream.readInt()
|
||||||
Logger.i(TAG, "performVersionCheck (version = $version)")
|
Logger.i(TAG, "performVersionCheck (version = $remoteVersion)")
|
||||||
if (version != CURRENT_VERSION)
|
if (remoteVersion < MINIMUM_VERSION)
|
||||||
throw Exception("Invalid version")
|
throw Exception("Invalid version")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user