Skip to content

chore: merge release in master #3792

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 27 commits into from
Aug 3, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
1e65021
chore: update common lib to get fix for detecting iOS devices on Win
KristianDD Jul 25, 2018
766094b
chore: fix release branch not included in .travis.yml
KristianDD Jul 25, 2018
699212e
Merge pull request #3771 from NativeScript/kddimitrov/fix-detect-ios-…
KristianDD Jul 25, 2018
3a948b1
chore: update ios-sim-portable version
Jul 25, 2018
81409aa
Merge pull request #3772 from NativeScript/kddmitrov/update-ios-sim-p…
KristianDD Jul 25, 2018
ed8b4aa
fix: ios fast sync restarts app
Jul 26, 2018
8f04fc8
Merge pull request #3776 from NativeScript/kddimitrov/fix-fast-sync-ios
KristianDD Jul 26, 2018
882de49
docs: improve the platform add logging by listing the installed runti…
Jul 27, 2018
3b2997c
Dispose android livesync sockets
Fatme Jul 30, 2018
eb5140f
Merge pull request #3780 from NativeScript/fatme/dispose-sockets
Jul 30, 2018
cac4ee9
Update to latest common lib
Fatme Jul 31, 2018
a3893e9
Merge pull request #3778 from NativeScript/tachev/log-installed-runtime
Jul 31, 2018
0805cbd
Merge pull request #3781 from NativeScript/fatme/fix-emulators
Jul 31, 2018
ccfa6d2
fix: socket not cleared on time for second sync
KristianDD Jul 31, 2018
f180c26
fix: plugin include.gradle not migrated
KristianDD Aug 1, 2018
3e70b85
Merge pull request #3783 from NativeScript/kddimitrov/fix-two-fast-co…
KristianDD Aug 1, 2018
40ecfdf
Merge pull request #3784 from NativeScript/kddimitrov/fix-include-gra…
Aug 1, 2018
64683af
fix: Test command runs tests twice and often fails on Android
rosen-vladimirov Aug 2, 2018
33976d8
fix: LiveSync to Android hangs for 30 seconds
rosen-vladimirov Aug 2, 2018
ed3c140
fix: do not use adb push directory on Android 9 or later as its throw…
rosen-vladimirov Aug 2, 2018
e2805e7
Merge pull request #3786 from NativeScript/vladimirov/fix-test-command
rosen-vladimirov Aug 2, 2018
ab14c46
Destroy properly net connection to android's emulator port
Fatme Aug 2, 2018
5f1e276
Merge pull request #3787 from NativeScript/fatme/fix-net-connect
Aug 2, 2018
9ec4ad9
chore: Rename exposed methods and events for emulators
rosen-vladimirov Aug 2, 2018
cd77446
Merge pull request #3788 from NativeScript/vladimirov/fix-public-api
rosen-vladimirov Aug 2, 2018
45a4834
Merge branch 'release' into vladimirov/merge-rel-master
rosen-vladimirov Aug 3, 2018
7299a62
chore: update to latest common lib
rosen-vladimirov Aug 3, 2018
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
branches:
only:
- master
- release
env:
global:
- DATE=$(date +%Y-%m-%d)
Expand Down
113 changes: 107 additions & 6 deletions PublicAPI.md
Original file line number Diff line number Diff line change
Expand Up @@ -53,9 +53,11 @@ const tns = require("nativescript");
* [sysInfo](#sysinfo)
* [getSupportedNodeVersionRange](#getsupportednodeversionrange)
* [getSystemWarnings](#getsystemwarnings)
* [devicesService](#devicesService)
* [getAvailableEmulators](#getAvailableEmulators)
* [startEmulator](#startEmulator)
* [devicesService](#devicesservice)
* [getEmulatorImages](#getemulatorimages)
* [startEmulator](#startemulator)
* [deviceEmitter](#deviceemitter)
* [events](#deviceemitterevents)

## Module projectService

Expand Down Expand Up @@ -1204,8 +1206,8 @@ tns.sysInfo.getSystemWarnings()
## devicesService
The `devicesService` module allows interaction with devices and emulators. You can get a list of the available emulators or start a specific emulator.

### getAvailableEmulators
The `getAvailableEmulators` method returns object of all running and available emulators. The result is in the following format:
### getEmulators
The `getEmulators` method returns object of all running and available emulators. The result is in the following format:
```JavaScript
{
android: {
Expand All @@ -1223,7 +1225,7 @@ This method accepts platform parameter. If provided only devices by specified pl

* Usage
```TypeScript
tns.devicesService.getAvailableEmulators()
tns.devicesService.getEmulators()
.then(availableEmulatorsOutput => {
Object.keys(availableEmulatorsOutput)
.forEach(platform => {
Expand All @@ -1240,6 +1242,105 @@ tns.devicesService.startEmulator({imageIdentifier: "my emulator imageIdentifier"
.then(errors => { });
```

## deviceEmitter
This module is used to emit information for devices, applications on them, etc.

### deviceEmitterEvents
`deviceEmitter` emits the following events:
`deviceEmitter` module is used to emit different events related to devices attached to the system.
You can use `deviceEmitter` to add handles for the following events:

* `deviceFound` - Raised when a new device is attached to the system. The callback function will receive one argument - `deviceInfoData`.
Sample usage:
```JavaScript
tns.deviceEmitter.on("deviceFound", (deviceInfoData) => {
console.log("Found device with identifier: " + deviceInfoData.identifier);
});
```

* `deviceLost` - Raised when a device is detached from the system. The callback function will receive one argument - `deviceInfoData`.
Sample usage:
```JavaScript
tns.deviceEmitter.on("deviceLost", (deviceInfoData) => {
console.log("Detached device with identifier: " + deviceInfoData.identifier);
});
```

* `deviceLogData` - Raised when attached device reports any information. This is the output of `adb logcat` for Android devices. For iOS this is the `iOS SysLog`.
The event is raised for any device that reports data. The callback function has two arguments - `deviceIdentifier` and `reportedData`. <br/><br/>
Sample usage:
```JavaScript
tns.deviceEmitter.on("deviceLogData", (identifier, reportedData) => {
console.log("Device " + identifier + " reports: " + reportedData);
});
```

* `applicationInstalled` - Raised when application is installed on a device. The callback has two arguments - `deviceIdentifier` and `applicationIdentifier`. <br/><br/>
Sample usage:
```JavaScript
tns.deviceEmitter.on("applicationInstalled", (identifier, applicationIdentifier) => {
console.log("Application " + applicationIdentifier + " has been installed on device with id: " + identifier);
});
```

* `applicationUninstalled` - Raised when application is removed from device. The callback has two arguments - `deviceIdentifier` and `applicationIdentifier`. <br/><br/>
Sample usage:
```JavaScript
tns.deviceEmitter.on("applicationUninstalled", (identifier, applicationIdentifier) => {
console.log("Application " + applicationIdentifier + " has been uninstalled from device with id: " + identifier);
});
```

* `debuggableAppFound` - Raised when application on a device becomes available for debugging. The callback has one argument - `applicationInfo`. <br/><br/>
Sample usage:
```JavaScript
tns.deviceEmitter.on("debuggableAppFound", (applicationInfo) => {
console.log("Application " + applicationInfo.appIdentifier + " is available for debugging on device with id: " + applicationInfo.deviceIdentifier);
});
```
Sample result for `applicationInfo` will be:
```JSON
{
"deviceIdentifier": "4df18f307d8a8f1b",
"appIdentifier": "com.telerik.Fitness",
"framework": "NativeScript",
"title": "NativeScript Application"
}
```

* `debuggableAppLost` - Raised when application on a device is not available for debugging anymore. The callback has one argument - `applicationInfo`. <br/><br/>
Sample usage:
```JavaScript
tns.deviceEmitter.on("debuggableAppLost", (applicationInfo) => {
console.log("Application " + applicationInfo.appIdentifier + " is not available for debugging anymore on device with id: " + applicationInfo.deviceIdentifier);
});
```
Sample result for `applicationInfo` will be:
```JSON
{
"deviceIdentifier": "4df18f307d8a8f1b",
"appIdentifier": "com.telerik.Fitness",
"framework": "NativeScript",
"title": "NativeScript Application"
}
```

* `emulatorImageFound` - Raised when a new Android Emulator Image or iOS Simulator is created/installed on the system. The callback has a single argument that describes the new image:
```JavaScript
tns.deviceEmitter.on("emulatorImageFound", (emulatorImageInfo) => {
console.log("Added new emulator image", emulatorImageInfo);
});
```
`emulatorImageInfo` is of type [Moble.IDeviceInfo](https://github.com/telerik/mobile-cli-lib/blob/61cdaaaf7533394afbbe84dd4eee355072ade2de/definitions/mobile.d.ts#L9-L86).

* `emulatorImageLost` - Raised when an Android Emulator Image or iOS Simulator is removed from the system. The callback has a single argument that describes the removed image:
```JavaScript
tns.deviceEmitter.on("emulatorImageLost", (emulatorImageInfo) => {
console.log("Removed emulator image", emulatorImageInfo);
});
```
`emulatorImageInfo` is of type [Moble.IDeviceInfo](https://github.com/telerik/mobile-cli-lib/blob/61cdaaaf7533394afbbe84dd4eee355072ade2de/definitions/mobile.d.ts#L9-L86).

## How to add a new method to Public API
CLI is designed as command line tool and when it is used as a library, it does not give you access to all of the methods. This is mainly implementation detail. Most of the CLI's code is created to work in command line, not as a library, so before adding method to public API, most probably it will require some modification.
For example the `$options` injected module contains information about all `--` options passed on the terminal. When the CLI is used as a library, the options are not populated. Before adding method to public API, make sure its implementation does not rely on `$options`.
Expand Down
7 changes: 0 additions & 7 deletions lib/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -98,13 +98,6 @@ class ItunesConnectApplicationTypesClass implements IiTunesConnectApplicationTyp
}

export const ItunesConnectApplicationTypes = new ItunesConnectApplicationTypesClass();
export class LiveSyncPaths {
static SYNC_DIR_NAME = "sync";
static REMOVEDSYNC_DIR_NAME = "removedsync";
static FULLSYNC_DIR_NAME = "fullsync";
static IOS_DEVICE_PROJECT_ROOT_PATH = "Library/Application Support/LiveSync";
static IOS_DEVICE_SYNC_ZIP_PATH = "Library/Application Support/LiveSync/sync.zip";
}
export const ANGULAR_NAME = "angular";
export const TYPESCRIPT_NAME = "typescript";
export const BUILD_OUTPUT_EVENT_NAME = "buildOutput";
Expand Down
3 changes: 2 additions & 1 deletion lib/definitions/livesync.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -452,8 +452,9 @@ interface IAndroidLivesyncTool {

/**
* Closes the current socket connection.
* @param error - Optional error for rejecting pending sync operations
*/
end(): void;
end(error?: Error): void;
}

interface IAndroidLivesyncToolConfiguration {
Expand Down
5 changes: 3 additions & 2 deletions lib/device-path-provider.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { fromWindowsRelativePathToUnix } from "./common/helpers";
import { APP_FOLDER_NAME, LiveSyncPaths } from "./constants";
import { APP_FOLDER_NAME } from "./constants";
import { LiveSyncPaths } from "./common/constants";
import { AndroidDeviceLiveSyncService } from "./services/livesync/android-device-livesync-service";
import * as path from "path";

Expand All @@ -23,7 +24,7 @@ export class DevicePathProvider implements IDevicePathProvider {
projectRoot = path.join(projectRoot, APP_FOLDER_NAME);
}
} else if (this.$mobileHelper.isAndroidPlatform(device.deviceInfo.platform)) {
projectRoot = `/data/local/tmp/${options.appIdentifier}`;
projectRoot = `${LiveSyncPaths.ANDROID_TMP_DIR_NAME}/${options.appIdentifier}`;
if (!options.getDirname) {
const deviceLiveSyncService = this.$injector.resolve<AndroidDeviceLiveSyncService>(AndroidDeviceLiveSyncService, { device });
const hashService = deviceLiveSyncService.getDeviceHashService(options.appIdentifier);
Expand Down
10 changes: 6 additions & 4 deletions lib/services/android-debug-service.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { sleep } from "../common/helpers";
import { DebugServiceBase } from "./debug-service-base";
import { LiveSyncPaths } from "../common/constants";

export class AndroidDebugService extends DebugServiceBase implements IPlatformDebugService {
private _packageName: string;
Expand Down Expand Up @@ -158,22 +159,23 @@ export class AndroidDebugService extends DebugServiceBase implements IPlatformDe
await this.device.applicationManager.stopApplication(appData);

if (debugOptions.debugBrk) {
await this.device.adb.executeShellCommand([`cat /dev/null > /data/local/tmp/${appData.appId}-debugbreak`]);
await this.device.adb.executeShellCommand([`cat /dev/null > ${LiveSyncPaths.ANDROID_TMP_DIR_NAME}/${appData.appId}-debugbreak`]);
}

await this.device.adb.executeShellCommand([`cat /dev/null > /data/local/tmp/${appData.appId}-debugger-started`]);
await this.device.adb.executeShellCommand([`cat /dev/null > ${LiveSyncPaths.ANDROID_TMP_DIR_NAME}/${appData.appId}-debugger-started`]);

await this.device.applicationManager.startApplication(appData);

await this.waitForDebugger(appData.appId);
}

private async waitForDebugger(packageName: String): Promise<void> {
const waitText: string = `0 /data/local/tmp/${packageName}-debugger-started`;
const debuggerStartedFilePath = `${LiveSyncPaths.ANDROID_TMP_DIR_NAME}/${packageName}-debugger-started`;
const waitText: string = `0 ${debuggerStartedFilePath}`;
let maxWait = 12;
let debuggerStarted: boolean = false;
while (maxWait > 0 && !debuggerStarted) {
const forwardsResult = await this.device.adb.executeShellCommand(["ls", "-s", `/data/local/tmp/${packageName}-debugger-started`]);
const forwardsResult = await this.device.adb.executeShellCommand(["ls", "-s", debuggerStartedFilePath]);

maxWait--;

Expand Down
4 changes: 2 additions & 2 deletions lib/services/android-project-service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import * as semver from "semver";
import * as projectServiceBaseLib from "./platform-project-service-base";
import { DeviceAndroidDebugBridge } from "../common/mobile/android/device-android-debug-bridge";
import { attachAwaitDetach, isRecommendedAarFile } from "../common/helpers";
import { Configurations } from "../common/constants";
import { Configurations, LiveSyncPaths } from "../common/constants";
import { SpawnOptions } from "child_process";

export class AndroidProjectService extends projectServiceBaseLib.PlatformProjectServiceBase implements IPlatformProjectService {
Expand Down Expand Up @@ -631,7 +631,7 @@ export class AndroidProjectService extends projectServiceBaseLib.PlatformProject

public async cleanDeviceTempFolder(deviceIdentifier: string, projectData: IProjectData): Promise<void> {
const adb = this.$injector.resolve(DeviceAndroidDebugBridge, { identifier: deviceIdentifier });
const deviceRootPath = `/data/local/tmp/${projectData.projectId}`;
const deviceRootPath = `${LiveSyncPaths.ANDROID_TMP_DIR_NAME}/${projectData.projectId}`;
await adb.executeShellCommand(["rm", "-rf", deviceRootPath]);
}

Expand Down
2 changes: 1 addition & 1 deletion lib/services/livesync/android-device-livesync-service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { DeviceAndroidDebugBridge } from "../../common/mobile/android/device-and
import { AndroidDeviceHashService } from "../../common/mobile/android/android-device-hash-service";
import { DeviceLiveSyncServiceBase } from "./device-livesync-service-base";
import * as helpers from "../../common/helpers";
import { LiveSyncPaths } from "../../constants";
import { LiveSyncPaths } from "../../common/constants";
import { cache } from "../../common/decorators";
import * as path from "path";
import * as net from "net";
Expand Down
39 changes: 26 additions & 13 deletions lib/services/livesync/android-device-livesync-sockets-service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,10 @@ import { DeviceAndroidDebugBridge } from "../../common/mobile/android/device-and
import { AndroidDeviceHashService } from "../../common/mobile/android/android-device-hash-service";
import { DeviceLiveSyncServiceBase } from "./device-livesync-service-base";
import { APP_FOLDER_NAME } from "../../constants";
import { LiveSyncPaths } from "../../common/constants";
import { AndroidLivesyncTool } from "./android-livesync-tool";
import * as path from "path";
import * as temp from "temp";

export class AndroidDeviceSocketsLiveSyncService extends DeviceLiveSyncServiceBase implements IAndroidNativeScriptDeviceLiveSyncService, INativeScriptDeviceLiveSyncService {
private livesyncTool: IAndroidLivesyncTool;
Expand All @@ -17,54 +19,65 @@ export class AndroidDeviceSocketsLiveSyncService extends DeviceLiveSyncServiceBa
private $logger: ILogger,
protected device: Mobile.IAndroidDevice,
private $options: ICommonOptions,
private $processService: IProcessService) {
private $processService: IProcessService,
private $fs: IFileSystem) {
super($platformsData, device);
this.livesyncTool = this.$injector.resolve(AndroidLivesyncTool);
}

public async beforeLiveSyncAction(deviceAppData: Mobile.IDeviceAppData): Promise<void> {
const platformData = this.$platformsData.getPlatformData(deviceAppData.platform, this.data);
const projectFilesPath = path.join(platformData.appDestinationDirectoryPath, APP_FOLDER_NAME);
const pathToLiveSyncFile = temp.path({ prefix: "livesync" });
this.$fs.writeFile(pathToLiveSyncFile, "");
await this.device.fileSystem.putFile(pathToLiveSyncFile, this.getPathToLiveSyncFileOnDevice(deviceAppData.appIdentifier), deviceAppData.appIdentifier);
await this.device.applicationManager.startApplication({ appId: deviceAppData.appIdentifier, projectName: this.data.projectName });
await this.connectLivesyncTool(projectFilesPath, this.data.projectId);
}

private getPathToLiveSyncFileOnDevice(appIdentifier: string): string {
return `${LiveSyncPaths.ANDROID_TMP_DIR_NAME}/${appIdentifier}-livesync-in-progress`;
}

public async finalizeSync(liveSyncInfo: ILiveSyncResultInfo) {
await this.doSync(liveSyncInfo);
}

private async doSync(liveSyncInfo: ILiveSyncResultInfo, {doRefresh = false}: {doRefresh?: boolean} = {}): Promise<IAndroidLivesyncSyncOperationResult> {
private async doSync(liveSyncInfo: ILiveSyncResultInfo, { doRefresh = false }: { doRefresh?: boolean } = {}): Promise<IAndroidLivesyncSyncOperationResult> {
const operationId = this.livesyncTool.generateOperationIdentifier();

let result = {operationId, didRefresh: true };
let result = { operationId, didRefresh: true };

if (liveSyncInfo.modifiedFilesData.length) {

const doSyncPromise = this.livesyncTool.sendDoSyncOperation(doRefresh, null, operationId);

const syncInterval : NodeJS.Timer = setInterval(() => {
const syncInterval: NodeJS.Timer = setInterval(() => {
if (this.livesyncTool.isOperationInProgress(operationId)) {
this.$logger.info("Sync operation in progress...");
}
}, AndroidDeviceSocketsLiveSyncService.STATUS_UPDATE_INTERVAL);

const clearSyncInterval = () => {
const actionOnEnd = async () => {
clearInterval(syncInterval);
await this.device.fileSystem.deleteFile(this.getPathToLiveSyncFileOnDevice(liveSyncInfo.deviceAppData.appIdentifier), liveSyncInfo.deviceAppData.appIdentifier);
};

this.$processService.attachToProcessExitSignals(this, clearSyncInterval);
doSyncPromise.then(clearSyncInterval, clearSyncInterval);
this.$processService.attachToProcessExitSignals(this, actionOnEnd);
doSyncPromise.then(actionOnEnd, actionOnEnd);

result = await doSyncPromise;
}

await this.device.fileSystem.deleteFile(this.getPathToLiveSyncFileOnDevice(liveSyncInfo.deviceAppData.appIdentifier), liveSyncInfo.deviceAppData.appIdentifier);

return result;
}

public async refreshApplication(projectData: IProjectData, liveSyncInfo: ILiveSyncResultInfo) {
const canExecuteFastSync = !liveSyncInfo.isFullSync && this.canExecuteFastSyncForPaths(liveSyncInfo.modifiedFilesData, projectData, this.device.deviceInfo.platform);

const syncOperationResult = await this.doSync(liveSyncInfo, {doRefresh: canExecuteFastSync});
const syncOperationResult = await this.doSync(liveSyncInfo, { doRefresh: canExecuteFastSync });

this.livesyncTool.end();

Expand Down Expand Up @@ -96,28 +109,28 @@ export class AndroidDeviceSocketsLiveSyncService extends DeviceLiveSyncServiceBa
}

private async _transferDirectory(deviceAppData: Mobile.IDeviceAppData, localToDevicePaths: Mobile.ILocalToDevicePathData[], projectFilesPath: string): Promise<Mobile.ILocalToDevicePathData[]> {
let transferredLocalToDevicePaths : Mobile.ILocalToDevicePathData[];
let transferredLocalToDevicePaths: Mobile.ILocalToDevicePathData[];
const deviceHashService = this.getDeviceHashService(deviceAppData.appIdentifier);
const currentShasums: IStringDictionary = await deviceHashService.generateHashesFromLocalToDevicePaths(localToDevicePaths);
const oldShasums = await deviceHashService.getShasumsFromDevice();

if (this.$options.force || !oldShasums) {
await this.livesyncTool.sendDirectory(projectFilesPath);
await deviceHashService.uploadHashFileToDevice(currentShasums);
transferredLocalToDevicePaths = localToDevicePaths;
transferredLocalToDevicePaths = localToDevicePaths;
} else {
const changedShasums = deviceHashService.getChangedShasums(oldShasums, currentShasums);
const changedFiles = _.keys(changedShasums);
if (changedFiles.length) {
await this.livesyncTool.sendFiles(changedFiles);
await deviceHashService.uploadHashFileToDevice(currentShasums);
transferredLocalToDevicePaths = localToDevicePaths.filter(localToDevicePathData => changedFiles.indexOf(localToDevicePathData.getLocalPath()) >= 0);
transferredLocalToDevicePaths = localToDevicePaths.filter(localToDevicePathData => changedFiles.indexOf(localToDevicePathData.getLocalPath()) >= 0);
} else {
transferredLocalToDevicePaths = [];
transferredLocalToDevicePaths = [];
}
}

return transferredLocalToDevicePaths ;
return transferredLocalToDevicePaths;
}

private async connectLivesyncTool(projectFilesPath: string, appIdentifier: string) {
Expand Down
3 changes: 2 additions & 1 deletion lib/services/livesync/android-livesync-tool.md
Original file line number Diff line number Diff line change
Expand Up @@ -177,8 +177,9 @@ End will close the current liveSync socket. Any sync operations that are still i
```TypeScript
/**
* Closes the current socket connection.
* @param error - Optional error for rejecting pending sync operations
*/
end(): void;
end(error? Error): void;
```

* Example:
Expand Down
Loading