From 81c9a5a062ef4297cd30ef777604823f3f00b133 Mon Sep 17 00:00:00 2001 From: "witchx44@gmail.com" Date: Tue, 2 Jun 2026 10:34:05 +0530 Subject: [PATCH] Replaced the deprecated SCREEN_BRIGHT_WAKE_LOCK to FLAG_KEEP_SCREEN_ON using an invisible window overlay --- app/src/main/AndroidManifest.xml | 2 +- .../cc/goll/caff/CaffeinePreferences.kt | 66 ++++++++----------- .../kotlin/cc/goll/caff/CaffeineService.kt | 57 +++++++++------- .../cc/goll/caff/CaffeineTileService.kt | 44 +++++++++---- 4 files changed, 94 insertions(+), 75 deletions(-) diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 018486e..7f52a1c 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -1,6 +1,6 @@ - + ) { - var currentDuration: Int by rememberSaveable { mutableStateOf(5 * 60) } + var currentDuration: Int by rememberSaveable { mutableIntStateOf(5 * 60) } val durationWasAdded: Boolean by remember { derivedStateOf { diff --git a/app/src/main/kotlin/cc/goll/caff/CaffeineService.kt b/app/src/main/kotlin/cc/goll/caff/CaffeineService.kt index 70eda1c..7790884 100644 --- a/app/src/main/kotlin/cc/goll/caff/CaffeineService.kt +++ b/app/src/main/kotlin/cc/goll/caff/CaffeineService.kt @@ -8,12 +8,11 @@ import android.content.Intent import android.os.IBinder import android.os.Binder -import android.os.PowerManager +import android.view.View +import android.view.WindowManager +import android.graphics.PixelFormat import android.os.CountDownTimer - -private lateinit var WAKE_LOCK: PowerManager.WakeLock; - // Amount of milliseconds in a second private const val S_TO_MS: Long = 1000 @@ -35,12 +34,12 @@ class CaffeineService : Service() { } - override fun onBind(intent: Intent): IBinder? { + override fun onBind(intent: Intent): IBinder { return binder } override fun onUnbind(intent: Intent): Boolean { - if (!WAKE_LOCK.isHeld) { + if (!isScreenKeptOn) { // If the value is null, we weren't started, which shouldn't happen. // Either way, we just won't be stopped, so everything is fine. stopSelfResult(lastStartId ?: 0) @@ -51,16 +50,6 @@ class CaffeineService : Service() { } override fun onStartCommand(intent: Intent, flags: Int, startId: Int): Int { - // Create a wake lock. This is done once for each execution of the application. - if (!::WAKE_LOCK.isInitialized) { - @Suppress("DEPRECATION") - WAKE_LOCK = (getSystemService(POWER_SERVICE) as PowerManager).newWakeLock( - PowerManager.SCREEN_BRIGHT_WAKE_LOCK or PowerManager.ON_AFTER_RELEASE, - "cc.goll.caff:caffeine" - ) - - WAKE_LOCK.setReferenceCounted(false) - } // NOTE: we don't care about earlier startService calls that may not have finished their lifecycle lastStartId = startId @@ -85,22 +74,48 @@ class CaffeineService : Service() { private var timer: CountDownTimer? = null + private var isScreenKeptOn = false + private var overlayView: View? = null + + private fun addOverlay() { + if (isScreenKeptOn) return + val windowManager = getSystemService(WINDOW_SERVICE) as WindowManager + val params = WindowManager.LayoutParams( + 1, 1, + WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY, + WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE or + WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE or + WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON, + PixelFormat.TRANSPARENT + ) + overlayView = View(this) + windowManager.addView(overlayView, params) + isScreenKeptOn = true + } + + private fun removeOverlay() { + if (!isScreenKeptOn) return + val windowManager = getSystemService(WINDOW_SERVICE) as WindowManager + overlayView?.let { windowManager.removeView(it) } + overlayView = null + isScreenKeptOn = false + } // Acquire a wake lock for @param duration seconds. // // If @param duration is @val Int.MAX_VALUE, acquires a wake // lock indefinitely (until @fun releaseWakeLock is called) fun acquireWakeLockFor(duration: Int): Boolean { - if (WAKE_LOCK.isHeld) + if (isScreenKeptOn) return false // Add a grace period of 1s so the user can read the duration shown initially - var grace = 0 + val grace = 0 elapsed = 0 acquiredFor = duration - WAKE_LOCK.acquire() + addOverlay() timer = when (duration) { Int.MAX_VALUE -> null @@ -108,8 +123,6 @@ class CaffeineService : Service() { override fun onTick(remaining: Long) { if (grace > 0) elapsed++ - - grace = 1 } override fun onFinish() { @@ -127,7 +140,7 @@ class CaffeineService : Service() { timer?.cancel() - WAKE_LOCK.release() + removeOverlay() if (shouldStop) { stopSelfResult(lastStartId ?: 0) diff --git a/app/src/main/kotlin/cc/goll/caff/CaffeineTileService.kt b/app/src/main/kotlin/cc/goll/caff/CaffeineTileService.kt index 49cc84f..f67a49d 100644 --- a/app/src/main/kotlin/cc/goll/caff/CaffeineTileService.kt +++ b/app/src/main/kotlin/cc/goll/caff/CaffeineTileService.kt @@ -1,27 +1,25 @@ package cc.goll.caff +import android.annotation.SuppressLint +import android.app.PendingIntent +import android.content.ComponentName import android.content.Intent import android.content.ServiceConnection -import android.content.ComponentName - import android.graphics.drawable.Icon - -import android.service.quicksettings.Tile -import android.service.quicksettings.TileService - import android.os.Build import android.os.IBinder import android.os.PowerManager - -import java.util.concurrent.TimeUnit -import java.util.concurrent.ScheduledExecutorService +import android.provider.Settings +import android.service.quicksettings.Tile +import android.service.quicksettings.TileService +import androidx.core.net.toUri +import cc.goll.caff.utils.HumanReadableTime +import java.util.TreeSet import java.util.concurrent.Executors +import java.util.concurrent.ScheduledExecutorService import java.util.concurrent.ScheduledFuture -import java.util.TreeSet -import java.util.Timer - -import cc.goll.caff.utils.HumanReadableTime +import java.util.concurrent.TimeUnit class CaffeineTileService : TileService() { @@ -111,7 +109,7 @@ class CaffeineTileService : TileService() { } - private final val tileUpdateScheduler: ScheduledExecutorService = + private val tileUpdateScheduler: ScheduledExecutorService = Executors.newSingleThreadScheduledExecutor() private var tileUpdateFuture: ScheduledFuture<*>? = null @@ -185,9 +183,27 @@ class CaffeineTileService : TileService() { } + @SuppressLint("StartActivityAndCollapseDeprecated") override fun onClick() { super.onClick() + if (!Settings.canDrawOverlays(this)) { + val intent = Intent( + Settings.ACTION_MANAGE_OVERLAY_PERMISSION, + "package:$packageName".toUri() + ) + intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK) + + if (Build.VERSION.SDK_INT >= 34) { + val pendingIntent = PendingIntent.getActivity(this, 0, intent, PendingIntent.FLAG_IMMUTABLE) + startActivityAndCollapse(pendingIntent) + } else { + @Suppress("DEPRECATION") + startActivityAndCollapse(intent) + } + return + } + if (batteryOptimizations || !::caffeine.isInitialized) { qsTile.state = Tile.STATE_UNAVAILABLE qsTile.updateTile()