check in midway through android startup/shutdown refactor

This commit is contained in:
Jonathan Lipps
2013-10-25 17:06:40 -07:00
parent b537c4ae71
commit 386de406f3

View File

@@ -40,7 +40,6 @@ Android.prototype.initialize = function(opts) {
this.verbose = opts.verbose;
this.queue = [];
this.progress = 0;
this.onStop = function() {};
this.implicitWaitMs = 0;
this.commandTimeoutMs = 60 * 1000;
this.origCommandTimeoutMs = this.commandTimeoutMs;
@@ -52,6 +51,9 @@ Android.prototype.initialize = function(opts) {
this.asyncWaitMs = 0;
this.remote = null;
this.curWindowHandle = null;
this.didLaunch = false;
this.launchCb = function() {};
this.uiautomatorExitCb = function() {};
this.capabilities = {
platform: 'LINUX'
, browserName: 'Android'
@@ -64,113 +66,109 @@ Android.prototype.initialize = function(opts) {
};
Android.prototype.start = function(cb, onDie) {
if (typeof onDie === "function") {
this.onStop = onDie;
}
var didLaunch = false;
var onLaunch = function(err, launchCb) {
if (typeof launchCb === "undefined" || launchCb === null) {
launchCb = cb;
}
// These messages are from adb.js. Must update when adb.js changes.
var relaunchOn = [
'Could not find a connected Android device'
, 'Device did not become ready'
];
var checkShouldRelaunch = function(msg) {
var relaunch = false;
_.each(relaunchOn, function(relaunchMsg) {
relaunch = relaunch || msg.indexOf(relaunchMsg) !== -1;
});
return relaunch;
};
if (err) {
if (err.message === null ||
typeof err.message === 'undefined' ||
checkShouldRelaunch(err.message.toString())) {
logger.error(err);
logger.error("Above error isn't fatal, maybe relaunching adb will help....");
this.adb.waitForDevice(function(err) {
if (err) return launchCb(err);
didLaunch = true;
launchCb();
});
} else {
// error is already printed by ADB.prototype.waitForActivity
this.shutdown();
this.adb = null;
this.onStop = null;
launchCb(err);
}
} else {
logger.info("ADB launched! Ready for commands (will time out in " +
(this.commandTimeoutMs / 1000) + "secs)");
this.resetTimeout();
didLaunch = true;
launchCb(null);
}
}.bind(this);
var onExit = function(code) {
if (!didLaunch) {
var msg = "UiAutomator quit before it successfully launched";
logger.error(msg);
cb(new Error(msg));
code = code || 1;
} else if (typeof this.cbForCurrentCmd === "function") {
var error = new UnknownError("UiAutomator died while responding to " +
"command, please check appium logs!");
this.cbForCurrentCmd(error, null);
code = code || 1;
}
if (this.adb) {
this.uninstallApp(function() {
this.adb = null;
this.uiautomator = null;
this.shuttingDown = false;
this.onStop(code);
this.onStop = null;
}.bind(this));
} else {
logger.info("We're in uiautomator's exit callback but adb is gone already");
}
}.bind(this);
this.launchCb = cb;
this.uiautomatorExitCb = onDie;
if (this.adb === null) {
// Pass Android opts and Android ref to adb.
logger.info("Starting android appium");
this.adb = new ADB(this.opts);
this.uiautomator = new UiAutomator(this.adb, this.opts);
this.startAppium(onLaunch, onExit);
this.uiautomator.onExit = this.uiautomatorExitCb;
logger.debug("Using fast reset? " + this.opts.fastReset);
async.series([
this.prepareDevice.bind(this),
this.pushStrings.bind(this),
this.requestXmlCompression.bind(this),
this.uninstallApp.bind(this),
this.installApp.bind(this),
this.forwardPort.bind(this),
this.pushAppium.bind(this),
this.pushUnlock.bind(this),
this.uiautomator.start.bind(this.uiautomator),
this.wakeUp.bind(this),
this.unlockScreen.bind(this),
this.startApp.bind(this)
], function(err) {
this.launchCb(err);
}.bind(this));
} else {
logger.error("Tried to start ADB when we already have one running!");
}
};
Android.prototype.startAppium = function(onLaunch, onExit) {
logger.info("Starting android appium");
this.uiautomator.onExit = onExit;
Android.prototype.onLaunch = function(err) {
var readyToGo = function() {
logger.info("ADB launched! Ready for commands (will time out in " +
(this.commandTimeoutMs / 1000) + "secs)");
this.resetTimeout();
this.didLaunch = true;
this.launchCb();
}.bind(this);
logger.debug("Using fast reset? " + this.opts.fastReset);
var giveUp = function(err) {
this.shutdown(function() {
this.launchCb(err);
}.bind(this));
}.bind(this);
async.series([
this.prepareDevice.bind(this),
this.pushStrings.bind(this),
this.requestXmlCompression.bind(this),
this.uninstallApp.bind(this),
this.installApp.bind(this),
this.forwardPort.bind(this),
this.pushAppium.bind(this),
this.pushUnlock.bind(this),
this.uiautomator.start.bind(this.uiautomator),
this.wakeUp.bind(this),
this.unlockScreen.bind(this),
this.startApp.bind(this)
], function(err) {
onLaunch(err);
if (err) {
if (this.checkShouldRelaunch(err)) {
logger.error(err);
logger.error("Above error isn't fatal, maybe relaunching adb will help....");
this.adb.waitForDevice(function(err) {
if (err) return giveUp(err);
readyToGo();
});
} else {
giveUp(err);
}
} else {
readyToGo();
}
};
Android.prototype.onUiautomatorExit = function(code) {
if (!this.didLaunch) {
var msg = "UiAutomator quit before it successfully launched";
logger.error(msg);
this.launchCb(new Error(msg));
} else if (typeof this.cbForCurrentCmd === "function") {
var error = new UnknownError("UiAutomator died while responding to " +
"command, please check appium logs!");
this.cbForCurrentCmd(error, null);
code = code || 1;
}
if (this.adb) {
this.uninstallApp(function() {
this.adb = null;
this.uiautomator = null;
this.shuttingDown = false;
}.bind(this));
} else {
logger.info("We're in uiautomator's exit callback but adb is gone already");
}
};
Android.prototype.checkShouldRelaunch = function(launchErr) {
if (launchErr.message === null || typeof launchErr.message === 'undefined') {
logger.error("We're checking if we should relaunch based on something " +
"which isn't an error object. Check the codez!");
return false;
}
var msg = launchErr.message.toString();
var relaunchOn = [
'Could not find a connected Android device'
, 'Device did not become ready'
];
var relaunch = false;
_.each(relaunchOn, function(relaunchMsg) {
relaunch = relaunch || msg.indexOf(relaunchMsg) !== -1;
});
return relaunch;
};
Android.prototype.pushStrings = function(cb) {
@@ -255,25 +253,21 @@ Android.prototype.uninstallApp = function(cb) {
};
Android.prototype.stop = function(cb) {
this.shuttingDown = true;
this.adb.goToHome(function() {
this.shutdown(cb);
}.bind(this));
};
Android.prototype.cleanup = function() {
// should be called after all shutdowns
if (this.commandTimeout) {
clearTimeout(this.commandTimeout);
}
if (this.adb === null) {
logger.info("Trying to stop adb but it already exited");
if (cb) {
cb();
}
} else {
if (cb) {
this.onStop = cb;
}
this.shuttingDown = true;
this.adb.goToHome(function() {
this.shutdown();
}.bind(this));
this.queue = [];
this.progress = 0;
}
this.queue = [];
this.progress = 0;
this.adb = null;
this.uiautomator = null;
};
Android.prototype.shutdown = function() {