Recently Written · git

assistkey

Hardware key remapper for the Viwoods AiPaper Reader: AI key, volume keys and power, with multi-tap, hold and chords

git clone https://github.com/equwal/assistkey

Log | Files | Refs


CHANGELOG.md (22011 bytes)

1 # Changelog
2 
3 ## 0.1.2-beta - 2026-09-26
4 
5 Version code 18.
6 
7 - **Smaller.** R8 now removes unused code from the release builds. F-Droid asks
8   for it. Names of classes stay the same.
9 - **Reproducible F-Droid build.** The signed APK has no dependency list for
10   Google in it. F-Droid builds the `fdroid` flavour itself and checks that it is
11   the same as the signed APK on GitHub.
12 
13 ## 0.1.1-beta - 2026-09-21
14 
15 Version code 17. The source code is now public under GPL-3.0-or-later.
16 
17 - **F-Droid.** A new build, the `fdroid` flavour, is free and complete. It has
18   no licence check, no Google Play Billing and no apps of other makers inside.
19   Its permissions are those of the `full` build, less the permission to
20   install apps. F-Droid builds each new `v*` tag by itself; see `fdroid/`.
21 - The `play` and `full` builds do not change.
22 
23 ## 0.1.0-beta - 2026-09-21
24 
25 Version code 16. The first beta. The alpha versions end here.
26 
27 - **Updates: Ink Update.** Rebind has no internet permission, so it cannot
28   look for a new version. Ink Update, an open source app of its own, does
29   that: F-Droid first, then Google Play (it leaves an app that Google Play
30   installed to Google Play), then GitHub. It makes a notification and opens
31   the page. Setup has an "Updates" row that installs or opens it. The build
32   for direct install carries it.
33 - The build for direct install carries Ink Dim too. Hardware hacks lists it.
34 - The lists of carried apps are named "Extensions".
35 
36 - **Settings are safe across versions and across an uninstall.** An update
37   always kept the settings: they are in the data of the app. An uninstall
38   removed them. Now Android asks at uninstall whether to keep the data
39   (`hasFragileUserData`), and Rebind keeps an automatic copy of the settings in
40   `Documents/Rebind/rebind-settings.json`, which an uninstall does not touch.
41   Import opens that folder. `StoredFormatTest` holds the texts that every
42   0.0.x version stored, so a new version cannot stop reading them unseen.
43 
44 ## 0.0.15-alpha - 2026-09-21
45 
46 Version code 15.
47 
48 - **The Recents button opens Ink Recents.** Android does not let an app take
49   the place of the recent-apps screen of the system. Rebind now sees that
50   screen open (the task manager of the Viwoods launcher, or the stock Android
51   one), closes it, and opens Ink Recents. It works for the Recents button of
52   the bar, for the swipe, and for the Recents action. Home and recents has the
53   switch "Recents button opens Ink Recents". It is on when Ink Recents is
54   installed. Tests: `SystemRecentsTest`.
55 
56 ## 0.0.14-alpha - 2026-09-21
57 
58 Version code 14.
59 
60 - **Permissions covers the extensions again.** New items, each only where it
61   can apply: "Install apps from Rebind" (the build that carries apps), "Ink
62   Recents: app usage data" (when Ink Recents is installed), and "Home screen"
63   to choose inkOS or ThinkLauncher (when one is installed). "Set up what is
64   missing" walks through them too. The main screen still counts only the
65   grants of Rebind itself.
66 - **Fix: voice typing said "The microphone is not allowed" although it was
67   allowed.** Android gives the microphone to an app only while that app is in
68   use. The Viwoods firmware does not count a speech app as in use while it
69   listens in the background for another app, so Whisper was refused (error
70   9). Rebind now goes to the speech screen of the speech app, where that app
71   is in use, takes the words from its result, and remembers the route.
72   Regression test: `DictationRouteTest`.
73 - **Fix: "Let Rebind get the Power hold" opened nothing.** Android has no
74   request dialog for the assistant role. The row now opens the settings page
75   "Default digital assistant app".
76 
77 ## 0.0.13-alpha - 2026-09-21
78 
79 Version code 13.
80 
81 - **Home screens: inkOS and ThinkLauncher in place of CLauncher.** The build
82   for direct install carries inkOS v0.6 and ThinkLauncher v3.0, both made for
83   e-ink, both GPL-3.0, each the release file of its maker and not changed.
84   ThinkLauncher has the internet permission of its own. Rebind still has
85   none.
86 
87 - **Change a button from the Done step.** "Change what it does" and "Change
88   how you press it" go back to those steps with the button kept. Back on the
89   Done step goes to the actions too. Tests: `Route.back`.
90 - **Show or hide the button bar** is an action (build for direct install).
91   Android 16 has no auto-hide for the three-button bar, so a button does it.
92   It uses the shell commands of the Navigation screen and keeps the gestures
93   as they are. The allow step asks for shell access for this action and for
94   the light actions.
95 - **AI voice prompt** is an action of its own (Viwoods). It is what the
96   firmware does on a hold of the AI key: the Viwoods AI screen, told to start
97   its voice prompt. It needs the Viwoods AI account, as the stock hold does.
98   A component launch can now carry text extras (`pkg/class?key=value`).
99   Tests: `ComponentPayloadTest`.
100 - **Ask when the user tries it.** The first run asks for every grant once.
101   After that the app asks at the moment something is missing: after a menu is
102   saved, after the Power switch on the Navigation screen, when a Power press
103   arrives while button remapping is off, and when voice typing starts with no
104   microphone grant. Before, those places showed a short message or nothing.
105 - **Fix: system Back always closed the button setup.** From Android 13 the
106   system does not call `onBackPressed` for an app with this target version.
107   The setup now registers the Back callback, and Back goes one step back.
108   Checked on the reader: Done, actions, how to press, main screen.
109 
110 ## 0.0.12-alpha - 2026-09-21
111 
112 Version code 12.
113 
114 - **Apps of other makers.** The build for direct install carries two apps and
115   can install them: CLauncher v5.3.0 (the release APK of its maker, not
116   changed) and Ink Recents 0.1.1 (open source). Home and recents lists them. Android asks before
117   each install. The APKs are in the build, because Rebind has no internet
118   permission. The Google Play build carries nothing and has no install
119   permission: Google Play does not allow that here. It opens the page of the
120   maker.
121 - Whisper 3.7 (speech to text on the device, MIT, the F-Droid build) is the
122   third app that the build for direct install carries. Voice typing lists it.
123 - **The home screen of Rebind is gone**, with its settings screens. CLauncher
124   is the home screen now, as its maker released it. An old settings file that
125   has home screen settings still imports. Those settings are skipped.
126 - **Recent apps is a program of its own: Ink Recents** (open source,
127   github.com/equwal/ink-recents). Rebind no longer has that screen, and no
128   longer asks for usage access or `KILL_BACKGROUND_PROCESSES`. The Recent apps
129   action opens Ink Recents. Old bindings keep working. Where Ink Recents is
130   not installed, the action opens the screen that offers it.
131 - Hardware hacks: the double tap of Power is one row. Its way in is the camera
132   intent or the wallet intent, as the device decides. There is no wallet
133   button.
134 - The setup of a Power combination no longer says the same thing twice.
135 
136 - **Hardware hacks** is a tile on the main screen with a screen of its own:
137   hold Power (assistant role), double tap Power (camera intent), the wallet
138   button, the full Power button (shell access), extra-dim light, and the
139   button settings of the device. Advanced no longer holds them.
140 
141 ## 0.0.11-alpha - 2026-09-21
142 
143 Version code 11.
144 
145 - **Fix: a Camera key in the drawing of a device that has none.** The Viwoods
146   reader declares a camera key to Android and has no such button. Detection
147   put the declared key in the drawing. The drawing now shows only the buttons
148   that the device profile knows, and a button that was really pressed in
149   normal use. The Detect screen still lists what the device declares, and
150   marks a key that was never seen. Regression test: `DeviceKeysTest`.
151   The double tap of Power uses the camera *intent* of Android. It needs no
152   camera button.
153 
154 ## 0.0.10-alpha - 2026-09-21
155 
156 Version code 10.
157 
158 - **No Google Play, no lock.** On a device where the Google Play app is not
159   installed or is turned off, the app is free and complete. There is no way
160   to buy there, so there is nothing to lock. The licence screen says "Free on
161   this device". A bought licence still comes first. Tests: `LicenseDecideTest`.
162 - The build for direct install has a tip link on the Licence screen
163   (ko-fi.com/truex). A tip unlocks nothing. The Google Play build has no such
164   link, because Google Play does not allow it.
165 - The reasons in the allow step are hints of three to seven words. The app
166   says "double tap" for Power too.
167 
168 ## 0.0.9-alpha - 2026-09-21
169 
170 Version code 9.
171 
172 - **New name: Rebind.** The name says what the app does, and it has the words
173   that buyers type in Play search. The package id stays `dev.equwal.assistkey`,
174   so an update keeps all settings. The settings file keeps its `AssistKey`
175   marker, so old exports still import.
176 - **Recent apps.** Swipe up closes the app. Swipe down closes all the others.
177   One swipe sideways moves one card in one step, with no glide. When the screen
178   opens, the card jumps up and sideways once to show the swipes. "Close all but
179   this app" and "Close all" are two tall buttons with space between them.
180   Closing works without shell access too: Android ends the background
181   processes of the app (`KILL_BACKGROUND_PROCESSES`, a normal permission).
182 - **Hardware hacks** have their own box under Advanced: hold Power, double
183   press Power, the wallet button, the full Power button, extra-dim light, and
184   the button settings of the device.
185 - **Ask when it is needed, everywhere.** A binding made under Advanced now opens
186   the same "allow" step as the guided setup, when something is missing.
187 - **The drawing is the main screen.** The device and its buttons are on the
188   first screen. Each button shows what it does now. Tap a button to set it up.
189   Tap two buttons to set up a combination.
190 - **Button order.** A device profile gives the order of its buttons from the
191   top down. Viwoods AiPaper: Power, Volume up, Volume down, AI key.
192 - **On-screen button.** A new button that needs no hardware: a small round
193   button that floats over every app. Tap it to do the action, drag it to move
194   it. The key filter draws it, only while it has an action. Android's own
195   accessibility button is not used, because Android shows that button to every
196   user as soon as a service asks for it.
197 - **More ways to press.** Step two lists tap, double tap, triple tap, hold, 4
198   taps and 5 taps, and an Advanced row with every gesture of the button.
199 - **More actions.** Step three adds Lock screen and Screenshot, and an Advanced
200   row with every action.
201 - **Ask when it is needed.** A Power press that Android hides from apps is now
202   offered where the build can have shell access. The app then asks for shell
203   access, which opens the full Power button. After a double press of Power is
204   set up, the app offers the wallet way for devices that use it.
205 - **Device detection.** At first start the app finds which buttons the device
206   has, and what the device can do. It never asks the user to press a button.
207   Advanced > Detect this device shows the result. The device report has it too.
208 - **Less text.** All "More about this" rows are gone. Notes are one short
209   sentence. The accessibility disclosure is short. Google Play requires it, so
210   it stays.
211 - Tests: selection rules of the drawing, the on-screen button route, shell
212   access as a need, detection parser and round trip.
213 
214 ## 0.0.8-alpha - 2026-09-21
215 
216 Version code 8.
217 
218 - **Set up a button.** The main screen starts with one large button. The user
219   taps a button in a drawing of the device, chooses tap, double tap or hold,
220   and chooses what the button does. The app then works out what that needs
221   (key filter, assistant role, camera role, microphone) and asks only for
222   that, by what it does. The app never asks the user to press a key to find
223   it. A button that is not in the drawing is chosen from a list of names.
224 - **New main screen.** A top bar with the licence state, "Your buttons" with
225   the bindings in use, and five tiles: Navigation, Voice typing, Home and
226   recents, Setup, Advanced. It fits on one screen with no scroll.
227 - **Advanced > Full control.** The screens from before (every key and gesture,
228   the Power button, two-key combinations) are all still there. Guided setup
229   and full control edit the same bindings.
230 - All screens use one look: title bar with a back arrow, state chips, one
231   filled main button for each screen, less text, details behind "More".
232 - Tests: `RouteTest` (what a wish needs, which gestures a button can have) and
233   `SummaryTest` (the one-line states on the main screen).
234 
235 ## 0.0.7-alpha - 2026-09-21
236 
237 Version code 7.
238 
239 - **Fix: Extra dim toggle.** On now goes to the lowest level (1). Off gives the
240   light back to the brightness set in the system. Before, on used the level
241   that was last in use, or a middle level. Regression tests added.
242 - **Emergency SOS switch.** Android starts Emergency SOS on five quick Power
243   presses, which collides with a 5-tap binding. The Power screen now has a
244   switch for it (`emergency_gesture_enabled`). The app never turns it off by
245   itself. The switch shows only where the app can write the setting.
246 - **Permissions screen.** Every grant the app can use, with what it is for and
247   whether it is granted. "Set up what is missing" opens the grant screens one
248   after the other. It opens once by itself on the first run and can be run
249   again at any time from Setup > Permissions.
250 - The accessibility disclosure is one shared text now, and it names voice
251   typing and the app-in-front note, which the old text did not.
252 - Recent apps: each card says "Swipe up to close", and there is "Close all but
253   <app>" beside "Close all".
254 - Store listing: title is now "AssistKey: E-Ink Key Remap", with no maker name
255   in the title and a not-affiliated line in the description.
256 - Shell access and the extra-dim light are under Advanced now, and are not
257   counted as missing permissions. They are for the few devices with Shizuku or
258   root; the app is complete without them.
259 - **Ready-made menus.** The action list offers menus that can be bound in one
260   tap: Brightness (`full` build), Navigation, System, Sound and media, Page
261   turning, and Viwoods AI on Viwoods devices. Each is an ordinary menu after it
262   is bound, and the menu editor can change it.
263 - **Brightness up and down.** Two more light actions, for the system
264   brightness. A step is a quarter of the present value and at least 5.
265 - **Recent apps: easier to read, nicer to scroll.** One swipe moves one card, in
266   the direction of the swipe. A row of icons under the cards shows every recent
267   app at once and marks the one in the middle; a tap on an icon goes to its
268   card. The heading says which app and "2 of 12".
269 - The three light actions are now named Extra dim toggle, Extra dim darker and
270   Extra dim brighter. A binding made by 0.0.6 shows the new name with no change.
271 
272 ## 0.0.6-alpha - 2026-09-21
273 
274 Version code 6.
275 
276 - **Voice typing prefers speech recognition on the device.** When the user has
277   not chosen a speech app, an on-device one (Whisper, FUTO Voice Input, Vosk,
278   Sayboard, Sherpa) wins over one that may use a server. The Voice typing screen
279   says which kind each app is.
280 - **A route to local Whisper.** If no on-device speech app is installed, the
281   screen offers Whisper from F-Droid (`org.woheller69.whisper`): offline after
282   the model download, many languages, automatic language detection.
283 - Language is "Detect the language" by default. A fixed language tag stays
284   possible.
285 - **Menu of actions.** A gesture can open a menu that holds any number of
286   actions, so there can be more actions than keys. The menu lives in its own
287   binding, so export, import and delete treat it like any other binding.
288 - **Export and import.** Settings as one JSON file: save, share, open, paste.
289   The licence, saved firmware values and device facts never enter the file, and
290   a file cannot write them.
291 - **Extra-dim from a key.** Three actions under Light: darker, brighter, on and
292   off. `full` build only.
293 - First unit tests, 20 in all: the speech app choice rule, the settings file
294   round trip (500 random cases) and its allow-list, the light level steps, the
295   menu round trip. Run them with `./gradlew testPlayReleaseUnitTest`.
296 
297 ## 0.0.5-alpha - 2026-09-21
298 
299 Version code 5.
300 
301 - **Recent apps as cards.** The list is now a row of cards, like the Android
302   switcher: swipe sideways, tap a card to open it, swipe a card up to close it.
303   It is drawn for e-ink: outlines only, and the row jumps from card to card with
304   no animation. With shell access a card is a real task and can be closed
305   (`am stack remove`). Where the shell is root, a card shows the picture the
306   system keeps of the task. Otherwise a card shows the app icon.
307 
308 ## 0.0.4-alpha - 2026-09-20
309 
310 Version code 4.
311 
312 - **Voice typing.** A new action. Press the key, speak, and the words go where
313   the cursor is. The app has no speech engine: it uses the Android
314   SpeechRecognizer interface, so any speech recognition app on the device does
315   the listening. The accessibility service puts the text into the focused
316   field. Password fields are never written to.
317 - **Two builds.** `play` for Google Play has no Shizuku code and no Shizuku
318   permission. `full` for direct install keeps shell access. Same app id and
319   signature, so one can replace the other.
320 - **Viwoods: AI key goes back.** Inside the AI screen or the crop screen, the AI
321   key returns to the app that was in use before. Switch on the AI key screen.
322   Test: `tools/e2e/ai-key-return.sh`.
323 - **Fix: Power always wakes and unlocks.** While the app manages the Power
324   button, a press on a sleeping or locked device is never a gesture. The app
325   also sends the wake and the keyguard dismissal through the shell, so waking
326   does not depend on the firmware. Regression test: `tools/e2e/power-wake.sh`.
327 
328 Known limits:
329 
330 - Voice typing needs a speech recognition app that has its own microphone
331   permission. The Viwoods voice prompt cannot be used: it sends audio to the
332   Viwoods cloud and has no interface for other apps.
333 - The listening screen pauses the app behind it for a moment. An app that
334   clears its text field on resume loses what was typed before.
335 
336 ## 0.0.3-alpha - 2026-09-20
337 
338 Version code 3.
339 
340 - **Shell access** through Shizuku, set up on the device over wireless
341   debugging. No computer, no root.
342 - **Power button, properly.** With shell access: tap, double tap, any number
343   of taps, hold, and true combinations. Defaults: tap Back, hold Home (closing
344   the keyboard first), double tap Recents, triple tap lock. The firmware is
345   told to do nothing on Power meanwhile, which is what stops a single tap from
346   swallowing a double tap, and gets the button back whenever shell access goes.
347 - **Navigation applies itself.** Bar, gestures and Power key in any mix, applied
348   in-app through the shell; adb commands only as the fallback.
349 - **One interface.** Assistant, camera and wallet are no longer "channels"
350   beside the key filter; they are the Power button's side doors for when there
351   is no shell access, and live on the Power screen.
352 - **Any Android device.** Viwoods is now one device profile. More key types;
353   a key appears once the device has produced it.
354 - **Extra-dim light**, below the system's brightness floor.
355 - **Home screen** and **recent apps list**, text-only, made for e-ink.
356 - **Device report**: what a tester can send to get a device supported. Shown in
357   full, sent only by the user.
358 - New action: Home, closing the keyboard first.
359 
360 Known limits:
361 
362 - Shizuku started over wireless debugging stops at restart; Power reverts to
363   the system until it is started again.
364 - Extra-dim needs a root-level shell.
365 - Purchases are still untested.
366 
367 ## 0.0.2-alpha — 2026-09-20
368 
369 Version code 2.
370 
371 - **Navigation screen.** Button bar, swipe gestures and Power key combinations
372   in any mix, with five named setups. The system half cannot be switched by an
373   app, so the screen reports the live state and gives the commands;
374   `tools/nav-mode` runs them.
375 - **Power key combinations.** Hold Power, then press the AI key, Volume up or
376   Volume down. Defaults to Home, Back and Recents. These three keep working
377   when the app is locked, so a reader with no bar and no gestures always has a
378   way out.
379 - **AI key hook.** Found that the firmware opens its AI screen on every AI key
380   press whether or not an app consumed it. `tools/ai-key hook` points the
381   firmware at a new entry point instead; taps then work cleanly. The app says
382   which state it is in and what that costs.
383 - Fixed: "ai key" in labels.
384 
385 Known limits:
386 
387 - The notification-shade action does nothing on this firmware.
388 - With the AI key hooked, that key has taps only: no hold, no volume
389   combinations.
390 
391 ## 0.0.1-alpha — 2026-09-20
392 
393 First alpha. Version code 1.
394 
395 - Remaps the AI key and both volume keys through an accessibility key filter:
396   1–5 taps, press-and-hold, and key combinations, each bound separately.
397 - Remaps Power: hold (as the digital assistant), double press (as the default
398   camera app), and the firmware short-press behaviour.
399 - Actions: Viwoods AI screens, navigation, page-turn swipes and scrolls,
400   volume and media, open an app or component, send an intent or broadcast.
401 - Licensing through Google Play Billing: licensed, beta, 7-day trial, locked.
402   The beta is opened and closed from Play Console; testers get a lower price.
403 - In-app accessibility disclosure with explicit consent.
404 - Key tester, and a read-only view of the firmware's own key hooks.
405 - No `INTERNET` permission.
406 
407 Known limits:
408 
409 - Purchases are untested: Play Billing cannot be exercised until the app exists
410   in Play Console. Everything up to the purchase sheet is tested on the device.
411 - A volume key whose firmware hook is set is invisible to every app, and only
412   adb can unset it.
413 - The reader ships with Google Play disabled; buying needs it switched on.