Recently Written · git

ink-dim

Ink Dim: tap to set the frontlight of a Viwoods AiPaper reader below the lowest system level. Tap again to go back.

git clone https://github.com/equwal/ink-dim

Log | Files | Refs


app/src/main/java/dev/equwal/inkdim/SettingsActivity.kt (4332 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         col.header("More apps")
64         for (app in MoreApps.ALL) {
65             col.row(app.name, app.line) { start(Intent(Intent.ACTION_VIEW, Uri.parse(app.url))) }
66         }
67     }
68 
69     private fun lightState(): String = when {
70         !Shell.ready -> "Needs Shizuku"
71         light == null -> "Looking"
72         light == true -> "Found"
73         else -> "None"
74     }
75 
76     /** The four steps to shell access, from the device itself. */
77     private fun steps(col: LinearLayout) {
78         val state = Shell.state(this)
79         col.note("1. Install Shizuku. It is free.")
80         if (state == Shell.State.NOT_INSTALLED) {
81             col.button("Get Shizuku") {
82                 if (!start(Intent(Intent.ACTION_VIEW, Uri.parse("market://details?id=" + Shell.SHIZUKU_PACKAGE)))) {
83                     start(Intent(Intent.ACTION_VIEW, Uri.parse("https://shizuku.rikka.app/download/")))
84                 }
85             }
86         }
87 
88         col.note("2. Turn on wireless debugging in Developer options.")
89         col.button("Open Developer options") {
90             if (!start(Intent(Settings.ACTION_APPLICATION_DEVELOPMENT_SETTINGS))) {
91                 start(Intent(Settings.ACTION_DEVICE_INFO_SETTINGS))
92             }
93         }
94 
95         col.note("3. In Shizuku, pair with the code, then press Start.")
96         if (state != Shell.State.NOT_INSTALLED) {
97             col.button("Open Shizuku") {
98                 packageManager.getLaunchIntentForPackage(Shell.SHIZUKU_PACKAGE)?.let { start(it) }
99             }
100         }
101 
102         col.note("4. Let Ink Dim use Shizuku.")
103         if (state == Shell.State.NO_PERMISSION) {
104             col.button("Ask for permission") { Shell.requestPermission() }
105         }
106     }
107 
108     private fun start(i: Intent): Boolean =
109         runCatching { startActivity(i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)); true }.getOrDefault(false)
110 
111     private companion object {
112         const val REPO = "https://github.com/equwal/ink-dim"
113         const val TIP = "https://ko-fi.com/truex"
114     }
115 }