Yaky's

Android: boot on plug, launch app after boot, shutdown on condition

(Updated 2024-10-12) Part of the Volty MIR project, but can be used for non-interactive applications.

Volty MIR - [M]ap + [I]intelligent [R]everse Camera
To display maps, I need a device that has:
My trusty and crusty old Samsung Galaxy S5 has all that functionality, even video output to HDMI via MHL. I found the MHL cable at a thrift store for a dollar or so.
MHL (Mobile High Definition Link)

What I want the device to do is:

For the map/navigation application, I chose Organic Maps, as it is lightweight, has a great interface, and works offline. I have used it for many years now.
Organic Maps
Other options are:
OsmAnd - more customizable, the OG of OpenStreetMap navigation
Osmin - similar to Organic Maps, and works great on Linux (PinePhone etc.)

These instructions presume you have the latest android-platform-tools (mainly adb and fastboot).


Boot on plug


Through fastboot (recommended method)

This does not work on Samsung devices!
Boot the device to fastboot mode (aka download mode) and run
fastboot oem off-mode-charge 0
This worked for Google Nexus 7 tablet, and probably works for most Google devices.
Be careful with this - if battery gets too low, device will be stuck in an annoying constantly crashing reboot loop until it is sufficiently charged. See below for automatic shutdown on condition.

Magisk module

This is what I ended up doing.
Root the device with Magisk, and then download and install Magisk Autoboot module.
Magisk Autoboot
Update: I previously could not get this to work with Android 7, but I believe this was due to a specific ROM I had installed. Clean Lineage 14, or Lineage 14 Optimized works.

playplm / plm / lpm

This is a somewhat strange way to boot some Samsung devices: It relies on replacing the binary that displays the battery charge animation with a script that (re)boots the device instead. Requires root.
Go to /system/bin and find a file named "playplm", "plm", or "lpm". Then edit it to contain only:
#!/system/bin/sh
/system/bin/reboot
Although I did not find any of these files on my S5, a redditor confirmed this worked on their Galaxy S3.

Launch app after boot


Termux with Termux:Boot plugin

Termux is a terminal emulator for Android, which can run with and without root.
I installed Termux and Termux:Boot via F-Droid, and ran Termux:Boot once to initialize it.
Termux on F-Droid
Termux:Boot on F-Droid
Some references:
Getting started with Termux
Termux:Boot plugin
Per instructions, I created a startup script
mkdir -p ~/.termux/boot
nano ~/.termux/boot/start-maps.sh
#!/data/data/com.termux/files/usr/bin/sh
am start app.organicmaps/.SplashActivity

Side note: how to find app name and activity

Easier way is to install and open Activity Launcher, find the app and its name, then find a list of activities it has, and find the main activity. Then use those names in the script above.
Activity Launcher on F-Droid
In my case:

Another possibility is to get this information through ADB. Allow ADB access and connect mobile device to main machine. Run these commands on main machine.
Get a list of applications via ADB:
adb shell pm list packages -f -3
Get a list of activities via ADB:
PACKAGE=package.name
adb shell dumpsys package | grep -Eo $(printf "^[[:space:]]+[0-9a-f]+[[:space:]]+%s/[^[:space:]]+" "${PACKAGE}") | grep -oE "[^[:space:]]+$"

Tasker

I have not tried this. Might be easier if you don't like the terminal.
Source on StackExchange

Easer

Easer is an open-source automation tool like Tasker. While it can be used for some scripting, I was unable to get it to launch Organic Maps on boot.


Shutdown on condition

Update: ACC (advanced charging controller) Magisk module handles this much better. See below

Previously, I implemented this using Termux, Termux:API and crontab. This requires root, because shutdown is a system function, and keeps a wakelock to run cron (which might and might not matter for your use case)

Root

I rooted my device using Magisk.
Official Magisk GitHub repo

Battery status

To check the battery status, I used Termux and Termux:API extension.
Termux:API on F-Droid
Termux API on Termux Wiki
To check battery status:
termux-battery-status
This returns JSON, which can be parsed using jq.
pkg install jq
Now I can extract the values I need, for example:
batt_pct=`termux-battery-status | jq -r '.percentage'`
batt_status=`termux-battery-status |jq -r '.status'`

Shutdown

To shut down Android:
su -c "reboot -p"

Note on shutdown commands

These are the various shutdown commands I found for Android.
Most of them seem to run fine in user's Termux session, but when they are run as a part of a cronjob, they run slowly, are buggy, and sometimes reboot the phone instead of shutting down:
sudo reboot -p
sudo /system/bin/svc power shutdown
sudo /system/bin/svc power reboot -p
sudo am start -a android.intent.action.ACTION_REBOOT
So stick with
su -c "reboot -p"

Script

Putting it all together: (with an extra spoken message using another API)
#!/data/data/com.termux/files/usr/bin/sh
batt_pct=`termux-battery-status | jq -r '.percentage'`
batt_status=`termux-battery-status | jq -r '.status'`
if [ $batt_pct -lt 60 ] && [ "$batt_status" = 'DISCHARGING' ]
then
	termux-tts-speak 'Low power. Shutting down.'
	su -c "reboot -p"
fi
I put this in a file at
/data/data/com.termux/files/usr/bin/yaky-auto-shutdown
This directory is in $PATH, so no need to specify the full path in the future.
Test by running in Termux:
yaky-auto-shutdown

Automation

To automate this script, I used crontab. First, install it through Termux:
pkg install cronie
Edit crontab:
crontab -e
Add an entry to run the auto-shutdown script
* * * * * yaky-auto-shutdown
To run the cron daemon, add another script to execute at boot:
nano ~/.termux/boot/start-cron.sh
#!/data/data/com.termux/files/usr/bin/sh
termux-wake-lock
crond
This will set a wakelock to prevent Android from killing the long-running process, and then launch crond.
Every minute, cron will run the script, which will check the battery percentage and status, and shut down the device if the specified conditions are met. Although shutdown command requires root, root privileges will be provided to Termux as necessary (as long as they have been provided at least once before)


Battery management

All of these require root.

ACC + app

Update: ACC (advanced charging controller) works pretty well, for both limiting the maximum charge level and for shutting down at a specific percentage. I used the simple version since I run Lineage 14 (Android 7).
Advanced Charging Controller (ACC) on GitHub
The easiest way is to install ACCA from F-Droid, give it root access, and let it install the ACC daemon.
AccA on F-Droid

Battery Charge Limit app

Previously, to reduce wear and damage to an already-old battery, I installed Battery Charge Limit app to keep the device charge between 70% and 80%.
Battery Charge Limit on F-Droid (this link is dead)
Battery Charge Limit on APKPure

Input Power Control

Similar to ACC but without the automatic shutdown. I did not try this.
IP Control on GitHub


Simulating events

Having root allows calling Android's input command to simulate touch and keyboard events from the terminal.

Note: Just like with the shutdown command above, it seems that the correct way to execute commands as root on Android is
su -c ""

Single tap:
su -c "input tap 500 1450"
Swipe or long press:
su -c "input swipe 100 500 100 500 250"
Exact screen locations can be found by enabling "Show pointer location" in Developer Settings.

For example, Organic Maps hides the UI on long-press, so I can call this after the app opens:
su -c "input swipe 500 500 500 500 1000"
This simulates holding a finger at coordinate (100,100) for a second (1000 milliseconds).


Current issues

It appears that the MHL cable does not supply enough current (pun intended) to keep the device charged, so it is gradually losing battery charge even though it is plugged in. Battery status shows current of 300mA when charging via MHL cable, and 450mA when charging through a regular USB cable connected to a laptop USB port.
I am considering combining the MHL USB cable with a regular charging USB cable, or going battery-less.
Topic on AndroidCentral

ROM and kernel

Lineage 14.1 (Android 7.1.2) Optimized ROM
Kernel for Samsung Galaxy S5 family

Final scripts

For my own reference.
nano ~/.termux/boot/yaky-auto-start.sh
#!/data/data/com.termux/files/usr/bin/sh
# Hold a wakelock for cron to run correctly
termux-wakelock
# Enable ssh server for easy access
sshd
# Enable cron for automatic shutdown
crond
# Start Organic Maps
am start app.organicmaps/.SplashActivity
# Wait for Organic Maps to start
sleep 10
# Long-press the map to hide the UI
su -c "input swipe 500 500 500 500 1000"
# Announce readiness
termux-volume music 10
termux-tts-speak 'Navigation ready'

nano /data/data/com.termux/files/usr/bin/yaky-auto-shutdown
#!/data/data/com.termux/files/usr/bin/sh
# Extract battery percentage
batt_pct=`termux-battery-status | jq -r '.percentage'`
# Extract battery status
batt_status=`termux-battery-status | jq -r '.status'`
# Shut down when unplugged and below 60%
if [ $batt_pct -lt 60 ] && [ "$batt_status" = 'DISCHARGING' ]
then
	termux-tts-speak 'Low power. Shutting down.'
	su -c "reboot -p"
fi

crontab -e
* * * * * yaky-auto-shutdown