2014-06-25 09:12:07 +04:00
|
|
|
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- /
|
2012-06-07 15:17:59 +04:00
|
|
|
/* vim: set shiftwidth=2 tabstop=2 autoindent cindent expandtab: */
|
|
|
|
/* 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';
|
|
|
|
|
|
|
|
/**
|
|
|
|
* This code exists to be a "grab bag" of global code that needs to be
|
|
|
|
* loaded per B2G process, but doesn't need to directly interact with
|
|
|
|
* web content.
|
|
|
|
*
|
|
|
|
* (It's written as an XPCOM service because it needs to watch
|
|
|
|
* app-startup.)
|
|
|
|
*/
|
|
|
|
|
|
|
|
const Cc = Components.classes;
|
|
|
|
const Ci = Components.interfaces;
|
|
|
|
const Cu = Components.utils;
|
|
|
|
|
|
|
|
Cu.import('resource://gre/modules/Services.jsm');
|
|
|
|
Cu.import('resource://gre/modules/XPCOMUtils.jsm');
|
|
|
|
|
2014-11-26 14:46:00 +03:00
|
|
|
XPCOMUtils.defineLazyServiceGetter(this, "settings",
|
|
|
|
"@mozilla.org/settingsService;1",
|
|
|
|
"nsISettingsService");
|
|
|
|
|
2012-06-07 15:17:59 +04:00
|
|
|
function debug(msg) {
|
|
|
|
log(msg);
|
|
|
|
}
|
|
|
|
function log(msg) {
|
|
|
|
// This file implements console.log(), so use dump().
|
|
|
|
//dump('ProcessGlobal: ' + msg + '\n');
|
|
|
|
}
|
|
|
|
|
2014-09-13 01:02:54 +04:00
|
|
|
function formatStackFrame(aFrame) {
|
|
|
|
let functionName = aFrame.functionName || '<anonymous>';
|
|
|
|
return ' at ' + functionName +
|
2014-09-23 02:07:42 +04:00
|
|
|
' (' + aFrame.filename + ':' + aFrame.lineNumber +
|
|
|
|
':' + aFrame.columnNumber + ')';
|
2014-09-13 01:02:54 +04:00
|
|
|
}
|
|
|
|
|
2014-09-23 02:33:15 +04:00
|
|
|
function ConsoleMessage(aMsg, aLevel) {
|
|
|
|
this.timeStamp = Date.now();
|
|
|
|
this.msg = aMsg;
|
|
|
|
|
|
|
|
switch (aLevel) {
|
|
|
|
case 'error':
|
|
|
|
case 'assert':
|
|
|
|
this.logLevel = Ci.nsIConsoleMessage.error;
|
|
|
|
break;
|
|
|
|
case 'warn':
|
|
|
|
this.logLevel = Ci.nsIConsoleMessage.warn;
|
|
|
|
break;
|
|
|
|
case 'log':
|
|
|
|
case 'info':
|
|
|
|
this.logLevel = Ci.nsIConsoleMessage.info;
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
this.logLevel = Ci.nsIConsoleMessage.debug;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-06-02 21:11:52 +03:00
|
|
|
function toggleUnrestrictedDevtools(unrestricted) {
|
|
|
|
Services.prefs.setBoolPref("devtools.debugger.forbid-certified-apps",
|
|
|
|
!unrestricted);
|
|
|
|
Services.prefs.setBoolPref("dom.apps.developer_mode", unrestricted);
|
|
|
|
// TODO: Remove once bug 1125916 is fixed.
|
|
|
|
Services.prefs.setBoolPref("network.disable.ipc.security", unrestricted);
|
|
|
|
Services.prefs.setBoolPref("dom.webcomponents.enabled", unrestricted);
|
|
|
|
let lock = settings.createLock();
|
|
|
|
lock.set("developer.menu.enabled", unrestricted, null);
|
|
|
|
lock.set("devtools.unrestricted", unrestricted, null);
|
|
|
|
}
|
|
|
|
|
2014-09-23 02:33:15 +04:00
|
|
|
ConsoleMessage.prototype = {
|
|
|
|
QueryInterface: XPCOMUtils.generateQI([Ci.nsIConsoleMessage]),
|
|
|
|
toString: function() { return this.msg; }
|
|
|
|
};
|
|
|
|
|
2014-10-01 10:11:44 +04:00
|
|
|
const gFactoryResetFile = "__post_reset_cmd__";
|
2014-07-18 05:30:47 +04:00
|
|
|
|
2012-06-07 15:17:59 +04:00
|
|
|
function ProcessGlobal() {}
|
|
|
|
ProcessGlobal.prototype = {
|
|
|
|
classID: Components.ID('{1a94c87a-5ece-4d11-91e1-d29c29f21b28}'),
|
|
|
|
QueryInterface: XPCOMUtils.generateQI([Ci.nsIObserver,
|
|
|
|
Ci.nsISupportsWeakReference]),
|
|
|
|
|
2014-07-18 05:30:47 +04:00
|
|
|
wipeDir: function(path) {
|
|
|
|
log("wipeDir " + path);
|
|
|
|
let dir = Cc["@mozilla.org/file/local;1"].createInstance(Ci.nsIFile);
|
|
|
|
dir.initWithPath(path);
|
|
|
|
if (!dir.exists() || !dir.isDirectory()) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
let entries = dir.directoryEntries;
|
|
|
|
while (entries.hasMoreElements()) {
|
|
|
|
let file = entries.getNext().QueryInterface(Ci.nsIFile);
|
|
|
|
log("Deleting " + file.path);
|
|
|
|
try {
|
|
|
|
file.remove(true);
|
|
|
|
} catch(e) {}
|
|
|
|
}
|
|
|
|
},
|
|
|
|
|
2014-11-26 14:46:00 +03:00
|
|
|
processCommandsFile: function(text) {
|
|
|
|
log("processCommandsFile " + text);
|
2014-07-18 05:30:47 +04:00
|
|
|
let lines = text.split("\n");
|
|
|
|
lines.forEach((line) => {
|
|
|
|
log(line);
|
|
|
|
let params = line.split(" ");
|
2015-06-02 21:11:52 +03:00
|
|
|
switch (params[0]) {
|
|
|
|
case "root":
|
|
|
|
log("unrestrict devtools");
|
|
|
|
toggleUnrestrictedDevtools(true);
|
|
|
|
break;
|
|
|
|
case "wipe":
|
|
|
|
this.wipeDir(params[1]);
|
|
|
|
case "normal":
|
|
|
|
log("restrict devtools");
|
|
|
|
toggleUnrestrictedDevtools(false);
|
|
|
|
break;
|
2014-07-18 05:30:47 +04:00
|
|
|
}
|
|
|
|
});
|
|
|
|
},
|
|
|
|
|
|
|
|
cleanupAfterFactoryReset: function() {
|
|
|
|
log("cleanupAfterWipe start");
|
|
|
|
|
2014-10-01 10:11:44 +04:00
|
|
|
Cu.import("resource://gre/modules/osfile.jsm");
|
|
|
|
let dir = Cc["@mozilla.org/file/local;1"].createInstance(Ci.nsIFile);
|
|
|
|
dir.initWithPath("/persist");
|
|
|
|
var postResetFile = dir.exists() ?
|
|
|
|
OS.Path.join("/persist", gFactoryResetFile):
|
|
|
|
OS.Path.join("/cache", gFactoryResetFile);
|
2014-07-18 05:30:47 +04:00
|
|
|
let file = Cc["@mozilla.org/file/local;1"].createInstance(Ci.nsIFile);
|
2014-10-01 10:11:44 +04:00
|
|
|
file.initWithPath(postResetFile);
|
2014-07-18 05:30:47 +04:00
|
|
|
if (!file.exists()) {
|
2014-11-26 14:46:00 +03:00
|
|
|
debug("No additional command.")
|
2014-07-18 05:30:47 +04:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2014-10-01 10:11:44 +04:00
|
|
|
let promise = OS.File.read(postResetFile);
|
2014-07-18 05:30:47 +04:00
|
|
|
promise.then(
|
|
|
|
(array) => {
|
|
|
|
file.remove(false);
|
|
|
|
let decoder = new TextDecoder();
|
2014-11-26 14:46:00 +03:00
|
|
|
this.processCommandsFile(decoder.decode(array));
|
2014-10-01 10:11:44 +04:00
|
|
|
},
|
|
|
|
function onError(error) {
|
|
|
|
debug("Error: " + error);
|
2014-07-18 05:30:47 +04:00
|
|
|
}
|
|
|
|
);
|
|
|
|
|
|
|
|
log("cleanupAfterWipe end.");
|
|
|
|
},
|
|
|
|
|
2012-06-07 15:17:59 +04:00
|
|
|
observe: function pg_observe(subject, topic, data) {
|
|
|
|
switch (topic) {
|
|
|
|
case 'app-startup': {
|
|
|
|
Services.obs.addObserver(this, 'console-api-log-event', false);
|
2014-05-26 12:39:00 +04:00
|
|
|
let inParent = Cc["@mozilla.org/xre/app-info;1"]
|
|
|
|
.getService(Ci.nsIXULRuntime)
|
|
|
|
.processType == Ci.nsIXULRuntime.PROCESS_TYPE_DEFAULT;
|
|
|
|
if (inParent) {
|
2015-08-15 02:55:09 +03:00
|
|
|
Services.ppmm.addMessageListener("getProfD", function(message) {
|
2014-05-26 12:39:00 +04:00
|
|
|
return Services.dirsvc.get("ProfD", Ci.nsIFile).path;
|
|
|
|
});
|
2014-07-18 05:30:47 +04:00
|
|
|
|
|
|
|
this.cleanupAfterFactoryReset();
|
2014-05-26 12:39:00 +04:00
|
|
|
}
|
2012-06-07 15:17:59 +04:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
case 'console-api-log-event': {
|
|
|
|
// Pipe `console` log messages to the nsIConsoleService which
|
|
|
|
// writes them to logcat on Gonk.
|
|
|
|
let message = subject.wrappedJSObject;
|
2014-09-13 01:02:54 +04:00
|
|
|
let args = message.arguments;
|
|
|
|
let stackTrace = '';
|
|
|
|
|
2015-04-03 23:45:42 +03:00
|
|
|
if (message.stacktrace &&
|
|
|
|
(message.level == 'assert' || message.level == 'error' || message.level == 'trace')) {
|
2014-09-13 01:02:54 +04:00
|
|
|
stackTrace = Array.map(message.stacktrace, formatStackFrame).join('\n');
|
|
|
|
} else {
|
|
|
|
stackTrace = formatStackFrame(message);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (stackTrace) {
|
|
|
|
args.push('\n' + stackTrace);
|
|
|
|
}
|
|
|
|
|
2014-09-23 02:33:15 +04:00
|
|
|
let msg = 'Content JS ' + message.level.toUpperCase() + ': ' + Array.join(args, ' ');
|
|
|
|
Services.console.logMessage(new ConsoleMessage(msg, message.level));
|
2012-06-07 15:17:59 +04:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
},
|
|
|
|
};
|
|
|
|
|
2012-10-31 20:13:28 +04:00
|
|
|
this.NSGetFactory = XPCOMUtils.generateNSGetFactory([ProcessGlobal]);
|