Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add QuickSettings Tile to disable AutoFreeze service temporarily. #142

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Add QuickSettings Tile to disable AutoFreeze service temporarily.
Tapping on it allows to set the amount of time AutoFreeze should be
disabled for. 1, 5 , 10, 30, 60 or 120 minutes. It can also be disabled
completely and the re-enabled.
  • Loading branch information
Juanito committed Oct 14, 2023
commit bf3bf2dda538a4486ef91a2e870c031a65d28cba
10 changes: 10 additions & 0 deletions app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,16 @@
<action android:name="android.service.notification.NotificationListenerService" />
</intent-filter>
</service>
<service
android:name=".services.AutoFreezeQSTileService"
android:exported="true"
android:icon="@drawable/ic_round_frozen"
android:label="@string/auto_freeze"
android:permission="android.permission.BIND_QUICK_SETTINGS_TILE">
<intent-filter>
<action android:name="android.service.quicksettings.action.QS_TILE" />
</intent-filter>
</service>
</application>

</manifest>
5 changes: 5 additions & 0 deletions app/src/main/kotlin/com/aistra/hail/HailApp.kt
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,11 @@ class HailApp : Application() {
}
}

fun stopAutoFreezeService() {
stopService(Intent(app, AutoFreezeService::class.java))
setAutoFreezeServiceEnabled(false)
}

fun setAutoFreezeServiceEnabled(enabled: Boolean) {
packageManager.setComponentEnabledSetting(
ComponentName(app, AutoFreezeService::class.java),
Expand Down
3 changes: 3 additions & 0 deletions app/src/main/kotlin/com/aistra/hail/app/HailApi.kt
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,9 @@ object HailApi {
/** @since 0.6.0 */
const val ACTION_LOCK_FREEZE = "${BuildConfig.APPLICATION_ID}.action.LOCK_FREEZE"

/** TODO @since when? **/
const val DISABLE_AUTO_FREEZE_SERVICE_TEMPORARILY = "${BuildConfig.APPLICATION_ID}.action.DISABLE_AUTO_FREEZE_SERVICE_TEMPORARILY"

fun getIntentForPackage(action: String, packageName: String) =
Intent(action).putExtra(HailData.KEY_PACKAGE, packageName)

Expand Down
9 changes: 8 additions & 1 deletion app/src/main/kotlin/com/aistra/hail/app/HailData.kt
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import androidx.preference.PreferenceManager
import com.aistra.hail.BuildConfig
import com.aistra.hail.HailApp.Companion.app
import com.aistra.hail.R
import com.aistra.hail.services.AutoFreezeQSTileState
import com.aistra.hail.utils.HFiles
import org.json.JSONArray
import org.json.JSONObject
Expand Down Expand Up @@ -70,6 +71,7 @@ object HailData {
private const val COMPACT_ICON = "compact_icon"
private const val SYNTHESIZE_ADAPTIVE_ICONS = "synthesize_adaptive_icons"
const val AUTO_FREEZE_AFTER_LOCK = "auto_freeze_after_lock"
private const val AUTO_FREEZE_DISABLED_UNTIL = "auto_freeze_disabled_until"
private const val SKIP_WHILE_CHARGING = "skip_while_charging"
const val SKIP_FOREGROUND_APP = "skip_foreground_app"
const val SKIP_NOTIFYING_APP = "skip_notifying_app"
Expand All @@ -88,7 +90,12 @@ object HailData {
val tileAction get() = sp.getString(TILE_ACTION, ACTION_LOCK_FREEZE)
val dynamicShortcutAction get() = sp.getString(DYNAMIC_SHORTCUT_ACTION, ACTION_NONE)!!
val synthesizeAdaptiveIcons get() = sp.getBoolean(SYNTHESIZE_ADAPTIVE_ICONS, false)
val autoFreezeAfterLock get() = sp.getBoolean(AUTO_FREEZE_AFTER_LOCK, false)
var autoFreezeAfterLock
get() = sp.getBoolean(AUTO_FREEZE_AFTER_LOCK, false)
set(value) = sp.edit().putBoolean(AUTO_FREEZE_AFTER_LOCK, value).apply()
var autoFreezeDisabledUntil
get() = sp.getLong(AUTO_FREEZE_DISABLED_UNTIL, 0L)
set(value) = sp.edit().putLong(AUTO_FREEZE_DISABLED_UNTIL, value).apply()
val skipWhileCharging get() = sp.getBoolean(SKIP_WHILE_CHARGING, false)
val skipForegroundApp get() = sp.getBoolean(SKIP_FOREGROUND_APP, false)
val skipNotifyingApp get() = sp.getBoolean(SKIP_NOTIFYING_APP, false)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,142 @@
package com.aistra.hail.services

import android.annotation.SuppressLint
import android.os.Build
import android.service.quicksettings.Tile
import android.service.quicksettings.TileService
import android.text.format.DateUtils
import androidx.annotation.RequiresApi
import com.aistra.hail.HailApp.Companion.app
import com.aistra.hail.R
import com.aistra.hail.app.HailApi
import com.aistra.hail.app.HailData
import com.aistra.hail.utils.HTarget
import com.aistra.hail.work.HWork

@RequiresApi(Build.VERSION_CODES.N)
class AutoFreezeQSTileService : TileService() {
private var updateTileThread: Thread? = null
private var tileState = AutoFreezeQSTileState.ENABLED
private var nextClickShouldEnable = false

override fun onStartListening() {
super.onStartListening()

tileState = AutoFreezeQSTileState.tileStateFromDisabledUntil(HailData.autoFreezeDisabledUntil)
if (tileState != AutoFreezeQSTileState.ENABLED) {
// UX: assuming that the user wants to re-enable if tapping on the tile while disabled
nextClickShouldEnable = true
}

updateTileThread = Thread {
try {
while (true) {
updateTile()
// This shows the countdown nicely, but has the problem that it restarts the tile's label every second making the scrolling to restart. TODO solve some other way? Is it possible to avoid restarting of scrolling?
Thread.sleep(1000)
}
} catch (_: InterruptedException) {}
}
updateTileThread?.start()

updateTile()
}

override fun onStopListening() {
super.onStopListening()
updateTileThread?.interrupt()
updateTileThread = null
}

override fun onClick() {
super.onClick()

if (nextClickShouldEnable) {
tileState = AutoFreezeQSTileState.ENABLED
nextClickShouldEnable = false
} else {
tileState = tileState.next
}

HailData.autoFreezeDisabledUntil = tileState.disableUntil

when (tileState) {
AutoFreezeQSTileState.ENABLED -> {
HailData.autoFreezeAfterLock = true
HWork.cancelWork(HailApi.DISABLE_AUTO_FREEZE_SERVICE_TEMPORARILY)
app.setAutoFreezeService()
}
AutoFreezeQSTileState.DISABLED -> {
HailData.autoFreezeAfterLock = false
app.stopAutoFreezeService()
}
else -> {
HWork.disableAutoFreezeServiceFor(tileState.millis)
}
}
updateTile()
}

override fun onTileAdded() {
updateTile()
}

@SuppressLint("NewApi")
private fun updateTile() {
if (!HailData.autoFreezeAfterLock) {
qsTile.state = Tile.STATE_INACTIVE
if (HTarget.Q) qsTile.subtitle = getString(R.string.auto_freeze_tile_off)
else qsTile.label = getString(R.string.auto_freeze_tile_off)
} else if (HailData.autoFreezeDisabledUntil > System.currentTimeMillis()) {
qsTile.state = Tile.STATE_INACTIVE
if (HTarget.Q) qsTile.subtitle = disabledFor(HailData.autoFreezeDisabledUntil)
else qsTile.label = disabledFor(HailData.autoFreezeDisabledUntil)
} else {
qsTile.state = Tile.STATE_ACTIVE
if (HTarget.Q) qsTile.subtitle = getString(R.string.auto_freeze_tile_on)
else qsTile.label = getString(R.string.auto_freeze_tile_on)
}

qsTile.updateTile()
}

private fun disabledFor(epochMilliseconds: Long): String {
val timeout = epochMilliseconds - System.currentTimeMillis()
return DateUtils.formatElapsedTime(timeout / 1000)
}
}

enum class AutoFreezeQSTileState(val millis: Long) {
ENABLED(0),
DISABLED_FOR_ONE_MINUTE(60 * 1000),
DISABLED_FOR_FIVE_MINUTES(5 * 60 * 1000),
DISABLED_FOR_TEN_MINUTES(10 * 60 * 1000),
DISABLED_FOR_THIRTY_MINUTES(30 * 60 * 1000),
DISABLED_FOR_ONE_HOUR(60 * 60 * 1000),
DISABLED_FOR_TWO_HOURS(120 * 60 * 1000),
DISABLED(Long.MAX_VALUE / 2); // Not Long.MAX_VALUE so that adding System.currentTimeMillis while calculating 'disableUntil' doesn't make it turn around

val disableUntil: Long get() = System.currentTimeMillis() + millis

val next: AutoFreezeQSTileState
get() {
val values = enumValues<AutoFreezeQSTileState>()
val nextOrdinal = (ordinal + 1) % values.size
return values[nextOrdinal]
}

companion object {
fun tileStateFromDisabledUntil(disabledUntil: Long): AutoFreezeQSTileState {
var tileState = DISABLED

for (value in enumValues<AutoFreezeQSTileState>()) {
if (disabledUntil - System.currentTimeMillis() <= value.millis) {
tileState = value
break
}
}

return tileState
}
}
}
11 changes: 11 additions & 0 deletions app/src/main/kotlin/com/aistra/hail/work/AutoFreezeWorker.kt
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ class AutoFreezeWorker(context: Context, params: WorkerParameters) : Worker(cont
if ((inputData.getBoolean(HailData.ACTION_LOCK, true)
&& HSystem.isInteractive(applicationContext))
|| isSkipWhileCharging(applicationContext)
|| HailData.autoFreezeDisabledUntil > System.currentTimeMillis()
) return Result.success() // Not stopping the AutoFreezeService here. The worker will run at some point. Then we'll stop the Service
var i = 0
var denied = false
Expand All @@ -38,4 +39,14 @@ class AutoFreezeWorker(context: Context, params: WorkerParameters) : Worker(cont
AppManager.isAppFrozen(appInfo.packageName) || (HailData.skipForegroundApp && HSystem.isForegroundApp(
context, appInfo.packageName
)) || (HailData.skipNotifyingApp && AutoFreezeService.instance.activeNotifications.any { it.packageName == appInfo.packageName }) || appInfo.whitelisted

class RestartAutoFreezeServiceWorker(private val context: Context, params: WorkerParameters) : Worker(context, params) {
override fun doWork(): Result {
app.setAutoFreezeService()
if (!HSystem.isInteractive(context)) { // Only run freeze directly if screen is off
HWork.setAutoFreeze(false) // TODO is false correct here? This was added after I implemented it and I'm not sure right now...
}
return Result.success()
}
}
}
11 changes: 11 additions & 0 deletions app/src/main/kotlin/com/aistra/hail/work/HWork.kt
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import androidx.work.ExistingWorkPolicy
import androidx.work.OneTimeWorkRequestBuilder
import androidx.work.WorkManager
import androidx.work.workDataOf
import com.aistra.hail.HailApp
import com.aistra.hail.HailApp.Companion.app
import com.aistra.hail.app.HailApi
import com.aistra.hail.app.HailData
Expand Down Expand Up @@ -37,4 +38,14 @@ object HWork {
}
)
}

fun disableAutoFreezeServiceFor(delay: Long) {
WorkManager.getInstance(HailApp.app).enqueueUniqueWork(
HailApi.DISABLE_AUTO_FREEZE_SERVICE_TEMPORARILY,
ExistingWorkPolicy.REPLACE,
OneTimeWorkRequestBuilder<AutoFreezeWorker.RestartAutoFreezeServiceWorker>()
.setInitialDelay(delay, TimeUnit.MILLISECONDS)
.build()
)
}
}
3 changes: 3 additions & 0 deletions app/src/main/res/values-ar/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,9 @@
<string name="working_mode">وضع العمل</string>
<string name="sort_name">التسمية</string>
<string name="auto_freeze_notification_title">خدمة التجميد التلقائي قيد التشغيل</string>
<string name="auto_freeze_notification_text_disabled_until">Disabled until %s</string>
<string name="auto_freeze_tile_on">On</string>
<string name="auto_freeze_tile_off">Off</string>
<string name="filter_frozen_apps">مجمد</string>
<string name="msg_selected">المحدد: %s</string>
<string name="action_terminal">الطرفية</string>
Expand Down
3 changes: 3 additions & 0 deletions app/src/main/res/values-de/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,9 @@
<string name="tile_action">Kachel-Aktion</string>
<string name="auto_freeze">Automatisches Einfrieren</string>
<string name="auto_freeze_notification_title">Der automatische Einfrierdienst läuft</string>
<string name="auto_freeze_notification_text_disabled_until">Deaktiviert bis %s</string>
<string name="auto_freeze_tile_on">An</string>
<string name="auto_freeze_tile_off">Aus</string>
<string name="auto_freeze_after_lock">Nach der Bildschirmsperre</string>
<string name="skip_while_charging">Überspringen beim Laden</string>
<string name="skip_foreground_app">Anwendung im Vordergrund überspringen</string>
Expand Down
3 changes: 3 additions & 0 deletions app/src/main/res/values-es/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,9 @@
<string name="tile_action">Acción del Tile</string>
<string name="auto_freeze">Congelación automática</string>
<string name="auto_freeze_notification_title">El servicio de congelación automática está funcionando</string>
<string name="auto_freeze_notification_text_disabled_until">Desactivado hasta %s</string>
<string name="auto_freeze_tile_on">Activado</string>
<string name="auto_freeze_tile_off">Desactivado</string>
<string name="auto_freeze_after_lock">Después de bloquear la pantalla</string>
<string name="skip_while_charging">Omitir durante la carga</string>
<string name="skip_foreground_app">Omitir aplicación corriendo en primer plano</string>
Expand Down
3 changes: 3 additions & 0 deletions app/src/main/res/values-in/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,9 @@
<string name="msg_text_copied">Disalin: %s</string>
<string name="auto_freeze">Bekukan otomatis</string>
<string name="auto_freeze_notification_title">Layanan bekukan otomatis sedang berjalan</string>
<string name="auto_freeze_notification_text_disabled_until">Disabled until %s</string>
<string name="auto_freeze_tile_on">On</string>
<string name="auto_freeze_tile_off">Off</string>
<string name="shizuku_missing">Shizuku tidak ditemukan :(</string>
<string name="msg_exported">Terekspor : %s</string>
<plurals name="deferred_task_entry">
Expand Down
3 changes: 3 additions & 0 deletions app/src/main/res/values-it/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,9 @@
<string name="tile_action">Tile action</string>
<string name="auto_freeze">Auto freeze</string>
<string name="auto_freeze_notification_title">Auto freeze service is running</string>
<string name="auto_freeze_notification_text_disabled_until">Disabled until %s</string>
<string name="auto_freeze_tile_on">On</string>
<string name="auto_freeze_tile_off">Off</string>
<string name="auto_freeze_after_lock">After screen locked</string>
<string name="skip_while_charging">Skip while charging</string>
<string name="skip_foreground_app">Skip foreground app</string>
Expand Down
3 changes: 3 additions & 0 deletions app/src/main/res/values-ja-rJP/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,9 @@
<string name="tile_action">タイルアクション</string>
<string name="auto_freeze">自動凍結</string>
<string name="auto_freeze_notification_title">自動凍結を待機中</string>
<string name="auto_freeze_notification_text_disabled_until">Disabled until %s</string>
<string name="auto_freeze_tile_on">On</string>
<string name="auto_freeze_tile_off">Off</string>
<string name="auto_freeze_after_lock">画面ロック後</string>
<string name="skip_while_charging">充電時にスキップ</string>
<string name="skip_foreground_app">フォアグラウンドアプリをスキップ</string>
Expand Down
3 changes: 3 additions & 0 deletions app/src/main/res/values-nb-rNO/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,9 @@
<string name="mode_shizuku_hide">Shizuku — skjul</string>
<string name="tile_action">Flishandling</string>
<string name="auto_freeze_notification_title">Autofrysningstjenesten kjører</string>
<string name="auto_freeze_notification_text_disabled_until">Disabled until %s</string>
<string name="auto_freeze_tile_on">On</string>
<string name="auto_freeze_tile_off">Off</string>
<string name="mode_shizuku_suspend">Shizuku — hvilemodus</string>
<string name="title_remove_owner">Fjern enhetseier</string>
<string name="tap_to_select">Trykk for å å velge flere</string>
Expand Down
3 changes: 3 additions & 0 deletions app/src/main/res/values-pt-rBR/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,9 @@
<string name="working_mode">Modo de trabalho</string>
<string name="sort_name">Nome</string>
<string name="auto_freeze_notification_title">O serviço de auto congelamento está em execução</string>
<string name="auto_freeze_notification_text_disabled_until">Disabled until %s</string>
<string name="auto_freeze_tile_on">On</string>
<string name="auto_freeze_tile_off">Off</string>
<string name="filter_frozen_apps">Congelados</string>
<string name="msg_selected">Selecionado: %s</string>
<string name="action_terminal">Terminal</string>
Expand Down
3 changes: 3 additions & 0 deletions app/src/main/res/values-ru/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,9 @@
<string name="tile_action">Действие плитки</string>
<string name="auto_freeze">Автозаморозка</string>
<string name="auto_freeze_notification_title">Служба автозаморозки работает</string>
<string name="auto_freeze_notification_text_disabled_until">Disabled until %s</string>
<string name="auto_freeze_tile_on">On</string>
<string name="auto_freeze_tile_off">Off</string>
<string name="auto_freeze_after_lock">После блокировки экрана</string>
<string name="skip_while_charging">Не замораживать во время зарядки</string>
<string name="skip_foreground_app">Не замораживать приложения переднего плана</string>
Expand Down
3 changes: 3 additions & 0 deletions app/src/main/res/values-tr/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,9 @@
<string name="tile_action">Hızlı eylem</string>
<string name="auto_freeze">Otomatik dondur</string>
<string name="auto_freeze_notification_title">Otomatik dondurma hizmeti çalışıyor</string>
<string name="auto_freeze_notification_text_disabled_until">Disabled until %s</string>
<string name="auto_freeze_tile_on">On</string>
<string name="auto_freeze_tile_off">Off</string>
<string name="msg_set_owner">adb komutu hatalı:
\n%s</string>
<string name="synthesize_adaptive_icons">Uyarlanabilir simgeler kullan</string>
Expand Down
3 changes: 3 additions & 0 deletions app/src/main/res/values-uk/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,9 @@
<string name="auto_freeze_after_lock">Після блокування екрану</string>
<string name="auto_freeze_delay">Затримка заморозки (хвилини)</string>
<string name="auto_freeze_notification_title">Запущено службу автозаморожування</string>
<string name="auto_freeze_notification_text_disabled_until">Disabled until %s</string>
<string name="auto_freeze_tile_on">On</string>
<string name="auto_freeze_tile_off">Off</string>
<string name="compact_icon">Компактні іконки</string>
<string name="donate_alipay">Alipay</string>
<string name="donate_bilibili">Bilibili</string>
Expand Down
3 changes: 3 additions & 0 deletions app/src/main/res/values-zh-rCN/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,9 @@
<string name="tile_action">快捷设置操作</string>
<string name="auto_freeze">自动冻结</string>
<string name="auto_freeze_notification_title">自动冻结服务正在运行</string>
<string name="auto_freeze_notification_text_disabled_until">Disabled until %s</string>
<string name="auto_freeze_tile_on">On</string>
<string name="auto_freeze_tile_off">Off</string>
<string name="auto_freeze_after_lock">锁屏后</string>
<string name="skip_while_charging">充电时例外</string>
<string name="skip_foreground_app">保留前台应用</string>
Expand Down
3 changes: 3 additions & 0 deletions app/src/main/res/values-zh-rTW/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,9 @@
<string name="tile_action">圖塊動作</string>
<string name="auto_freeze">自動凍結</string>
<string name="auto_freeze_notification_title">自動凍結服務正在執行</string>
<string name="auto_freeze_notification_text_disabled_until">Disabled until %s</string>
<string name="auto_freeze_tile_on">On</string>
<string name="auto_freeze_tile_off">Off</string>x
<string name="auto_freeze_after_lock">螢幕鎖定後</string>
<string name="skip_while_charging">充電時跳過</string>
<string name="skip_foreground_app">跳過前景應用程式</string>
Expand Down
Loading