app/src/main/java/dev/equwal/inkdim/SettingsActivity.kt (4155 bytes)
1 // SPDX-License-Identifier: GPL-3.0-or-later 2 // Copyright (c) 2026 equwal 3 package dev.equwal.inkdim 4 5 import android.app.Activity 6 import android.content.Intent 7 import android.net.Uri 8 import android.provider.Settings 9 import android.widget.LinearLayout 10 import dev.equwal.inkdim.Ui.button 11 import dev.equwal.inkdim.Ui.header 12 import dev.equwal.inkdim.Ui.note 13 import dev.equwal.inkdim.Ui.primaryButton 14 import dev.equwal.inkdim.Ui.row 15 16 /** 17 * What the app needs, and what the app is. 18 * 19 * The launcher icon only toggles, so this screen opens from the icon shortcut, 20 * or by itself when the app cannot do the toggle. 21 */ 22 class SettingsActivity : Activity() { 23 24 /** Null until the light node is looked for. */ 25 private var light: Boolean? = null 26 27 private val redraw: () -> Unit = { if (!isFinishing) build() } 28 29 override fun onResume() { 30 super.onResume() 31 Shell.onChange(redraw) 32 Shell.connect(this) 33 build() 34 if (Shell.ready) Toggle.hasNode { found -> light = found; redraw() } 35 } 36 37 override fun onPause() { 38 super.onPause() 39 Shell.removeOnChange(redraw) 40 } 41 42 private fun build() { 43 val col = Ui.page(this, "Ink Dim") 44 45 col.header("Extra dim") 46 col.note("Sets the frontlight below the lowest level of the system.") 47 col.note("Tap the icon to turn it on. Tap it again for the system level.") 48 col.row("Light", null, enabled = false, state = lightState()) 49 if (light == false) col.note("This device has no light that the app knows.") 50 col.primaryButton("Try it") { Toggle.run(this, Dim.Action.TOGGLE) } 51 52 col.header("Shizuku") 53 col.note("The light belongs to the system. Shizuku gives the app a shell. The shell then writes the light.") 54 col.row("State", null, enabled = false, state = Shell.describe(this)) 55 if (Shell.state(this) != Shell.State.READY) steps(col) 56 57 col.header("About") 58 col.row("Version", null, enabled = false, state = BuildConfig.VERSION_NAME) 59 col.row("Licence", null, enabled = false, state = "GPL-3.0-or-later") 60 col.row("Source code", REPO.removePrefix("https://")) { start(Intent(Intent.ACTION_VIEW, Uri.parse(REPO))) } 61 col.row("Buy me a coffee", TIP.removePrefix("https://")) { start(Intent(Intent.ACTION_VIEW, Uri.parse(TIP))) } 62 } 63 64 private fun lightState(): String = when { 65 !Shell.ready -> "Needs Shizuku" 66 light == null -> "Looking" 67 light == true -> "Found" 68 else -> "None" 69 } 70 71 /** The four steps to shell access, from the device itself. */ 72 private fun steps(col: LinearLayout) { 73 val state = Shell.state(this) 74 col.note("1. Install Shizuku. It is free.") 75 if (state == Shell.State.NOT_INSTALLED) { 76 col.button("Get Shizuku") { 77 if (!start(Intent(Intent.ACTION_VIEW, Uri.parse("market://details?id=" + Shell.SHIZUKU_PACKAGE)))) { 78 start(Intent(Intent.ACTION_VIEW, Uri.parse("https://shizuku.rikka.app/download/"))) 79 } 80 } 81 } 82 83 col.note("2. Turn on wireless debugging in Developer options.") 84 col.button("Open Developer options") { 85 if (!start(Intent(Settings.ACTION_APPLICATION_DEVELOPMENT_SETTINGS))) { 86 start(Intent(Settings.ACTION_DEVICE_INFO_SETTINGS)) 87 } 88 } 89 90 col.note("3. In Shizuku, pair with the code, then press Start.") 91 if (state != Shell.State.NOT_INSTALLED) { 92 col.button("Open Shizuku") { 93 packageManager.getLaunchIntentForPackage(Shell.SHIZUKU_PACKAGE)?.let { start(it) } 94 } 95 } 96 97 col.note("4. Let Ink Dim use Shizuku.") 98 if (state == Shell.State.NO_PERMISSION) { 99 col.button("Ask for permission") { Shell.requestPermission() } 100 } 101 } 102 103 private fun start(i: Intent): Boolean = 104 runCatching { startActivity(i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)); true }.getOrDefault(false) 105 106 private companion object { 107 const val REPO = "https://github.com/equwal/ink-dim" 108 const val TIP = "https://ko-fi.com/truex" 109 } 110 }