2015-03-17 16:10:58 +00:00
|
|
|
/* This Source Code Form is subject to the terms of the Mozilla Public
|
|
|
|
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
|
|
|
* You can obtain one at http://mozilla.org/MPL/2.0/. */
|
|
|
|
|
|
|
|
"use strict";
|
|
|
|
|
2015-09-26 16:12:01 +00:00
|
|
|
const {classes: Cc, interfaces: Ci, utils: Cu} = Components;
|
2015-03-17 16:10:58 +00:00
|
|
|
|
2015-09-26 16:12:01 +00:00
|
|
|
Cu.import("resource://gre/modules/Log.jsm");
|
|
|
|
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
|
2015-03-17 16:10:58 +00:00
|
|
|
|
2015-09-26 16:12:01 +00:00
|
|
|
const logger = Log.repository.getLogger("Marionette");
|
|
|
|
|
|
|
|
this.EXPORTED_SYMBOLS = ["Emulator"];
|
2015-03-17 16:10:58 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Represents the connection between Marionette and the emulator it's
|
|
|
|
* running on.
|
|
|
|
*
|
|
|
|
* When injected scripts call the JS routines {@code runEmulatorCmd} or
|
|
|
|
* {@code runEmulatorShell}, the second argument to those is a callback
|
|
|
|
* which is stored in cbs. They are later retreived by their unique ID
|
|
|
|
* using popCallback.
|
|
|
|
*
|
2015-09-26 16:12:01 +00:00
|
|
|
* @param {function(Object)} sendToEmulatorFn
|
2015-03-17 16:10:58 +00:00
|
|
|
* Callback function that sends a message to the emulator.
|
2015-09-26 16:12:01 +00:00
|
|
|
* @param {function(Object)} sendToEmulatorFn
|
|
|
|
* Callback function that sends a message asynchronously to the
|
|
|
|
* current listener.
|
2015-03-17 16:10:58 +00:00
|
|
|
*/
|
2015-09-26 16:12:01 +00:00
|
|
|
this.Emulator = function(sendToEmulatorFn) {
|
|
|
|
this.sendToEmulator = sendToEmulatorFn;
|
2015-03-17 16:10:58 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
/**
|
2015-09-26 16:12:01 +00:00
|
|
|
* Instruct the client to run an Android emulator command.
|
2015-03-17 16:10:58 +00:00
|
|
|
*
|
2015-09-26 16:12:01 +00:00
|
|
|
* @param {string} cmd
|
|
|
|
* The command to run.
|
|
|
|
* @param {function(?)} resCb
|
|
|
|
* Callback on a result response from the emulator.
|
|
|
|
* @param {function(?)} errCb
|
|
|
|
* Callback on an error in running the command.
|
2015-03-17 16:10:58 +00:00
|
|
|
*/
|
2015-09-26 16:12:01 +00:00
|
|
|
Emulator.prototype.command = function(cmd, resCb, errCb) {
|
|
|
|
assertDefined(cmd, "runEmulatorCmd");
|
|
|
|
this.sendToEmulator(
|
|
|
|
"runEmulatorCmd", {emulator_cmd: cmd}, resCb, errCb);
|
2015-03-17 16:10:58 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
/**
|
2015-09-26 16:12:01 +00:00
|
|
|
* Instruct the client to execute Android emulator shell arguments.
|
2015-03-17 16:10:58 +00:00
|
|
|
*
|
2015-09-26 16:12:01 +00:00
|
|
|
* @param {Array.<string>} args
|
|
|
|
* The shell instruction for the emulator to execute.
|
|
|
|
* @param {function(?)} resCb
|
|
|
|
* Callback on a result response from the emulator.
|
|
|
|
* @param {function(?)} errCb
|
|
|
|
* Callback on an error in executing the shell arguments.
|
2015-03-17 16:10:58 +00:00
|
|
|
*/
|
2015-09-26 16:12:01 +00:00
|
|
|
Emulator.prototype.shell = function(args, resCb, errCb) {
|
|
|
|
assertDefined(args, "runEmulatorShell");
|
|
|
|
this.sendToEmulator(
|
|
|
|
"runEmulatorShell", {emulator_shell: args}, resCb, errCb);
|
2015-03-17 16:10:58 +00:00
|
|
|
};
|
|
|
|
|
2015-09-26 16:12:01 +00:00
|
|
|
Emulator.prototype.processMessage = function(msg) {
|
|
|
|
let resCb = this.resultCallback(msg.json.id);
|
|
|
|
let errCb = this.errorCallback(msg.json.id);
|
|
|
|
|
|
|
|
switch (msg.name) {
|
|
|
|
case "Marionette:runEmulatorCmd":
|
|
|
|
this.command(msg.json.command, resCb, errCb);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case "Marionette:runEmulatorShell":
|
|
|
|
this.shell(msg.json.arguments, resCb, errCb);
|
|
|
|
break;
|
|
|
|
}
|
2015-03-17 16:10:58 +00:00
|
|
|
};
|
|
|
|
|
2015-09-26 16:12:01 +00:00
|
|
|
Emulator.prototype.resultCallback = function(msgId) {
|
|
|
|
return res => this.sendResult({result: res, id: msgId});
|
2015-03-17 16:10:58 +00:00
|
|
|
};
|
|
|
|
|
2015-09-26 16:12:01 +00:00
|
|
|
Emulator.prototype.errorCallback = function(msgId) {
|
|
|
|
return err => this.sendResult({error: err, id: msgId});
|
2015-03-17 16:10:58 +00:00
|
|
|
};
|
|
|
|
|
2015-09-26 16:12:01 +00:00
|
|
|
Emulator.prototype.sendResult = function(msg) {
|
|
|
|
// sendToListener set explicitly in GeckoDriver's ctor
|
|
|
|
this.sendToListener("emulatorCmdResult", msg);
|
|
|
|
};
|
2015-03-17 16:10:58 +00:00
|
|
|
|
2015-09-26 16:12:01 +00:00
|
|
|
/** Receives IPC messages from the listener. */
|
|
|
|
Emulator.prototype.receiveMessage = function(msg) {
|
2015-03-17 16:10:58 +00:00
|
|
|
try {
|
2015-09-26 16:12:01 +00:00
|
|
|
this.processMessage(msg);
|
2015-03-17 16:10:58 +00:00
|
|
|
} catch (e) {
|
2015-09-26 16:12:01 +00:00
|
|
|
this.sendResult({error: `${e.name}: ${e.message}`, id: msg.json.id});
|
2015-03-17 16:10:58 +00:00
|
|
|
}
|
|
|
|
};
|
2015-09-26 16:12:01 +00:00
|
|
|
|
|
|
|
Emulator.prototype.QueryInterface = XPCOMUtils.generateQI(
|
|
|
|
[Ci.nsIMessageListener, Ci.nsISupportsWeakReference]);
|
|
|
|
|
|
|
|
function assertDefined(arg, action) {
|
|
|
|
if (typeof arg == "undefined") {
|
|
|
|
throw new TypeError("Not enough arguments to " + action);
|
|
|
|
}
|
|
|
|
}
|