Skip to content
This repository was archived by the owner on Feb 2, 2021. It is now read-only.

Commit 46e271f

Browse files
FatmeFatme
Fatme
authored and
Fatme
committed
Merge pull request #511 from telerik/fatme/page-reload
Send page reload message to android runtime
2 parents c280ac5 + e1b792c commit 46e271f

11 files changed

+312
-172
lines changed

declarations.d.ts

Lines changed: 24 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -289,14 +289,30 @@ interface IHtmlHelpService {
289289
interface IUsbLiveSyncServiceBase {
290290
initialize(platform: string): IFuture<string>;
291291
isInitialized: boolean;
292-
sync(platform: string, appIdentifier: string, projectFilesPath: string, excludedProjectDirsAndFiles: string[], watchGlob: any,
293-
platformSpecificLiveSyncServices: IDictionary<any>,
294-
notInstalledAppOnDeviceAction: (device: Mobile.IDevice) => IFuture<boolean>,
295-
notRunningiOSSimulatorAction: () => IFuture<boolean>,
296-
localProjectRootPath?: string,
297-
beforeLiveSyncAction?: (device: Mobile.IDevice, deviceAppData: Mobile.IDeviceAppData) => IFuture<void>,
298-
beforeBatchLiveSyncAction?: (filePath: string) => IFuture<string>,
299-
iOSSimulatorRelativeToProjectBasePathAction?: (projectFile: string) => string): IFuture<void>;
292+
sync(data: ILiveSyncData): IFuture<void>;
293+
}
294+
295+
interface ILiveSyncData {
296+
platform: string;
297+
appIdentifier: string;
298+
projectFilesPath: string;
299+
excludedProjectDirsAndFiles: string[];
300+
watchGlob: any;
301+
platformSpecificLiveSyncServices: IDictionary<any>;
302+
notInstalledAppOnDeviceAction: (device: Mobile.IDevice) => IFuture<void>;
303+
notRunningiOSSimulatorAction: () => IFuture<void>;
304+
localProjectRootPath?: string;
305+
beforeLiveSyncAction?: (device: Mobile.IDevice, deviceAppData: Mobile.IDeviceAppData) => IFuture<void>;
306+
beforeBatchLiveSyncAction?: (filePath: string) => IFuture<string>;
307+
iOSSimulatorRelativeToProjectBasePathAction?: (projectFile: string) => string;
308+
canExecuteFastLiveSync?: (filePath: string) => boolean;
309+
fastLiveSync?: (filePath: string) => void;
310+
}
311+
312+
interface IPlatformSpecificUsbLiveSyncService {
313+
restartApplication(deviceAppData: Mobile.IDeviceAppData, localToDevicePaths?: Mobile.ILocalToDevicePathData[]): IFuture<void>;
314+
beforeLiveSyncAction?(deviceAppData: Mobile.IDeviceAppData): IFuture<void>;
315+
sendPageReloadMessageToDevice?(deviceAppData: Mobile.IDeviceAppData): IFuture<void>;
300316
}
301317

302318
interface ISysInfoData {

definitions/mobile.d.ts

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,7 @@ declare module Mobile {
8383
putFile(localFilePath: string, deviceFilePath: string): IFuture<void>;
8484
deleteFile?(deviceFilePath: string, appIdentifier: string): void;
8585
transferFiles(appIdentifier: string, localToDevicePaths: Mobile.ILocalToDevicePathData[]): IFuture<void>;
86+
transferDirectory(deviceAppData: Mobile.IDeviceAppData, localToDevicePaths: Mobile.ILocalToDevicePathData[], projectFilesPath: string): IFuture<void>;
8687
transferFile?(localFilePath: string, deviceFilePath: string): IFuture<void>;
8788
}
8889

@@ -261,7 +262,8 @@ declare module Mobile {
261262

262263
interface IGDBServer {
263264
run(argv: string[]): IFuture<void>;
264-
kill(bundleExecutableName: string): IFuture<void>;
265+
kill(argv: string[]): IFuture<void>;
266+
destory(): void;
265267
}
266268

267269
interface INotificationProxyClient {
@@ -298,9 +300,10 @@ declare module Mobile {
298300

299301
interface IiOSSimulatorService extends IEmulatorPlatformServices {
300302
postDarwinNotification(notification: string): IFuture<void>;
301-
sync(appIdentifier: string, projectFilesPath: string, notRunningSimulatorAction: () => IFuture<boolean>): IFuture<void>;
302-
syncFiles(appIdentifier: string, projectFilesPath: string, projectFiles: string[], notRunningSimulatorAction: () => IFuture<boolean>, relativeToProjectBasePathAction?: (projectFile: string) => string): IFuture<void>;
303+
sync(appIdentifier: string, projectFilesPath: string, notRunningSimulatorAction: () => IFuture<void>): IFuture<void>;
304+
syncFiles(appIdentifier: string, projectFilesPath: string, projectFiles: string[], notRunningSimulatorAction: () => IFuture<void>, relativeToProjectBasePathAction?: (projectFile: string) => string): IFuture<void>;
303305
isSimulatorRunning(): IFuture<boolean>;
306+
transferFiles(appIdentifier: string, projectFiles: string[], relativeToProjectBasePathAction?: (_projectFile: string) => string, applicationPath?: string): IFuture<void>
304307
}
305308

306309
interface IEmulatorSettingsService {

helpers.ts

Lines changed: 20 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33

44
import * as uuid from "node-uuid";
55
import * as Fiber from "fibers";
6+
import * as net from "net";
67
let Table = require("cli-table");
78
import Future = require("fibers/future");
89
import { platform } from "os";
@@ -238,25 +239,39 @@ export function isFuture(candidateFuture: any): boolean {
238239
export function whenAny<T>(...futures: IFuture<T>[]): IFuture<IFuture<T>> {
239240
let resultFuture = new Future<IFuture<T>>();
240241
let futuresLeft = futures.length;
241-
let futureLocal: IFuture<T>;
242242

243-
for (let future of futures) {
244-
futureLocal = future;
243+
_.each(futures, future => {
245244
future.resolve((error, result?) => {
246245
futuresLeft--;
247246

248247
if (!resultFuture.isResolved()) {
249248
if (typeof error === "undefined") {
250-
resultFuture.return(futureLocal);
249+
resultFuture.return(future);
251250
} else if (futuresLeft === 0) {
252251
resultFuture.throw(new Error("None of the futures succeeded."));
253252
}
254253
}
255254
});
256-
}
255+
});
257256

258257
return resultFuture;
259258
}
259+
260+
export function connectEventually(factory: () => net.Socket, handler: (_socket: net.Socket) => void): void {
261+
function tryConnect() {
262+
let tryConnectAfterTimeout = setTimeout.bind(undefined, tryConnect, 1000);
263+
264+
let socket = factory();
265+
socket.on("connect", () => {
266+
socket.removeListener("error", tryConnectAfterTimeout);
267+
handler(socket);
268+
});
269+
socket.on("error", tryConnectAfterTimeout);
270+
}
271+
272+
tryConnect();
273+
}
274+
260275
//--- begin part copied from AngularJS
261276

262277
//The MIT License

mobile/android/android-device-file-system.ts

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,8 @@ export class AndroidDeviceFileSystem implements Mobile.IDeviceFileSystem {
88
constructor(private adb: Mobile.IAndroidDebugBridge,
99
private identifier: string,
1010
private $fs: IFileSystem,
11-
private $logger: ILogger) { }
11+
private $logger: ILogger,
12+
private $deviceAppDataFactory: Mobile.IDeviceAppDataFactory) { }
1213

1314
public listFiles(devicePath: string): IFuture<void> {
1415
return future.fromResult();
@@ -22,7 +23,7 @@ export class AndroidDeviceFileSystem implements Mobile.IDeviceFileSystem {
2223
return future.fromResult();
2324
}
2425

25-
public transferFiles(appIdentifier: string, localToDevicePaths: Mobile.ILocalToDevicePathData[]): IFuture<void> {
26+
public transferFiles(appIdentifier: string, localToDevicePaths: Mobile.ILocalToDevicePathData[], projectFilesPath?: string): IFuture<void> {
2627
return (() => {
2728
_(localToDevicePaths)
2829
.filter(localToDevicePathData => this.$fs.getFsStats(localToDevicePathData.getLocalPath()).wait().isFile())
@@ -40,6 +41,15 @@ export class AndroidDeviceFileSystem implements Mobile.IDeviceFileSystem {
4041
}).future<void>()();
4142
}
4243

44+
public transferDirectory(deviceAppData: Mobile.IDeviceAppData, localToDevicePaths: Mobile.ILocalToDevicePathData[], projectFilesPath: string): IFuture<void> {
45+
return (() => {
46+
this.adb.executeCommand(["push", projectFilesPath, deviceAppData.deviceProjectRootPath]).wait();
47+
48+
let command = _.map(localToDevicePaths, (localToDevicePathData) => localToDevicePathData.getDevicePath()).join(" ");
49+
this.adb.executeCommand(["chmod", "0777", command]).wait();
50+
}).future<void>()();
51+
}
52+
4353
public transferFile(localPath: string, devicePath: string): IFuture<void> {
4454
return (() => {
4555
this.$logger.trace(`Transfering ${localPath} to ${devicePath}`);

mobile/android/android-device.ts

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -59,12 +59,8 @@ export class AndroidDevice implements Mobile.IAndroidDevice {
5959
}
6060

6161
public deploy(packageFile: string, packageName: string): IFuture<void> {
62-
return (() => {
63-
this.applicationManager.reinstallApplication(packageName, packageFile).wait();
64-
this.applicationManager.startApplication(packageName).wait();
65-
this.$logger.info("Successfully deployed on device with identifier '%s'", this.identifier);
66-
}).future<void>()();
67-
}
62+
return this.applicationManager.reinstallApplication(packageName, packageFile);
63+
}
6864

6965
public openDeviceLogStream(): void {
7066
this.$logcatHelper.start(this.identifier);

mobile/ios/ios-application-manager.ts

Lines changed: 15 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import * as iOSProxyServices from "./ios-proxy-services";
99

1010
export class IOSApplicationManager implements Mobile.IDeviceApplicationManager {
1111
private uninstallApplicationCallbackPtr: NodeBuffer = null;
12+
private _gdbServer: Mobile.IGDBServer = null;
1213

1314
constructor(private device: Mobile.IiOSDevice,
1415
private devicePointer: NodeBuffer,
@@ -80,13 +81,12 @@ export class IOSApplicationManager implements Mobile.IDeviceApplicationManager {
8081
public stopApplication(applicationId: string): IFuture<void> {
8182
let application = this.getApplicationById(applicationId);
8283
let gdbServer = this.createGdbServer();
83-
return gdbServer.kill(application.CFBundleExecutable);
84+
return gdbServer.kill([`${application.Path}`]);
8485
}
8586

8687
public restartApplication(applicationId: string): IFuture<void> {
8788
return (() => {
88-
// This must be executed in separate process because ddb sometimes fails and the cli crashes.
89-
this.$childProcess.exec(`${process.argv[0]} ${process.argv[1]} device stop ${applicationId} ${this.$devicePlatformsConstants.iOS}`).wait();
89+
this.stopApplication(applicationId).wait();
9090
this.runApplicationCore(applicationId).wait();
9191
}).future<void>()();
9292
}
@@ -118,17 +118,23 @@ export class IOSApplicationManager implements Mobile.IDeviceApplicationManager {
118118
}
119119

120120
private runApplicationCore(applicationId: any) {
121+
if (this._gdbServer) {
122+
this._gdbServer.destory();
123+
this._gdbServer = null;
124+
}
125+
121126
let application = this.getApplicationById(applicationId);
122127
let gdbServer = this.createGdbServer();
123-
return gdbServer.run([`${application.Path}/${application.CFBundleExecutable}`]);
128+
return gdbServer.run([`${application.Path}`]);
124129
}
125130

126131
private createGdbServer(): Mobile.IGDBServer {
127-
let service = this.device.startService(iOSProxyServices.MobileServices.DEBUG_SERVER);
128-
let socket = this.$hostInfo.isWindows ? service : new net.Socket({ fd: service });
129-
let gdbServer = this.$injector.resolve(GDBServer, { socket: socket });
130-
131-
return gdbServer;
132+
if(!this._gdbServer) {
133+
let service = this.device.startService(iOSProxyServices.MobileServices.DEBUG_SERVER);
134+
let socket = this.$hostInfo.isWindows ? service : new net.Socket({ fd: service });
135+
this._gdbServer = this.$injector.resolve(GDBServer, { socket: socket });
136+
}
137+
return this._gdbServer;
132138
}
133139

134140
private getApplicationById(applicationId: string): Mobile.IDeviceApplication {

0 commit comments

Comments
 (0)