mirror of
https://github.com/apache/cordova-android.git
synced 2025-01-19 15:12:51 +08:00
CB-12546: leverage avdmanager
if android
warns it is no longer
useful, which happens in Android SDK Tools 25.3.1. explicitly set the CWD of the spawned emulator process to workaround a recent google android sdk bug. rename android_sdk_version.js to android_sdk.js, to better reflect its contents. have create.js copy over the android_sdk_version batch file.
This commit is contained in:
parent
e2af492a63
commit
a7ef686a27
@ -19,7 +19,7 @@
|
|||||||
under the License.
|
under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
var android_sdk_version = require('./lib/android_sdk_version');
|
var android_sdk_version = require('./lib/android_sdk');
|
||||||
|
|
||||||
android_sdk_version.run().done(null, function(err) {
|
android_sdk_version.run().done(null, function(err) {
|
||||||
console.log(err);
|
console.log(err);
|
||||||
|
@ -62,3 +62,17 @@ module.exports.run = function() {
|
|||||||
return Q.all([get_sdks()]);
|
return Q.all([get_sdks()]);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
module.exports.version_string_to_api_level = {
|
||||||
|
'4.0': 14,
|
||||||
|
'4.0.3': 15,
|
||||||
|
'4.1': 16,
|
||||||
|
'4.2': 17,
|
||||||
|
'4.3': 18,
|
||||||
|
'4.4': 19,
|
||||||
|
'4.4W': 20,
|
||||||
|
'5.0': 21,
|
||||||
|
'5.1': 22,
|
||||||
|
'6.0': 23,
|
||||||
|
'7.0': 24,
|
||||||
|
'7.1.1': 25
|
||||||
|
};
|
@ -147,8 +147,8 @@ function copyScripts(projectPath) {
|
|||||||
shell.cp('-r', path.join(ROOT, 'node_modules'), destScriptsDir);
|
shell.cp('-r', path.join(ROOT, 'node_modules'), destScriptsDir);
|
||||||
shell.cp(path.join(ROOT, 'bin', 'check_reqs*'), destScriptsDir);
|
shell.cp(path.join(ROOT, 'bin', 'check_reqs*'), destScriptsDir);
|
||||||
shell.cp(path.join(ROOT, 'bin', 'lib', 'check_reqs.js'), path.join(projectPath, 'cordova', 'lib', 'check_reqs.js'));
|
shell.cp(path.join(ROOT, 'bin', 'lib', 'check_reqs.js'), path.join(projectPath, 'cordova', 'lib', 'check_reqs.js'));
|
||||||
shell.cp(path.join(ROOT, 'bin', 'android_sdk_version'), path.join(destScriptsDir, 'android_sdk_version'));
|
shell.cp(path.join(ROOT, 'bin', 'android_sdk_version*'), destScriptsDir);
|
||||||
shell.cp(path.join(ROOT, 'bin', 'lib', 'android_sdk_version.js'), path.join(projectPath, 'cordova', 'lib', 'android_sdk_version.js'));
|
shell.cp(path.join(ROOT, 'bin', 'lib', 'android_sdk.js'), path.join(projectPath, 'cordova', 'lib', 'android_sdk.js'));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
128
bin/templates/cordova/lib/emulator.js
vendored
128
bin/templates/cordova/lib/emulator.js
vendored
@ -29,9 +29,11 @@ var AndroidManifest = require('./AndroidManifest');
|
|||||||
var events = require('cordova-common').events;
|
var events = require('cordova-common').events;
|
||||||
var spawn = require('cordova-common').superspawn.spawn;
|
var spawn = require('cordova-common').superspawn.spawn;
|
||||||
var CordovaError = require('cordova-common').CordovaError;
|
var CordovaError = require('cordova-common').CordovaError;
|
||||||
|
var shelljs = require('shelljs');
|
||||||
|
|
||||||
var Q = require('q');
|
var Q = require('q');
|
||||||
var os = require('os');
|
var os = require('os');
|
||||||
|
var fs = require('fs');
|
||||||
var child_process = require('child_process');
|
var child_process = require('child_process');
|
||||||
|
|
||||||
// constants
|
// constants
|
||||||
@ -42,18 +44,16 @@ var NUM_INSTALL_RETRIES = 3;
|
|||||||
var CHECK_BOOTED_INTERVAL = 3 * ONE_SECOND; // in milliseconds
|
var CHECK_BOOTED_INTERVAL = 3 * ONE_SECOND; // in milliseconds
|
||||||
var EXEC_KILL_SIGNAL = 'SIGKILL';
|
var EXEC_KILL_SIGNAL = 'SIGKILL';
|
||||||
|
|
||||||
/**
|
function forgivingWhichSync(cmd) {
|
||||||
* Returns a Promise for a list of emulator images in the form of objects
|
try {
|
||||||
* {
|
return fs.realpathSync(shelljs.which(cmd));
|
||||||
name : <emulator_name>,
|
} catch (e) {
|
||||||
path : <path_to_emulator_image>,
|
return '';
|
||||||
target : <api_target>,
|
}
|
||||||
abi : <cpu>,
|
}
|
||||||
skin : <skin>
|
|
||||||
}
|
function list_images_using_avdmanager() {
|
||||||
*/
|
return spawn('avdmanager', ['list', 'avd'])
|
||||||
module.exports.list_images = function() {
|
|
||||||
return spawn('android', ['list', 'avds'])
|
|
||||||
.then(function(output) {
|
.then(function(output) {
|
||||||
var response = output.split('\n');
|
var response = output.split('\n');
|
||||||
var emulator_list = [];
|
var emulator_list = [];
|
||||||
@ -70,14 +70,32 @@ module.exports.list_images = function() {
|
|||||||
i++;
|
i++;
|
||||||
img_obj['path'] = response[i].split('Path: ')[1].replace('\r', '');
|
img_obj['path'] = response[i].split('Path: ')[1].replace('\r', '');
|
||||||
}
|
}
|
||||||
if (response[i + 1].match(/\(API\slevel\s/) || (response[i + 2] && response[i + 2].match(/\(API\slevel\s/))) {
|
if (response[i + 1].match(/Target:\s/)) {
|
||||||
i++;
|
i++;
|
||||||
var secondLine = response[i + 1].match(/\(API\slevel\s/) ? response[i + 1] : '';
|
if (response[i + 1].match(/ABI:\s/)) {
|
||||||
img_obj['target'] = (response[i] + secondLine).split('Target: ')[1].replace('\r', '');
|
img_obj['abi'] = response[i + 1].split('ABI: ')[1].replace('\r', '');
|
||||||
}
|
}
|
||||||
if (response[i + 1].match(/ABI:\s/)) {
|
// This next conditional just aims to match the old output of `android list avd`
|
||||||
i++;
|
// We do so so that we don't have to change the logic when parsing for the
|
||||||
img_obj['abi'] = response[i].split('ABI: ')[1].replace('\r', '');
|
// best emulator target to spawn (see below in `best_image`)
|
||||||
|
// This allows us to transitionally support both `android` and `avdmanager` binaries,
|
||||||
|
// depending on what SDK version the user has
|
||||||
|
if (response[i + 1].match(/Based\son:\s/)) {
|
||||||
|
img_obj['target'] = response[i + 1].split('Based on:')[1];
|
||||||
|
if (img_obj['target'].match(/Tag\/ABI:\s/)) {
|
||||||
|
img_obj['target'] = img_obj['target'].split('Tag/ABI:')[0].replace('\r', '').trim();
|
||||||
|
if (img_obj['target'].indexOf('(') > -1) {
|
||||||
|
img_obj['target'] = img_obj['target'].substr(0, img_obj['target'].indexOf('(') - 1).trim();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
var version_string = img_obj['target'].replace(/Android\s+/, '');
|
||||||
|
|
||||||
|
var android_sdk = require('./android_sdk');
|
||||||
|
var api_level = android_sdk.version_string_to_api_level[version_string];
|
||||||
|
if (api_level) {
|
||||||
|
img_obj['target'] += ' (API level ' + api_level + ')';
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (response[i + 1].match(/Skin:\s/)) {
|
if (response[i + 1].match(/Skin:\s/)) {
|
||||||
i++;
|
i++;
|
||||||
@ -94,6 +112,73 @@ module.exports.list_images = function() {
|
|||||||
}
|
}
|
||||||
return emulator_list;
|
return emulator_list;
|
||||||
});
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a Promise for a list of emulator images in the form of objects
|
||||||
|
* {
|
||||||
|
name : <emulator_name>,
|
||||||
|
path : <path_to_emulator_image>,
|
||||||
|
target : <api_target>,
|
||||||
|
abi : <cpu>,
|
||||||
|
skin : <skin>
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
module.exports.list_images = function() {
|
||||||
|
if (forgivingWhichSync('android')) {
|
||||||
|
return spawn('android', ['list', 'avds'])
|
||||||
|
.then(function(output) {
|
||||||
|
var response = output.split('\n');
|
||||||
|
var emulator_list = [];
|
||||||
|
for (var i = 1; i < response.length; i++) {
|
||||||
|
// To return more detailed information use img_obj
|
||||||
|
var img_obj = {};
|
||||||
|
if (response[i].match(/Name:\s/)) {
|
||||||
|
img_obj['name'] = response[i].split('Name: ')[1].replace('\r', '');
|
||||||
|
if (response[i + 1].match(/Device:\s/)) {
|
||||||
|
i++;
|
||||||
|
img_obj['device'] = response[i].split('Device: ')[1].replace('\r', '');
|
||||||
|
}
|
||||||
|
if (response[i + 1].match(/Path:\s/)) {
|
||||||
|
i++;
|
||||||
|
img_obj['path'] = response[i].split('Path: ')[1].replace('\r', '');
|
||||||
|
}
|
||||||
|
if (response[i + 1].match(/\(API\slevel\s/) || (response[i + 2] && response[i + 2].match(/\(API\slevel\s/))) {
|
||||||
|
i++;
|
||||||
|
var secondLine = response[i + 1].match(/\(API\slevel\s/) ? response[i + 1] : '';
|
||||||
|
img_obj['target'] = (response[i] + secondLine).split('Target: ')[1].replace('\r', '');
|
||||||
|
}
|
||||||
|
if (response[i + 1].match(/ABI:\s/)) {
|
||||||
|
i++;
|
||||||
|
img_obj['abi'] = response[i].split('ABI: ')[1].replace('\r', '');
|
||||||
|
}
|
||||||
|
if (response[i + 1].match(/Skin:\s/)) {
|
||||||
|
i++;
|
||||||
|
img_obj['skin'] = response[i].split('Skin: ')[1].replace('\r', '');
|
||||||
|
}
|
||||||
|
|
||||||
|
emulator_list.push(img_obj);
|
||||||
|
}
|
||||||
|
/* To just return a list of names use this
|
||||||
|
if (response[i].match(/Name:\s/)) {
|
||||||
|
emulator_list.push(response[i].split('Name: ')[1].replace('\r', '');
|
||||||
|
}*/
|
||||||
|
|
||||||
|
}
|
||||||
|
return emulator_list;
|
||||||
|
}).catch(function(stderr) {
|
||||||
|
// try to use `avdmanager` in case `android` has problems
|
||||||
|
// this likely means the target machine is using a newer version of
|
||||||
|
// the android sdk, and possibly `avdmanager` is available.
|
||||||
|
return list_images_using_avdmanager();
|
||||||
|
});
|
||||||
|
} else if (forgivingWhichSync('avdmanager')) {
|
||||||
|
return list_images_using_avdmanager();
|
||||||
|
} else {
|
||||||
|
return Q().then(function() {
|
||||||
|
throw new CordovaError('Could not find either `android` or `avdmanager` on your $PATH! Are you sure the Android SDK is installed and available?');
|
||||||
|
});
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -199,10 +284,13 @@ module.exports.start = function(emulator_ID, boot_timeout) {
|
|||||||
}).then(function(emulatorId) {
|
}).then(function(emulatorId) {
|
||||||
return self.get_available_port()
|
return self.get_available_port()
|
||||||
.then(function (port) {
|
.then(function (port) {
|
||||||
|
// Figure out the directory the emulator binary runs in, and set the cwd to that directory.
|
||||||
|
// Workaround for https://code.google.com/p/android/issues/detail?id=235461
|
||||||
|
var emulator_dir = path.dirname(shelljs.which('emulator'));
|
||||||
var args = ['-avd', emulatorId, '-port', port];
|
var args = ['-avd', emulatorId, '-port', port];
|
||||||
// Don't wait for it to finish, since the emulator will probably keep running for a long time.
|
// Don't wait for it to finish, since the emulator will probably keep running for a long time.
|
||||||
child_process
|
child_process
|
||||||
.spawn('emulator', args, { stdio: 'inherit', detached: true })
|
.spawn('emulator', args, { stdio: 'inherit', detached: true, cwd: emulator_dir })
|
||||||
.unref();
|
.unref();
|
||||||
|
|
||||||
// wait for emulator to start
|
// wait for emulator to start
|
||||||
|
Loading…
Reference in New Issue
Block a user