зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1452200 - 1c. Inject logging functions into GeckoView JS modules; r=snorp
Inject new logging functions, "debug" and "warn", into each GeckoView JS module that geckoview.js loads. Also do the same thing for frame script classes that extend from GeckoViewContentModule. The new logging functions are used with template literals (debug `hello ${foo} world`;), which are lazily evaluated, so disabled logs don't use as many CPU cycles. They can also be easily enabled/disabled. MozReview-Commit-ID: 7ZfYAMrcCyU --HG-- extra : rebase_source : 8a830f29ea1cabcdc5055fc86c9880a5216aa456
This commit is contained in:
Родитель
48885775a4
Коммит
9fd43f9378
|
@ -4,6 +4,10 @@
|
|||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm");
|
||||
ChromeUtils.import("resource://gre/modules/GeckoViewUtils.jsm");
|
||||
|
||||
/* global debug:false, warn:false */
|
||||
GeckoViewUtils.initLogging("GeckoView.ErrorPageEventHandler", this);
|
||||
|
||||
ChromeUtils.defineModuleGetter(this, "SSLExceptions",
|
||||
"resource://gre/modules/SSLExceptions.jsm");
|
||||
|
|
|
@ -197,4 +197,5 @@ class GeckoViewContent extends GeckoViewContentModule {
|
|||
}
|
||||
}
|
||||
|
||||
var contentListener = new GeckoViewContent("GeckoViewContent", this);
|
||||
let {debug, warn} = GeckoViewContent.initLogging("GeckoViewContent");
|
||||
let module = GeckoViewContent.create(this);
|
||||
|
|
|
@ -71,4 +71,5 @@ class GeckoViewContentSettings extends GeckoViewContentModule {
|
|||
}
|
||||
}
|
||||
|
||||
var settings = new GeckoViewContentSettings("GeckoViewSettings", this);
|
||||
let {debug, warn} = GeckoViewContentSettings.initLogging("GeckoViewSettings");
|
||||
let module = GeckoViewContentSettings.create(this);
|
||||
|
|
|
@ -47,4 +47,5 @@ class GeckoViewNavigationContent extends GeckoViewContentModule {
|
|||
}
|
||||
}
|
||||
|
||||
var navigationListener = new GeckoViewNavigationContent("GeckoViewNavigation", this);
|
||||
let {debug, warn} = GeckoViewNavigationContent.initLogging("GeckoViewNavigation");
|
||||
let module = GeckoViewNavigationContent.create(this);
|
||||
|
|
|
@ -43,4 +43,6 @@ class GeckoViewScrollContent extends GeckoViewContentModule {
|
|||
}
|
||||
}
|
||||
}
|
||||
var scrollListener = new GeckoViewScrollContent("GeckoViewScroll", this);
|
||||
|
||||
let {debug, warn} = GeckoViewScrollContent.initLogging("GeckoViewScroll");
|
||||
let module = GeckoViewScrollContent.create(this);
|
||||
|
|
|
@ -258,5 +258,6 @@ class GeckoViewSelectionActionContent extends GeckoViewContentModule {
|
|||
}
|
||||
}
|
||||
|
||||
var selectionActionListener =
|
||||
new GeckoViewSelectionActionContent("GeckoViewSelectionAction", this);
|
||||
let {debug, warn} =
|
||||
GeckoViewSelectionActionContent.initLogging("GeckoViewSelectionAction");
|
||||
let module = GeckoViewSelectionActionContent.create(this);
|
||||
|
|
|
@ -4,13 +4,14 @@
|
|||
|
||||
"use strict";
|
||||
|
||||
ChromeUtils.import("resource://gre/modules/AppConstants.jsm");
|
||||
ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm");
|
||||
|
||||
ChromeUtils.defineModuleGetter(this, "EventDispatcher",
|
||||
"resource://gre/modules/Messaging.jsm");
|
||||
ChromeUtils.defineModuleGetter(this, "Services",
|
||||
"resource://gre/modules/Services.jsm");
|
||||
XPCOMUtils.defineLazyModuleGetters(this, {
|
||||
EventDispatcher: "resource://gre/modules/Messaging.jsm",
|
||||
GeckoViewUtils: "resource://gre/modules/GeckoViewUtils.jsm",
|
||||
Services: "resource://gre/modules/Services.jsm",
|
||||
});
|
||||
|
||||
XPCOMUtils.defineLazyGetter(this, "WindowEventDispatcher",
|
||||
() => EventDispatcher.for(window));
|
||||
|
||||
|
@ -32,8 +33,11 @@ var ModuleManager = {
|
|||
|
||||
add: function(aResource, aType, ...aArgs) {
|
||||
this.remove(aType);
|
||||
let scope = {};
|
||||
ChromeUtils.import(aResource, scope);
|
||||
|
||||
const scope = {};
|
||||
const global = ChromeUtils.import(aResource, scope);
|
||||
const tag = aType.replace("GeckoView", "GeckoView.");
|
||||
GeckoViewUtils.initLogging(tag, global);
|
||||
|
||||
this.modules.set(aType, new scope[aType](
|
||||
aType, window, this.browser, WindowEventDispatcher, ...aArgs
|
||||
|
@ -58,6 +62,8 @@ function createBrowser() {
|
|||
}
|
||||
|
||||
function startup() {
|
||||
GeckoViewUtils.initLogging("GeckoView.XUL", window);
|
||||
|
||||
const browser = createBrowser();
|
||||
ModuleManager.init(browser);
|
||||
|
||||
|
|
|
@ -5,6 +5,10 @@
|
|||
"use strict";
|
||||
|
||||
ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm");
|
||||
ChromeUtils.import("resource://gre/modules/GeckoViewUtils.jsm");
|
||||
|
||||
/* global debug:false, warn:false */
|
||||
GeckoViewUtils.initLogging("GeckoView.ExternalAppService", this);
|
||||
|
||||
ChromeUtils.defineModuleGetter(this, "EventDispatcher",
|
||||
"resource://gre/modules/Messaging.jsm");
|
||||
|
|
|
@ -0,0 +1,8 @@
|
|||
"use strict";
|
||||
|
||||
module.exports = {
|
||||
"globals": {
|
||||
"debug": false,
|
||||
"warn": false,
|
||||
},
|
||||
};
|
|
@ -7,6 +7,9 @@
|
|||
var EXPORTED_SYMBOLS = ["GeckoViewContentModule"];
|
||||
|
||||
ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm");
|
||||
ChromeUtils.import("resource://gre/modules/GeckoViewUtils.jsm");
|
||||
|
||||
GeckoViewUtils.initLogging("GeckoView.Module.[C]", this);
|
||||
|
||||
ChromeUtils.defineModuleGetter(this, "EventDispatcher",
|
||||
"resource://gre/modules/Messaging.jsm");
|
||||
|
@ -20,6 +23,16 @@ XPCOMUtils.defineLazyGetter(this, "dump", () =>
|
|||
// }
|
||||
|
||||
class GeckoViewContentModule {
|
||||
static initLogging(aModuleName) {
|
||||
this._moduleName = aModuleName;
|
||||
const tag = aModuleName.replace("GeckoView", "GeckoView.") + ".[C]";
|
||||
return GeckoViewUtils.initLogging(tag, {});
|
||||
}
|
||||
|
||||
static create(aGlobal, aModuleName) {
|
||||
return new this(aModuleName || this._moduleName, aGlobal);
|
||||
}
|
||||
|
||||
constructor(aModuleName, aMessageManager) {
|
||||
this.moduleName = aModuleName;
|
||||
this.messageManager = aMessageManager;
|
||||
|
|
|
@ -7,6 +7,9 @@
|
|||
var EXPORTED_SYMBOLS = ["GeckoViewModule"];
|
||||
|
||||
ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm");
|
||||
ChromeUtils.import("resource://gre/modules/GeckoViewUtils.jsm");
|
||||
|
||||
GeckoViewUtils.initLogging("GeckoView.Module", this);
|
||||
|
||||
XPCOMUtils.defineLazyGetter(this, "dump", () =>
|
||||
ChromeUtils.import("resource://gre/modules/AndroidLog.jsm",
|
||||
|
|
|
@ -6,8 +6,9 @@
|
|||
ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm");
|
||||
|
||||
XPCOMUtils.defineLazyModuleGetters(this, {
|
||||
Services: "resource://gre/modules/Services.jsm",
|
||||
EventDispatcher: "resource://gre/modules/Messaging.jsm",
|
||||
Log: "resource://gre/modules/Log.jsm",
|
||||
Services: "resource://gre/modules/Services.jsm",
|
||||
});
|
||||
|
||||
var EXPORTED_SYMBOLS = ["GeckoViewUtils"];
|
||||
|
@ -252,6 +253,90 @@ var GeckoViewUtils = {
|
|||
}
|
||||
return null;
|
||||
},
|
||||
|
||||
/**
|
||||
* Add logging functions to the specified scope that forward to the given
|
||||
* Log.jsm logger. Currently "debug" and "warn" functions are supported. To
|
||||
* log something, call the function through a template literal:
|
||||
*
|
||||
* function foo(bar, baz) {
|
||||
* debug `hello world`;
|
||||
* debug `foo called with ${bar} as bar`;
|
||||
* warn `this is a warning for ${baz}`;
|
||||
* }
|
||||
*
|
||||
* An inline format can also be used for logging:
|
||||
*
|
||||
* let bar = 42;
|
||||
* do_something(bar); // No log.
|
||||
* do_something(debug.foo = bar); // Output "foo = 42" to the log.
|
||||
*
|
||||
* @param tag Name of the Log.jsm logger to forward logs to.
|
||||
* @param scope Scope to add the logging functions to.
|
||||
*/
|
||||
initLogging: function(tag, scope) {
|
||||
// Only provide two levels for simplicity.
|
||||
// For "info", use "debug" instead.
|
||||
// For "error", throw an actual JS error instead.
|
||||
for (const level of ["debug", "warn"]) {
|
||||
const log = (strings, ...exprs) =>
|
||||
this._log(log.logger, level, strings, exprs);
|
||||
|
||||
XPCOMUtils.defineLazyGetter(log, "logger", _ => {
|
||||
const logger = Log.repository.getLogger(tag);
|
||||
logger.parent = this.rootLogger;
|
||||
return logger;
|
||||
});
|
||||
|
||||
scope[level] = new Proxy(log, {
|
||||
set: (obj, prop, value) => obj([prop + " = ", ""], value) || true,
|
||||
});
|
||||
}
|
||||
return scope;
|
||||
},
|
||||
|
||||
get rootLogger() {
|
||||
if (!this._rootLogger) {
|
||||
this._rootLogger = Log.repository.getLogger("GeckoView");
|
||||
this._rootLogger.addAppender(new Log.AndroidAppender());
|
||||
}
|
||||
return this._rootLogger;
|
||||
},
|
||||
|
||||
_log: function(logger, level, strings, exprs) {
|
||||
if (!Array.isArray(strings)) {
|
||||
const [, file, line] =
|
||||
(new Error()).stack.match(/.*\n.*\n.*@(.*):(\d+):/);
|
||||
throw Error(`Expecting template literal: ${level} \`foo \${bar}\``,
|
||||
file, +line);
|
||||
}
|
||||
|
||||
// Do some GeckoView-specific formatting:
|
||||
// 1) Heuristically format flags as hex.
|
||||
// 2) Heuristically format nsresult as string name or hex.
|
||||
for (let i = 0; i < exprs.length; i++) {
|
||||
const expr = exprs[i];
|
||||
switch (typeof expr) {
|
||||
case "number":
|
||||
if (expr > 0 && /\ba?[fF]lags?[\s=:]+$/.test(strings[i])) {
|
||||
// Likely a flag; display in hex.
|
||||
exprs[i] = `0x${expr.toString(0x10)}`;
|
||||
} else if (expr >= 0 && /\b(a?[sS]tatus|rv)[\s=:]+$/.test(strings[i])) {
|
||||
// Likely an nsresult; display in name or hex.
|
||||
exprs[i] = `0x${expr.toString(0x10)}`;
|
||||
for (const name in Cr) {
|
||||
if (expr === Cr[name]) {
|
||||
exprs[i] = name;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return logger[level](strings, ...exprs);
|
||||
},
|
||||
};
|
||||
|
||||
XPCOMUtils.defineLazyGetter(GeckoViewUtils, "IS_PARENT_PROCESS", _ =>
|
||||
|
|
Загрузка…
Ссылка в новой задаче