AIDL Server

Finally, we can create a server which exposes the service:

birthday_service/src/server.rs:

  1. //! Birthday service.
  2. use birthdayservice::BirthdayService;
  3. use com_example_birthdayservice::aidl::com::example::birthdayservice::IBirthdayService::BnBirthdayService;
  4. use com_example_birthdayservice::binder;
  5. const SERVICE_IDENTIFIER: &str = "birthdayservice";
  6. /// Entry point for birthday service.
  7. fn main() {
  8. let birthday_service = BirthdayService;
  9. let birthday_service_binder = BnBirthdayService::new_binder(
  10. birthday_service,
  11. binder::BinderFeatures::default(),
  12. );
  13. binder::add_service(SERVICE_IDENTIFIER, birthday_service_binder.as_binder())
  14. .expect("Failed to register service");
  15. binder::ProcessState::join_thread_pool();
  16. }

birthday_service/Android.bp:

  1. rust_binary {
  2. name: "birthday_server",
  3. crate_name: "birthday_server",
  4. srcs: ["src/server.rs"],
  5. rustlibs: [
  6. "com.example.birthdayservice-rust",
  7. "libbinder_rs",
  8. "libbirthdayservice",
  9. ],
  10. prefer_rlib: true, // To avoid dynamic link error.
  11. }

The process for taking a user-defined service implementation (in this case the BirthdayService type, which implements the IBirthdayService) and starting it as a Binder service has multiple steps, and may appear more complicated than students are used to if they’ve used Binder from C++ or another language. Explain to students why each step is necessary.

  1. Create an instance of your service type (BirthdayService).
  2. Wrap the service object in corresponding Bn* type (BnBirthdayService in this case). This type is generated by Binder and provides the common Binder functionality that would be provided by the BnBinder base class in C++. We don’t have inheritance in Rust, so instead we use composition, putting our BirthdayService within the generated BnBinderService.
  3. Call add_service, giving it a service identifier and your service object (the BnBirthdayService object in the example).
  4. Call join_thread_pool to add the current thread to Binder’s thread pool and start listening for connections.