123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244 |
- "use strict";
- Object.defineProperty(exports, "__esModule", { value: true });
- const child_process_1 = require("child_process");
- const fs = require("fs");
- const glob = require("glob");
- const ini = require("ini");
- const path = require("path");
- const q = require("q");
- const config_1 = require("../config");
- const utils_1 = require("../utils");
- const noop = () => { };
- // Make a function which configures a child process to automatically respond
- // to a certain question
- function respondFactory(question, answer, verbose) {
- return (child) => {
- child.stdin.setDefaultEncoding('utf-8');
- child.stdout.on('data', (data) => {
- if (data != null) {
- if (verbose) {
- process.stdout.write(data);
- }
- if (data.toString().indexOf(question) != -1) {
- child.stdin.write(answer + '\n');
- }
- }
- });
- };
- }
- // Run a command on the android SDK
- function runAndroidSDKCommand(sdkPath, cmd, args, stdio, config_fun) {
- let child = utils_1.spawn(path.resolve(sdkPath, 'tools', 'android'), [cmd].concat(args), stdio);
- if (config_fun) {
- config_fun(child);
- }
- ;
- let deferred = q.defer();
- child.on('exit', (code) => {
- if (deferred != null) {
- if (code) {
- deferred.reject(code);
- }
- else {
- deferred.resolve();
- }
- deferred = null;
- }
- });
- child.on('error', (err) => {
- if (deferred != null) {
- deferred.reject(err);
- deferred = null;
- }
- });
- return deferred.promise;
- }
- // Download updates via the android SDK
- function downloadAndroidUpdates(sdkPath, targets, search_all, auto_accept, verbose) {
- return runAndroidSDKCommand(sdkPath, 'update', ['sdk', '-u'].concat(search_all ? ['-a'] : []).concat(['-t', targets.join(',')]), auto_accept ? 'pipe' : 'inherit', auto_accept ? respondFactory('Do you accept the license', 'y', verbose) : noop);
- }
- // Setup hardware acceleration for x86-64 emulation
- function setupHardwareAcceleration(sdkPath) {
- // TODO(sjelin): linux setup
- let toolDir = path.resolve(sdkPath, 'extras', 'intel', 'Hardware_Accelerated_Execution_Manager');
- if (config_1.Config.osType() == 'Darwin') {
- console.log('Enabling hardware acceleration (requires root access)');
- // We don't need the wrapped spawnSync because we know we're on OSX
- child_process_1.spawnSync('sudo', ['silent_install.sh'], { stdio: 'inherit', cwd: toolDir });
- }
- else if (config_1.Config.osType() == 'Windows_NT') {
- console.log('Enabling hardware acceleration (requires admin access)');
- // We don't need the wrapped spawnSync because we know we're on windows
- child_process_1.spawnSync('silent_install.bat', [], { stdio: 'inherit', cwd: toolDir });
- }
- }
- // Get a list of all the SDK download targets for a given set of APIs,
- // architectures, and platforms
- function getAndroidSDKTargets(apiLevels, architectures, platforms, oldAVDs) {
- function getSysImgTarget(architecture, platform, level) {
- if (platform.toUpperCase() == 'DEFAULT') {
- platform = 'android';
- }
- return 'sys-img-' + architecture + '-' + platform + '-' + level;
- }
- let targets = apiLevels
- .map((level) => {
- return 'android-' + level;
- })
- .concat(architectures.reduce((targets, architecture) => {
- return targets.concat.apply(targets, platforms.map((platform) => {
- return apiLevels.map(getSysImgTarget.bind(null, architecture, platform));
- }));
- }, []));
- oldAVDs.forEach((name) => {
- let avd = new AVDDescriptor(name);
- if (targets.indexOf(avd.api) == -1) {
- targets.push(avd.api);
- }
- let sysImgTarget = getSysImgTarget(avd.architecture, avd.platform, avd.api.slice('android-'.length));
- if (targets.indexOf(sysImgTarget) == -1) {
- targets.push(sysImgTarget);
- }
- });
- return targets;
- }
- // All the information about an android virtual device
- class AVDDescriptor {
- constructor(api, platform, architecture) {
- if (platform != undefined) {
- this.api = api;
- this.platform = platform;
- this.architecture = architecture;
- this.name = [api, platform, architecture].join('-');
- }
- else {
- this.name = api;
- let nameParts = this.name.split('-');
- this.api = nameParts[0] + '-' + nameParts[1];
- if (/v[0-9]+[a-z]+/.test(nameParts[nameParts.length - 1]) &&
- (nameParts[nameParts.length - 2].slice(0, 3) == 'arm')) {
- this.architecture = nameParts[nameParts.length - 2] + '-' + nameParts[nameParts.length - 1];
- }
- else {
- this.architecture = nameParts[nameParts.length - 1];
- }
- this.platform = this.name.slice(this.api.length + 1, -this.architecture.length - 1);
- }
- this.abi =
- (this.platform.toUpperCase() == 'DEFAULT' ? '' : this.platform + '/') + this.architecture;
- }
- avdName(version) {
- return this.name + '-v' + version + '-wd-manager';
- }
- }
- // Gets the descriptors for all AVDs which are possible to make given the
- // SDKs which were downloaded
- function getAVDDescriptors(sdkPath) {
- let deferred = q.defer();
- // `glob` package always prefers patterns to use `/`
- glob('system-images/*/*/*', { cwd: sdkPath }, (err, files) => {
- if (err) {
- deferred.reject(err);
- }
- else {
- deferred.resolve(files.map((file) => {
- // `file` could use `/` or `\`, so we use `path.normalize`
- let info = path.normalize(file).split(path.sep).slice(-3);
- return new AVDDescriptor(info[0], info[1], info[2]);
- }));
- }
- });
- return deferred.promise;
- }
- function sequentialForEach(array, func) {
- let ret = q(null);
- array.forEach((x) => {
- ret = ret.then(() => {
- return func(x);
- });
- });
- return ret;
- }
- // Configures the hardware.ini file for a system image of a new AVD
- function configureAVDHardware(sdkPath, desc) {
- let file = path.resolve(sdkPath, 'system-images', desc.api, desc.platform, desc.architecture, 'hardware.ini');
- return q.nfcall(fs.stat, file)
- .then((stats) => {
- return q.nfcall(fs.readFile, file);
- }, (err) => {
- return q('');
- })
- .then((contents) => {
- let config = ini.parse(contents.toString());
- config['hw.keyboard'] = 'yes';
- config['hw.battery'] = 'yes';
- config['hw.ramSize'] = 1024;
- return q.nfcall(fs.writeFile, file, ini.stringify(config));
- });
- }
- // Make an android virtual device
- function makeAVD(sdkPath, desc, version, verbose) {
- return runAndroidSDKCommand(sdkPath, 'delete', ['avd', '--name', desc.avdName(version)])
- .then(noop, noop)
- .then(() => {
- return runAndroidSDKCommand(sdkPath, 'create', ['avd', '--name', desc.avdName(version), '--target', desc.api, '--abi', desc.abi], 'pipe', respondFactory('Do you wish to create a custom hardware profile', 'no', verbose));
- });
- }
- // Initialize the android SDK
- function android(sdkPath, apiLevels, architectures, platforms, acceptLicenses, version, oldAVDs, logger, verbose) {
- let avdDescriptors;
- let tools = ['platform-tool', 'tool'];
- if ((config_1.Config.osType() == 'Darwin') || (config_1.Config.osType() == 'Windows_NT')) {
- tools.push('extra-intel-Hardware_Accelerated_Execution_Manager');
- }
- logger.info('android-sdk: Downloading additional SDK updates');
- downloadAndroidUpdates(sdkPath, tools, false, acceptLicenses, verbose)
- .then(() => {
- return setupHardwareAcceleration(sdkPath);
- })
- .then(() => {
- logger.info('android-sdk: Downloading more additional SDK updates ' +
- '(this may take a while)');
- return downloadAndroidUpdates(sdkPath, ['build-tools-24.0.0'].concat(getAndroidSDKTargets(apiLevels, architectures, platforms, oldAVDs)), true, acceptLicenses, verbose);
- })
- .then(() => {
- return getAVDDescriptors(sdkPath);
- })
- .then((descriptors) => {
- avdDescriptors = descriptors;
- logger.info('android-sdk: Configuring virtual device hardware');
- return sequentialForEach(avdDescriptors, (descriptor) => {
- return configureAVDHardware(sdkPath, descriptor);
- });
- })
- .then(() => {
- return sequentialForEach(avdDescriptors, (descriptor) => {
- logger.info('android-sdk: Setting up virtual device "' + descriptor.name + '"');
- return makeAVD(sdkPath, descriptor, version, verbose);
- });
- })
- .then(() => {
- return q.nfcall(fs.writeFile, path.resolve(sdkPath, 'available_avds.json'), JSON.stringify(avdDescriptors.map((descriptor) => {
- return descriptor.name;
- })));
- })
- .then(() => {
- logger.info('android-sdk: Initialization complete');
- })
- .done();
- }
- exports.android = android;
- ;
- function iOS(logger) {
- if (config_1.Config.osType() != 'Darwin') {
- throw new Error('Must be on a Mac to simulate iOS devices.');
- }
- try {
- fs.statSync('/Applications/Xcode.app');
- }
- catch (e) {
- logger.warn('You must install the xcode commandline tools!');
- }
- }
- exports.iOS = iOS;
- //# sourceMappingURL=initialize.js.map
|