Android Open Source Project (AOSP) for Automotive and Python automation

More and more often, automotive companies are creating their own ROM based on AOSP (Android Open Source Project) for things like cockpit platforms, etc. The main effort on this project was to port middleware code to AOSP’s framework for C/C++/Java without using Android’s NDK, and deliver AOSP-ready libraries to customers in the Automotive industry.


During these efforts several realizations came into being:

  1. Android and AOSP are not compatible at the C++ level, since the C++ library used for Android’s NDK has a different ABI than the one used for AOSP. Trying to link an NDK-built library into an AOSP-based application would result into namespace issues, and vice versa
  2. The build and test infrastructure used CMake, and the latest version at the time did not support AOSP
  3. The python-based AIT (Automation Install Testing) did not support AOSP

To illustrate 1) above, let’s imagine the following code is built into a library named libmystring.so:

Source File: MyString.cpp


#include "MyString.hpp"
 
void MyString::displayString(std::string msg) {
	std::cout << "msg:" << msg << std::endl;
}
Header File:  MyString.hpp


#include <string>
#include <iostream>
 
class MyString {
	public:
    	MyString(){};
    	void displayString(std::string msg);
};

Using Android’s NDK to compile this library and checking the symbol table for the display function modified by the compiler, we find the following:

_ZN8MyString13displayStringENSt6__ndk112basic_stringIcNS0_11char_traitsIcEENS0_9allocatorIcEEEE

Using the c++filt tool to demangle it, we can see:

MyString::displayString(std::__ndk1::basic_string<char, std::__ndk1::char_traits<char>, std::__ndk1::allocator<char> >)

Note the namespace std::__ndk1::

Now, let’s use AOSP and write an android.mk or android.bp to create a C++ application application like the following that would use the previous NDK library:

# Main.cpp


int main(int argv, char** args) {
	MyString myString;
	myString.displayString("hello");
}


If we try to link the main app, built within AOSP environment, and the library, built with Android’s NDK, we will see something like this:

ndk_sample_android/main.cpp:7: error: undefined reference to 'MyString::displayString(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >)'

AOSP will use and expect the namespace std::__1::, which is different from the namespace that is used in the library built with Android’s NDK. And this is expected, as the compiler is just trying to make sure we don’t mix C++ ABIs which are different.

Having this into account, all above concerns were resolved. I took the following actions to address these issues and to have all our unit-tests and example apps ported for AOSP running into an AOSP device:

  1. Internally ported, debugged and tested CMake to add support to AOSP
  2. Updated our Python-based Android automation to make sure AOSP was tested along with Android 9 and 12
  3. Built an AOSP kernel and flashed it into the device to be tested
  4. Understanding Android compatibility between versions, new changes and requirements is fundamental. Always recommended to use the latest NDK and SDK with a minimum version always in mind to support.


Note that there was no need to learn Soong, but it was necessary to know how Soong was building C/C++ code in the backend, which system and header paths were used, etc.

The good thing about building an APK from the AOSP environment is that you can actually run it not only in an AOSP-base device but also in a Google device or any Android device and it would work as long as the correct C++ library is packaged along with the APK.