/* 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";
const {
bindActionCreators,
} = require(
"resource://devtools/client/shared/vendor/redux.js");
const {
createFactory,
} = require(
"resource://devtools/client/shared/vendor/react.js");
const {
render,
unmountComponentAtNode,
} = require(
"resource://devtools/client/shared/vendor/react-dom.js");
const Provider = createFactory(
require(
"resource://devtools/client/shared/vendor/react-redux.js").Provider
);
const FluentReact = require(
"resource://devtools/client/shared/vendor/fluent-react.js");
const LocalizationProvider = createFactory(FluentReact.LocalizationProvider);
const actions = require(
"resource://devtools/client/aboutdebugging/src/actions/index.js");
const {
configureStore,
} = require(
"resource://devtools/client/aboutdebugging/src/create-store.js");
const {
setDebugTargetCollapsibilities,
} = require(
"resource://devtools/client/aboutdebugging/src/modules/debug-target-collapsibilities.js");
const {
l10n,
} = require(
"resource://devtools/client/aboutdebugging/src/modules/l10n.js");
const {
addNetworkLocationsObserver,
getNetworkLocations,
removeNetworkLocationsObserver,
} = require(
"resource://devtools/client/aboutdebugging/src/modules/network-locations.js");
const {
addUSBRuntimesObserver,
getUSBRuntimes,
removeUSBRuntimesObserver,
} = require(
"resource://devtools/client/aboutdebugging/src/modules/usb-runtimes.js");
loader.lazyRequireGetter(
this,
"adb",
"resource://devtools/client/shared/remote-debugging/adb/adb.js",
true
);
loader.lazyRequireGetter(
this,
"adbAddon",
"resource://devtools/client/shared/remote-debugging/adb/adb-addon.js",
true
);
loader.lazyRequireGetter(
this,
"adbProcess",
"resource://devtools/client/shared/remote-debugging/adb/adb-process.js",
true
);
const Router = createFactory(
require(
"resource://devtools/client/shared/vendor/react-router-dom.js")
.HashRouter
);
const App = createFactory(
require(
"resource://devtools/client/aboutdebugging/src/components/App.js")
);
const AboutDebugging = {
async init() {
const direction = Services.locale.isAppLocaleRTL ?
"rtl" :
"ltr";
document.documentElement.setAttribute(
"dir", direction);
this.onAdbAddonUpdated =
this.onAdbAddonUpdated.bind(
this);
this.onAdbProcessReady =
this.onAdbProcessReady.bind(
this);
this.onNetworkLocationsUpdated =
this.onNetworkLocationsUpdated.bind(
this);
this.onUSBRuntimesUpdated =
this.onUSBRuntimesUpdated.bind(
this);
this.store = configureStore();
this.actions = bindActionCreators(actions,
this.store.dispatch);
const width =
this.getRoundedViewportWidth();
this.actions.recordTelemetryEvent(
"open_adbg", { width });
await l10n.init([
"branding/brand.ftl",
"devtools/client/aboutdebugging.ftl",
]);
this.actions.createThisFirefoxRuntime();
// Listen to Network locations updates and retrieve the initial list of locations.
addNetworkLocationsObserver(
this.onNetworkLocationsUpdated);
await
this.onNetworkLocationsUpdated();
// Listen to USB runtime updates and retrieve the initial list of runtimes.
// If ADB is already started, wait for the initial runtime list to be able to restore
// already connected runtimes.
const isProcessStarted = await adb.isProcessStarted();
const onAdbRuntimesReady = isProcessStarted
? adb.once(
"runtime-list-ready")
:
null;
addUSBRuntimesObserver(
this.onUSBRuntimesUpdated);
await onAdbRuntimesReady;
await
this.onUSBRuntimesUpdated();
render(
Provider(
{
store:
this.store,
},
LocalizationProvider(
{ bundles: l10n.getBundles() },
Router({}, App({}))
)
),
this.mount
);
adbAddon.on(
"update",
this.onAdbAddonUpdated);
this.onAdbAddonUpdated();
adbProcess.on(
"adb-ready",
this.onAdbProcessReady);
// get the initial status of adb process, in case it's already started
this.onAdbProcessReady();
},
onAdbAddonUpdated() {
this.actions.updateAdbAddonStatus(adbAddon.status);
},
onAdbProcessReady() {
this.actions.updateAdbReady(adbProcess.ready);
},
onNetworkLocationsUpdated() {
return this.actions.updateNetworkLocations(getNetworkLocations());
},
async onUSBRuntimesUpdated() {
const runtimes = await getUSBRuntimes();
return this.actions.updateUSBRuntimes(runtimes);
},
async destroy() {
const width =
this.getRoundedViewportWidth();
this.actions.recordTelemetryEvent(
"close_adbg", { width });
const state =
this.store.getState();
const currentRuntimeId = state.runtimes.selectedRuntimeId;
if (currentRuntimeId) {
await
this.actions.unwatchRuntime(currentRuntimeId);
}
// Remove all client listeners.
this.actions.removeRuntimeListeners();
removeNetworkLocationsObserver(
this.onNetworkLocationsUpdated);
removeUSBRuntimesObserver(
this.onUSBRuntimesUpdated);
adbAddon.off(
"update",
this.onAdbAddonUpdated);
adbProcess.off(
"adb-ready",
this.onAdbProcessReady);
setDebugTargetCollapsibilities(state.ui.debugTargetCollapsibilities);
unmountComponentAtNode(
this.mount);
},
get mount() {
return document.getElementById(
"mount");
},
/**
* Computed viewport width, rounded at 50px. Used for telemetry events.
*/
getRoundedViewportWidth() {
return Math.ceil(window.outerWidth / 50) * 50;
},
};
window.addEventListener(
"DOMContentLoaded",
() => {
AboutDebugging.init();
},
{ once:
true }
);
window.addEventListener(
"unload",
() => {
AboutDebugging.destroy();
},
{ once:
true }
);
// Expose AboutDebugging to tests so that they can access to the store.
window.AboutDebugging = AboutDebugging;