You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cordova.apache.org by an...@apache.org on 2016/01/22 11:29:04 UTC

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

Repository: cordova-android
Updated Branches:
  refs/heads/master 44421bbc7 -> 9d3ee3d56


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


Project: http://git-wip-us.apache.org/repos/asf/cordova-android/repo
Commit: http://git-wip-us.apache.org/repos/asf/cordova-android/commit/9d3ee3d5
Tree: http://git-wip-us.apache.org/repos/asf/cordova-android/tree/9d3ee3d5
Diff: http://git-wip-us.apache.org/repos/asf/cordova-android/diff/9d3ee3d5

Branch: refs/heads/master
Commit: 9d3ee3d56eb7be9ca2ae823364e7eef04c109816
Parents: 44421bb
Author: Vladimir Kotikov <v-...@microsoft.com>
Authored: Thu Jan 21 15:52:29 2016 +0300
Committer: Vladimir Kotikov <v-...@microsoft.com>
Committed: Fri Jan 22 12:36:48 2016 +0300

----------------------------------------------------------------------
 bin/templates/cordova/lib/device.js   | 23 +++++++++++----
 bin/templates/cordova/lib/emulator.js | 47 +++++++++++++++++++++---------
 2 files changed, 51 insertions(+), 19 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cordova-android/blob/9d3ee3d5/bin/templates/cordova/lib/device.js
----------------------------------------------------------------------
diff --git a/bin/templates/cordova/lib/device.js b/bin/templates/cordova/lib/device.js
index e62e3db..4f9acc8 100644
--- a/bin/templates/cordova/lib/device.js
+++ b/bin/templates/cordova/lib/device.js
@@ -89,12 +89,25 @@ module.exports.install = function(target, buildResults) {
         var pkgName = manifest.getPackageId();
         var launchName = pkgName + '/.' + manifest.getActivity().getName();
         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.uninstall(resolvedTarget.target, pkgName)
+
+        return Adb.install(resolvedTarget.target, apk_path, {replace: true})
+        .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() {
-            return Adb.install(resolvedTarget.target, apk_path, {replace: true});
-        }).then(function() {
             //unlock screen
             return Adb.shell(resolvedTarget.target, 'input keyevent 82');
         }).then(function() {

http://git-wip-us.apache.org/repos/asf/cordova-android/blob/9d3ee3d5/bin/templates/cordova/lib/emulator.js
----------------------------------------------------------------------
diff --git a/bin/templates/cordova/lib/emulator.js b/bin/templates/cordova/lib/emulator.js
index 9e214b1..d0bd622 100644
--- a/bin/templates/cordova/lib/emulator.js
+++ b/bin/templates/cordova/lib/emulator.js
@@ -321,7 +321,7 @@ module.exports.install = function(givenTarget, buildResults) {
     }).then(function () {
         // 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(target.target, pkgName)
+        return Q.when()
         .then(function() {
 
             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('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) {
                     child_process.exec(command, opts, function(err, stdout, 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);
                     });
                 });
             }
 
-            var retriedInstall = retry.retryPromise(
-                NUM_INSTALL_RETRIES,
-                exec, 'adb -s ' + target.target + ' install -r "' + apk_path + '"', execOptions
-            );
+            function installPromise () {
+                return adbInstallWithOptions(target.target, 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;
+
+                    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(target.target, pkgName)
+                    .then(function() {
+                        return adbInstallWithOptions(target.target, apk_path, execOptions);
+                    });
+                });
+            }
 
-            return retriedInstall.then(function (output) {
-                if (output.match(/Failure/)) {
-                    return Q.reject(new CordovaError('Failed to install apk to emulator: ' + output));
-                } else {
-                    events.emit('log', 'INSTALL SUCCESS');
-                }
-            }, function (err) {
-                return Q.reject(new CordovaError('Failed to install apk to emulator: ' + err));
+            return retry.retryPromise(NUM_INSTALL_RETRIES, installPromise)
+            .then(function (output) {
+                events.emit('log', 'INSTALL SUCCESS');
             });
         });
     // unlock screen


---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@cordova.apache.org
For additional commands, e-mail: commits-help@cordova.apache.org