3.3. Android OTA

This application note contains steps to test the OTA (Over The Air) feature on Android.

There are 2 ways of applying an OTA update:

  1. OTA via adb sideload

  2. OTA via Update Engine

3.3.1. OTA via adb sideload

  1. Build and flash android images following Build Instructions instructions.

  2. Build OTA package

    $ cd ${YOUR_PATH}/ti-aosp-15
    $ source build/envsetup.sh
    $ lunch <BUILD_TARGET>
    $ export DIST_DIR=./dist_output
    $ m dist
    
  3. Enable adb debugging on your device

  4. Reboot to recovery and apply OTA

    $ BOARD=am62p
    
    $ adb reboot sideload
    $ adb wait-for-sideload
    $ adb sideload $DIST_DIR/${BOARD}-ota-${USER}.zip
    $ adb reboot
    

3.3.2. OTA via Update Engine

  1. Install the python dependency for the google module

    $ pip install --user google-api-python-client
    
  2. Build the OTA package

    $ source build/envsetup.sh
    $ lunch <BUILD_TARGET>
    $ export DIST_DIR=./dist_output
    $ m
    $ m dist
    
  3. Set your PYTHONPATH.

    Some dependent python modules for gen_update_config.py are part of AOSP tree or part of the build output.

    $ cd $ANDROID_BUILD_TOP
    $ PYTHONPATH=$ANDROID_BUILD_TOP/build/make/tools/releasetools:$PYTHONPATH
    $ PYTHONPATH=$ANDROID_BUILD_TOP/system/apex/apexer/:$PYTHONPATH
    $ export PYTHONPATH
    
  4. Update the ota config file. Feel free to change $DIST_DIR to match your developer environment.

    $ BOARD=am62p
    
    $ source build/envsetup.sh
    $ lunch <BUILD_TARGET>
    $ DIST_DIR=dist_output
    $ bootable/recovery/updater_sample/tools/gen_update_config.py --ab_install NON_STREAMING $DIST_DIR/$BOARD-ota-${USER}.zip $DIST_DIR/$BOARD-ota-${USER}.json file:///data/user/0/com.example.android.systemupdatersample/files/packages/$BOARD-ota-${USER}.zip
    

    Warning

    Be careful, last line is one single very long line.

  5. Run the SystemUpdaterSample app once:

    $ adb root
    $ adb shell setenforce 0
    $ adb shell am start com.example.android.systemupdatersample/com.example.android.systemupdatersample.ui.MainActivity
    
  6. Push the files on the board:

    $ adb root
    $ adb shell mkdir /data/user/0/com.example.android.systemupdatersample/files/configs
    $ adb shell mkdir /data/user/0/com.example.android.systemupdatersample/files/packages
    $ adb push $DIST_DIR/$BOARD-ota-${USER}.json /data/user/0/com.example.android.systemupdatersample/files/configs/
    $ adb push $DIST_DIR/$BOARD-ota-${USER}.zip /data/user/0/com.example.android.systemupdatersample/files/packages/
    
  7. Change SELinux label:

    $ adb shell chcon -R u:object_r:ota_package_file:s0 /data/user/0/com.example.android.systemupdatersample/
    
  8. Change Unix permisssions:

    $ adb shell chmod -R 777 /data/user/0/com.example.android.systemupdatersample/
    
  9. Run the update on the UI:

    • Tap on RELOAD to load the config

    • Tap on APPLY to apply the OTA

    • Tap OK to confirm application

    • Wait for progress bar to complete

    • Tap on SWITCH SLOT to finish update (scroll downwards to see the button)

    • Wait for verification

  10. Reboot the device with:

    $ adb shell svc power reboot
    
  11. Confirm that booting on slot b

    $ adb root
    $ adb shell grep 'androidboot.slot_suffix' /proc/bootconfig
    androidboot.slot_suffix = "_b"
    

3.3.2.1. Troubleshooting

Python 3.12 is not supported, because it removed the imp module and also comes with a too recent version of protobuf.

To install and older version, use virtualenv:

$ pip install virtualenv # make sure python3.11 is installed on your system
$ virtualenv --py 3.11 venv_ota_build

$ source venv_ota_build/bin/activate
$ pip install protobuf==3.20

From here, you should be able to invoke gen_update_config.py.