Skip to content

Android (LineageOS 15.1) Execute Script on Start Up

For a project I am currently working on I needed my old mobile phone (a Nexus 5X) to start a script directly after start up. I already did it for a Motorola Moto G 2014 running LineageOS 16. However, the hardware broke down because of old age. So I needed to do all the same for my next old mobile phone. Unfortunately, the steps I took on LineageOS 16 did not work for LineageOS 15.1 which is the only available for the Nexus 5X. Hence, here is a description how to do it on LineageOS 15.1.


Installing LineageOS 15.1

The first step is to install LineageOS 15.1 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 Nexus 5X). 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 is a combination of this forum thread and that forum thread. In a short description, we have to change the init.rc in the boot image to enable the init.d process to execute start scripts. However, for this we have to reflash the mobile phone. I tried to change the file directly via adb (getting write permissions to the file and editing it directly). However, after each reboot it changes back to the original file. So, we have to change it in the boot image itself.

Normally, I work on Linux. However, since there is a Windows tool that does all the packing and repacking (and I actually do not care about the Android image internals), I used Windows for this part. The steps we have to do are the following:


  1. Download Android Image Kitchen. I used version 3.5.

  2. Unzip our LineageOS file (the lineage-15.1-20200107-nightly-bullhead-signed.zip) and copy the boot.img into the Android Image Kitchen directory (next to unpackimg.bat and repackimg.bat).

  3. Open a command line in Windows into this directory and execute:



  4. unpackimg.bat boot.img
     


  5. Go into the directory ramdisk and edit the file init.rc. I would suggest to use Notepad++ for this, since the normal Windows editor could fuck up the charset (e.g., by using \r\n instead of \n).

  6. Go to the end of the file and add the following to enable init.d:



  7. Find the section that starts with on charger and change it to the following:



  8. #[...]

    service init_d /system/bin/sh /system/bin/sysinit
        user root
        group root
        disabled
        oneshot
        seclabel u:r:sudaemon:s0

    on property:sys.boot_completed=1 && property:sys.logbootcomplete=1
        start init_d
     


  9. Repack the image by open a command line into the Android Image Kitchen directory and execute repackimg.bat. You should now have a file that is called image-new.img. This is our new boot image.

  10. Copy the image-new.img to your phone (I used adb push for this, however, SD card also works).

  11. Start TWRP on your phone (you used it to flash your LineageOS onto your phone, so do the same steps to go into the recovery mode which uses TWRP).

  12. In TWRP, go to install, switch to install image and then select the image-new.img file you copied to your phone. Select the boot partition and swipe to install it. In short, do install -> install image -> select image-new.img -> select boot partition -> swipe to install.

  13. Reboot.

  14. Done.

  15. Now you can go into the directory /system/etc/init.d and create scripts that are executed on start up.



After this, the mobile phone should boot up as normally. If you want to check if your changes are now on the phone, you can use adb for it. Do the following if you want to check:


  1. Turn on the developer options on your mobile phone.

  2. Allow USB debugging.

  3. Allow adb to have root access.

  4. Use the command adb root on your computer to restart adb with root access.

  5. Use the command adb shell to get a shell on the phone.

  6. Output the file init.rc file via cat init.rc and see if your changes are there.



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:


  1. Go to the directory /system/etc/init.d and execute:



  2. touch 99batteryshutdown
     


  3. Execute the following commands to give the correct permissions:



  4. chgrp shell 99batteryshutdown
    chmod 755 99batteryshutdown
     


  5. Place the following content into the file:


    #!/system/bin/sh

    # Start script in background
    /system/bin/batteryshutdown.sh &
     


  6. Now go to directory /system/bin and create the file batteryshutdown.sh with the correct permissions:



  7. touch batteryshutdown.sh
    chmod 755 batteryshutdown.sh
     


  8. Place the following content into the script file:


    #!/system/bin/sh

    CTR=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'
        fi

        sleep 5
    done
     



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.

Trackbacks

No Trackbacks

Comments

Display comments as Linear | Threaded

No comments

Add Comment

Standard emoticons like :-) and ;-) are converted to images.
E-Mail addresses will not be displayed and will only be used for E-Mail notifications.
Form options

Submitted comments will be subject to moderation before being displayed.