diff --git a/constants.ts b/constants.ts index 7ba9d546..537a31aa 100644 --- a/constants.ts +++ b/constants.ts @@ -8,6 +8,7 @@ export class ProvisionType { export class DeviceTypes { static Emulator = "Emulator"; + static Simulator = "Simulator"; static Device = "Device"; } diff --git a/mobile/android/android-emulator-services.ts b/mobile/android/android-emulator-services.ts index 7026ec50..3a9544e2 100644 --- a/mobile/android/android-emulator-services.ts +++ b/mobile/android/android-emulator-services.ts @@ -119,7 +119,7 @@ class AndroidEmulatorServices implements Mobile.IAndroidEmulatorServices { await this.unlockScreen(emulatorId); } else { if (emulatorImage) { - this.$errors.fail(this.$messages.Devices.NotFoundDeviceByIdentifierErrorMessageWithIdentifier, emulatorImage, this.$staticConfig.CLIENT_NAME.toLowerCase()); + this.$errors.fail(`No emulator image available for device identifier '${emulatorImage}'.`); } else { this.$errors.fail(this.$messages.Devices.NotFoundDeviceByIdentifierErrorMessage, this.$staticConfig.CLIENT_NAME.toLowerCase()); } diff --git a/mobile/mobile-core/devices-service.ts b/mobile/mobile-core/devices-service.ts index 4e74e3c7..45f78d52 100644 --- a/mobile/mobile-core/devices-service.ts +++ b/mobile/mobile-core/devices-service.ts @@ -392,19 +392,34 @@ export class DevicesService extends EventEmitter implements Mobile.IDevicesServi } let deviceInstances = this.getDeviceInstances(); - //if no --device is passed and no devices are found, the default emulator is started if (!data.deviceId && _.isEmpty(deviceInstances)) { if (!this.$hostInfo.isDarwin && this.$mobileHelper.isiOSPlatform(data.platform)) { this.$errors.failWithoutHelp(constants.ERROR_NO_DEVICES_CANT_USE_IOS_SIMULATOR); } + } + + try { + await this._startEmulatorIfNecessary(data); + } catch (err) { + const errorMessage = this.getEmulatorError(err, data.platform); + + this.$errors.failWithoutHelp(errorMessage); + } + } + } + + private async _startEmulatorIfNecessary(data?: Mobile.IDevicesServicesInitializationOptions): Promise { + const deviceInstances = this.getDeviceInstances(); + //if no --device is passed and no devices are found, the default emulator is started + if (!data.deviceId && _.isEmpty(deviceInstances)) { return await this.startEmulator(data.platform); } //check if --device(value) is running, if it's not or it's not the same as is specified, start with name from --device(value) if (data.deviceId) { if (!helpers.isNumber(data.deviceId)) { - let activeDeviceInstance = _.find(this.getDeviceInstances(), (device: Mobile.IDevice) => { return device.deviceInfo.identifier === data.deviceId; }); + let activeDeviceInstance = _.find(deviceInstances, (device: Mobile.IDevice) => { return device.deviceInfo.identifier === data.deviceId; }); if (!activeDeviceInstance) { return await this.startEmulator(data.platform, data.deviceId); } @@ -418,7 +433,6 @@ export class DevicesService extends EventEmitter implements Mobile.IDevicesServi return await this.startEmulator(data.platform); } } - } } /** @@ -672,6 +686,19 @@ export class DevicesService extends EventEmitter implements Mobile.IDevicesServi shouldReturnImmediateResult = shouldReturnImmediateResult || false; return { shouldReturnImmediateResult: shouldReturnImmediateResult, platform: platform }; } + + private getEmulatorError(error: Error, platform: string): string { + let emulatorName = constants.DeviceTypes.Emulator; + + if (this.$mobileHelper.isiOSPlatform(platform)) { + emulatorName = constants.DeviceTypes.Simulator; + } + + return `Cannot find connected devices.${EOL}` + + `${emulatorName} start failed with: ${error.message}${EOL}` + + `To list currently connected devices and verify that the specified identifier exists, run '${this.$staticConfig.CLIENT_NAME.toLowerCase()} device'.${EOL}` + + `To list available ${emulatorName.toLowerCase()} images, run '${this.$staticConfig.CLIENT_NAME.toLowerCase()} device --available-devices'.`; + } } $injector.register("devicesService", DevicesService);