Skip to content

Commit 600355b

Browse files
committed
Support reading adb from the toolchain
This makes it so you aren't required to include the `platform-tools` in your `PATH` just for `adb`
1 parent afb95a9 commit 600355b

5 files changed

Lines changed: 76 additions & 40 deletions

File tree

mobile_install/launcher_direct.bzl

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
# limitations under the License.
1414
"""Creates the app launcher scripts."""
1515

16+
load("//rules:utils.bzl", "get_android_toolchain")
1617
load("//rules:visibility.bzl", "PROJECT_VISIBILITY")
1718
load("//rules/flags:flags.bzl", "flags")
1819
load(":deploy_info.bzl", "make_deploy_info_pb")
@@ -75,6 +76,7 @@ def _make_app_runner(
7576
path_type = "path" if ctx.attr._mi_is_cmd else "short_path"
7677

7778
deploy = utils.first(ctx.attr._deploy[DefaultInfo].files.to_list())
79+
adb = get_android_toolchain(ctx).adb.files_to_run.executable
7880

7981
args = {
8082
"is_cmd": str(ctx.attr._mi_is_cmd).lower(),
@@ -85,6 +87,9 @@ def _make_app_runner(
8587

8688
args["java_home"] = utils.host_jvm_path(ctx)
8789

90+
if adb:
91+
args["toolchain_adb"] = getattr(adb, path_type)
92+
8893
args["studio_deployer"] = getattr(ctx.file._studio_deployer, path_type)
8994
args["use_adb_root"] = str(use_adb_root).lower()
9095

@@ -108,6 +113,8 @@ def _make_app_runner(
108113
)
109114

110115
runner = [deploy]
116+
if adb:
117+
runner.append(adb)
111118
return runner
112119

113120
def make_direct_launcher(

src/tools/mi/broker/adb.go

Lines changed: 21 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -215,16 +215,24 @@ func (a *Controller) Pull(ctx context.Context, from, to string) error {
215215

216216
// setupEnv determines which adb path to use and sets up the implicit environment settings required
217217
// and returns a prepared environment and the correct adb path.
218-
func setupEnv(ctx context.Context, env []string, adbPath string) (*ADB, error) {
218+
func setupEnv(ctx context.Context, env []string, adbPath, toolchainADBPath string) (*ADB, error) {
219219
adbSource := "default"
220-
221-
// Find ANDROID_ADB entry from environment vars, if found set it as the path unless overridden.
222220
adbEnv := &ADB{}
223-
for _, entry := range env {
224-
if strings.HasPrefix(entry, androidADBVar) {
225-
adbEnv.Path = strings.TrimPrefix(entry, androidADBVar)
226-
adbSource = "environment variable"
227-
break
221+
222+
// The flag should always win
223+
if adbPath != "" {
224+
adbEnv.Path = adbPath
225+
adbSource = "flag"
226+
}
227+
228+
if adbEnv.Path == "" {
229+
// Find ANDROID_ADB entry from environment vars, if found set it as the path unless overridden.
230+
for _, entry := range env {
231+
if strings.HasPrefix(entry, androidADBVar) {
232+
adbEnv.Path = strings.TrimPrefix(entry, androidADBVar)
233+
adbSource = "environment variable"
234+
break
235+
}
228236
}
229237
}
230238

@@ -237,10 +245,9 @@ func setupEnv(ctx context.Context, env []string, adbPath string) (*ADB, error) {
237245
}
238246
}
239247

240-
// The flag should always win
241-
if adbPath != "" {
242-
adbEnv.Path = adbPath
243-
adbSource = "flag"
248+
if adbEnv.Path == "" && toolchainADBPath != "" {
249+
adbEnv.Path = toolchainADBPath
250+
adbSource = "toolchain"
244251
}
245252

246253
// Fallback to default pre-installed adb, if it exists, or fail if not found.
@@ -258,8 +265,8 @@ func setupEnv(ctx context.Context, env []string, adbPath string) (*ADB, error) {
258265

259266
// New creates a new adb Controller.
260267
// If more than once device is available, deviceFlag must be specified.
261-
func New(ctx context.Context, env []string, deviceSerial, adbPort, adbPath string, useADBRoot bool) (*Controller, error) {
262-
a, err := setupEnv(ctx, env, adbPath)
268+
func New(ctx context.Context, env []string, deviceSerial, adbPort, adbPath, toolchainADBPath string, useADBRoot bool) (*Controller, error) {
269+
a, err := setupEnv(ctx, env, adbPath, toolchainADBPath)
263270
if err != nil {
264271
return nil, err
265272
}

src/tools/mi/broker/adb_test.go

Lines changed: 23 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -22,13 +22,14 @@ import (
2222
)
2323

2424
func TestSetupEnv(t *testing.T) {
25+
t.Setenv("PATH", t.TempDir())
2526
tcs := []struct {
26-
name string
27-
env []string
28-
adbPath string
29-
adbTurboPath string
30-
wantPath string
31-
wantEnv []string
27+
name string
28+
env []string
29+
adbPath string
30+
toolchainADBPath string
31+
wantPath string
32+
wantEnv []string
3233
}{
3334
/*
3435
Following test cases fail due to the os.stat check need refactor
@@ -54,11 +55,26 @@ func TestSetupEnv(t *testing.T) {
5455
env: []string{androidADBVar + "/my/adb"},
5556
wantPath: "/my/adb",
5657
wantEnv: []string{}, // Expect the env entry to be removed, which produces an empty list.
58+
}, {
59+
name: "SpecifyADBPathOverridesEnvAndToolchain",
60+
env: []string{androidADBVar + "/env/adb"},
61+
adbPath: "/flag/adb",
62+
toolchainADBPath: "/toolchain/adb",
63+
wantPath: "/flag/adb",
64+
}, {
65+
name: "SpecifyADBPathViaEnvOverridesToolchain",
66+
env: []string{androidADBVar + "/env/adb"},
67+
toolchainADBPath: "/toolchain/adb",
68+
wantPath: "/env/adb",
69+
}, {
70+
name: "SpecifyADBPathViaToolchain",
71+
toolchainADBPath: "/toolchain/adb",
72+
wantPath: "/toolchain/adb",
5773
},
5874
}
5975
for _, tc := range tcs {
6076
t.Run(tc.name, func(t *testing.T) {
61-
ae, err := setupEnv(context.Background(), tc.env, tc.adbPath)
77+
ae, err := setupEnv(context.Background(), tc.env, tc.adbPath, tc.toolchainADBPath)
6278
if err != nil {
6379
t.Fatalf("error occurred, got: %v", err)
6480
}

src/tools/mi/broker/device.go

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ type Controller interface {
4848
// Device holds information of a particular android device.
4949
type Device struct {
5050
Ctl Controller
51+
ADBPath string
5152
abis []string
5253
Props map[string]string
5354
userOnce sync.Once
@@ -59,11 +60,15 @@ type Device struct {
5960
}
6061

6162
// New creates and returns a new Device.
62-
func New(ctx context.Context, deviceSerial, port, tmpDir string, adbPath string, useADBRoot bool) (*Device, error) {
63-
ctl, err := initDeviceController(ctx, adbPath, deviceSerial, port, useADBRoot)
63+
func New(ctx context.Context, deviceSerial, port, tmpDir string, adbPath, toolchainADBPath string, useADBRoot bool) (*Device, error) {
64+
ctl, err := initDeviceController(ctx, adbPath, toolchainADBPath, deviceSerial, port, useADBRoot)
6465
if err != nil {
6566
return nil, fmt.Errorf("failed to initialize device controller %v", err)
6667
}
68+
selectedADBPath := ""
69+
if adbCtl, ok := ctl.(*adb.Controller); ok {
70+
selectedADBPath = adbCtl.Path
71+
}
6772
props, err := getProp(ctx, ctl)
6873
if err != nil {
6974
return nil, fmt.Errorf("failed to get device properties. Confirm that your device is visible to `adb devices`, "+
@@ -85,7 +90,7 @@ func New(ctx context.Context, deviceSerial, port, tmpDir string, adbPath string,
8590
if abis == "" {
8691
return nil, errors.New("unable to get supported ABIs from device")
8792
}
88-
d := &Device{Ctl: ctl, tmpDir: tmpDir, APILevel: apiLevel, ABI: abi, ABIs: strings.Split(abis, ",")}
93+
d := &Device{Ctl: ctl, ADBPath: selectedADBPath, tmpDir: tmpDir, APILevel: apiLevel, ABI: abi, ABIs: strings.Split(abis, ",")}
8994
return d, nil
9095
}
9196

@@ -181,10 +186,10 @@ func parseProperties(in string) (map[string]string, error) {
181186
return props, nil
182187
}
183188

184-
func initDeviceController(ctx context.Context, adbPath string, deviceSerial, port string, useADBRoot bool) (Controller, error) {
189+
func initDeviceController(ctx context.Context, adbPath, toolchainADBPath string, deviceSerial, port string, useADBRoot bool) (Controller, error) {
185190
var ctl Controller
186191
var err error
187-
ctl, err = adb.New(ctx, os.Environ(), deviceSerial, port, adbPath, useADBRoot)
192+
ctl, err = adb.New(ctx, os.Environ(), deviceSerial, port, adbPath, toolchainADBPath, useADBRoot)
188193
if err != nil {
189194
return nil, fmt.Errorf("Unable to connect to device: %v", err)
190195
}

src/tools/mi/deployment/deploy_binary.go

Lines changed: 15 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -32,18 +32,19 @@ import (
3232
)
3333

3434
var (
35-
adbArgs = flags.NewStringList("adb_arg", "Options for the adb binary.")
36-
adbPath = flag.String("adb", "", "Path to the adb binary to use with mobile-install.")
37-
device = flag.String("device", "", "The adb device serial number.")
38-
javaHome = flag.String("java_home", "", "Path to JDK.")
39-
launchActivity = flag.String("launch_activity", "", "Activity to launch via am start -n package/.activity_to_launch.")
40-
appPackagePath = flag.String("manifest_package_name_path", "", "Path to file containing the manifest package name.")
41-
splits = flags.NewStringList("splits", "The list of split apk paths.")
42-
start = flag.String("start", "", "start_type from mobile-install.")
43-
startType = flag.String("start_type", "", "start_type (deprecated, use --start).")
44-
toolTag = flag.String("tool_tag", "", "tool_tag from blaze.")
45-
useADBRoot = flag.Bool("use_adb_root", true, "whether (true) or not (false) to use root permissions.")
46-
userID = flag.Int("user", 0, "User id to install the app for.")
35+
adbArgs = flags.NewStringList("adb_arg", "Options for the adb binary.")
36+
adbPath = flag.String("adb", "", "Path to the adb binary to use with mobile-install.")
37+
toolchainADBPath = flag.String("toolchain_adb", "", "Path to the adb binary from the Android toolchain.")
38+
device = flag.String("device", "", "The adb device serial number.")
39+
javaHome = flag.String("java_home", "", "Path to JDK.")
40+
launchActivity = flag.String("launch_activity", "", "Activity to launch via am start -n package/.activity_to_launch.")
41+
appPackagePath = flag.String("manifest_package_name_path", "", "Path to file containing the manifest package name.")
42+
splits = flags.NewStringList("splits", "The list of split apk paths.")
43+
start = flag.String("start", "", "start_type from mobile-install.")
44+
startType = flag.String("start_type", "", "start_type (deprecated, use --start).")
45+
toolTag = flag.String("tool_tag", "", "tool_tag from blaze.")
46+
useADBRoot = flag.Bool("use_adb_root", true, "whether (true) or not (false) to use root permissions.")
47+
userID = flag.Int("user", 0, "User id to install the app for.")
4748

4849
// Studio deployer args
4950
studioDeployerPath = flag.String("studio_deployer", "", "Path to the Android Studio deployer.")
@@ -165,7 +166,7 @@ func main() {
165166
}
166167

167168
pprint.Info("Connecting to device %s", deviceSerial)
168-
d, err := devlib.New(ctx, deviceSerial, port, devTmp, *adbPath, *useADBRoot)
169+
d, err := devlib.New(ctx, deviceSerial, port, devTmp, *adbPath, *toolchainADBPath, *useADBRoot)
169170
if err != nil {
170171
glog.Exitln(err)
171172
}
@@ -178,7 +179,7 @@ func main() {
178179
startTime := time.Now()
179180

180181
pprint.Info("Installing application using the Android Studio deployer ...")
181-
if err := deployment.AndroidStudioSync(ctx, deviceSerial, port, appPackage, *splits, *studioDeployerPath, *adbPath, *javaHome, *optimisticInstall, *studioVerboseLog, *userID, *useADBRoot); err != nil {
182+
if err := deployment.AndroidStudioSync(ctx, deviceSerial, port, appPackage, *splits, *studioDeployerPath, d.ADBPath, *javaHome, *optimisticInstall, *studioVerboseLog, *userID, *useADBRoot); err != nil {
182183
flushAndExitf(ctx, "", "", "", "", "Got error installing using the Android Studio deployer: %v", err)
183184
}
184185

0 commit comments

Comments
 (0)