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