From fde6148ece8a88b6c29870fc36f2584ed89c807b Mon Sep 17 00:00:00 2001 From: Koen J Date: Mon, 18 Nov 2024 11:27:55 +0100 Subject: [PATCH 1/7] Added subopcode byte. --- .../mainactivity/main/VideoDetailView.kt | 2 +- .../platformplayer/states/StateHistory.kt | 2 +- .../platformplayer/states/StatePlaylists.kt | 4 +- .../states/StateSubscriptionGroups.kt | 4 +- .../states/StateSubscriptions.kt | 4 +- .../futo/platformplayer/states/StateSync.kt | 23 ++++---- .../sync/internal/SyncSession.kt | 41 ++++++++----- .../sync/internal/SyncSocketSession.kt | 57 ++++++++++++------- .../sync/internal/SyncStream.kt | 2 +- .../futo/platformplayer/NoiseProtocolTests.kt | 14 ++--- 10 files changed, 90 insertions(+), 63 deletions(-) diff --git a/app/src/main/java/com/futo/platformplayer/fragment/mainactivity/main/VideoDetailView.kt b/app/src/main/java/com/futo/platformplayer/fragment/mainactivity/main/VideoDetailView.kt index 33e53ccb..c424f640 100644 --- a/app/src/main/java/com/futo/platformplayer/fragment/mainactivity/main/VideoDetailView.kt +++ b/app/src/main/java/com/futo/platformplayer/fragment/mainactivity/main/VideoDetailView.kt @@ -927,7 +927,7 @@ class VideoDetailView : ConstraintLayout { val device = devices.first(); UIDialogs.showConfirmationDialog(context, "Would you like to open\n[${videoToSend.name}]\non ${device.remotePublicKey}" , { fragment.lifecycleScope.launch(Dispatchers.IO) { - device.sendJson(GJSyncOpcodes.sendToDevices, SendToDevicePackage(videoToSend.url, (lastPositionMilliseconds/1000).toInt())); + device.sendJsonData(GJSyncOpcodes.sendToDevices, SendToDevicePackage(videoToSend.url, (lastPositionMilliseconds/1000).toInt())); } }) } diff --git a/app/src/main/java/com/futo/platformplayer/states/StateHistory.kt b/app/src/main/java/com/futo/platformplayer/states/StateHistory.kt index acd92a67..cf2c032c 100644 --- a/app/src/main/java/com/futo/platformplayer/states/StateHistory.kt +++ b/app/src/main/java/com/futo/platformplayer/states/StateHistory.kt @@ -89,7 +89,7 @@ class StateHistory { StateApp.instance.scopeOrNull?.launch(Dispatchers.IO) { if(StateSync.instance.hasAtLeastOneOnlineDevice()) { Logger.i(TAG, "SyncHistory playback broadcasted (${liveObj.name}: ${position})"); - StateSync.instance.broadcastJson( + StateSync.instance.broadcastJsonData( GJSyncOpcodes.syncHistory, listOf(historyVideo) ); diff --git a/app/src/main/java/com/futo/platformplayer/states/StatePlaylists.kt b/app/src/main/java/com/futo/platformplayer/states/StatePlaylists.kt index 2826cb91..f5a033ab 100644 --- a/app/src/main/java/com/futo/platformplayer/states/StatePlaylists.kt +++ b/app/src/main/java/com/futo/platformplayer/states/StatePlaylists.kt @@ -198,7 +198,7 @@ class StatePlaylists { StateApp.instance.scopeOrNull?.launch(Dispatchers.IO) { if(StateSync.instance.hasAtLeastOneOnlineDevice()) { Logger.i(StateSubscriptionGroups.TAG, "SyncPlaylist (${playlist.name})"); - StateSync.instance.broadcastJson( + StateSync.instance.broadcastJsonData( GJSyncOpcodes.syncPlaylists, SyncPlaylistsPackage(listOf(playlist), mapOf()) ); @@ -217,7 +217,7 @@ class StatePlaylists { StateApp.instance.scopeOrNull?.launch(Dispatchers.IO) { if(StateSync.instance.hasAtLeastOneOnlineDevice()) { Logger.i(StateSubscriptionGroups.TAG, "SyncPlaylist (${playlist.name})"); - StateSync.instance.broadcastJson( + StateSync.instance.broadcastJsonData( GJSyncOpcodes.syncPlaylists, SyncPlaylistsPackage(listOf(), mapOf(Pair(playlist.id, OffsetDateTime.now().toEpochSecond()))) ); diff --git a/app/src/main/java/com/futo/platformplayer/states/StateSubscriptionGroups.kt b/app/src/main/java/com/futo/platformplayer/states/StateSubscriptionGroups.kt index 2b4883da..5ca521ec 100644 --- a/app/src/main/java/com/futo/platformplayer/states/StateSubscriptionGroups.kt +++ b/app/src/main/java/com/futo/platformplayer/states/StateSubscriptionGroups.kt @@ -81,7 +81,7 @@ class StateSubscriptionGroups { StateApp.instance.scopeOrNull?.launch(Dispatchers.IO) { if(StateSync.instance.hasAtLeastOneOnlineDevice()) { Logger.i(TAG, "SyncSubscriptionGroup (${subGroup.name})"); - StateSync.instance.broadcastJson( + StateSync.instance.broadcastJsonData( GJSyncOpcodes.syncSubscriptionGroups, SyncSubscriptionGroupsPackage(listOf(subGroup), mapOf()) ); @@ -100,7 +100,7 @@ class StateSubscriptionGroups { StateApp.instance.scopeOrNull?.launch(Dispatchers.IO) { if(StateSync.instance.hasAtLeastOneOnlineDevice()) { Logger.i(TAG, "SyncSubscriptionGroup delete (${group.name})"); - StateSync.instance.broadcastJson( + StateSync.instance.broadcastJsonData( GJSyncOpcodes.syncSubscriptionGroups, SyncSubscriptionGroupsPackage(listOf(), mapOf(Pair(id, OffsetDateTime.now().toEpochSecond()))) ); diff --git a/app/src/main/java/com/futo/platformplayer/states/StateSubscriptions.kt b/app/src/main/java/com/futo/platformplayer/states/StateSubscriptions.kt index df680fed..52fb9f2e 100644 --- a/app/src/main/java/com/futo/platformplayer/states/StateSubscriptions.kt +++ b/app/src/main/java/com/futo/platformplayer/states/StateSubscriptions.kt @@ -250,7 +250,7 @@ class StateSubscriptions { StateApp.instance.scopeOrNull?.launch(Dispatchers.IO) { try { - StateSync.instance.broadcast( + StateSync.instance.broadcastData( GJSyncOpcodes.syncSubscriptions, Json.encodeToString( SyncSubscriptionsPackage( listOf(subObj), @@ -299,7 +299,7 @@ class StateSubscriptions { StateApp.instance.scopeOrNull?.launch(Dispatchers.IO) { try { - StateSync.instance.broadcast( + StateSync.instance.broadcastData( GJSyncOpcodes.syncSubscriptions, Json.encodeToString( SyncSubscriptionsPackage( listOf(), diff --git a/app/src/main/java/com/futo/platformplayer/states/StateSync.kt b/app/src/main/java/com/futo/platformplayer/states/StateSync.kt index b6bf0ca8..4de1b41c 100644 --- a/app/src/main/java/com/futo/platformplayer/states/StateSync.kt +++ b/app/src/main/java/com/futo/platformplayer/states/StateSync.kt @@ -370,26 +370,29 @@ class StateSync { Logger.i(TAG, "Connection authorized for ${remotePublicKey} because initiator") } }, - onData = { s, opcode, data -> - session?.handlePacket(s, opcode, data) + onData = { s, opcode, subOpcode, data -> + session?.handlePacket(s, opcode, subOpcode, data) }) } - inline fun broadcastJson(opcode: UByte, data: T) { - broadcast(opcode, Json.encodeToString(data)); + inline fun broadcastJsonData(subOpcode: UByte, data: T) { + broadcast(SyncSocketSession.Opcode.DATA.value, subOpcode, Json.encodeToString(data)); } - fun broadcast(opcode: UByte, data: String) { - broadcast(opcode, data.toByteArray(Charsets.UTF_8)); + fun broadcastData(subOpcode: UByte, data: String) { + broadcast(SyncSocketSession.Opcode.DATA.value, subOpcode, data.toByteArray(Charsets.UTF_8)); } - fun broadcast(opcode: UByte, data: ByteArray) { + fun broadcast(opcode: UByte, subOpcode: UByte, data: String) { + broadcast(opcode, subOpcode, data.toByteArray(Charsets.UTF_8)); + } + fun broadcast(opcode: UByte, subOpcode: UByte, data: ByteArray) { for(session in getSessions()) { try { if (session.isAuthorized && session.connected) { - session.send(opcode, data); + session.send(opcode, subOpcode, data); } } catch(ex: Exception) { - Logger.w(TAG, "Failed to broadcast ${opcode} to ${session.remotePublicKey}: ${ex.message}}", ex); + Logger.w(TAG, "Failed to broadcast (opcode = ${opcode}, subOpcode = ${subOpcode}) to ${session.remotePublicKey}: ${ex.message}}", ex); } } } @@ -398,7 +401,7 @@ class StateSync { val time = measureTimeMillis { //val export = StateBackup.export(); //session.send(GJSyncOpcodes.syncExport, export.asZip()); - session.send(GJSyncOpcodes.syncStateExchange, getSyncSessionDataString(session.remotePublicKey)); + session.sendData(GJSyncOpcodes.syncStateExchange, getSyncSessionDataString(session.remotePublicKey)); } Logger.i(TAG, "Generated and sent sync export in ${time}ms"); } diff --git a/app/src/main/java/com/futo/platformplayer/sync/internal/SyncSession.kt b/app/src/main/java/com/futo/platformplayer/sync/internal/SyncSession.kt index 6c46f59d..fd457d52 100644 --- a/app/src/main/java/com/futo/platformplayer/sync/internal/SyncSession.kt +++ b/app/src/main/java/com/futo/platformplayer/sync/internal/SyncSession.kt @@ -45,6 +45,7 @@ class SyncSession : IAuthorizable { private val _onConnectedChanged: (session: SyncSession, connected: Boolean) -> Unit val remotePublicKey: String override val isAuthorized get() = _authorized && _remoteAuthorized + private var _wasAuthorized = false var connected: Boolean = false private set(v) { @@ -94,8 +95,10 @@ class SyncSession : IAuthorizable { } private fun checkAuthorized() { - if (isAuthorized) + if (!_wasAuthorized && isAuthorized) { + _wasAuthorized = true _onAuthorized.invoke(this) + } } fun removeSocketSession(socketSession: SyncSocketSession) { @@ -117,8 +120,8 @@ class SyncSession : IAuthorizable { _onClose.invoke(this) } - fun handlePacket(socketSession: SyncSocketSession, opcode: UByte, data: ByteBuffer) { - Logger.i(TAG, "Handle packet (opcode: ${opcode}, data.length: ${data.remaining()})") + fun handlePacket(socketSession: SyncSocketSession, opcode: UByte, subOpcode: UByte, data: ByteBuffer) { + Logger.i(TAG, "Handle packet (opcode: ${opcode}, subOpcode: ${subOpcode}, data.length: ${data.remaining()})") when (opcode) { Opcode.NOTIFY_AUTHORIZED.value -> { @@ -136,10 +139,15 @@ class SyncSession : IAuthorizable { return } - Logger.i(TAG, "Received ${opcode} (${data.remaining()} bytes)") + if (opcode != Opcode.DATA.value) { + Logger.w(TAG, "Unknown opcode received: (opcode = ${opcode}, subOpcode = ${subOpcode})}") + return + } + + Logger.i(TAG, "Received (opcode = ${opcode}, subOpcode = ${subOpcode}) (${data.remaining()} bytes)") //TODO: Abstract this out try { - when (opcode) { + when (subOpcode) { GJSyncOpcodes.sendToDevices -> { StateApp.instance.scopeOrNull?.launch(Dispatchers.Main) { val context = StateApp.instance.contextOrNull; @@ -164,13 +172,13 @@ class SyncSession : IAuthorizable { Logger.i(TAG, "Received SyncSessionData from " + remotePublicKey); - send(GJSyncOpcodes.syncSubscriptions, StateSubscriptions.instance.getSyncSubscriptionsPackageString()); - send(GJSyncOpcodes.syncSubscriptionGroups, StateSubscriptionGroups.instance.getSyncSubscriptionGroupsPackageString()); - send(GJSyncOpcodes.syncPlaylists, StatePlaylists.instance.getSyncPlaylistsPackageString()) + sendData(GJSyncOpcodes.syncSubscriptions, StateSubscriptions.instance.getSyncSubscriptionsPackageString()); + sendData(GJSyncOpcodes.syncSubscriptionGroups, StateSubscriptionGroups.instance.getSyncSubscriptionGroupsPackageString()); + sendData(GJSyncOpcodes.syncPlaylists, StatePlaylists.instance.getSyncPlaylistsPackageString()) val recentHistory = StateHistory.instance.getRecentHistory(syncSessionData.lastHistory); if(recentHistory.size > 0) - sendJson(GJSyncOpcodes.syncHistory, recentHistory); + sendJsonData(GJSyncOpcodes.syncHistory, recentHistory); } GJSyncOpcodes.syncExport -> { @@ -338,16 +346,19 @@ class SyncSession : IAuthorizable { } - inline fun sendJson(opcode: UByte, data: T) { - send(opcode, Json.encodeToString(data)); + inline fun sendJsonData(subOpcode: UByte, data: T) { + send(Opcode.DATA.value, subOpcode, Json.encodeToString(data)); } - fun send(opcode: UByte, data: String) { - send(opcode, data.toByteArray(Charsets.UTF_8)); + fun sendData(subOpcode: UByte, data: String) { + send(Opcode.DATA.value, subOpcode, data.toByteArray(Charsets.UTF_8)); } - fun send(opcode: UByte, data: ByteArray) { + fun send(opcode: UByte, subOpcode: UByte, data: String) { + send(opcode, subOpcode, data.toByteArray(Charsets.UTF_8)); + } + fun send(opcode: UByte, subOpcode: UByte, data: ByteArray) { val sock = _socketSessions.firstOrNull(); if(sock != null){ - sock.send(opcode, ByteBuffer.wrap(data)); + sock.send(opcode, subOpcode, ByteBuffer.wrap(data)); } else throw IllegalStateException("Session has no active sockets"); diff --git a/app/src/main/java/com/futo/platformplayer/sync/internal/SyncSocketSession.kt b/app/src/main/java/com/futo/platformplayer/sync/internal/SyncSocketSession.kt index b7b5ab79..6a5fd4a3 100644 --- a/app/src/main/java/com/futo/platformplayer/sync/internal/SyncSocketSession.kt +++ b/app/src/main/java/com/futo/platformplayer/sync/internal/SyncSocketSession.kt @@ -2,6 +2,7 @@ package com.futo.platformplayer.sync.internal import com.futo.platformplayer.LittleEndianDataInputStream import com.futo.platformplayer.LittleEndianDataOutputStream +import com.futo.platformplayer.ensureNotMainThread import com.futo.platformplayer.logging.Logger import com.futo.platformplayer.noise.protocol.CipherStatePair import com.futo.platformplayer.noise.protocol.DHState @@ -18,7 +19,8 @@ class SyncSocketSession { NOTIFY_UNAUTHORIZED(3u), STREAM_START(4u), STREAM_DATA(5u), - STREAM_END(6u) + STREAM_END(6u), + DATA(7u) } private val _inputStream: LittleEndianDataInputStream @@ -41,12 +43,12 @@ class SyncSocketSession { private val _localKeyPair: DHState private var _localPublicKey: String val localPublicKey: String get() = _localPublicKey - private val _onData: (session: SyncSocketSession, opcode: UByte, data: ByteBuffer) -> Unit + private val _onData: (session: SyncSocketSession, opcode: UByte, subOpcode: UByte, data: ByteBuffer) -> Unit var authorizable: IAuthorizable? = null val remoteAddress: String - constructor(remoteAddress: String, localKeyPair: DHState, inputStream: LittleEndianDataInputStream, outputStream: LittleEndianDataOutputStream, onClose: (session: SyncSocketSession) -> Unit, onHandshakeComplete: (session: SyncSocketSession) -> Unit, onData: (session: SyncSocketSession, opcode: UByte, data: ByteBuffer) -> Unit) { + constructor(remoteAddress: String, localKeyPair: DHState, inputStream: LittleEndianDataInputStream, outputStream: LittleEndianDataOutputStream, onClose: (session: SyncSocketSession) -> Unit, onHandshakeComplete: (session: SyncSocketSession) -> Unit, onData: (session: SyncSocketSession, opcode: UByte, subOpcode: UByte, data: ByteBuffer) -> Unit) { _inputStream = inputStream _outputStream = outputStream _onClose = onClose @@ -159,10 +161,11 @@ class SyncSocketSession { } private fun performVersionCheck() { - _outputStream.writeInt(1) + val CURRENT_VERSION = 2 + _outputStream.writeInt(CURRENT_VERSION) val version = _inputStream.readInt() Logger.i(TAG, "performVersionCheck (version = $version)") - if (version != 1) + if (version != CURRENT_VERSION) throw Exception("Invalid version") } @@ -205,8 +208,9 @@ class SyncSocketSession { throw Exception("Handshake finished without completing") } + fun send(opcode: UByte, subOpcode: UByte, data: ByteBuffer) { + ensureNotMainThread() - fun send(opcode: UByte, data: ByteBuffer) { if (data.remaining() + HEADER_SIZE > MAXIMUM_PACKET_SIZE) { val segmentSize = MAXIMUM_PACKET_SIZE - HEADER_SIZE val segmentData = ByteArray(segmentSize) @@ -223,8 +227,8 @@ class SyncSocketSession { if (sendOffset == 0) { segmentOpcode = Opcode.STREAM_START.value - bytesToSend = segmentSize - 4 - 4 - 1 - segmentPacketSize = bytesToSend + 4 + 4 + 1 + bytesToSend = segmentSize - 4 - 4 - 1 - 1 + segmentPacketSize = bytesToSend + 4 + 4 + 1 + 1 } else { bytesToSend = minOf(segmentSize - 4 - 4, bytesRemaining) segmentOpcode = if (bytesToSend >= bytesRemaining) Opcode.STREAM_END.value else Opcode.STREAM_DATA.value @@ -236,18 +240,20 @@ class SyncSocketSession { putInt(if (segmentOpcode == Opcode.STREAM_START.value) data.remaining() else sendOffset) if (segmentOpcode == Opcode.STREAM_START.value) { put(opcode.toByte()) + put(subOpcode.toByte()) } put(data.array(), data.position() + sendOffset, bytesToSend) } - send(segmentOpcode, ByteBuffer.wrap(segmentData, 0, segmentPacketSize)) + send(segmentOpcode, 0u, ByteBuffer.wrap(segmentData, 0, segmentPacketSize)) sendOffset += bytesToSend } } else { synchronized(_sendLockObject) { ByteBuffer.wrap(_sendBuffer).order(ByteOrder.LITTLE_ENDIAN).apply { - putInt(data.remaining() + 1) + putInt(data.remaining() + 2) put(opcode.toByte()) + put(subOpcode.toByte()) put(data.array(), data.position(), data.remaining()) } @@ -260,10 +266,13 @@ class SyncSocketSession { } } - fun send(opcode: UByte) { + fun send(opcode: UByte, subOpcode: UByte = 0u) { + ensureNotMainThread() + synchronized(_sendLockObject) { - ByteBuffer.wrap(_sendBuffer, 0, 4).order(ByteOrder.LITTLE_ENDIAN).putInt(1) + ByteBuffer.wrap(_sendBuffer, 0, 4).order(ByteOrder.LITTLE_ENDIAN).putInt(2) _sendBuffer.asUByteArray()[4] = opcode + _sendBuffer.asUByteArray()[5] = subOpcode //Logger.i(TAG, "Encrypting message (size = ${HEADER_SIZE})") @@ -277,19 +286,19 @@ class SyncSocketSession { private fun handleData(data: ByteArray, length: Int) { if (length < HEADER_SIZE) - throw Exception("Packet must be at least 5 bytes (header size)") + throw Exception("Packet must be at least 6 bytes (header size)") val size = ByteBuffer.wrap(data, 0, 4).order(ByteOrder.LITTLE_ENDIAN).int if (size != length - 4) throw Exception("Incomplete packet received") val opcode = data.asUByteArray()[4] - val packetData = ByteBuffer.wrap(data, HEADER_SIZE, size - 1) - - handlePacket(opcode, packetData.order(ByteOrder.LITTLE_ENDIAN)) + val subOpcode = data.asUByteArray()[5] + val packetData = ByteBuffer.wrap(data, HEADER_SIZE, size - 2) + handlePacket(opcode, subOpcode, packetData.order(ByteOrder.LITTLE_ENDIAN)) } - private fun handlePacket(opcode: UByte, data: ByteBuffer) { + private fun handlePacket(opcode: UByte, subOpcode: UByte, data: ByteBuffer) { when (opcode) { Opcode.PING.value -> { send(Opcode.PONG.value) @@ -302,7 +311,7 @@ class SyncSocketSession { } Opcode.NOTIFY_AUTHORIZED.value, Opcode.NOTIFY_UNAUTHORIZED.value -> { - _onData.invoke(this, opcode, data) + _onData.invoke(this, opcode, subOpcode, data) return } } @@ -316,8 +325,9 @@ class SyncSocketSession { val id = data.int val expectedSize = data.int val op = data.get().toUByte() + val subOp = data.get().toUByte() - val syncStream = SyncStream(expectedSize, op) + val syncStream = SyncStream(expectedSize, op, subOp) if (data.remaining() > 0) { syncStream.add(data.array(), data.position(), data.remaining()) } @@ -362,10 +372,13 @@ class SyncSocketSession { throw Exception("After sync stream end, the stream must be complete") } - handlePacket(syncStream.opcode, syncStream.getBytes().let { ByteBuffer.wrap(it).order(ByteOrder.LITTLE_ENDIAN) }) + handlePacket(syncStream.opcode, syncStream.subOpcode, syncStream.getBytes().let { ByteBuffer.wrap(it).order(ByteOrder.LITTLE_ENDIAN) }) + } + Opcode.DATA.value -> { + _onData.invoke(this, opcode, subOpcode, data) } else -> { - _onData.invoke(this, opcode, data) + Logger.w(TAG, "Unknown opcode received (opcode = ${opcode}, subOpcode = ${subOpcode})") } } } @@ -374,6 +387,6 @@ class SyncSocketSession { private const val TAG = "SyncSocketSession" const val MAXIMUM_PACKET_SIZE = 65535 - 16 const val MAXIMUM_PACKET_SIZE_ENCRYPTED = MAXIMUM_PACKET_SIZE + 16 - const val HEADER_SIZE = 5 + const val HEADER_SIZE = 6 } } \ No newline at end of file diff --git a/app/src/main/java/com/futo/platformplayer/sync/internal/SyncStream.kt b/app/src/main/java/com/futo/platformplayer/sync/internal/SyncStream.kt index 5a60e295..d558feef 100644 --- a/app/src/main/java/com/futo/platformplayer/sync/internal/SyncStream.kt +++ b/app/src/main/java/com/futo/platformplayer/sync/internal/SyncStream.kt @@ -1,6 +1,6 @@ package com.futo.platformplayer.sync.internal -class SyncStream(expectedSize: Int, val opcode: UByte) { +class SyncStream(expectedSize: Int, val opcode: UByte, val subOpcode: UByte) { companion object { const val MAXIMUM_SIZE = 10_000_000 } diff --git a/app/src/test/java/com/futo/platformplayer/NoiseProtocolTests.kt b/app/src/test/java/com/futo/platformplayer/NoiseProtocolTests.kt index 1597fd64..33b640f9 100644 --- a/app/src/test/java/com/futo/platformplayer/NoiseProtocolTests.kt +++ b/app/src/test/java/com/futo/platformplayer/NoiseProtocolTests.kt @@ -524,8 +524,8 @@ class NoiseProtocolTest { println("Initiator handshake complete") handshakeLatch.countDown() // Handshake complete for initiator }, - onData = { session, opcode, data -> - println("Initiator received: Opcode $opcode, Data Length: ${data.remaining()}") + onData = { session, opcode, subOpcode, data -> + println("Initiator received: Opcode: $opcode, SubOpcode: $subOpcode, Data Length: ${data.remaining()}") when (data.remaining()) { randomBytesExactlyOnePacket.remaining() -> { @@ -556,8 +556,8 @@ class NoiseProtocolTest { println("Responder handshake complete") handshakeLatch.countDown() // Handshake complete for responder }, - onData = { session, opcode, data -> - println("Responder received: Opcode $opcode, Data Length: ${data.remaining()}") + onData = { session, opcode, subOpcode, data -> + println("Responder received: Opcode $opcode, SubOpcode $subOpcode, Data Length: ${data.remaining()}") when (data.remaining()) { randomBytesExactlyOnePacket.remaining() -> { @@ -590,12 +590,12 @@ class NoiseProtocolTest { responderSession.send(SyncSocketSession.Opcode.PONG.value) // Test data transfer - responderSession.send(SyncSocketSession.Opcode.NOTIFY_AUTHORIZED.value, randomBytesExactlyOnePacket) - initiatorSession.send(SyncSocketSession.Opcode.NOTIFY_AUTHORIZED.value, randomBytes) + responderSession.send(SyncSocketSession.Opcode.DATA.value, 0u, randomBytesExactlyOnePacket) + initiatorSession.send(SyncSocketSession.Opcode.DATA.value, 1u, randomBytes) // Send large data to test stream handling val start = System.currentTimeMillis() - responderSession.send(SyncSocketSession.Opcode.NOTIFY_AUTHORIZED.value, randomBytesBig) + responderSession.send(SyncSocketSession.Opcode.DATA.value, 0u, randomBytesBig) println("Sent 10MB in ${System.currentTimeMillis() - start}ms") // Wait for a brief period to simulate delay and allow communication From 42cbbc28fdc1e15303b1db4b85658193d75c6d83 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zvonimir=20Zraki=C4=87?= Date: Mon, 18 Nov 2024 11:23:25 +0000 Subject: [PATCH 2/7] docs: Update CONTRIBUTION.md to reflect changes of accepting --- CONTRIBUTION.md | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/CONTRIBUTION.md b/CONTRIBUTION.md index 23cc959e..8af2e2f5 100644 --- a/CONTRIBUTION.md +++ b/CONTRIBUTION.md @@ -49,9 +49,23 @@ We encourage developers to write their own plugins. Please refer to the "Getting ## Contributing to Core -**We are currently not accepting contributions to the core.** -The core is currently licensed under the FUTO Temporary License (FTL). The licensing and ownership of contributions to the core are complex topics that we are still working on. We'll update these guidelines when we have more clarity. +### License + +The core is currently licensed under the [Source First License 1.1](./LICENSE.md). All contributors have to sign FUTO Individual Contributor License Agreement before contributions can be accepted. You can read more about it at [https://cla.futo.org/](https://cla.futo.org/). + +### How to Contribute + +1. Fork the core repository. +2. Clone your fork. +3. Make your changes. +4. Commit and push your changes. +5. Open a pull request. + +### Guidelines + +- Ensure your code adheres to the existing style. +- Include documentation and unit tests (where applicable). --- From 2d4af2e867eafd05e6c43a24b5b53d0c2ab15040 Mon Sep 17 00:00:00 2001 From: Koen J Date: Mon, 18 Nov 2024 12:35:40 +0100 Subject: [PATCH 3/7] Updated submodules. --- app/src/main/java/com/futo/platformplayer/Settings.kt | 2 +- app/src/stable/assets/sources/twitch | 2 +- app/src/stable/assets/sources/youtube | 2 +- app/src/unstable/assets/sources/twitch | 2 +- app/src/unstable/assets/sources/youtube | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/app/src/main/java/com/futo/platformplayer/Settings.kt b/app/src/main/java/com/futo/platformplayer/Settings.kt index d9a6e459..ff80acd3 100644 --- a/app/src/main/java/com/futo/platformplayer/Settings.kt +++ b/app/src/main/java/com/futo/platformplayer/Settings.kt @@ -929,7 +929,7 @@ class Settings : FragmentedStorageFileJson() { var enabled: Boolean = true; @FormField(R.string.broadcast, FieldForm.TOGGLE, R.string.broadcast_description, 1) - var broadcast: Boolean = true; + var broadcast: Boolean = false; @FormField(R.string.connect_discovered, FieldForm.TOGGLE, R.string.connect_discovered_description, 2) var connectDiscovered: Boolean = true; diff --git a/app/src/stable/assets/sources/twitch b/app/src/stable/assets/sources/twitch index 58ea7722..543a727d 160000 --- a/app/src/stable/assets/sources/twitch +++ b/app/src/stable/assets/sources/twitch @@ -1 +1 @@ -Subproject commit 58ea77229dcdb5c9ce8f1bd642baf29486d0bf21 +Subproject commit 543a727d781fe5780fd0e8f20d53f6a53b285446 diff --git a/app/src/stable/assets/sources/youtube b/app/src/stable/assets/sources/youtube index 80c9b4d3..0ce91be2 160000 --- a/app/src/stable/assets/sources/youtube +++ b/app/src/stable/assets/sources/youtube @@ -1 +1 @@ -Subproject commit 80c9b4d3b48739170b40b313be930329dcc59fe4 +Subproject commit 0ce91be276681ab82d26f9471523beab6b2a0a00 diff --git a/app/src/unstable/assets/sources/twitch b/app/src/unstable/assets/sources/twitch index 58ea7722..543a727d 160000 --- a/app/src/unstable/assets/sources/twitch +++ b/app/src/unstable/assets/sources/twitch @@ -1 +1 @@ -Subproject commit 58ea77229dcdb5c9ce8f1bd642baf29486d0bf21 +Subproject commit 543a727d781fe5780fd0e8f20d53f6a53b285446 diff --git a/app/src/unstable/assets/sources/youtube b/app/src/unstable/assets/sources/youtube index 80c9b4d3..0ce91be2 160000 --- a/app/src/unstable/assets/sources/youtube +++ b/app/src/unstable/assets/sources/youtube @@ -1 +1 @@ -Subproject commit 80c9b4d3b48739170b40b313be930329dcc59fe4 +Subproject commit 0ce91be276681ab82d26f9471523beab6b2a0a00 From 7cfa6c163f9f1f543a59185a3dd357c010fd2dac Mon Sep 17 00:00:00 2001 From: Koen J Date: Mon, 18 Nov 2024 12:48:02 +0100 Subject: [PATCH 4/7] Use SINGLE_TOP instead of CLEAR_TOP and do not start a new task for import data. --- app/src/main/java/com/futo/platformplayer/Settings.kt | 1 - .../com/futo/platformplayer/activities/MainActivity.kt | 8 ++++---- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/app/src/main/java/com/futo/platformplayer/Settings.kt b/app/src/main/java/com/futo/platformplayer/Settings.kt index ff80acd3..30d96683 100644 --- a/app/src/main/java/com/futo/platformplayer/Settings.kt +++ b/app/src/main/java/com/futo/platformplayer/Settings.kt @@ -150,7 +150,6 @@ class Settings : FragmentedStorageFileJson() { fun import() { val act = SettingsActivity.getActivity() ?: return; val intent = MainActivity.getImportOptionsIntent(act); - intent.flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK; act.startActivity(intent); } diff --git a/app/src/main/java/com/futo/platformplayer/activities/MainActivity.kt b/app/src/main/java/com/futo/platformplayer/activities/MainActivity.kt index e4efd6c6..3f6c38bd 100644 --- a/app/src/main/java/com/futo/platformplayer/activities/MainActivity.kt +++ b/app/src/main/java/com/futo/platformplayer/activities/MainActivity.kt @@ -1231,28 +1231,28 @@ class MainActivity : AppCompatActivity, IWithResultLauncher { val sourcesIntent = Intent(context, MainActivity::class.java); sourcesIntent.action = "TAB"; sourcesIntent.putExtra("TAB", tab); - sourcesIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); + sourcesIntent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP); return sourcesIntent; } fun getVideoIntent(context: Context, videoUrl: String) : Intent { val sourcesIntent = Intent(context, MainActivity::class.java); sourcesIntent.action = "VIDEO"; sourcesIntent.putExtra("VIDEO", videoUrl); - sourcesIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); + sourcesIntent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP); return sourcesIntent; } fun getActionIntent(context: Context, action: String) : Intent { val sourcesIntent = Intent(context, MainActivity::class.java); sourcesIntent.action = "ACTION"; sourcesIntent.putExtra("ACTION", action); - sourcesIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); + sourcesIntent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP); return sourcesIntent; } fun getImportOptionsIntent(context: Context): Intent { val sourcesIntent = Intent(context, MainActivity::class.java); sourcesIntent.action = "IMPORT_OPTIONS"; - sourcesIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); + sourcesIntent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP); return sourcesIntent; } } From 1c05b398619804a8765110020e477b9686fc32c2 Mon Sep 17 00:00:00 2001 From: zvonimir Date: Fri, 15 Nov 2024 23:29:09 +0100 Subject: [PATCH 5/7] feat: add android:contentDescription. Closes #1181 --- .../main/res/layout/activity_add_source.xml | 1 + .../layout/activity_add_source_options.xml | 1 + app/src/main/res/layout/activity_dev.xml | 1 + .../main/res/layout/activity_fcast_guide.xml | 1 + app/src/main/res/layout/activity_login.xml | 1 + app/src/main/res/layout/activity_main.xml | 1 + .../main/res/layout/activity_manage_tabs.xml | 1 + .../layout/activity_polycentric_backup.xml | 2 + .../activity_polycentric_create_profile.xml | 2 + .../res/layout/activity_polycentric_home.xml | 2 + .../activity_polycentric_import_profile.xml | 2 + .../layout/activity_polycentric_profile.xml | 3 + .../res/layout/activity_polycentric_why.xml | 1 + app/src/main/res/layout/activity_settings.xml | 1 + .../main/res/layout/activity_sync_home.xml | 1 + .../main/res/layout/activity_sync_pair.xml | 1 + .../activity_sync_show_pairing_code.xml | 1 + .../res/layout/dialog_automatic_backup.xml | 1 + .../res/layout/dialog_casting_connect.xml | 2 + .../res/layout/dialog_casting_connected.xml | 6 ++ app/src/main/res/layout/dialog_update.xml | 1 + .../main/res/layout/fragment_add_top_bar.xml | 3 + app/src/main/res/layout/fragment_channel.xml | 3 + .../res/layout/fragment_channel_about.xml | 1 + app/src/main/res/layout/fragment_creators.xml | 1 + app/src/main/res/layout/fragment_history.xml | 2 + .../res/layout/fragment_import_top_bar.xml | 1 + .../layout/fragment_navigation_top_bar.xml | 2 + .../res/layout/fragment_overview_top_bar.xml | 3 + .../main/res/layout/fragment_playlists.xml | 2 + .../res/layout/fragment_remote_playlist.xml | 1 + .../res/layout/fragment_search_top_bar.xml | 4 ++ .../layout/fragment_subscriptions_group.xml | 5 ++ .../res/layout/fragment_video_list_editor.xml | 3 + .../main/res/layout/fragview_post_detail.xml | 6 +- .../main/res/layout/fragview_video_detail.xml | 6 +- .../main/res/layout/list_chat_donation.xml | 1 + app/src/main/res/layout/list_comment.xml | 3 + .../layout/list_comment_with_reference.xml | 2 + app/src/main/res/layout/list_creator.xml | 2 + app/src/main/res/layout/list_device.xml | 2 + app/src/main/res/layout/list_donation.xml | 1 + app/src/main/res/layout/list_history.xml | 1 + .../res/layout/list_import_subscription.xml | 3 +- .../main/res/layout/list_locked_preview.xml | 2 + .../main/res/layout/list_locked_thumbnail.xml | 1 + app/src/main/res/layout/list_playlist.xml | 3 + .../main/res/layout/list_playlist_feed.xml | 1 + .../res/layout/list_playlist_feed_preview.xml | 2 + app/src/main/res/layout/list_playlists.xml | 1 + app/src/main/res/layout/list_post_preview.xml | 4 ++ .../main/res/layout/list_post_thumbnail.xml | 1 + .../res/layout/list_source_construction.xml | 1 + .../main/res/layout/list_source_disabled.xml | 1 + .../main/res/layout/list_source_enabled.xml | 2 + app/src/main/res/layout/list_subscription.xml | 6 +- .../res/layout/list_subscription_group.xml | 3 + app/src/main/res/layout/list_tab.xml | 1 + .../main/res/layout/list_video_preview.xml | 4 ++ .../res/layout/list_video_preview_nested.xml | 5 ++ .../main/res/layout/list_video_thumbnail.xml | 3 + .../layout/list_video_thumbnail_nested.xml | 4 ++ app/src/main/res/layout/overlay_livechat.xml | 4 ++ app/src/main/res/layout/overlay_topbar.xml | 1 + .../main/res/layout/thumbnail_player_ui.xml | 1 + app/src/main/res/layout/video_player_ui.xml | 9 +++ .../res/layout/video_player_ui_fullscreen.xml | 9 +++ app/src/main/res/values/strings.xml | 58 +++++++++++++++++++ 68 files changed, 214 insertions(+), 4 deletions(-) diff --git a/app/src/main/res/layout/activity_add_source.xml b/app/src/main/res/layout/activity_add_source.xml index 9adf25ed..469a4508 100644 --- a/app/src/main/res/layout/activity_add_source.xml +++ b/app/src/main/res/layout/activity_add_source.xml @@ -22,6 +22,7 @@ android:id="@+id/button_back" android:layout_width="wrap_content" android:layout_height="match_parent" + android:contentDescription="@string/cd_button_back" android:paddingRight="20dp" app:srcCompat="@drawable/ic_back_thin_white_16dp" /> diff --git a/app/src/main/res/layout/activity_add_source_options.xml b/app/src/main/res/layout/activity_add_source_options.xml index 28752940..541d489d 100644 --- a/app/src/main/res/layout/activity_add_source_options.xml +++ b/app/src/main/res/layout/activity_add_source_options.xml @@ -22,6 +22,7 @@ android:id="@+id/button_back" android:layout_width="wrap_content" android:layout_height="match_parent" + android:contentDescription="@string/cd_button_back" android:paddingRight="20dp" app:srcCompat="@drawable/ic_back_thin_white_16dp" /> diff --git a/app/src/main/res/layout/activity_dev.xml b/app/src/main/res/layout/activity_dev.xml index 1780ede6..c1caef04 100644 --- a/app/src/main/res/layout/activity_dev.xml +++ b/app/src/main/res/layout/activity_dev.xml @@ -22,6 +22,7 @@ android:id="@+id/button_back" android:layout_width="wrap_content" android:layout_height="match_parent" + android:contentDescription="@string/cd_button_back" android:paddingRight="20dp" app:srcCompat="@drawable/ic_back_thin_white_16dp" /> diff --git a/app/src/main/res/layout/activity_fcast_guide.xml b/app/src/main/res/layout/activity_fcast_guide.xml index 4d6a2b89..5ccd0fa7 100644 --- a/app/src/main/res/layout/activity_fcast_guide.xml +++ b/app/src/main/res/layout/activity_fcast_guide.xml @@ -10,6 +10,7 @@ android:id="@+id/button_back" android:layout_width="50dp" android:layout_height="50dp" + android:contentDescription="@string/cd_button_back" android:padding="10dp" android:scaleType="fitCenter" app:srcCompat="@drawable/ic_back_thin_white_16dp" diff --git a/app/src/main/res/layout/activity_login.xml b/app/src/main/res/layout/activity_login.xml index fd35ed06..6f8fe755 100644 --- a/app/src/main/res/layout/activity_login.xml +++ b/app/src/main/res/layout/activity_login.xml @@ -14,6 +14,7 @@ android:id="@+id/button_close" android:layout_width="50dp" android:layout_height="50dp" + android:contentDescription="@string/cd_button_close" android:scaleType="fitCenter" android:padding="10dp" app:layout_constraintLeft_toLeftOf="parent" diff --git a/app/src/main/res/layout/activity_main.xml b/app/src/main/res/layout/activity_main.xml index 34f54a1f..1708eeb4 100644 --- a/app/src/main/res/layout/activity_main.xml +++ b/app/src/main/res/layout/activity_main.xml @@ -75,6 +75,7 @@ android:id="@+id/incognito_button" android:layout_width="50dp" android:layout_height="50dp" + android:contentDescription="@string/cd_incognito_button" android:src="@drawable/ic_disabled_visible_purple" android:background="@drawable/background_button_round_black" android:scaleType="fitCenter" diff --git a/app/src/main/res/layout/activity_manage_tabs.xml b/app/src/main/res/layout/activity_manage_tabs.xml index 7a4a1e1f..986dfa11 100644 --- a/app/src/main/res/layout/activity_manage_tabs.xml +++ b/app/src/main/res/layout/activity_manage_tabs.xml @@ -21,6 +21,7 @@ android:id="@+id/button_back" android:layout_width="wrap_content" android:layout_height="match_parent" + android:contentDescription="@string/cd_button_back" android:paddingRight="20dp" app:srcCompat="@drawable/ic_back_thin_white_16dp" /> diff --git a/app/src/main/res/layout/activity_polycentric_backup.xml b/app/src/main/res/layout/activity_polycentric_backup.xml index 3f437667..e31e8584 100644 --- a/app/src/main/res/layout/activity_polycentric_backup.xml +++ b/app/src/main/res/layout/activity_polycentric_backup.xml @@ -9,6 +9,7 @@ android:id="@+id/button_back" android:layout_width="50dp" android:layout_height="50dp" + android:contentDescription="@string/cd_button_back" android:padding="10dp" android:scaleType="fitCenter" app:srcCompat="@drawable/ic_back_thin_white_16dp" @@ -19,6 +20,7 @@ android:id="@+id/button_help" android:layout_width="wrap_content" android:layout_height="wrap_content" + android:contentDescription="@string/cd_button_help" app:srcCompat="@drawable/ic_help" app:layout_constraintRight_toRightOf="parent" app:layout_constraintTop_toTopOf="parent" /> diff --git a/app/src/main/res/layout/activity_polycentric_create_profile.xml b/app/src/main/res/layout/activity_polycentric_create_profile.xml index 787e3efd..198488fd 100644 --- a/app/src/main/res/layout/activity_polycentric_create_profile.xml +++ b/app/src/main/res/layout/activity_polycentric_create_profile.xml @@ -9,6 +9,7 @@ android:id="@+id/button_back" android:layout_width="50dp" android:layout_height="50dp" + android:contentDescription="@string/cd_button_back" android:padding="10dp" android:scaleType="fitCenter" app:srcCompat="@drawable/ic_back_thin_white_16dp" @@ -19,6 +20,7 @@ android:id="@+id/button_help" android:layout_width="50dp" android:layout_height="50dp" + android:contentDescription="@string/cd_button_help" app:srcCompat="@drawable/ic_help" app:layout_constraintRight_toRightOf="parent" app:layout_constraintTop_toTopOf="parent" /> diff --git a/app/src/main/res/layout/activity_polycentric_home.xml b/app/src/main/res/layout/activity_polycentric_home.xml index 36e206cd..a948d54b 100644 --- a/app/src/main/res/layout/activity_polycentric_home.xml +++ b/app/src/main/res/layout/activity_polycentric_home.xml @@ -9,6 +9,7 @@ android:id="@+id/button_back" android:layout_width="50dp" android:layout_height="50dp" + android:contentDescription="@string/cd_button_back" android:padding="10dp" android:scaleType="fitCenter" app:srcCompat="@drawable/ic_back_thin_white_16dp" @@ -19,6 +20,7 @@ android:id="@+id/button_help" android:layout_width="wrap_content" android:layout_height="wrap_content" + android:contentDescription="@string/cd_button_help" app:srcCompat="@drawable/ic_help" app:layout_constraintRight_toRightOf="parent" app:layout_constraintTop_toTopOf="parent" /> diff --git a/app/src/main/res/layout/activity_polycentric_import_profile.xml b/app/src/main/res/layout/activity_polycentric_import_profile.xml index 992395cf..b7013f40 100644 --- a/app/src/main/res/layout/activity_polycentric_import_profile.xml +++ b/app/src/main/res/layout/activity_polycentric_import_profile.xml @@ -9,6 +9,7 @@ android:id="@+id/button_back" android:layout_width="50dp" android:layout_height="50dp" + android:contentDescription="@string/cd_button_back" android:padding="10dp" android:scaleType="fitCenter" app:srcCompat="@drawable/ic_back_thin_white_16dp" @@ -19,6 +20,7 @@ android:id="@+id/button_help" android:layout_width="50dp" android:layout_height="50dp" + android:contentDescription="@string/cd_button_help" app:srcCompat="@drawable/ic_help" app:layout_constraintRight_toRightOf="parent" app:layout_constraintTop_toTopOf="parent" /> diff --git a/app/src/main/res/layout/activity_polycentric_profile.xml b/app/src/main/res/layout/activity_polycentric_profile.xml index e4b81d5d..d9266fd0 100644 --- a/app/src/main/res/layout/activity_polycentric_profile.xml +++ b/app/src/main/res/layout/activity_polycentric_profile.xml @@ -10,6 +10,7 @@ android:id="@+id/button_back" android:layout_width="50dp" android:layout_height="50dp" + android:contentDescription="@string/cd_button_back" android:padding="10dp" android:scaleType="fitCenter" app:srcCompat="@drawable/ic_back_thin_white_16dp" @@ -20,6 +21,7 @@ android:id="@+id/button_help" android:layout_width="wrap_content" android:layout_height="wrap_content" + android:contentDescription="@string/cd_button_help" app:srcCompat="@drawable/ic_help" app:layout_constraintRight_toRightOf="parent" app:layout_constraintTop_toTopOf="parent" /> @@ -28,6 +30,7 @@ android:id="@+id/image_polycentric" android:layout_height="80dp" android:layout_width="80dp" + android:contentDescription="@string/cd_image_polycentric" android:scaleType="centerCrop" app:shapeAppearanceOverlay="@style/roundedCorners_40dp" app:srcCompat="@drawable/placeholder_profile" diff --git a/app/src/main/res/layout/activity_polycentric_why.xml b/app/src/main/res/layout/activity_polycentric_why.xml index 1f4a8872..63d8f19c 100644 --- a/app/src/main/res/layout/activity_polycentric_why.xml +++ b/app/src/main/res/layout/activity_polycentric_why.xml @@ -10,6 +10,7 @@ android:id="@+id/button_back" android:layout_width="50dp" android:layout_height="50dp" + android:contentDescription="@string/cd_button_back" android:padding="10dp" android:scaleType="fitCenter" app:srcCompat="@drawable/ic_back_thin_white_16dp" diff --git a/app/src/main/res/layout/activity_settings.xml b/app/src/main/res/layout/activity_settings.xml index b0bf134b..0c815387 100644 --- a/app/src/main/res/layout/activity_settings.xml +++ b/app/src/main/res/layout/activity_settings.xml @@ -24,6 +24,7 @@ android:id="@+id/button_back" android:layout_width="wrap_content" android:layout_height="match_parent" + android:contentDescription="@string/cd_button_back" android:paddingRight="20dp" app:srcCompat="@drawable/ic_back_thin_white_16dp" /> diff --git a/app/src/main/res/layout/activity_sync_home.xml b/app/src/main/res/layout/activity_sync_home.xml index 6cb4872c..0f353fb4 100644 --- a/app/src/main/res/layout/activity_sync_home.xml +++ b/app/src/main/res/layout/activity_sync_home.xml @@ -10,6 +10,7 @@ android:id="@+id/button_back" android:layout_width="50dp" android:layout_height="50dp" + android:contentDescription="@string/cd_button_back" android:padding="10dp" android:scaleType="fitCenter" app:srcCompat="@drawable/ic_back_thin_white_16dp" diff --git a/app/src/main/res/layout/activity_sync_pair.xml b/app/src/main/res/layout/activity_sync_pair.xml index e95f324b..e5355ecc 100644 --- a/app/src/main/res/layout/activity_sync_pair.xml +++ b/app/src/main/res/layout/activity_sync_pair.xml @@ -10,6 +10,7 @@ android:id="@+id/button_back" android:layout_width="50dp" android:layout_height="50dp" + android:contentDescription="@string/cd_button_back" android:padding="10dp" android:scaleType="fitCenter" app:srcCompat="@drawable/ic_back_thin_white_16dp" diff --git a/app/src/main/res/layout/activity_sync_show_pairing_code.xml b/app/src/main/res/layout/activity_sync_show_pairing_code.xml index a7d5631a..4d92980a 100644 --- a/app/src/main/res/layout/activity_sync_show_pairing_code.xml +++ b/app/src/main/res/layout/activity_sync_show_pairing_code.xml @@ -14,6 +14,7 @@ android:id="@+id/button_back" android:layout_width="50dp" android:layout_height="50dp" + android:contentDescription="@string/cd_button_back" android:padding="10dp" android:scaleType="fitCenter" app:srcCompat="@drawable/ic_back_thin_white_16dp" diff --git a/app/src/main/res/layout/dialog_automatic_backup.xml b/app/src/main/res/layout/dialog_automatic_backup.xml index 1f570c4b..bfa7c0f6 100644 --- a/app/src/main/res/layout/dialog_automatic_backup.xml +++ b/app/src/main/res/layout/dialog_automatic_backup.xml @@ -27,6 +27,7 @@ android:id="@+id/button_cancel" android:layout_width="20dp" android:layout_height="20dp" + android:contentDescription="@string/cd_button_close" app:srcCompat="@drawable/ic_close_thin" app:tint="#888888" android:layout_marginEnd="30dp" /> diff --git a/app/src/main/res/layout/dialog_casting_connect.xml b/app/src/main/res/layout/dialog_casting_connect.xml index 24777828..e76b8c65 100644 --- a/app/src/main/res/layout/dialog_casting_connect.xml +++ b/app/src/main/res/layout/dialog_casting_connect.xml @@ -97,6 +97,7 @@ android:id="@+id/button_scan_qr" android:layout_width="40dp" android:layout_height="40dp" + android:contentDescription="@string/cd_button_scan_qr" android:scaleType="centerCrop" app:srcCompat="@drawable/ic_qr" app:tint="@color/primary" /> @@ -109,6 +110,7 @@ android:id="@+id/button_add" android:layout_width="40dp" android:layout_height="40dp" + android:contentDescription="@string/cd_button_add" android:scaleType="centerCrop" app:srcCompat="@drawable/ic_add" app:tint="@color/primary" diff --git a/app/src/main/res/layout/dialog_casting_connected.xml b/app/src/main/res/layout/dialog_casting_connected.xml index 8b593e9d..027db929 100644 --- a/app/src/main/res/layout/dialog_casting_connected.xml +++ b/app/src/main/res/layout/dialog_casting_connected.xml @@ -58,6 +58,7 @@ android:id="@+id/image_device" android:layout_width="25dp" android:layout_height="25dp" + android:contentDescription="@string/cd_image_device" app:srcCompat="@drawable/ic_chromecast" android:scaleType="fitCenter" app:layout_constraintLeft_toLeftOf="parent" @@ -197,6 +198,7 @@ android:id="@id/button_previous" android:layout_width="60dp" android:layout_height="60dp" + android:contentDescription="@string/cd_button_previous" android:scaleType="centerCrop" android:clickable="true" android:padding="10dp" @@ -206,6 +208,7 @@ android:id="@+id/button_play" android:layout_width="60dp" android:layout_height="60dp" + android:contentDescription="@string/cd_button_play" android:padding="20dp" android:scaleType="fitCenter" android:clickable="true" @@ -215,6 +218,7 @@ android:id="@+id/button_pause" android:layout_width="60dp" android:layout_height="60dp" + android:contentDescription="@string/cd_button_pause" android:padding="10dp" android:scaleType="fitCenter" android:clickable="true" @@ -224,6 +228,7 @@ android:id="@+id/button_stop" android:layout_width="60dp" android:layout_height="60dp" + android:contentDescription="@string/cd_button_stop" android:scaleType="fitCenter" android:padding="5dp" android:clickable="true" @@ -233,6 +238,7 @@ android:id="@id/button_next" android:layout_width="60dp" android:layout_height="60dp" + android:contentDescription="@string/cd_button_next" android:clickable="true" android:scaleType="centerCrop" android:padding="10dp" diff --git a/app/src/main/res/layout/dialog_update.xml b/app/src/main/res/layout/dialog_update.xml index 051a604c..9dceccd4 100644 --- a/app/src/main/res/layout/dialog_update.xml +++ b/app/src/main/res/layout/dialog_update.xml @@ -23,6 +23,7 @@ android:id="@+id/update_spinner" android:layout_width="100dp" android:layout_height="100dp" + android:contentDescription="@string/cd_update_spinner" app:srcCompat="@drawable/ic_update_animated" /> diff --git a/app/src/main/res/layout/fragment_navigation_top_bar.xml b/app/src/main/res/layout/fragment_navigation_top_bar.xml index ab8d8f87..f7317f6a 100644 --- a/app/src/main/res/layout/fragment_navigation_top_bar.xml +++ b/app/src/main/res/layout/fragment_navigation_top_bar.xml @@ -11,6 +11,7 @@ android:id="@+id/button_back" android:layout_width="wrap_content" android:layout_height="match_parent" + android:contentDescription="@string/cd_button_back" android:paddingLeft="16dp" android:paddingRight="8dp" app:srcCompat="@drawable/ic_back_nav" /> @@ -34,6 +35,7 @@ android:id="@+id/button_cast" android:layout_width="wrap_content" android:layout_height="match_parent" + android:contentDescription="@string/cd_cast_button" android:paddingStart="4dp" android:paddingEnd="4dp" android:paddingTop="9dp" diff --git a/app/src/main/res/layout/fragment_overview_top_bar.xml b/app/src/main/res/layout/fragment_overview_top_bar.xml index c87619bf..1fe9e047 100644 --- a/app/src/main/res/layout/fragment_overview_top_bar.xml +++ b/app/src/main/res/layout/fragment_overview_top_bar.xml @@ -10,6 +10,7 @@ android:id="@+id/app_icon" android:layout_width="35dp" android:layout_height="35dp" + android:contentDescription="@string/cd_app_icon" android:layout_marginStart="16dp" android:layout_marginEnd="4dp" android:scaleType="fitCenter" @@ -37,6 +38,7 @@ android:id="@+id/button_cast" android:layout_width="wrap_content" android:layout_height="match_parent" + android:contentDescription="@string/cd_cast_button" android:paddingStart="16dp" android:paddingEnd="12dp" android:paddingTop="12dp" @@ -49,6 +51,7 @@ android:id="@+id/button_search" android:layout_width="wrap_content" android:layout_height="match_parent" + android:contentDescription="@string/cd_button_search" android:paddingStart="5dp" android:paddingEnd="12dp" android:paddingTop="11dp" diff --git a/app/src/main/res/layout/fragment_playlists.xml b/app/src/main/res/layout/fragment_playlists.xml index b86cfe68..cd2050b6 100644 --- a/app/src/main/res/layout/fragment_playlists.xml +++ b/app/src/main/res/layout/fragment_playlists.xml @@ -34,6 +34,7 @@ android:id="@+id/image_history" android:layout_width="wrap_content" android:layout_height="wrap_content" + android:contentDescription="@string/cd_icon_history" app:srcCompat="@drawable/ic_clock_white" app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintTop_toTopOf="parent" @@ -119,6 +120,7 @@ android:id="@+id/button_create_playlist" android:layout_width="35dp" android:layout_height="20dp" + android:contentDescription="@string/cd_button_create_playlist" app:srcCompat="@drawable/ic_add_white_16dp" android:paddingEnd="15dp" android:paddingStart="15dp" diff --git a/app/src/main/res/layout/fragment_remote_playlist.xml b/app/src/main/res/layout/fragment_remote_playlist.xml index bee1f714..42b38fb5 100644 --- a/app/src/main/res/layout/fragment_remote_playlist.xml +++ b/app/src/main/res/layout/fragment_remote_playlist.xml @@ -58,6 +58,7 @@ android:id="@+id/button_share" android:layout_width="40dp" android:layout_height="40dp" + android:contentDescription="@string/cd_button_share" android:background="@drawable/background_button_round" android:gravity="center" android:layout_marginStart="5dp" diff --git a/app/src/main/res/layout/fragment_search_top_bar.xml b/app/src/main/res/layout/fragment_search_top_bar.xml index f4b64615..277eb133 100644 --- a/app/src/main/res/layout/fragment_search_top_bar.xml +++ b/app/src/main/res/layout/fragment_search_top_bar.xml @@ -13,6 +13,7 @@ android:id="@+id/button_back" android:layout_width="wrap_content" android:layout_height="match_parent" + android:contentDescription="@string/cd_button_back" android:paddingLeft="16dp" android:paddingRight="16dp" app:srcCompat="@drawable/ic_back_white_24dp" /> @@ -27,6 +28,7 @@ android:id="@+id/edit_search" android:layout_width="fill_parent" android:layout_height="wrap_content" + android:hint="Search" android:layout_weight="1" android:inputType="text" android:imeOptions="actionDone" @@ -37,6 +39,7 @@ android:id="@+id/button_clear_search" android:layout_width="wrap_content" android:layout_height="match_parent" + android:contentDescription="@string/cd_button_clear_search" android:paddingStart="18dp" android:paddingEnd="18dp" android:layout_gravity="right|center_vertical" @@ -48,6 +51,7 @@ android:id="@+id/button_filter" android:layout_width="wrap_content" android:layout_height="match_parent" + android:contentDescription="@string/cd_button_filter" android:paddingStart="8dp" android:paddingEnd="8dp" android:scaleType="fitCenter" diff --git a/app/src/main/res/layout/fragment_subscriptions_group.xml b/app/src/main/res/layout/fragment_subscriptions_group.xml index a26789cc..31c8d5fa 100644 --- a/app/src/main/res/layout/fragment_subscriptions_group.xml +++ b/app/src/main/res/layout/fragment_subscriptions_group.xml @@ -43,6 +43,7 @@ android:id="@+id/button_delete" android:layout_width="50dp" android:layout_height="50dp" + android:contentDescription="@string/cd_button_delete" android:layout_marginLeft="5dp" android:layout_marginRight="0dp" android:src="@drawable/ic_trash" @@ -56,6 +57,7 @@ android:id="@+id/button_settings" android:layout_width="50dp" android:layout_height="50dp" + android:contentDescription="@string/cd_button_settings" android:layout_marginLeft="5dp" android:layout_marginRight="5dp" android:src="@drawable/ic_settings" @@ -69,6 +71,7 @@ android:id="@+id/image_group" android:layout_width="110dp" android:layout_height="70dp" + android:contentDescription="@string/cd_image_group" android:adjustViewBounds="true" app:circularflow_defaultRadius="10dp" android:layout_marginLeft="30dp" @@ -90,6 +93,7 @@ + android:layout_height="27dp" + android:contentDescription="@string/cd_creator_thumbnail" /> @@ -285,6 +288,7 @@ android:id="@+id/button_share" android:layout_width="32dp" android:layout_height="32dp" + android:contentDescription="@string/cd_button_share" android:background="@drawable/background_button_round" android:gravity="center" android:layout_marginStart="5dp" diff --git a/app/src/main/res/layout/fragview_video_detail.xml b/app/src/main/res/layout/fragview_video_detail.xml index 71ad3869..d5062c06 100644 --- a/app/src/main/res/layout/fragview_video_detail.xml +++ b/app/src/main/res/layout/fragview_video_detail.xml @@ -103,6 +103,7 @@ android:id="@+id/minimize_play" android:layout_width="40dp" android:layout_height="40dp" + android:contentDescription="@string/cd_minimize_play" android:padding="10dp" android:clickable="true" android:scaleType="fitCenter" @@ -111,6 +112,7 @@ android:id="@+id/minimize_pause" android:layout_width="40dp" android:layout_height="40dp" + android:contentDescription="@string/cd_minimize_pause" android:padding="5dp" android:scaleType="fitCenter" android:clickable="true" @@ -119,6 +121,7 @@ android:id="@+id/minimize_close" android:layout_width="40dp" android:layout_height="40dp" + android:contentDescription="@string/cd_minimize_close" android:padding="5dp" android:scaleType="fitCenter" android:layout_marginStart="2dp" @@ -337,7 +340,8 @@ + android:layout_height="35dp" + android:contentDescription="@string/cd_creator_thumbnail" /> diff --git a/app/src/main/res/layout/list_comment.xml b/app/src/main/res/layout/list_comment.xml index 2141bf7f..ea2c861a 100644 --- a/app/src/main/res/layout/list_comment.xml +++ b/app/src/main/res/layout/list_comment.xml @@ -100,6 +100,7 @@ android:id="@+id/image_like_icon" android:layout_width="18dp" android:layout_height="18dp" + android:contentDescription="@string/cd_image_like_icon" app:srcCompat="@drawable/ic_thumb_up" /> @@ -134,6 +136,7 @@ android:id="@+id/button_replies" android:layout_width="wrap_content" android:layout_height="wrap_content" + android:contentDescription="@string/cd_button_replies" app:pillIcon="@drawable/ic_forum" app:pillText="55 Replies" android:layout_marginStart="15dp" /> diff --git a/app/src/main/res/layout/list_comment_with_reference.xml b/app/src/main/res/layout/list_comment_with_reference.xml index 2e828255..73d53a3f 100644 --- a/app/src/main/res/layout/list_comment_with_reference.xml +++ b/app/src/main/res/layout/list_comment_with_reference.xml @@ -91,6 +91,7 @@ android:id="@+id/button_replies" android:layout_width="wrap_content" android:layout_height="wrap_content" + android:contentDescription="@string/cd_button_replies" app:pillIcon="@drawable/ic_forum" app:pillText="55 Replies" android:layout_marginStart="15dp" /> @@ -112,6 +113,7 @@ android:id="@+id/pill_text" android:layout_width="wrap_content" android:layout_height="match_parent" + android:contentDescription="@string/cd_button_delete" android:textColor="@color/white" android:textSize="13dp" android:gravity="center_vertical" diff --git a/app/src/main/res/layout/list_creator.xml b/app/src/main/res/layout/list_creator.xml index d14ad856..5237ccd9 100644 --- a/app/src/main/res/layout/list_creator.xml +++ b/app/src/main/res/layout/list_creator.xml @@ -56,6 +56,7 @@ android:id="@+id/button_subscribe" android:layout_width="wrap_content" android:layout_height="wrap_content" + android:contentDescription="@string/cd_button_subscribe" android:layout_marginTop="10dp" app:layout_constraintTop_toBottomOf="@id/text_channel_metadata" app:layout_constraintLeft_toLeftOf="parent" @@ -65,6 +66,7 @@ android:id="@+id/platform_indicator" android:layout_width="24dp" android:layout_height="24dp" + android:contentDescription="@string/cd_platform_indicator" android:layout_marginTop="18dp" app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintRight_toRightOf="parent" diff --git a/app/src/main/res/layout/list_device.xml b/app/src/main/res/layout/list_device.xml index 874adba9..534a9f2f 100644 --- a/app/src/main/res/layout/list_device.xml +++ b/app/src/main/res/layout/list_device.xml @@ -10,6 +10,7 @@ android:id="@+id/image_device" android:layout_width="25dp" android:layout_height="25dp" + android:contentDescription="@string/cd_image_device" app:srcCompat="@drawable/ic_chromecast" android:scaleType="fitCenter" app:layout_constraintLeft_toLeftOf="parent" @@ -63,6 +64,7 @@ android:id="@+id/image_loader" android:layout_width="25dp" android:layout_height="25dp" + android:contentDescription="@string/cd_image_loader" app:srcCompat="@drawable/ic_loader_animated" android:layout_marginEnd="8dp"/> diff --git a/app/src/main/res/layout/list_donation.xml b/app/src/main/res/layout/list_donation.xml index 921cd87a..cf0a05f1 100644 --- a/app/src/main/res/layout/list_donation.xml +++ b/app/src/main/res/layout/list_donation.xml @@ -20,6 +20,7 @@ android:id="@+id/donation_author_image" android:layout_width="20dp" android:layout_height="20dp" + android:contentDescription="@string/cd_donation_author_image" app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintTop_toTopOf="parent" app:layout_constraintBottom_toBottomOf="parent" diff --git a/app/src/main/res/layout/list_history.xml b/app/src/main/res/layout/list_history.xml index ec1d943c..88a10b81 100644 --- a/app/src/main/res/layout/list_history.xml +++ b/app/src/main/res/layout/list_history.xml @@ -173,6 +173,7 @@ android:id="@+id/image_trash" android:layout_width="40dp" android:layout_height="40dp" + android:contentDescription="@string/cd_button_delete" app:srcCompat="@drawable/ic_trash_18dp" android:scaleType="fitCenter" android:paddingTop="10dp" diff --git a/app/src/main/res/layout/list_import_subscription.xml b/app/src/main/res/layout/list_import_subscription.xml index 15424fc3..9d30ead2 100644 --- a/app/src/main/res/layout/list_import_subscription.xml +++ b/app/src/main/res/layout/list_import_subscription.xml @@ -45,7 +45,8 @@ + android:layout_height="25dp" + android:contentDescription="@string/cd_platform_indicator" /> \ No newline at end of file diff --git a/app/src/main/res/layout/list_locked_preview.xml b/app/src/main/res/layout/list_locked_preview.xml index 59cb602a..2413c98c 100644 --- a/app/src/main/res/layout/list_locked_preview.xml +++ b/app/src/main/res/layout/list_locked_preview.xml @@ -194,6 +194,7 @@ android:id="@+id/creator_thumbnail" android:layout_width="32dp" android:layout_height="32dp" + android:contentDescription="@string/cd_creator_thumbnail" app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintTop_toTopOf="parent" android:layout_marginStart="10dp" @@ -272,6 +273,7 @@ android:id="@+id/thumbnail_platform" android:layout_width="25dp" android:layout_height="25dp" + android:contentDescription="@string/cd_platform_indicator" android:scaleType="centerInside" tools:src="@drawable/ic_peertube"/> diff --git a/app/src/main/res/layout/list_locked_thumbnail.xml b/app/src/main/res/layout/list_locked_thumbnail.xml index f5fe8a57..462d65d4 100644 --- a/app/src/main/res/layout/list_locked_thumbnail.xml +++ b/app/src/main/res/layout/list_locked_thumbnail.xml @@ -306,6 +306,7 @@ android:id="@+id/thumbnail_platform" android:layout_width="20dp" android:layout_height="20dp" + android:contentDescription="@string/cd_platform_indicator" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintRight_toRightOf="parent" android:layout_margin="4dp" /> diff --git a/app/src/main/res/layout/list_playlist.xml b/app/src/main/res/layout/list_playlist.xml index 3a46a6be..d51cdfc5 100644 --- a/app/src/main/res/layout/list_playlist.xml +++ b/app/src/main/res/layout/list_playlist.xml @@ -14,6 +14,7 @@ android:id="@+id/image_drag_drop" android:layout_width="40dp" android:layout_height="40dp" + android:contentDescription="@string/cd_drag_drop" app:srcCompat="@drawable/ic_dragdrop_white" android:scaleType="fitCenter" android:paddingTop="10dp" @@ -116,6 +117,7 @@ android:layout_width="match_parent" android:layout_height="match_parent" android:scaleType="fitXY" + android:contentDescription="@string/cd_download_indicator" app:srcCompat="@drawable/download_for_offline" /> @@ -174,6 +176,7 @@ android:id="@+id/image_trash" android:layout_width="40dp" android:layout_height="40dp" + android:contentDescription="@string/cd_button_delete" app:srcCompat="@drawable/ic_trash_18dp" android:scaleType="fitCenter" android:paddingTop="10dp" diff --git a/app/src/main/res/layout/list_playlist_feed.xml b/app/src/main/res/layout/list_playlist_feed.xml index f2f30845..14a01d39 100644 --- a/app/src/main/res/layout/list_playlist_feed.xml +++ b/app/src/main/res/layout/list_playlist_feed.xml @@ -41,6 +41,7 @@ android:id="@+id/thumbnail_platform" android:layout_width="20dp" android:layout_height="20dp" + android:contentDescription="@string/cd_platform_indicator" android:layout_alignParentStart="true" android:layout_alignParentBottom="true" android:layout_gravity="end" diff --git a/app/src/main/res/layout/list_playlist_feed_preview.xml b/app/src/main/res/layout/list_playlist_feed_preview.xml index 6ce90101..6be094b0 100644 --- a/app/src/main/res/layout/list_playlist_feed_preview.xml +++ b/app/src/main/res/layout/list_playlist_feed_preview.xml @@ -108,6 +108,7 @@ android:id="@+id/creator_thumbnail" android:layout_width="32dp" android:layout_height="32dp" + android:contentDescription="@string/cd_creator_thumbnail" app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintTop_toTopOf="parent" android:layout_marginStart="10dp" @@ -161,6 +162,7 @@ android:id="@+id/thumbnail_platform" android:layout_width="25dp" android:layout_height="25dp" + android:contentDescription="@string/cd_platform_indicator" android:scaleType="centerInside" /> diff --git a/app/src/main/res/layout/list_playlists.xml b/app/src/main/res/layout/list_playlists.xml index 52ada168..a180d134 100644 --- a/app/src/main/res/layout/list_playlists.xml +++ b/app/src/main/res/layout/list_playlists.xml @@ -72,6 +72,7 @@ android:id="@+id/button_trash" android:layout_width="50dp" android:layout_height="50dp" + android:contentDescription="@string/cd_button_delete" app:srcCompat="@drawable/ic_trash" android:padding="10dp" android:scaleType="fitCenter" diff --git a/app/src/main/res/layout/list_post_preview.xml b/app/src/main/res/layout/list_post_preview.xml index e298fd88..3eb61c55 100644 --- a/app/src/main/res/layout/list_post_preview.xml +++ b/app/src/main/res/layout/list_post_preview.xml @@ -90,6 +90,7 @@ android:id="@+id/platform_indicator" android:layout_width="25dp" android:layout_height="25dp" + android:contentDescription="@string/cd_platform_indicator" android:scaleType="centerInside" android:layout_marginEnd="8dp" app:layout_constraintTop_toTopOf="@id/image_author_thumbnail" @@ -157,6 +158,7 @@ android:id="@+id/image_like_icon" android:layout_width="18dp" android:layout_height="18dp" + android:contentDescription="@string/cd_image_like_icon" app:srcCompat="@drawable/ic_thumb_up" /> @@ -202,6 +205,7 @@ android:id="@+id/image_comments" android:layout_width="18dp" android:layout_height="18dp" + android:contentDescription="@string/Replies" android:layout_marginStart="8dp" android:layout_marginTop="2dp" app:srcCompat="@drawable/ic_forum" /> diff --git a/app/src/main/res/layout/list_post_thumbnail.xml b/app/src/main/res/layout/list_post_thumbnail.xml index e16ab48f..922e0f28 100644 --- a/app/src/main/res/layout/list_post_thumbnail.xml +++ b/app/src/main/res/layout/list_post_thumbnail.xml @@ -90,6 +90,7 @@ android:id="@+id/platform_indicator" android:layout_width="20dp" android:layout_height="20dp" + android:contentDescription="@string/cd_platform_indicator" android:scaleType="centerInside" tools:src="@drawable/ic_peertube" android:layout_marginEnd="8dp" diff --git a/app/src/main/res/layout/list_source_construction.xml b/app/src/main/res/layout/list_source_construction.xml index 8b5cf0af..0da89b04 100644 --- a/app/src/main/res/layout/list_source_construction.xml +++ b/app/src/main/res/layout/list_source_construction.xml @@ -24,6 +24,7 @@ android:id="@+id/image_source" android:layout_width="35dp" android:layout_height="35dp" + android:contentDescription="@string/cd_platform_indicator" app:srcCompat="@drawable/ic_peertube" android:scaleType="fitCenter" /> diff --git a/app/src/main/res/layout/list_source_disabled.xml b/app/src/main/res/layout/list_source_disabled.xml index 4ef72985..3a6de99d 100644 --- a/app/src/main/res/layout/list_source_disabled.xml +++ b/app/src/main/res/layout/list_source_disabled.xml @@ -24,6 +24,7 @@ android:id="@+id/image_source" android:layout_width="35dp" android:layout_height="35dp" + android:contentDescription="@string/cd_platform_indicator" app:srcCompat="@drawable/ic_peertube" android:scaleType="fitCenter" /> diff --git a/app/src/main/res/layout/list_source_enabled.xml b/app/src/main/res/layout/list_source_enabled.xml index 0223971f..630b2bcc 100644 --- a/app/src/main/res/layout/list_source_enabled.xml +++ b/app/src/main/res/layout/list_source_enabled.xml @@ -15,6 +15,7 @@ android:id="@+id/image_drag_drop" android:layout_width="40dp" android:layout_height="40dp" + android:contentDescription="@string/cd_drag_drop" app:srcCompat="@drawable/ic_dragdrop_white" android:scaleType="fitCenter" android:paddingTop="10dp" @@ -34,6 +35,7 @@ android:id="@+id/image_source" android:layout_width="35dp" android:layout_height="35dp" + android:contentDescription="@string/cd_platform_indicator" app:srcCompat="@drawable/ic_peertube" android:scaleType="fitCenter" /> diff --git a/app/src/main/res/layout/list_subscription.xml b/app/src/main/res/layout/list_subscription.xml index 6abd51c7..ffbdf4ed 100644 --- a/app/src/main/res/layout/list_subscription.xml +++ b/app/src/main/res/layout/list_subscription.xml @@ -14,6 +14,7 @@ android:id="@+id/creator_thumbnail" android:layout_width="46dp" android:layout_height="46dp" + android:contentDescription="@string/cd_creator_thumbnail" android:layout_marginStart="20dp"/> + android:layout_height="25dp" + android:contentDescription="@string/cd_platform_indicator" /> @@ -213,6 +215,7 @@ android:id="@+id/thumbnail_platform" android:layout_width="25dp" android:layout_height="25dp" + android:contentDescription="@string/cd_platform_indicator" android:scaleType="centerInside" tools:src="@drawable/ic_peertube" /> @@ -230,6 +233,7 @@ android:id="@+id/button_add_to_watch_later" android:layout_width="30dp" android:layout_height="30dp" + android:contentDescription="@string/cd_button_add_to_watch_later" android:layout_marginEnd="5dp" android:background="@drawable/edit_text_background" app:srcCompat="@drawable/ic_clock_white" /> diff --git a/app/src/main/res/layout/list_video_preview_nested.xml b/app/src/main/res/layout/list_video_preview_nested.xml index c61c37e6..d321ed81 100644 --- a/app/src/main/res/layout/list_video_preview_nested.xml +++ b/app/src/main/res/layout/list_video_preview_nested.xml @@ -40,6 +40,7 @@ android:id="@+id/thumbnail_platform_nested" android:layout_width="25dp" android:layout_height="25dp" + android:contentDescription="@string/cd_platform_indicator" app:layout_constraintTop_toTopOf="parent" app:layout_constraintRight_toRightOf="parent" android:layout_margin="5dp" @@ -173,6 +174,7 @@ android:id="@+id/creator_thumbnail" android:layout_width="32dp" android:layout_height="32dp" + android:contentDescription="@string/cd_creator_thumbnail" app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintTop_toTopOf="parent" android:layout_marginStart="10dp" @@ -242,6 +244,7 @@ @@ -250,6 +253,7 @@ android:id="@+id/thumbnail_platform" android:layout_width="25dp" android:layout_height="25dp" + android:contentDescription="@string/cd_platform_indicator" android:scaleType="centerInside" tools:src="@drawable/ic_peertube"/> @@ -267,6 +271,7 @@ android:id="@+id/button_add_to_watch_later" android:layout_width="30dp" android:layout_height="30dp" + android:contentDescription="@string/cd_button_add_to_watch_later" android:layout_marginEnd="5dp" android:background="@drawable/edit_text_background" app:srcCompat="@drawable/ic_clock_white" /> diff --git a/app/src/main/res/layout/list_video_thumbnail.xml b/app/src/main/res/layout/list_video_thumbnail.xml index 51806a95..367730cc 100644 --- a/app/src/main/res/layout/list_video_thumbnail.xml +++ b/app/src/main/res/layout/list_video_thumbnail.xml @@ -104,6 +104,7 @@ @@ -112,6 +113,7 @@ android:id="@+id/thumbnail_platform" android:layout_width="20dp" android:layout_height="20dp" + android:contentDescription="@string/cd_platform_indicator" android:layout_alignParentStart="true" android:layout_alignParentBottom="true" android:layout_gravity="end" @@ -188,6 +190,7 @@ android:id="@+id/button_add_to_watch_later" android:layout_width="wrap_content" android:layout_height="27dp" + android:contentDescription="@string/cd_button_add_to_watch_later" android:src="@drawable/ic_clock_white" android:paddingTop="7dp" android:paddingBottom="6dp" diff --git a/app/src/main/res/layout/list_video_thumbnail_nested.xml b/app/src/main/res/layout/list_video_thumbnail_nested.xml index 4ddc8a61..82018ddb 100644 --- a/app/src/main/res/layout/list_video_thumbnail_nested.xml +++ b/app/src/main/res/layout/list_video_thumbnail_nested.xml @@ -104,6 +104,7 @@ @@ -112,6 +113,7 @@ android:id="@+id/thumbnail_platform" android:layout_width="20dp" android:layout_height="20dp" + android:contentDescription="@string/cd_platform_indicator" android:layout_alignParentStart="true" android:layout_alignParentBottom="true" android:layout_gravity="end" @@ -227,6 +229,7 @@ android:id="@+id/button_add_to_watch_later" android:layout_width="wrap_content" android:layout_height="27dp" + android:contentDescription="@string/cd_button_add_to_watch_later" android:src="@drawable/ic_clock_white" android:paddingTop="7dp" android:paddingBottom="6dp" @@ -320,6 +323,7 @@ android:id="@+id/thumbnail_platform_nested" android:layout_width="20dp" android:layout_height="20dp" + android:contentDescription="@string/cd_platform_indicator" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintRight_toRightOf="parent" android:layout_margin="4dp" /> diff --git a/app/src/main/res/layout/overlay_livechat.xml b/app/src/main/res/layout/overlay_livechat.xml index 9339c9a5..3e83d8e4 100644 --- a/app/src/main/res/layout/overlay_livechat.xml +++ b/app/src/main/res/layout/overlay_livechat.xml @@ -66,6 +66,7 @@ android:id="@+id/button_close" android:layout_width="40dp" android:layout_height="40dp" + android:contentDescription="@string/cd_button_close" app:layout_constraintRight_toRightOf="parent" app:layout_constraintTop_toTopOf="parent" android:layout_margin="7dp" @@ -126,6 +127,7 @@ android:scaleType="fitCenter" android:layout_width="40dp" android:layout_height="40dp" + android:contentDescription="@string/cd_creator_thumbnail" app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintTop_toTopOf="parent" android:layout_margin="20dp" @@ -159,6 +161,7 @@ android:id="@+id/donation_amount" android:layout_width="match_parent" android:layout_height="wrap_content" + android:contentDescription="@string/cd_donation_amount" android:gravity="center" tools:text="$100" /> @@ -229,6 +232,7 @@ android:scaleType="fitCenter" android:layout_width="40dp" android:layout_height="40dp" + android:contentDescription="@string/cd_creator_thumbnail" android:layout_marginEnd="10dp" android:layout_marginStart="-20dp" android:src="@drawable/placeholder_profile" /> diff --git a/app/src/main/res/layout/overlay_topbar.xml b/app/src/main/res/layout/overlay_topbar.xml index f7a9cae9..53ea310d 100644 --- a/app/src/main/res/layout/overlay_topbar.xml +++ b/app/src/main/res/layout/overlay_topbar.xml @@ -56,6 +56,7 @@ android:id="@+id/button_close" android:layout_width="40dp" android:layout_height="40dp" + android:contentDescription="@string/cd_button_close" android:padding="5dp" android:src="@drawable/ic_close" /> diff --git a/app/src/main/res/layout/thumbnail_player_ui.xml b/app/src/main/res/layout/thumbnail_player_ui.xml index a1df6ede..2b590856 100644 --- a/app/src/main/res/layout/thumbnail_player_ui.xml +++ b/app/src/main/res/layout/thumbnail_player_ui.xml @@ -25,6 +25,7 @@ android:id="@+id/thumbnail_player_unmute" android:layout_width="34dp" android:layout_height="34dp" + android:contentDescription="@string/cd_thumbnail_player_unmute" android:padding="7dp" android:layout_gravity="center_vertical" android:background="@color/transparent" diff --git a/app/src/main/res/layout/video_player_ui.xml b/app/src/main/res/layout/video_player_ui.xml index e849b942..486936a6 100644 --- a/app/src/main/res/layout/video_player_ui.xml +++ b/app/src/main/res/layout/video_player_ui.xml @@ -14,6 +14,7 @@ android:id="@+id/button_minimize" android:layout_width="50dp" android:layout_height="50dp" + android:contentDescription="@string/cd_button_minimize" android:scaleType="fitCenter" android:clickable="true" android:padding="3dp" @@ -33,6 +34,7 @@ android:id="@+id/button_autoplay" android:layout_width="50dp" android:layout_height="50dp" + android:contentDescription="@string/cd_button_autoplay" android:scaleType="fitCenter" android:clickable="true" android:padding="12dp" @@ -41,6 +43,7 @@ android:id="@+id/button_cast" android:layout_width="50dp" android:layout_height="50dp" + android:contentDescription="@string/cd_cast_button" android:scaleType="fitCenter" android:clickable="true" android:padding="12dp" @@ -49,6 +52,7 @@ android:id="@+id/button_rotate_lock" android:layout_width="50dp" android:layout_height="50dp" + android:contentDescription="@string/cd_button_rotate_lock" android:scaleType="fitCenter" android:clickable="true" android:padding="12dp" @@ -57,6 +61,7 @@ android:id="@+id/button_loop" android:layout_width="50dp" android:layout_height="50dp" + android:contentDescription="@string/cd_button_loop" android:scaleType="fitCenter" android:clickable="true" android:padding="12dp" @@ -65,6 +70,7 @@ android:id="@+id/button_settings" android:layout_width="50dp" android:layout_height="50dp" + android:contentDescription="@string/cd_button_settings" android:scaleType="fitCenter" android:clickable="true" android:padding="12dp" @@ -75,6 +81,7 @@ android:id="@+id/button_previous" android:layout_width="60dp" android:layout_height="60dp" + android:contentDescription="@string/cd_button_previous" android:scaleType="centerCrop" android:clickable="true" android:layout_marginRight="40dp" @@ -118,6 +125,7 @@ android:id="@+id/button_next" android:layout_width="60dp" android:layout_height="60dp" + android:contentDescription="@string/cd_button_next" android:clickable="true" android:scaleType="centerCrop" android:padding="5dp" @@ -131,6 +139,7 @@ android:id="@+id/button_fullscreen" android:layout_width="55dp" android:layout_height="40dp" + android:contentDescription="@string/cd_button_fullscreen" android:clickable="true" app:srcCompat="@drawable/ic_expand" app:layout_constraintRight_toRightOf="parent" diff --git a/app/src/main/res/layout/video_player_ui_fullscreen.xml b/app/src/main/res/layout/video_player_ui_fullscreen.xml index d4d93182..f291bc1c 100644 --- a/app/src/main/res/layout/video_player_ui_fullscreen.xml +++ b/app/src/main/res/layout/video_player_ui_fullscreen.xml @@ -13,6 +13,7 @@ android:id="@+id/button_minimize" android:layout_width="50dp" android:layout_height="50dp" + android:contentDescription="@string/cd_button_minimize" android:layout_centerVertical="true" android:layout_centerHorizontal="true" android:scaleType="fitCenter" @@ -61,6 +62,7 @@ android:id="@+id/button_autoplay" android:layout_width="50dp" android:layout_height="50dp" + android:contentDescription="@string/cd_button_autoplay" android:scaleType="fitCenter" android:clickable="true" android:padding="12dp" @@ -69,6 +71,7 @@ android:id="@+id/button_cast" android:layout_width="50dp" android:layout_height="50dp" + android:contentDescription="@string/cd_cast_button" android:scaleType="fitCenter" android:clickable="true" android:padding="12dp" @@ -77,6 +80,7 @@ android:id="@+id/button_rotate_lock" android:layout_width="50dp" android:layout_height="50dp" + android:contentDescription="@string/cd_button_rotate_lock" android:scaleType="fitCenter" android:clickable="true" android:padding="12dp" @@ -85,6 +89,7 @@ android:id="@+id/button_loop" android:layout_width="50dp" android:layout_height="50dp" + android:contentDescription="@string/cd_button_loop" android:scaleType="fitCenter" android:clickable="true" android:padding="12dp" @@ -93,6 +98,7 @@ android:id="@+id/button_settings" android:layout_width="50dp" android:layout_height="50dp" + android:contentDescription="@string/cd_button_settings" android:scaleType="fitCenter" android:clickable="true" android:padding="12dp" @@ -103,6 +109,7 @@ android:id="@+id/button_previous" android:layout_width="60dp" android:layout_height="60dp" + android:contentDescription="@string/cd_button_previous" android:scaleType="centerCrop" android:clickable="true" android:layout_marginRight="40dp" @@ -146,6 +153,7 @@ android:id="@+id/button_next" android:layout_width="60dp" android:layout_height="60dp" + android:contentDescription="@string/cd_button_next" android:clickable="true" android:scaleType="centerCrop" android:padding="5dp" @@ -159,6 +167,7 @@ android:id="@+id/button_fullscreen" android:layout_width="55dp" android:layout_height="40dp" + android:contentDescription="@string/cd_button_fullscreen" android:clickable="true" app:srcCompat="@drawable/ic_expand" app:layout_constraintRight_toRightOf="parent" diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 32015d9f..cfa7338d 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -810,6 +810,64 @@ Scroll to top Disable Battery Optimization Click to go to battery optimization settings. Disabling battery optimization will prevent the OS from killing media sessions. + Cast button + Incognito button + Creator thumbnail + Clear search + Search + Search icon + Back button + App icon + History icon + Create playlist + Share + Filter + Delete + Settings + Group image + Edit + Download + Close + Pause + Play + Donation amount + Replies + Like + Dislike + Subscribe + Platform indicator + Device icon + Loader + Donation author's image + Edit image + Add + Download indicator + Drag and drop + Add to Watch Later + Close + Unmute + Minimize + Lock rotation + Loop + Previous + Next + Fullscreen + Autoplay + Update spinner + Play + Pause + Stop + Scan QR code + Help + Change Polycentric profile picture + Settings + Settings + Settings + Settings + Settings + Settings + Settings + Settings Recommendations Subscriptions From 73b048d4c56759f7df75cfd97588213970bfa18c Mon Sep 17 00:00:00 2001 From: Koen J Date: Mon, 18 Nov 2024 14:20:31 +0100 Subject: [PATCH 6/7] Fixed resume not always working. --- .../fragment/mainactivity/main/VideoDetailView.kt | 2 +- .../futo/platformplayer/views/video/FutoVideoPlayerBase.kt | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/app/src/main/java/com/futo/platformplayer/fragment/mainactivity/main/VideoDetailView.kt b/app/src/main/java/com/futo/platformplayer/fragment/mainactivity/main/VideoDetailView.kt index c424f640..5551722d 100644 --- a/app/src/main/java/com/futo/platformplayer/fragment/mainactivity/main/VideoDetailView.kt +++ b/app/src/main/java/com/futo/platformplayer/fragment/mainactivity/main/VideoDetailView.kt @@ -1698,7 +1698,7 @@ class VideoDetailView : ConstraintLayout { }); else _player.setArtwork(null); - _player.setSource(videoSource, audioSource, _playWhenReady, false); + _player.setSource(videoSource, audioSource, _playWhenReady, false, resume = resumePositionMs > 0); if(subtitleSource != null) _player.swapSubtitles(fragment.lifecycleScope, subtitleSource); _player.seekTo(resumePositionMs); diff --git a/app/src/main/java/com/futo/platformplayer/views/video/FutoVideoPlayerBase.kt b/app/src/main/java/com/futo/platformplayer/views/video/FutoVideoPlayerBase.kt index 82ad7944..fcc6dc6d 100644 --- a/app/src/main/java/com/futo/platformplayer/views/video/FutoVideoPlayerBase.kt +++ b/app/src/main/java/com/futo/platformplayer/views/video/FutoVideoPlayerBase.kt @@ -327,8 +327,8 @@ abstract class FutoVideoPlayerBase : RelativeLayout { return _chapters?.let { chaps -> chaps.find { pos.toDouble() / 1000 > it.timeStart && pos.toDouble() / 1000 < it.timeEnd && (toIgnore.isEmpty() || !toIgnore.contains(it)) } }; } - fun setSource(videoSource: IVideoSource?, audioSource: IAudioSource? = null, play: Boolean = false, keepSubtitles: Boolean = false) { - swapSources(videoSource, audioSource,false, play, keepSubtitles); + fun setSource(videoSource: IVideoSource?, audioSource: IAudioSource? = null, play: Boolean = false, keepSubtitles: Boolean = false, resume: Boolean = false) { + swapSources(videoSource, audioSource,resume, play, keepSubtitles); } fun swapSources(videoSource: IVideoSource?, audioSource: IAudioSource?, resume: Boolean = true, play: Boolean = true, keepSubtitles: Boolean = false): Boolean { var videoSourceUsed = videoSource; From 0e64fa8d4cb2e2d407cc74e09d857e8d30605fb1 Mon Sep 17 00:00:00 2001 From: Koen J Date: Mon, 18 Nov 2024 14:28:56 +0100 Subject: [PATCH 7/7] Added a try catch to HandlePacket. --- .../sync/internal/SyncSession.kt | 50 +++++++++---------- .../sync/internal/SyncSocketSession.kt | 2 +- 2 files changed, 26 insertions(+), 26 deletions(-) diff --git a/app/src/main/java/com/futo/platformplayer/sync/internal/SyncSession.kt b/app/src/main/java/com/futo/platformplayer/sync/internal/SyncSession.kt index fd457d52..cca42a54 100644 --- a/app/src/main/java/com/futo/platformplayer/sync/internal/SyncSession.kt +++ b/app/src/main/java/com/futo/platformplayer/sync/internal/SyncSession.kt @@ -121,32 +121,32 @@ class SyncSession : IAuthorizable { } fun handlePacket(socketSession: SyncSocketSession, opcode: UByte, subOpcode: UByte, data: ByteBuffer) { - Logger.i(TAG, "Handle packet (opcode: ${opcode}, subOpcode: ${subOpcode}, data.length: ${data.remaining()})") - - when (opcode) { - Opcode.NOTIFY_AUTHORIZED.value -> { - _remoteAuthorized = true - checkAuthorized() - } - Opcode.NOTIFY_UNAUTHORIZED.value -> { - _remoteAuthorized = false - _onUnauthorized(this) - } - //TODO: Handle any kind of packet (that is not necessarily authorized) - } - - if (!isAuthorized) { - return - } - - if (opcode != Opcode.DATA.value) { - Logger.w(TAG, "Unknown opcode received: (opcode = ${opcode}, subOpcode = ${subOpcode})}") - return - } - - Logger.i(TAG, "Received (opcode = ${opcode}, subOpcode = ${subOpcode}) (${data.remaining()} bytes)") - //TODO: Abstract this out try { + Logger.i(TAG, "Handle packet (opcode: ${opcode}, subOpcode: ${subOpcode}, data.length: ${data.remaining()})") + + when (opcode) { + Opcode.NOTIFY_AUTHORIZED.value -> { + _remoteAuthorized = true + checkAuthorized() + } + Opcode.NOTIFY_UNAUTHORIZED.value -> { + _remoteAuthorized = false + _onUnauthorized(this) + } + //TODO: Handle any kind of packet (that is not necessarily authorized) + } + + if (!isAuthorized) { + return + } + + if (opcode != Opcode.DATA.value) { + Logger.w(TAG, "Unknown opcode received: (opcode = ${opcode}, subOpcode = ${subOpcode})}") + return + } + + Logger.i(TAG, "Received (opcode = ${opcode}, subOpcode = ${subOpcode}) (${data.remaining()} bytes)") + //TODO: Abstract this out when (subOpcode) { GJSyncOpcodes.sendToDevices -> { StateApp.instance.scopeOrNull?.launch(Dispatchers.Main) { diff --git a/app/src/main/java/com/futo/platformplayer/sync/internal/SyncSocketSession.kt b/app/src/main/java/com/futo/platformplayer/sync/internal/SyncSocketSession.kt index 6a5fd4a3..8b5f305a 100644 --- a/app/src/main/java/com/futo/platformplayer/sync/internal/SyncSocketSession.kt +++ b/app/src/main/java/com/futo/platformplayer/sync/internal/SyncSocketSession.kt @@ -274,7 +274,7 @@ class SyncSocketSession { _sendBuffer.asUByteArray()[4] = opcode _sendBuffer.asUByteArray()[5] = subOpcode - //Logger.i(TAG, "Encrypting message (size = ${HEADER_SIZE})") + //Logger.i(TAG, "Encrypting message (opcode = ${opcode}, subOpcode = ${subOpcode}, size = ${HEADER_SIZE})") val len = _cipherStatePair!!.sender.encryptWithAd(null, _sendBuffer, 0, _sendBufferEncrypted, 0, HEADER_SIZE) //Logger.i(TAG, "Sending encrypted message (size = ${len})")