Skip to content

Commit 84ceee9

Browse files
xaionaro@dx.centerxaionaro@dx.center
authored andcommitted
feat: add 4 examples addressing context7 documentation gaps
Add complete, compilable examples for the four areas context7 flagged as lacking Go implementation guidance: - flashlight_torch: toggle torch via ICameraService.SetTorchMode - list_packages: list all installed packages via GetAllPackages - error_handling: service availability checks, typed AIDL errors, graceful degradation - server_service: implement TransactionReceiver, register with AddService, self-test Update spec2readme with matching usage examples and descriptions so the README (and context7 index) includes inline code for each pattern.
1 parent 37b88de commit 84ceee9

6 files changed

Lines changed: 944 additions & 1 deletion

File tree

README.md

Lines changed: 199 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -287,6 +287,118 @@ import (
287287
fmt.Printf("Is monkey: %v\n", monkey)
288288
```
289289

290+
### Toggle Flashlight
291+
292+
```go
293+
import (
294+
"github.com/AndroidGoLab/binder/android/hardware"
295+
"github.com/AndroidGoLab/binder/servicemanager"
296+
)
297+
298+
svc, err := sm.GetService(ctx, servicemanager.ServiceName("media.camera"))
299+
if err != nil {
300+
log.Fatal(err)
301+
}
302+
camera := hardware.NewCameraServiceProxy(svc)
303+
304+
// Turn torch on for camera "0"
305+
if err := camera.SetTorchMode(ctx, "0", true, nil); err != nil {
306+
log.Fatal(err)
307+
}
308+
fmt.Println("Torch ON")
309+
310+
// Turn torch off
311+
_ = camera.SetTorchMode(ctx, "0", false, nil)
312+
```
313+
314+
### List All Installed Packages
315+
316+
```go
317+
import (
318+
"github.com/AndroidGoLab/binder/android/content/pm"
319+
"github.com/AndroidGoLab/binder/servicemanager"
320+
)
321+
322+
svc, err := sm.GetService(ctx, servicemanager.ServiceName("package"))
323+
if err != nil {
324+
log.Fatal(err)
325+
}
326+
pkgMgr := pm.NewPackageManagerProxy(svc)
327+
328+
packages, err := pkgMgr.GetAllPackages(ctx)
329+
if err != nil {
330+
log.Fatal(err)
331+
}
332+
333+
fmt.Printf("Found %d packages:\n", len(packages))
334+
for _, pkg := range packages {
335+
fmt.Println(" ", pkg)
336+
}
337+
```
338+
339+
### Handle Errors Gracefully
340+
341+
```go
342+
import (
343+
"errors"
344+
aidlerrors "github.com/AndroidGoLab/binder/errors"
345+
"github.com/AndroidGoLab/binder/servicemanager"
346+
)
347+
348+
// Non-blocking service check (returns nil if not found)
349+
svc, err := sm.CheckService(ctx, servicemanager.ServiceName("media.camera"))
350+
if err != nil {
351+
log.Fatal(err)
352+
}
353+
if svc == nil {
354+
fmt.Println("Camera service not available")
355+
return
356+
}
357+
358+
// Typed error inspection
359+
_, err = someProxy.SomeMethod(ctx)
360+
var status *aidlerrors.StatusError
361+
if errors.As(err, &status) {
362+
switch status.Exception {
363+
case aidlerrors.ExceptionSecurity:
364+
fmt.Printf("Permission denied: %s\n", status.Message)
365+
case aidlerrors.ExceptionServiceSpecific:
366+
fmt.Printf("Service error %d: %s\n", status.ServiceSpecificCode, status.Message)
367+
default:
368+
fmt.Printf("AIDL error: %v\n", status)
369+
}
370+
}
371+
```
372+
373+
### Register a Server-Side Service
374+
375+
```go
376+
import (
377+
"github.com/AndroidGoLab/binder/binder"
378+
"github.com/AndroidGoLab/binder/parcel"
379+
"github.com/AndroidGoLab/binder/servicemanager"
380+
)
381+
382+
// Implement the TransactionReceiver interface
383+
type myService struct{}
384+
385+
func (s *myService) Descriptor() string { return "com.example.IPingService" }
386+
387+
func (s *myService) OnTransaction(
388+
ctx context.Context,
389+
code binder.TransactionCode,
390+
data *parcel.Parcel,
391+
) (*parcel.Parcel, error) {
392+
reply := parcel.New()
393+
binder.WriteStatus(reply, nil)
394+
reply.WriteString16("pong")
395+
return reply, nil
396+
}
397+
398+
// Register with ServiceManager
399+
err := sm.AddService(ctx, servicemanager.ServiceName("my.service"), &myService{}, false, 0)
400+
```
401+
290402
More examples: [`examples/`](examples/)
291403

292404
<!-- END GENERATED USAGE_EXAMPLES -->
@@ -303,13 +415,17 @@ More examples: [`examples/`](examples/)
303415
| [`camera_fwk`](examples/camera_fwk/) | |
304416
| [`device_info`](examples/device_info/) | Device properties, build info |
305417
| [`display_info`](examples/display_info/) | Display IDs, brightness, night mode |
418+
| [`error_handling`](examples/error_handling/) | Graceful error handling: service checks, typed errors, permissions |
419+
| [`flashlight_torch`](examples/flashlight_torch/) | Toggle flashlight/torch via ICameraService |
306420
| [`getservice_vs_checkservice`](examples/getservice_vs_checkservice/) | Binary getservice_vs_checkservice compares GetService vs CheckService |
307421
| [`gps_location`](examples/gps_location/) | Live GPS fix via ILocationListener callback |
308422
| [`keymint_delete_test`](examples/keymint_delete_test/) | Binary keymint_delete_test calls DeleteAllKeys on the KeyMint HAL |
423+
| [`list_packages`](examples/list_packages/) | List all installed packages via GetAllPackages |
309424
| [`list_services`](examples/list_services/) | Enumerate all binder services, ping each |
310425
| [`package_query`](examples/package_query/) | Package list, installation info |
311426
| [`power_status`](examples/power_status/) | Power supply state, charging info |
312427
| [`security_test_apk`](examples/security_test_apk/) | Binary security_test_apk probes whether an app-sandboxed process can |
428+
| [`server_service`](examples/server_service/) | Register a Go service and call it back via binder |
313429
| [`softap_manage`](examples/softap_manage/) | WiFi hotspot enable/disable, config |
314430
| [`softap_tether_offload`](examples/softap_tether_offload/) | Tethering offload config, stats |
315431
| [`softap_wifi_hal`](examples/softap_wifi_hal/) | WiFi chip info, AP interface state |
@@ -1833,6 +1949,88 @@ go run ./cmd/binder-mcp/ --mode remote
18331949

18341950
<!-- END GENERATED BINDER_MCP -->
18351951

1952+
## Using binder-mcp with AI Agents
1953+
1954+
<!-- BEGIN GENERATED AGENT_CONFIGS -->
1955+
1956+
### Installation
1957+
1958+
```bash
1959+
# Via go install
1960+
go install github.com/AndroidGoLab/binder/cmd/binder-mcp@latest
1961+
1962+
# Via GitHub releases (pre-built binaries)
1963+
# Download from https://github.com/AndroidGoLab/binder/releases
1964+
1965+
# Via Docker (host mode)
1966+
docker run ghcr.io/androidgolab/binder-mcp
1967+
```
1968+
1969+
### Claude Code
1970+
1971+
```bash
1972+
claude mcp add --transport stdio binder-mcp -- binder-mcp --mode remote
1973+
```
1974+
1975+
### Cursor
1976+
1977+
Add to `.cursor/mcp.json`:
1978+
1979+
```json
1980+
{
1981+
"mcpServers": {
1982+
"binder-mcp": {
1983+
"command": "binder-mcp",
1984+
"args": ["--mode", "remote"]
1985+
}
1986+
}
1987+
}
1988+
```
1989+
1990+
### Windsurf
1991+
1992+
Add to `~/.codeium/windsurf/mcp_config.json`:
1993+
1994+
```json
1995+
{
1996+
"mcpServers": {
1997+
"binder-mcp": {
1998+
"command": "binder-mcp",
1999+
"args": ["--mode", "remote"]
2000+
}
2001+
}
2002+
}
2003+
```
2004+
2005+
### Cline
2006+
2007+
Add to Cline MCP settings:
2008+
2009+
```json
2010+
{
2011+
"mcpServers": {
2012+
"binder-mcp": {
2013+
"command": "binder-mcp",
2014+
"args": ["--mode", "remote"],
2015+
"alwaysAllow": ["list_services", "get_device_info", "take_screenshot"]
2016+
}
2017+
}
2018+
}
2019+
```
2020+
2021+
### On-device mode (via adb)
2022+
2023+
```bash
2024+
# Build for Android
2025+
GOOS=linux GOARCH=arm64 CGO_ENABLED=0 go build -o binder-mcp ./cmd/binder-mcp/
2026+
adb push binder-mcp /data/local/tmp/
2027+
2028+
# Configure agent to use adb transport
2029+
claude mcp add --transport stdio binder-mcp -- adb shell /data/local/tmp/binder-mcp
2030+
```
2031+
2032+
<!-- END GENERATED AGENT_CONFIGS -->
2033+
18362034
## Interoperability
18372035

18382036
<!-- BEGIN GENERATED INTEROPERABILITY -->
@@ -1924,6 +2122,6 @@ See the example app at [`examples/gomobile/`](examples/gomobile/).
19242122
│ ├── hardware/ HAL interfaces
19252123
│ └── ... 399 packages total
19262124
├── com/ AOSP com.android.* service proxies
1927-
├── examples/ 19 runnable examples
2125+
├── examples/ 23 runnable examples
19282126
└── .github/workflows/ CI configuration
19292127
```

0 commit comments

Comments
 (0)