CB-10157 Uninstall app from device/emulator only when signed apk is already installed

This commit is contained in:
Vladimir Kotikov 2016-01-21 15:52:29 +03:00
parent 44421bbc79
commit 9d3ee3d56e
2 changed files with 51 additions and 19 deletions

View File

@ -89,12 +89,25 @@ module.exports.install = function(target, buildResults) {
var pkgName = manifest.getPackageId(); var pkgName = manifest.getPackageId();
var launchName = pkgName + '/.' + manifest.getActivity().getName(); var launchName = pkgName + '/.' + manifest.getActivity().getName();
events.emit('log', 'Using apk: ' + apk_path); events.emit('log', 'Using apk: ' + apk_path);
// This promise is always resolved, even if 'adb uninstall' fails to uninstall app
// or the app doesn't installed at all, so no error catching needed. return Adb.install(resolvedTarget.target, apk_path, {replace: true})
return Adb.uninstall(resolvedTarget.target, pkgName) .catch(function (error) {
// CB-9557 CB-10157 only uninstall and reinstall app if the one that
// is already installed on device was signed w/different certificate
if (!/INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES/.test(error.toString()))
throw error;
events.emit('warn', 'Uninstalling app from device and reinstalling it again because the ' +
'installed app already signed with different key');
// This promise is always resolved, even if 'adb uninstall' fails to uninstall app
// or the app doesn't installed at all, so no error catching needed.
return Adb.uninstall(resolvedTarget.target, pkgName)
.then(function() {
return Adb.install(resolvedTarget.target, apk_path, {replace: true});
});
})
.then(function() { .then(function() {
return Adb.install(resolvedTarget.target, apk_path, {replace: true});
}).then(function() {
//unlock screen //unlock screen
return Adb.shell(resolvedTarget.target, 'input keyevent 82'); return Adb.shell(resolvedTarget.target, 'input keyevent 82');
}).then(function() { }).then(function() {

View File

@ -321,7 +321,7 @@ module.exports.install = function(givenTarget, buildResults) {
}).then(function () { }).then(function () {
// This promise is always resolved, even if 'adb uninstall' fails to uninstall app // This promise is always resolved, even if 'adb uninstall' fails to uninstall app
// or the app doesn't installed at all, so no error catching needed. // or the app doesn't installed at all, so no error catching needed.
return Adb.uninstall(target.target, pkgName) return Q.when()
.then(function() { .then(function() {
var apk_path = build.findBestApkForArchitecture(buildResults, target.arch); var apk_path = build.findBestApkForArchitecture(buildResults, target.arch);
@ -334,28 +334,47 @@ module.exports.install = function(givenTarget, buildResults) {
events.emit('log', 'Using apk: ' + apk_path); events.emit('log', 'Using apk: ' + apk_path);
events.emit('verbose', 'Installing app on emulator...'); events.emit('verbose', 'Installing app on emulator...');
function exec(command, opts) { // A special function to call adb install in specific environment w/ specific options.
// Introduced as a part of fix for http://issues.apache.org/jira/browse/CB-9119
// to workaround sporadic emulator hangs
function adbInstallWithOptions(target, apk, opts) {
events.emit('verbose', 'Installing apk ' + apk + ' on ' + target + '...');
var command = 'adb -s ' + target + ' install -r "' + apk + '"';
return Q.promise(function (resolve, reject) { return Q.promise(function (resolve, reject) {
child_process.exec(command, opts, function(err, stdout, stderr) { child_process.exec(command, opts, function(err, stdout, stderr) {
if (err) reject(new CordovaError('Error executing "' + command + '": ' + stderr)); if (err) reject(new CordovaError('Error executing "' + command + '": ' + stderr));
// adb does not return an error code even if installation fails. Instead it puts a specific
// message to stdout, so we have to use RegExp matching to detect installation failure.
else if (/Failure/.test(stdout)) reject(new CordovaError('Failed to install apk to emulator: ' + stdout));
else resolve(stdout); else resolve(stdout);
}); });
}); });
} }
var retriedInstall = retry.retryPromise( function installPromise () {
NUM_INSTALL_RETRIES, return adbInstallWithOptions(target.target, apk_path, execOptions)
exec, 'adb -s ' + target.target + ' install -r "' + apk_path + '"', execOptions .catch(function (error) {
); // CB-9557 CB-10157 only uninstall and reinstall app if the one that
// is already installed on device was signed w/different certificate
if (!/INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES/.test(error.toString()))
throw error;
return retriedInstall.then(function (output) { events.emit('warn', 'Uninstalling app from device and reinstalling it again because the ' +
if (output.match(/Failure/)) { 'installed app already signed with different key');
return Q.reject(new CordovaError('Failed to install apk to emulator: ' + output));
} else { // This promise is always resolved, even if 'adb uninstall' fails to uninstall app
events.emit('log', 'INSTALL SUCCESS'); // or the app doesn't installed at all, so no error catching needed.
} return Adb.uninstall(target.target, pkgName)
}, function (err) { .then(function() {
return Q.reject(new CordovaError('Failed to install apk to emulator: ' + err)); return adbInstallWithOptions(target.target, apk_path, execOptions);
});
});
}
return retry.retryPromise(NUM_INSTALL_RETRIES, installPromise)
.then(function (output) {
events.emit('log', 'INSTALL SUCCESS');
}); });
}); });
// unlock screen // unlock screen