aboutdebugging.js (6158B)
1 /* This Source Code Form is subject to the terms of the Mozilla Public 2 * License, v. 2.0. If a copy of the MPL was not distributed with this 3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 4 5 "use strict"; 6 7 const { 8 bindActionCreators, 9 } = require("resource://devtools/client/shared/vendor/redux.js"); 10 const { 11 createFactory, 12 } = require("resource://devtools/client/shared/vendor/react.mjs"); 13 const { 14 render, 15 unmountComponentAtNode, 16 } = require("resource://devtools/client/shared/vendor/react-dom.mjs"); 17 const Provider = createFactory( 18 require("resource://devtools/client/shared/vendor/react-redux.js").Provider 19 ); 20 const { 21 START_IGNORE_ACTION, 22 } = require("resource://devtools/client/shared/redux/middleware/ignore.js"); 23 24 const FluentReact = require("resource://devtools/client/shared/vendor/fluent-react.js"); 25 const LocalizationProvider = createFactory(FluentReact.LocalizationProvider); 26 27 const actions = require("resource://devtools/client/aboutdebugging/src/actions/index.js"); 28 const { 29 configureStore, 30 } = require("resource://devtools/client/aboutdebugging/src/create-store.js"); 31 const { 32 setDebugTargetCollapsibilities, 33 } = require("resource://devtools/client/aboutdebugging/src/modules/debug-target-collapsibilities.js"); 34 35 const { 36 l10n, 37 } = require("resource://devtools/client/aboutdebugging/src/modules/l10n.js"); 38 39 const { 40 addNetworkLocationsObserver, 41 getNetworkLocations, 42 removeNetworkLocationsObserver, 43 } = require("resource://devtools/client/aboutdebugging/src/modules/network-locations.js"); 44 const { 45 addUSBRuntimesObserver, 46 getUSBRuntimes, 47 removeUSBRuntimesObserver, 48 } = require("resource://devtools/client/aboutdebugging/src/modules/usb-runtimes.js"); 49 50 loader.lazyRequireGetter( 51 this, 52 "adb", 53 "resource://devtools/client/shared/remote-debugging/adb/adb.js", 54 true 55 ); 56 loader.lazyRequireGetter( 57 this, 58 "adbAddon", 59 "resource://devtools/client/shared/remote-debugging/adb/adb-addon.js", 60 true 61 ); 62 loader.lazyRequireGetter( 63 this, 64 "adbProcess", 65 "resource://devtools/client/shared/remote-debugging/adb/adb-process.js", 66 true 67 ); 68 69 const Router = createFactory( 70 require("resource://devtools/client/shared/vendor/react-router-dom.js") 71 .HashRouter 72 ); 73 const App = createFactory( 74 require("resource://devtools/client/aboutdebugging/src/components/App.js") 75 ); 76 77 const AboutDebugging = { 78 async init() { 79 const direction = Services.locale.isAppLocaleRTL ? "rtl" : "ltr"; 80 document.documentElement.setAttribute("dir", direction); 81 82 this.onAdbAddonUpdated = this.onAdbAddonUpdated.bind(this); 83 this.onAdbProcessReady = this.onAdbProcessReady.bind(this); 84 this.onNetworkLocationsUpdated = this.onNetworkLocationsUpdated.bind(this); 85 this.onUSBRuntimesUpdated = this.onUSBRuntimesUpdated.bind(this); 86 87 this.store = configureStore(); 88 this.actions = bindActionCreators(actions, this.store.dispatch); 89 90 const width = this.getRoundedViewportWidth(); 91 this.actions.recordTelemetryEvent("open_adbg", { width }); 92 93 await l10n.init([ 94 "branding/brand.ftl", 95 "devtools/client/aboutdebugging.ftl", 96 ]); 97 98 this.actions.createThisFirefoxRuntime(); 99 100 // Listen to Network locations updates and retrieve the initial list of locations. 101 addNetworkLocationsObserver(this.onNetworkLocationsUpdated); 102 await this.onNetworkLocationsUpdated(); 103 104 // Listen to USB runtime updates and retrieve the initial list of runtimes. 105 106 // If ADB is already started, wait for the initial runtime list to be able to restore 107 // already connected runtimes. 108 const isProcessStarted = await adb.isProcessStarted(); 109 const onAdbRuntimesReady = isProcessStarted 110 ? adb.once("runtime-list-ready") 111 : null; 112 addUSBRuntimesObserver(this.onUSBRuntimesUpdated); 113 await onAdbRuntimesReady; 114 115 await this.onUSBRuntimesUpdated(); 116 117 render( 118 Provider( 119 { 120 store: this.store, 121 }, 122 LocalizationProvider( 123 { bundles: l10n.getBundles() }, 124 Router({}, App({})) 125 ) 126 ), 127 this.mount 128 ); 129 130 adbAddon.on("update", this.onAdbAddonUpdated); 131 this.onAdbAddonUpdated(); 132 adbProcess.on("adb-ready", this.onAdbProcessReady); 133 // get the initial status of adb process, in case it's already started 134 this.onAdbProcessReady(); 135 }, 136 137 onAdbAddonUpdated() { 138 this.actions.updateAdbAddonStatus(adbAddon.status); 139 }, 140 141 onAdbProcessReady() { 142 this.actions.updateAdbReady(adbProcess.ready); 143 }, 144 145 onNetworkLocationsUpdated() { 146 return this.actions.updateNetworkLocations(getNetworkLocations()); 147 }, 148 149 async onUSBRuntimesUpdated() { 150 const runtimes = await getUSBRuntimes(); 151 return this.actions.updateUSBRuntimes(runtimes); 152 }, 153 154 async destroy() { 155 const width = this.getRoundedViewportWidth(); 156 this.actions.recordTelemetryEvent("close_adbg", { width }); 157 158 const state = this.store.getState(); 159 const currentRuntimeId = state.runtimes.selectedRuntimeId; 160 if (currentRuntimeId) { 161 await this.actions.unwatchRuntime(currentRuntimeId); 162 } 163 164 // Remove all client listeners. 165 this.actions.removeRuntimeListeners(); 166 167 // Prevents any further action from being dispatched 168 this.store.dispatch(START_IGNORE_ACTION); 169 170 removeNetworkLocationsObserver(this.onNetworkLocationsUpdated); 171 removeUSBRuntimesObserver(this.onUSBRuntimesUpdated); 172 adbAddon.off("update", this.onAdbAddonUpdated); 173 adbProcess.off("adb-ready", this.onAdbProcessReady); 174 setDebugTargetCollapsibilities(state.ui.debugTargetCollapsibilities); 175 unmountComponentAtNode(this.mount); 176 }, 177 178 get mount() { 179 return document.getElementById("mount"); 180 }, 181 182 /** 183 * Computed viewport width, rounded at 50px. Used for telemetry events. 184 */ 185 getRoundedViewportWidth() { 186 return Math.ceil(window.outerWidth / 50) * 50; 187 }, 188 }; 189 190 window.addEventListener( 191 "DOMContentLoaded", 192 () => { 193 AboutDebugging.init(); 194 }, 195 { once: true } 196 ); 197 198 window.addEventListener( 199 "unload", 200 () => { 201 AboutDebugging.destroy(); 202 }, 203 { once: true } 204 ); 205 206 // Expose AboutDebugging to tests so that they can access to the store. 207 window.AboutDebugging = AboutDebugging;