👻 Clean up services
This commit is contained in:
parent
ccfdff7fd8
commit
6128fd32f9
@ -118,10 +118,6 @@
|
|||||||
</intent-filter>
|
</intent-filter>
|
||||||
</activity>
|
</activity>
|
||||||
|
|
||||||
<service
|
|
||||||
android:name=".service.BitmessageService"
|
|
||||||
android:description="@string/bitmessage_service_description"
|
|
||||||
android:exported="false" />
|
|
||||||
<service
|
<service
|
||||||
android:name=".service.ProofOfWorkService"
|
android:name=".service.ProofOfWorkService"
|
||||||
android:exported="false" />
|
android:exported="false" />
|
||||||
@ -154,6 +150,11 @@
|
|||||||
android:exported="true"
|
android:exported="true"
|
||||||
android:permission="android.permission.BIND_JOB_SERVICE" />
|
android:permission="android.permission.BIND_JOB_SERVICE" />
|
||||||
|
|
||||||
|
<service
|
||||||
|
android:name=".service.CleanupService"
|
||||||
|
android:exported="true"
|
||||||
|
android:permission="android.permission.BIND_JOB_SERVICE" />
|
||||||
|
|
||||||
<service
|
<service
|
||||||
android:name=".service.BatchProcessorService"
|
android:name=".service.BatchProcessorService"
|
||||||
android:exported="false" />
|
android:exported="false" />
|
||||||
|
@ -25,7 +25,7 @@ import android.support.v4.app.NotificationCompat
|
|||||||
import ch.dissem.apps.abit.MainActivity
|
import ch.dissem.apps.abit.MainActivity
|
||||||
import ch.dissem.apps.abit.R
|
import ch.dissem.apps.abit.R
|
||||||
import ch.dissem.apps.abit.service.BitmessageIntentService
|
import ch.dissem.apps.abit.service.BitmessageIntentService
|
||||||
import ch.dissem.apps.abit.service.BitmessageService
|
import ch.dissem.apps.abit.service.NodeStartupService
|
||||||
import java.util.*
|
import java.util.*
|
||||||
import kotlin.concurrent.fixedRateTimer
|
import kotlin.concurrent.fixedRateTimer
|
||||||
|
|
||||||
@ -51,9 +51,9 @@ class NetworkNotification(ctx: Context) : AbstractNotification(ctx) {
|
|||||||
|
|
||||||
@SuppressLint("StringFormatMatches")
|
@SuppressLint("StringFormatMatches")
|
||||||
private fun update(): Boolean {
|
private fun update(): Boolean {
|
||||||
val running = BitmessageService.isRunning
|
val running = NodeStartupService.isRunning
|
||||||
builder.setOngoing(running)
|
builder.setOngoing(running)
|
||||||
val connections = BitmessageService.status.getProperty("network", "connections")
|
val connections = NodeStartupService.status.getProperty("network", "connections")
|
||||||
if (!running) {
|
if (!running) {
|
||||||
builder.setSmallIcon(R.drawable.ic_notification_full_node_disconnected)
|
builder.setSmallIcon(R.drawable.ic_notification_full_node_disconnected)
|
||||||
builder.setContentText(ctx.getString(R.string.connection_info_disconnected))
|
builder.setContentText(ctx.getString(R.string.connection_info_disconnected))
|
||||||
@ -112,7 +112,6 @@ class NetworkNotification(ctx: Context) : AbstractNotification(ctx) {
|
|||||||
timer = fixedRateTimer(initialDelay = 10000, period = 10000) {
|
timer = fixedRateTimer(initialDelay = 10000, period = 10000) {
|
||||||
if (!update()) {
|
if (!update()) {
|
||||||
cancel()
|
cancel()
|
||||||
ctx.stopService(Intent(ctx, BitmessageService::class.java))
|
|
||||||
}
|
}
|
||||||
super@NetworkNotification.show()
|
super@NetworkNotification.show()
|
||||||
}
|
}
|
||||||
|
@ -1,111 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2016 Christian Basler
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package ch.dissem.apps.abit.service
|
|
||||||
|
|
||||||
import android.app.Service
|
|
||||||
import android.content.BroadcastReceiver
|
|
||||||
import android.content.Context
|
|
||||||
import android.content.Intent
|
|
||||||
import android.content.IntentFilter
|
|
||||||
import android.net.ConnectivityManager
|
|
||||||
import android.os.Handler
|
|
||||||
import ch.dissem.apps.abit.notification.NetworkNotification
|
|
||||||
import ch.dissem.apps.abit.util.preferences
|
|
||||||
import ch.dissem.bitmessage.BitmessageContext
|
|
||||||
import ch.dissem.bitmessage.utils.Property
|
|
||||||
import org.jetbrains.anko.doAsync
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Define a Service that returns an IBinder for the
|
|
||||||
* sync adapter class, allowing the sync adapter framework to call
|
|
||||||
* onPerformSync().
|
|
||||||
*/
|
|
||||||
class BitmessageService : Service() {
|
|
||||||
|
|
||||||
private val bmc: BitmessageContext by lazy { Singleton.getBitmessageContext(this) }
|
|
||||||
private lateinit var notification: NetworkNotification
|
|
||||||
|
|
||||||
private val connectivityReceiver: BroadcastReceiver = object : BroadcastReceiver() {
|
|
||||||
override fun onReceive(context: Context, intent: Intent?) {
|
|
||||||
if (bmc.isRunning() && !preferences.connectionAllowed) {
|
|
||||||
bmc.shutdown()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private val cleanupHandler = Handler()
|
|
||||||
private val cleanupTask: Runnable = object : Runnable {
|
|
||||||
override fun run() {
|
|
||||||
bmc.cleanup()
|
|
||||||
if (isRunning) {
|
|
||||||
cleanupHandler.postDelayed(this, 24 * 60 * 60 * 1000L) // once a day
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onCreate() {
|
|
||||||
registerReceiver(
|
|
||||||
connectivityReceiver,
|
|
||||||
IntentFilter().apply {
|
|
||||||
addAction(ConnectivityManager.CONNECTIVITY_ACTION)
|
|
||||||
addAction(Intent.ACTION_BATTERY_CHANGED)
|
|
||||||
}
|
|
||||||
)
|
|
||||||
notification = NetworkNotification(this)
|
|
||||||
running = false
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
|
|
||||||
if (!isRunning) {
|
|
||||||
running = true
|
|
||||||
notification.connecting()
|
|
||||||
if (!bmc.isRunning()) {
|
|
||||||
bmc.startup()
|
|
||||||
}
|
|
||||||
notification.show()
|
|
||||||
cleanupHandler.postDelayed(cleanupTask, 24 * 60 * 60 * 1000L)
|
|
||||||
}
|
|
||||||
return Service.START_STICKY
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onDestroy() {
|
|
||||||
if (bmc.isRunning()) {
|
|
||||||
bmc.shutdown()
|
|
||||||
}
|
|
||||||
running = false
|
|
||||||
notification.showShutdown()
|
|
||||||
cleanupHandler.removeCallbacks(cleanupTask)
|
|
||||||
doAsync {
|
|
||||||
bmc.cleanup()
|
|
||||||
}
|
|
||||||
unregisterReceiver(connectivityReceiver)
|
|
||||||
stopSelf()
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onBind(intent: Intent) = null
|
|
||||||
|
|
||||||
companion object {
|
|
||||||
@Volatile
|
|
||||||
private var running = false
|
|
||||||
|
|
||||||
val isRunning: Boolean
|
|
||||||
get() = running && Singleton.bitmessageContext?.isRunning() == true
|
|
||||||
|
|
||||||
val status: Property
|
|
||||||
get() = Singleton.bitmessageContext?.status() ?: Property("bitmessage context")
|
|
||||||
}
|
|
||||||
}
|
|
@ -0,0 +1,18 @@
|
|||||||
|
package ch.dissem.apps.abit.service
|
||||||
|
|
||||||
|
import android.app.job.JobParameters
|
||||||
|
import android.app.job.JobService
|
||||||
|
import org.jetbrains.anko.doAsync
|
||||||
|
|
||||||
|
class CleanupService : JobService() {
|
||||||
|
|
||||||
|
override fun onStartJob(params: JobParameters?): Boolean {
|
||||||
|
doAsync {
|
||||||
|
Singleton.getBitmessageContext(this@CleanupService).cleanup()
|
||||||
|
jobFinished(params, false)
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onStopJob(params: JobParameters?) = false
|
||||||
|
}
|
@ -2,8 +2,17 @@ package ch.dissem.apps.abit.service
|
|||||||
|
|
||||||
import android.app.job.JobParameters
|
import android.app.job.JobParameters
|
||||||
import android.app.job.JobService
|
import android.app.job.JobService
|
||||||
|
import android.content.BroadcastReceiver
|
||||||
|
import android.content.Context
|
||||||
|
import android.content.Intent
|
||||||
|
import android.content.IntentFilter
|
||||||
|
import android.net.ConnectivityManager
|
||||||
|
import ch.dissem.apps.abit.notification.NetworkNotification
|
||||||
import ch.dissem.apps.abit.util.network
|
import ch.dissem.apps.abit.util.network
|
||||||
import ch.dissem.apps.abit.util.preferences
|
import ch.dissem.apps.abit.util.preferences
|
||||||
|
import ch.dissem.bitmessage.BitmessageContext
|
||||||
|
import ch.dissem.bitmessage.utils.Property
|
||||||
|
import org.jetbrains.anko.doAsync
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Starts the full node if
|
* Starts the full node if
|
||||||
@ -13,14 +22,55 @@ import ch.dissem.apps.abit.util.preferences
|
|||||||
* And stops it when the preconditions for the job (unmetered network) aren't met anymore.
|
* And stops it when the preconditions for the job (unmetered network) aren't met anymore.
|
||||||
*/
|
*/
|
||||||
class NodeStartupService : JobService() {
|
class NodeStartupService : JobService() {
|
||||||
|
private val bmc: BitmessageContext by lazy { Singleton.getBitmessageContext(this) }
|
||||||
|
|
||||||
|
private lateinit var notification: NetworkNotification
|
||||||
|
|
||||||
|
private val connectivityReceiver: BroadcastReceiver = object : BroadcastReceiver() {
|
||||||
|
override fun onReceive(context: Context, intent: Intent?) {
|
||||||
|
if (bmc.isRunning() && !preferences.connectionAllowed) {
|
||||||
|
bmc.shutdown()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
override fun onStartJob(params: JobParameters?): Boolean {
|
override fun onStartJob(params: JobParameters?): Boolean {
|
||||||
if (preferences.online) {
|
if (preferences.online) {
|
||||||
network.scheduleNodeStart()
|
registerReceiver(
|
||||||
|
connectivityReceiver,
|
||||||
|
IntentFilter().apply {
|
||||||
|
addAction(ConnectivityManager.CONNECTIVITY_ACTION)
|
||||||
|
addAction(Intent.ACTION_BATTERY_CHANGED)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
notification = NetworkNotification(this)
|
||||||
|
NodeStartupService.running = false
|
||||||
|
|
||||||
|
if (!isRunning) {
|
||||||
|
running = true
|
||||||
|
notification.connecting()
|
||||||
|
if (!bmc.isRunning()) {
|
||||||
|
bmc.startup()
|
||||||
|
}
|
||||||
|
notification.show()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun onDestroy() {
|
||||||
|
if (bmc.isRunning()) {
|
||||||
|
bmc.shutdown()
|
||||||
|
}
|
||||||
|
running = false
|
||||||
|
notification.showShutdown()
|
||||||
|
doAsync {
|
||||||
|
bmc.cleanup()
|
||||||
|
}
|
||||||
|
unregisterReceiver(connectivityReceiver)
|
||||||
|
stopSelf()
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Don't actually stop the service, otherwise it will be stopped after 1 or 10 minutes
|
* Don't actually stop the service, otherwise it will be stopped after 1 or 10 minutes
|
||||||
* depending on Android version.
|
* depending on Android version.
|
||||||
@ -30,4 +80,14 @@ class NodeStartupService : JobService() {
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
@Volatile
|
||||||
|
private var running = false
|
||||||
|
|
||||||
|
val isRunning: Boolean
|
||||||
|
get() = running && Singleton.bitmessageContext?.isRunning() == true
|
||||||
|
|
||||||
|
val status: Property
|
||||||
|
get() = Singleton.bitmessageContext?.status() ?: Property("bitmessage context")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -8,14 +8,17 @@ import android.content.Context
|
|||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
import android.os.Build
|
import android.os.Build
|
||||||
import ch.dissem.apps.abit.dialog.FullNodeDialogActivity
|
import ch.dissem.apps.abit.dialog.FullNodeDialogActivity
|
||||||
import ch.dissem.apps.abit.service.BitmessageService
|
import ch.dissem.apps.abit.service.CleanupService
|
||||||
import ch.dissem.apps.abit.service.NodeStartupService
|
import ch.dissem.apps.abit.service.NodeStartupService
|
||||||
import java.lang.ref.WeakReference
|
import java.lang.ref.WeakReference
|
||||||
|
import java.util.concurrent.TimeUnit
|
||||||
|
|
||||||
val Context.network get() = NetworkUtils.getInstance(this)
|
val Context.network get() = NetworkUtils.getInstance(this)
|
||||||
|
|
||||||
class NetworkUtils internal constructor(private val ctx: Context) {
|
class NetworkUtils internal constructor(private val ctx: Context) {
|
||||||
|
|
||||||
|
private val jobScheduler by lazy { ctx.getSystemService(Context.JOB_SCHEDULER_SERVICE) as JobScheduler }
|
||||||
|
|
||||||
fun enableNode(ask: Boolean = true) {
|
fun enableNode(ask: Boolean = true) {
|
||||||
if (ask && !ctx.preferences.connectionAllowed) {
|
if (ask && !ctx.preferences.connectionAllowed) {
|
||||||
// Ask for connection
|
// Ask for connection
|
||||||
@ -31,24 +34,32 @@ class NetworkUtils internal constructor(private val ctx: Context) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun disableNode() {
|
fun disableNode() {
|
||||||
ctx.stopService(Intent(ctx, BitmessageService::class.java))
|
jobScheduler.cancelAll()
|
||||||
}
|
}
|
||||||
|
|
||||||
fun scheduleNodeStart() {
|
fun scheduleNodeStart() {
|
||||||
val jobScheduler = ctx.getSystemService(Context.JOB_SCHEDULER_SERVICE) as JobScheduler
|
JobInfo.Builder(0, ComponentName(ctx, NodeStartupService::class.java)).let { builder ->
|
||||||
val serviceComponent = ComponentName(ctx, NodeStartupService::class.java)
|
when {
|
||||||
val builder = JobInfo.Builder(0, serviceComponent)
|
ctx.preferences.wifiOnly ->
|
||||||
when {
|
builder.setRequiredNetworkType(JobInfo.NETWORK_TYPE_UNMETERED)
|
||||||
ctx.preferences.wifiOnly ->
|
Build.VERSION.SDK_INT >= Build.VERSION_CODES.N ->
|
||||||
builder.setRequiredNetworkType(JobInfo.NETWORK_TYPE_UNMETERED)
|
builder.setRequiredNetworkType(JobInfo.NETWORK_TYPE_NOT_ROAMING)
|
||||||
Build.VERSION.SDK_INT >= Build.VERSION_CODES.N ->
|
else ->
|
||||||
builder.setRequiredNetworkType(JobInfo.NETWORK_TYPE_NOT_ROAMING)
|
builder.setRequiredNetworkType(JobInfo.NETWORK_TYPE_ANY)
|
||||||
else ->
|
}
|
||||||
builder.setRequiredNetworkType(JobInfo.NETWORK_TYPE_ANY)
|
builder.setRequiresCharging(ctx.preferences.requireCharging)
|
||||||
|
builder.setPersisted(true)
|
||||||
|
|
||||||
|
jobScheduler.schedule(builder.build())
|
||||||
|
}
|
||||||
|
|
||||||
|
JobInfo.Builder(1, ComponentName(ctx, CleanupService::class.java)).let { builder ->
|
||||||
|
builder.setPeriodic(TimeUnit.DAYS.toMillis(1))
|
||||||
|
builder.setRequiresDeviceIdle(true)
|
||||||
|
builder.setRequiresCharging(true)
|
||||||
|
|
||||||
|
jobScheduler.schedule(builder.build())
|
||||||
}
|
}
|
||||||
builder.setRequiresCharging(ctx.preferences.requireCharging)
|
|
||||||
builder.setPersisted(true)
|
|
||||||
jobScheduler.schedule(builder.build())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
|
Loading…
Reference in New Issue
Block a user