This is a living blog post with tips and tricks for developing within the Android Open Source Project’s framework.
What is "the Android Framework"? In short; it is the layer of Android that defines APIs, services, and environments for Android applications. For a better explanation you should see AOSP’s description.
Iterating Within the Java Framework
In a Nutshell
#!/usr/bin/env bash # source this script. For example: # > . iterate.sh # build the framework module mmm frameworks/base || return # ensure adb is running as root adb root; # make the system partition on the device writeable adb remount; # synchronize files between the local system folder under # out/target/product/<device>/system and the device's system partition adb sync; # restart the framework adb shell stop; adb shell start;
The Android framework module is built by the
makefile. In AOSP
mm builds the module for the current directory and
<dir> builds the module in
<dir> (or in a list of dirs).
ProTip: elinux.org’s wiki is a good cheatsheet
You’ll need a rooted device to iterate on the framework without having to
flash the entire system each time. This is because the
adb sync command is
copying just the parts of the framework you have rebuilt to the device’s
/system partition. For the Java framework this will be
Alternative System Build
It’s worth mentioning that there’s an alternative way to get a system image which contains a java framework onto a device. Once you’ve run the mmm part of the build and have the build intermediates you want to get onto a device you can run
which stands for "Make System with No Dependencies". This simply packages up whatever is in the out folder into a new system image. You can then
reboot fastboot and
fastboot flash system to install the entire system image onto a connected device.
Careful here though, if this is the first time you are flashing a device from your local build you’ll want to do a full build/flash or your device may get into the infamous infinite app optimization and reboot. See the Android Open Source Project’s docs for full details on building AOSP and get past the point where you:
before starting to use
make snod or
become more important when developing for the Android application framework.
That said, don’t define systemOrSignature permissions unless you understand the
ramifications doing so has for your Android distribution (I’ll have to write a
follow up post some day about this). For the signature level, the
framework itself is signed using a key that establishes a signature defining
what packages belong to the system and what packages are from another source
(i.e. "downloaded"). Because of this your package will have to have the same
signature as the framework to obtain signature level permissions defined by
Under build/target/product/security you’ll see several keys that sign various parts of the system. We’re mostly concerned with the platform key when working with the application framework.
To create an application keystore with the same signature as the application
framework build you’ll need to create a java keystore that contains the platform
key and certificate found the build. To do this you’ll need two things: the JDK’s
openssl. Once you have these on your path, have a working AOSP
build, and an Android application development environment you can create a new debug
keystore like so:
openssl pkcs8 \ -in build/target/product/security/platform.pk8 \ -inform DER \ -nocrypt \ -out platform.pem; openssl pkcs12 -export \ -in build/target/product/security/platform.x509.pem \ -out platform.p12 \ -inkey platform.pem \ -password pass:android \ -name androiddebugkey; keytool -importkeystore \ -deststorepass android \ -destkeystore platform.jks \ -srckeystore ./platform.p12 \ -srcstoretype PKCS12 \ -srcstorepass android;
You can check that this is a valid keystore using keytool:
keytool -list -keystore platform.jks Enter keystore password: > android
Now all you have to do is either point your app build to use this keystore or replace your randomly generated debug keystore with this one:
mv platform.jks ~/.android/debug.keystore
If you’ve already installed an application package and get an Application Installation Failed, INSTALL_FAILED_UPDATE_INCOMPATIBLE error this is because the signature has changed. Uninstall the package and you should be able to install the version with the new signature without further errors.
WARNING This hack disables critical security measures in Android. Don’t install any real user accounts on a development device running this hack.
Sometimes you want to test integration with apps that are production signed and
limit access to certain activities by signature. If production signing
your development app is too much of a burden you can just disable the signature
check. In Lollipop this was found in ActivityStackSupervisor.java:1430.
By commenting out the real security check and always reporting
you can start any Activity you want on your hacked system regardless of signatures:
- final int startAnyPerm = mService.checkPermission( - START_ANY_ACTIVITY, callingPid, callingUid); - final int componentPerm = mService.checkComponentPermission(aInfo.permission, callingPid, - callingUid, aInfo.applicationInfo.uid, aInfo.exported); + final int startAnyPerm = PERMISSION_GRANTED; + //mService.checkPermission( + // START_ANY_ACTIVITY, callingPid, callingUid); + final int componentPerm = PERMISSION_GRANTED; + //mService.checkComponentPermission(aInfo.permission, callingPid, + // callingUid, aInfo.applicationInfo.uid, aInfo.exported);
Here are some resources that you’ll find useful while hacking AOSP:
AndroidXREF – Online OpenGrok index of the full AOSP codebase organized by release branch. This resource is invaluable for developing AOSP and applications. Frankly the existence of this site is one of the key benefits of Android over iOS for developers. There’s no scouring docs and trying to reverse engineer strange behaviours. You just go to the source and you know exactly what the problem is. done.
App Detective – A useful app for enumerating all the activities, services, providers, permissions, etc available on a system. This can help with building rich integrations with other popular apps.