1
0
mirror of https://github.com/google/comprehensive-rust.git synced 2025-06-21 08:19:32 +02:00

Publish Comprehensive Rust 🦀

This commit is contained in:
Martin Geisler
2022-12-21 16:36:30 +01:00
commit c212a473ba
252 changed files with 8047 additions and 0 deletions

View File

@ -0,0 +1,38 @@
// ANCHOR: libbirthdayservice
rust_library {
name: "libbirthdayservice",
srcs: ["src/lib.rs"],
crate_name: "birthdayservice",
rustlibs: [
"com.example.birthdayservice-rust",
"libbinder_rs",
],
}
// ANCHOR_END: libbirthdayservice
// ANCHOR: birthday_server
rust_binary {
name: "birthday_server",
crate_name: "birthday_server",
srcs: ["src/server.rs"],
rustlibs: [
"com.example.birthdayservice-rust",
"libbinder_rs",
"libbirthdayservice",
],
prefer_rlib: true,
}
// ANCHOR_END: birthday_server
// ANCHOR: birthday_client
rust_binary {
name: "birthday_client",
crate_name: "birthday_client",
srcs: ["src/client.rs"],
rustlibs: [
"com.example.birthdayservice-rust",
"libbinder_rs",
],
prefer_rlib: true,
}
// ANCHOR_END: birthday_client

View File

@ -0,0 +1,10 @@
aidl_interface {
name: "com.example.birthdayservice",
srcs: ["com/example/birthdayservice/*.aidl"],
unstable: true,
backend: {
rust: { // Rust is not enabled by default
enabled: true,
},
},
}

View File

@ -0,0 +1,22 @@
// Copyright 2022 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// ANCHOR: IBirthdayService
package com.example.birthdayservice;
/** Birthday service interface. */
interface IBirthdayService {
/** Generate a Happy Birthday message. */
String wishHappyBirthday(String name, int years);
}

View File

@ -0,0 +1,42 @@
// Copyright 2022 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// ANCHOR: main
//! Birthday service.
use com_example_birthdayservice::aidl::com::example::birthdayservice::IBirthdayService::IBirthdayService;
use com_example_birthdayservice::binder;
const SERVICE_IDENTIFIER: &str = "birthdayservice";
/// Connect to the BirthdayService.
pub fn connect() -> Result<binder::Strong<dyn IBirthdayService>, binder::StatusCode> {
binder::get_interface(SERVICE_IDENTIFIER)
}
/// Call the birthday service.
fn main() -> Result<(), binder::Status> {
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 = connect().expect("Failed to connect to BirthdayService");
let msg = service.wishHappyBirthday(&name, years)?;
println!("{msg}");
Ok(())
}

View File

@ -0,0 +1,31 @@
// Copyright 2022 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// ANCHOR: IBirthdayService
//! Implementation of the `IBirthdayService` AIDL interface.
use com_example_birthdayservice::aidl::com::example::birthdayservice::IBirthdayService::IBirthdayService;
use com_example_birthdayservice::binder;
/// The `IBirthdayService` implementation.
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!"
))
}
}

View File

@ -0,0 +1,33 @@
// Copyright 2022 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// ANCHOR: main
//! 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";
/// Entry point for birthday service.
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()
}

View File

@ -0,0 +1,14 @@
# Changing API
Let us extend the API with more functionality: we want to let clients specify a
list of lines for the birthday card:
```java
package com.example.birthdayservice;
/** Birthday service interface. */
interface IBirthdayService {
/** Generate a Happy Birthday message. */
String wishHappyBirthday(String name, int years, in String[] text);
}
```

View File

@ -0,0 +1,24 @@
# AIDL Client
Finally, we can create a Rust client for our new service.
*birthday_service/src/client.rs*:
```rust,ignore
{{#include birthday_service/src/client.rs:main}}
```
*birthday_service/Android.bp*:
```javascript
{{#include birthday_service/Android.bp:birthday_client}}
```
Notice that the client does not depend on `libbirthdayservice`.
Build, push, and run the client on your device:
```shell
{{#include ../build_all.sh:birthday_client}}
Happy Birthday Charlie, congratulations with the 60 years!
```

View File

@ -0,0 +1,29 @@
# Deploy
We can now build, push, and start the service:
```shell
{{#include ../build_all.sh:birthday_server}}
```
In another terminal, check that the service runs:
```shell
{{#include ../build_all.sh:service_check_birthday_server}}
Service birthdayservice: found
```
You can also call the service with `service call`:
```shell
$ {{#include ../build_all.sh:service_call_birthday_server}}
Result: Parcel(
0x00000000: 00000000 00000036 00610048 00700070 '....6...H.a.p.p.'
0x00000010: 00200079 00690042 00740072 00640068 'y. .B.i.r.t.h.d.'
0x00000020: 00790061 00420020 0062006f 0020002c 'a.y. .B.o.b.,. .'
0x00000030: 006f0063 0067006e 00610072 00750074 'c.o.n.g.r.a.t.u.'
0x00000040: 0061006c 00690074 006e006f 00200073 'l.a.t.i.o.n.s. .'
0x00000050: 00690077 00680074 00740020 00650068 'w.i.t.h. .t.h.e.'
0x00000060: 00320020 00200034 00650079 00720061 ' .2.4. .y.e.a.r.'
0x00000070: 00210073 00000000 's.!..... ')
```

View File

@ -0,0 +1,15 @@
# Service Implementation
We can now implement the AIDL service:
*birthday_service/src/lib.rs*:
```rust,ignore
{{#include birthday_service/src/lib.rs:IBirthdayService}}
```
*birthday_service/Android.bp*:
```javascript
{{#include birthday_service/Android.bp:libbirthdayservice}}
```

View File

@ -0,0 +1,18 @@
# AIDL Interfaces
You declare the API of your service using an AIDL interface:
*birthday_service/aidl/com/example/birthdayservice/IBirthdayService.aidl*:
```java
{{#include birthday_service/aidl/com/example/birthdayservice/IBirthdayService.aidl:IBirthdayService}}
```
*birthday_service/aidl/Android.bp*:
```javascript
{{#include birthday_service/aidl/Android.bp}}
```
Add `vendor_available: true` if your AIDL file is used by a binary in the vendor
partition.

View File

@ -0,0 +1,15 @@
# AIDL Server
Finally, we can create a server which exposes the service:
*birthday_service/src/server.rs*:
```rust,ignore
{{#include birthday_service/src/server.rs:main}}
```
*birthday_service/Android.bp*:
```javascript
{{#include birthday_service/Android.bp:birthday_server}}
```