From fb408598888ae26e0717344696892ce5ed0a8091 Mon Sep 17 00:00:00 2001 From: Ross Savage Date: Sun, 14 Apr 2024 21:24:18 +0200 Subject: [PATCH] Add a service timeout to the android notification plugin (cherry picked from commit 4e9d81f80946a36c7b82834a5d38a6c5359f6006) --- .../breez_sdk_notification/Constants.kt | 3 ++- .../ForegroundService.kt | 26 ++++++++++++++----- .../kotlin/breez_sdk_notification/job/Job.kt | 8 ++++++ .../job/LnurlPayInfo.kt | 2 ++ .../job/LnurlPayInvoice.kt | 2 ++ .../job/ReceivePayment.kt | 2 ++ .../breez_sdk_notification/job/RedeemSwap.kt | 8 +++--- 7 files changed, 40 insertions(+), 11 deletions(-) diff --git a/libs/sdk-bindings/bindings-android/lib/src/main/kotlin/breez_sdk_notification/Constants.kt b/libs/sdk-bindings/bindings-android/lib/src/main/kotlin/breez_sdk_notification/Constants.kt index b8d972ff3..a2e7fccb0 100644 --- a/libs/sdk-bindings/bindings-android/lib/src/main/kotlin/breez_sdk_notification/Constants.kt +++ b/libs/sdk-bindings/bindings-android/lib/src/main/kotlin/breez_sdk_notification/Constants.kt @@ -1,8 +1,9 @@ package breez_sdk_notification object Constants { + const val SERVICE_TIMEOUT_MS = 3 * 60 * 1000L const val SHUTDOWN_DELAY_MS = 60 * 1000L - + // Notification Channels const val NOTIFICATION_CHANNEL_FOREGROUND_SERVICE = "FOREGROUND_SERVICE" const val NOTIFICATION_CHANNEL_LNURL_PAY = "LNURL_PAY" diff --git a/libs/sdk-bindings/bindings-android/lib/src/main/kotlin/breez_sdk_notification/ForegroundService.kt b/libs/sdk-bindings/bindings-android/lib/src/main/kotlin/breez_sdk_notification/ForegroundService.kt index c28bcd833..c8d4730fd 100644 --- a/libs/sdk-bindings/bindings-android/lib/src/main/kotlin/breez_sdk_notification/ForegroundService.kt +++ b/libs/sdk-bindings/bindings-android/lib/src/main/kotlin/breez_sdk_notification/ForegroundService.kt @@ -16,6 +16,7 @@ import breez_sdk_notification.Constants.MESSAGE_TYPE_LNURL_PAY_INFO import breez_sdk_notification.Constants.MESSAGE_TYPE_LNURL_PAY_INVOICE import breez_sdk_notification.Constants.MESSAGE_TYPE_PAYMENT_RECEIVED import breez_sdk_notification.Constants.NOTIFICATION_ID_FOREGROUND_SERVICE +import breez_sdk_notification.Constants.SERVICE_TIMEOUT_MS import breez_sdk_notification.Constants.SHUTDOWN_DELAY_MS import breez_sdk_notification.NotificationHelper.Companion.notifyForegroundService import breez_sdk_notification.job.Job @@ -53,6 +54,7 @@ abstract class ForegroundService : SdkForegroundService, EventListener, Service( return null } + /** Called by a Job to signal that it is complete. */ override fun onFinished(job: Job) { synchronized(this) { logger.log(TAG, "Job has finished: $job", "DEBUG") @@ -62,14 +64,27 @@ abstract class ForegroundService : SdkForegroundService, EventListener, Service( } /** Stop the service */ + private val serviceTimeoutHandler = Handler(Looper.getMainLooper()) + private val serviceTimeoutRunnable: Runnable = Runnable { + logger.log(TAG, "Reached service timeout...", "DEBUG") + synchronized(this) { + jobs.forEach { job -> job.onShutdown() } + } + + shutdown() + } + private val shutdownHandler = Handler(Looper.getMainLooper()) private val shutdownRunnable: Runnable = Runnable { logger.log(TAG, "Reached scheduled shutdown...", "DEBUG") shutdown() } - private fun resetShutdown() { + private fun resetDelayedCallbacks() { + serviceTimeoutHandler.removeCallbacksAndMessages(null) shutdownHandler.removeCallbacksAndMessages(null) + + shutdownHandler.postDelayed(serviceTimeoutRunnable, SERVICE_TIMEOUT_MS) } private fun delayedShutdown() { @@ -84,14 +99,10 @@ abstract class ForegroundService : SdkForegroundService, EventListener, Service( stopSelf() } - // =========================================================== // - // START COMMAND HANDLER // - // =========================================================== // - /** Called when an intent is called for this service. */ override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int { super.onStartCommand(intent, flags, startId) - resetShutdown() + resetDelayedCallbacks() val intentDetails = "[ intent=$intent, flag=$flags, startId=$startId ]" logger.log(TAG, "Start foreground service from intent $intentDetails", "DEBUG") @@ -127,7 +138,7 @@ abstract class ForegroundService : SdkForegroundService, EventListener, Service( abstract fun getConnectRequest(): ConnectRequest? /** To be implemented by the application foreground service. - * Allows the user to override the default ServiceConfig. */ + * Allows the user to override the default ServiceConfig. */ abstract fun getServiceConfig(): ServiceConfig? /** Get the job to be executed from the Message data in the Intent. @@ -189,6 +200,7 @@ abstract class ForegroundService : SdkForegroundService, EventListener, Service( } } + /** Handles incoming events from the Breez SDK EventListener */ override fun onEvent(e: BreezEvent) { synchronized(this) { jobs.forEach { job -> job.onEvent(e) } diff --git a/libs/sdk-bindings/bindings-android/lib/src/main/kotlin/breez_sdk_notification/job/Job.kt b/libs/sdk-bindings/bindings-android/lib/src/main/kotlin/breez_sdk_notification/job/Job.kt index 8b46b6706..1bfe4b02d 100644 --- a/libs/sdk-bindings/bindings-android/lib/src/main/kotlin/breez_sdk_notification/job/Job.kt +++ b/libs/sdk-bindings/bindings-android/lib/src/main/kotlin/breez_sdk_notification/job/Job.kt @@ -4,5 +4,13 @@ import breez_sdk.BlockingBreezServices import breez_sdk.EventListener interface Job : EventListener { + /** When the notification service is connected to the Breez SDK + * it calls `start` to initiate the job. + */ fun start(breezSDK: BlockingBreezServices) + + /** When the short service timeout is reached it calls `onShutdown` + * to cleanup the job. + */ + fun onShutdown() } diff --git a/libs/sdk-bindings/bindings-android/lib/src/main/kotlin/breez_sdk_notification/job/LnurlPayInfo.kt b/libs/sdk-bindings/bindings-android/lib/src/main/kotlin/breez_sdk_notification/job/LnurlPayInfo.kt index 35b0cd07d..61b575c1b 100644 --- a/libs/sdk-bindings/bindings-android/lib/src/main/kotlin/breez_sdk_notification/job/LnurlPayInfo.kt +++ b/libs/sdk-bindings/bindings-android/lib/src/main/kotlin/breez_sdk_notification/job/LnurlPayInfo.kt @@ -118,4 +118,6 @@ class LnurlPayInfoJob( fgService.onFinished(this) } + + override fun onShutdown() {} } diff --git a/libs/sdk-bindings/bindings-android/lib/src/main/kotlin/breez_sdk_notification/job/LnurlPayInvoice.kt b/libs/sdk-bindings/bindings-android/lib/src/main/kotlin/breez_sdk_notification/job/LnurlPayInvoice.kt index d69abfc3a..73e197050 100644 --- a/libs/sdk-bindings/bindings-android/lib/src/main/kotlin/breez_sdk_notification/job/LnurlPayInvoice.kt +++ b/libs/sdk-bindings/bindings-android/lib/src/main/kotlin/breez_sdk_notification/job/LnurlPayInvoice.kt @@ -118,4 +118,6 @@ class LnurlPayInvoiceJob( fgService.onFinished(this) } + + override fun onShutdown() {} } diff --git a/libs/sdk-bindings/bindings-android/lib/src/main/kotlin/breez_sdk_notification/job/ReceivePayment.kt b/libs/sdk-bindings/bindings-android/lib/src/main/kotlin/breez_sdk_notification/job/ReceivePayment.kt index d621e1a42..398b77bba 100644 --- a/libs/sdk-bindings/bindings-android/lib/src/main/kotlin/breez_sdk_notification/job/ReceivePayment.kt +++ b/libs/sdk-bindings/bindings-android/lib/src/main/kotlin/breez_sdk_notification/job/ReceivePayment.kt @@ -68,6 +68,8 @@ class ReceivePaymentJob( } } + override fun onShutdown() {} + private fun handleReceivedPayment( bolt11: String, paymentHash: String, diff --git a/libs/sdk-bindings/bindings-android/lib/src/main/kotlin/breez_sdk_notification/job/RedeemSwap.kt b/libs/sdk-bindings/bindings-android/lib/src/main/kotlin/breez_sdk_notification/job/RedeemSwap.kt index 1294c74f6..e44c1f354 100644 --- a/libs/sdk-bindings/bindings-android/lib/src/main/kotlin/breez_sdk_notification/job/RedeemSwap.kt +++ b/libs/sdk-bindings/bindings-android/lib/src/main/kotlin/breez_sdk_notification/job/RedeemSwap.kt @@ -38,7 +38,7 @@ class RedeemSwapJob( breezSDK.redeemSwap(request.address) logger.log(TAG, "Found swap for ${request.address}", "INFO") } catch (e: Exception) { - logger.log(TAG, "Failed to manually reedeem swap notification: ${e.message}", "WARN") + logger.log(TAG, "Failed to manually redeem swap notification: ${e.message}", "WARN") } } @@ -47,7 +47,7 @@ class RedeemSwapJob( when (e) { is BreezEvent.SwapUpdated -> { val swapInfo = e.details - logger.log(TAG, "Received swap updated event: ${swapInfo.bitcoinAddress} current address: ${address} status: ${swapInfo.status}", "TRACE") + logger.log(TAG, "Received swap updated event: ${swapInfo.bitcoinAddress} current address: $address status: ${swapInfo.status}", "TRACE") if (swapInfo.bitcoinAddress == address) { if (swapInfo.paidMsat.toLong() > 0) { notifySuccessAndShutdown(address) @@ -60,8 +60,10 @@ class RedeemSwapJob( } } + override fun onShutdown() {} + private fun notifySuccessAndShutdown(address: String) { - logger.log(TAG, "Swap address ${address} redeemed succesfully", "INFO") + logger.log(TAG, "Swap address $address redeemed successfully", "INFO") notifyChannel( context, NOTIFICATION_CHANNEL_SWAP_TX_CONFIRMED,