diff --git a/lib/ParamedicConfig.js b/lib/ParamedicConfig.js index cdb955a8..6de77049 100644 --- a/lib/ParamedicConfig.js +++ b/lib/ParamedicConfig.js @@ -30,6 +30,8 @@ var BROWSERIFY_ARG = '--browserify '; var DEFAULT_CLI = 'cordova'; // use globally installed cordova by default var util = require('./utils').utilities; +var ip = require('ip'); +var logger = require('./utils').logger; function ParamedicConfig(json) { this._config = json; @@ -152,7 +154,14 @@ ParamedicConfig.prototype.setPlugins = function (plugins) { }; ParamedicConfig.prototype.getExternalServerUrl = function () { - return this._config.externalServerUrl; + if (this._config.externalServerUrl) { + return this._config.externalServerUrl; + } else { + // Android emulator defaults to 10.0.0.2 for some reason. If that is needed, it must be passed using the externalServerUrl parameter + var serverIp = "http://" + ip.address(); + logger.info("Using local server address = " + serverIp); + return serverIp; + } }; ParamedicConfig.prototype.isVerbose = function () { diff --git a/lib/ParamedicTargetChooser.js b/lib/ParamedicTargetChooser.js index c3544db9..edc913fa 100644 --- a/lib/ParamedicTargetChooser.js +++ b/lib/ParamedicTargetChooser.js @@ -53,6 +53,22 @@ ParamedicTargetChooser.prototype.chooseTarget = function (emulator, target) { ParamedicTargetChooser.prototype.chooseTargetForAndroid = function (emulator, target) { logger.info('cordova-paramedic: Choosing Target for Android'); + + if (target) { + logger.info('cordova-paramedic: Target defined as: ' + target); + var obj = {}; + obj.target = target; + return obj; + } + + var connectedPhysicalDevice = util.getAndroidPhysicalDevice(); + if (connectedPhysicalDevice) { + logger.info('cordova-paramedic: Physical device connected, use: ' + connectedPhysicalDevice); + var obj = {}; + obj.target = connectedPhysicalDevice; + return obj; + } + return this.startAnAndroidEmulator(target).then(function(emulatorId) { var obj = {}; obj.target = emulatorId; diff --git a/lib/paramedic.js b/lib/paramedic.js index a4947190..937340af 100644 --- a/lib/paramedic.js +++ b/lib/paramedic.js @@ -244,6 +244,20 @@ ParamedicRunner.prototype.setPermissions = function () { paramediciOSPermissions.updatePermissions(applicationsToGrantPermission); } } + + if(this.config.getPlatformId() === util.ANDROID) { + var self = this; + self.server.on('jasmineStarted', function (data) { + logger.info('cordova-paramedic: Jasmine started'); + logger.warn('Requesting permissions'); + cp.exec("adb shell pm grant " + util.PARAMEDIC_DEFAULT_APP_NAME + " android.permission.READ_PHONE_STATE"); + cp.exec("adb shell pm grant " + util.PARAMEDIC_DEFAULT_APP_NAME + " android.permission.READ_SMS"); + cp.exec("adb shell pm grant " + util.PARAMEDIC_DEFAULT_APP_NAME + " android.permission.READ_CALL_LOG"); + cp.exec("adb shell pm grant " + util.PARAMEDIC_DEFAULT_APP_NAME + " android.permission.ACCESS_FINE_LOCATION"); + cp.exec("adb shell pm grant " + util.PARAMEDIC_DEFAULT_APP_NAME + " android.permission.ACCESS_COARSE_LOCATION"); + cp.exec("adb shell pm grant " + util.PARAMEDIC_DEFAULT_APP_NAME + " android.permission.RECORD_AUDIO"); + }); + } }; ParamedicRunner.prototype.injectReporters = function () { @@ -332,8 +346,18 @@ ParamedicRunner.prototype.runLocalTests = function () { if (!self.config.getPlatformId() === util.BROWSER) { return execPromise(command); } - runProcess = cp.exec(command, function () { - // a precaution not to try to kill some other process + // We do not wait for the child process to finish, server connects when deployed and ready. + runProcess = cp.exec(command, (error, stdout, stderr) => { + if (error) { + // This won't show up until the process completes: + console.log('[ERROR]: Running cordova run failed'); + + console.log(stdout); + console.log(stderr); + reject(error); + } + console.log(stdout); + console.log(stderr); runProcess = null; }); }) diff --git a/lib/utils/utilities.js b/lib/utils/utilities.js index a2c7fbb1..5970c33b 100644 --- a/lib/utils/utilities.js +++ b/lib/utils/utilities.js @@ -29,6 +29,7 @@ var kill = require('tree-kill'); var HEADING_LINE_PATTERN = /List of devices/m; var DEVICE_ROW_PATTERN = /(emulator|device|host)/m; +var DEVICE_ONLY_ROW_PATTERN = /(device)/m; var KILL_SIGNAL = 'SIGINT'; @@ -52,6 +53,24 @@ function countAndroidDevices() { return numDevices; } +function getAndroidPhysicalDevice() { + var listCommand = 'adb devices'; + + logger.info('running:'); + logger.info(' ' + listCommand); + + var numDevices = 0; + var result = shelljs.exec(listCommand, {silent: false, async: false}); + var deviceId = null; + result.output.split('\n').forEach(function (line) { + if (!HEADING_LINE_PATTERN.test(line) && DEVICE_ONLY_ROW_PATTERN.test(line)) { + deviceId = line.split('\t')[0]; + logger.info("Identified deviceId as: " + deviceId); + } + }); + return deviceId; +} + function secToMin(seconds) { return Math.ceil(seconds / 60); } @@ -218,6 +237,7 @@ module.exports = { secToMin: secToMin, isWindows: isWindows, countAndroidDevices: countAndroidDevices, + getAndroidPhysicalDevice: getAndroidPhysicalDevice, getSimulatorsFolder: getSimulatorsFolder, doesFileExist: doesFileExist, getSqlite3InsertionCommand: getSqlite3InsertionCommand,