Сервер AIDL
Наконец, мы можем создать сервер, который открывает сервис:
birthday_service/src/server.rs:
// Copyright 2024 Google LLC
// SPDX-License-Identifier: Apache-2.0
//! Сервис дня рождения.
use birthdayservice::BirthdayService;
use com_example_birthdayservice::aidl::com::example::birthdayservice::IBirthdayService::BnBirthdayService;
use com_example_birthdayservice::binder;
const SERVICE_IDENTIFIER: &str = "birthdayservice";
/// Точка входа сервиса дня рождения.
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("Failed to register service");
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",
"libbirthdayservice",
],
prefer_rlib: true, // Чтобы избежать ошибки динамической линковки.
}
Процесс превращения пользовательской реализации сервиса (в данном случае типа BirthdayService, который реализует IBirthdayService) в сервис Binder состоит из нескольких шагов. Это может показаться сложнее, чем студенты привыкли, если они использовали Binder из C++ или другого языка. Объясните студентам, зачем нужен каждый шаг.
- Создайте экземпляр вашего типа сервиса (
BirthdayService). - Оберните объект сервиса в соответствующий тип
Bn*(в данном случаеBnBirthdayService). Этот тип генерируется Binder и предоставляет общую функциональность Binder, похожую на базовый классBnBinderв C++. Поскольку в Rust нет наследования, мы используем композицию: помещаем нашBirthdayServiceвнутрь сгенерированногоBnBinderService. - Вызовите
add_service, передав ему идентификатор сервиса и объект сервиса (в примере — объектBnBirthdayService). - Вызовите
join_thread_pool, чтобы добавить текущий поток в пул потоков Binder и начать слушать подключения.