"..."
source link: https://nolirium.blogspot.com/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
Installing Xposed in Android on Chrome OS
1. Ensure that your Android container is rooted, and that the rootfs is writable.
(If you've already used the rooting script, but you find the Android rootfs still isn't writeable, this may help).
2. Download the Xposed framework installer app (to ~/Downloads).
3. Install the app via the Chrome OS shell (as root), e.g. :
sudo su -
setenforce 0
printf "pm install /storage/emulated/0/Download/XposedInstaller_3.1.5.apk" | android-sh
printf reboot | android-sh
4. Assuming the installation was successful, open the Xposed installer app from the Chrome OS Launcher, click on 'Install/Update' then, in the next menu, click on 'Install'.
NB: If the prompt to grant root access doesn't show up at this point, see step 2. of the older instructions further down this page.
5. Once the framework installer app indicates it is 'Done', then reboot.
The above steps should work on current Chrome OS versions. If you find it doesn't work for you, feel free to leave a comment on this post.
The original blog post is below...
Just a short post to note that it is now possible to successfully install and use Xposed in Android in Chrome OS. It works for me on CrOS version 67.0.3390.0 canary (arm), but it may be possible on some earlier builds, too.*
After success with a script based approach, I thought I'd try using the official installer app, and found that it actually isn't necessary to copy the files manually/with a script. Given a writeable Android rootfs, the installer app was able to install the framework successfully, as long as I allowed the app to gain root (which, on at least one CrOS version, necessitated temporarily setting 'Default Access' in SuperSU to grant root automatically, since the regular pop-up root request prompt didn't appear for this app).
Here are the exact steps I took to install Xposed from its installer app.
1. After creating a rooted writeable Android rootfs with the rooting script, I downloaded the latest Xposed installer app from the Xposed announcement thread on xda.
3. After this, I simply clicked on 'Install/Update' in the Xposed installer, and then 'Install' again in the following menu.
After Android had loaded up, I went into the Xposed installer again, and added a few modules. Everything seems to be working as expected, as far as I can see, within certain limitations, mostly related to running in a container environment.
For example: adding shortcuts and actions to screen tap areas with 'Xposed Edge' works, but the shortcuts/actions only function when Android apps are actually on the screen. Also, the lack of 'parallel running of tasks' in the CrOS version I'm currently running could possibly be an issue.
In any case, now I actually have Xposed working, I can't seem to see much use for it at present. However, I guess it could possibly be useful for something in future.
*It seems not to be easily possible currently to install Xposed via the installer app on CrOS version 65 at present, due to a (temporary) issue mounting the Android rootfs as writeable at runtime. Installing files (manually, or via a script) into the container image while it is mounted elsewhere does still work. The writeable mount issue is also present on v66 but can be fixed by editing the container config.json (deleting the string "dev", from the "rootfs/root" section under "mounts".
Modifying hardware key layouts for Android apps on Chrome OS
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).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
cp -a /opt/google/containers/android/rootfs/root/system/usr/keychars/Generic.kcm /home/chronos/user/Downloads
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
Step 1. Changing key 43 in cros_ec.kl
Step 2. Changing the relevant key declaration in Generic.kcm
printf "logcat | grep key" | android-sh
Enabling Managed Profile in Android in Chrome OS
This can usually be done via the excellent app Island, which utilizes the Work/Managed profile functionality in Android in order to 'clone' selected apps, which can then be used either independently or both at the same time.
I wanted to have this functionality in Android on Chrome OS, but I found that initially the Island app didn't seem to be able to install properly.
I modified the file /system/etc/permissions/cheets.xml within the Android container, removing the word "unavailable" from two relevant lines, so
<unavailable-feature name="android.software.device_admin" />
<unavailable-feature name="android.software.managed_users" />
becomes
<feature name="android.software.device_admin" />
<feature name="android.software.managed_users" />
After rebooting Android, I was able to install Island fully, and was able to run it as normal, cloning apps, then keeping two copies of the same app open at the same time.
Since the Android file /system/etc/permissions/cheets.xml is located within the Android container, a writeable Android rootfs is needed in order to modify the file directly. One way of achieving this is via the rooting scripts.
Alternatively, for example if one perhaps wants just to run a quick test for a cloned app, the original rootfs can be kept untouched, and an edited cheets.xml file bind mounted over the original. However, the bind mount would only last until the Chromebook is rebooted, which could lead to unexpected consequences.
e.g:
Copy cheets xml to /usr/local
cp /opt/google/containers/android/rootfs/root/system/etc/permissions/cheets.xml /usr/local/cheets.xml
Remove the word "unavailable-" from the device_admin linesed -i 's/unavailable-feature name="android.software.device_admin"/feature name="android.software.device_admin"/g' /usr/local/cheets.xmlRemove the word "unavailable-" from the managed_users line
sed -i 's/unavailable-feature name="android.software.managed_users"/feature name="android.software.managed_users"/g' /usr/local/cheets.xmlBind mount the edited cheets.xml back over the original
mount -o bind /usr/local/cheets.xml /opt/google/containers/android/rootfs/root/system/etc/permissions/cheets.xmlFinally, reboot the android container
printf reboot | android-sh
I should note that, although I haven't noticed any issues as yet, enabling unsupported features may have unexpected consequences. It would be prudent to ensure any important files are backed up before experimenting.
Enabling Mock Locations in Android on Chrome OS
In Developer mode, with adb debugging switched on in the Android Developer options, if we connect to Android via adb in the Chrome OS shell
sudo su - adb connect 100.115.92.2We can then switch on mock locations via adb
adb shell settings put secure mock_location 1If a suitable fake location Android app (e.g. https://play.google.com/store/apps/details?id=com.lexa.fakegps) is installed on the device, this can be set as the default mock locations app
adb shell appops set com.lexa.fakegps android:mock_location allow
To set a different app as the mock locations app, change the package name/App ID (com.lexa.fakegps in the example above) to the appropriate package name (as shown on the app's Play Store URL).
After setting Fake GPS as the mock locations app, I was able to select my mock location in Fake GPS and e.g. Maps in Opera would successfully show the mock location, rather than my current location. I haven't really tested in many other apps at this time.
I understand that some Android apps may specifically check if mock locations are being used. For those apps, I imagine further steps would probably be required, such as perhaps installing (possibly a different app such as GPS JoyStick) as a system app. This, however, would require remaking the Android rootfs container as a R/W image. If this is required, the rooting script can be run, which, as part of the rooting process, replaces the Android read-only rootfs with a R/W copy.
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 100.115.92.2
adb shell settings get secure enabled_input_methods
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 methods6. 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: R
ather 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 withadb shell settings put secure default_input_method [ID]
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)
adb shell ime list -a
adb shell ime list -s
adb shell ime enable [ID]
adb shell ime set [ID]
Running a shell command with a single click on a shelf shortcut on Chrome OS
Here's how I did it on a freshly powerwashed device (in Developer mode). Not all of the below steps are strictly necessary; as ever, YMMV.
Briefly, what I did was:
Installed Secure Shell extension; setup sshd on the Chromebook; added public key from ConnectBot (Android app) to ~/.ssh/authorized_keys in order to test connection; created profile to connect to chronos@localhost/my local IP address in Secure Shell extension; generated keys on Chromebook (in ~/.ssh); added generated public key to ~/.ssh/authorized_keys; imported newly-generated private/public key pair within Secure Shell app (one by one); created bookmark link to chronos@localhost profile in shelf, and, finally, added required command to 'arguments' field of profile in Secure Shell.
A more detailed description follows.
1. Installed Secure Shell extension
Installed Secure Shell extension fromhttps://chrome.google.com/webstore/detail/secure-shell/pnhechapfaindjhompbnflcldabbghjo?hl=en2. (a) Added ssh upstart job to /etc/init/
sudo ln -s /usr/share/chromeos-ssh-config/init/openssh-server.conf /etc/init/openssh-server.conf
The above file, openssh-server.conf, will auto-start sshd at boot, and, additionally, will add a firewall rule which opens port 22, enabling ssh access to the device from external networks. This firewall rule is only required if connecting from another device - to use ssh purely within the Chromebook, it is not necessary to open port 22. Therefore, if not intending to connect to the Chromebook from another device via ssh, one may create a .conf in /etc/init omitting this part. For instance, for purely accessing localhost, the following works for me:
sudo su -
echo "start on starting system-services
script
exec /usr/sbin/sshd
end script" > /etc/init/openssh-server.conf
chmod 644 /etc/init/openssh-server.conf
2. (b) Registered and initialised upstart job
sudo initctl reload-configuration
sudo initctl start openssh-server
The above pair of shell commands registered and then initialised the open ssh server. After entering the commands, the server was running in the background.
3. (a) Optional: Tested the connection with ConnectBot on Android tablet (Nexus 9)
This step is not actually necessary (unless you specifically want to control your Chromebook in the shell with an Android device).
Rebooted Chrome OS, launched ConnectBot, generated Pubkey, long-pressed on newly-generated key, chose Copy public key. Mailed it to self. Opened Gmail on the Chromebook, copied key from email, opened shell tab (non-root) and added the key to Chrome OS as follows:
(*DOUBLETAP* indicates a double tap on the touchpad to paste the key)
touch ~/.ssh/authorized_keys
echo *DOUBLETAP* > ~/.ssh/authorized_keys
chmod 600 ~/.ssh/authorized_keys
Created a new host profile in ConnectBot; set the second field as [email protected] (my local IP address); left all other fields as default.
Connected to the profile...
chronos@localhost / $
Success! Disconnected ConnectBot. Back in the host profile, edited the field "Post-login automation". to add a shell command:
powerd_dbus_suspend
Connected to the profile...
The Chromebook sleeps!
Long pressed the N9 homescreen to bring up the "Add Widget" dialog. Dragged ConnectBot to homescreen. Chose [email protected] from the pop-up list of hosts. Tapped the new homescreen shortcut...
The Chromebook sleeps!
Unfortunately, the current implementation of Android on Chrome OS doesn't appear to support creating homescreen 'widget shortcuts'. So it seemed that another approach was required in order to create the one-click shortcut.
3. (b) Connected to the Chromebook... from the Chromebook
Opened Secure Shell extension in Chrome with the keyboard shortcut Ctrl+Alt+T, typed ssh, in omnibar, hit Tab, hit Enter.Clicked on "New Connection"
Typed chronos@localhost
Clicked on "Connect"
At this point, it only seemed to be possible to connect after setting a password for chronos (passwd chronos), and then the password had to be entered manually at every connection. No good for automation.
Some further setup seemed to be required.
Generated a new key, added the generated key to ~/.ssh/authorized_keys, and copied the keys to ~/Downloads.
cd ~/.ssh/
echo | ssh-keygen -P ''
cat ~/.ssh/id_rsa.pub >> ~/.ssh/authorized_keys
cp -a ~/.ssh/id_rsa* ~/Downloads
Opened Secure Shell
Chose 'Import'
Navigated to private key in the file explorer (/home/chronos/user/Downloads/id_rsa). Clicked on it.
Chose 'Import', again
Navigated to public key in the file explorer (/home/chronos/user/Downloads/id_rsa.pub). Clicked on it.
Tried connecting to the chronos@localhost profile in Secure Shell again and... Boom!
chronos@localhost / $
4. Bookmarked the extension
With the Secure Shell profile command prompt tab open (which looks identical to the regular shell command prompt tab, except that in the address bar, rather than ending with crosh.html, the address ends with a profile number):
Three dot menu at top right>More tools>Add to shelf (open as window)
This created a clickable shelf bookmark icon.
5. Added the shell command
So now it was possible to open a shell command prompt with a single click, the final part of the puzzle was to add the command of interest. This turned out to be a piece of cake, once the syntax was correct. All that needed to be added to the saved Secure Shell profile was-- thecommand
...to the SSH Arguments field.
So, after adding
-- powerd_dbus_suspend
to the SSH Arguments field for my chronos@localhost profile, the final result is a bookmark in the shelf which, when clicked, sends the Chromebook to sleep. Since I added it to the 9th position on the shelf, it can also be triggered with the keyboard shortcut: Alt+9.
I am not sure if it will be possible to set it up so that the command runs without opening a window, but it does at least seem to remember the window size and position, so the window can be hidden away at the side, or rolled up' into a small bar. I think it might be possible to set it up so the command runs in the background but I haven't looked into this yet.
Other use cases: Crouton etc.
-- sudo enter-chroot xiwi steam
-t -- echo mypassword | sudo -S sh /media/removable/3/bin/enter-chroot xiwi firefox
to the Arguments field.
Similarly, I set up a shelf shortcut to open my chrooted Ubuntu desktop in a window with the argument
-t -- echo mypassword | sudo -S sh /media/removable/3/bin/startxfce4
Another way to do it is to save the string to a file in /usr/bin, then just put -- thefile as the argument. This is what I did with a few commands that I find it tedious to regularly open up a prompt and enter in, such as the ectool command(s) to switch off the bright LEDs on the side of the device:
sudo ectool led power off
sudo ectool led battery off
Customizing the icons
(a) Prepared icons
To avoid any manifest editing, saved them as *size*.png
(b) Located correct directory to copy icons into; copied icons into folder:
Easy way:
Other way:
If a generic name was chosen, and grepping it brings up too many results to go through,another way to locate the correct directory is as follows:
cd ~/Extensions/&&cd $(ls -v1td */ | sed '/\Temp/d' | head -1)/&& cd $(ls -v1td */ | head -1)/icons&&ls -al
If the one-liner didn't work; the icons directory can be located manually i.e.
Update regarding the latter: After an OS update, the only part that needed redoing was the SSH upstart job. After a powerwash, however, in addition to having to generate keys and add them to Secure Shell again, while the extension shortcuts (and Secure Shell profiles) themselves synced and restored OK , the icons did not. Next time, I'll see if adding a favicon URL instead of icon files works at all, and, if not, to restore them, I suppose I might have to add this into the customization scripts I run post-powerwash.
Sources:
(1) https://www.dereckson.be/blog/2015/01/15/chromebook-run-a-ssh-server-on-chrome-os/
(2) https://chromium.googlesource.com/chromiumos/overlays/chromiumos-overlay/+/master/chromeos-base/openssh-server-init/openssh-server-init-0.0.1.ebuild
(3) https://chromium.googlesource.com/apps/libapps/+/master/nassh/doc/FAQ.md
(4) https://groups.google.com/a/chromium.org/forum/#!msg/chromium-hterm/UpQRttX_LJk/Wj241kcSCAAJ
Recommend
About Joyk
Aggregate valuable and interesting links.
Joyk means Joy of geeK