From 66fa12a091c44d062ce4423e9e413e647895c466 Mon Sep 17 00:00:00 2001 From: Andrew Grieve Date: Thu, 4 Dec 2014 09:58:00 -0500 Subject: [PATCH] CB-8119 Restart adb when we detect it's hung --- bin/templates/cordova/lib/build.js | 42 +++++++++++++++++++++++++---- bin/templates/cordova/lib/device.js | 40 ++++++++++++++++++++------- 2 files changed, 67 insertions(+), 15 deletions(-) diff --git a/bin/templates/cordova/lib/build.js b/bin/templates/cordova/lib/build.js index 85a6e7cd..0d4d0046 100644 --- a/bin/templates/cordova/lib/build.js +++ b/bin/templates/cordova/lib/build.js @@ -398,12 +398,44 @@ module.exports.run = function(options, optResolvedTarget) { * Returns "arm" or "x86". */ module.exports.detectArchitecture = function(target) { - return exec('adb -s ' + target + ' shell cat /proc/cpuinfo') - .then(function(output) { - if (/intel/i.exec(output)) { - return 'x86'; + function helper() { + return exec('adb -s ' + target + ' shell cat /proc/cpuinfo') + .then(function(output) { + if (/intel/i.exec(output)) { + return 'x86'; + } + return 'arm'; + }); + } + // It sometimes happens (at least on OS X), that this command will hang forever. + // To fix it, either unplug & replug device, or restart adb server. + return helper().timeout(1000, 'Device communication timed out. Try unplugging & replugging the device.') + .then(null, function(err) { + if (/timed out/.exec('' + err)) { + // adb kill-server doesn't seem to do the trick. + // Could probably find a x-platform version of killall, but I'm not actually + // sure that this scenario even happens on non-OSX machines. + return exec('killall adb') + .then(function() { + console.log('adb seems hung. retrying.'); + return helper() + .then(null, function() { + // The double kill is sadly often necessary, at least on mac. + console.log('Now device not found... restarting adb again.'); + return exec('killall adb') + .then(function() { + return helper() + .then(null, function() { + return Q.reject('USB is flakey. Try unplugging & replugging the device.'); + }); + }); + }); + }, function() { + // For non-killall OS's. + return Q.reject(err); + }) } - return 'arm'; + throw err; }); }; diff --git a/bin/templates/cordova/lib/device.js b/bin/templates/cordova/lib/device.js index 6be55e30..6430d732 100644 --- a/bin/templates/cordova/lib/device.js +++ b/bin/templates/cordova/lib/device.js @@ -28,23 +28,43 @@ var exec = require('./exec'), /** * Returns a promise for the list of the device ID's found + * @param lookHarder When true, try restarting adb if no devices are found. */ -module.exports.list = function() { - return exec('adb devices') - .then(function(output) { - var response = output.split('\n'); - var device_list = []; - for (var i = 1; i < response.length; i++) { - if (response[i].match(/\w+\tdevice/) && !response[i].match(/emulator/)) { - device_list.push(response[i].replace(/\tdevice/, '').replace('\r', '')); +module.exports.list = function(lookHarder) { + function helper() { + return exec('adb devices') + .then(function(output) { + var response = output.split('\n'); + var device_list = []; + for (var i = 1; i < response.length; i++) { + if (response[i].match(/\w+\tdevice/) && !response[i].match(/emulator/)) { + device_list.push(response[i].replace(/\tdevice/, '').replace('\r', '')); + } } + return device_list; + }); + } + return helper() + .then(function(list) { + if (list.length === 0 && lookHarder) { + // adb kill-server doesn't seem to do the trick. + // Could probably find a x-platform version of killall, but I'm not actually + // sure that this scenario even happens on non-OSX machines. + return exec('killall adb') + .then(function() { + console.log('Restarting adb to see if more devices are detected.'); + return helper(); + }, function() { + // For non-killall OS's. + return list; + }); } - return device_list; + return list; }); } module.exports.resolveTarget = function(target) { - return this.list() + return this.list(true) .then(function(device_list) { if (!device_list || !device_list.length) { return Q.reject('ERROR: Failed to deploy to device, no devices found.');