Skip to content

Commit bf76bdc

Browse files
committed
release devicekit tunnels upon shutdown
1 parent 646b264 commit bf76bdc

File tree

1 file changed

+54
-26
lines changed

1 file changed

+54
-26
lines changed

devices/ios.go

Lines changed: 54 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -42,13 +42,15 @@ type IOSDevice struct {
4242
DeviceName string `json:"DeviceName"`
4343
OSVersion string `json:"Version"`
4444

45-
mu sync.Mutex // protects fields below
46-
tunnelManager *ios.TunnelManager
47-
wdaClient *wda.WdaClient
48-
mjpegClient *mjpeg.WdaMjpegClient
49-
wdaCancel context.CancelFunc
50-
portForwarder *ios.PortForwarder
51-
portForwarderMjpeg *ios.PortForwarder
45+
mu sync.Mutex // protects fields below
46+
tunnelManager *ios.TunnelManager
47+
wdaClient *wda.WdaClient
48+
mjpegClient *mjpeg.WdaMjpegClient
49+
wdaCancel context.CancelFunc
50+
portForwarderWda *ios.PortForwarder
51+
portForwarderMjpeg *ios.PortForwarder
52+
portForwarderDeviceKit *ios.PortForwarder // devicekit http forwarder
53+
portForwarderAvc *ios.PortForwarder // devicekit h264 stream forwarder
5254
}
5355

5456
func (d IOSDevice) ID() string {
@@ -256,11 +258,13 @@ func (d *IOSDevice) hasResourcesToCleanup() bool {
256258
defer d.mu.Unlock()
257259

258260
hasWda := d.wdaCancel != nil
259-
hasWdaPort := d.portForwarder != nil && d.portForwarder.IsRunning()
261+
hasWdaPort := d.portForwarderWda != nil && d.portForwarderWda.IsRunning()
260262
hasMjpegPort := d.portForwarderMjpeg != nil && d.portForwarderMjpeg.IsRunning()
263+
hasHTTPPort := d.portForwarderDeviceKit != nil && d.portForwarderDeviceKit.IsRunning()
264+
hasStreamPort := d.portForwarderAvc != nil && d.portForwarderAvc.IsRunning()
261265
hasTunnel := d.tunnelManager != nil && d.tunnelManager.IsTunnelRunning()
262266

263-
return hasWda || hasWdaPort || hasMjpegPort || hasTunnel
267+
return hasWda || hasWdaPort || hasMjpegPort || hasHTTPPort || hasStreamPort || hasTunnel
264268
}
265269

266270
// cleanupWDA cancels the WebDriverAgent context
@@ -278,11 +282,13 @@ func (d *IOSDevice) cleanupWDA() error {
278282
return nil
279283
}
280284

281-
// cleanupPortForwarders stops WDA and MJPEG port forwarders
285+
// cleanupPortForwarders stops WDA, MJPEG, and DeviceKit port forwarders
282286
func (d *IOSDevice) cleanupPortForwarders() error {
283287
d.mu.Lock()
284-
wdaForwarder := d.portForwarder
288+
wdaForwarder := d.portForwarderWda
285289
mjpegForwarder := d.portForwarderMjpeg
290+
httpForwarder := d.portForwarderDeviceKit
291+
streamForwarder := d.portForwarderAvc
286292
d.mu.Unlock()
287293

288294
var errs []error
@@ -301,6 +307,20 @@ func (d *IOSDevice) cleanupPortForwarders() error {
301307
}
302308
}
303309

310+
if httpForwarder != nil && httpForwarder.IsRunning() {
311+
utils.Verbose("Stopping DeviceKit HTTP port forwarder for device %s", d.Udid)
312+
if err := httpForwarder.Stop(); err != nil {
313+
errs = append(errs, fmt.Errorf("failed to stop DeviceKit HTTP port forwarder: %w", err))
314+
}
315+
}
316+
317+
if streamForwarder != nil && streamForwarder.IsRunning() {
318+
utils.Verbose("Stopping DeviceKit AVC stream port forwarder for device %s", d.Udid)
319+
if err := streamForwarder.Stop(); err != nil {
320+
errs = append(errs, fmt.Errorf("failed to stop DeviceKit AVC stream port forwarder: %w", err))
321+
}
322+
}
323+
304324
if len(errs) > 0 {
305325
return fmt.Errorf("port forwarder cleanup errors: %v", errs)
306326
}
@@ -442,7 +462,7 @@ func (d *IOSDevice) StartAgent(config StartAgentConfig) error {
442462

443463
// set up WDA port forwarding if not already running
444464
d.mu.Lock()
445-
needsPortForwarder := d.portForwarder == nil || !d.portForwarder.IsRunning()
465+
needsPortForwarder := d.portForwarderWda == nil || !d.portForwarderWda.IsRunning()
446466
d.mu.Unlock()
447467

448468
if needsPortForwarder {
@@ -458,21 +478,23 @@ func (d *IOSDevice) StartAgent(config StartAgentConfig) error {
458478
}
459479

460480
d.mu.Lock()
461-
d.portForwarder = forwarder
481+
d.portForwarderWda = forwarder
462482
d.wdaClient = wda.NewWdaClient(fmt.Sprintf("http://localhost:%d", port))
463483
d.mu.Unlock()
464484

465485
utils.Verbose("WDA port forwarder set up on port %d", port)
466486
} else {
467487
d.mu.Lock()
468-
srcPort, _ := d.portForwarder.GetPorts()
488+
srcPort, _ := d.portForwarderWda.GetPorts()
469489
d.mu.Unlock()
470490
utils.Verbose("WDA port forwarder already running on port %d", srcPort)
471491

472492
// ensure wdaClient is set if not already
493+
d.mu.Lock()
473494
if d.wdaClient == nil {
474495
d.wdaClient = wda.NewWdaClient(fmt.Sprintf("http://localhost:%d", srcPort))
475496
}
497+
d.mu.Unlock()
476498
}
477499

478500
// check if wda is already running, now that we have a port forwarder set up
@@ -1204,24 +1226,30 @@ func (d *IOSDevice) StartDeviceKit(hook *ShutdownHook) (*DeviceKitInfo, error) {
12041226
return nil, fmt.Errorf("failed to find available port for HTTP: %w", err)
12051227
}
12061228

1207-
httpForwarder := ios.NewPortForwarder(d.ID())
1208-
err = httpForwarder.Forward(localHTTPPort, deviceKitHTTPPort)
1229+
d.mu.Lock()
1230+
d.portForwarderDeviceKit = ios.NewPortForwarder(d.ID())
1231+
d.mu.Unlock()
1232+
1233+
err = d.portForwarderDeviceKit.Forward(localHTTPPort, deviceKitHTTPPort)
12091234
if err != nil {
12101235
return nil, fmt.Errorf("failed to forward HTTP port: %w", err)
12111236
}
12121237
utils.Verbose("Port forwarding started: localhost:%d -> device:%d (HTTP)", localHTTPPort, deviceKitHTTPPort)
12131238
// Find available local port for stream forwarding after HTTP is bound.
12141239
localStreamPort, err := findAvailablePortInRange(portRangeStart, portRangeEnd)
12151240
if err != nil {
1216-
_ = httpForwarder.Stop()
1241+
_ = d.portForwarderDeviceKit.Stop()
12171242
return nil, fmt.Errorf("failed to find available port for stream: %w", err)
12181243
}
12191244

1220-
streamForwarder := ios.NewPortForwarder(d.ID())
1221-
err = streamForwarder.Forward(localStreamPort, deviceKitStreamPort)
1245+
d.mu.Lock()
1246+
d.portForwarderAvc = ios.NewPortForwarder(d.ID())
1247+
d.mu.Unlock()
1248+
1249+
err = d.portForwarderAvc.Forward(localStreamPort, deviceKitStreamPort)
12221250
if err != nil {
12231251
// clean up HTTP forwarder on failure
1224-
_ = httpForwarder.Stop()
1252+
_ = d.portForwarderDeviceKit.Stop()
12251253
return nil, fmt.Errorf("failed to forward stream port: %w", err)
12261254
}
12271255
utils.Verbose("Port forwarding started: localhost:%d -> device:%d (H.264 stream)", localStreamPort, deviceKitStreamPort)
@@ -1231,8 +1259,8 @@ func (d *IOSDevice) StartDeviceKit(hook *ShutdownHook) (*DeviceKitInfo, error) {
12311259
err = d.LaunchApp(devicekitMainAppBundleId)
12321260
if err != nil {
12331261
// clean up port forwarders on failure
1234-
_ = httpForwarder.Stop()
1235-
_ = streamForwarder.Stop()
1262+
_ = d.portForwarderDeviceKit.Stop()
1263+
_ = d.portForwarderAvc.Stop()
12361264
return nil, fmt.Errorf("failed to launch DeviceKit app: %w", err)
12371265
}
12381266

@@ -1248,17 +1276,17 @@ func (d *IOSDevice) StartDeviceKit(hook *ShutdownHook) (*DeviceKitInfo, error) {
12481276
})
12491277
if err != nil {
12501278
// clean up port forwarders on failure
1251-
_ = httpForwarder.Stop()
1252-
_ = streamForwarder.Stop()
1279+
_ = d.portForwarderDeviceKit.Stop()
1280+
_ = d.portForwarderAvc.Stop()
12531281
return nil, fmt.Errorf("failed to start agent: %w", err)
12541282
}
12551283

12561284
// find and tap the "Start Broadcast" button
12571285
err = d.clickStartBroadcastButton()
12581286
if err != nil {
12591287
// clean up port forwarders on failure
1260-
_ = httpForwarder.Stop()
1261-
_ = streamForwarder.Stop()
1288+
_ = d.portForwarderDeviceKit.Stop()
1289+
_ = d.portForwarderAvc.Stop()
12621290
return nil, fmt.Errorf("failed to click Start Broadcast button: %w", err)
12631291
}
12641292

0 commit comments

Comments
 (0)