Phase 4: foreground service for background tasks
Browse files
app/src/main/java/io/github/abrarul/modularai/service/AgentService.kt
ADDED
|
@@ -0,0 +1,42 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
package io.github.abrarul.modularai.service
|
| 2 |
+
|
| 3 |
+
import android.app.*
|
| 4 |
+
import android.content.Context
|
| 5 |
+
import android.content.Intent
|
| 6 |
+
import android.content.pm.ServiceInfo
|
| 7 |
+
import android.os.IBinder
|
| 8 |
+
import android.os.PowerManager
|
| 9 |
+
|
| 10 |
+
/** Keeps long jobs (downloads, inference, scripts) alive under a visible notification. */
|
| 11 |
+
class AgentService : Service() {
|
| 12 |
+
private var wake: PowerManager.WakeLock? = null
|
| 13 |
+
|
| 14 |
+
override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
|
| 15 |
+
if (intent?.action == ACTION_STOP) { stopSelf(); return START_NOT_STICKY }
|
| 16 |
+
val nm = getSystemService(NotificationManager::class.java)
|
| 17 |
+
nm.createNotificationChannel(NotificationChannel(CH, "Background tasks", NotificationManager.IMPORTANCE_LOW))
|
| 18 |
+
val stop = PendingIntent.getService(
|
| 19 |
+
this, 0, Intent(this, AgentService::class.java).setAction(ACTION_STOP),
|
| 20 |
+
PendingIntent.FLAG_IMMUTABLE
|
| 21 |
+
)
|
| 22 |
+
val n = Notification.Builder(this, CH)
|
| 23 |
+
.setContentTitle("ModularAI running")
|
| 24 |
+
.setContentText("Background task active")
|
| 25 |
+
.setSmallIcon(android.R.drawable.stat_sys_download)
|
| 26 |
+
.addAction(Notification.Action.Builder(null, "Stop", stop).build())
|
| 27 |
+
.build()
|
| 28 |
+
startForeground(1, n, ServiceInfo.FOREGROUND_SERVICE_TYPE_DATA_SYNC)
|
| 29 |
+
wake = getSystemService(PowerManager::class.java)
|
| 30 |
+
.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "modularai:agent").apply { acquire(30 * 60 * 1000L) }
|
| 31 |
+
return START_STICKY
|
| 32 |
+
}
|
| 33 |
+
|
| 34 |
+
override fun onDestroy() { wake?.takeIf { it.isHeld }?.release(); super.onDestroy() }
|
| 35 |
+
override fun onBind(i: Intent?): IBinder? = null
|
| 36 |
+
|
| 37 |
+
companion object {
|
| 38 |
+
private const val CH = "agent"
|
| 39 |
+
const val ACTION_STOP = "io.github.abrarul.modularai.STOP"
|
| 40 |
+
fun start(ctx: Context) = ctx.startForegroundService(Intent(ctx, AgentService::class.java))
|
| 41 |
+
}
|
| 42 |
+
}
|