AeroToss v0.5.0: финальный аудит, багфиксы, тесты, релиз

- Исправлен cleanup файлов (catch-блок удаляет реальный файл)
- Null safety для NsdManager (as? с проверками)
- JSON парсер: isLenient = false (отвергает malformed JSON)
- ByteArray.toInt(): добавлена require(size >= 4)
- Исправлен typo в SendScreen
- TransferEdgeCaseTest: 8 новых тестов edge cases
- Собран macOS arm64 JAR (28 МБ)
- Итого 73+ тестов, все проходят
This commit is contained in:
2026-08-19 17:50:39 +03:00
parent afc526d6e8
commit 5434ab314c
6 changed files with 191 additions and 12 deletions
@@ -17,7 +17,7 @@ class AndroidNsdDiscovery(context: Context) : DiscoveryManager {
private val _devices = MutableStateFlow<List<Device>>(emptyList())
override val devices: Flow<List<Device>> = _devices.asStateFlow()
private val nsdManager = context.getSystemService(Context.NSD_SERVICE) as NsdManager
private val nsdManager = context.getSystemService(Context.NSD_SERVICE) as? NsdManager
private var registrationListener: NsdManager.RegistrationListener? = null
private var discoveryListener: NsdManager.DiscoveryListener? = null
private val deviceId = generateDeviceId()
@@ -54,7 +54,7 @@ class AndroidNsdDiscovery(context: Context) : DiscoveryManager {
}
}
nsdManager.registerService(serviceInfo, NsdManager.PROTOCOL_DNS_SD, registrationListener)
nsdManager?.registerService(serviceInfo, NsdManager.PROTOCOL_DNS_SD, registrationListener)
}
private fun startServiceDiscovery() {
@@ -68,7 +68,7 @@ class AndroidNsdDiscovery(context: Context) : DiscoveryManager {
serviceInfo.serviceName != SERVICE_NAME &&
resolvingServices.add(serviceInfo.serviceName)
) {
nsdManager.resolveService(serviceInfo, object : NsdManager.ResolveListener {
nsdManager?.resolveService(serviceInfo, object : NsdManager.ResolveListener {
override fun onResolveFailed(info: NsdServiceInfo, errorCode: Int) {
resolvingServices.remove(info.serviceName)
Log.e(TAG, "Resolve failed: $errorCode")
@@ -110,16 +110,16 @@ class AndroidNsdDiscovery(context: Context) : DiscoveryManager {
}
}
nsdManager.discoverServices(SERVICE_TYPE, NsdManager.PROTOCOL_DNS_SD, discoveryListener)
nsdManager?.discoverServices(SERVICE_TYPE, NsdManager.PROTOCOL_DNS_SD, discoveryListener)
}
override fun stopDiscovery() {
try {
discoveryListener?.let { nsdManager.stopServiceDiscovery(it) }
discoveryListener?.let { nsdManager?.stopServiceDiscovery(it) }
} catch (_: Exception) {
}
try {
registrationListener?.let { nsdManager.unregisterService(it) }
registrationListener?.let { nsdManager?.unregisterService(it) }
} catch (_: Exception) {
}
discoveryListener = null
@@ -78,6 +78,8 @@ class AndroidFileTransferManager(private val context: Context) : TransferManager
private suspend fun handleIncomingConnection(socket: Socket) {
withContext(Dispatchers.IO) {
val progressId = UUID.randomUUID().toString()
var actualFile: File? = null
var requestFileName: String = ""
try {
socket.use { sock ->
sock.soTimeout = 30_000
@@ -86,6 +88,7 @@ class AndroidFileTransferManager(private val context: Context) : TransferManager
val requestJson = input.readUTF()
val request = Json.decodeFromString<TransferRequest>(requestJson)
requestFileName = request.fileName
val progress = TransferProgress(
id = progressId,
@@ -105,6 +108,7 @@ class AndroidFileTransferManager(private val context: Context) : TransferManager
}
val file = FileUtils.resolveUniqueFile(downloadsDir, request.fileName)
actualFile = file
val sha256 = MessageDigest.getInstance("SHA-256")
var bytesWritten = 0L
@@ -157,11 +161,11 @@ class AndroidFileTransferManager(private val context: Context) : TransferManager
}
} catch (e: Exception) {
e.printStackTrace()
actualFile?.let { FileUtils.deleteIfExists(it) }
val current = _incomingTransfers.value.find { it.id == progressId }
if (current != null && current.state != TransferState.COMPLETED &&
current.state != TransferState.FAILED && current.state != TransferState.CANCELLED
) {
FileUtils.deleteIfExists(File(downloadsDir, FileUtils.sanitizeFileName(current.request.fileName)))
updateIncomingById(progressId, current.copy(
state = TransferState.FAILED,
error = e.message ?: "Unknown error"