refactor(service): Simplify boot-time service startup (#3730)

Signed-off-by: James Rich <2199651+jamesarich@users.noreply.github.com>
This commit is contained in:
James Rich
2025-11-18 12:42:20 -06:00
committed by GitHub
parent f84747cea6
commit bdf9dc375b
2 changed files with 9 additions and 41 deletions

View File

@@ -21,13 +21,18 @@ import android.content.BroadcastReceiver
import android.content.Context
import android.content.Intent
/** This receiver starts the MeshService on boot if a device was previously connected. */
class BootCompleteReceiver : BroadcastReceiver() {
override fun onReceive(mContext: Context, intent: Intent) {
// Verify the intent action
override fun onReceive(context: Context, intent: Intent) {
if (Intent.ACTION_BOOT_COMPLETED != intent.action) {
return
}
// start listening for bluetooth messages from our device
MeshService.startServiceLater(mContext)
val prefs = context.getSharedPreferences("mesh-prefs", Context.MODE_PRIVATE)
if (!prefs.contains("device_address")) {
return
}
MeshService.startService(context)
}
}

View File

@@ -20,45 +20,8 @@ package com.geeksville.mesh.service
import android.app.ForegroundServiceStartNotAllowedException
import android.content.Context
import android.os.Build
import androidx.work.BackoffPolicy
import androidx.work.OneTimeWorkRequestBuilder
import androidx.work.WorkManager
import androidx.work.Worker
import androidx.work.WorkerParameters
import com.geeksville.mesh.BuildConfig
import timber.log.Timber
import java.util.concurrent.TimeUnit
/** Helper that calls MeshService.startService() */
class ServiceStarter(appContext: Context, workerParams: WorkerParameters) : Worker(appContext, workerParams) {
override fun doWork(): Result = try {
MeshService.startService(this.applicationContext)
// Indicate whether the task finished successfully with the Result
Result.success()
} catch (ex: Exception) {
Timber.e(ex, "failure starting service, will retry")
Result.retry()
}
}
/**
* Just after boot the android OS is super busy, so if we call startForegroundService then, our thread might be stalled
* long enough to expose this Google/Samsung bug: https://issuetracker.google.com/issues/76112072#comment56
*/
fun MeshService.Companion.startServiceLater(context: Context) {
// No point in even starting the service if the user doesn't have a device bonded
Timber.i("Received boot complete announcement, starting mesh service in two minutes")
val delayRequest =
OneTimeWorkRequestBuilder<ServiceStarter>()
.setInitialDelay(2, TimeUnit.MINUTES)
.setBackoffCriteria(BackoffPolicy.EXPONENTIAL, 2, TimeUnit.MINUTES)
.addTag("startLater")
.build()
WorkManager.getInstance(context).enqueue(delayRequest)
}
// / Helper function to start running our service
fun MeshService.Companion.startService(context: Context) {