To fix the keylayout for the locale of my Chromebook's physical keyboard, I modified a couple of files on the rootfs. Although I edited the files directly, which requires a writeable Android system, it's also possible to make a copy, edit the copy, then bind mount it over the original.
Switching the " and @
First way - editing the file directly. Modified (R/W) Android rootfs needed.
With a read/write Android filesystem, as created with the rooting scripts, the easiest way to fix the key layout seemed to be by editing the relevant key mapping file directly. It would be best to make a backup of the file to be edited beforehand.I opened a root shell in CrOS and entered
vi /opt/google/containers/android/rootfs/root/system/usr/keychars/Generic.kcm
(To swap the " and @ characters, in vi I entered /@ to search Generic.kcm for the @ character, pressed x to delete the @, then pressed i to enter "insert text mode" and typed " to add the quote mark character at the place where the @ had been. I did similar with the " character, replacing it with @)After modifying the file I saved and quit vi by typing :wq!
I then rebooted the Android container
printf reboot | android-sh
Now, in Termux etc., Shift+2 types the " character, and Shift+' types the @ character, as is expected with a UK keyboard layout. Second way - Editing a copy of the file and bind mounting it over the original.
It's also possible to do it without editing the file directly, by copying it out to /usr/local (or to a place accessible within the File Browser such as ~/Downloads) editing the copy, bind mounting it back in place, then rebooting the Android container. In this case, the bind mount and Android reboot have to be redone after every time Chrome OS is rebooted.i.e.
Either:
To copy the file to /usr/local and edit it with vi, then bind it back:
Copy the file with permissions preserved
cp
-a /opt/google/containers/android/rootfs/root/system/usr/keychars/Generic.kcm /usr/local
Edit the copy e.g. in vi (as above).
Bind mount the file back over the original
mount --bind /usr/local/keychars/generic.kcm /opt/google/containers/android/rootfs/root/system/usr/keychars/Generic.kcm
Then reboot the Android container so it sees the new fileprintf reboot | android-sh
Or:
Alternatively, it might be easier to copy the file to ~/Downloads and edit it with another text editor (e.g. Caret), then move it to /usr/local and bind mount it & reboot Android
Copy the file to ~/Downloads
cp -a /opt/google/containers/android/rootfs/root/system/usr/keychars/Generic.kcm /home/chronos/user/Downloads
After editing the file in text editor, move it to /usr/local/
mv /home/chronos/user/Downloads/Generic.kcm /usr/local/Generic.kcm
Mount bind and then reboot Android as aboveAdding the #~ key found on UK keyboards
After swapping the " and @, I still had an issue with the key for # and ~ (located to the left of the Enter key on my UK keyboard). It appeared to have the same mapping in Android as the \ key (to the right of my left Shift key). It turned out that to fix this I had to do two things:
Step 1. Changing key 43 in cros_ec.kl
I found that key 43 and key 86 were both mapped to BACKSLASH at /system/usr/keylayout/cros_ec.kl in the Android container. I had a look at the list of key codes for Android, and decided to change key 43 from BACKSLASH to POUND, since the key code POUND in Android apparently refers to the # key found on phones.
Step 2. Changing the relevant key declaration in Generic.kcm
then opened the key character map file I'd previously modified (/system/usr/keychars/Generic.kcm), found the key declaration for POUND therein, which looked like this:
key POUND {
label: '#'
base: '#'
}
And added a line for the shift modifier.
key POUND {
label: '#'
base: '#'
shift: '~'
}
I rebooted Android again, and now my keyboard was finally behaving how I wanted it to in Android terminal apps.
If anyone is considering making the changes detailed above, or similar, I should mention that Android is quite particular about how it expects these files to be; if the formatting is at all out of place or if an unexpected character is present then Android might fail to load, or revert to a fallback character mapping. If the latter is happening then logcat usually notes the offending line in the problematic file, which can be seen in the output to the following (entered in a CrOS root shell):
printf "logcat | grep key" | android-sh
In the event of Android failing to load completely and the above command returning an error, if the files had been bind mounted, a reboot would fix it, and if they were edited directly it might be necessary to restore the original file/s from backups.