зеркало из https://github.com/mozilla/gecko-dev.git
Bug 895360 - [app manager] Device meta data actor. r=poirot.alex
This commit is contained in:
Родитель
95434b21b1
Коммит
0f07087e67
|
@ -997,6 +997,7 @@ let RemoteDebugger = {
|
|||
}
|
||||
DebuggerServer.addActors('chrome://browser/content/dbg-browser-actors.js');
|
||||
DebuggerServer.addActors("resource://gre/modules/devtools/server/actors/webapps.js");
|
||||
DebuggerServer.registerModule("devtools/server/actors/device");
|
||||
}
|
||||
|
||||
let port = Services.prefs.getIntPref('devtools.debugger.remote-port') || 6000;
|
||||
|
|
|
@ -0,0 +1,214 @@
|
|||
/* 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/. */
|
||||
|
||||
const {Cc, Ci, Cu} = require("chrome");
|
||||
const protocol = require("devtools/server/protocol");
|
||||
const {method, RetVal} = protocol;
|
||||
const promise = require("sdk/core/promise");
|
||||
const {LongStringActor} = require("devtools/server/actors/string");
|
||||
|
||||
Cu.import("resource://gre/modules/Services.jsm");
|
||||
Cu.import("resource://gre/modules/PermissionsTable.jsm")
|
||||
Cu.import('resource://gre/modules/devtools/dbg-server.jsm');
|
||||
|
||||
const APP_MAP = {
|
||||
'{ec8030f7-c20a-464f-9b0e-13a3a9e97384}': 'firefox',
|
||||
'{3550f703-e582-4d05-9a08-453d09bdfdc6}': 'thunderbird',
|
||||
'{92650c4d-4b8e-4d2a-b7eb-24ecf4f6b63a}': 'seamonkey',
|
||||
'{718e30fb-e89b-41dd-9da7-e25a45638b28}': 'sunbird',
|
||||
'{3c2e2abc-06d4-11e1-ac3b-374f68613e61}': 'b2g',
|
||||
'{aa3c5121-dab2-40e2-81ca-7ea25febc110}': 'mobile/android',
|
||||
'{a23983c0-fd0e-11dc-95ff-0800200c9a66}': 'mobile/xul'
|
||||
}
|
||||
|
||||
exports.register = function(handle) {
|
||||
handle.addGlobalActor(DeviceActor, "deviceActor");
|
||||
};
|
||||
|
||||
exports.unregister = function(handle) {
|
||||
};
|
||||
|
||||
let DeviceActor = protocol.ActorClass({
|
||||
typeName: "device",
|
||||
|
||||
_desc: null,
|
||||
|
||||
_getAppIniString : function(section, key) {
|
||||
let inifile = Services.dirsvc.get("GreD", Ci.nsIFile);
|
||||
inifile.append("application.ini");
|
||||
|
||||
if (!inifile.exists()) {
|
||||
inifile = Services.dirsvc.get("CurProcD", Ci.nsIFile);
|
||||
inifile.append("application.ini");
|
||||
}
|
||||
|
||||
if (!inifile.exists()) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
let iniParser = Cc["@mozilla.org/xpcom/ini-parser-factory;1"].getService(Ci.nsIINIParserFactory).createINIParser(inifile);
|
||||
try {
|
||||
return iniParser.getString(section, key);
|
||||
} catch (e) {
|
||||
return undefined;
|
||||
}
|
||||
},
|
||||
|
||||
_getSetting: function(name) {
|
||||
let deferred = promise.defer();
|
||||
if (Services.settings) {
|
||||
let req = Services.settings.createLock().get(name, {
|
||||
handle: (name, value) => deferred.resolve(value),
|
||||
handleError: (error) => deferred.reject(error),
|
||||
});
|
||||
} else {
|
||||
deferred.reject(new Error("No settings service"));
|
||||
}
|
||||
return deferred.promise;
|
||||
},
|
||||
|
||||
getDescription: method(function() {
|
||||
// Most of this code is inspired from Nightly Tester Tools:
|
||||
// https://wiki.mozilla.org/Auto-tools/Projects/NightlyTesterTools
|
||||
|
||||
let appInfo = Services.appinfo;
|
||||
let win = Services.wm.getMostRecentWindow(DebuggerServer.chromeWindowType);
|
||||
let utils = win.QueryInterface(Ci.nsIInterfaceRequestor).getInterface(Ci.nsIDOMWindowUtils);
|
||||
|
||||
desc = {
|
||||
appid: appInfo.ID,
|
||||
apptype: APP_MAP[appInfo.ID],
|
||||
vendor: appInfo.vendor,
|
||||
name: appInfo.name,
|
||||
version: appInfo.version,
|
||||
appbuildid: appInfo.appBuildID,
|
||||
platformbuildid: appInfo.platformBuildID,
|
||||
platformversion: appInfo.platformVersion,
|
||||
geckobuildid: appInfo.platformBuildID,
|
||||
geckoversion: appInfo.platformVersion,
|
||||
changeset: this._getAppIniString("App", "SourceStamp"),
|
||||
useragent: win.navigator.userAgent,
|
||||
locale: Cc["@mozilla.org/chrome/chrome-registry;1"].getService(Ci.nsIXULChromeRegistry).getSelectedLocale("global"),
|
||||
os: null,
|
||||
hardware: "unknown",
|
||||
processor: appInfo.XPCOMABI.split("-")[0],
|
||||
compiler: appInfo.XPCOMABI.split("-")[1],
|
||||
dpi: utils.displayDPI,
|
||||
brandName: null,
|
||||
channel: null,
|
||||
profile: null,
|
||||
width: win.screen.width,
|
||||
height: win.screen.height
|
||||
};
|
||||
|
||||
// Profile
|
||||
let profd = Services.dirsvc.get("ProfD", Ci.nsILocalFile);
|
||||
let profservice = Cc["@mozilla.org/toolkit/profile-service;1"].getService(Ci.nsIToolkitProfileService);
|
||||
var profiles = profservice.profiles;
|
||||
while (profiles.hasMoreElements()) {
|
||||
let profile = profiles.getNext().QueryInterface(Ci.nsIToolkitProfile);
|
||||
if (profile.rootDir.path == profd.path) {
|
||||
desc.profile = profile.name;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!desc.profile) {
|
||||
desc.profile = profd.leafName;
|
||||
}
|
||||
|
||||
// Channel
|
||||
try {
|
||||
desc.channel = Services.prefs.getCharPref('app.update.channel');
|
||||
} catch(e) {}
|
||||
|
||||
if (desc.apptype == "b2g") {
|
||||
// B2G specific
|
||||
desc.os = "B2G";
|
||||
|
||||
return this._getSetting('deviceinfo.hardware')
|
||||
.then(value => desc.hardware = value)
|
||||
.then(() => this._getSetting('deviceinfo.os'))
|
||||
.then(value => desc.version = value)
|
||||
.then(() => desc);
|
||||
}
|
||||
|
||||
// Not B2G
|
||||
desc.os = appInfo.OS;
|
||||
let bundle = Services.strings.createBundle("chrome://branding/locale/brand.properties");
|
||||
if (bundle) {
|
||||
desc.brandName = bundle.GetStringFromName("brandFullName");
|
||||
}
|
||||
|
||||
return desc;
|
||||
|
||||
}, {request: {},response: { value: RetVal("json")}}),
|
||||
|
||||
screenshotToDataURL: method(function() {
|
||||
let window = Services.wm.getMostRecentWindow(DebuggerServer.chromeWindowType);
|
||||
let canvas = window.document.createElementNS("http://www.w3.org/1999/xhtml", "canvas");
|
||||
let width = window.innerWidth;
|
||||
let height = window.innerHeight;
|
||||
canvas.setAttribute('width', width);
|
||||
canvas.setAttribute('height', height);
|
||||
let context = canvas.getContext('2d');
|
||||
let flags =
|
||||
context.DRAWWINDOW_DRAW_CARET |
|
||||
context.DRAWWINDOW_DRAW_VIEW |
|
||||
context.DRAWWINDOW_USE_WIDGET_LAYERS;
|
||||
context.drawWindow(window, 0, 0, width, height, 'rgb(255,255,255)', flags);
|
||||
let dataURL = canvas.toDataURL('image/png')
|
||||
return new LongStringActor(this.conn, dataURL);
|
||||
}, {request: {},response: { value: RetVal("longstring")}}),
|
||||
|
||||
getRawPermissionsTable: method(function() {
|
||||
return {
|
||||
rawPermissionsTable: PermissionsTable,
|
||||
UNKNOWN_ACTION: Ci.nsIPermissionManager.UNKNOWN_ACTION,
|
||||
ALLOW_ACTION: Ci.nsIPermissionManager.ALLOW_ACTION,
|
||||
DENY_ACTION: Ci.nsIPermissionManager.DENY_ACTION,
|
||||
PROMPT_ACTION: Ci.nsIPermissionManager.PROMPT_ACTION
|
||||
};
|
||||
}, {request: {},response: { value: RetVal("json")}})
|
||||
});
|
||||
|
||||
let DeviceFront = protocol.FrontClass(DeviceActor, {
|
||||
initialize: function(client, form) {
|
||||
protocol.Front.prototype.initialize.call(this, client);
|
||||
this.actorID = form.deviceActor;
|
||||
client.addActorPool(this);
|
||||
this.manage(this);
|
||||
},
|
||||
|
||||
screenshotToBlob: function() {
|
||||
return this.screenshotToDataURL().then(longstr => {
|
||||
return longstr.string().then(dataURL => {
|
||||
let deferred = promise.defer();
|
||||
longstr.release().then(null, Cu.reportError);
|
||||
let req = Cc["@mozilla.org/xmlextras/xmlhttprequest;1"].createInstance(Ci.nsIXMLHttpRequest);
|
||||
req.open("GET", dataURL, true);
|
||||
req.responseType = "blob";
|
||||
req.onload = () => {
|
||||
deferred.resolve(req.response);
|
||||
};
|
||||
req.onerror = () => {
|
||||
deferred.reject(req.status);
|
||||
}
|
||||
req.send();
|
||||
return deferred.promise;
|
||||
});
|
||||
});
|
||||
},
|
||||
});
|
||||
|
||||
const _knownDeviceFronts = new WeakMap();
|
||||
|
||||
exports.getDeviceFront = function(client, form) {
|
||||
if (_knownDeviceFronts.has(client))
|
||||
return _knownDeviceFronts.get(client);
|
||||
|
||||
let front = new DeviceFront(client, form);
|
||||
_knownDeviceFronts.set(client, front);
|
||||
return front;
|
||||
}
|
|
@ -303,6 +303,7 @@ var DebuggerServer = {
|
|||
this.addActors("resource://gre/modules/devtools/server/actors/webapps.js");
|
||||
this.registerModule("devtools/server/actors/inspector");
|
||||
this.registerModule("devtools/server/actors/tracer");
|
||||
this.registerModule("devtools/server/actors/device");
|
||||
},
|
||||
|
||||
/**
|
||||
|
|
|
@ -37,6 +37,7 @@ MOCHITEST_CHROME_FILES = \
|
|||
test_unsafeDereference.html \
|
||||
nonchrome_unsafeDereference.html \
|
||||
test_connection-manager.html \
|
||||
test_device.html \
|
||||
$(NULL)
|
||||
|
||||
include $(topsrcdir)/config/rules.mk
|
||||
|
|
|
@ -0,0 +1,97 @@
|
|||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<!--
|
||||
Bug 895360 - [app manager] Device meta data actor
|
||||
-->
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Mozilla Bug</title>
|
||||
<script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css">
|
||||
</head>
|
||||
<body>
|
||||
<pre id="test">
|
||||
<script>
|
||||
|
||||
window.onload = function() {
|
||||
var Cu = Components.utils;
|
||||
var Cc = Components.classes;
|
||||
var Ci = Components.interfaces;
|
||||
|
||||
Cu.import("resource://gre/modules/PermissionsTable.jsm");
|
||||
Cu.import("resource://gre/modules/devtools/Loader.jsm");
|
||||
Cu.import("resource://gre/modules/devtools/dbg-client.jsm");
|
||||
Cu.import("resource://gre/modules/devtools/dbg-server.jsm");
|
||||
Cu.import("resource://gre/modules/Services.jsm");
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
|
||||
var {getDeviceFront} = devtools.require("devtools/server/actors/device");
|
||||
|
||||
DebuggerServer.init(function () { return true; });
|
||||
DebuggerServer.addBrowserActors();
|
||||
|
||||
var client = new DebuggerClient(DebuggerServer.connectPipe());
|
||||
client.connect(function onConnect() {
|
||||
client.listTabs(function onListTabs(aResponse) {
|
||||
var d = getDeviceFront(client, aResponse);
|
||||
|
||||
var desc, permissions;
|
||||
var appInfo = Services.appinfo;
|
||||
var utils = window.QueryInterface(Ci.nsIInterfaceRequestor).getInterface(Ci.nsIDOMWindowUtils);
|
||||
|
||||
|
||||
var localDesc = {
|
||||
appid: appInfo.ID,
|
||||
vendor: appInfo.vendor,
|
||||
name: appInfo.name,
|
||||
version: appInfo.version,
|
||||
appbuildid: appInfo.appBuildID,
|
||||
platformbuildid: appInfo.platformBuildID,
|
||||
platformversion: appInfo.platformVersion,
|
||||
geckobuildid: appInfo.platformBuildID,
|
||||
geckoversion: appInfo.platformVersion,
|
||||
useragent: window.navigator.userAgent,
|
||||
locale: Cc["@mozilla.org/chrome/chrome-registry;1"].getService(Ci.nsIXULChromeRegistry).getSelectedLocale("global"),
|
||||
os: appInfo.OS,
|
||||
processor: appInfo.XPCOMABI.split("-")[0],
|
||||
compiler: appInfo.XPCOMABI.split("-")[1],
|
||||
dpi: utils.displayDPI,
|
||||
width: window.screen.width,
|
||||
height: window.screen.height
|
||||
}
|
||||
|
||||
function checkValues() {
|
||||
for (var key in localDesc) {
|
||||
is(desc[key], localDesc[key], "valid field (" + key + ")");
|
||||
}
|
||||
|
||||
var currProfD = Services.dirsvc.get("ProfD", Ci.nsIFile);
|
||||
var profileDir = currProfD.path;
|
||||
ok(profileDir.indexOf(desc.profile.length > 0 && desc.profile) != -1, "valid profile name");
|
||||
|
||||
var a = JSON.stringify(PermissionsTable);
|
||||
var b = JSON.stringify(permissions.rawPermissionsTable);
|
||||
|
||||
is(a, b, "Permissions Tables is valid");
|
||||
|
||||
client.close(() => {
|
||||
DebuggerServer.destroy();
|
||||
SimpleTest.finish()
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
d.getDescription().then((v) => desc = v)
|
||||
.then(() => d.getRawPermissionsTable())
|
||||
.then((json) => permissions = json)
|
||||
.then(checkValues);
|
||||
|
||||
});
|
||||
});
|
||||
|
||||
}
|
||||
</script>
|
||||
</pre>
|
||||
</body>
|
||||
</html>
|
Загрузка…
Ссылка в новой задаче