Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Unverified Commit 4c3680eb authored by Simon Chan's avatar Simon Chan
Browse files

chore: separate the book package

This cuts the total dependency count in half (1514->777)
parent aecc8883
Loading
Loading
Loading
Loading

apps/book/.gitignore

deleted100644 → 0
+0 −20
Original line number Original line Diff line number Diff line
# Dependencies
/node_modules

# Production
/build

# Generated files
.docusaurus
.cache-loader

# Misc
.DS_Store
.env.local
.env.development.local
.env.test.local
.env.production.local

npm-debug.log*
yarn-debug.log*
yarn-error.log*

apps/book/README.md

deleted100644 → 0
+0 −33
Original line number Original line Diff line number Diff line
# Website

This website is built using [Docusaurus 2](https://docusaurus.io/), a modern static website generator.

## Installation

```console
yarn install
```

## Local Development

```console
yarn start
```

This command starts a local development server and opens up a browser window. Most changes are reflected live without having to restart the server.

## Build

```console
yarn build
```

This command generates static content into the `build` directory and can be served using any static contents hosting service.

## Deployment

```console
GIT_USER=<Your GitHub username> USE_SSH=true yarn deploy
```

If you are using GitHub pages for hosting, this command is a convenient way to build the website and push to the `gh-pages` branch.

apps/book/babel.config.js

deleted100644 → 0
+0 −3
Original line number Original line Diff line number Diff line
module.exports = {
  presets: [require.resolve('@docusaurus/core/lib/babel/preset')],
};
+0 −146
Original line number Original line Diff line number Diff line
---
sidebar_position: 1
---

<!--
cspell: ignore libusb
cspell: ignore nodaemon
-->

# Architecture

This part describes the architecture of native ADB and Web ADB, and why there are designed in this way.

## Native ADB

Native ADB has three components:

<div className="flow-chart">

```
┌───────────────────────────────┐  ┌──────────────┐
│                               │  │              │
│ ┌───────────┐     ┌────────┐  │  │ ┌──────────┐ │
│ │           ├─────►        ├──┼──┼─►          │ │
│ │ Client A  │     │        │  │  │ │ Daemon A │ │
│ │           ◄─────┤        ◄──┼──┼─┤          │ │
│ └───────────┘     │        │  │  │ └──────────┘ │
│                   │        │  │  │              │
│ ┌───────────┐     │ Server │  │  │   Device A   │
│ │           ├─────►        │  │  │              │  ┌──────────────┐
│ │ Client B  │     │        │  │  └──────────────┘  │              │
│ │           ◄─────┤        │  │                    │ ┌──────────┐ │
│ └───────────┘     │        ├──┼────────────────────┼─►          │ │
│                   │        │  │                    │ │ Daemon B │ │
│                   │        ◄──┼────────────────────┼─┤          │ │
│  Computer A       └──▲──┬──┘  │                    │ └──────────┘ │
│                      │  │     │                    │              │
└──────────────────────┼──┼─────┘                    │   Device B   │
                       │  │                          │              │
┌───────────────┐      │  │                          └──────────────┘
│               │      │  │
│ ┌───────────┐ │      │  │
│ │           ├─┼──────┘  │
│ │ Client C  │ │         │
│ │           ◄─┼─────────┘
│ └───────────┘ │
│               │
│  Computer B   │
│               │
└───────────────┘
```

</div>

### Client

**Client** receives command line inputs, generates request packets, sends them to **server** over TCP.

Because there can be multiple devices connected to the computer, **clients** add a "host prefix" to specify the device.

### Server

**Server** is in the same binary as **client**, but runs in a separate process with different command line arguments. Usually **servers** are spawned by **clients** when they cannot find one on localhost. To manually spawn a **server**, use `adb server nodaemon`. By default, it binds to `localhost:5037`.

It is also possible to use SSH tunnel to let **clients** connect to a **server** running on a remote machine.

**Servers** are responsible for discovering and connecting to devices. They also handle packets from **clients**.

Some packets should be processed by **server** itself (for example `adb devices`), it generates response packets and sends them to **client**.

Others need to be forwarded to **daemons** (for example `adb shell`). It finds the specified **daemon** using the "host prefix", rewrites the packet to remove "host prefix", and finally sends it to the **daemon** over USB (libusb/WinUSB) or TCP.

Because USB APIs only allow one connection to a device simultaneously, to use multiple CLI applications with one device, the **server** is required to multiplex the packets.

### Daemon

**Daemon** runs on Android devices and emulators, it receives packets, handles them, and generates responses.

Historically, because most device only has one USB port, **daemons** can only handle one connection. But even after ADB over Wi-Fi has been added, one **daemon** can still handle one TCP connection.

### Protocol

All packets between **client-server** and **server-daemon** are in the ADB packet format, but as mentioned before, **client-server** packets contain an extra "host prefix". ADB packet format will be described in [packet](./packet.md) chapter, while "host prefix" will be described in [stream](./stream.md) chapter.

## Web ADB

Web ADB reuses native ADB daemons, but there is no **client**/**server**: One application, one connection, to one device.

<div className="flow-chart">

```
┌──────────────────────────────────┐  ┌──────────────┐
│                                  │  │              │
│ ┌──────────┐    ┌─────────────┐  │  │ ┌──────────┐ │
│ │          ├────►             ├──┼──┼─►          │ │
│ │  Core A  │    │  Backend A  │  │  │ │ Daemon A │ │
│ │          ◄────┤             ◄──┼──┼─┤          │ │
│ └──────────┘    └─────────────┘  │  │ └──────────┘ │
│                                  │  │              │
│                                  │  │   Device A   │
│                                  │  │              │  ┌──────────────┐
│                                  │  └──────────────┘  │              │
│ ┌──────────┐    ┌─────────────┐  │                    │ ┌──────────┐ │
│ │          ├────►             ├──┼────────────────────┼─►          │ │
│ │  Core B  │    │  Backend B  │  │                    │ │ Daemon B │ │
│ │          ◄────┤             ◄──┼────────────────────┼─┤          │ │
│ └──────────┘    └─────────────┘  │                    │ └──────────┘ │
│                                  │                    │              │
│        JavaScript Runtime        │                    │   Device B   │
│                                  │                    │              │
└──────────────────────────────────┘                    └──────────────┘
```

</div>

### Core

**Core** is the `@yume-chan/adb` package. It generates data in ADB protocol, without "host prefix" (not needed because packets are directly sent to **daemons** via a **backend**).

### Backend

One **backend** defines one method to transmit and receive ADB packets. There are already multiple backend implementations, for example `@yume-chan/adb-backend-usb` and `@yume-chan/adb-backend-ws`.

One **core** instance requires one **backend** instance, so it only connects to one device.

Because JavaScript runtimes are generally more isolated, sharing devices between multiple application is not a consideration. However, it is still very easy to share a **core** instance within a single application, and if a runtime has more privileges, sharing **core** using a custom protocol is also not impossible.

Having Backend as an independent part also makes it extremely easy to port to other runtimes (Web Browsers, Node.js, Electron, etc.).

Possible Backend implementations:

* Web Browsers
  * WebUSB API (USB)
  * WebSocket + Custom WebSockify forwarder (TCP)
* Node.js/Electron
  * Any USB libraries (USB)
  * `net` module (TCP)
  * WebSocket + Custom WebSockify forwarder (TCP)

## Comparison

|                                  | Native ADB                             | Web ADB              |
| -------------------------------- | -------------------------------------- | -------------------- |
| Who implements all ADB commands? | Client                                 | Core                 |
| Who directly talks to device?    | Server                                 | Backend              |
| How does them talk internally?   | TCP Socket (variation of ADB protocol) | JavaScript API calls |
+0 −7
Original line number Original line Diff line number Diff line
---
sidebar_position: 4
---

# Authentication

Because ADB can be remotely controlled to modify device states, authentication is required to prevent malicious actions.
Loading