Move wakelocks to a dedicated class

This commit is contained in:
sim 2024-10-29 14:57:30 +00:00
parent 7d8b142ef4
commit 1cd2340b6c
4 changed files with 130 additions and 74 deletions

View File

@ -0,0 +1,68 @@
package org.unifiedpush.distributor.nextpush
import android.content.Context
import android.os.PowerManager
import android.util.Log
/**
* WakeLock to stay the CPU awake while doing important activities
*/
class WakeLock(context: Context) {
private var wakeLock: PowerManager.WakeLock =
(context.getSystemService(Context.POWER_SERVICE) as PowerManager)
.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, WAKE_LOCK_TAG)
/**
* Acquire the [WakeLock][PowerManager.WakeLock] with 10 seconds timeout.
*
* It have to be released before.
*/
fun acquire() {
Log.d(TAG, "Acquiring WakeLock.")
wakeLock.acquire(10_000L /*10 secs*/)
}
/**
* Release [WakeLock][PowerManager.WakeLock] created during service [StartService]
*/
fun release() {
wakeLock.let {
if (it.isHeld) {
Log.d(TAG, "Releasing WakeLock.")
it.release()
}
}
}
companion object {
private const val WAKE_LOCK_TAG = "NextPush:WakeLock"
private const val TAG = "WakeLock"
/** Current instance of [WakeLock] */
var instance: WakeLock? = null
private set
/** Release old instance of [WakeLock] and generate a new one */
fun new(context: Context): WakeLock {
Log.d(TAG, "Generating a new instance")
instance?.release()
return WakeLock(context).also {
instance = it
}
}
fun withWakeLock(block: () -> Unit) {
instance?.acquire()
block()
instance?.release()
}
/**
* Release WakeLock if exists
*/
fun destroyWakeLock() {
instance?.release()
instance = null
}
}
}

View File

@ -9,6 +9,7 @@ import okhttp3.sse.EventSource
import okhttp3.sse.EventSourceListener
import org.unifiedpush.distributor.nextpush.AppCompanion
import org.unifiedpush.distributor.nextpush.Database
import org.unifiedpush.distributor.nextpush.WakeLock
import org.unifiedpush.distributor.nextpush.api.response.SSEResponse
import org.unifiedpush.distributor.nextpush.distributor.Distributor.deleteAppFromSSE
import org.unifiedpush.distributor.nextpush.distributor.Distributor.sendMessage
@ -45,11 +46,7 @@ class SSEListener(val context: Context) : EventSourceListener() {
null
}
startingTimer.getAndSet(timer)?.cancel()
StartService.wakeLock?.let {
while (it.isHeld) {
it.release()
}
}
WakeLock.instance?.release()
try {
Log.d(TAG, "onOpen: " + response.code)
} catch (e: Exception) {
@ -58,54 +55,54 @@ class SSEListener(val context: Context) : EventSourceListener() {
}
override fun onEvent(eventSource: EventSource, id: String?, type: String?, data: String) {
Log.d(TAG, "New SSE message event: $type")
StartService.wakeLock?.acquire(30000L /*30 secs*/)
AppCompanion.lastEventDate = Calendar.getInstance()
WakeLock.withWakeLock {
Log.d(TAG, "New SSE message event: $type")
AppCompanion.lastEventDate = Calendar.getInstance()
when (type) {
"start" -> {
AppCompanion.started.set(true)
startingTimer.getAndSet(null)?.cancel()
AppCompanion.bufferedResponseChecked.set(true)
NoStartNotification(context).delete()
}
"ping" -> {
AppCompanion.pinged.set(true)
FailureHandler.newPing(context)
}
"keepalive" -> {
val message = Gson().fromJson(data, SSEResponse::class.java)
message.keepalive.let {
AppCompanion.keepalive.set(it)
Log.d(TAG, "New keepalive: $it")
if (it < 25) {
LowKeepAliveNotification(context, it).showSingle()
} else {
LowKeepAliveNotification(context, it).delete()
when (type) {
"start" -> {
AppCompanion.started.set(true)
startingTimer.getAndSet(null)?.cancel()
AppCompanion.bufferedResponseChecked.set(true)
NoStartNotification(context).delete()
}
"ping" -> {
AppCompanion.pinged.set(true)
FailureHandler.newPing(context)
}
"keepalive" -> {
val message = Gson().fromJson(data, SSEResponse::class.java)
message.keepalive.let {
AppCompanion.keepalive.set(it)
Log.d(TAG, "New keepalive: $it")
if (it < 25) {
LowKeepAliveNotification(context, it).showSingle()
} else {
LowKeepAliveNotification(context, it).delete()
}
}
}
}
"message" -> {
val message = Gson().fromJson(data, SSEResponse::class.java)
sendMessage(
context,
message.token,
Base64.decode(message.message, Base64.DEFAULT)
)
}
"deleteApp" -> {
val message = Gson().fromJson(data, SSEResponse::class.java)
if (Database.getDb(context).getPackageName(message.token) != null &&
!AppCompanion.delQueue.containsTokenElseAdd(message.token)
) {
deleteAppFromSSE(context, message.token)
AppCompanion.delQueue.removeToken(message.token)
"message" -> {
val message = Gson().fromJson(data, SSEResponse::class.java)
sendMessage(
context,
message.token,
Base64.decode(message.message, Base64.DEFAULT)
)
}
"deleteApp" -> {
val message = Gson().fromJson(data, SSEResponse::class.java)
if (Database.getDb(context).getPackageName(message.token) != null &&
!AppCompanion.delQueue.containsTokenElseAdd(message.token)
) {
deleteAppFromSSE(context, message.token)
AppCompanion.delQueue.removeToken(message.token)
}
}
}
}
StartService.wakeLock?.let {
if (it.isHeld) {
it.release()
}
}
}
@ -113,6 +110,7 @@ class SSEListener(val context: Context) : EventSourceListener() {
override fun onClosed(eventSource: EventSource) {
Log.d(TAG, "onClosed: $eventSource")
eventSource.cancel()
WakeLock.instance?.release()
if (!shouldRestart()) return
if (FailureHandler.newFail(context, eventSource)) {
clearDebugVars()
@ -123,6 +121,7 @@ class SSEListener(val context: Context) : EventSourceListener() {
override fun onFailure(eventSource: EventSource, t: Throwable?, response: Response?) {
Log.d(TAG, "onFailure")
eventSource.cancel()
WakeLock.instance?.release()
if (!shouldRestart()) return
t?.let {
Log.d(TAG, "An error occurred: $t")

View File

@ -5,12 +5,12 @@ import android.content.BroadcastReceiver
import android.content.Context
import android.content.Intent
import android.os.Build
import android.os.PowerManager
import android.util.Log
import android.widget.Toast
import androidx.annotation.RequiresApi
import org.unifiedpush.distributor.nextpush.AppCompanion
import org.unifiedpush.distributor.nextpush.Database.Companion.getDb
import org.unifiedpush.distributor.nextpush.WakeLock
import org.unifiedpush.distributor.nextpush.account.Account.isConnected
import org.unifiedpush.distributor.nextpush.distributor.* // ktlint-disable no-wildcard-imports
import org.unifiedpush.distributor.nextpush.distributor.Distributor.checkToken
@ -96,10 +96,8 @@ class RegisterBroadcastReceiver : BroadcastReceiver() {
override fun onReceive(rContext: Context, intent: Intent?) {
val context = rContext.applicationContext
val wakeLock = (context.getSystemService(Context.POWER_SERVICE) as PowerManager).run {
newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, WAKE_LOCK_TAG)
}
wakeLock?.acquire(30000L /*30 secs*/)
val wakeLock = WakeLock(context)
wakeLock.acquire()
when (intent?.action) {
ACTION_REGISTER -> {
Log.i(TAG, "REGISTER")
@ -119,11 +117,7 @@ class RegisterBroadcastReceiver : BroadcastReceiver() {
onUnregister(context, connectorToken)
}
}
wakeLock?.let {
if (it.isHeld) {
it.release()
}
}
wakeLock.release()
}
/**

View File

@ -8,6 +8,7 @@ import android.os.IBinder
import android.os.PowerManager
import android.util.Log
import org.unifiedpush.distributor.nextpush.AppCompanion
import org.unifiedpush.distributor.nextpush.WakeLock
import org.unifiedpush.distributor.nextpush.account.Account.getAccount
import org.unifiedpush.distributor.nextpush.api.Api
import org.unifiedpush.distributor.nextpush.utils.ForegroundNotification
@ -55,11 +56,7 @@ class StartService : Service() {
private fun destroy(mayRestart: Boolean) {
Log.d(TAG, "Destroying Service")
api?.apiDestroy()
wakeLock?.let {
while (it.isHeld) {
it.release()
}
}
WakeLock.destroyWakeLock()
if (mayRestart && isServiceStarted) {
Log.d(TAG, "onDestroy: restarting worker")
RestartWorker.run(this, delay = 0)
@ -80,25 +77,23 @@ class StartService : Service() {
isServiceStarted = true
RestartWorker.startPeriodic(this)
// we need this lock so our service gets not affected by Doze Mode
wakeLock = (getSystemService(Context.POWER_SERVICE) as PowerManager).run {
newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, WAKE_LOCK_TAG).apply {
acquire(10000L /*10 secs*/)
}
}
/**
* Acquire a lock so our service gets not affected by Doze Mode
*
* This lock is released by [org.unifiedpush.distributor.nextpush.api.SSEListener.onOpen]
* [org.unifiedpush.distributor.nextpush.api.SSEListener.onClosed]
* or [org.unifiedpush.distributor.nextpush.api.SSEListener.onFailure]
*/
WakeLock.new(this).acquire()
api = Api(this).also {
it.apiSync()
}
}
companion object StartServiceCompanion {
private const val WAKE_LOCK_TAG = "NextPush:StartService:lock"
private val service: AtomicReference<StartService?> = AtomicReference(null)
var isServiceStarted = false
private set
var wakeLock: PowerManager.WakeLock? = null
private set
fun startListener(context: Context) {
val hasRegistration = RegistrationCountCache.oneOrMore(context)