Servidor AIDL

Finalmente, podemos criar um servidor que expõe o serviço:

birthday_service/src/server.rs:

//! Birthday service.
use birthdayservice::BirthdayService;
use com_example_birthdayservice::aidl::com::example::birthdayservice::IBirthdayService::BnBirthdayService;
use com_example_birthdayservice::binder;

const SERVICE_IDENTIFIER: &str = "birthdayservice";

/// Ponto de entrada para serviço de aniversário.
fn main() {
    let birthday_service = BirthdayService;
    let birthday_service_binder = BnBirthdayService::new_binder(
        birthday_service,
        binder::BinderFeatures::default(),
    );
    binder::add_service(SERVICE_IDENTIFIER, birthday_service_binder.as_binder())
        .expect("Falha ao registrar o serviço");
    binder::ProcessState::join_thread_pool()
}

birthday_service/Android.bp:

rust_binary {
    name: "birthday_server",
    crate_name: "birthday_server",
    srcs: ["src/server.rs"],
    rustlibs: [
        "com.example.birthdayservice-rust",
        "libbinder_rs",
        "libbirthdayservice",
    ],
    prefer_rlib: true, // Para evitar erro de ligação dinâmica.
}

O processo de pegar uma implementação de serviço definida pelo(a) usuário(a) (neste caso o tipo BirthdayService, que implementa o IBirthdayService) e iniciá-la como um serviço Binder tem várias etapas, e pode parecer mais complicado do que os estudantes estão acostumados se eles usaram Binder a partir de C++ ou de outra linguagem. Explique aos estudantes por que cada etapa é necessária.

  1. Crie uma instância do seu tipo de serviço (BirthdayService).
  2. Envolva o objeto de serviço no tipo Bn* correspondente (BnBirthdayService neste caso). Este tipo é gerado pelo Binder e fornece a funcionalidade comum do Binder que seria fornecida pela classe base BnBinder em C++. Não temos herança em Rust, então em vez disso usamos composição, colocando nosso BirthdayService dentro do BnBinderService gerado.
  3. Chame add_service, passando a ele um identificador de serviço e seu objeto de serviço (o objeto BnBirthdayService no exemplo).
  4. Chame join_thread_pool para adicionar a thread atual ao pool de threads do Binder e começar a ouvir conexões.