-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #2 from hiking90/main
Updated document for rsbinder 0.2.0
- Loading branch information
Showing
11 changed files
with
282 additions
and
3 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,13 @@ | ||
# Summary | ||
# **Rsbinder** Development Guide | ||
|
||
- [Chapter 1](./chapter_1.md) | ||
**rsbinder** provides crates implemented in pure Rust that make Binder IPC available on both Android and Linux. | ||
|
||
- [Overview](./overview.md) | ||
- [Architecture](./architecture.md) | ||
- [Getting Started](./getting-started.md) | ||
- [Installation](./installation.md) | ||
- [Hello, World!](./hello-world.md) | ||
- [Enable binder for Linux](./enable-binder-for-linux.md) | ||
- [Arch Linux](./arch-linux.md) | ||
- [TODO: Ubuntu Linux]() | ||
- [TODO: Redhat Linux]() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
# Enable Binder IPC on Arch Linux | ||
|
||
Let's install the linux-zen kernel provided by Arch Linux. Zen kernel already includes Binder IPC. | ||
``` | ||
$ pacman -S linux-zen | ||
``` | ||
|
||
For detailed instructions on installing a new kernel in Arch Linux, refer to the following URL. | ||
|
||
[https://wiki.archlinux.org/title/kernel](https://wiki.archlinux.org/title/kernel) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
# Architecture | ||
|
||
```mermaid | ||
--- | ||
title: Binder IPC Architecture | ||
--- | ||
flowchart BT | ||
AIDL | ||
G[[Generated Rust Code | ||
for Service and Client]] | ||
S(Your Binder Service) | ||
C(Binder Client) | ||
H(HUB | ||
Service Manager) | ||
AIDL-->|rsbinder-aidl compiler|G; | ||
G-.->|Include|S; | ||
G-.->|Include|C; | ||
S-.->|Register Service|H; | ||
C-.->|Query Service|H; | ||
C<-->|Communication|S; | ||
``` | ||
|
||
### Description of each component of the diagram | ||
- AIDL | ||
- The Android Interface Definition Language (AIDL) is a tool that lets users abstract away IPC. Given an interface (specified in a .aidl file), various build systems use the **rsbinder-aidl** crate to construct Rust bindings so that this interface can be used across processes, regardless of the runtime or bitness there. | ||
- [https://source.android.com/docs/core/architecture/aidl](https://source.android.com/docs/core/architecture/aidl) | ||
- Your Binder Service | ||
- Include the Rust code generated from AIDL to create your service. | ||
- Use rsbinder::hub to register your service with the HUB and wait for client requests. | ||
- Binder Client | ||
- Use the Rust code generated from AIDL to communicate with the service. | ||
- Query the HUB to check if the required service is available and receive a Binder Object (rsbinder::SIBinder) for the service. | ||
- Use the Binder Object to communicate with the Binder Service. | ||
- HUB(Service Manager) | ||
- rsbinder provides **rsb_hub**, a service manager for Linux. | ||
- On Android, no additional work is required since the Android service manager is already running. | ||
|
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
# Enable binder for Linux | ||
Most Linux distributions do not have Binder IPC enabled by default, so additional steps are required to use it. | ||
|
||
If you are able to build the Linux kernel yourself, you can enable Binder IPC by adding the following kernel configuration options: | ||
``` | ||
CONFIG_ASHMEM=y | ||
CONFIG_ANDROID=y | ||
CONFIG_ANDROID_BINDER_IPC=y | ||
CONFIG_ANDROID_BINDERFS=y | ||
``` | ||
|
||
Let's examine methods to activate Binder IPC in some representative Linux distributions. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
# Getting Started | ||
If you are new to Binder IPC, | ||
read the [Architecture](./architecture.md) document first. | ||
|
||
The Architecture document provides a comprehensive overview of Binder IPC, including its design, implementation, and usage. It will help you understand the basics of Binder IPC before you start using **rsbinder**. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,170 @@ | ||
# Hello World! | ||
This tutorial will guide you through creating a simple Binder service that echoes a string back to the client, and a client program that uses the service. | ||
|
||
## Create a new Rust project | ||
Create a new Rust project using Cargo: | ||
``` | ||
$ cargo new --lib hello | ||
``` | ||
Create a library project for the common library used by both the client and service: | ||
|
||
## Modify Cargo.toml | ||
In the hello project's Cargo.toml, add the following dependencies: | ||
|
||
``` | ||
[package] | ||
name = "hello" | ||
version = "0.1.0" | ||
publish = false | ||
edition = "2021" | ||
[dependencies] | ||
rsbinder = "0.2.0" | ||
lazy_static = "1" | ||
async-trait = "0.1" | ||
env_logger = "0.11" | ||
[build-dependencies] | ||
rsbinder-aidl = "0.2.0" | ||
``` | ||
Add rsbinder, lazy_static, and async-trait to [dependencies], and add rsbinder-aidl to [build-dependencies]. | ||
|
||
## Create a AIDL File | ||
Create an aidl folder in the project's top directory to manage AIDL files: | ||
``` | ||
$ mkdir -p aidl/hello | ||
$ touch IHello.aidl | ||
``` | ||
The reason for creating an additional **hello** folder is to create a space for the **hello** package. | ||
|
||
Create an IHello.aidl file with the following contents: | ||
``` | ||
package hello; | ||
// Defining the IHello Interface | ||
interface IHello { | ||
// Defining the echo() Function. | ||
// The function takes a single parameter of type String and returns a value of type String. | ||
String echo(in String hello); | ||
} | ||
``` | ||
For more information on AIDL syntax, refer to the [Android AIDL documentation](https://source.android.com/docs/core/architecture/aidl). | ||
|
||
## Create the build.rs | ||
Create a build.rs file to compile the AIDL file and generate Rust code: | ||
``` | ||
use std::path::PathBuf; | ||
fn main() { | ||
rsbinder_aidl::Builder::new() | ||
.source(PathBuf::from("aidl/hello/IHello.aidl")) | ||
.output(PathBuf::from("hello.rs")) | ||
.generate().unwrap(); | ||
} | ||
``` | ||
This uses **rsbinder-aidl** to specify the AIDL source file("**IHello.aidl**") and the generated Rust file name("**hello.rs**"), and then generates the code. | ||
|
||
## Create a common library for Client and Service | ||
For the Client and Service, create a library that includes the Rust code generated from AIDL. | ||
|
||
Create src/lib.rs and add the following content. | ||
``` | ||
// Include the code hello.rs generated from AIDL. | ||
include!(concat!(env!("OUT_DIR"), "/hello.rs")); | ||
// Set up to use the APIs provided in the code generated for Client and Service. | ||
pub use crate::hello::IHello::*; | ||
// Define the name of the service to be registered in the HUB(service manager). | ||
pub const SERVICE_NAME: &str = "my.hello"; | ||
``` | ||
|
||
## Create a service | ||
Let's configure the src/bin/hello_service.rs file as follows. | ||
``` | ||
use env_logger::Env; | ||
use rsbinder::*; | ||
use hello::*; | ||
// Define the name of the service to be registered in the HUB(service manager). | ||
struct IHelloService; | ||
// Implement the IHello interface for the IHelloService. | ||
impl Interface for IHelloService { | ||
// Reimplement the dump method. This is optional. | ||
fn dump(&self, writer: &mut dyn std::io::Write, _args: &[String]) -> Result<()> { | ||
writeln!(writer, "Dump IHelloService")?; | ||
Ok(()) | ||
} | ||
} | ||
// Implement the IHello interface for the IHelloService. | ||
impl IHello for IHelloService { | ||
// Implement the echo method. | ||
fn echo(&self, echo: &str) -> rsbinder::status::Result<String> { | ||
Ok(echo.to_owned()) | ||
} | ||
} | ||
fn main() -> std::result::Result<(), Box<dyn std::error::Error>> { | ||
env_logger::Builder::from_env(Env::default().default_filter_or("warn")).init(); | ||
// Initialize ProcessState with the default binder path and the default max threads. | ||
ProcessState::init_default(); | ||
// Start the thread pool. | ||
// This is optional. If you don't call this, only one thread will be created to handle the binder transactions. | ||
ProcessState::start_thread_pool(); | ||
// Create a binder service. | ||
let service = BnHello::new_binder(IHelloService{}); | ||
// Add the service to binder service manager. | ||
hub::add_service(SERVICE_NAME, service.as_binder())?; | ||
// Join the thread pool. | ||
// This is a blocking call. It will return when the thread pool is terminated. | ||
Ok(ProcessState::join_thread_pool()?) | ||
} | ||
``` | ||
|
||
## Create a client | ||
Create the src/bin/hello_client.rs file and configure it as follows. | ||
``` | ||
use env_logger::Env; | ||
use rsbinder::*; | ||
use hello::*; | ||
fn main() -> std::result::Result<(), Box<dyn std::error::Error>> { | ||
env_logger::Builder::from_env(Env::default().default_filter_or("warn")).init(); | ||
// Initialize ProcessState with the default binder path and the default max threads. | ||
ProcessState::init_default(); | ||
// Create a Hello proxy from binder service manager. | ||
let hello: rsbinder::Strong<dyn IHello> = hub::get_interface(SERVICE_NAME) | ||
.expect(&format!("Can't find {SERVICE_NAME}")); | ||
// Call echo method of Hello proxy. | ||
println!("Result: {}", hello.echo("Hello World!")?); | ||
Ok(()) | ||
} | ||
``` | ||
|
||
## Project folder and file structure | ||
``` | ||
. | ||
├── Cargo.toml | ||
├── aidl | ||
│ └── hello | ||
│ └── IHello.aidl | ||
├── build.rs | ||
└── src | ||
├── bin | ||
│ ├── hello_client.rs | ||
│ └── hello_service.rs | ||
└── lib.rs | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
# Installation | ||
Add the following configuration to your Cargo.toml file: | ||
|
||
``` | ||
[dependencies] | ||
rsbinder = "0.2.0" | ||
lazy_static = "1" | ||
async-trait = "0.1" | ||
[build-dependencies] | ||
rsbinder-aidl = "0.2.0" | ||
``` | ||
|
||
The crates purposes: | ||
- **rsbinder**: This library provides various functionalities for Binder IPC, including communication with the Linux kernel and data serialization/deserialization. | ||
- **lazy_static**: The code generated by the **rsbinder-aidl** compiler depends on the lazy_static crate. | ||
- **async-trait**: The code generated by **rsbinder-aidl** creates both sync and async code. The async code depends on the async-trait crate. | ||
- **rsbinder-aidl**: This is used for AIDL compilation and is invoked in build.rs. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
# Overview | ||
Welcome to **rsbinder**! | ||
|
||
**rsbinder** is a Rust library and toolset that enables you to utilize Binder IPC on Linux and Android OS. | ||
|
||
Binder IPC is an object-oriented IPC (Inter-Process Communication) mechanism that Google added to the Linux kernel for Android. Android uses Binder IPC for all process communication, and since 2015, it has been integrated into the Linux kernel, making it available on all Linux systems. | ||
|
||
However, since it is rarely used outside of Android, it is disabled by default in most Linux distributions. | ||
|
||
### Key Features of Binder IPC: | ||
|
||
- Object-oriented: Binder IPC provides a clean and intuitive object-oriented API for inter-process communication. | ||
- Efficient: Binder IPC is designed for high performance and low overhead. | ||
- Secure: Binder IPC provides strong security features to prevent unauthorized access and tampering. | ||
- Versatile: Binder IPC can be used for a variety of purposes, including remote procedure calls, data sharing, and event notification. | ||
|
||
Before using Binder IPC, you must enable the feature in the kernel. Please refer to [Enable binder for Linux](./ch02-00-enable-binder-for-linux.md) for detailed instructions on setting it up. |
Empty file.
Empty file.