Skip to content

Commit 5a8d635

Browse files
docs: update README for transaction resolve and dynamic code resolution
1 parent 96f2bc7 commit 5a8d635

1 file changed

Lines changed: 20 additions & 15 deletions

File tree

README.md

Lines changed: 20 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1519,8 +1519,9 @@ Core subcommands:
15191519
| ------------------------------------------------ | ---------------------------------------------------------- |
15201520
| `bindercli service list` | List all registered binder services with alive/dead status |
15211521
| `bindercli service inspect <name>` | Show a service's handle, descriptor, and alive status |
1522-
| `bindercli service methods <name>` | List all methods available on a service |
1523-
| `bindercli service transact <name> <code> [hex]` | Send a raw binder transaction |
1522+
| `bindercli service methods <name>` | List all methods with their transaction codes |
1523+
| `bindercli service transact <name> <code-or-method> [hex]` | Send a raw binder transaction (code or method name) |
1524+
| `bindercli service resolve <name> <method-or-code>` | Resolve between method names and transaction codes |
15241525
| `bindercli aidl compile [-I path] <files>` | Compile `.aidl` files to Go |
15251526
| `bindercli aidl parse <file>` | Dump parsed AIDL AST as JSON |
15261527
| `bindercli aidl check <files>` | Validate AIDL files without generating |
@@ -1530,10 +1531,10 @@ Global flags: `--format json|text|auto`, `--binder-device`, `--map-size`.
15301531

15311532
### Examples
15321533

1533-
> **Note:** Generated proxy commands use transaction codes compiled from the AIDL snapshot in
1534-
> `tools/pkg/3rdparty/`. If the device runs a different Android version, some proxy methods may
1535-
> return parse errors due to transaction code mismatches. The `service` subcommands and
1536-
> ServiceManager-level lookups work across all versions.
1534+
> **Note:** Transaction codes are resolved dynamically from the device's framework JARs
1535+
> (`/system/framework/*.jar`) at runtime. Compiled version tables are used as a fallback
1536+
> when JARs are not readable. The `service` subcommands and ServiceManager-level lookups
1537+
> work across all versions.
15371538
15381539
<details>
15391540
<summary>List and inspect services</summary>
@@ -1545,10 +1546,14 @@ bindercli service list
15451546
# Inspect a specific service (show handle, descriptor, alive status)
15461547
bindercli service inspect SurfaceFlinger
15471548

1548-
# List methods available on a service (from generated registry)
1549+
# List methods available on a service with transaction codes
15491550
bindercli service methods activity
15501551

1551-
# Send a raw binder transaction (service name, transaction code, optional hex data)
1552+
# Resolve a method name to its transaction code (or vice versa)
1553+
bindercli service resolve activity is-user-a-monkey
1554+
1555+
# Send a raw binder transaction by method name or numeric code
1556+
bindercli service transact activity is-user-a-monkey
15521557
bindercli service transact SurfaceFlinger 64
15531558
```
15541559

@@ -1777,7 +1782,7 @@ bindercli com.android.internal.telephony.ITelephony get-network-country-iso-for-
17771782

17781783
### Verified Devices
17791784

1780-
Commands are tested against the following devices. The runtime uses version-aware transaction code resolution (`binder/versionaware`) with tables for API 34, 35, and 36. "SM" = ServiceManager-level lookup, "Proxy" = generated proxy method with version-aware code resolution.
1785+
Commands are tested against the following devices. The runtime uses version-aware transaction code resolution (`binder/versionaware`) that dynamically extracts codes from the device's framework JARs, with compiled tables as a fallback. "SM" = ServiceManager-level lookup, "Proxy" = generated proxy method with version-aware code resolution.
17811786

17821787
<details>
17831788
<summary>Verification matrix</summary>
@@ -2068,15 +2073,15 @@ This discovers all AIDL files across `frameworks-base`, `frameworks-native`, `ha
20682073

20692074
### Transaction Code Resolution
20702075

2071-
Each binder method has a numeric transaction code that can differ between Android versions. The generated proxies call `ResolveCode()` at runtime to get the correct code for the device, using a three-layer detection strategy:
2076+
Each binder method has a numeric transaction code that can differ between Android versions. The generated proxies call `ResolveCode()` at runtime to get the correct code for the device, using a multi-layer detection strategy:
20722077

2073-
1. **DEX bytecode extraction** (primary) — scans `/system/framework/*.jar`, parses DEX bytecode, and reads `TRANSACTION_*` constants from `$Stub` classes. This gives definitive codes for the exact firmware running on the device. This method is expected to work on all Android devices. If it fails on your platform, please [open an issue](https://github.com/AndroidGoLab/binder/issues).
2078+
1. **DEX bytecode extraction** (primary) — scans `/system/framework/*.jar` and APEX module JARs, parses DEX bytecode, and reads `TRANSACTION_*` constants from `$Stub` classes. Individual interfaces are extracted on demand (lazy), and results are cached to avoid re-scanning. This gives definitive codes for the exact firmware running on the device. This method is expected to work on all Android devices. If it fails on your platform, please [open an issue](https://github.com/AndroidGoLab/binder/issues).
20742079

2075-
2. **Compiled version tables + ELF filtering** (fallback) — pre-compiled tables from multiple AOSP revision tags, narrowed by API level (from ELF `.note.android.ident`) and exported symbols in `libbinder.so`.
2080+
2. **Compiled version tables + ELF filtering** (fallback) — pre-compiled tables from AOSP revision tags, narrowed by API level and exported symbols in `libbinder.so`. Used when framework JARs are not readable (e.g. non-Android host, restricted SELinux context).
20762081

2077-
3. **Live transaction probing** (last resort) — sends a test transaction (`isUserAMonkey()` on ActivityManager) with each candidate code and picks the one that returns a valid response.
2082+
3. **Live transaction probing** (last resort) — sends a test transaction (`isUserAMonkey()` on ActivityManager) with each candidate code and picks the one that returns a valid response. Used only to distinguish between AOSP revisions when ELF inspection is ambiguous.
20782083

2079-
Methods 2 and 3 exist only for extra reliability in edge cases (e.g. no read access to `/system/framework/`). The `genversions` tool builds the version tables by checking out AOSP revision tags and recording method→code mappings.
2084+
Methods 2 and 3 exist only for environments where framework JARs are unavailable. On a standard Android device, all transaction codes are resolved dynamically from the device's own JARs.
20802085

20812086
## Testing and Verification
20822087

@@ -2330,7 +2335,7 @@ See the example app at [`examples/gomobile/`](examples/gomobile/).
23302335
│ │ ├── gen_e2e_smoke/ Smoke test generator
23312336
│ │ ├── genbindercli/ bindercli command dispatcher generator
23322337
│ │ ├── genreadme/ README package table generator
2333-
│ │ └── genversions/ Version-aware transaction code table generator
2338+
│ │ └── genversions/ Compiled transaction code table generator (fallback tables)
23342339
│ └── pkg/
23352340
│ └── aidlc/ AIDL processing pipeline
23362341
│ ├── parser/ Lexer + recursive-descent AIDL parser

0 commit comments

Comments
 (0)