gecko/browser/devtools/app-manager/content/connection-footer.js

210 lines
7.5 KiB
JavaScript

/* 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/. */
const Cu = Components.utils;
const Ci = Components.interfaces;
Cu.import("resource://gre/modules/Services.jsm");
Cu.import("resource:///modules/devtools/gDevTools.jsm");
const {Simulator} = Cu.import("resource://gre/modules/devtools/Simulator.jsm")
const {Devices} = Cu.import("resource://gre/modules/devtools/Devices.jsm");
const {devtools} = Cu.import("resource://gre/modules/devtools/Loader.jsm", {});
const {require} = devtools;
const {ConnectionManager, Connection} = require("devtools/client/connection-manager");
const {getDeviceFront} = require("devtools/server/actors/device");
const ConnectionStore = require("devtools/app-manager/connection-store");
const DeviceStore = require("devtools/app-manager/device-store");
const simulatorsStore = require("devtools/app-manager/simulators-store");
const adbStore = require("devtools/app-manager/builtin-adb-store");
window.addEventListener("unload", function onUnload() {
window.removeEventListener("unload", onUnload);
UI.destroy();
});
let UI = {
init: function() {
this.useFloatingScrollbarsIfNeeded();
let connections = ConnectionManager.connections;
if (connections.length > 0) {
let hash = window.location.hash;
if (hash) {
let res = (/cid=([^&]+)/).exec(hash)
if (res) {
let [,cid] = res;
this.connection = connections.filter((({uid}) => uid == cid))[0];
}
}
if (!this.connection) {
// We take the first connection available.
this.connection = connections[0];
}
} else {
let host = Services.prefs.getCharPref("devtools.debugger.remote-host");
let port = Services.prefs.getIntPref("devtools.debugger.remote-port");
this.connection = ConnectionManager.createConnection(host, port);
}
window.location.hash = "cid=" + this.connection.uid;
window.parent.postMessage(JSON.stringify({name:"connection",cid:this.connection.uid}), "*");
this.store = Utils.mergeStores({
"device": new DeviceStore(this.connection),
"connection": new ConnectionStore(this.connection),
"simulators": simulatorsStore,
"adb": adbStore
});
let pre = document.querySelector("#logs > pre");
pre.textContent = this.connection.logs;
pre.scrollTop = pre.scrollTopMax;
this.connection.on(Connection.Events.NEW_LOG, this._onNewLog);
this.template = new Template(document.body, this.store, Utils.l10n);
this.template.start();
this._onSimulatorConnected = this._onSimulatorConnected.bind(this);
this._onSimulatorDisconnected = this._onSimulatorDisconnected.bind(this);
},
destroy: function() {
this.store.destroy();
this.connection.off(Connection.Events.NEW_LOG, this._onNewLog);
this.template.destroy();
},
_onNewLog: function(event, str) {
let pre = document.querySelector("#logs > pre");
pre.textContent += "\n" + str;
pre.scrollTop = pre.scrollTopMax;
},
useFloatingScrollbarsIfNeeded: function() {
if (Services.appinfo.OS == "Darwin") {
return;
}
let scrollbarsUrl = Services.io.newURI("chrome://browser/skin/devtools/floating-scrollbars-light.css", null, null);
let winUtils = window.QueryInterface(Ci.nsIInterfaceRequestor).getInterface(Ci.nsIDOMWindowUtils);
winUtils.loadSheet(scrollbarsUrl, winUtils.AGENT_SHEET);
let computedStyle = window.getComputedStyle(document.documentElement);
if (computedStyle) { // Force a reflow to take the new css into account
let display = computedStyle.display; // Save display value
document.documentElement.style.display = "none";
window.getComputedStyle(document.documentElement).display; // Flush
document.documentElement.style.display = display; // Restore
}
},
disconnect: function() {
this.connection.disconnect();
},
connect: function() {
this.connection.connect();
},
editConnectionParameters: function() {
document.body.classList.add("edit-connection");
document.querySelector("input.host").focus();
},
saveConnectionInfo: function() {
document.body.classList.remove("edit-connection");
document.querySelector("#connect-button").focus();
let host = document.querySelector("input.host").value;
let port = document.querySelector("input.port").value;
this.connection.port = port;
this.connection.host = host;
Services.prefs.setCharPref("devtools.debugger.remote-host", host);
Services.prefs.setIntPref("devtools.debugger.remote-port", port);
},
showSimulatorList: function() {
document.body.classList.add("show-simulators");
},
cancelShowSimulatorList: function() {
document.body.classList.remove("show-simulators");
},
installSimulator: function() {
let url = "https://developer.mozilla.org/docs/Mozilla/Firefox_OS/Using_the_App_Manager#Simulator";
window.open(url);
},
startSimulator: function(version) {
this._portBeforeSimulatorStarted = this.connection.port;
let port = ConnectionManager.getFreeTCPPort();
let simulator = Simulator.getByVersion(version);
if (!simulator) {
this.connection.log("Error: can't find simulator: " + version);
return;
}
if (!simulator.launch) {
this.connection.log("Error: invalid simulator: " + version);
return;
}
this.connection.log("Found simulator: " + version);
this.connection.log("Starting simulator...");
this.simulator = simulator;
this.simulator.launch({ port: port })
.then(() => {
this.connection.log("Simulator ready. Connecting.");
this.connection.port = port;
this.connection.host = "localhost";
this.connection.once("connected",
this._onSimulatorConnected);
this.connection.once("disconnected",
this._onSimulatorDisconnected);
this.connection.keepConnecting = true;
this.connection.connect();
});
document.body.classList.remove("show-simulators");
},
_onSimulatorConnected: function() {
this.connection.log("Connected to simulator.");
this.connection.keepConnecting = false;
// This doesn't change the current (successful) connection,
// but makes sure that when the simulator is disconnected, the
// connection doesn't end up with a random port number (from
// getFreeTCPPort).
this.connection.port = this._portBeforeSimulatorStarted;
},
_onSimulatorDisconnected: function() {
this.connection.off("connected", this._onSimulatorConnected);
},
connectToAdbDevice: function(name) {
let device = Devices.getByName(name);
device.connect().then((port) => {
this.connection.host = "localhost";
this.connection.port = port;
this.connect();
});
},
screenshot: function() {
this.connection.client.listTabs(
response => {
let front = getDeviceFront(this.connection.client, response);
front.screenshotToBlob().then(blob => {
let topWindow = Services.wm.getMostRecentWindow("navigator:browser");
let gBrowser = topWindow.gBrowser;
let url = topWindow.URL.createObjectURL(blob);
let tab = gBrowser.selectedTab = gBrowser.addTab(url);
tab.addEventListener("TabClose", function onTabClose() {
tab.removeEventListener("TabClose", onTabClose, false);
topWindow.URL.revokeObjectURL(url);
}, false);
}).then(null, console.error);
}
);
},
}