2
0
mirror of https://github.com/KDE/kdeconnect-android synced 2025-10-21 14:38:19 +00:00

Compare commits

...

4 Commits

Author SHA1 Message Date
Albert Vaca Cintora
6bae0d7503 Rename locks 2025-10-12 00:16:20 +02:00
Albert Vaca Cintora
f27fdbf52e Make ConnectionMultiplexer non-null 2025-10-10 12:34:18 +02:00
Albert Vaca Cintora
0c14b3fb1a Add missing withLock call 2025-10-10 12:31:43 +02:00
Albert Vaca Cintora
f4a0c53ca0 Make socket non-null 2025-10-10 12:31:26 +02:00
2 changed files with 38 additions and 43 deletions

View File

@@ -25,15 +25,14 @@ import java.util.UUID
import kotlin.text.Charsets.UTF_8 import kotlin.text.Charsets.UTF_8
class BluetoothLink( class BluetoothLink(
context: Context?, context: Context,
connection: ConnectionMultiplexer, private val connection: ConnectionMultiplexer,
val input: InputStream, val input: InputStream,
val output: OutputStream, val output: OutputStream,
val remoteAddress: BluetoothDevice, val remoteAddress: BluetoothDevice,
val theDeviceInfo: DeviceInfo, val theDeviceInfo: DeviceInfo,
val linkProvider: BluetoothLinkProvider val linkProvider: BluetoothLinkProvider
) : BaseLink(context!!, linkProvider) { ) : BaseLink(context, linkProvider) {
private val connection: ConnectionMultiplexer? = connection
private var continueAccepting = true private var continueAccepting = true
private val receivingThread = Thread(object : Runnable { private val receivingThread = Thread(object : Runnable {
override fun run() { override fun run() {
@@ -99,13 +98,10 @@ class BluetoothLink(
} }
override fun disconnect() { override fun disconnect() {
if (connection == null) {
return
}
continueAccepting = false continueAccepting = false
try { try {
connection.close() connection.close()
} catch (ignored: IOException) { } catch (_: IOException) {
} }
linkProvider.disconnectedLink(this, remoteAddress) linkProvider.disconnectedLink(this, remoteAddress)
} }
@@ -124,7 +120,7 @@ class BluetoothLink(
return try { return try {
var transferUuid: UUID? = null var transferUuid: UUID? = null
if (np.hasPayload()) { if (np.hasPayload()) {
transferUuid = connection!!.newChannel() transferUuid = connection.newChannel()
val payloadTransferInfo = JSONObject() val payloadTransferInfo = JSONObject()
payloadTransferInfo.put("uuid", transferUuid.toString()) payloadTransferInfo.put("uuid", transferUuid.toString())
np.payloadTransferInfo = payloadTransferInfo np.payloadTransferInfo = payloadTransferInfo
@@ -132,7 +128,7 @@ class BluetoothLink(
sendMessage(np) sendMessage(np)
if (transferUuid != null) { if (transferUuid != null) {
try { try {
connection!!.getChannelOutputStream(transferUuid).use { payloadStream -> connection.getChannelOutputStream(transferUuid).use { payloadStream ->
val BUFFER_LENGTH = 1024 val BUFFER_LENGTH = 1024
val buffer = ByteArray(BUFFER_LENGTH) val buffer = ByteArray(BUFFER_LENGTH)
var bytesRead: Int var bytesRead: Int

View File

@@ -133,6 +133,7 @@ class ConnectionMultiplexer(socket: BluetoothSocket) : Closeable {
override fun close() { override fun close() {
flush() flush()
lock.withLock { lock.withLock {
if (!open) return
open = false open = false
readBuffer.clear() readBuffer.clear()
lockCondition.signalAll() lockCondition.signalAll()
@@ -158,7 +159,7 @@ class ConnectionMultiplexer(socket: BluetoothSocket) : Closeable {
if (freeWriteAmount == 0) { if (freeWriteAmount == 0) {
try { try {
lockCondition.await() lockCondition.await()
} catch (ignored: Exception) { } catch (_: Exception) {
} }
} else { } else {
break break
@@ -177,9 +178,9 @@ class ConnectionMultiplexer(socket: BluetoothSocket) : Closeable {
} }
} }
private var socket: BluetoothSocket? private val socket: BluetoothSocket
private val channels: MutableMap<UUID, Channel> = HashMap() private val channels: MutableMap<UUID, Channel> = HashMap()
private val lock = ReentrantLock() private val channelsLock = ReentrantLock()
private var open = true private var open = true
private var receivedProtocolVersion = false private var receivedProtocolVersion = false
@@ -199,27 +200,27 @@ class ConnectionMultiplexer(socket: BluetoothSocket) : Closeable {
message.position(19) message.position(19)
message.putShort(1.toShort()) message.putShort(1.toShort())
message.putShort(1.toShort()) message.putShort(1.toShort())
socket!!.outputStream.write(data) socket.outputStream.write(data)
} }
private fun handleException(@Suppress("UNUSED_PARAMETER") ignored: Exception) { private fun handleException(@Suppress("UNUSED_PARAMETER") ignored: Exception) {
lock.withLock { channelsLock.withLock {
open = false open = false
for (channel in channels.values) { for (channel in channels.values) {
channel.doClose() channel.doClose()
} }
channels.clear() channels.clear()
if (socket != null && socket!!.isConnected) { if (socket.isConnected) {
try { try {
socket!!.close() socket.close()
} catch (ignored: IOException) { } catch (_: IOException) {
} }
} }
} }
} }
private fun closeChannel(id: UUID) { private fun closeChannel(id: UUID) {
lock.withLock { channelsLock.withLock {
if (channels.containsKey(id)) { if (channels.containsKey(id)) {
channels.remove(id) channels.remove(id)
val data = ByteArray(19) val data = ByteArray(19)
@@ -230,7 +231,7 @@ class ConnectionMultiplexer(socket: BluetoothSocket) : Closeable {
message.putLong(id.mostSignificantBits) message.putLong(id.mostSignificantBits)
message.putLong(id.leastSignificantBits) message.putLong(id.leastSignificantBits)
try { try {
socket!!.outputStream.write(data) socket.outputStream.write(data)
} catch (e: IOException) { } catch (e: IOException) {
handleException(e) handleException(e)
} }
@@ -239,7 +240,7 @@ class ConnectionMultiplexer(socket: BluetoothSocket) : Closeable {
} }
private fun readRequest(id: UUID) { private fun readRequest(id: UUID) {
lock.withLock { channelsLock.withLock {
val channel = channels[id] ?: return val channel = channels[id] ?: return
val data = ByteArray(21) val data = ByteArray(21)
channel.lock.withLock { channel.lock.withLock {
@@ -254,7 +255,7 @@ class ConnectionMultiplexer(socket: BluetoothSocket) : Closeable {
message.putShort(amount.toShort()) message.putShort(amount.toShort())
channel.requestedReadAmount += amount channel.requestedReadAmount += amount
try { try {
socket!!.outputStream.write(data) socket.outputStream.write(data)
} catch (e: IOException) { } catch (e: IOException) {
handleException(e) handleException(e)
} catch (e: NullPointerException) { } catch (e: NullPointerException) {
@@ -267,7 +268,7 @@ class ConnectionMultiplexer(socket: BluetoothSocket) : Closeable {
@Throws(IOException::class) @Throws(IOException::class)
private fun writeRequest(id: UUID, writeData: ByteArray, off: Int, writeLen: Int): Int { private fun writeRequest(id: UUID, writeData: ByteArray, off: Int, writeLen: Int): Int {
lock.withLock { channelsLock.withLock {
val channel = channels[id] ?: return 0 val channel = channels[id] ?: return 0
val data = ByteArray(19 + BUFFER_SIZE) val data = ByteArray(19 + BUFFER_SIZE)
var length: Int var length: Int
@@ -296,7 +297,7 @@ class ConnectionMultiplexer(socket: BluetoothSocket) : Closeable {
channel.lockCondition.signalAll() channel.lockCondition.signalAll()
} }
try { try {
socket!!.outputStream.write(data, 0, 19 + length) socket.outputStream.write(data, 0, 19 + length)
} catch (e: IOException) { } catch (e: IOException) {
handleException(e) handleException(e)
} }
@@ -306,29 +307,27 @@ class ConnectionMultiplexer(socket: BluetoothSocket) : Closeable {
@Throws(IOException::class) @Throws(IOException::class)
private fun flush() { private fun flush() {
lock.withLock { channelsLock.withLock {
if (!open) return if (!open) return
socket!!.outputStream.flush() socket.outputStream.flush()
} }
} }
@Throws(IOException::class) @Throws(IOException::class)
override fun close() { override fun close() {
if (socket == null) { channelsLock.withLock {
return socket.close()
for (channel in channels.values) {
channel.doClose()
}
channels.clear()
} }
socket!!.close()
socket = null
for (channel in channels.values) {
channel.doClose()
}
channels.clear()
} }
@Throws(IOException::class) @Throws(IOException::class)
fun newChannel(): UUID { fun newChannel(): UUID {
val id = UUID.randomUUID() val id = UUID.randomUUID()
lock.withLock { channelsLock.withLock {
val data = ByteArray(19) val data = ByteArray(19)
val message = ByteBuffer.wrap(data) val message = ByteBuffer.wrap(data)
message.order(ByteOrder.BIG_ENDIAN) message.order(ByteOrder.BIG_ENDIAN)
@@ -337,7 +336,7 @@ class ConnectionMultiplexer(socket: BluetoothSocket) : Closeable {
message.putLong(id.mostSignificantBits) message.putLong(id.mostSignificantBits)
message.putLong(id.leastSignificantBits) message.putLong(id.leastSignificantBits)
try { try {
socket!!.outputStream.write(data) socket.outputStream.write(data)
} catch (e: IOException) { } catch (e: IOException) {
handleException(e) handleException(e)
throw e throw e
@@ -357,7 +356,7 @@ class ConnectionMultiplexer(socket: BluetoothSocket) : Closeable {
@Throws(IOException::class) @Throws(IOException::class)
fun getChannelInputStream(id: UUID): InputStream { fun getChannelInputStream(id: UUID): InputStream {
lock.withLock { channelsLock.withLock {
val channel = channels[id] ?: throw IOException("Invalid channel!") val channel = channels[id] ?: throw IOException("Invalid channel!")
return ChannelInputStream(channel) return ChannelInputStream(channel)
} }
@@ -365,7 +364,7 @@ class ConnectionMultiplexer(socket: BluetoothSocket) : Closeable {
@Throws(IOException::class) @Throws(IOException::class)
fun getChannelOutputStream(id: UUID): OutputStream { fun getChannelOutputStream(id: UUID): OutputStream {
lock.withLock { channelsLock.withLock {
val channel = channels[id] ?: throw IOException("Invalid channel!") val channel = channels[id] ?: throw IOException("Invalid channel!")
return ChannelOutputStream(channel) return ChannelOutputStream(channel)
} }
@@ -416,12 +415,12 @@ class ConnectionMultiplexer(socket: BluetoothSocket) : Closeable {
} }
when (type) { when (type) {
MESSAGE_OPEN_CHANNEL -> { MESSAGE_OPEN_CHANNEL -> {
lock.withLock { channelsLock.withLock {
channels.put(channelId, Channel(this@ConnectionMultiplexer, channelId)) channels.put(channelId, Channel(this@ConnectionMultiplexer, channelId))
} }
} }
MESSAGE_CLOSE_CHANNEL -> { MESSAGE_CLOSE_CHANNEL -> {
lock.withLock { channelsLock.withLock {
val channel = channels[channelId] ?: return val channel = channels[channelId] ?: return
channels.remove(channelId) channels.remove(channelId)
channel.doClose() channel.doClose()
@@ -435,7 +434,7 @@ class ConnectionMultiplexer(socket: BluetoothSocket) : Closeable {
var amount = ByteBuffer.wrap(data, 0, 2).order(ByteOrder.BIG_ENDIAN).short.toInt() var amount = ByteBuffer.wrap(data, 0, 2).order(ByteOrder.BIG_ENDIAN).short.toInt()
//signed short -> unsigned short (as int) conversion //signed short -> unsigned short (as int) conversion
if (amount < 0) amount += 0x10000 if (amount < 0) amount += 0x10000
lock.withLock { channelsLock.withLock {
val channel = channels[channelId] ?: return val channel = channels[channelId] ?: return
channel.lock.withLock { channel.lock.withLock {
channel.freeWriteAmount += amount channel.freeWriteAmount += amount
@@ -448,7 +447,7 @@ class ConnectionMultiplexer(socket: BluetoothSocket) : Closeable {
throw IOException("Message length is bigger than read size!") throw IOException("Message length is bigger than read size!")
} }
readBuffer(data, length) readBuffer(data, length)
lock.withLock { channelsLock.withLock {
val channel = channels[channelId] ?: return val channel = channels[channelId] ?: return
channel.lock.withLock { channel.lock.withLock {
if (channel.requestedReadAmount < length) { if (channel.requestedReadAmount < length) {
@@ -495,7 +494,7 @@ class ConnectionMultiplexer(socket: BluetoothSocket) : Closeable {
override fun run() { override fun run() {
while (true) { while (true) {
lock.withLock { channelsLock.withLock {
if (!open) { if (!open) {
Log.w("ConnectionMultiplexer", "connection not open, returning") Log.w("ConnectionMultiplexer", "connection not open, returning")
return return