For a project I am currently working on I needed my old mobile phone (a Motorola Moto G 2014) to start a script directly after start up. I searched a lot in the depth of the Internet but did only find outdated information. Therefore, I write this article so others do not have the same problem (and I have notes available if I want to do it again. Since this is a change to the operating system, I needed something like LineageOS to have access to it. So, this is a description how to set up your LineageOS 16 to start a script on start up.
Installing LineageOS 16
The first step is to install LineageOS 16 onto your mobile phone. I will not describe how this is done, because the LineageOS website has really good tutorials for this (here for the Moto G 2014). Since my phone is no longer supported, there are no official images for it. But I did not want to build LineageOS for myself. So I searched for unofficial builds and found one with the name lineage-16.0-20190420-UNOFFICIAL-titan.zip. I used this to flash my mobile phone. Additionally, please install the LineageOS SU Addon to get root permissions on the phone. When everything is working, we can start our changes to the operating system.
Execute Script on Start Up
As I said, I tested a lot of different methods I found on the Internet. The one that worked for me I found in a forum thread. In a short description, we have to enable the init.d process to execute start scripts. Everything you have to do can be done via adb under root permissions: The steps we have to do are the following:
Turn on the developer options on your mobile phone.
Allow USB debugging.
Allow adb to have root access.
Use the command adb root on your computer to restart adb with root access.
Use the command adb shell to get a shell on the phone.
Remount the file system with write permissions via:
mount -oremount,rw /system
Go to the directory /system/etc/init/ and create the file init_d.rc with the following content:
service init_d /system/bin/sh /system/bin/sysinit user root group root disabled oneshot seclabel u:r:sudaemon:s0on property:sys.boot_completed=1 && property:sys.logbootcomplete=1 start init_d
Now you can go into the directory /etc/init.d and create scripts that are executed on start up.
To give an example, I add a script that loops and checks if the mobile phone is charged. If it is not charged for more than 5 seconds, it shuts down the mobile phone. The following has to be done:
Go to the directory /etc/init.d and execute:
Execute the following commands to give the correct permissions:
chgrp shell 99batteryshutdown chmod 755 99batteryshutdown
Place the following content into the file:
#!/system/bin/sh# Start script in background /bin/batteryshutdown.sh &
Now go to directory /bin and create the file batteryshutdown.sh with the correct permissions:
touch batteryshutdown.sh chmod 755 batteryshutdown.sh
Place the following content into the script file:
#!/system/bin/shCTR=0 while true; do STATUS=$(cat /sys/class/power_supply/battery/status) # Observed states: Charging, Discharging, Full if [ $STATUS == "Discharging" ]; then let CTR=CTR+1 else CTR=0 fi
# Tested: when on battery mode, after around 20 seconds the process
# does not wake up from sleep until charger is plugged in again
# or mobile phone is used by user.
if [ $CTR -gt 1 ]; then
# On Lineage 15 with ‘su -c’, the command returns
# CANNOT LINK EXECUTABLE “su”: cannot locate symbol
#svc power shutdown
# On Lineage 16 without the ‘su -c’, the command returns just ‘Killed’
# (perhaps SELinux settings).
su -c ‘svc power shutdown’
With this script, around 10 seconds after the charger has been removed from the mobile phone it gets shutdown. Please note, that the Android operating system optimizes the processes for the battery usage. This means as soon as the phone runs on battery, processes get suspended when the system goes to sleep. You can see my observations in the comments of the script above. Hopefully, this helps some of you to not spend hours on testing.