Enabling third party input methods in Android on Chrome OS

At the moment, the default choice of input methods for Android apps in Chrome OS seems to be limited to either the physical keyboard, or the built-in Chrome OS virtual keyboard. Installing a third party Android IME and clicking on its 'Enable' button (which, on Android phones and tablets, usually brings up the Languages and Input dialog where third party IMEs can be enabled), brings up CrOS' own 'Languages and Input' settings dialog, usually found at chrome://settings/languages, rendering it apparently impossible to choose a third party input method for Android apps this way.

However, it is possible to enable third party input methods via adb in the shell, or with the Android terminal. Once the third party input method has been added to the list of enabled Android input methods, it can be selected as the default input method for Android apps.

I already had 'Hacker's Keyboard' installed on the Android instance but had not been able to enable it, as it didn't seem to be possible to open up the Android 'Languages and Input' settings dialog. 

One thing I tried first of all was editing /system/etc/permissions/cheets.xml as in that file I noticed this:

   <!-- Disallow third-party IME apps in favor of ARC IME. -->
    <unavailable-feature name="android.software.input_methods" />

However, it turns out that editing this isn't necessary.

I was able to enable IMEs via the android shell 'settings' command, either in the Android terminal emulator (which requires root), or through Chrome OS via adb, which does not require a rooted Android instance.

Here's how I did the latter:

1. Enabled ADB debugging in the Android Developer options

2. Opened Chrome OS shell (Ctrl_Alt+T, type shell), and connected to the Android instance with
adb connect
3. Agreed to the RSA authentication dialog popup (ticked the box).

4. To check currently enabled input methods I entered
adb shell settings get secure enabled_input_methods
which returned: org.chromium.arc.ime/.ArcInputMethodService

5. Added HK to the list of enabled input methods by appending its ID to the latter string, i.e. entering
adb shell settings put secure enabled_input_methods org.chromium.arc.ime/.ArcInputMethodService:org.pocketworkstation.pckeyboard/.LatinIME
Edit: See the footnote at the bottom of this page for an alternate, perhaps easier, way to do this, and how to find the IDs for installed input methods

6. To set a new default, I opened the Hacker's Keyboard app via the search button/launcher,`and tapped 'Set input method', which brought up the Android IME picker, where HK was now visible. Picked it as the default, and hit the "show keyboard when a physical keyboard is active" switch and it appeared!

To set the IME as default via adb: Rather than having to find the Android IME picker - after adding the ID of the input method to the 'enabled' list, I could have set it as the default with
adb shell settings put secure default_input_method [ID]
e.g. in this case:
adb shell settings put secure default_input_method org.pocketworkstation.pckeyboard/.LatinIME

7. Done! Here's what it looks like in Firefox in tablet mode:

Caution is advised if enabling third party Android input methods this way - I found that HK mostly seemed to function as expected in tablet mode, working perfectly with some Android apps that I tried such as Firefox, e.g. popping up when a text input box was highlighted, then disappearing when I tapped away from the text input box allowing me to navigate by touch normally by dragging to scroll, tapping links, etc, and reappearing if an input box was highlighted again. 

In other apps, however, e.g. Terminal Emulator, the interaction seemed perhaps a little buggy; scrolling initially didn't work (but started working after I did a few things (fiddled with the 'Window Size and Orientation' settings in Android's 'Developer Options/maximised HKs parent app/rebooted), and after closing the keyboard, it didn't immediately pop up again when tapping in an input field.

Due to the latter issue, I found it necessary to customize the settings a little; in the Chrome OS shell, I entered
adb shell am start -n org.pocketworkstation.pckeyboard/.PrefScreenActions
which brought up HKs 'Gesture and key actions' preference page. For the gesture 'Swipe Left', I chose 'Launch Settings', and for the gesture 'Swipe Right', I chose 'Close keyboard'. I then went back to the Hacker's Keyboard app and disabled extra languages for ease of swiping left/right over the spacebar.

Finally, I opened up the keyboard's main settings dialog by swiping left over the spacebar area, and ticked the 'Use permanent notification' box so that, should it not pop up automatically in any Android apps, it may still be activated simply by tapping the notification.

Rather than setting up a swipe gesture, for the purpose of opening the settings dialog to enable the permanent notification, I could instead have entered
adb shell am start -n org.pocketworkstation.pckeyboard/.LatinIMESettings
to bring Hacker's Keyboard's main settings dialog activity up.

I also tried installing Gboard from the Play Store. Again, it can be chosen as a default input method for Android apps, once its string has been added to enabled_input_methods:

e.g. to have Gboard and the original CrOS virtual keyboard enabled and available to be chosen as default:
adb shell settings put secure enabled_input_methods org.chromium.arc.ime/.ArcInputMethodService:com.google.android.inputmethod.latin/com.android.inputmethod.latin.LatinIME
or to have both Hacker's Keyboard and Gboard enabled, in addition to the original CrOS virtual keyboard:
adb shell settings put secure enabled_input_methods org.chromium.arc.ime/.ArcInputMethodService:org.pocketworkstation.pckeyboard/.LatinIME:com.google.android.inputmethod.latin/com.android.inputmethod.latin.LatinIME
Gboard worked OK but was not perfect; sometimes taking over the screen - the lack of a 'back' button in tablet mode being something of an issue (swiping down not seeming to work to disable it). Edit: Although a 'back' button has now been implemented in CrOS in tablet mode, it is located in the shelf, which now seems to be getting pinned to the bottom of the screen, behind the keyboard.

I also tried out SwiftKey:
adb shell settings put secure enabled_input_methods org.chromium.arc.ime/.ArcInputMethodService:com.touchtype.swiftkey/com.touchtype.KeyboardService
This seemed to work quite well in portrait mode, but I did encounter some issues with graphics glitches in landscape mode.

Footnote: the 'ime' command (perhaps an easier method)

The above was what I did initially but it's not the only way. Similarly, it is possible, and perhaps easier, to enable input methods with the 'ime' command.

Installed input methods and their associated IDs (among other information) can be listed with
adb shell ime list -a
The IDs of currently enabled input methods can be listed with
adb shell ime list -s
An input method can be enabled with
adb shell ime enable [ID]
And an input method can be set as the default with
adb shell ime set [ID]