I've been using my Cosmo for a few days now and something that's irked me a lot has been the inability to customise the Fn mappings. Some keys like Fn+S and Fn+Z have nothing mapped to them at all, and others like Fn+F are mapped to actions that I rarely need - not enough to justify a keyboard shortcut, anyway. And, Alt is forcibly mapped to the Planet App Bar which I would much rather replace with something more interesting.
There are two sets of mappings. The first is used for plain old character inputs, mostly the stuff on the number row and the right hand of the keyboard: |#\€<>[]{}+-=_@;:` and Home/PgUp/PgDn/End. I haven't messed with these myself just yet, but
this thread in the Gemini subforum says they are specified through .kcm files contained in the Planet Keyboard app.
The second one, more interesting to myself, defines the handling of the Alt key (toggling the Planet AppBar) and all the Fn shortcuts with special actions: screenshot, mute, volume, brightness, home, app switcher, etc. This is part of Planet's modifications to Android itself. First, a bit of technical background.
--
On the Cosmo ROM these are handled in
com.android.server.policy.PhoneWindowManager; specifically in the
interceptKeyBeforeQueueing method (
original AOSP code). If you want to look at this yourself you can use adb to pull
/system/framework from your Cosmo and examine the
services package (I used
vdexExtractor's deodex script to get .dex files out of everything, and then jadx and Ghidra to analyse services.dex).
Planet's
interceptKeyBeforeQueueing is hard to follow (jadx fails to decompile it, so I had to use Ghidra), but here is a summary of the interesting bits:
- redirects Volume Up/Volume Down (fingerprint sensor buttons) to accept or reject an incoming call iff the Cosmo is closed
- detects keycode 0x8D (F11) as the Cosmo having been closed
- detects keycode 0x8E (F12) as the Cosmo having been opened
- *on Cosmo open, jumps to the Home Screen and/or opens the AppBar depending on what is configured in Cosmo Settings
- detects keycode 0x131, and sends the CoDi command 0x1f,1 iff the Cosmo is closed
- detects Volume Up/Volume Down, keycodes 0xf9-0xfd and 0x12c-0x30, and sends them to the CoDi with command 0x15
- **detects Back and closes AppBar if it was opened with Alt
- detects Alt key-up and opens AppBar
- **detects Esc, Left/Up/Right/Down and Enter and redirects them to AppBar if it was opened with Alt
- **detects Fn,
hijacks the press and sets a flag
- **redirects all keys pressed while Fn is held to the
fnAction method (entirely a Planet addition, not in AOSP)
- handles Call/EndCall buttons (not sure if Cosmo uses this or if it's a holdover from generic Mediatek modifications to Android)
- toggles Caps Lock light
- *on Cosmo close, broadcasts
com.iwrist.action.HALLCLOSE, notifies Planet VoiceAssistant, sends CoDi command 5,0, sleeps PowerManager
- *on Cosmo open, broadcasts
com.iwrist.action.HALLOPEN, notifies Planet VoiceAssistant, sends CoDi command 5,1, wakes up PowerManager
- detects USB port connections using special keys F14-F17
--
So how does this help us?
We can probably use EdXposed to write a module that hooks
interceptKeyBeforeQueueing and
fnAction, and replaces how specific keys are handled. This gives us full control but requires more effort (I will probably do this myself over the coming days -- if I do, it will be open sourced on GitHub) and of course also requires rooting.
There is another way though. Note that some of the things above are marked with * and **. The Cosmo (at least, in the out-of-the-box Android 9 build) allows these to be disabled --
without root!
The ones marked with * can be disabled using the following shell command (e.g. via
adb shell):
settings put system AEON_HALL_TEST 1. Use 0 instead of 1 to revert to normal.
This is slightly interesting but not practical -- it stops the Cosmo from locking on close (and unlocking on open), and stops the CoDi from changing states. Instead of these behaviours, the OS broadcasts
com.eastaeon.action.HALLCLOSE on close and
com.eastaeon.action.HALLOPEN on open.
For keymapping, the far more interesting command is:
settings put system AEON_KEY_TEST 1 which disables the ones marked with **. Use 0 instead of 1 to revert to normal.
With this in play, Fn is now freed up and regular Android applications can detect it! I'm currently using Key Mapper (
F-Droid,
Play Store) to map Fn+stuff to the actions I want, both replicating the stock Cosmo actions like home and screenshot, and also adding new ones.
Unfortunately, this trick does not allow the Alt key to be replaced (unless someone can think of a crafty way to let us supply our own
com.Pripla.Floating package exposing a
com.Pripla.Floating.FloatingWindow service, without Android complaining about it having the same package ID as the Planet AppBar which is a system app). Still, it's a start and already exposes lots more possibilities.