Skip to content

Commit 44a7a1c

Browse files
Merge pull request #1394 from NativeScript/wait-for-debugger-before-starting-client
wait for the debugger to settle before starting a client and output t…
2 parents ccf55f2 + 5fe74be commit 44a7a1c

File tree

4 files changed

+66
-7
lines changed

4 files changed

+66
-7
lines changed

lib/commands/debug.ts

Lines changed: 41 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,25 +2,61 @@
22
"use strict";
33

44
export class DebugPlatformCommand implements ICommand {
5-
constructor(private debugService: IDebugService) { }
5+
constructor(private debugService: IDebugService,
6+
private $devicesService: Mobile.IDevicesService,
7+
private $errors: IErrors,
8+
protected $options: IOptions) { }
69

710
execute(args: string[]): IFuture<void> {
811
return this.debugService.debug();
912
}
1013

1114
allowedParameters: ICommandParameter[] = [];
15+
16+
canExecute(args: string[]): IFuture<boolean> {
17+
return ((): boolean => {
18+
this.$devicesService.initialize({ platform: this.debugService.platform, deviceId: this.$options.device }).wait();
19+
if(this.$devicesService.deviceCount === 0) {
20+
this.$errors.failWithoutHelp("No devices detected. Connect a device and try again.");
21+
} else if (this.$devicesService.deviceCount > 1) {
22+
this.$errors.fail("Cannot debug on multiple devices. Select device with --device option.");
23+
}
24+
25+
return true;
26+
}).future<boolean>()();
27+
}
1228
}
1329

1430
export class DebugIOSCommand extends DebugPlatformCommand {
15-
constructor(private $iOSDebugService: IDebugService) {
16-
super($iOSDebugService);
31+
constructor($iOSDebugService: IDebugService,
32+
$devicesService: Mobile.IDevicesService,
33+
$errors: IErrors,
34+
$options: IOptions) {
35+
super($iOSDebugService, $devicesService, $errors, $options);
36+
}
37+
38+
canExecute(args: string[]): IFuture<boolean> {
39+
return ((): boolean => {
40+
if(this.$options.emulator) {
41+
return true;
42+
}
43+
44+
return super.canExecute(args).wait();
45+
}).future<boolean>()();
1746
}
1847
}
1948
$injector.registerCommand("debug|ios", DebugIOSCommand);
2049

2150
export class DebugAndroidCommand extends DebugPlatformCommand {
22-
constructor(private $androidDebugService: IDebugService) {
23-
super($androidDebugService);
51+
constructor($androidDebugService: IDebugService,
52+
$devicesService: Mobile.IDevicesService,
53+
$errors: IErrors,
54+
$options: IOptions) {
55+
super($androidDebugService, $devicesService, $errors, $options);
56+
}
57+
58+
canExecute(args: string[]): IFuture<boolean> {
59+
return super.canExecute(args);
2460
}
2561
}
2662
$injector.registerCommand("debug|android", DebugAndroidCommand);

lib/definitions/debug.d.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
interface IDebugService {
22
debug(): IFuture<void>;
33
debugStart(): IFuture<void>;
4+
platform: string;
45
}

lib/services/android-debug-service.ts

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
import * as path from "path";
44
import * as net from "net";
55
import Future = require("fibers/future");
6+
import { sleep } from "../common/helpers";
67

78
class AndroidDebugService implements IDebugService {
89
private static DEFAULT_NODE_INSPECTOR_URL = "http://127.0.0.1:8080/debug";
@@ -21,7 +22,7 @@ class AndroidDebugService implements IDebugService {
2122
private $opener: IOpener,
2223
private $config: IConfiguration) { }
2324

24-
private get platform() { return "android"; }
25+
public get platform() { return "android"; }
2526

2627
private get device(): Mobile.IAndroidDevice {
2728
return this._device;
@@ -182,11 +183,32 @@ class AndroidDebugService implements IDebugService {
182183
return (() => {
183184
let packageName = this.$projectData.projectId;
184185

186+
// Arguments passed to executeShellCommand must be in array ([]), but it turned out adb shell "arg with intervals" still works correctly.
187+
// As we need to redirect output of a command on the device, keep using only one argument.
188+
// We could rewrite this with two calls - touch and rm -f , but -f flag is not available on old Android, so rm call will fail when file does not exist.
185189
this.device.adb.executeShellCommand([`cat /dev/null > /data/local/tmp/${packageName}-debugbreak`]).wait();
186190

187191
this.device.applicationManager.stopApplication(packageName).wait();
188192
this.device.applicationManager.startApplication(packageName).wait();
189193

194+
let waitText: string = `0 /data/local/tmp/${packageName}-debugbreak`;
195+
let maxWait = 6;
196+
let debugerStarted: boolean = false;
197+
while (maxWait > 0 && !debugerStarted) {
198+
let forwardsResult = this.device.adb.executeShellCommand(["ls", "-s", `/data/local/tmp/${packageName}-debugbreak`]).wait();
199+
maxWait--;
200+
debugerStarted = forwardsResult.indexOf(waitText) === -1;
201+
if (!debugerStarted) {
202+
sleep(500);
203+
}
204+
}
205+
206+
if (debugerStarted) {
207+
this.$logger.info("# NativeScript Debugger started #");
208+
} else {
209+
this.$logger.warn("# NativeScript Debugger did not start in time #");
210+
}
211+
190212
if (this.$options.client) {
191213
let localDebugPort = this.getForwardedLocalDebugPortForPackageName(this.device.deviceInfo.identifier, packageName).wait();
192214
this.startDebuggerClient(localDebugPort).wait();

lib/services/ios-debug-service.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ class IOSDebugService implements IDebugService {
3232
private $iOSSocketRequestExecutor: IiOSSocketRequestExecutor,
3333
private $socketProxyFactory: ISocketProxyFactory) { }
3434

35-
get platform(): string {
35+
public get platform(): string {
3636
return "ios";
3737
}
3838

0 commit comments

Comments
 (0)