A guide to application development within the Android Open Source Project (AOSP) and elevating standard apps to System Apps or Privileged Apps to access special APIs.
1. AOSP App vs Gradle App
App development on AOSP uses a different Build Platform (Soong/Make) compared to Android Studio (Gradle).
Key Differences
- Build System: Uses
Android.bp(Soong) instead ofbuild.gradle - Location: Source Code resides in the Android Source Tree (e.g.,
packages/apps/MyApp) - API Access: Direct access to Hidden APIs (
@hide) and Internal Resources (com.android.internal.R)
1.5 The Battle: Android.bp vs Android.mk
| Feature | Android.mk (Legacy) | Android.bp (Modern) |
|---|---|---|
| Engine | GNU Make | Soong (Blueprint) |
| Logic | Shell Script / If-else Support | Declarative JSON-like (No Logic) |
| Status | Deprecated | Recommended (Standard) |
Recommendation: Use Android.bp for all new modules unless complex Shell Scripts are required.
2. Basic AOSP App Structure
File structure example for the MySystemControl app:
Directory: packages/apps/MySystemControl/
AndroidManifest.xmlAndroid.bp(Build Config)src/(Java/Kotlin Code)res/(Resources)
Android.bp Example:
android_app {
name: "MySystemControl",
srcs: ["src/**/*.java"],
resource_dirs: ["res"],
static_libs: ["androidx.appcompat_appcompat"],
// Key Configs
platform_apis: true, // Allow Hidden APIs
certificate: "platform", // Sign with System Key
}
Build Command:
source build/envsetup.sh
lunch aosp_arm64-userdebug
m MySystemControl
2.5 Bonus: Importing Prebuilt APK
If you want to include an APK from Android Studio into the ROM without moving the Source Code:
android_app_import {
name: "PrebuiltMyApp",
apk: "MyApp.apk",
presigned: true, // Keep original signature
// privileged: true, // Optional
}
Note: presigned: true cannot use Shared System UID.
2.6 Workflow: Debugging System Apps from Android Studio
The INSTALL_FAILED_UPDATE_INCOMPATIBLE issue arises from mismatched Signatures (Debug Key vs Platform Key).
Solution: Sign APK with Platform Key
- Get Key from
build/target/product/security/(platform.pk8,platform.x509.pem) - Convert to KeyStore (
.jks) usingopensslandkeytool - Configure
signingConfigin Android Studio’sbuild.gradleto use this Key.
3. System App vs Privileged App
Installation location determines the app’s privilege level.
3.1 System App (/system/app)
- Definition: Pre-installed app in ROM
- Capabilities: Cannot be uninstalled by user.
- Setup: Include module in Product Makefile.
3.2 Privileged App (/system/priv-app)
- Definition: System App with elevated permissions.
- Capabilities: Access Signature/Privileged Permissions (e.g.,
REBOOT,SHUTDOWN,INSTALL_PACKAGES). - Setup: Add
privileged: trueinAndroid.bp.
4. How to Create a Privileged App
Steps to create a complete Privileged App:
- Android.bp: Add
privileged: trueandcertificate: "platform" - Manifest: Request desired Permission (e.g.,
<uses-permission android:name="android.permission.REBOOT" />) - Allowlist XML (Mandatory): Create XML file in
/system/etc/permissions/to verify rights (Prevents Boot Loop in Android 8.0+)
XML Example:
<permissions>
<privapp-permissions package="com.example.mysystemcontrol">
<permission name="android.permission.REBOOT"/>
</privapp-permissions>
</permissions>
5. The “God Mode”: Shared System UID
android:sharedUserId="android.uid.system"
- Concept: Run app as System User (uid=1000), not a general User.
- Requirements: Must be signed with Platform Key only.
- Capabilities: Full Access to
/data/system, Kill processes, Direct Hardware access. - Risk: App crash = System Crash.
Comparison Table
| Feature | Privileged App | Shared System UID |
|---|---|---|
| Identity | Normal User ID | System User ID (1000) |
| Access | Via Permissions (Reboot, etc.) | Direct File/Process Access |
| Location | Must be in /system/priv-app | Anywhere (if signed correctly) |
6. Summary
| Type | Location | Uninstallable? | Special API Access | Configuration |
|---|---|---|---|---|
| User App | /data/app | Yes | No | Gradle Standard |
| System App | /system/app | No | Some | mk/bp include |
| Priv App | /system/priv-app | No | Full | privileged: true + Whitelist |