Skip to content

Commit 7cb1de5

Browse files
committed
fix(pkg/board): handle adb connection error
1 parent cd29de0 commit 7cb1de5

File tree

1 file changed

+37
-5
lines changed

1 file changed

+37
-5
lines changed

pkg/board/remote/adb/adb.go

Lines changed: 37 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,13 @@ import (
3636
"github.com/arduino/arduino-app-cli/pkg/x/ports"
3737
)
3838

39-
const username = "arduino"
39+
var (
40+
// NotFoundErr is returned when the ADB device is not found.
41+
NotFoundErr = fmt.Errorf("ADB device not found")
42+
// DeviceOfflineErr is returned when the ADB device is not reachable.
43+
// This usually requires a restart of the adbd server daemon on the device.
44+
DeviceOfflineErr = fmt.Errorf("ADB device is offline")
45+
)
4046

4147
type ADBConnection struct {
4248
adbPath string
@@ -46,15 +52,21 @@ type ADBConnection struct {
4652
// Ensures ADBConnection implements the RemoteConn interface at compile time.
4753
var _ remote.RemoteConn = (*ADBConnection)(nil)
4854

55+
const username = "arduino"
56+
4957
func FromSerial(serial string, adbPath string) (*ADBConnection, error) {
5058
if adbPath == "" {
5159
adbPath = FindAdbPath()
5260
}
5361

54-
return &ADBConnection{
55-
host: serial,
56-
adbPath: adbPath,
57-
}, nil
62+
conn := ADBConnection{host: serial, adbPath: adbPath}
63+
if connected, err := conn.IsConnected(); err != nil {
64+
return nil, err
65+
} else if !connected {
66+
return nil, fmt.Errorf("device %s is not connected", serial)
67+
}
68+
69+
return &conn, nil
5870
}
5971

6072
func FromHost(host string, adbPath string) (*ADBConnection, error) {
@@ -71,6 +83,26 @@ func FromHost(host string, adbPath string) (*ADBConnection, error) {
7183
return FromSerial(host, adbPath)
7284
}
7385

86+
// IsConnected checks if the ADB device is connected and online.
87+
func (a *ADBConnection) IsConnected() (bool, error) {
88+
cmd, err := paths.NewProcess(nil, a.adbPath, "-s", a.host, "get-state")
89+
if err != nil {
90+
return false, fmt.Errorf("failed to create ADB command: %w", err)
91+
}
92+
93+
output, err := cmd.RunAndCaptureCombinedOutput(context.TODO())
94+
if err != nil {
95+
if bytes.Contains(output, []byte("device offline")) {
96+
return false, DeviceOfflineErr
97+
} else if bytes.Contains(output, []byte("not found")) {
98+
return false, NotFoundErr
99+
}
100+
return false, fmt.Errorf("failed to get ADB device state: %w: %s", err, output)
101+
}
102+
103+
return string(bytes.TrimSpace(output)) == "device", nil
104+
}
105+
74106
func (a *ADBConnection) Forward(ctx context.Context, localPort int, remotePort int) error {
75107
if !ports.IsAvailable(localPort) {
76108
return remote.ErrPortAvailable

0 commit comments

Comments
 (0)