How to build and use an Android SDK Add-on

Georgia Garcia
ProFUSION Engineering
5 min readOct 21, 2020

UPDATE: for this article, you can find the source code and more updated documentation here here.

Whether you are an OEM company or a developer customising the Android Open Source Project, you might have come across the issue where you developed a feature and you would like for App developers to use it. That’s when the SDK Add-on comes in handy.

The Android Software Development Kit (SDK) is a collection of libraries and tools that enables and makes it easier to develop Android applications. SDK Add-ons allow third-party actors to extend the Android SDK to add interfaces to their features without changing the Android SDK. According to the Android Compatibility Definition Document (CDD), OEMs are not allowed to change the Android public APIs — namely those in the protected namespaces: java.*, javax.*, sun.*, android.*, com.android.*. Therefore, by using add-ons, OEMs can add libraries in their namespaces, providing functionalities that can be exported without infringing the CDD. Having to build only the add-on is also a great advantage that might save a lot of development time.

In this post, we will build an SDK Add-on containing an example service — for which we will cover all the necessary config files. We will also learn how to connect an application to our example service using the add-on. Here, we are assuming you already have access to the Android source code and that you can build and deploy these changes. The code and configuration files were made with Android 10 (API level 29) in mind but they can be easily modified to work with other versions.

Hello World System Service

To facilitate the understanding of how to build and extract your own SDK Add-on, we will create a simple “hello world” service so that later we can use an application to connect to it.

HelloWorldService.java

An AIDL interface is needed for a client app to connect to.

IHelloWorldService.aidl

The service also needs a set of permissions that will be installed on the /system/etc directory. When the client app is installed, it will look for this file to determine if the HelloWorld library exists. The service library is installed in the /system/framework directory.

helloworld-permissions.xml

If helloworld-permissions.xml does not exist, then the app will not be installed and adb install will return an error such as:

Failure [INSTALL_FAILED_MISSING_SHARED_LIBRARY: Package couldn't be installed...]

Also, AndroidManifest.xml needs to define the service interface.

AndroidManifest.xml

Unfortunately, the SDK Add-on does not recognise the library if it’s defined in an Android.bp file, so the .jar must be defined in an Android.mk. We will still have a .bp, but it only defines the service APK that will be built and will not be a part of the add-on.

Android.bp

Android.mk

SDK Add-on configs

If you already have a service, then this is the interesting part: You need a .mk file that defines the name and properties of your SDK Add-on, and several other files that define miscellaneous properties such as the API level being used, the revision version, and the libraries contained in the add-on. During the Android build, these files are bundled into a .zip containing the add-on to be distributed. In the next sections, I will go into further detail into each of the included files.

profusion_sdk_addon.mk

The profusion_sdk_addon.mk provides all the information needed to build the add-on, like the modules that will be included. In this case, we want to include our helloworld.jar, so we need to specify the module to be built in the PRODUCT_PACKAGES variable and copy it to the add-on using the PRODUCT_SDK_ADDON_COPY_MODULES variable. The PRODUCT_SDK_ADDON_COPY_FILES is used to copy the config files that will be used in Android Studio to build the application.

manifest.ini

The manifest.ini file contains the properties of the add-on, including the Android API Level, the libraries included, and the revision number. If there is more than one library, they must be separated by a semicolon (;) and also be defined below in a new line containing the library name and its .jar file name.

source.properties

The source.properties defines add-on properties used for the built image, which can be distributed along with the SDK Add-on.

package.xml

The package.xml file makes it easier for Android Studio to import the add-on.

sdk_addon_stub_defs.txt

The sdk_addon_stub_defs.txt file contains the rules for public APIs.

For these tests, I was using lunch aosp_x86_64-eng, so I decided to add the reference to profusion_sdk_addon.mk in the build/make/target/product/aosp_x86_64.mk, but you may add it to whichever device you are using. Simply add:

Building

The SDK Add-on is all set. Now we only have to build it. Note, again, that I’m using aosp_x86_64:

$ make PRODUCT-aosp_x86_64-sdk_addon

When the compilation succeeds, the SDK Add-on .zip will be in out/host/linux-x86/sdk_addon/profusion_sdk_addon-eng.user-linux-x86.zip

Adding the SDK Add-on to Android Studio

Create a path on your Android SDK for the add-ons, then extract the contents of the add-on .zip file. You will need to rename the directory using the names defined in the "localPackage path" tag in package.xml

$ mkdir -p /path/to/Sdk/add-ons$ unzip out/host/linux-x86/sdk_addon/profusion_sdk_addon-eng.user-linux-x86.zip -d /path/to/Sdk/add-ons/$ mv /path/to/Sdk/add-ons/profusion_sdk_addon-eng.user-linux-x86/ /path/to/Sdk/add-ons/addon-profusionaddon-profusion-29/

Open Android Studio and go to Tools -> SDK Manager. Check the “Show Package Details” checkbox then you will be able to see the SDK Add-on for the API level configured.

SDK Manager containing the SDK Add-on

Using the SDK Add-on in an application

To use the SDK Add-on, you must first change the compileSdkVersion on the build.gradle to the vendor name, along with the add-on name and the API level - as defined in the manifest.ini - all separated by colons. In your case, it will look like this:

Import the class from the SDK you’d like to use. In our case, it’s com.profusion.helloworld.IHelloWorldService. Sometimes Android Studio will not recognise the package, so I recommend you go to Tools -> SDK Manager and on the "SDK Location" click on Edit and without changing anything, but click Next until it finishes. This will force Android Studio to re-parse the package.xml from the add-on.

Below is an example of an application using the HelloWorldService:

MainActivity.kt

Make sure to include the following in your AndroidManifest.xml under the application tag:

And that’s it!

If you run the application and then check the logcat searching for "HelloWorldService," then you will be able to see the service printing "Hello World."

$ adb shell
# logcat | grep -i HelloWorldService
3261 3279 D HelloWorldService: Hello World.

This documentation and all the source code are also available here.

--

--