Use aidl-cpp to generate c++ Binder interfaces
background
“Aidl” expresses several related but different concepts
- AIDL Interface definition language
- .aidl file (with AIDL)
- Convert aiDL to a Client/Server IPC interface
The AIDL generator is a command-line tool that generates binder interfaces for client and Server stubs from a file ending in.aidl. For Java interfaces, the feasibility file for the call is aidl, while for c++ files, aidl-cpp is called. In this document, we will use AIDL to describe the. AIDL file. The AIDL generator uses a code generation tool to parse the AIDL in the. AIDL file and output the code.
Previously, aidl generators generated only interface/proxy/stub Java code. C++ binder interfaces were manually written and compatible with Java. The Brillo project added c++ support to the aidl generator, and the generated c++ is cross-language compatible (e.g., Java client has been tested to interact with native servers).
The overview
This document focuses on how c++ is generated:
- Build interfaces
- Cross-language type mapping
- Implement the generated interface
- C + + package
- Error reporting across languages
- Empty reference processing across languages
- Integer constants across languages
Design details
Establish interface
Write aiDL in a.aidl file and add it to LOCAL_SRC_FILES in android.mk. If the build target is a binary file (for example, include $(BUILD_SHARED_LIBRARY)), then the generated code will be C ++. Not Java.
The definition of AIDL should be in the same repository as the implementation, and any system that needs to be defined needs to be implemented (including Parcelables and interfaces). If there are multiple implementations (one c++ and one Java), the definition is kept consistent with the native implementation, and the Android system now has native components that run without Java.
If you use the import statement in AIDL, even in the same package, you need to add the path of the import file in LOCAL_AIDL_INCLUDES, which should be a path relative to the Android tree. For example, a definition of com. Example. IFoo IFoo. Aidl document, its path hierarchy for something/something else/com/example/IFoo aidl. Then we should write:
LOCAL_AIDL_INCLUDES := something/something-else
Copy the code
The resulting C++ is in the nested namespace corresponding to the interface package, and the generated headers correspond to the interface package. For example, package com.example.IFoo corresponds to namespace ::com::example::IFoo. The header file path corresponds to com/example/ ifoo.h.
Similar to how Java works, the file path ending in.aidl must match the corresponding package. If IFoo. Aidl statement itself in com. Package of example, the directory structure (such as adding in LOCAL_SRC_FILES) must be similar to: / some/prefix/com/example/IFoo aidl
To generate code from.aidl files in other build targets (such as other binaries or Java), simply add the relative.aidl path to LOCAL_SRC_FILES. The same goes for code imported from other directories to AIDL: add its root path (the root path of the.aidl file) to LOCAL_AIDL_INCLUDES.
Supplementary (important)
All of this is based on the android.mk file, how about the android.bp file? By way of example, the comparison is as follows
Android.bp is like a JSON description; Android.mk appears to be an environment change assignment process;
Assuming that current/some/prefix/com/example/IFoo aidl stay application, IFoo in com/example package, Bn end inheritance need public com: example: : BnIFoo, At the BP end, iBinder is converted to COM ::example::IIFoo. In fact, bpIFoo is called. At last, IPC is carried out through bpBinder.
The use of LOCAL_SRC_FILES in android. mk described above:
LOCAL_SRC_FILES := /some/path
LOCAL_SRC_FILES += /some/prefix/com/example/IFoo.aidl
Copy the code
Corresponding to android.bp would be:
src: [
"/some/path",
] + [
"/some/prefix/com/example/IFoo.aid",
],
Copy the code
LOCAL_AIDL_INCLUDES in android.mk
LOCAL_AIDL_INCLUDES += /some/prefix
Copy the code
Corresponding to android.bp would be:
aidl: {
include_dirs: ["/some/prefix"]
}
Copy the code
Through the above examples, fine products, not much to repeat!
Type mapping
The following table summarizes the Java types corresponding to c++ types that might be used for in/out/inout arguments in AIDL files.
Java type | c++ type | inout | Notes |
---|---|---|---|
boolean | bool | in | “The first eight types are considered basic.” |
byte | int8_t | in | |
char | char16_t | in | |
int | int32_t | in | |
long | int64_t | in | |
float | float | in | |
double | double | in | |
String | String16 | in | Support for null references |
android.os.Parcelable | android::Parcelable | inout | |
T extends IBinder | sp | in | |
Arrays( T[ ] ) | vector | inout | |
List | vector | inout | |
PersistableBundle | PersistableBundle | inout | binder/PersistableBundle.h |
List | vector<sp> | inout | |
FileDescriptor | ScopedFd | inout | nativehelper/ScopedFd.h |
Note that java.util.Map and java.utils.List are not good choices for cross-language communication, as they can contain arbitrary types on the Java side. For example, cast a Map to Map <String, Object>, and then dynamically examine the Object value and serialize it as a type/value pair. Support to send any Java serializable files, Android bundle software, etc.
Implement the generated interface
Given an interface declaration, for example:
package foo;
import bar.IAnotherInterface;
interface IFoo {
IAnotherInterface DoSomething(int count, out List<String> output);
}
Copy the code
Aidl-cpp will generate the c++ interface:
namespace foo { // Some headers have been omitted for clarity. #include <android/String16.h> #include <cstdint> #include <vector> #include <bar/IAnotherInterface.h> // Some class members have been omitted for clarity. class IFoo : public android::IInterface { public: virtual android::binder::Status DoSomething( int32_t count, std::vector<android::String16>* output, android::sp<bar::IAnotherInterface>* returned_value) = 0; };Copy the code
Note that this AIDL-cpp will import the imported package type used in the.aiDL file. For the type of import (for example: package and interface), it imports the header corresponding to the imported package/class name. For example, import bar.ianOtherInterface. Aidl-cpp generates #include
.
When writing an implementation on the service side:
#include "foo/BnFoo.h"
namespace unrelated_namespace {
class MyFoo : public foo::BnFoo {
public:
android::binder::Status DoSomething(
int32_t count,
std::vector<android::String16>* output,
android::sp<bar::IAnotherInterface>* returned_value) override {
for (int32_t i = 0; i < count; ++i) {
output->push_back(String16("..."));
}
*returned_value = new InstanceOfAnotherInterface;
return Status::ok();
}
}; // class MyFoo
} // namespace unrelated_namespace
Copy the code
Note that the output values output and returned_value are passed through Pointers and are always valid.
C++ Parcelables
Parcelables are packable objects that are transported by binder.
In Java, a parcelables should extend Android.os. Parcelable and provide an implementation of Static Final CREATOR, as well as a readFormPacel method if an out parameter is required.
In C++, parcelables must implement android::Parcelable, the original file is located in binder/ parcelable.h in libbinder. Parcelables must define a constructor that takes no arguments. To be used in an array, a Parcelable must implement a copy constructor or a move constructor (implicitly called in a vector).
The C++ AIDL generator needs to know which header file parcelables are defined in, which it will know from the following cpp_header directive. The generator will take the string bar/foo.h and include it.
// ExampleParcelable.aidl
package com.example.android;
// Native types must be aliased at their declaration in the appropriate .aidl
// file. This allows multiple interfaces to use a parcelable and its C++
// equivalent without duplicating the mapping between the C++ and Java types.
// Generator will assume bar/foo.h declares class
// com::example::android::ExampleParcelable
parcelable ExampleParcelable cpp_header "bar/foo.h";
Copy the code
Null reference processing
Abnormality report
Integer constants
(I’ll leave off the last three for now until I use them.)
Android.googlesource.com/platform/sy…