AIDL クライアント

最後に、新しいサービス用の Rust クライアントを作成できます。

birthday_service/src/client.rs:

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

use com_example_birthdayservice::aidl::com::example::birthdayservice::IBirthdayService::IBirthdayService;
use com_example_birthdayservice::binder;

const SERVICE_IDENTIFIER: &str = "birthdayservice";

/// Call the birthday service.
fn main() -> Result<(), Box<dyn Error>> {
    let name = std::env::args().nth(1).unwrap_or_else(|| String::from("Bob"));
    let years = std::env::args()
        .nth(2)
        .and_then(|arg| arg.parse::<i32>().ok())
        .unwrap_or(42);

    binder::ProcessState::start_thread_pool();
    let service = binder::get_interface::<dyn IBirthdayService>(SERVICE_IDENTIFIER)
        .map_err(|_| "Failed to connect to BirthdayService")?;

    // Call the service.
    let msg = service.wishHappyBirthday(&name, years)?;
    println!("{msg}");
}

birthday_service/Android.bp:

rust_binary {
    name: "birthday_client",
    crate_name: "birthday_client",
    srcs: ["src/client.rs"],
    rustlibs: [
        "com.example.birthdayservice-rust",
    ],
    prefer_rlib: true, // To avoid dynamic link error.
}

クライアントは libbirthdayservice に依存しないことに注意してください。

クライアントをビルドし、デバイスにプッシュして実行します。

m birthday_client
adb push "$ANDROID_PRODUCT_OUT/system/bin/birthday_client" /data/local/tmp
adb shell /data/local/tmp/birthday_client Charlie 60
Happy Birthday Charlie, congratulations with the 60 years!
  • Strong<dyn IBirthdayService> は、クライアントが接続したサービスを表すトレイトオブジェクトです。
    • Strong は Binder 用のカスタムスマートポインタ型です。これは、サービスのトレイトオブジェクトに対するプロセス内の参照カウントと、そのオブジェクトを参照しているプロセス数を追跡するグローバルな Binder の参照カウントの両方を処理します。
    • クライアントがサービスとやり取りするために使用するトレイトオブジェクトは、サーバーが実装するものとまったく同じトレイトを使用することに注意してください。特定の Binder インターフェースに対して生成される Rust のトレイトは 1 つだけであり、クライアントとサーバーの両方がそれを使用します。
  • サービスの登録時に使用したものと同じサービス識別子を使用します。理想的には、これはクライアントとサーバーの両方が依存できる共通のクレートで定義するのがよいでしょう。