Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Developing system apps without AOSP

Developing system apps without AOSP

If you work with Android development long enough, there is a high chance that you eventually will be developing system applications for a custom Android device. This is quite different from doing regular apps we publish on Google Play Store, and used to require that you have the entire AOSP source code checked out in order to work with it.

However, with some understanding of how Android internals work and how to use some undocumented features of the regular build tools, we can actually develop system apps without the whole mess that comes with AOSP.

In this session you'll learn how to use system and signature level permissions, how to efficiently call system APIs, and how to test all of this on a regular Android emulator. Hopefully this will make the daily life easier for all the Android developers working on system applications.

Erik Hellman

April 28, 2023

More Decks by Erik Hellman

Other Decks in Programming


  1. System Apps vs Regular Apps • Hidden & System APIs

    • Signature & Permissions • Pre-installed
  2. Prepare the GSI $ unzip aosp_arm64-img-10018685.zip $ simg2img system.img system_raw.img

    $ gzip -c system_raw.img > system_raw.gz $ adb push system_raw.gz /storage/emulated/0/Download/
  3. Flash a GSI using DSU $ adb shell am start-activity

    \ -n com.android.dynsystem/com.android.dynsystem.VerificationActivity \ -a android.os.image.action.START_INSTALL \ -d file:///storage/emulated/0/Download/system_raw.gz \ --el KEY_SYSTEM_SIZE $(du -b system_raw.img|cut -f1) \ --el KEY_USERDATA_SIZE <size-of-system_raw.img>
  4. Converting AOSP test certificates to Android keystore $ openssl pkcs8

    -inform DER -nocrypt -in platform.pk8 -out platform-signing.key $ openssl pkcs12 -export -in platform.x509.pem -inkey platform.key \ -name platform -out platform-signing.pem -password pass:password $ openssl pkcs12 -export -in platform.x509.pem -inkey platform-signing.key \ -name platform -out platform-signing.pem -password pass:password $ keytool -importkeystore -destkeystore platform-signing.keystore \ -deststorepass password -srckeystore platform.pem -srcstoretype PKCS12 -srcstorepass password
  5. Using the platform key for signing signingConfigs { debug {

    keyAlias 'platform' keyPassword 'password' storeFile rootProject.file('platform-signing.keystore') storePassword 'password' } }
  6. Installing on the /system/app or / system/priv-app partition $ adb

    root $ adb disable-verity $ adb reboot # Wait for device to reboot... $ adb root $ adb remount $ adb shell mkdir /system/app/YourSystemApp $ adb push YourSystemApp.apk /system/app/YourSystemApp $ adb reboot # Not usually needed Remember to bump versionCode!
  7. Permissions frameworks/base/core/res/AndroidManifest.xml <!-- @SystemApi Allows an application to inject user

    events (keys, touch, trackball) into the event stream and deliver them to ANY window. Without this permission, you can only deliver events to windows in your own process. <p>Not for use by third-party applications. @hide --> <permission android:name="android.permission.INJECT_EVENTS" android:protectionLevel="signature" />
  8. Calling hidden APIs Refelctions (Slow!) private val injectMethod: Method =

    InputEvent::class.java .getMethod("injectInputEvent", InputEvent::class.java, Int::class.java) fun InputManager.injectEvent(inputEvent: InputEvent) { injectMethod.invoke(this, inputEvent, 0) }
  9. Calling hidden APIs Add an interface package android.hardware.input; import android.view.InputEvent;

    public interface InputManager { public boolean injectInputEvent(InputEvent event, int mode); }
  10. Calling hidden APIs Extract framework.jar & android.jar 1. Copy files

    from device or emulator 2. Convert from DEX to Java classes (DexTools) 3. Package into a new android.jar file 4. Replace android.jar in your SDK
  11. Calling hidden APIs Build a custom SDK $ mkdir ~/my-android-git

    $ cd ~/my-android-git $ repo init -u https://android.googlesource.com/platform/manifest \ -b master -g all,-notdefault,tools $ repo sync -j8 # Edit AOSP! $ . build/envsetup.sh $ lunch sdk-eng $ m
  12. Interesting @SystemAPI permissions <!-- Allows uhid write access for creating

    virtual input devices @hide --> <permission android:name="android.permission.VIRTUAL_INPUT_DEVICE" android:protectionLevel="signature" /> <!-- Allows injecting the external camera to replace the internal camera. @hide --> <permission android:name="android.permission.CAMERA_INJECT_EXTERNAL_CAMERA" android:protectionLevel="signature" /> <!-- @SystemApi @TestApi @hide Allows an application to embed other activities --> <permission android:name="android.permission.ACTIVITY_EMBEDDING" android:protectionLevel="signature|privileged" />
  13. Interesting @SystemAPI permissions <!-- @SystemApi @hide Allows an application to

    start activities from background --> <permission android:name="android.permission.START_ACTIVITIES_FROM_BACKGROUND" android:protectionLevel="signature|privileged|vendorPrivileged|oem|verifier|role" /> <!-- Allows an application to start foreground services from the background at any time. <em>This permission is not for use by third-party applications</em>, with the only exception being if the app is the default SMS app. Otherwise, it's only usable by privileged apps, app verifier app, and apps with any of the EMERGENCY or SYSTEM GALLERY roles. --> <permission android:name="android.permission.START_FOREGROUND_SERVICES_FROM_BACKGROUND" android:protectionLevel="signature|privileged|vendorPrivileged|oem|verifier|role"/>
  14. Interesting @SystemAPI permissions <!-- @SystemApi @hide Allows an application to

    create windows using the type {@link android.view.WindowManager.LayoutParams#TYPE_APPLICATION_OVERLAY}, shown on top of all other apps. Allows an application to use {@link android.view.WindowManager.LayoutsParams#setSystemApplicationOverlay(boolean)} to create overlays that will stay visible, even if another window is requesting overlays to be hidden through {@link android.view.Window#setHideOverlayWindows(boolean)}. <p>Not for use by third-party applications. --> <permission android:name="android.permission.SYSTEM_APPLICATION_OVERLAY" android:protectionLevel="signature|recents|role|installer"/>
  15. Summary • How much System APIs do you need to

    use? • Reflection? • Custom interface • Custom Engineering SDK • Bookmark system AndroidManifest.xml • Navigating cs.andorid.com