diff --git a/android/app/src/main/java/com/eddy/atomrelay/EspFlasher.kt b/android/app/src/main/java/com/eddy/atomrelay/EspFlasher.kt index ffda218..a53548a 100644 --- a/android/app/src/main/java/com/eddy/atomrelay/EspFlasher.kt +++ b/android/app/src/main/java/com/eddy/atomrelay/EspFlasher.kt @@ -24,20 +24,13 @@ class EspFlasher(private val context: Context) { fun onProgress(percent: Int, message: String) } - @Volatile - private var cancelled = false - - fun cancel() { - cancelled = true - } - suspend fun flashDevice(usbManager: UsbManager, device: UsbDevice, callback: FlashCallback) { - cancelled = false try { withContext(kotlinx.coroutines.Dispatchers.IO) { doFlash(usbManager, device, callback) } } catch (e: CancellationException) { + Log.i(TAG, "Flash cancelled") throw e } catch (e: Exception) { Log.e(TAG, "Flash failed", e) @@ -56,7 +49,7 @@ class EspFlasher(private val context: Context) { private suspend fun doFlash(usbManager: UsbManager, device: UsbDevice, callback: FlashCallback) { kotlinx.coroutines.delay(500) - checkCancelled() + coroutineContext.ensureActive() val connection = usbManager.openDevice(device) ?: throw IOException("Kan USB-apparaat niet openen") @@ -77,7 +70,7 @@ class EspFlasher(private val context: Context) { callback.onProgress(0, "Verbinden met ESP bootloader...") val transport = UsbSerialTransport(connection, epOut, epIn) - checkCancelled() + coroutineContext.ensureActive() val assets = context.assets val bootloader = assets.open("firmware/bootloader.bin").readBytes() @@ -116,7 +109,7 @@ class EspFlasher(private val context: Context) { stub.eraseFlash() for (step in steps) { - checkCancelled() + coroutineContext.ensureActive() val sizeStr = if (step.data.size > 1024) "${step.data.size / 1024}KB" else "${step.data.size} bytes" callback.onProgress(step.baseProgress, "${step.name} schrijven ($sizeStr)...") @@ -136,9 +129,4 @@ class EspFlasher(private val context: Context) { } } - private suspend fun checkCancelled() { - if (cancelled) { - coroutineContext.ensureActive() - } - } } diff --git a/android/app/src/main/java/com/eddy/atomrelay/SettingsActivity.kt b/android/app/src/main/java/com/eddy/atomrelay/SettingsActivity.kt index c81b131..39c49d5 100644 --- a/android/app/src/main/java/com/eddy/atomrelay/SettingsActivity.kt +++ b/android/app/src/main/java/com/eddy/atomrelay/SettingsActivity.kt @@ -22,9 +22,9 @@ import android.widget.Toast import androidx.appcompat.app.AppCompatActivity import androidx.lifecycle.lifecycleScope import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.Job import kotlinx.coroutines.withContext import kotlinx.coroutines.launch -import kotlinx.coroutines.withContext import java.nio.charset.StandardCharsets import java.security.SecureRandom @@ -47,7 +47,7 @@ class SettingsActivity : AppCompatActivity() { private var currentAction = UsbAction.NONE private var progressDialog: AlertDialog? = null private var dialog: AlertDialog? = null - private var flasher: EspFlasher? = null + private var flasherJob: Job? = null private val usbAttachedReceiver = object : BroadcastReceiver() { override fun onReceive(context: Context, intent: Intent) { @@ -124,8 +124,8 @@ class SettingsActivity : AppCompatActivity() { override fun onDestroy() { super.onDestroy() currentAction = UsbAction.NONE - flasher?.cancel() - flasher = null + flasherJob?.cancel() + flasherJob = null try { unregisterReceiver(usbAttachedReceiver) } catch (_: Exception) {} try { unregisterReceiver(usbPermissionReceiver) } catch (_: Exception) {} try { unregisterReceiver(usbDetachedReceiver) } catch (_: Exception) {} @@ -211,7 +211,7 @@ class SettingsActivity : AppCompatActivity() { dialog = null showProgressDialog("Firmware Flashen", "Initialiseren...", STYLE_HORIZONTAL) - flasher = EspFlasher(this) + val flasher = EspFlasher(this) val progressCallback = object : EspFlasher.FlashCallback { override fun onProgress(percent: Int, message: String) { lifecycleScope.launch(Dispatchers.Main) { @@ -221,9 +221,9 @@ class SettingsActivity : AppCompatActivity() { } } } - lifecycleScope.launch { + flasherJob = lifecycleScope.launch { try { - flasher?.flashDevice(usbManager, device, progressCallback) + flasher.flashDevice(usbManager, device, progressCallback) if (isFinishing || isDestroyed) return@launch currentAction = UsbAction.NONE progressDialog?.dismiss() @@ -240,6 +240,7 @@ class SettingsActivity : AppCompatActivity() { .show() } catch (e: kotlinx.coroutines.CancellationException) { cleanupAction() + throw e } catch (e: Exception) { progressDialog?.dismiss() progressDialog = null @@ -290,7 +291,7 @@ class SettingsActivity : AppCompatActivity() { .setTitle(title) .setView(view) .setNegativeButton("Annuleren") { _, _ -> - flasher?.cancel() + flasherJob?.cancel() cleanupAction() } .setCancelable(false)