Skip to content

Commit b244937

Browse files
xaionaro@dx.centerxaionaro@dx.center
authored andcommitted
docs: add gRPC remote access, deployment, and E2E sections to README
Sections moved from the jni repository: gRPC architecture diagrams, jniservice deployment (adb/Magisk/APK), connecting instructions, E2E test verification table, and security disclaimer.
1 parent 91ea292 commit b244937

1 file changed

Lines changed: 127 additions & 10 deletions

File tree

README.md

Lines changed: 127 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -3,19 +3,132 @@
33
gRPC proxy layer for [AndroidGoLab/jni](https://github.com/AndroidGoLab/jni).
44

55
Exposes Android JNI bindings over gRPC so that a host machine can control an
6-
Android device remotely.
6+
Android device remotely. Includes `jniservice` (the on-device gRPC server),
7+
`jnicli` (the command-line client), and `jniserviceadmin` (ACL management).
78

89
## Components
910

10-
- **cmd/jnicli** CLI client that talks to jniservice over gRPC
11-
- **cmd/jniservice** gRPC server that runs on the Android device (APK or Magisk module)
12-
- **cmd/jniserviceadmin** Admin CLI for ACL management
13-
- **grpc/** gRPC server and client wrappers
14-
- **proto/** Protobuf service definitions
15-
- **handlestore/** Object handle mapping for cross-process JNI references
16-
- **tools/cmd/callbackgen** Code generator for Java callback adapter classes
11+
- **cmd/jnicli** -- CLI client that talks to jniservice over gRPC
12+
- **cmd/jniservice** -- gRPC server that runs on the Android device (APK or Magisk module)
13+
- **cmd/jniserviceadmin** -- Admin CLI for ACL management
14+
- **grpc/** -- gRPC server and client wrappers
15+
- **proto/** -- Protobuf service definitions
16+
- **handlestore/** -- Object handle mapping for cross-process JNI references
17+
- **tools/cmd/callbackgen** -- Code generator for Java callback adapter classes
1718

18-
## Quick start
19+
## gRPC Remote Access
20+
21+
The gRPC layer turns any Android phone into a remotely accessible API server. A companion service (`jniservice`) runs on the device -- either as an APK (non-rooted) or a Magisk module (rooted, auto-starts on boot). Clients on any machine connect over the network using `jnicli`.
22+
23+
```mermaid
24+
sequenceDiagram
25+
participant Client as jnicli (host)
26+
participant Server as jniservice (phone)
27+
participant Android as Android APIs
28+
29+
Client->>Server: auth register (CSR)
30+
Server-->>Client: signed client cert + CA cert
31+
32+
Client->>Server: auth request-permission
33+
Server->>Android: launch approval dialog
34+
Note over Android: User taps "Approve"
35+
Server-->>Client: status: approved
36+
37+
Client->>Server: location get (mTLS)
38+
Server->>Android: LocationManager.getLastKnownLocation()
39+
Android-->>Server: Location object
40+
Server-->>Client: {lat, lon, alt, accuracy}
41+
```
42+
43+
Each client registers with a unique certificate (mTLS). Method access is controlled by per-service ACLs -- the device owner approves which services each client can use through an on-screen dialog:
44+
45+
```mermaid
46+
flowchart LR
47+
subgraph Client
48+
CLI["jnicli"]
49+
end
50+
51+
subgraph "jniservice (on device)"
52+
TLS["mTLS gateway"]
53+
ACL["Per-service ACL"]
54+
SVC["31 Android API\nservices"]
55+
RAW["Raw JNI surface"]
56+
PROXY["Callback proxy\n(Camera2, etc.)"]
57+
end
58+
59+
CLI -->|client cert| TLS
60+
TLS --> ACL
61+
ACL -->|"camera.*"| SVC
62+
ACL -->|"admin only"| RAW
63+
SVC --> Android["Android\nFramework"]
64+
RAW --> Android
65+
PROXY --> Android
66+
```
67+
68+
**Available services** include camera, location, bluetooth, WiFi, telephony, battery, power, alarm, vibrator, audio, NFC, notifications, and more (31 services total, ~2000 RPCs). Callback-based APIs (like Camera2) work through a bidirectional streaming proxy with build-time generated adapter classes.
69+
70+
## Running jniservice on Android
71+
72+
jniservice is a gRPC server that exposes the JNI surface and Android APIs over the network.
73+
74+
### Development (via adb)
75+
76+
```bash
77+
make deploy # build, push, start, forward port
78+
make deploy HOST_PORT=50052 # use different host port
79+
make stop-server # stop the server
80+
```
81+
82+
### Rooted devices (Magisk module)
83+
84+
Auto-starts on boot. Self-contained -- no `make deploy` needed after install.
85+
86+
```bash
87+
make magisk DIST_GOARCH=arm64 # build module
88+
adb push build/jniservice-magisk-arm64-v8a.zip /sdcard/
89+
adb shell su -c "magisk --install-module /sdcard/jniservice-magisk-arm64-v8a.zip"
90+
adb reboot # starts on next boot
91+
```
92+
93+
Configuration: create `/data/local/tmp/jniservice.env` on the device:
94+
```bash
95+
JNISERVICE_PORT=50051
96+
JNISERVICE_TOKEN=my-secret-token
97+
```
98+
99+
### Non-rooted devices (APK)
100+
101+
Auto-starts on boot via foreground service.
102+
103+
```bash
104+
make apk DIST_GOARCH=arm64 # build APK
105+
adb install build/jniservice-arm64-v8a.apk
106+
```
107+
108+
Open "jniservice" from the launcher once to start the service and register the boot receiver.
109+
110+
### Connecting
111+
112+
```bash
113+
adb forward tcp:50051 tcp:50051
114+
jnicli --addr localhost:50051 --insecure jni get-version
115+
```
116+
117+
## E2E Test Verification
118+
119+
Run `make test-emulator` to test against a connected device or emulator. Tests skip when `JNICTL_E2E_ADDR` is not set.
120+
121+
<details>
122+
<summary>Verified platforms (click to expand)</summary>
123+
124+
| Type | Device | Android | API | ABI | Build | Date | Passed | Total |
125+
|------|--------|---------|-----|-----|-------|------|--------|-------|
126+
| Phone | Pixel 8a | 16 | 36 | arm64-v8a | BP4A.260205.001 | 2026-03-14 | 21 | 21 |
127+
| Emulator | sdk_gphone64_x86_64 | 15 | 35 | x86_64 | | 2026-03-14 | 21 | 21 |
128+
129+
</details>
130+
131+
## Quick Start
19132

20133
```bash
21134
# Build the CLI for Linux
@@ -28,7 +141,11 @@ make deploy
28141
make test-emulator
29142
```
30143

144+
## Security
145+
146+
> **Security disclaimer:** This is a hobby/research project. The mTLS + ACL system provides basic access control, but it has not been audited and should not be relied upon for security-critical deployments. The self-signed CA, handle-based object references, and raw JNI surface all have inherent attack surface. Use it on trusted networks for development, testing, and experimentation.
147+
31148
## Dependencies
32149

33-
This module depends on `github.com/AndroidGoLab/jni` for core JNI bindings.
150+
This module depends on [github.com/AndroidGoLab/jni](https://github.com/AndroidGoLab/jni) for core JNI bindings and code generation tools.
34151
When developing locally, use a `go.work` file pointing to both repos.

0 commit comments

Comments
 (0)