1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/browser/devtools/app-manager/content/connection-footer.js Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,209 @@ 1.4 +/* This Source Code Form is subject to the terms of the Mozilla Public 1.5 + * License, v. 2.0. If a copy of the MPL was not distributed with this 1.6 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 1.7 + 1.8 +const Cu = Components.utils; 1.9 +const Ci = Components.interfaces; 1.10 +Cu.import("resource://gre/modules/Services.jsm"); 1.11 +Cu.import("resource:///modules/devtools/gDevTools.jsm"); 1.12 + 1.13 +const {Simulator} = Cu.import("resource://gre/modules/devtools/Simulator.jsm") 1.14 +const {Devices} = Cu.import("resource://gre/modules/devtools/Devices.jsm"); 1.15 +const {devtools} = Cu.import("resource://gre/modules/devtools/Loader.jsm", {}); 1.16 +const {require} = devtools; 1.17 + 1.18 +const {ConnectionManager, Connection} = require("devtools/client/connection-manager"); 1.19 +const {getDeviceFront} = require("devtools/server/actors/device"); 1.20 +const ConnectionStore = require("devtools/app-manager/connection-store"); 1.21 +const DeviceStore = require("devtools/app-manager/device-store"); 1.22 +const simulatorsStore = require("devtools/app-manager/simulators-store"); 1.23 +const adbStore = require("devtools/app-manager/builtin-adb-store"); 1.24 + 1.25 +window.addEventListener("unload", function onUnload() { 1.26 + window.removeEventListener("unload", onUnload); 1.27 + UI.destroy(); 1.28 +}); 1.29 + 1.30 +let UI = { 1.31 + init: function() { 1.32 + this.useFloatingScrollbarsIfNeeded(); 1.33 + let connections = ConnectionManager.connections; 1.34 + if (connections.length > 0) { 1.35 + let hash = window.location.hash; 1.36 + if (hash) { 1.37 + let res = (/cid=([^&]+)/).exec(hash) 1.38 + if (res) { 1.39 + let [,cid] = res; 1.40 + this.connection = connections.filter((({uid}) => uid == cid))[0]; 1.41 + } 1.42 + } 1.43 + if (!this.connection) { 1.44 + // We take the first connection available. 1.45 + this.connection = connections[0]; 1.46 + } 1.47 + } else { 1.48 + let host = Services.prefs.getCharPref("devtools.debugger.remote-host"); 1.49 + let port = Services.prefs.getIntPref("devtools.debugger.remote-port"); 1.50 + this.connection = ConnectionManager.createConnection(host, port); 1.51 + } 1.52 + 1.53 + window.location.hash = "cid=" + this.connection.uid; 1.54 + window.parent.postMessage(JSON.stringify({name:"connection",cid:this.connection.uid}), "*"); 1.55 + 1.56 + this.store = Utils.mergeStores({ 1.57 + "device": new DeviceStore(this.connection), 1.58 + "connection": new ConnectionStore(this.connection), 1.59 + "simulators": simulatorsStore, 1.60 + "adb": adbStore 1.61 + }); 1.62 + 1.63 + let pre = document.querySelector("#logs > pre"); 1.64 + pre.textContent = this.connection.logs; 1.65 + pre.scrollTop = pre.scrollTopMax; 1.66 + this.connection.on(Connection.Events.NEW_LOG, this._onNewLog); 1.67 + 1.68 + this.template = new Template(document.body, this.store, Utils.l10n); 1.69 + this.template.start(); 1.70 + 1.71 + this._onSimulatorConnected = this._onSimulatorConnected.bind(this); 1.72 + this._onSimulatorDisconnected = this._onSimulatorDisconnected.bind(this); 1.73 + }, 1.74 + 1.75 + destroy: function() { 1.76 + this.store.destroy(); 1.77 + this.connection.off(Connection.Events.NEW_LOG, this._onNewLog); 1.78 + this.template.destroy(); 1.79 + }, 1.80 + 1.81 + _onNewLog: function(event, str) { 1.82 + let pre = document.querySelector("#logs > pre"); 1.83 + pre.textContent += "\n" + str; 1.84 + pre.scrollTop = pre.scrollTopMax; 1.85 + }, 1.86 + 1.87 + useFloatingScrollbarsIfNeeded: function() { 1.88 + if (Services.appinfo.OS == "Darwin") { 1.89 + return; 1.90 + } 1.91 + let scrollbarsUrl = Services.io.newURI("chrome://browser/skin/devtools/floating-scrollbars-light.css", null, null); 1.92 + let winUtils = window.QueryInterface(Ci.nsIInterfaceRequestor).getInterface(Ci.nsIDOMWindowUtils); 1.93 + winUtils.loadSheet(scrollbarsUrl, winUtils.AGENT_SHEET); 1.94 + let computedStyle = window.getComputedStyle(document.documentElement); 1.95 + if (computedStyle) { // Force a reflow to take the new css into account 1.96 + let display = computedStyle.display; // Save display value 1.97 + document.documentElement.style.display = "none"; 1.98 + window.getComputedStyle(document.documentElement).display; // Flush 1.99 + document.documentElement.style.display = display; // Restore 1.100 + } 1.101 + }, 1.102 + 1.103 + disconnect: function() { 1.104 + this.connection.disconnect(); 1.105 + }, 1.106 + 1.107 + connect: function() { 1.108 + this.connection.connect(); 1.109 + }, 1.110 + 1.111 + editConnectionParameters: function() { 1.112 + document.body.classList.add("edit-connection"); 1.113 + document.querySelector("input.host").focus(); 1.114 + }, 1.115 + 1.116 + saveConnectionInfo: function() { 1.117 + document.body.classList.remove("edit-connection"); 1.118 + document.querySelector("#connect-button").focus(); 1.119 + let host = document.querySelector("input.host").value; 1.120 + let port = document.querySelector("input.port").value; 1.121 + this.connection.port = port; 1.122 + this.connection.host = host; 1.123 + Services.prefs.setCharPref("devtools.debugger.remote-host", host); 1.124 + Services.prefs.setIntPref("devtools.debugger.remote-port", port); 1.125 + }, 1.126 + 1.127 + showSimulatorList: function() { 1.128 + document.body.classList.add("show-simulators"); 1.129 + }, 1.130 + 1.131 + cancelShowSimulatorList: function() { 1.132 + document.body.classList.remove("show-simulators"); 1.133 + }, 1.134 + 1.135 + installSimulator: function() { 1.136 + let url = "https://developer.mozilla.org/docs/Mozilla/Firefox_OS/Using_the_App_Manager#Simulator"; 1.137 + window.open(url); 1.138 + }, 1.139 + 1.140 + startSimulator: function(version) { 1.141 + this._portBeforeSimulatorStarted = this.connection.port; 1.142 + let port = ConnectionManager.getFreeTCPPort(); 1.143 + let simulator = Simulator.getByVersion(version); 1.144 + if (!simulator) { 1.145 + this.connection.log("Error: can't find simulator: " + version); 1.146 + return; 1.147 + } 1.148 + if (!simulator.launch) { 1.149 + this.connection.log("Error: invalid simulator: " + version); 1.150 + return; 1.151 + } 1.152 + this.connection.log("Found simulator: " + version); 1.153 + this.connection.log("Starting simulator..."); 1.154 + 1.155 + this.simulator = simulator; 1.156 + this.simulator.launch({ port: port }) 1.157 + .then(() => { 1.158 + this.connection.log("Simulator ready. Connecting."); 1.159 + this.connection.port = port; 1.160 + this.connection.host = "localhost"; 1.161 + this.connection.once("connected", 1.162 + this._onSimulatorConnected); 1.163 + this.connection.once("disconnected", 1.164 + this._onSimulatorDisconnected); 1.165 + this.connection.keepConnecting = true; 1.166 + this.connection.connect(); 1.167 + }); 1.168 + document.body.classList.remove("show-simulators"); 1.169 + }, 1.170 + 1.171 + _onSimulatorConnected: function() { 1.172 + this.connection.log("Connected to simulator."); 1.173 + this.connection.keepConnecting = false; 1.174 + 1.175 + // This doesn't change the current (successful) connection, 1.176 + // but makes sure that when the simulator is disconnected, the 1.177 + // connection doesn't end up with a random port number (from 1.178 + // getFreeTCPPort). 1.179 + this.connection.port = this._portBeforeSimulatorStarted; 1.180 + }, 1.181 + 1.182 + _onSimulatorDisconnected: function() { 1.183 + this.connection.off("connected", this._onSimulatorConnected); 1.184 + }, 1.185 + 1.186 + connectToAdbDevice: function(name) { 1.187 + let device = Devices.getByName(name); 1.188 + device.connect().then((port) => { 1.189 + this.connection.host = "localhost"; 1.190 + this.connection.port = port; 1.191 + this.connect(); 1.192 + }); 1.193 + }, 1.194 + 1.195 + screenshot: function() { 1.196 + this.connection.client.listTabs( 1.197 + response => { 1.198 + let front = getDeviceFront(this.connection.client, response); 1.199 + front.screenshotToBlob().then(blob => { 1.200 + let topWindow = Services.wm.getMostRecentWindow("navigator:browser"); 1.201 + let gBrowser = topWindow.gBrowser; 1.202 + let url = topWindow.URL.createObjectURL(blob); 1.203 + let tab = gBrowser.selectedTab = gBrowser.addTab(url); 1.204 + tab.addEventListener("TabClose", function onTabClose() { 1.205 + tab.removeEventListener("TabClose", onTabClose, false); 1.206 + topWindow.URL.revokeObjectURL(url); 1.207 + }, false); 1.208 + }).then(null, console.error); 1.209 + } 1.210 + ); 1.211 + }, 1.212 +}