README.md
1# Android Platform Binder Codelab
2
3go/android-binder-codelab
4
5This Android Platform Developer codelab explores the use of Binder in the
6Android Platform. go/android-codelab is a prerequisite for this work. In this
7codelab, you create an AIDL interface along with client and server processes
8that communicate with each other over Binder.
9
10## Goals
11
12There are four goals for this codelab:
13
141. Introduce you to Binder, Android's core IPC mechanism
152. Use AIDL to define a Binder interface for a simple client/server interaction
163. Use Binder's Service Management infrastructure to make the service available
17 to clients
184. Get and use the service with basic error handling
19
20## What to expect
21
22### Estimated time
23
24* Hands-off time ~4 hours
25* Hands-on time ~1 hours
26
27### Prerequisites
28
29**Before** taking this codelab, complete go/android-codelab first. If external,
30follow https://source.android.com/docs/setup/start.
31
32You will need an Android repo with the ability to make changes, build, deploy,
33test, and upload the changes. All of this is covered in go/android-codelab.
34
35See the slides at go/onboarding-binder for a summary of key concepts that will
36help you understand the steps in this codelab.
37
38## Codelab
39
40Most of this code can be found in `system/tools/aidl/codelab`, but the example
41service isn't installed on real devices. The build code to install the service
42on the device and the sepolicy changes are described in this `README.md` but not
43submitted.
44
45### Create the new AIDL interface
46
47Choose a location for the AIDL interface definition.
48
49* `hardware/interfaces` - for
50 [HAL](https://source.android.com/docs/core/architecture/hal) interfaces that
51 device-specific processes implement and the Android Platform depends on as a
52 client
53* `frameworks/hardware/interfaces` - for interfaces that the Android Framework
54 implements for device-specific clients
55* `system/hardware/interfaces` - for interfaces that Android system process
56 implement for device-specific clients
57* Any other directory for interfaces that are used between processes that are
58 installed on the same
59 [partitions](https://source.android.com/docs/core/architecture/partitions)
60
61Create a new `aidl_interface` module in a new or existing `Android.bp` file.
62
63Note: go/android.bp has all of the available Soong modules and their supported
64fields.
65
66```soong
67// File: `codelab/aidl/Android.bp`
68aidl_interface {
69 // Package name for the interface. This is used when generating the libraries
70 // that the services and clients will depend on.
71 name: "hello.world",
72 // The source `.aidl` files that define this interface. It is recommended to
73 // create them in a directory next to this Android.bp file with a
74 // directory structure that follows the package name. If you want to change
75 // this, use `local_include_dir` to point to the new directory.
76 srcs: [
77 "hello/world/*.aidl",
78 ],
79 // For simplicity we start with an unstable interface. See
80 // https://source.android.com/docs/core/architecture/aidl/stable-aidl
81 // for details on stable interfaces.
82 unstable: true,
83 // This field controls which libraries are generated at build time and their
84 // backend-specific configurations. AIDL supports different languages.
85 backend: {
86 ndk: {
87 enabled: true,
88 }
89 rust: {
90 enabled: true,
91 }
92 }
93}
94```
95
96Create your first AIDL file.
97
98```java
99// File: `codelab/aidl/hello/world/IHello.aidl`
100// The package name is recommended to match the `name` in the `aidl_interface`
101package hello.world;
102
103interface IHello {
104 // Have the service log a message for us
105 void LogMessage(String message);
106 // Get a "hello world" message from the service
107 String getMessage();
108}
109```
110
111Build the generated AIDL libraries.
112
113```shell
114m hello.world-ndk hello.world-rust
115```
116
117Note: `m hello.world` without the backend suffix will not build anything.
118
119### Create the service
120
121Android encourages Rust for native services so let's build a Rust service!
122
123Binder has easy-to-use libraries to facilitate fuzzing of binder services that
124require the service being defined in its own library. With that in mind, we
125create the library that implements the interface first.
126
127#### Interface implementation
128
129Create a separate library for the interface implementation so it can be used
130for the service and for the fuzzer.
131
132* See [codelab/service/Android.bp](codelab/service/Android.bp)
133
134* See [codelab/service/hello_service.rs](codelab/service/hello_service.rs)
135
136#### Service binary
137
138Create the service that registers itself with servicemanager and joins the
139binder threadpool.
140
141* See [codelab/service/Android.bp](codelab/service/Android.bp)
142
143* See [codelab/service/service_main.rs](codelab/service/service_main.rs)
144
145An init.rc file is required for the process to be started on a device.
146
147* See
148 [codelab/service/hello-world-service-test.rc](codelab/service/hello-world-service-test.rc)
149
150#### Sepolicy for the service
151
152Associate the service binary with a selinux context so init can start it.
153```
154// File: system/sepolicy/private/file_contexts
155/system/bin/hello-world-service-test u:object_r:hello_exec:s0
156```
157
158Add a file for the service to define its types, associate the binary to the
159types, and give permissions to the service..
160```
161// File: system/sepolicy/private/hello.te
162
163// Permissions required for the process to start
164type hello, domain;
165typeattribute hello coredomain;
166type hello_exec, system_file_type, exec_type, file_type;
167init_daemon_domain(hello)
168
169// Permissions to be a binder service and talk to service_manager
170binder_service(hello)
171binder_use(hello)
172binder_call(hello, binderservicedomain)
173
174// Give permissions to this service to register itself with service_manager
175allow hello hello_service:service_manager { add find };
176```
177
178Declare this service as a service_manager_type
179```
180// File: system/sepolicy/public/service.te
181type hello_service, service_manager_type;
182```
183
184Associate the AIDL interface/instance with this service
185```
186// File: system/sepolicy/private/service_contexts
187hello.world.IHello/default u:object_r:hello_service:s0
188```
189
190#### Fuzzer
191
192Create the fuzzer and use `fuzz_service` to do all of the hard work!
193
194* See [codelab/service/Android.bp](codelab/service/Android.bp)
195
196* See [codelab/service/service_fuzzer.rs](codelab/service/service_fuzzer.rs)
197
198Associate the fuzzer with the interface by adding the following to
199`system/sepolicy/build/soong/service_fuzzer_bindings.go`:
200```
201"hello.world.IHello/default": []string{"hello-world-fuzzer"},
202```
203This step is required by the build system once we add the sepolicy for the
204service in the previous step.
205
206### Create the client
207
208#### Sepolicy for the client
209
210We skip these details by creating the client in a `cc_test`.
211
212The clients need permission to `find` the service through servicemanager:
213
214`allow <client> hello_service:servicemanager find;`
215
216The clients need permission to `call` the service, pass the binders to other
217processes, and use any file descriptors returned through the interface. The
218`binder_call` macro handles all this for us.
219
220`binder_call(<client>, hello_service);`
221
222### Test the changes
223
224Add the service to the device. Since this is a system service it needs to be
225added to the system partition. We add the following to
226`build/make/target/product/base_system.mk`.
227
228```
229PRODUCT_PACKAGES += hello-world-service-test
230```
231
232Build the device.
233
234Launch the device.
235
236Verify the service is in the `dumpsys -l` output.
237
238`atest hello-world-client-test` and verify it passes!
239
240## Wrap up
241
242Congratulations! You are now familiar with some core concepts of Binder and AIDL
243in Android.
244When you think of IPC in Android, think of Binder.
245When you think of Binder, think of AIDL.
246
247See https://source.android.com/docs/core/architecture/aidl for related AIDL and
248Binder documentation.
249Check out https://source.android.com/docs/core/architecture/aidl/aidl-hals for
250details that are more specific to Hardware Abstraction Layer (HAL) services.
251
252### Supporting documentation
253
254* go/onboarding-binder
255* go/binder-ipc
256* go/stable-aidl
257* go/aidl-backends
258* go/aidl (for app developers with Java/Kotlin)
259
260See all of the other AIDL related pages in our external documentation:
261https://source.android.com/docs/core/architecture/aidl.
262
263### Feedback
264
265If you are external please see
266https://source.android.com/docs/setup/contribute/report-bugs to find out how to
267create a Bug for questions, suggestions, or reporting bugs.
268
269Please write to android-idl-discuss@google.com.
270
271Anyone is free to create and upload CLs in `system/tools/aidl/codelab/` with any
272suggestions or corrections.
273
274### Wish list
275
276Add your suggested additions and updates to this codelab here!
277
2781. I wish this codelab would dive deeper into `DeathRecipients` and remote
279 reference counting
280
281