Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Реализация сервиса

Теперь мы можем реализовать сервис AIDL:

birthday_service/src/lib.rs:

// Copyright 2024 Google LLC
// SPDX-License-Identifier: Apache-2.0

//! Реализация интерфейса AIDL `IBirthdayService`.
use com_example_birthdayservice::aidl::com::example::birthdayservice::IBirthdayService::IBirthdayService;
use com_example_birthdayservice::binder;

/// Реализация `IBirthdayService`.
pub struct BirthdayService;

impl binder::Interface for BirthdayService {}

impl IBirthdayService for BirthdayService {
    fn wishHappyBirthday(&self, name: &str, years: i32) -> binder::Result<String> {
        Ok(format!("Happy Birthday {name}, congratulations with the {years} years!"))
    }
}

birthday_service/Android.bp:

rust_library {
    name: "libbirthdayservice",
    crate_name: "birthdayservice",
    srcs: ["src/lib.rs"],
    rustlibs: [
        "com.example.birthdayservice-rust",
    ],
}
  • Покажите путь к сгенерированному трейту IBirthdayService и объясните, почему нужен каждый из сегментов пути.
  • Обратите внимание, что wishHappyBirthday и другие методы IPC AIDL принимают &self (а не &mut self).
    • Это необходимо, потому что Binder обрабатывает входящие запросы в пуле потоков, что позволяет обрабатывать несколько запросов параллельно. Поэтому методы сервиса получают только разделяемую ссылку на self.
    • Любое состояние, которое сервис должен изменять, придётся поместить во что-то вроде Mutex, чтобы допустить безопасное изменение.
    • Правильный подход к управлению состоянием сервиса сильно зависит от деталей вашего сервиса.
  • TODO: Что делает трейт binder::Interface? Есть ли методы, которые можно переопределить? Где исходный код?