You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Make transaction code caching configurable and disabled by default
Add OptionCachePath to versionaware.NewTransport that enables caching
of the fully resolved VersionTable (not just DEX extraction) to a
user-specified path. Cache is fingerprinted and auto-invalidated on
firmware changes.
Previously caching was always on and hardcoded to
/data/local/tmp/.binder_cache/codes.json, only covering DEX results.
Now it covers all resolution strategies and is opt-in.
Copy file name to clipboardExpand all lines: README.md
+10Lines changed: 10 additions & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -1750,6 +1750,16 @@ Each binder method has a numeric transaction code that can differ between Androi
1750
1750
1751
1751
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.
1752
1752
1753
+
The resolved table can be cached to disk for fast subsequent startups by passing `OptionCachePath`:
Copy file name to clipboardExpand all lines: binder/versionaware/transport.go
+72-39Lines changed: 72 additions & 39 deletions
Original file line number
Diff line number
Diff line change
@@ -6,6 +6,7 @@ import (
6
6
"encoding/json"
7
7
"fmt"
8
8
"os"
9
+
"path/filepath"
9
10
"sort"
10
11
"strings"
11
12
@@ -52,25 +53,65 @@ func NewTransport(
52
53
ctx context.Context,
53
54
inner binder.Transport,
54
55
targetAPIint,
56
+
opts...Option,
55
57
) (*Transport, error) {
58
+
cfg:=Options(opts).config()
59
+
56
60
iftargetAPI<=0 {
57
61
targetAPI=detectAPILevel()
58
62
}
59
63
iftargetAPI<=0 {
60
64
returnnil, fmt.Errorf("versionaware: unable to detect Android API level; pass --target-api explicitly or ensure /etc/build_flags.json is readable; supported API levels: %v", supportedAPILevels())
// Fallback: use compiled version tables with revision detection.
@@ -80,7 +121,7 @@ func NewTransport(
80
121
81
122
revisions:=Revisions[targetAPI]
82
123
iflen(revisions) ==0 {
83
-
returnnil, fmt.Errorf("versionaware: API level %d is not supported and framework JARs not readable; supported API levels: %v", targetAPI, supportedAPILevels())
124
+
returnnil, "", fmt.Errorf("versionaware: API level %d is not supported and framework JARs not readable; supported API levels: %v", targetAPI, supportedAPILevels())
84
125
}
85
126
86
127
// Narrow revision candidates by checking which methods exist in
@@ -97,23 +138,25 @@ func NewTransport(
97
138
varerrerror
98
139
version, err=probeRevision(ctx, inner, targetAPI)
99
140
iferr!=nil {
100
-
returnnil, fmt.Errorf("versionaware: probing revision for API %d: %w", targetAPI, err)
141
+
returnnil, "", fmt.Errorf("versionaware: probing revision for API %d: %w", targetAPI, err)
101
142
}
102
143
}
103
144
104
145
table, ok:=Tables[version]
105
146
if!ok {
106
-
returnnil, fmt.Errorf("versionaware: no transaction code table for version %q", version)
147
+
returnnil, "", fmt.Errorf("versionaware: no transaction code table for version %q", version)
107
148
}
108
149
109
150
logger.Debugf(ctx, "versionaware: using compiled version table %s (%d interfaces)", version, len(table))
151
+
returntable, version, nil
152
+
}
110
153
111
-
return&Transport{
112
-
inner: inner,
113
-
apiLevel: targetAPI,
114
-
table: table,
115
-
version: version,
116
-
}, nil
154
+
// resolvedTableFingerprint returns a fingerprint that changes when
155
+
// the device's firmware changes, invalidating cached transaction codes.
156
+
// Combines API level with framework JAR fingerprint (if available).
0 commit comments