[ASUS ZenFone 8] bnsmb:
Sometimes it makes sense to install additional predefined applications as part of the operating system.

For ROMs for which you compile the installation image yourself, adding prebuild applications to a CustomROM can be done as follows.

Notes

There are already some websites with instructions on this topic (e.g. here: https://adityatelange.in/blog/aosp/aosp-adding-prebuilt-apk/), but I didn't find all the information needed to add the apks and all the errors encountered during testing in one place, so I created this post.

All relative paths in the following instructions refer to the directory with the repositories for the ROM

The following example is for adding the app ChangeLog as prebuild app to the OmniROM.

This is certainly not very useful, but is only intended as an example (and it has been proven to work ...)

Note that the directory for the prebuild apps, vendor/omni/prebuild/app in the OmniROM, may be different in other Custom ROMS -- see How to add the ASUS Hardware Testtool as prebuild app for the StatiXOS ROM for an example.

1. Create a directory for the new app in the directory vendor/omni/prebuilt/app in the directory tree with the source files for the ROM:

# change the working directory to the directory with the repositories for the OmniROM
#
cd /data/develop/android/OmniROM_14.0/

# create the new directory
#
mkdir vendor/omni/prebuilt/app/changelog

2. Copy the apk file to the new created directory (the source directory on your PC will be different I guess ...):

cp /data/backup/Android/EssentialApps/com.bytehamster.changelog_v49.apk vendor/omni/prebuilt/app/changelog/com.bytehamster.changelog_v49.apk

3. Create the necessary Android.mk file for the new application. Either create the file manually or copy the Android.mk file from the directory of another app and edit the file contents:

cp vendor/omni/prebuilt/app/OmniStore/Android.mk vendor/omni/prebuilt/app/changelog/Android.mk

When done the file should look like this:

LOCAL_PATH:= $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := ChangeLog
LOCAL_SRC_FILES := com.bytehamster.changelog_v49.apk
LOCAL_MODULE_CLASS := APPS
LOCAL_MODULE_TAGS := optional
LOCAL_CERTIFICATE := PRESIGNED
LOCAL_DEX_PREOPT := false
LOCAL_SYSTEM_EXT_MODULE := true
include $(BUILD_PREBUILT)

Be careful not to use leading or trailing whitespaces in the file - the make tools for Android don't like them and produce strange error message for these whitespaces.

And for the records because I only found this infos by accident (see also https://android.googlesource.com/pl...cd70d12622bf9fdb4af5d8f0eb24/core/prebuilt.mk)

Known values for LOCAL_CERTIFIACTE are (as far as I know ...):

Value	Description
PRESIGNED	the apk file is already signed
platform	the build scripts will sign the apk with the platform key

this will be converted to:

-> LOCAL_CERTIFICATE := build/make/target/product/security/platform
shared	"a key for things that are shared in the home/contacts process."

this will be converted to:

-> LOCAL_CERTIFICATE := build/make/target/product/security/shared
media	the build scripts will sign the apk with the key used for packages in media/download

this will be converted to:

-> LOCAL_CERTIFICATE := build/make/target/product/security/media
vendor/example/certs/app	the bulild scripts will sign the apk with the key found in the local directory

vendor/example/certs/

this will be converted to:

-> LOCAL_CERTIFICATE := vendor/example/certs/app
testkey	a key used for all other packages default

this will be converted to:

-> LOCAL_CERTIFICATE := build/make/target/product/security/testkey
EXTERNAL	"The magic string "EXTERNAL" means this package will be signed with the test key throughout the build process, but we expect the final package to be signed with a different key."

-> LOCAL_CERTIFICATE := build/make/target/product/security/testkey

After converting the value like described in the table above the make system creates the final file names of the certificates to use :

PACKAGES.$(LOCAL_MODULE).PRIVATE_KEY := $(LOCAL_CERTIFICATE).pk8
PACKAGES.$(LOCAL_MODULE).CERTIFICATE := $(LOCAL_CERTIFICATE).x509.pem

4. Finally add the new app to the file vendor/omni/config/packages.mk, e.g.:

[ OmniRom 14 Dev - xtrnaw7@t15g /data/develop/android/OmniROM_14.0 ] $ grep -B2 -A1 ChangeLog vendor/omni/config/packages.mk

PRODUCT_PACKAGES += \
ChangeLog
[ OmniRom 14 Dev - xtrnaw7@t15g /data/develop/android/OmniROM_14.0 ] $

Note:

If you use a name in PRODUCT_PACKAGES that doesn't exist the build system silently ignores your mistake.

Now recreate the OS image and you're done.

Notes:

To add SELinux policies for the new app; create a new .te file in one of the directories named sepolicy , e.g.:

echo "allow system_app proc_stat:file { ioctl read getattr lock map open watch watch_reads };" >device/asus/zenfone8/sepolicy/vendor/asus_hardware_testtool.te

see How to add missing SELinux policies dynamically using Magisk for some details regarding SELinux policies.

Trouble Shooting

Error message like this

vendor/omni/prebuilt/app/MyTerminal/Android.mk: error: MyTerminal: Invalid characters in module stem \(LOCAL_INSTALLED_MODULE_STEM\):

while creating the OS image are most probably caused by leading or trailing whitespaces in the file Android.mk.

If you get an error message like this:

FAILED: out/target/product/zenfone8/obj/APPS/MyTerminal_intermediates/enforce_uses_libraries.status
/bin/bash -c "(rm -f out/target/product/zenfone8/obj/APPS/MyTerminal_intermediates/enforce_uses_libraries.status ) && (build/soong/scripts/manifest_check.py --enforce-uses-libraries --enforce-uses-libraries-
status out/target/product/zenfone8/obj/APPS/MyTerminal_intermediates/enforce_uses_libraries.status --aapt out/host/linux-x86/bin/aapt2 vendor/omni/prebuilt/app/MyTerminal/com.t
ermoneplus_501.apk )"
error: mismatch in the <uses-library> tags between the build system and the manifest:
- required libraries in build system: []
vs. in the manifest: []
- optional libraries in build system: []
vs. in the manifest: [androidx.window.extensions, androidx.window.sidecar]
- tags in the manifest (vendor/omni/prebuilt/app/MyTerminal/com.termoneplus_501.apk):
uses-library-not-required:'androidx.window.extensions' uses-library-not-required:'androidx.window.sidecar'
note: the following options are available:
- to temporarily disable the check on command line, rebuild with RELAX_USES_LIBRARY_CHECK=true (this will set compiler filter "verify" and disable AOT-compilation in dexpreopt)
- to temporarily disable the check for the whole product, set PRODUCT_BROKEN_VERIFY_USES_LIBRARIES := true in the product makefiles
- to fix the check, make build system properties coherent with the manifest
- for details, see build/make/Changes.md and https://source.android.com/devices/tech/dalvik/art-class-loader-context

11:30:28 ninja failed with: exit status 1
There were 3 actions that completed after the action that failed. See verbose.log.gz for their output.

while building the OS image use the instructions below to fix the error.

The reason for the error message are instructions for required libraries in the manifest file of the apk file, which are missing in the Android.mk file for adding the app as a prebuild app.

To fix the issue:

First double check the list of required libraries in the Manifest from the apk file using aapt:

[ OmniRom 14 Dev - xtrnaw7@t15g /data/develop/android/OmniROM_14.0 ] $ APK=vendor/omni/prebuilt/app/MyTerminal/com.termoneplus_501.apk
[ OmniRom 14 Dev - xtrnaw7@t15g /data/develop/android/OmniROM_14.0 ] $
[
[ OmniRom 14 Dev - xtrnaw7@t15g /data/develop/android/OmniROM_14.0 ] $ ../android_sdk/build-tools/34.0.0/aapt dump badging $APK | grep uses-library
uses-library-not-required:'androidx.window.extensions'
uses-library-not-required:'androidx.window.sidecar'
[ OmniRom 14 Dev - xtrnaw7@t15g /data/develop/android/OmniROM_14.0 ] $

The list should be equal to the list of tags in the error message.

Now to fix this issue add another line to the Android.mk file with these requirements for the apk fie:

LOCAL_OPTIONAL_USES_LIBRARIES := androidx.window.extensions androidx.window.sidecar

Note that the order of the values for LOCAL_OPTIONAL_USES_LIBRARIES must match the order from the manifest in the apk file.

If the new app does not appear to be installed on the phone after installing the new operating system image, first check whether the apk file is present on the phone, e.g.:

ASUS_I006D:/ $ ls -l /system_ext/app/ChangeLog/
total 1096
-rw-r--r-- 1 root root 1121030 2009-01-01 01:00 ChangeLog.apk
ASUS_I006D:/ $

The new apk should be in the directory /system_ext/app/<appname> because of this entry in the Android.mk file: LOCAL_SYSTEM_EXT_MODULE := true; without this statement the apk file should be in the directory /system/app/<appname> or, if the statement LOCAL_MODULE_PATH := $(TARGET_OUT_DATA) is used in the Android.mk file, in the directory /data/app/<appname>.

If the file does not exist something went wrong creating the OS image - check the log file of the build process, e.g:

gzip -cd out/verbose.log.gz | grep -i ChangeLog.apk

If the file exists check the logcat output on the phone for error messages regarding the apk file:

logcat -d | grep ChangeLog.apk

To prove that the file can be installed, try to install the apk manually in an adb shell:

CUR_SIZE=$( ls -l /system_ext/app/ChangeLog/ChangeLog.apk | awk '{ print $5}' )
cat /system_ext/app/ChangeLog/ChangeLog.apk | pm install -S ${CUR_SIZE}

Error message like this in the logcat on the phone regarding the new application:

05-12 09:02:43.968 1265 1265 W PackageManager: Failed to scan /system_ext/app/MyTerminal: No APK Signature Scheme v2 signature in package /system_ext/app/MyTerminal/MyTerminal.apk

are most likely there because the Android make tools rebuilt the apk file but did not re-sign the file and therefor the apk file is not signed anymore.

To fix it, change the value for the variable LOCAL_CERTIFICATE in the file Android.mk to force the Android tools to re-sign the apk file.

Or add the entry

LOCAL_REPLACE_PREBUILT_APK_INSTALLED := $(LOCAL_PATH)/com.bytehamster.changelog_v49.apk

to the file Android.mk .

Notes

see the post How to "simulate" prebuild apps using Magisk for how to "simulate" pre-build apps on ROMs that you do not compile yourself

see How to add the ASUS Hardware Testtool as prebuild app for a custom ROM for examples