This commit is contained in:
Ryan VanderMeulen 2013-12-10 15:46:02 -05:00
Родитель c3a9915a32 2b769f4918
Коммит 5e8271d74b
212 изменённых файлов: 2770 добавлений и 2983 удалений

Просмотреть файл

@ -621,7 +621,7 @@ TextAttrsMgr::FontWeightTextAttr::
if (font->IsSyntheticBold()) if (font->IsSyntheticBold())
return 700; return 700;
#ifdef MOZ_PANGO #if defined(MOZ_WIDGET_GTK) || defined(MOZ_WIDGET_QT)
// On Linux, font->GetStyle()->weight will give the absolute weight requested // On Linux, font->GetStyle()->weight will give the absolute weight requested
// of the font face. The Linux code uses the gfxFontEntry constructor which // of the font face. The Linux code uses the gfxFontEntry constructor which
// doesn't initialize the weight field. // doesn't initialize the weight field.

Просмотреть файл

@ -377,11 +377,7 @@ function getPotentialLeaks() {
let mgr = Cc["@mozilla.org/memory-reporter-manager;1"]. let mgr = Cc["@mozilla.org/memory-reporter-manager;1"].
getService(Ci.nsIMemoryReporterManager); getService(Ci.nsIMemoryReporterManager);
let enm = mgr.enumerateReporters(); mgr.getReportsForThisProcess(logReporter, null);
while (enm.hasMoreElements()) {
let mr = enm.getNext().QueryInterface(Ci.nsIMemoryReporter);
mr.collectReports(logReporter, null);
}
return { compartments: compartments, windows: windows }; return { compartments: compartments, windows: windows };
} }

Просмотреть файл

@ -5,7 +5,7 @@
"use strict" "use strict"
function debug(str) { function debug(str) {
//dump("-*- ContentPermissionPrompt: " + str + "\n"); //dump("-*- ContentPermissionPrompt: " + s + "\n");
} }
const Ci = Components.interfaces; const Ci = Components.interfaces;
@ -13,14 +13,11 @@ const Cr = Components.results;
const Cu = Components.utils; const Cu = Components.utils;
const Cc = Components.classes; const Cc = Components.classes;
const PROMPT_FOR_UNKNOWN = ["audio-capture", const PROMPT_FOR_UNKNOWN = ["geolocation", "desktop-notification",
"desktop-notification", "audio-capture"];
"geolocation",
"video-capture"];
// Due to privary issue, permission requests like GetUserMedia should prompt // Due to privary issue, permission requests like GetUserMedia should prompt
// every time instead of providing session persistence. // every time instead of providing session persistence.
const PERMISSION_NO_SESSION = ["audio-capture", "video-capture"]; const PERMISSION_NO_SESSION = ["audio-capture"];
const ALLOW_MULTIPLE_REQUESTS = ["audio-capture", "video-capture"];
Cu.import("resource://gre/modules/XPCOMUtils.jsm"); Cu.import("resource://gre/modules/XPCOMUtils.jsm");
Cu.import("resource://gre/modules/Services.jsm"); Cu.import("resource://gre/modules/Services.jsm");
@ -44,21 +41,7 @@ XPCOMUtils.defineLazyServiceGetter(this,
"@mozilla.org/telephony/audiomanager;1", "@mozilla.org/telephony/audiomanager;1",
"nsIAudioManager"); "nsIAudioManager");
/** function rememberPermission(aPermission, aPrincipal, aSession)
* aTypesInfo is an array of {permission, access, action, deny} which keeps
* the information of each permission. This arrary is initialized in
* ContentPermissionPrompt.prompt and used among functions.
*
* aTypesInfo[].permission : permission name
* aTypesInfo[].access : permission name + request.access
* aTypesInfo[].action : the default action of this permission
* aTypesInfo[].deny : true if security manager denied this app's origin
* principal.
* Note:
* aTypesInfo[].permission will be sent to prompt only when
* aTypesInfo[].action is PROMPT_ACTION and aTypesInfo[].deny is false.
*/
function rememberPermission(aTypesInfo, aPrincipal, aSession)
{ {
function convertPermToAllow(aPerm, aPrincipal) function convertPermToAllow(aPerm, aPrincipal)
{ {
@ -66,13 +49,12 @@ function rememberPermission(aTypesInfo, aPrincipal, aSession)
permissionManager.testExactPermissionFromPrincipal(aPrincipal, aPerm); permissionManager.testExactPermissionFromPrincipal(aPrincipal, aPerm);
if (type == Ci.nsIPermissionManager.PROMPT_ACTION || if (type == Ci.nsIPermissionManager.PROMPT_ACTION ||
(type == Ci.nsIPermissionManager.UNKNOWN_ACTION && (type == Ci.nsIPermissionManager.UNKNOWN_ACTION &&
PROMPT_FOR_UNKNOWN.indexOf(aPerm) >= 0)) { PROMPT_FOR_UNKNOWN.indexOf(aPermission) >= 0)) {
debug("add " + aPerm + " to permission manager with ALLOW_ACTION");
if (!aSession) { if (!aSession) {
permissionManager.addFromPrincipal(aPrincipal, permissionManager.addFromPrincipal(aPrincipal,
aPerm, aPerm,
Ci.nsIPermissionManager.ALLOW_ACTION); Ci.nsIPermissionManager.ALLOW_ACTION);
} else if (PERMISSION_NO_SESSION.indexOf(aPerm) < 0) { } else if (PERMISSION_NO_SESSION.indexOf(aPermission) < 0) {
permissionManager.addFromPrincipal(aPrincipal, permissionManager.addFromPrincipal(aPrincipal,
aPerm, aPerm,
Ci.nsIPermissionManager.ALLOW_ACTION, Ci.nsIPermissionManager.ALLOW_ACTION,
@ -81,18 +63,14 @@ function rememberPermission(aTypesInfo, aPrincipal, aSession)
} }
} }
for (let i in aTypesInfo) { // Expand the permission to see if we have multiple access properties to convert
// Expand the permission to see if we have multiple access properties let access = PermissionsTable[aPermission].access;
// to convert if (access) {
let perm = aTypesInfo[i].permission; for (let idx in access) {
let access = PermissionsTable[perm].access; convertPermToAllow(aPermission + "-" + access[idx], aPrincipal);
if (access) {
for (let idx in access) {
convertPermToAllow(perm + "-" + access[idx], aPrincipal);
}
} else {
convertPermToAllow(perm, aPrincipal);
} }
} else {
convertPermToAllow(aPermission, aPrincipal);
} }
} }
@ -100,66 +78,23 @@ function ContentPermissionPrompt() {}
ContentPermissionPrompt.prototype = { ContentPermissionPrompt.prototype = {
handleExistingPermission: function handleExistingPermission(request, handleExistingPermission: function handleExistingPermission(request) {
typesInfo) { let access = (request.access && request.access !== "unused") ? request.type + "-" + request.access :
typesInfo.forEach(function(type) { request.type;
type.action = let result = Services.perms.testExactPermissionFromPrincipal(request.principal, access);
Services.perms.testExactPermissionFromPrincipal(request.principal, if (result == Ci.nsIPermissionManager.ALLOW_ACTION) {
type.access);
if (type.action == Ci.nsIPermissionManager.UNKNOWN_ACTION &&
PROMPT_FOR_UNKNOWN.indexOf(type.access) >= 0) {
type.action = Ci.nsIPermissionManager.PROMPT_ACTION;
}
});
// If all permissions are allowed already, call allow() without prompting.
let checkAllowPermission = function(type) {
if (type.action == Ci.nsIPermissionManager.ALLOW_ACTION) {
return true;
}
return false;
}
if (typesInfo.every(checkAllowPermission)) {
debug("all permission requests are allowed");
request.allow(); request.allow();
return true; return true;
} }
if (result == Ci.nsIPermissionManager.DENY_ACTION ||
// If all permissions are DENY_ACTION or UNKNOWN_ACTION, call cancel() result == Ci.nsIPermissionManager.UNKNOWN_ACTION && PROMPT_FOR_UNKNOWN.indexOf(access) < 0) {
// without prompting.
let checkDenyPermission = function(type) {
if (type.action == Ci.nsIPermissionManager.DENY_ACTION ||
type.action == Ci.nsIPermissionManager.UNKNOWN_ACTION) {
return true;
}
return false;
}
if (typesInfo.every(checkDenyPermission)) {
debug("all permission requests are denied");
request.cancel(); request.cancel();
return true; return true;
} }
return false; return false;
}, },
// multiple requests should be audio and video handledByApp: function handledByApp(request) {
checkMultipleRequest: function checkMultipleRequest(typesInfo) {
if (typesInfo.length == 1) {
return true;
} else if (typesInfo.length > 1) {
let checkIfAllowMultiRequest = function(type) {
return (ALLOW_MULTIPLE_REQUESTS.indexOf(type.access) !== -1);
}
if (typesInfo.every(checkIfAllowMultiRequest)) {
debug("legal multiple requests");
return true;
}
}
return false;
},
handledByApp: function handledByApp(request, typesInfo) {
if (request.principal.appId == Ci.nsIScriptSecurityManager.NO_APP_ID || if (request.principal.appId == Ci.nsIScriptSecurityManager.NO_APP_ID ||
request.principal.appId == Ci.nsIScriptSecurityManager.UNKNOWN_APP_ID) { request.principal.appId == Ci.nsIScriptSecurityManager.UNKNOWN_APP_ID) {
// This should not really happen // This should not really happen
@ -171,94 +106,49 @@ ContentPermissionPrompt.prototype = {
.getService(Ci.nsIAppsService); .getService(Ci.nsIAppsService);
let app = appsService.getAppByLocalId(request.principal.appId); let app = appsService.getAppByLocalId(request.principal.appId);
// Check each permission if it's denied by permission manager with app's let url = Services.io.newURI(app.origin, null, null);
// URL. let principal = secMan.getAppCodebasePrincipal(url, request.principal.appId,
let notDenyAppPrincipal = function(type) { /*mozbrowser*/false);
let url = Services.io.newURI(app.origin, null, null); let access = (request.access && request.access !== "unused") ? request.type + "-" + request.access :
let principal = secMan.getAppCodebasePrincipal(url, request.type;
request.principal.appId, let result = Services.perms.testExactPermissionFromPrincipal(principal, access);
/*mozbrowser*/false);
let result = Services.perms.testExactPermissionFromPrincipal(principal,
type.access);
if (result == Ci.nsIPermissionManager.ALLOW_ACTION || if (result == Ci.nsIPermissionManager.ALLOW_ACTION ||
result == Ci.nsIPermissionManager.PROMPT_ACTION) { result == Ci.nsIPermissionManager.PROMPT_ACTION) {
type.deny = false; return false;
}
return !type.deny;
}
if (typesInfo.filter(notDenyAppPrincipal).length === 0) {
request.cancel();
return true;
} }
return false; request.cancel();
return true;
}, },
handledByPermissionType: function handledByPermissionType(request, typesInfo) { handledByPermissionType: function handledByPermissionType(request) {
for (let i in typesInfo) { return permissionSpecificChecker.hasOwnProperty(request.type)
if (permissionSpecificChecker.hasOwnProperty(typesInfo[i].permission) && ? permissionSpecificChecker[request.type](request)
permissionSpecificChecker[typesInfo[i].permission](request)) { : false;
return true;
}
}
return false;
}, },
_id: 0, _id: 0,
prompt: function(request) { prompt: function(request) {
if (secMan.isSystemPrincipal(request.principal)) { if (secMan.isSystemPrincipal(request.principal)) {
request.allow(); request.allow();
return; return true;
} }
// Initialize the typesInfo and set the default value. if (this.handledByApp(request) ||
let typesInfo = []; this.handledByPermissionType(request)) {
let perms = request.types.QueryInterface(Ci.nsIArray);
for (let idx = 0; idx < perms.length; idx++) {
let perm = perms.queryElementAt(idx, Ci.nsIContentPermissionType);
let tmp = {
permission: perm.type,
access: (perm.access && perm.access !== "unused") ?
perm.type + "-" + perm.access : perm.type,
deny: true,
action: Ci.nsIPermissionManager.UNKNOWN_ACTION
};
typesInfo.push(tmp);
}
if (typesInfo.length == 0) {
request.cancel();
return;
}
if(!this.checkMultipleRequest(typesInfo)) {
request.cancel();
return;
}
if (this.handledByApp(request, typesInfo) ||
this.handledByPermissionType(request, typesInfo)) {
return; return;
} }
// returns true if the request was handled // returns true if the request was handled
if (this.handleExistingPermission(request, typesInfo)) { if (this.handleExistingPermission(request))
return; return;
}
// prompt PROMPT_ACTION request only.
typesInfo.forEach(function(aType, aIndex) {
if (aType.action != Ci.nsIPermissionManager.PROMPT_ACTION || aType.deny) {
typesInfo.splice(aIndex);
}
});
let frame = request.element; let frame = request.element;
let requestId = this._id++; let requestId = this._id++;
if (!frame) { if (!frame) {
this.delegatePrompt(request, requestId, typesInfo); this.delegatePrompt(request, requestId);
return; return;
} }
@ -273,7 +163,7 @@ ContentPermissionPrompt.prototype = {
if (evt.detail.visible === true) if (evt.detail.visible === true)
return; return;
self.cancelPrompt(request, requestId, typesInfo); self.cancelPrompt(request, requestId);
cancelRequest(); cancelRequest();
} }
@ -290,7 +180,7 @@ ContentPermissionPrompt.prototype = {
// away but the request is still here. // away but the request is still here.
frame.addEventListener("mozbrowservisibilitychange", onVisibilityChange); frame.addEventListener("mozbrowservisibilitychange", onVisibilityChange);
self.delegatePrompt(request, requestId, typesInfo, function onCallback() { self.delegatePrompt(request, requestId, function onCallback() {
frame.removeEventListener("mozbrowservisibilitychange", onVisibilityChange); frame.removeEventListener("mozbrowservisibilitychange", onVisibilityChange);
}); });
}; };
@ -301,17 +191,22 @@ ContentPermissionPrompt.prototype = {
} }
}, },
cancelPrompt: function(request, requestId, typesInfo) { cancelPrompt: function(request, requestId) {
this.sendToBrowserWindow("cancel-permission-prompt", request, requestId, this.sendToBrowserWindow("cancel-permission-prompt", request, requestId);
typesInfo);
}, },
delegatePrompt: function(request, requestId, typesInfo, callback) { delegatePrompt: function(request, requestId, callback) {
let access = (request.access && request.access !== "unused") ? request.type + "-" + request.access :
request.type;
let principal = request.principal;
this.sendToBrowserWindow("permission-prompt", request, requestId, typesInfo, this._permission = access;
function(type, remember) { this._uri = principal.URI.spec;
this._origin = principal.origin;
this.sendToBrowserWindow("permission-prompt", request, requestId, function(type, remember) {
if (type == "permission-allow") { if (type == "permission-allow") {
rememberPermission(typesInfo, request.principal, !remember); rememberPermission(request.type, principal, !remember);
if (callback) { if (callback) {
callback(); callback();
} }
@ -319,20 +214,14 @@ ContentPermissionPrompt.prototype = {
return; return;
} }
let addDenyPermission = function(type) { if (remember) {
debug("add " + type.permission + Services.perms.addFromPrincipal(principal, access,
" to permission manager with DENY_ACTION"); Ci.nsIPermissionManager.DENY_ACTION);
if (remember) { } else {
Services.perms.addFromPrincipal(request.principal, type.access, Services.perms.addFromPrincipal(principal, access,
Ci.nsIPermissionManager.DENY_ACTION); Ci.nsIPermissionManager.DENY_ACTION,
} else if (PERMISSION_NO_SESSION.indexOf(aPerm) < 0) { Ci.nsIPermissionManager.EXPIRE_SESSION, 0);
Services.perms.addFromPrincipal(request.principal, type.access,
Ci.nsIPermissionManager.DENY_ACTION,
Ci.nsIPermissionManager.EXPIRE_SESSION,
0);
}
} }
typesInfo.forEach(addDenyPermission);
if (callback) { if (callback) {
callback(); callback();
@ -341,7 +230,7 @@ ContentPermissionPrompt.prototype = {
}); });
}, },
sendToBrowserWindow: function(type, request, requestId, typesInfo, callback) { sendToBrowserWindow: function(type, request, requestId, callback) {
let browser = Services.wm.getMostRecentWindow("navigator:browser"); let browser = Services.wm.getMostRecentWindow("navigator:browser");
let content = browser.getContentWindow(); let content = browser.getContentWindow();
if (!content) if (!content)
@ -364,15 +253,10 @@ ContentPermissionPrompt.prototype = {
principal.appStatus == Ci.nsIPrincipal.APP_STATUS_CERTIFIED) principal.appStatus == Ci.nsIPrincipal.APP_STATUS_CERTIFIED)
? true ? true
: request.remember; : request.remember;
let permissions = {};
for (let i in typesInfo) {
debug("prompt " + typesInfo[i].permission);
permissions[typesInfo[i].permission] = [];
}
let details = { let details = {
type: type, type: type,
permissions: permissions, permission: request.type,
id: requestId, id: requestId,
origin: principal.origin, origin: principal.origin,
isApp: isApp, isApp: isApp,
@ -405,5 +289,6 @@ ContentPermissionPrompt.prototype = {
}; };
})(); })();
//module initialization //module initialization
this.NSGetFactory = XPCOMUtils.generateNSGetFactory([ContentPermissionPrompt]); this.NSGetFactory = XPCOMUtils.generateNSGetFactory([ContentPermissionPrompt]);

Просмотреть файл

@ -1056,11 +1056,6 @@ let CustomizableUIInternal = {
} }
} }
if (aWidget.id == "switch-to-metro-button") {
let brandBundle = aDocument.getElementById("bundle_brand");
let brandShortName = brandBundle.getString("brandShortName");
additionalTooltipArguments = [brandShortName];
}
let tooltip = this.getLocalizedProperty(aWidget, "tooltiptext", additionalTooltipArguments); let tooltip = this.getLocalizedProperty(aWidget, "tooltiptext", additionalTooltipArguments);
node.setAttribute("tooltiptext", tooltip); node.setAttribute("tooltiptext", tooltip);
node.setAttribute("class", "toolbarbutton-1 chromeclass-toolbar-additional"); node.setAttribute("class", "toolbarbutton-1 chromeclass-toolbar-additional");
@ -1072,9 +1067,8 @@ let CustomizableUIInternal = {
// If the widget has a view, and has view showing / hiding listeners, // If the widget has a view, and has view showing / hiding listeners,
// hook those up to this widget. // hook those up to this widget.
if (aWidget.type == "view" && if (aWidget.type == "view") {
(aWidget.onViewShowing || aWidget.onViewHiding)) { LOG("Widget " + aWidget.id + " has a view. Auto-registering event handlers.");
LOG("Widget " + aWidget.id + " has a view with showing and hiding events. Auto-registering event handlers.");
let viewNode = aDocument.getElementById(aWidget.viewId); let viewNode = aDocument.getElementById(aWidget.viewId);
if (viewNode) { if (viewNode) {
@ -1753,10 +1747,6 @@ let CustomizableUIInternal = {
return null; return null;
} }
if (aData.id == "switch-to-metro-button") {
widget.showInPrivateBrowsing = false;
}
delete widget.implementation.currentArea; delete widget.implementation.currentArea;
widget.implementation.__defineGetter__("currentArea", function() widget.currentArea); widget.implementation.__defineGetter__("currentArea", function() widget.currentArea);
@ -2270,8 +2260,8 @@ this.CustomizableUI = {
* and an onWidgetBeforeDOMChange and onWidgetAfterDOMChange notification * and an onWidgetBeforeDOMChange and onWidgetAfterDOMChange notification
* for each window CustomizableUI knows about. * for each window CustomizableUI knows about.
* *
* @param aWidgetId the widget to add * @param aWidgetId the ID of the widget to add
* @param aArea the area to add the widget to * @param aArea the ID of the area to add the widget to
* @param aPosition the position at which to add the widget. If you do not * @param aPosition the position at which to add the widget. If you do not
* pass a position, the widget will be added to the end * pass a position, the widget will be added to the end
* of the area. * of the area.
@ -2286,7 +2276,7 @@ this.CustomizableUI = {
* onWidgetAfterDOMChange notification for each window CustomizableUI knows * onWidgetAfterDOMChange notification for each window CustomizableUI knows
* about. * about.
* *
* @param aWidgetId the widget to remove * @param aWidgetId the ID of the widget to remove
*/ */
removeWidgetFromArea: function(aWidgetId) { removeWidgetFromArea: function(aWidgetId) {
CustomizableUIInternal.removeWidgetFromArea(aWidgetId); CustomizableUIInternal.removeWidgetFromArea(aWidgetId);
@ -2300,7 +2290,7 @@ this.CustomizableUI = {
* and an onWidgetBeforeDOMChange and onWidgetAfterDOMChange notification for * and an onWidgetBeforeDOMChange and onWidgetAfterDOMChange notification for
* each window CustomizableUI knows about. * each window CustomizableUI knows about.
* *
* @param aWidgetid the widget to move * @param aWidgetId the ID of the widget to move
* @param aPosition the position to move the widget to. * @param aPosition the position to move the widget to.
* Negative values or values greater than the number of * Negative values or values greater than the number of
* widgets will be interpreted to mean moving the widget to * widgets will be interpreted to mean moving the widget to
@ -2318,7 +2308,7 @@ this.CustomizableUI = {
* because it delegates to addWidgetToArea) or, worse, moving items in the * because it delegates to addWidgetToArea) or, worse, moving items in the
* DOM yourself. * DOM yourself.
* *
* @param aWidgetId the widget that was just created * @param aWidgetId the ID of the widget that was just created
* @param aWindow the window in which you want to ensure it was added. * @param aWindow the window in which you want to ensure it was added.
* *
* NB: why is this API per-window, you wonder? Because if you need this, * NB: why is this API per-window, you wonder? Because if you need this,
@ -2335,7 +2325,7 @@ this.CustomizableUI = {
* Calls to begin/endBatchUpdate may be nested. * Calls to begin/endBatchUpdate may be nested.
* *
* Callers should ensure that NO MATTER WHAT they call endBatchUpdate once * Callers should ensure that NO MATTER WHAT they call endBatchUpdate once
* for each call to endBatchUpdate, even if there are exceptions in the * for each call to beginBatchUpdate, even if there are exceptions in the
* code in the batch update. Otherwise, for the duration of the * code in the batch update. Otherwise, for the duration of the
* Firefox session, customization state is never saved. Typically, you * Firefox session, customization state is never saved. Typically, you
* would do this using a try...finally block. * would do this using a try...finally block.
@ -2406,6 +2396,7 @@ this.CustomizableUI = {
* mode (optional, default: true) * mode (optional, default: true)
* *
* @param aProperties the specifications for the widget. * @param aProperties the specifications for the widget.
* @return a wrapper around the created widget (see getWidget)
*/ */
createWidget: function(aProperties) { createWidget: function(aProperties) {
return CustomizableUIInternal.wrapWidget( return CustomizableUIInternal.wrapWidget(
@ -2421,20 +2412,105 @@ this.CustomizableUI = {
* in at the time. You can remove it from there yourself by calling * in at the time. You can remove it from there yourself by calling
* CustomizableUI.removeWidgetFromArea(aWidgetId). * CustomizableUI.removeWidgetFromArea(aWidgetId).
* *
* @param aWidgetId the widget to destroy * @param aWidgetId the ID of the widget to destroy
*/ */
destroyWidget: function(aWidgetId) { destroyWidget: function(aWidgetId) {
CustomizableUIInternal.destroyWidget(aWidgetId); CustomizableUIInternal.destroyWidget(aWidgetId);
}, },
/**
* Get a wrapper object with information about the widget.
* The object provides the following properties
* (all read-only unless otherwise indicated):
*
* - id: the widget's ID;
* - type: the type of widget (button, view, custom). For
* XUL-provided widgets, this is always 'custom';
* - provider: the provider type of the widget, id est one of
* PROVIDER_API or PROVIDER_XUL;
* - forWindow(w): a method to obtain a single window wrapper for a widget,
* in the window w passed as the only argument;
* - instances: an array of all instances (single window wrappers)
* of the widget. This array is NOT live;
* - areaType: the type of the widget's current area
* - isGroup: true; will be false for wrappers around single widget nodes;
* - source: for API-provided widgets, whether they are built-in to
* Firefox or add-on-provided;
* - disabled: for API-provided widgets, whether the widget is currently
* disabled. NB: this property is writable, and will toggle
* all the widgets' disabled state;
* - label: for API-provied widgets, the label of the widget;
* - tooltiptext: for API-provided widgets, the tooltip of the widget;
* - showInPrivateBrowsing: for API-provided widgets, whether the widget is
* visible in private browsing;
*
* Single window wrappers obtained through forWindow(someWindow) or from the
* instances array have the following properties
* (all read-only unless otherwise indicated):
*
* - id: the widget's ID;
* - type: the type of widget (button, view, custom). For
* XUL-provided widgets, this is always 'custom';
* - provider: the provider type of the widget, id est one of
* PROVIDER_API or PROVIDER_XUL;
* - node: reference to the corresponding DOM node;
* - anchor: the anchor on which to anchor panels opened from this
* node. This will point to the overflow chevron on
* overflowable toolbars if and only if your widget node
* is overflowed, to the anchor for the panel menu
* if your widget is inside the panel menu, and to the
* node itself in all other cases;
* - overflowed: boolean indicating whether the node is currently in the
* overflow panel of the toolbar;
* - isGroup: false; will be true for the group widget;
* - label: for API-provided widgets, convenience getter for the
* label attribute of the DOM node;
* - tooltiptext: for API-provided widgets, convenience getter for the
* tooltiptext attribute of the DOM node;
* - disabled: for API-provided widgets, convenience getter *and setter*
* for the disabled state of this single widget. Note that
* you may prefer to use the group wrapper's getter/setter
* instead.
*
* @param aWidgetId the ID of the widget whose information you need
* @return a wrapper around the widget as described above, or null if the
* widget is known not to exist (anymore). NB: non-null return
* is no guarantee the widget exists because we cannot know in
* advance if a XUL widget exists or not.
*/
getWidget: function(aWidgetId) { getWidget: function(aWidgetId) {
return CustomizableUIInternal.wrapWidget(aWidgetId); return CustomizableUIInternal.wrapWidget(aWidgetId);
}, },
/**
* Get an array of widget wrappers (see getWidget) for all the widgets
* which are currently not in any area (so which are in the palette).
*
* @param aWindowPalette the palette (and by extension, the window) in which
* CustomizableUI should look. This matters because of
* course XUL-provided widgets could be available in
* some windows but not others, and likewise
* API-provided widgets might not exist in a private
* window (because of the showInPrivateBrowsing
* property).
*
* @return an array of widget wrappers (see getWidget)
*/
getUnusedWidgets: function(aWindowPalette) { getUnusedWidgets: function(aWindowPalette) {
return CustomizableUIInternal.getUnusedWidgets(aWindowPalette).map( return CustomizableUIInternal.getUnusedWidgets(aWindowPalette).map(
CustomizableUIInternal.wrapWidget, CustomizableUIInternal.wrapWidget,
CustomizableUIInternal CustomizableUIInternal
); );
}, },
/**
* Get an array of all the widget IDs placed in an area. This is roughly
* equivalent to fetching the currentset attribute and splitting by commas
* in the legacy APIs. Modifying the array will not affect CustomizableUI.
*
* @param aArea the ID of the area whose placements you want to obtain.
* @return an array containing the widget IDs that are in the area.
*
* NB: will throw if called too early (before placements have been fetched)
* or if the area is not currently known to CustomizableUI.
*/
getWidgetIdsInArea: function(aArea) { getWidgetIdsInArea: function(aArea) {
if (!gAreas.has(aArea)) { if (!gAreas.has(aArea)) {
throw new Error("Unknown customization area: " + aArea); throw new Error("Unknown customization area: " + aArea);
@ -2446,67 +2522,261 @@ this.CustomizableUI = {
// We need to clone this, as we don't want to let consumers muck with placements // We need to clone this, as we don't want to let consumers muck with placements
return [...gPlacements.get(aArea)]; return [...gPlacements.get(aArea)];
}, },
/**
* Get an array of widget wrappers for all the widgets in an area. This is
* the same as calling getWidgetIdsInArea and .map() ing the result through
* CustomizableUI.getWidget. Careful: this means that if there are IDs in there
* which don't have corresponding DOM nodes (like in the old-style currentset
* attribute), there might be nulls in this array, or items for which
* wrapper.forWindow(win) will return null.
*
* @param aArea the ID of the area whose widgets you want to obtain.
* @return an array of widget wrappers and/or null values for the widget IDs
* placed in an area.
*
* NB: will throw if called too early (before placements have been fetched)
* or if the area is not currently known to CustomizableUI.
*/
getWidgetsInArea: function(aArea) { getWidgetsInArea: function(aArea) {
return this.getWidgetIdsInArea(aArea).map( return this.getWidgetIdsInArea(aArea).map(
CustomizableUIInternal.wrapWidget, CustomizableUIInternal.wrapWidget,
CustomizableUIInternal CustomizableUIInternal
); );
}, },
/**
* Obtain an array of all the area IDs known to CustomizableUI.
* This array is created for you, so is modifiable without CustomizableUI
* being affected.
*/
get areas() { get areas() {
return [area for ([area, props] of gAreas)]; return [area for ([area, props] of gAreas)];
}, },
/**
* Check what kind of area (toolbar or menu panel) an area is. This is
* useful if you have a widget that needs to behave differently depending
* on its location. Note that widget wrappers have a convenience getter
* property (areaType) for this purpose.
*
* @param aArea the ID of the area whose type you want to know
* @return TYPE_TOOLBAR or TYPE_MENU_PANEL depending on the area, null if
* the area is unknown.
*/
getAreaType: function(aArea) { getAreaType: function(aArea) {
let area = gAreas.get(aArea); let area = gAreas.get(aArea);
return area ? area.get("type") : null; return area ? area.get("type") : null;
}, },
/**
* Obtain the DOM node that is the customize target for an area in a
* specific window.
*
* Areas can have a customization target that does not correspond to the
* node itself. In particular, toolbars that have a customizationtarget
* attribute set will have their customization target set to that node.
* This means widgets will end up in the customization target, not in the
* DOM node with the ID that corresponds to the area ID. This is useful
* because it lets you have fixed content in a toolbar (e.g. the panel
* menu item in the navbar) and have all the customizable widgets use
* the customization target.
*
* Using this API yourself is discouraged; you should generally not need
* to be asking for the DOM container node used for a particular area.
* In particular, if you're wanting to check it in relation to a widget's
* node, your DOM node might not be a direct child of the customize target
* in a window if, for instance, the window is in customization mode, or if
* this is an overflowable toolbar and the widget has been overflowed.
*
* @param aArea the ID of the area whose customize target you want to have
* @param aWindow the window where you want to fetch the DOM node.
* @return the customize target DOM node for aArea in aWindow
*/
getCustomizeTargetForArea: function(aArea, aWindow) { getCustomizeTargetForArea: function(aArea, aWindow) {
return CustomizableUIInternal.getCustomizeTargetForArea(aArea, aWindow); return CustomizableUIInternal.getCustomizeTargetForArea(aArea, aWindow);
}, },
/**
* Reset the customization state back to its default.
*
* This is the nuclear option. You should never call this except if the user
* explicitly requests it. Firefox does this when the user clicks the
* "Restore Defaults" button in customize mode.
*/
reset: function() { reset: function() {
CustomizableUIInternal.reset(); CustomizableUIInternal.reset();
}, },
/**
* Get the placement of a widget. This is by far the best way to obtain
* information about what the state of your widget is. The internals of
* this call are cheap (no DOM necessary) and you will know where the user
* has put your widget.
*
* @param aWidgetId the ID of the widget whose placement you want to know
* @return
* {
* area: "somearea", // The ID of the area where the widget is placed
* position: 42 // the index in the placements array corresponding to
* // your widget.
* }
*
* OR
*
* null // if the widget is not placed anywhere (ie in the palette)
*/
getPlacementOfWidget: function(aWidgetId) { getPlacementOfWidget: function(aWidgetId) {
return CustomizableUIInternal.getPlacementOfWidget(aWidgetId, true); return CustomizableUIInternal.getPlacementOfWidget(aWidgetId, true);
}, },
/**
* Check if a widget can be removed from the area it's in.
*
* Note that if you're wanting to move the widget somewhere, you should
* generally be checking canWidgetMoveToArea, because that will return
* true if the widget is already in the area where you want to move it (!).
*
* NB: oh, also, this method might lie if the widget in question is a
* XUL-provided widget and there are no windows open, because it
* can obviously not check anything in this case. It will return
* true. You will be able to move the widget elsewhere. However,
* once the user reopens a window, the widget will move back to its
* 'proper' area automagically.
*
* @param aWidgetId a widget ID or DOM node to check
* @return true if the widget can be removed from its area,
* false otherwise.
*/
isWidgetRemovable: function(aWidgetId) { isWidgetRemovable: function(aWidgetId) {
return CustomizableUIInternal.isWidgetRemovable(aWidgetId); return CustomizableUIInternal.isWidgetRemovable(aWidgetId);
}, },
/**
* Check if a widget can be moved to a particular area. Like
* isWidgetRemovable but better, because it'll return true if the widget
* is already in the right area.
*
* @param aWidgetId the widget ID or DOM node you want to move somewhere
* @param aArea the area ID you want to move it to.
* @return true if this is possible, false if it is not. Same caveats as
* for isWidgetRemovable apply, however, if no windows are open.
*/
canWidgetMoveToArea: function(aWidgetId, aArea) { canWidgetMoveToArea: function(aWidgetId, aArea) {
return CustomizableUIInternal.canWidgetMoveToArea(aWidgetId, aArea); return CustomizableUIInternal.canWidgetMoveToArea(aWidgetId, aArea);
}, },
/**
* Whether we're in a default state.
*
* NB: this is a property with a getter. The getter is NOT cheap, because
* it does smart things with non-removable non-default items, non-existent
* items, and so forth. Please don't call unless necessary.
*/
get inDefaultState() { get inDefaultState() {
return CustomizableUIInternal.inDefaultState; return CustomizableUIInternal.inDefaultState;
}, },
/**
* Get a localized property off a (widget?) object.
*
* NB: this is unlikely to be useful unless you're in Firefox code, because
* this code uses the builtin widget stringbundle, and can't be told
* to use add-on-provided strings. It's mainly here as convenience for
* custom builtin widgets that build their own DOM but use the same
* stringbundle as the other builtin widgets.
*
* @param aWidget the object whose property we should use to fetch a
* localizable string;
* @param aProp the property on the object to use for the fetching;
* @param aFormatArgs (optional) any extra arguments to use for a formatted
* string;
* @param aDef (optional) the default to return if we don't find the
* string in the stringbundle;
*
* @return the localized string, or aDef if the string isn't in the bundle.
* If no default is provided,
* if aProp exists on aWidget, we'll return that,
* otherwise we'll return the empty string
*
*/
getLocalizedProperty: function(aWidget, aProp, aFormatArgs, aDef) { getLocalizedProperty: function(aWidget, aProp, aFormatArgs, aDef) {
return CustomizableUIInternal.getLocalizedProperty(aWidget, aProp, return CustomizableUIInternal.getLocalizedProperty(aWidget, aProp,
aFormatArgs, aDef); aFormatArgs, aDef);
}, },
/**
* Given a node, walk up to the first panel in its ancestor chain, and
* close it.
*
* @param aNode a node whose panel should be closed;
*/
hidePanelForNode: function(aNode) { hidePanelForNode: function(aNode) {
CustomizableUIInternal.hidePanelForNode(aNode); CustomizableUIInternal.hidePanelForNode(aNode);
}, },
/**
* Check if a widget is a "special" widget: a spring, spacer or separator.
*
* @param aWidgetId the widget ID to check.
*/
isSpecialWidget: function(aWidgetId) { isSpecialWidget: function(aWidgetId) {
return CustomizableUIInternal.isSpecialWidget(aWidgetId); return CustomizableUIInternal.isSpecialWidget(aWidgetId);
}, },
/**
* Add listeners to a panel that will close it. For use from PanelUI and
* the overflowable toolbars, unlikely to be useful for consumers.
*
* @param aPanel the panel to which listeners should be attached.
*/
addPanelCloseListeners: function(aPanel) { addPanelCloseListeners: function(aPanel) {
CustomizableUIInternal.addPanelCloseListeners(aPanel); CustomizableUIInternal.addPanelCloseListeners(aPanel);
}, },
/**
* Remove close listeners that have been added to a panel with
* addPanelCloseListeners. For use from PanelUI and the overflowable
* toolbars, unlikely to be useful for consumers.
*
* @param aPanel the panel from which listeners should be removed.
*/
removePanelCloseListeners: function(aPanel) { removePanelCloseListeners: function(aPanel) {
CustomizableUIInternal.removePanelCloseListeners(aPanel); CustomizableUIInternal.removePanelCloseListeners(aPanel);
}, },
/**
* Notify listeners a widget is about to be dragged to an area. For use from
* Customize Mode only, do not use otherwise.
*
* @param aWidgetId the ID of the widget that is being dragged to an area.
* @param aArea the ID of the area to which the widget is being dragged.
*/
onWidgetDrag: function(aWidgetId, aArea) { onWidgetDrag: function(aWidgetId, aArea) {
CustomizableUIInternal.notifyListeners("onWidgetDrag", aWidgetId, aArea); CustomizableUIInternal.notifyListeners("onWidgetDrag", aWidgetId, aArea);
}, },
/**
* Notify listeners that a window is entering customize mode. For use from
* Customize Mode only, do not use otherwise.
* @param aWindow the window entering customize mode
*/
notifyStartCustomizing: function(aWindow) { notifyStartCustomizing: function(aWindow) {
CustomizableUIInternal.notifyListeners("onCustomizeStart", aWindow); CustomizableUIInternal.notifyListeners("onCustomizeStart", aWindow);
}, },
/**
* Notify listeners that a window is exiting customize mode. For use from
* Customize Mode only, do not use otherwise.
* @param aWindow the window exiting customize mode
*/
notifyEndCustomizing: function(aWindow) { notifyEndCustomizing: function(aWindow) {
CustomizableUIInternal.notifyListeners("onCustomizeEnd", aWindow); CustomizableUIInternal.notifyListeners("onCustomizeEnd", aWindow);
}, },
/**
* Check whether an area is overflowable.
*
* @param aAreaId the ID of an area to check for overflowable-ness
* @return true if the area is overflowable, false otherwise.
*/
isAreaOverflowable: function(aAreaId) { isAreaOverflowable: function(aAreaId) {
let area = gAreas.get(aAreaId); let area = gAreas.get(aAreaId);
return area ? area.get("type") == this.TYPE_TOOLBAR && area.get("overflowable") return area ? area.get("type") == this.TYPE_TOOLBAR && area.get("overflowable")
: false; : false;
}, },
/**
* Obtain a string indicating the place of an element. This is intended
* for use from customize mode; You should generally use getPlacementOfWidget
* instead, which is cheaper because it does not use the DOM.
*
* @param aElement the DOM node whose place we need to check
* @return "toolbar" if the node is in a toolbar, "panel" if it is in the
* menu panel, "palette" if it is in the (visible!) customization
* palette, undefined otherwise.
*/
getPlaceForItem: function(aElement) { getPlaceForItem: function(aElement) {
let place; let place;
let node = aElement; let node = aElement;

Просмотреть файл

@ -17,6 +17,10 @@ XPCOMUtils.defineLazyModuleGetter(this, "RecentlyClosedTabsAndWindowsMenuUtils",
XPCOMUtils.defineLazyServiceGetter(this, "CharsetManager", XPCOMUtils.defineLazyServiceGetter(this, "CharsetManager",
"@mozilla.org/charset-converter-manager;1", "@mozilla.org/charset-converter-manager;1",
"nsICharsetConverterManager"); "nsICharsetConverterManager");
XPCOMUtils.defineLazyGetter(this, "BrandBundle", function() {
const kBrandBundle = "chrome://branding/locale/brand.properties";
return Services.strings.createBundle(kBrandBundle);
});
const kNSXUL = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"; const kNSXUL = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";
const kPrefCustomizationDebug = "browser.uiCustomization.debug"; const kPrefCustomizationDebug = "browser.uiCustomization.debug";
@ -25,14 +29,6 @@ const kWidePanelItemClass = "panel-wide-item";
let gModuleName = "[CustomizableWidgets]"; let gModuleName = "[CustomizableWidgets]";
#include logging.js #include logging.js
function isWin8OrHigher() {
let osName = Services.sysinfo.getProperty("name");
let version = Services.sysinfo.getProperty("version");
// Windows 8 is version >= 6.2
return osName == "Windows_NT" && Services.vc.compare(version, "6.2") >= 0;
}
function setAttributes(aNode, aAttrs) { function setAttributes(aNode, aAttrs) {
for (let [name, value] of Iterator(aAttrs)) { for (let [name, value] of Iterator(aAttrs)) {
if (!value) { if (!value) {
@ -796,17 +792,20 @@ const CustomizableWidgets = [{
#ifdef XP_WIN #ifdef XP_WIN
#ifdef MOZ_METRO #ifdef MOZ_METRO
if (isWin8OrHigher()) { if (Services.sysinfo.getProperty("hasWindowsTouchInterface")) {
let widgetArgs = {tooltiptext: "switch-to-metro-button2.tooltiptext"};
let brandShortName = BrandBundle.GetStringFromName("brandShortName");
let metroTooltip = CustomizableUI.getLocalizedProperty(widgetArgs, "tooltiptext",
[brandShortName]);
CustomizableWidgets.push({ CustomizableWidgets.push({
id: "switch-to-metro-button", id: "switch-to-metro-button",
label: "switch-to-metro-button2.label", label: "switch-to-metro-button2.label",
tooltiptext: "switch-to-metro-button2.tooltiptext", tooltiptext: metroTooltip,
removable: true, removable: true,
defaultArea: CustomizableUI.AREA_PANEL, defaultArea: CustomizableUI.AREA_PANEL,
showInPrivateBrowsing: false, /* See bug 928068 */
onCommand: function(aEvent) { onCommand: function(aEvent) {
let win = aEvent.target && let win = aEvent.view;
aEvent.target.ownerDocument &&
aEvent.target.ownerDocument.defaultView;
if (win && typeof win.SwitchToMetro == "function") { if (win && typeof win.SwitchToMetro == "function") {
win.SwitchToMetro(); win.SwitchToMetro();
} }

Просмотреть файл

@ -1591,7 +1591,7 @@ BrowserGlue.prototype = {
// be set to the version it has been added in, we will compare its value // be set to the version it has been added in, we will compare its value
// to users' smartBookmarksVersion and add new smart bookmarks without // to users' smartBookmarksVersion and add new smart bookmarks without
// recreating old deleted ones. // recreating old deleted ones.
const SMART_BOOKMARKS_VERSION = 5; const SMART_BOOKMARKS_VERSION = 6;
const SMART_BOOKMARKS_ANNO = "Places/SmartBookmark"; const SMART_BOOKMARKS_ANNO = "Places/SmartBookmark";
const SMART_BOOKMARKS_PREF = "browser.places.smartBookmarksVersion"; const SMART_BOOKMARKS_PREF = "browser.places.smartBookmarksVersion";
@ -1653,7 +1653,10 @@ BrowserGlue.prototype = {
position: menuIndex++, position: menuIndex++,
newInVersion: 1 newInVersion: 1
}, },
Windows8Touch: { };
if (Services.sysinfo.getProperty("hasWindowsTouchInterface")) {
smartBookmarks.Windows8Touch = {
title: bundle.GetStringFromName("windows8TouchTitle"), title: bundle.GetStringFromName("windows8TouchTitle"),
uri: NetUtil.newURI("place:folder=" + uri: NetUtil.newURI("place:folder=" +
PlacesUtils.annotations.getItemsWithAnnotation('metro/bookmarksRoot', {})[0] + PlacesUtils.annotations.getItemsWithAnnotation('metro/bookmarksRoot', {})[0] +
@ -1665,9 +1668,9 @@ BrowserGlue.prototype = {
"&excludeQueries=1"), "&excludeQueries=1"),
parent: PlacesUtils.bookmarksMenuFolderId, parent: PlacesUtils.bookmarksMenuFolderId,
position: menuIndex++, position: menuIndex++,
newInVersion: 5 newInVersion: 6
}, };
}; }
// Set current itemId, parent and position if Smart Bookmark exists, // Set current itemId, parent and position if Smart Bookmark exists,
// we will use these informations to create the new version at the same // we will use these informations to create the new version at the same
@ -2030,21 +2033,13 @@ ContentPermissionPrompt.prototype = {
prompt: function CPP_prompt(request) { prompt: function CPP_prompt(request) {
// Only allow exactly one permission rquest here.
let types = request.types.QueryInterface(Ci.nsIArray);
if (types.length != 1) {
request.cancel();
return;
}
let perm = types.queryElementAt(0, Ci.nsIContentPermissionType);
const kFeatureKeys = { "geolocation" : "geo", const kFeatureKeys = { "geolocation" : "geo",
"desktop-notification" : "desktop-notification", "desktop-notification" : "desktop-notification",
"pointerLock" : "pointerLock", "pointerLock" : "pointerLock",
}; };
// Make sure that we support the request. // Make sure that we support the request.
if (!(perm.type in kFeatureKeys)) { if (!(request.type in kFeatureKeys)) {
return; return;
} }
@ -2056,7 +2051,7 @@ ContentPermissionPrompt.prototype = {
return; return;
var autoAllow = false; var autoAllow = false;
var permissionKey = kFeatureKeys[perm.type]; var permissionKey = kFeatureKeys[request.type];
var result = Services.perms.testExactPermissionFromPrincipal(requestingPrincipal, permissionKey); var result = Services.perms.testExactPermissionFromPrincipal(requestingPrincipal, permissionKey);
if (result == Ci.nsIPermissionManager.DENY_ACTION) { if (result == Ci.nsIPermissionManager.DENY_ACTION) {
@ -2067,7 +2062,7 @@ ContentPermissionPrompt.prototype = {
if (result == Ci.nsIPermissionManager.ALLOW_ACTION) { if (result == Ci.nsIPermissionManager.ALLOW_ACTION) {
autoAllow = true; autoAllow = true;
// For pointerLock, we still want to show a warning prompt. // For pointerLock, we still want to show a warning prompt.
if (perm.type != "pointerLock") { if (request.type != "pointerLock") {
request.allow(); request.allow();
return; return;
} }
@ -2081,7 +2076,7 @@ ContentPermissionPrompt.prototype = {
return; return;
// Show the prompt. // Show the prompt.
switch (perm.type) { switch (request.type) {
case "geolocation": case "geolocation":
this._promptGeo(request); this._promptGeo(request);
break; break;

Просмотреть файл

@ -63,9 +63,10 @@ let (XULAppInfo = {
} }
// Smart bookmarks constants. // Smart bookmarks constants.
const SMART_BOOKMARKS_VERSION = 5; let isWin8OrHigher = Services.sysinfo.getProperty("hasWindowsTouchInterface");
const SMART_BOOKMARKS_VERSION = 6
const SMART_BOOKMARKS_ON_TOOLBAR = 1; const SMART_BOOKMARKS_ON_TOOLBAR = 1;
const SMART_BOOKMARKS_ON_MENU = 4; // Takes in count the additional separator. const SMART_BOOKMARKS_ON_MENU = isWin8OrHigher ? 4 : 3; // Takes in count the additional separator.
// Default bookmarks constants. // Default bookmarks constants.
const DEFAULT_BOOKMARKS_ON_TOOLBAR = 1; const DEFAULT_BOOKMARKS_ON_TOOLBAR = 1;

Просмотреть файл

@ -78,6 +78,11 @@ const TAB_EVENTS = [
"TabUnpinned" "TabUnpinned"
]; ];
// Browser events observed.
const BROWSER_EVENTS = [
"load", "SwapDocShells", "UserTypedValueChanged"
];
// The number of milliseconds in a day // The number of milliseconds in a day
const MS_PER_DAY = 1000.0 * 60.0 * 60.0 * 24.0; const MS_PER_DAY = 1000.0 * 60.0 * 60.0 * 24.0;
@ -1243,9 +1248,7 @@ let SessionStoreInternal = {
*/ */
onTabAdd: function ssi_onTabAdd(aWindow, aTab, aNoNotification) { onTabAdd: function ssi_onTabAdd(aWindow, aTab, aNoNotification) {
let browser = aTab.linkedBrowser; let browser = aTab.linkedBrowser;
browser.addEventListener("load", this, true); BROWSER_EVENTS.forEach(msg => browser.addEventListener(msg, this, true));
browser.addEventListener("SwapDocShells", this, true);
browser.addEventListener("UserTypedValueChanged", this, true);
let mm = browser.messageManager; let mm = browser.messageManager;
MESSAGES.forEach(msg => mm.addMessageListener(msg, this)); MESSAGES.forEach(msg => mm.addMessageListener(msg, this));
@ -1271,9 +1274,7 @@ let SessionStoreInternal = {
*/ */
onTabRemove: function ssi_onTabRemove(aWindow, aTab, aNoNotification) { onTabRemove: function ssi_onTabRemove(aWindow, aTab, aNoNotification) {
let browser = aTab.linkedBrowser; let browser = aTab.linkedBrowser;
browser.removeEventListener("load", this, true); BROWSER_EVENTS.forEach(msg => browser.removeEventListener(msg, this, true));
browser.removeEventListener("SwapDocShells", this, true);
browser.removeEventListener("UserTypedValueChanged", this, true);
let mm = browser.messageManager; let mm = browser.messageManager;
MESSAGES.forEach(msg => mm.removeMessageListener(msg, this)); MESSAGES.forEach(msg => mm.removeMessageListener(msg, this));

Просмотреть файл

@ -237,8 +237,20 @@ Toolbox.prototype = {
}, true); }, true);
}, },
_isResponsiveModeActive: function() {
let responsiveModeActive = false;
if (this.target.isLocalTab) {
let tab = this.target.tab;
let browserWindow = tab.ownerDocument.defaultView;
let responsiveUIManager = browserWindow.ResponsiveUI.ResponsiveUIManager;
responsiveModeActive = responsiveUIManager.isActiveForTab(tab);
}
return responsiveModeActive;
},
_splitConsoleOnKeypress: function(e) { _splitConsoleOnKeypress: function(e) {
if (e.keyCode === e.DOM_VK_ESCAPE) { let responsiveModeActive = this._isResponsiveModeActive();
if (e.keyCode === e.DOM_VK_ESCAPE && !responsiveModeActive) {
this.toggleSplitConsole(); this.toggleSplitConsole();
} }
}, },

Просмотреть файл

@ -176,7 +176,7 @@ function ResponsiveUI(aWindow, aTab)
// Events // Events
this.tab.addEventListener("TabClose", this); this.tab.addEventListener("TabClose", this);
this.tabContainer.addEventListener("TabSelect", this); this.tabContainer.addEventListener("TabSelect", this);
this.mainWindow.document.addEventListener("keypress", this.bound_onKeypress, true); this.mainWindow.document.addEventListener("keypress", this.bound_onKeypress, false);
this.buildUI(); this.buildUI();
this.checkMenus(); this.checkMenus();
@ -276,7 +276,7 @@ ResponsiveUI.prototype = {
this.stopResizing(); this.stopResizing();
// Remove listeners. // Remove listeners.
this.mainWindow.document.removeEventListener("keypress", this.bound_onKeypress, true); this.mainWindow.document.removeEventListener("keypress", this.bound_onKeypress, false);
this.menulist.removeEventListener("select", this.bound_presetSelected, true); this.menulist.removeEventListener("select", this.bound_presetSelected, true);
this.tab.removeEventListener("TabClose", this); this.tab.removeEventListener("TabClose", this);
this.tabContainer.removeEventListener("TabSelect", this); this.tabContainer.removeEventListener("TabSelect", this);

Просмотреть файл

@ -6,6 +6,7 @@ function test() {
let ruleView; let ruleView;
let inspector; let inspector;
let mgr = ResponsiveUI.ResponsiveUIManager;
waitForExplicitFinish(); waitForExplicitFinish();
@ -78,14 +79,22 @@ function test() {
ruleView.element.addEventListener("CssRuleViewRefreshed", function refresh() { ruleView.element.addEventListener("CssRuleViewRefreshed", function refresh() {
ruleView.element.removeEventListener("CssRuleViewRefreshed", refresh, false); ruleView.element.removeEventListener("CssRuleViewRefreshed", refresh, false);
is(numberOfRules(), 2, "Should have two rules after growing."); is(numberOfRules(), 2, "Should have two rules after growing.");
finishUp(); testEscapeCloses();
}, false); }, false);
instance.setSize(500, 500); instance.setSize(500, 500);
} }
function testEscapeCloses() {
is(document.getElementById("Tools:ResponsiveUI").getAttribute("checked"), "true", "menu checked");
ok(!inspector._toolbox._splitConsole, "Console is not split.");
mgr.once("off", function() {executeSoon(finishUp)});
EventUtils.synthesizeKey("VK_ESCAPE", {});
}
function finishUp() { function finishUp() {
document.getElementById("Tools:ResponsiveUI").doCommand(); ok(!inspector._toolbox._splitConsole, "Console is still not split after pressing escape.");
// Menus are correctly updated? // Menus are correctly updated?
is(document.getElementById("Tools:ResponsiveUI").getAttribute("checked"), "false", "menu unchecked"); is(document.getElementById("Tools:ResponsiveUI").getAttribute("checked"), "false", "menu unchecked");

Просмотреть файл

@ -44,8 +44,6 @@ let IndexedDB = {
} }
let prompt = Cc["@mozilla.org/content-permission/prompt;1"].createInstance(Ci.nsIContentPermissionPrompt); let prompt = Cc["@mozilla.org/content-permission/prompt;1"].createInstance(Ci.nsIContentPermissionPrompt);
let types = Cc["@mozilla.org/array;1"].createInstance(Ci.nsIMutableArray);
types.appendElement({type: type, access: "unused"}, false);
// If the user waits a long time before responding, we default to UNKNOWN_ACTION. // If the user waits a long time before responding, we default to UNKNOWN_ACTION.
let timeoutId = setTimeout(function() { let timeoutId = setTimeout(function() {
@ -62,7 +60,7 @@ let IndexedDB = {
} }
prompt.prompt({ prompt.prompt({
types: types, type: type,
uri: Services.io.newURI(payload.location, null, null), uri: Services.io.newURI(payload.location, null, null),
window: null, window: null,
element: aMessage.target, element: aMessage.target,

Просмотреть файл

@ -56,8 +56,8 @@ ContentPermissionPrompt.prototype = {
return chromeWin.Browser.getNotificationBox(request.element); return chromeWin.Browser.getNotificationBox(request.element);
}, },
handleExistingPermission: function handleExistingPermission(request, type) { handleExistingPermission: function handleExistingPermission(request) {
let result = Services.perms.testExactPermissionFromPrincipal(request.principal, type); let result = Services.perms.testExactPermissionFromPrincipal(request.principal, request.type);
if (result == Ci.nsIPermissionManager.ALLOW_ACTION) { if (result == Ci.nsIPermissionManager.ALLOW_ACTION) {
request.allow(); request.allow();
return true; return true;
@ -70,28 +70,20 @@ ContentPermissionPrompt.prototype = {
}, },
prompt: function(request) { prompt: function(request) {
// Only allow exactly one permission rquest here.
let types = request.types.QueryInterface(Ci.nsIArray);
if (types.length != 1) {
request.cancel();
return;
}
let perm = types.queryElementAt(0, Ci.nsIContentPermissionType);
// returns true if the request was handled // returns true if the request was handled
if (this.handleExistingPermission(request, perm.type)) if (this.handleExistingPermission(request))
return; return;
let pm = Services.perms; let pm = Services.perms;
let notificationBox = this.getNotificationBoxForRequest(request); let notificationBox = this.getNotificationBoxForRequest(request);
let browserBundle = Services.strings.createBundle("chrome://browser/locale/browser.properties"); let browserBundle = Services.strings.createBundle("chrome://browser/locale/browser.properties");
let notification = notificationBox.getNotificationWithValue(perm.type); let notification = notificationBox.getNotificationWithValue(request.type);
if (notification) if (notification)
return; return;
let entityName = kEntities[perm.type]; let entityName = kEntities[request.type];
let icon = kIcons[perm.type] || ""; let icon = kIcons[request.type] || "";
let buttons = [{ let buttons = [{
label: browserBundle.GetStringFromName(entityName + ".allow"), label: browserBundle.GetStringFromName(entityName + ".allow"),
@ -104,7 +96,7 @@ ContentPermissionPrompt.prototype = {
label: browserBundle.GetStringFromName("contentPermissions.alwaysForSite"), label: browserBundle.GetStringFromName("contentPermissions.alwaysForSite"),
accessKey: "", accessKey: "",
callback: function(notification) { callback: function(notification) {
Services.perms.addFromPrincipal(request.principal, perm.type, Ci.nsIPermissionManager.ALLOW_ACTION); Services.perms.addFromPrincipal(request.principal, request.type, Ci.nsIPermissionManager.ALLOW_ACTION);
request.allow(); request.allow();
} }
}, },
@ -112,7 +104,7 @@ ContentPermissionPrompt.prototype = {
label: browserBundle.GetStringFromName("contentPermissions.neverForSite"), label: browserBundle.GetStringFromName("contentPermissions.neverForSite"),
accessKey: "", accessKey: "",
callback: function(notification) { callback: function(notification) {
Services.perms.addFromPrincipal(request.principal, perm.type, Ci.nsIPermissionManager.DENY_ACTION); Services.perms.addFromPrincipal(request.principal, request.type, Ci.nsIPermissionManager.DENY_ACTION);
request.cancel(); request.cancel();
} }
}]; }];
@ -120,12 +112,12 @@ ContentPermissionPrompt.prototype = {
let message = browserBundle.formatStringFromName(entityName + ".wantsTo", let message = browserBundle.formatStringFromName(entityName + ".wantsTo",
[request.principal.URI.host], 1); [request.principal.URI.host], 1);
let newBar = notificationBox.appendNotification(message, let newBar = notificationBox.appendNotification(message,
perm.type, request.type,
icon, icon,
notificationBox.PRIORITY_WARNING_MEDIUM, notificationBox.PRIORITY_WARNING_MEDIUM,
buttons); buttons);
if (perm.type == "geolocation") { if (request.type == "geolocation") {
// Add the "learn more" link. // Add the "learn more" link.
let link = newBar.ownerDocument.createElement("label"); let link = newBar.ownerDocument.createElement("label");
link.setAttribute("value", browserBundle.GetStringFromName("geolocation.learnMore")); link.setAttribute("value", browserBundle.GetStringFromName("geolocation.learnMore"));

Просмотреть файл

@ -1,9 +0,0 @@
# 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/.
ifeq ($(MOZ_WIDGET_TOOLKIT),windows)
MOCHITEST_BROWSER_FILES += \
browser_taskbar_preview.js \
$(NULL)
endif

Просмотреть файл

@ -4,3 +4,5 @@
[browser_SignInToWebsite.js] [browser_SignInToWebsite.js]
[browser_UITour.js] [browser_UITour.js]
support-files = uitour.* support-files = uitour.*
[browser_taskbar_preview.js]
run-if = os == "win"

Просмотреть файл

@ -104,17 +104,6 @@ toolbarpaletteitem[place="toolbar"] {
margin-bottom: 25px; margin-bottom: 25px;
} }
#customization-palette > #wrapper-edit-controls,
#customization-palette > #wrapper-zoom-controls {
width: 225px;
}
#wrapper-edit-controls[place="palette"] > .toolbarpaletteitem-box,
#wrapper-zoom-controls[place="palette"] > .toolbarpaletteitem-box {
width: 225px;
max-width: 225px;
}
#wrapper-edit-controls[place="palette"] > #edit-controls > toolbarbutton, #wrapper-edit-controls[place="palette"] > #edit-controls > toolbarbutton,
#wrapper-edit-controls[place="palette"] > #edit-controls > separator, #wrapper-edit-controls[place="palette"] > #edit-controls > separator,
#wrapper-zoom-controls[place="palette"] > #zoom-controls > toolbarbutton, #wrapper-zoom-controls[place="palette"] > #zoom-controls > toolbarbutton,
@ -126,21 +115,25 @@ toolbarpaletteitem[place="toolbar"] {
#wrapper-zoom-controls[place="palette"] > #zoom-controls > toolbarbutton { #wrapper-zoom-controls[place="palette"] > #zoom-controls > toolbarbutton {
margin-left: 0; margin-left: 0;
margin-right: 0; margin-right: 0;
max-width: 70px; max-width: 24px;
min-width: 70px; min-width: 24px;
max-height: 24px; max-height: 24px;
height: 24px; height: 24px;
} padding: 4px;
#wrapper-edit-controls[place="palette"] > #edit-controls > toolbarbutton > .toolbarbutton-text,
#wrapper-zoom-controls[place="palette"] > #zoom-controls > #zoom-reset-button > .toolbarbutton-text {
display: inline;
} }
#wrapper-edit-controls[place="palette"] > #edit-controls > toolbarbutton > .toolbarbutton-icon, #wrapper-edit-controls[place="palette"] > #edit-controls > toolbarbutton > .toolbarbutton-icon,
#wrapper-zoom-controls[place="palette"] > #zoom-controls > toolbarbutton > .toolbarbutton-icon { #wrapper-zoom-controls[place="palette"] > #zoom-controls > toolbarbutton > .toolbarbutton-icon {
margin: 0; width: 16px;
-moz-margin-start: 5px; }
#wrapper-edit-controls > #edit-controls > toolbarbutton > .toolbarbutton-icon {
opacity: 1; /* To ensure these buttons always look enabled in customize mode */
}
#wrapper-zoom-controls[place="palette"] > #zoom-controls > #zoom-reset-button,
#wrapper-zoom-controls[place="palette"] > #zoom-controls > #zoom-reset-button + separator {
display: none;
} }
#customization-palette > toolbarpaletteitem > label { #customization-palette > toolbarpaletteitem > label {

Просмотреть файл

@ -12,11 +12,11 @@ public interface Assert {
void endTest(); void endTest();
void ok(boolean condition, String name, String diag); void ok(boolean condition, String name, String diag);
void is(Object a, Object b, String name); void is(Object actual, Object expected, String name);
void isnot(Object a, Object b, String name); void isnot(Object actual, Object notExpected, String name);
void todo(boolean condition, String name, String diag); void todo(boolean condition, String name, String diag);
void todo_is(Object a, Object b, String name); void todo_is(Object actual, Object expected, String name);
void todo_isnot(Object a, Object b, String name); void todo_isnot(Object actual, Object notExpected, String name);
void info(String name, String message); void info(String name, String message);
// robocop-specific asserts // robocop-specific asserts

Просмотреть файл

@ -15,7 +15,7 @@ public class FennecMochitestAssert implements Assert {
private int mPassed = 0; private int mPassed = 0;
private int mFailed = 0; private int mFailed = 0;
private int mTodo = 0; private int mTodo = 0;
// Used to write the first line of the test file // Used to write the first line of the test file
private boolean mLogStarted = false; private boolean mLogStarted = false;
@ -140,14 +140,14 @@ public class FennecMochitestAssert implements Assert {
mTestList.add(test); mTestList.add(test);
} }
public void is(Object a, Object b, String name) { public void is(Object actual, Object expected, String name) {
boolean pass = checkObjectsEqual(a,b); boolean pass = checkObjectsEqual(actual, expected);
ok(pass, name, getEqualString(a,b, pass)); ok(pass, name, getEqualString(actual, expected, pass));
} }
public void isnot(Object a, Object b, String name) { public void isnot(Object actual, Object notExpected, String name) {
boolean pass = checkObjectsNotEqual(a,b); boolean pass = checkObjectsNotEqual(actual, notExpected);
ok(pass, name, getNotEqualString(a,b,pass)); ok(pass, name, getNotEqualString(actual, notExpected, pass));
} }
public void ispixel(int actual, int r, int g, int b, String name) { public void ispixel(int actual, int r, int g, int b, String name) {
@ -197,14 +197,14 @@ public class FennecMochitestAssert implements Assert {
mTestList.add(test); mTestList.add(test);
} }
public void todo_is(Object a, Object b, String name) { public void todo_is(Object actual, Object expected, String name) {
boolean pass = checkObjectsEqual(a,b); boolean pass = checkObjectsEqual(actual, expected);
todo(pass, name, getEqualString(a,b,pass)); todo(pass, name, getEqualString(actual, expected, pass));
} }
public void todo_isnot(Object a, Object b, String name) { public void todo_isnot(Object actual, Object notExpected, String name) {
boolean pass = checkObjectsNotEqual(a,b); boolean pass = checkObjectsNotEqual(actual, notExpected);
todo(pass, name, getNotEqualString(a,b,pass)); todo(pass, name, getNotEqualString(actual, notExpected, pass));
} }
private boolean checkObjectsEqual(Object a, Object b) { private boolean checkObjectsEqual(Object a, Object b) {

Просмотреть файл

@ -6,7 +6,7 @@ package org.mozilla.gecko;
public class FennecTalosAssert implements Assert { public class FennecTalosAssert implements Assert {
public FennecTalosAssert() { } public FennecTalosAssert() { }
/** /**
@ -38,14 +38,14 @@ public class FennecTalosAssert implements Assert {
} }
} }
public void is(Object a, Object b, String name) { public void is(Object actual, Object expected, String name) {
boolean pass = (a == null ? b == null : a.equals(b)); boolean pass = (actual == null ? expected == null : actual.equals(expected));
ok(pass, name, "got " + a + ", expected " + b); ok(pass, name, "got " + actual + ", expected " + expected);
} }
public void isnot(Object a, Object b, String name) { public void isnot(Object actual, Object notExpected, String name) {
boolean fail = (a == null ? b == null : a.equals(b)); boolean fail = (actual == null ? notExpected == null : actual.equals(notExpected));
ok(!fail, name, "got " + a + ", expected not " + b); ok(!fail, name, "got " + actual + ", expected not " + notExpected);
} }
public void ispixel(int actual, int r, int g, int b, String name) { public void ispixel(int actual, int r, int g, int b, String name) {
@ -60,11 +60,11 @@ public class FennecTalosAssert implements Assert {
throw new UnsupportedOperationException(); throw new UnsupportedOperationException();
} }
public void todo_is(Object a, Object b, String name) { public void todo_is(Object actual, Object expected, String name) {
throw new UnsupportedOperationException(); throw new UnsupportedOperationException();
} }
public void todo_isnot(Object a, Object b, String name) { public void todo_isnot(Object actual, Object notExpected, String name) {
throw new UnsupportedOperationException(); throw new UnsupportedOperationException();
} }

Просмотреть файл

@ -9,7 +9,7 @@ dir-tests := $(DEPTH)/$(mobile-tests)
ANDROID_APK_NAME := robocop-debug ANDROID_APK_NAME := robocop-debug
ANDROID_EXTRA_JARS += \ ANDROID_EXTRA_JARS += \
$(srcdir)/robotium-solo-4.3.jar \ $(srcdir)/robotium-solo-4.3.1.jar \
$(NULL) $(NULL)
ANDROID_ASSETS_DIR := $(TESTPATH)/assets ANDROID_ASSETS_DIR := $(TESTPATH)/assets

Просмотреть файл

@ -4,7 +4,7 @@ Robotium is an open source tool licensed under the Apache 2.0 license and the or
source can be found here: source can be found here:
http://code.google.com/p/robotium/ http://code.google.com/p/robotium/
We are including robotium-solo-4.3.jar as a binary and are not modifying it in any way We are including robotium-solo-4.3.1.jar as a binary and are not modifying it in any way
from the original download found at: from the original download found at:
http://code.google.com/p/robotium/ http://code.google.com/p/robotium/

Двоичный файл не отображается.

Просмотреть файл

@ -3983,7 +3983,6 @@ LIBJPEG_TURBO_ASFLAGS=
LIBJPEG_TURBO_X86_ASM= LIBJPEG_TURBO_X86_ASM=
LIBJPEG_TURBO_X64_ASM= LIBJPEG_TURBO_X64_ASM=
LIBJPEG_TURBO_ARM_ASM= LIBJPEG_TURBO_ARM_ASM=
MOZ_PANGO=1
MOZ_PERMISSIONS=1 MOZ_PERMISSIONS=1
MOZ_PLACES=1 MOZ_PLACES=1
MOZ_SOCIAL=1 MOZ_SOCIAL=1
@ -4731,34 +4730,16 @@ AC_DEFINE_UNQUOTED(MOZ_DISTRIBUTION_ID,"$MOZ_DISTRIBUTION_ID")
AC_SUBST(MOZ_DISTRIBUTION_ID) AC_SUBST(MOZ_DISTRIBUTION_ID)
dnl ========================================================
dnl complex text support off by default
dnl ========================================================
MOZ_ARG_DISABLE_BOOL(pango,
[ --disable-pango Disable usage of Pango ],
MOZ_PANGO=,
MOZ_PANGO=1)
dnl ======================================================== dnl ========================================================
dnl = Pango dnl = Pango
dnl ======================================================== dnl ========================================================
if test "$MOZ_ENABLE_GTK" -o "$MOZ_ENABLE_QT" if test "$MOZ_ENABLE_GTK" -o "$MOZ_ENABLE_QT"
then then
AC_SUBST(MOZ_PANGO) PKG_CHECK_MODULES(_PANGOCHK, pango >= $PANGO_VERSION)
if test "$MOZ_PANGO" PKG_CHECK_MODULES(MOZ_PANGO, pango >= $PANGO_VERSION pangoft2 >= $PANGO_VERSION pangocairo >= $PANGO_VERSION)
then AC_SUBST(MOZ_PANGO_CFLAGS)
PKG_CHECK_MODULES(_PANGOCHK, pango >= $PANGO_VERSION) AC_SUBST(MOZ_PANGO_LIBS)
PKG_CHECK_MODULES(MOZ_PANGO, pango >= $PANGO_VERSION pangoft2 >= $PANGO_VERSION pangocairo >= $PANGO_VERSION)
AC_SUBST(MOZ_PANGO_CFLAGS)
AC_SUBST(MOZ_PANGO_LIBS)
AC_DEFINE(MOZ_PANGO)
else
PKG_CHECK_MODULES(FT2, freetype2 > 6.1.0)
AC_SUBST(FT2_CFLAGS)
AC_SUBST(FT2_LIBS)
fi
fi fi
dnl ======================================================== dnl ========================================================

Просмотреть файл

@ -642,13 +642,13 @@ nsDOMMemoryFile::DataOwner::sDataOwners;
/* static */ bool /* static */ bool
nsDOMMemoryFile::DataOwner::sMemoryReporterRegistered; nsDOMMemoryFile::DataOwner::sMemoryReporterRegistered;
NS_MEMORY_REPORTER_MALLOC_SIZEOF_FUN(DOMMemoryFileDataOwnerMallocSizeOf) MOZ_DEFINE_MALLOC_SIZE_OF(DOMMemoryFileDataOwnerMallocSizeOf)
class nsDOMMemoryFileDataOwnerMemoryReporter MOZ_FINAL class nsDOMMemoryFileDataOwnerMemoryReporter MOZ_FINAL
: public MemoryMultiReporter : public nsIMemoryReporter
{ {
public: public:
nsDOMMemoryFileDataOwnerMemoryReporter() {} NS_DECL_THREADSAFE_ISUPPORTS
NS_IMETHOD CollectReports(nsIMemoryReporterCallback *aCallback, NS_IMETHOD CollectReports(nsIMemoryReporterCallback *aCallback,
nsISupports *aClosure) nsISupports *aClosure)
@ -723,6 +723,8 @@ public:
} }
}; };
NS_IMPL_ISUPPORTS1(nsDOMMemoryFileDataOwnerMemoryReporter, nsIMemoryReporter)
/* static */ void /* static */ void
nsDOMMemoryFile::DataOwner::EnsureMemoryReporterRegistered() nsDOMMemoryFile::DataOwner::EnsureMemoryReporterRegistered()
{ {

Просмотреть файл

@ -217,8 +217,6 @@
#include "mozilla/dom/XPathEvaluator.h" #include "mozilla/dom/XPathEvaluator.h"
#include "nsIDocumentEncoder.h" #include "nsIDocumentEncoder.h"
#include "nsIStructuredCloneContainer.h" #include "nsIStructuredCloneContainer.h"
#include "nsIMutableArray.h"
#include "nsContentPermissionHelper.h"
using namespace mozilla; using namespace mozilla;
using namespace mozilla::dom; using namespace mozilla::dom;
@ -10754,11 +10752,17 @@ NS_IMPL_ISUPPORTS_INHERITED1(nsPointerLockPermissionRequest,
nsIContentPermissionRequest) nsIContentPermissionRequest)
NS_IMETHODIMP NS_IMETHODIMP
nsPointerLockPermissionRequest::GetTypes(nsIArray** aTypes) nsPointerLockPermissionRequest::GetType(nsACString& aType)
{ {
return CreatePermissionArray(NS_LITERAL_CSTRING("pointerLock"), aType = "pointerLock";
NS_LITERAL_CSTRING("unused"), return NS_OK;
aTypes); }
NS_IMETHODIMP
nsPointerLockPermissionRequest::GetAccess(nsACString& aAccess)
{
aAccess = "unused";
return NS_OK;
} }
NS_IMETHODIMP NS_IMETHODIMP

Просмотреть файл

@ -1130,13 +1130,11 @@ struct MessageManagerReferentCount
namespace mozilla { namespace mozilla {
namespace dom { namespace dom {
class MessageManagerReporter MOZ_FINAL : public MemoryMultiReporter class MessageManagerReporter MOZ_FINAL : public nsIMemoryReporter
{ {
public: public:
MessageManagerReporter() {} NS_DECL_ISUPPORTS
NS_DECL_NSIMEMORYREPORTER
NS_IMETHOD CollectReports(nsIMemoryReporterCallback* aCallback,
nsISupports* aData);
static const size_t kSuspectReferentCount = 300; static const size_t kSuspectReferentCount = 300;
protected: protected:
@ -1144,6 +1142,8 @@ protected:
MessageManagerReferentCount* aReferentCount); MessageManagerReferentCount* aReferentCount);
}; };
NS_IMPL_ISUPPORTS1(MessageManagerReporter, nsIMemoryReporter)
static PLDHashOperator static PLDHashOperator
CollectMessageListenerData(const nsAString& aKey, CollectMessageListenerData(const nsAString& aKey,
nsAutoTObserverArray<nsMessageListenerInfo, 1>* aListeners, nsAutoTObserverArray<nsMessageListenerInfo, 1>* aListeners,

Просмотреть файл

@ -85,7 +85,7 @@ WebGLMemoryTracker::CollectReports(nsIHandleReportCallback* aHandleReport,
return NS_OK; return NS_OK;
} }
NS_IMPL_ISUPPORTS_INHERITED0(WebGLMemoryTracker, MemoryMultiReporter) NS_IMPL_ISUPPORTS1(WebGLMemoryTracker, nsIMemoryReporter)
StaticRefPtr<WebGLMemoryTracker> WebGLMemoryTracker::sUniqueInstance; StaticRefPtr<WebGLMemoryTracker> WebGLMemoryTracker::sUniqueInstance;
@ -113,7 +113,7 @@ WebGLMemoryTracker::~WebGLMemoryTracker()
UnregisterWeakMemoryReporter(this); UnregisterWeakMemoryReporter(this);
} }
NS_MEMORY_REPORTER_MALLOC_SIZEOF_FUN(WebGLBufferMallocSizeOf) MOZ_DEFINE_MALLOC_SIZE_OF(WebGLBufferMallocSizeOf)
int64_t int64_t
WebGLMemoryTracker::GetBufferCacheMemoryUsed() { WebGLMemoryTracker::GetBufferCacheMemoryUsed() {
@ -131,7 +131,7 @@ WebGLMemoryTracker::GetBufferCacheMemoryUsed() {
return result; return result;
} }
NS_MEMORY_REPORTER_MALLOC_SIZEOF_FUN(WebGLShaderMallocSizeOf) MOZ_DEFINE_MALLOC_SIZE_OF(WebGLShaderMallocSizeOf)
int64_t int64_t
WebGLMemoryTracker::GetShaderSize() { WebGLMemoryTracker::GetShaderSize() {

Просмотреть файл

@ -19,9 +19,10 @@
namespace mozilla { namespace mozilla {
class WebGLMemoryTracker : public MemoryMultiReporter class WebGLMemoryTracker : public nsIMemoryReporter
{ {
NS_DECL_ISUPPORTS NS_DECL_THREADSAFE_ISUPPORTS
NS_DECL_NSIMEMORYREPORTER
WebGLMemoryTracker(); WebGLMemoryTracker();
virtual ~WebGLMemoryTracker(); virtual ~WebGLMemoryTracker();
@ -55,9 +56,6 @@ class WebGLMemoryTracker : public MemoryMultiReporter
} }
} }
NS_IMETHOD CollectReports(nsIHandleReportCallback* aHandleReport,
nsISupports* aData);
private: private:
static int64_t GetTextureMemoryUsed() { static int64_t GetTextureMemoryUsed() {
const ContextsArrayType & contexts = Contexts(); const ContextsArrayType & contexts = Contexts();

Просмотреть файл

@ -54,9 +54,10 @@ PRLogModuleInfo* gMediaDecoderLog;
#define DECODER_LOG(type, msg) #define DECODER_LOG(type, msg)
#endif #endif
class MediaMemoryTracker : public MemoryMultiReporter class MediaMemoryTracker : public nsIMemoryReporter
{ {
NS_DECL_ISUPPORTS NS_DECL_THREADSAFE_ISUPPORTS
NS_DECL_NSIMEMORYREPORTER
MediaMemoryTracker(); MediaMemoryTracker();
virtual ~MediaMemoryTracker(); virtual ~MediaMemoryTracker();
@ -93,14 +94,11 @@ public:
sUniqueInstance = nullptr; sUniqueInstance = nullptr;
} }
} }
NS_IMETHOD CollectReports(nsIHandleReportCallback* aHandleReport,
nsISupports* aData);
}; };
StaticRefPtr<MediaMemoryTracker> MediaMemoryTracker::sUniqueInstance; StaticRefPtr<MediaMemoryTracker> MediaMemoryTracker::sUniqueInstance;
NS_IMPL_ISUPPORTS_INHERITED0(MediaMemoryTracker, MemoryMultiReporter) NS_IMPL_ISUPPORTS1(MediaMemoryTracker, nsIMemoryReporter)
NS_IMPL_ISUPPORTS1(MediaDecoder, nsIObserver) NS_IMPL_ISUPPORTS1(MediaDecoder, nsIObserver)

Просмотреть файл

@ -5,7 +5,6 @@
#ifndef MEDIAENGINE_H_ #ifndef MEDIAENGINE_H_
#define MEDIAENGINE_H_ #define MEDIAENGINE_H_
#include "mozilla/RefPtr.h"
#include "nsIDOMFile.h" #include "nsIDOMFile.h"
#include "DOMMediaStream.h" #include "DOMMediaStream.h"
#include "MediaStreamGraph.h" #include "MediaStreamGraph.h"
@ -36,7 +35,7 @@ enum {
kAudioTrack = 2 kAudioTrack = 2
}; };
class MediaEngine : public RefCounted<MediaEngine> class MediaEngine
{ {
public: public:
virtual ~MediaEngine() {} virtual ~MediaEngine() {}

Просмотреть файл

@ -101,7 +101,7 @@ MediaEngineWebRTC::EnumerateVideoDevices(nsTArray<nsRefPtr<MediaEngineVideoSourc
// We've already seen this device, just append. // We've already seen this device, just append.
aVSources->AppendElement(vSource.get()); aVSources->AppendElement(vSource.get());
} else { } else {
vSource = new MediaEngineWebRTCVideoSource(mCameraManager, i); vSource = new MediaEngineWebRTCVideoSource(mCameraManager, i, mWindowId);
mVideoSources.Put(uuid, vSource); // Hashtable takes ownership. mVideoSources.Put(uuid, vSource); // Hashtable takes ownership.
aVSources->AppendElement(vSource); aVSources->AppendElement(vSource);
} }

Просмотреть файл

@ -52,7 +52,6 @@
#include "ImageContainer.h" #include "ImageContainer.h"
#include "nsGlobalWindow.h" #include "nsGlobalWindow.h"
#include "prprf.h" #include "prprf.h"
#include "nsProxyRelease.h"
#endif #endif
#include "NullTransport.h" #include "NullTransport.h"
@ -74,7 +73,7 @@ class GetCameraNameRunnable;
* mSources, mImageContainer, mSources, mState, mImage, mLastCapture * mSources, mImageContainer, mSources, mState, mImage, mLastCapture
* *
* MainThread: * MainThread:
* mDOMCameraControl, mCaptureIndex, mCameraThread, mCameraManager, * mDOMCameraControl, mCaptureIndex, mCameraThread, mWindowId, mCameraManager,
* mNativeCameraControl, mPreviewStream, mState, mLastCapture, mWidth, mHeight * mNativeCameraControl, mPreviewStream, mState, mLastCapture, mWidth, mHeight
* *
* Where mWidth, mHeight, mImage are protected by mMonitor * Where mWidth, mHeight, mImage are protected by mMonitor
@ -97,10 +96,11 @@ class MediaEngineWebRTCVideoSource : public MediaEngineVideoSource
public: public:
#ifdef MOZ_B2G_CAMERA #ifdef MOZ_B2G_CAMERA
MediaEngineWebRTCVideoSource(nsDOMCameraManager* aCameraManager, MediaEngineWebRTCVideoSource(nsDOMCameraManager* aCameraManager,
int aIndex) int aIndex, uint64_t aWindowId)
: mCameraManager(aCameraManager) : mCameraManager(aCameraManager)
, mNativeCameraControl(nullptr) , mNativeCameraControl(nullptr)
, mPreviewStream(nullptr) , mPreviewStream(nullptr)
, mWindowId(aWindowId)
, mCallbackMonitor("WebRTCCamera.CallbackMonitor") , mCallbackMonitor("WebRTCCamera.CallbackMonitor")
, mCaptureIndex(aIndex) , mCaptureIndex(aIndex)
, mMonitor("WebRTCCamera.Monitor") , mMonitor("WebRTCCamera.Monitor")
@ -223,6 +223,7 @@ private:
nsRefPtr<nsDOMCameraControl> mDOMCameraControl; nsRefPtr<nsDOMCameraControl> mDOMCameraControl;
nsRefPtr<nsGonkCameraControl> mNativeCameraControl; nsRefPtr<nsGonkCameraControl> mNativeCameraControl;
nsRefPtr<DOMCameraPreview> mPreviewStream; nsRefPtr<DOMCameraPreview> mPreviewStream;
uint64_t mWindowId;
mozilla::ReentrantMonitor mCallbackMonitor; // Monitor for camera callback handling mozilla::ReentrantMonitor mCallbackMonitor; // Monitor for camera callback handling
nsRefPtr<nsIThread> mCameraThread; nsRefPtr<nsIThread> mCameraThread;
nsRefPtr<nsIDOMFile> mLastCapture; nsRefPtr<nsIDOMFile> mLastCapture;
@ -351,14 +352,15 @@ class MediaEngineWebRTC : public MediaEngine
{ {
public: public:
#ifdef MOZ_B2G_CAMERA #ifdef MOZ_B2G_CAMERA
MediaEngineWebRTC(nsDOMCameraManager* aCameraManager) MediaEngineWebRTC(nsDOMCameraManager* aCameraManager, uint64_t aWindowId)
: mMutex("mozilla::MediaEngineWebRTC") : mMutex("mozilla::MediaEngineWebRTC")
, mVideoEngine(nullptr) , mVideoEngine(nullptr)
, mVoiceEngine(nullptr) , mVoiceEngine(nullptr)
, mVideoEngineInit(false) , mVideoEngineInit(false)
, mAudioEngineInit(false) , mAudioEngineInit(false)
, mHasTabVideoSource(false)
, mCameraManager(aCameraManager) , mCameraManager(aCameraManager)
, mWindowId(aWindowId)
, mHasTabVideoSource(false)
{ {
AsyncLatencyLogger::Get(true)->AddRef(); AsyncLatencyLogger::Get(true)->AddRef();
mLoadMonitor = new LoadMonitor(); mLoadMonitor = new LoadMonitor();
@ -399,8 +401,6 @@ private:
nsRefPtrHashtable<nsStringHashKey, MediaEngineWebRTCAudioSource > mAudioSources; nsRefPtrHashtable<nsStringHashKey, MediaEngineWebRTCAudioSource > mAudioSources;
#ifdef MOZ_B2G_CAMERA #ifdef MOZ_B2G_CAMERA
// XXX Should use nsMainThreadPtrHandle/etc
// MediaEngine hold this DOM object, and the MediaEngine is hold by Navigator // MediaEngine hold this DOM object, and the MediaEngine is hold by Navigator
// Their life time is always much longer than this object. Use a raw-pointer // Their life time is always much longer than this object. Use a raw-pointer
// here should be safe. // here should be safe.
@ -409,6 +409,7 @@ private:
// avoid any bad thing do to addref/release DOM-object on other thread, we use // avoid any bad thing do to addref/release DOM-object on other thread, we use
// raw-pointer for now. // raw-pointer for now.
nsDOMCameraManager* mCameraManager; nsDOMCameraManager* mCameraManager;
uint64_t mWindowId;
#endif #endif
nsRefPtr<LoadMonitor> mLoadMonitor; nsRefPtr<LoadMonitor> mLoadMonitor;

Просмотреть файл

@ -312,6 +312,7 @@ nsresult
MediaEngineWebRTCVideoSource::Start(SourceMediaStream* aStream, TrackID aID) MediaEngineWebRTCVideoSource::Start(SourceMediaStream* aStream, TrackID aID)
{ {
LOG((__FUNCTION__)); LOG((__FUNCTION__));
int error = 0;
if (!mInitDone || !aStream) { if (!mInitDone || !aStream) {
return NS_ERROR_FAILURE; return NS_ERROR_FAILURE;
} }
@ -340,7 +341,7 @@ MediaEngineWebRTCVideoSource::Start(SourceMediaStream* aStream, TrackID aID)
} }
#else #else
mState = kStarted; mState = kStarted;
int error = mViERender->AddRenderer(mCaptureIndex, webrtc::kVideoI420, (webrtc::ExternalRenderer*)this); error = mViERender->AddRenderer(mCaptureIndex, webrtc::kVideoI420, (webrtc::ExternalRenderer*)this);
if (error == -1) { if (error == -1) {
return NS_ERROR_FAILURE; return NS_ERROR_FAILURE;
} }
@ -491,9 +492,12 @@ void
MediaEngineWebRTCVideoSource::AllocImpl() { MediaEngineWebRTCVideoSource::AllocImpl() {
MOZ_ASSERT(NS_IsMainThread()); MOZ_ASSERT(NS_IsMainThread());
ErrorResult rv; mDOMCameraControl = new nsDOMCameraControl(mCaptureIndex,
mDOMCameraControl = mCameraManager->GetCameraControl(mCaptureIndex, mCameraThread,
this, this, rv); this,
this,
nsGlobalWindow::GetInnerWindowWithId(mWindowId));
mCameraManager->Register(mDOMCameraControl);
} }
void void
@ -502,7 +506,6 @@ MediaEngineWebRTCVideoSource::DeallocImpl() {
mNativeCameraControl->ReleaseHardware(this, this); mNativeCameraControl->ReleaseHardware(this, this);
mNativeCameraControl = nullptr; mNativeCameraControl = nullptr;
mDOMCameraControl = nullptr;
} }
void void

Просмотреть файл

@ -45,6 +45,7 @@ support-files =
skip-if = true # disabled-for-intermittent-failures--bug-701060 skip-if = true # disabled-for-intermittent-failures--bug-701060
[test_length.xhtml] [test_length.xhtml]
skip-if = true skip-if = true
[test_lengthParsing.html]
[test_nonAnimStrings.xhtml] [test_nonAnimStrings.xhtml]
[test_non-scaling-stroke.html] [test_non-scaling-stroke.html]
[test_pathAnimInterpolation.xhtml] [test_pathAnimInterpolation.xhtml]

Просмотреть файл

@ -0,0 +1,77 @@
<!doctype html>
<html>
<!--
https://bugzilla.mozilla.org/show_bug.cgi?id=946529
-->
<head>
<meta charset="utf-8">
<title>Test transform parsing</title>
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
</head>
<body>
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=946529">Mozilla Bug 946529</a>
<p id="display"></p>
<div id="content" style="display: none">
<svg width="100%" height="1" id="svg">
<rect id="rect"/>
</svg>
</div>
<pre id="test">
<script class="testbody" type="text/javascript">
// Test cases
checkParseOk("", 0);
checkParseOk("-.1", -0.1);
checkParseOk("1e1", 10);
checkParseOk("1em", 1, "em");
checkParseOk("1ex", 1, "ex");
checkParseOk("1e1em", 10, "em");
checkParseOk("1E+2", 100);
checkParseOk(".1e-2", 0.001);
// Fail cases
checkParseFail("1e");
checkParseFail("1 e");
checkParseFail("1 em");
checkParseFail("1ee");
function checkParseOk(spec, valueInUnits, units) {
var rect = document.getElementById("rect");
// Clear previous value
rect.removeAttribute("x");
rect.setAttribute("x", spec);
// Check number part
const tolerance = 1 / 65535;
var actual = rect.x.baseVal.valueInSpecifiedUnits;
ok(Math.abs(actual - valueInUnits) < tolerance,
spec + ' (value) - got ' + actual + ', expected ' + valueInUnits);
// Check unit part
var unitMapping = {
"unknown": SVGLength.SVG_LENGTHTYPE_UNKNOWN,
"": SVGLength.SVG_LENGTHTYPE_NUMBER,
"%": SVGLength.SVG_LENGTHTYPE_PERCENTAGE,
"em": SVGLength.SVG_LENGTHTYPE_EMS,
"ex": SVGLength.SVG_LENGTHTYPE_EXS,
"px": SVGLength.SVG_LENGTHTYPE_PX,
"cm": SVGLength.SVG_LENGTHTYPE_CM,
"mm": SVGLength.SVG_LENGTHTYPE_MM,
"in": SVGLength.SVG_LENGTHTYPE_IN,
"pt": SVGLength.SVG_LENGTHTYPE_PT,
"pc": SVGLength.SVG_LENGTHTYPE_PC
};
if (typeof units == "undefined") {
units = "";
}
ise(rect.x.baseVal.unitType, unitMapping[units], spec + " (unit)");
}
function checkParseFail(spec) {
checkParseOk(spec, 0);
}
</script>
</pre>
</body>
</html>

Просмотреть файл

@ -323,11 +323,6 @@ this.PermissionsTable = { geolocation: {
privileged: DENY_ACTION, privileged: DENY_ACTION,
certified: ALLOW_ACTION certified: ALLOW_ACTION
}, },
"video-capture": {
app: PROMPT_ACTION,
privileged: PROMPT_ACTION,
certified: PROMPT_ACTION
},
}; };
/** /**

Просмотреть файл

@ -21,7 +21,6 @@
#include "mozilla/dom/quota/QuotaObject.h" #include "mozilla/dom/quota/QuotaObject.h"
#include "mozilla/dom/quota/UsageInfo.h" #include "mozilla/dom/quota/UsageInfo.h"
#include "mozilla/unused.h" #include "mozilla/unused.h"
#include "nsContentUtils.h"
#include "nsIAtom.h" #include "nsIAtom.h"
#include "nsIFile.h" #include "nsIFile.h"
#include "nsIPrincipal.h" #include "nsIPrincipal.h"
@ -975,7 +974,7 @@ DeallocEntryChild(PAsmJSCacheEntryChild* aActor)
namespace { namespace {
bool bool
OpenFile(JS::Handle<JSObject*> aGlobal, OpenFile(nsIPrincipal* aPrincipal,
OpenMode aOpenMode, OpenMode aOpenMode,
size_t aSizeToWrite, size_t aSizeToWrite,
File::AutoClose* aFile) File::AutoClose* aFile)
@ -998,17 +997,14 @@ OpenFile(JS::Handle<JSObject*> aGlobal,
return false; return false;
} }
// This assumes a non-worker global.
nsIPrincipal* principal = nsContentUtils::GetObjectPrincipal(aGlobal);
// If we are in a child process, we need to synchronously call into the // If we are in a child process, we need to synchronously call into the
// parent process to open the file and interact with the QuotaManager. The // parent process to open the file and interact with the QuotaManager. The
// child can then map the file into its address space to perform I/O. // child can then map the file into its address space to perform I/O.
nsRefPtr<File> file; nsRefPtr<File> file;
if (IsMainProcess()) { if (IsMainProcess()) {
file = new SingleProcessRunnable(principal, aOpenMode, aSizeToWrite); file = new SingleProcessRunnable(aPrincipal, aOpenMode, aSizeToWrite);
} else { } else {
file = new ChildProcessRunnable(principal, aOpenMode, aSizeToWrite); file = new ChildProcessRunnable(aPrincipal, aOpenMode, aSizeToWrite);
} }
if (!file->BlockUntilOpen(aFile)) { if (!file->BlockUntilOpen(aFile)) {
@ -1028,7 +1024,7 @@ static const uint32_t sAsmJSCookie = 0x600d600d;
static const size_t sMinCachedModuleLength = 10000; static const size_t sMinCachedModuleLength = 10000;
bool bool
OpenEntryForRead(JS::Handle<JSObject*> aGlobal, OpenEntryForRead(nsIPrincipal* aPrincipal,
const jschar* aBegin, const jschar* aBegin,
const jschar* aLimit, const jschar* aLimit,
size_t* aSize, size_t* aSize,
@ -1040,7 +1036,7 @@ OpenEntryForRead(JS::Handle<JSObject*> aGlobal,
} }
File::AutoClose file; File::AutoClose file;
if (!OpenFile(aGlobal, eOpenForRead, 0, &file)) { if (!OpenFile(aPrincipal, eOpenForRead, 0, &file)) {
return false; return false;
} }
@ -1082,7 +1078,7 @@ CloseEntryForRead(JS::Handle<JSObject*> global,
} }
bool bool
OpenEntryForWrite(JS::Handle<JSObject*> aGlobal, OpenEntryForWrite(nsIPrincipal* aPrincipal,
const jschar* aBegin, const jschar* aBegin,
const jschar* aEnd, const jschar* aEnd,
size_t aSize, size_t aSize,
@ -1097,7 +1093,7 @@ OpenEntryForWrite(JS::Handle<JSObject*> aGlobal,
aSize += sizeof(AsmJSCookieType); aSize += sizeof(AsmJSCookieType);
File::AutoClose file; File::AutoClose file;
if (!OpenFile(aGlobal, eOpenForWrite, aSize, &file)) { if (!OpenFile(aPrincipal, eOpenForWrite, aSize, &file)) {
return false; return false;
} }

Просмотреть файл

@ -32,10 +32,20 @@ enum OpenMode
NUM_OPEN_MODES NUM_OPEN_MODES
}; };
// Implementation of AsmJSCacheOps, installed by nsJSEnvironment: // Implementation of AsmJSCacheOps, installed for the main JSRuntime by
// nsJSEnvironment.cpp and DOM Worker JSRuntimes in RuntimeService.cpp.
//
// The Open* functions cannot be called directly from AsmJSCacheOps: they take
// an nsIPrincipal as the first argument instead of a Handle<JSObject*>. The
// caller must map the object to an nsIPrincipal.
//
// These methods may be called off the main thread and guarantee not to
// access the given aPrincipal except on the main thread. In exchange, the
// caller must ensure the given principal is alive from when OpenEntryForX is
// called to when CloseEntryForX returns.
bool bool
OpenEntryForRead(JS::Handle<JSObject*> aGlobal, OpenEntryForRead(nsIPrincipal* aPrincipal,
const jschar* aBegin, const jschar* aBegin,
const jschar* aLimit, const jschar* aLimit,
size_t* aSize, size_t* aSize,
@ -47,7 +57,7 @@ CloseEntryForRead(JS::Handle<JSObject*> aGlobal,
const uint8_t* aMemory, const uint8_t* aMemory,
intptr_t aHandle); intptr_t aHandle);
bool bool
OpenEntryForWrite(JS::Handle<JSObject*> aGlobal, OpenEntryForWrite(nsIPrincipal* aPrincipal,
const jschar* aBegin, const jschar* aBegin,
const jschar* aEnd, const jschar* aEnd,
size_t aSize, size_t aSize,

Просмотреть файл

@ -6,156 +6,20 @@
#include "GonkPermission.h" #include "GonkPermission.h"
#include "mozilla/dom/ContentParent.h" #include "mozilla/dom/ContentParent.h"
#endif // MOZ_WIDGET_GONK #endif // MOZ_WIDGET_GONK
#include "nsContentPermissionHelper.h"
#include "nsIContentPermissionPrompt.h"
#include "nsCOMPtr.h" #include "nsCOMPtr.h"
#include "nsIDOMElement.h" #include "nsIDOMElement.h"
#include "nsIPrincipal.h" #include "nsIPrincipal.h"
#include "mozilla/dom/Element.h" #include "mozilla/dom/Element.h"
#include "mozilla/dom/PContentPermission.h"
#include "mozilla/dom/PermissionMessageUtils.h"
#include "mozilla/dom/PContentPermissionRequestParent.h"
#include "mozilla/dom/TabParent.h" #include "mozilla/dom/TabParent.h"
#include "mozilla/unused.h" #include "mozilla/unused.h"
#include "nsComponentManagerUtils.h" #include "nsComponentManagerUtils.h"
#include "nsArrayUtils.h"
#include "nsIMutableArray.h"
#include "nsContentPermissionHelper.h"
using mozilla::unused; // <snicker> using mozilla::unused; // <snicker>
using namespace mozilla::dom; using namespace mozilla::dom;
using namespace mozilla; using namespace mozilla;
namespace mozilla {
namespace dom {
class ContentPermissionRequestParent : public PContentPermissionRequestParent
{
public:
ContentPermissionRequestParent(const nsTArray<PermissionRequest>& aRequests,
Element* element,
const IPC::Principal& principal);
virtual ~ContentPermissionRequestParent();
bool IsBeingDestroyed();
nsCOMPtr<nsIPrincipal> mPrincipal;
nsCOMPtr<Element> mElement;
nsCOMPtr<nsContentPermissionRequestProxy> mProxy;
nsTArray<PermissionRequest> mRequests;
private:
virtual bool Recvprompt();
virtual void ActorDestroy(ActorDestroyReason why);
};
ContentPermissionRequestParent::ContentPermissionRequestParent(const nsTArray<PermissionRequest>& aRequests,
Element* aElement,
const IPC::Principal& aPrincipal)
{
MOZ_COUNT_CTOR(ContentPermissionRequestParent);
mPrincipal = aPrincipal;
mElement = aElement;
mRequests = aRequests;
}
ContentPermissionRequestParent::~ContentPermissionRequestParent()
{
MOZ_COUNT_DTOR(ContentPermissionRequestParent);
}
bool
ContentPermissionRequestParent::Recvprompt()
{
mProxy = new nsContentPermissionRequestProxy();
NS_ASSERTION(mProxy, "Alloc of request proxy failed");
if (NS_FAILED(mProxy->Init(mRequests, this))) {
mProxy->Cancel();
}
return true;
}
void
ContentPermissionRequestParent::ActorDestroy(ActorDestroyReason why)
{
if (mProxy) {
mProxy->OnParentDestroyed();
}
}
bool
ContentPermissionRequestParent::IsBeingDestroyed()
{
// When TabParent::Destroy() is called, we are being destroyed. It's unsafe
// to send out any message now.
TabParent* tabParent = static_cast<TabParent*>(Manager());
return tabParent->IsDestroyed();
}
NS_IMPL_ISUPPORTS1(ContentPermissionType, nsIContentPermissionType)
ContentPermissionType::ContentPermissionType(const nsACString& aType,
const nsACString& aAccess)
{
mType = aType;
mAccess = aAccess;
}
ContentPermissionType::~ContentPermissionType()
{
}
NS_IMETHODIMP
ContentPermissionType::GetType(nsACString& aType)
{
aType = mType;
return NS_OK;
}
NS_IMETHODIMP
ContentPermissionType::GetAccess(nsACString& aAccess)
{
aAccess = mAccess;
return NS_OK;
}
uint32_t
ConvertPermissionRequestToArray(nsTArray<PermissionRequest>& aSrcArray,
nsIMutableArray* aDesArray)
{
uint32_t len = aSrcArray.Length();
for (uint32_t i = 0; i < len; i++) {
nsRefPtr<ContentPermissionType> cpt =
new ContentPermissionType(aSrcArray[i].type(), aSrcArray[i].access());
aDesArray->AppendElement(cpt, false);
}
return len;
}
nsresult
CreatePermissionArray(const nsACString& aType,
const nsACString& aAccess,
nsIArray** aTypesArray)
{
nsCOMPtr<nsIMutableArray> types = do_CreateInstance(NS_ARRAY_CONTRACTID);
nsRefPtr<ContentPermissionType> permType = new ContentPermissionType(aType,
aAccess);
types->AppendElement(permType, false);
types.forget(aTypesArray);
return NS_OK;
}
PContentPermissionRequestParent*
CreateContentPermissionRequestParent(const nsTArray<PermissionRequest>& aRequests,
Element* element,
const IPC::Principal& principal)
{
return new ContentPermissionRequestParent(aRequests, element, principal);
}
} // namespace dom
} // namespace mozilla
nsContentPermissionRequestProxy::nsContentPermissionRequestProxy() nsContentPermissionRequestProxy::nsContentPermissionRequestProxy()
{ {
MOZ_COUNT_CTOR(nsContentPermissionRequestProxy); MOZ_COUNT_CTOR(nsContentPermissionRequestProxy);
@ -167,12 +31,14 @@ nsContentPermissionRequestProxy::~nsContentPermissionRequestProxy()
} }
nsresult nsresult
nsContentPermissionRequestProxy::Init(const nsTArray<PermissionRequest>& requests, nsContentPermissionRequestProxy::Init(const nsACString & type,
const nsACString & access,
ContentPermissionRequestParent* parent) ContentPermissionRequestParent* parent)
{ {
NS_ASSERTION(parent, "null parent"); NS_ASSERTION(parent, "null parent");
mParent = parent; mParent = parent;
mPermissionRequests = requests; mType = type;
mAccess = access;
nsCOMPtr<nsIContentPermissionPrompt> prompt = do_CreateInstance(NS_CONTENT_PERMISSION_PROMPT_CONTRACTID); nsCOMPtr<nsIContentPermissionPrompt> prompt = do_CreateInstance(NS_CONTENT_PERMISSION_PROMPT_CONTRACTID);
if (!prompt) { if (!prompt) {
@ -192,14 +58,17 @@ nsContentPermissionRequestProxy::OnParentDestroyed()
NS_IMPL_ISUPPORTS1(nsContentPermissionRequestProxy, nsIContentPermissionRequest) NS_IMPL_ISUPPORTS1(nsContentPermissionRequestProxy, nsIContentPermissionRequest)
NS_IMETHODIMP NS_IMETHODIMP
nsContentPermissionRequestProxy::GetTypes(nsIArray** aTypes) nsContentPermissionRequestProxy::GetType(nsACString & aType)
{ {
nsCOMPtr<nsIMutableArray> types = do_CreateInstance(NS_ARRAY_CONTRACTID); aType = mType;
if (ConvertPermissionRequestToArray(mPermissionRequests, types)) { return NS_OK;
types.forget(aTypes); }
return NS_OK;
} NS_IMETHODIMP
return NS_ERROR_FAILURE; nsContentPermissionRequestProxy::GetAccess(nsACString & aAccess)
{
aAccess = mAccess;
return NS_OK;
} }
NS_IMETHODIMP NS_IMETHODIMP
@ -267,18 +136,10 @@ nsContentPermissionRequestProxy::Allow()
} }
#ifdef MOZ_WIDGET_GONK #ifdef MOZ_WIDGET_GONK
uint32_t len = mPermissionRequests.Length(); if (mType.Equals("audio-capture")) {
for (uint32_t i = 0; i < len; i++) { GonkPermissionService::GetInstance()->addGrantInfo(
if (mPermissionRequests[i].type().Equals("audio-capture")) { "android.permission.RECORD_AUDIO",
GonkPermissionService::GetInstance()->addGrantInfo( static_cast<TabParent*>(mParent->Manager())->Manager()->Pid());
"android.permission.RECORD_AUDIO",
static_cast<TabParent*>(mParent->Manager())->Manager()->Pid());
}
if (mPermissionRequests[i].type().Equals("video-capture")) {
GonkPermissionService::GetInstance()->addGrantInfo(
"android.permission.CAMERA",
static_cast<TabParent*>(mParent->Manager())->Manager()->Pid());
}
} }
#endif #endif
@ -286,3 +147,55 @@ nsContentPermissionRequestProxy::Allow()
mParent = nullptr; mParent = nullptr;
return NS_OK; return NS_OK;
} }
namespace mozilla {
namespace dom {
ContentPermissionRequestParent::ContentPermissionRequestParent(const nsACString& aType,
const nsACString& aAccess,
Element* aElement,
const IPC::Principal& aPrincipal)
{
MOZ_COUNT_CTOR(ContentPermissionRequestParent);
mPrincipal = aPrincipal;
mElement = aElement;
mType = aType;
mAccess = aAccess;
}
ContentPermissionRequestParent::~ContentPermissionRequestParent()
{
MOZ_COUNT_DTOR(ContentPermissionRequestParent);
}
bool
ContentPermissionRequestParent::Recvprompt()
{
mProxy = new nsContentPermissionRequestProxy();
NS_ASSERTION(mProxy, "Alloc of request proxy failed");
if (NS_FAILED(mProxy->Init(mType, mAccess, this))) {
mProxy->Cancel();
}
return true;
}
void
ContentPermissionRequestParent::ActorDestroy(ActorDestroyReason why)
{
if (mProxy) {
mProxy->OnParentDestroyed();
}
}
bool
ContentPermissionRequestParent::IsBeingDestroyed()
{
// When TabParent::Destroy() is called, we are being destroyed. It's unsafe
// to send out any message now.
TabParent* tabParent = static_cast<TabParent*>(Manager());
return tabParent->IsDestroyed();
}
} // namespace dom
} // namespace mozilla

Просмотреть файл

@ -6,75 +6,60 @@
#define nsContentPermissionHelper_h #define nsContentPermissionHelper_h
#include "nsIContentPermissionPrompt.h" #include "nsIContentPermissionPrompt.h"
#include "nsTArray.h" #include "nsString.h"
#include "nsIMutableArray.h"
#include "mozilla/dom/PermissionMessageUtils.h"
#include "mozilla/dom/PContentPermissionRequestParent.h"
class nsContentPermissionRequestProxy; class nsContentPermissionRequestProxy;
// Forward declare IPC::Principal here which is defined in
// PermissionMessageUtils.h. Include this file will transitively includes
// "windows.h" and it defines
// #define CreateEvent CreateEventW
// #define LoadImage LoadImageW
// That will mess up windows build.
namespace IPC {
class Principal;
}
namespace mozilla { namespace mozilla {
namespace dom { namespace dom {
class Element; class Element;
class PermissionRequest;
class ContentPermissionRequestParent;
class PContentPermissionRequestParent;
class ContentPermissionType : public nsIContentPermissionType class ContentPermissionRequestParent : public PContentPermissionRequestParent
{ {
public: public:
NS_DECL_ISUPPORTS ContentPermissionRequestParent(const nsACString& type,
NS_DECL_NSICONTENTPERMISSIONTYPE const nsACString& access,
Element* element,
const IPC::Principal& principal);
virtual ~ContentPermissionRequestParent();
ContentPermissionType(const nsACString& aType, const nsACString& aAccess); bool IsBeingDestroyed();
virtual ~ContentPermissionType();
protected: nsCOMPtr<nsIPrincipal> mPrincipal;
nsCOMPtr<Element> mElement;
nsCOMPtr<nsContentPermissionRequestProxy> mProxy;
nsCString mType; nsCString mType;
nsCString mAccess; nsCString mAccess;
private:
virtual bool Recvprompt();
virtual void ActorDestroy(ActorDestroyReason why);
}; };
uint32_t ConvertPermissionRequestToArray(nsTArray<PermissionRequest>& aSrcArray,
nsIMutableArray* aDesArray);
nsresult CreatePermissionArray(const nsACString& aType,
const nsACString& aAccess,
nsIArray** aTypesArray);
PContentPermissionRequestParent*
CreateContentPermissionRequestParent(const nsTArray<PermissionRequest>& aRequests,
Element* element,
const IPC::Principal& principal);
} // namespace dom } // namespace dom
} // namespace mozilla } // namespace mozilla
class nsContentPermissionRequestProxy : public nsIContentPermissionRequest class nsContentPermissionRequestProxy : public nsIContentPermissionRequest
{ {
public: public:
NS_DECL_ISUPPORTS
NS_DECL_NSICONTENTPERMISSIONREQUEST
nsContentPermissionRequestProxy(); nsContentPermissionRequestProxy();
virtual ~nsContentPermissionRequestProxy(); virtual ~nsContentPermissionRequestProxy();
nsresult Init(const nsTArray<mozilla::dom::PermissionRequest>& requests, nsresult Init(const nsACString& type, const nsACString& access, mozilla::dom::ContentPermissionRequestParent* parent);
mozilla::dom::ContentPermissionRequestParent* parent);
void OnParentDestroyed(); void OnParentDestroyed();
NS_DECL_ISUPPORTS
NS_DECL_NSICONTENTPERMISSIONREQUEST
private: private:
// Non-owning pointer to the ContentPermissionRequestParent object which owns this proxy. // Non-owning pointer to the ContentPermissionRequestParent object which owns this proxy.
mozilla::dom::ContentPermissionRequestParent* mParent; mozilla::dom::ContentPermissionRequestParent* mParent;
nsTArray<mozilla::dom::PermissionRequest> mPermissionRequests; nsCString mType;
nsCString mAccess;
}; };
#endif // nsContentPermissionHelper_h #endif // nsContentPermissionHelper_h

Просмотреть файл

@ -1687,7 +1687,7 @@ ReportAndDump(JSContext *cx, unsigned argc, JS::Value *vp)
dmd::ClearReports(); dmd::ClearReports();
fprintf(stderr, "DMD: running reporters...\n"); fprintf(stderr, "DMD: running reporters...\n");
dmd::RunReporters(); dmd::RunReportersForThisProcess();
dmd::Writer writer(FpWrite, fp); dmd::Writer writer(FpWrite, fp);
dmd::Dump(writer); dmd::Dump(writer);
@ -2831,6 +2831,32 @@ NS_DOMStructuredCloneError(JSContext* cx,
xpc::Throw(cx, NS_ERROR_DOM_DATA_CLONE_ERR); xpc::Throw(cx, NS_ERROR_DOM_DATA_CLONE_ERR);
} }
static bool
AsmJSCacheOpenEntryForRead(JS::Handle<JSObject*> aGlobal,
const jschar* aBegin,
const jschar* aLimit,
size_t* aSize,
const uint8_t** aMemory,
intptr_t *aHandle)
{
nsIPrincipal* principal = nsContentUtils::GetObjectPrincipal(aGlobal);
return asmjscache::OpenEntryForRead(principal, aBegin, aLimit, aSize, aMemory,
aHandle);
}
static bool
AsmJSCacheOpenEntryForWrite(JS::Handle<JSObject*> aGlobal,
const jschar* aBegin,
const jschar* aEnd,
size_t aSize,
uint8_t** aMemory,
intptr_t* aHandle)
{
nsIPrincipal* principal = nsContentUtils::GetObjectPrincipal(aGlobal);
return asmjscache::OpenEntryForWrite(principal, aBegin, aEnd, aSize, aMemory,
aHandle);
}
static NS_DEFINE_CID(kDOMScriptObjectFactoryCID, NS_DOM_SCRIPT_OBJECT_FACTORY_CID); static NS_DEFINE_CID(kDOMScriptObjectFactoryCID, NS_DOM_SCRIPT_OBJECT_FACTORY_CID);
void void
@ -2879,9 +2905,9 @@ nsJSContext::EnsureStatics()
// Set up the asm.js cache callbacks // Set up the asm.js cache callbacks
static JS::AsmJSCacheOps asmJSCacheOps = { static JS::AsmJSCacheOps asmJSCacheOps = {
asmjscache::OpenEntryForRead, AsmJSCacheOpenEntryForRead,
asmjscache::CloseEntryForRead, asmjscache::CloseEntryForRead,
asmjscache::OpenEntryForWrite, AsmJSCacheOpenEntryForWrite,
asmjscache::CloseEntryForWrite, asmjscache::CloseEntryForWrite,
asmjscache::GetBuildId asmjscache::GetBuildId
}; };

Просмотреть файл

@ -166,7 +166,7 @@ AppendWindowURI(nsGlobalWindow *aWindow, nsACString& aStr)
} }
} }
NS_MEMORY_REPORTER_MALLOC_SIZEOF_FUN(WindowsMallocSizeOf) MOZ_DEFINE_MALLOC_SIZE_OF(WindowsMallocSizeOf)
// The key is the window ID. // The key is the window ID.
typedef nsDataHashtable<nsUint64HashKey, nsCString> WindowPaths; typedef nsDataHashtable<nsUint64HashKey, nsCString> WindowPaths;

Просмотреть файл

@ -7652,8 +7652,13 @@ class CGProxySpecialOperation(CGPerSignatureCall):
""" """
Base class for classes for calling an indexed or named special operation Base class for classes for calling an indexed or named special operation
(don't use this directly, use the derived classes below). (don't use this directly, use the derived classes below).
If checkFound is False, will just assert that the prop is found instead of
checking that it is before wrapping the value.
""" """
def __init__(self, descriptor, operation): def __init__(self, descriptor, operation, checkFound=True):
self.checkFound = checkFound;
nativeName = MakeNativeName(descriptor.binaryNames.get(operation, operation)) nativeName = MakeNativeName(descriptor.binaryNames.get(operation, operation))
operation = descriptor.operations[operation] operation = descriptor.operations[operation]
assert len(operation.signatures()) == 1 assert len(operation.signatures()) == 1
@ -7699,15 +7704,26 @@ class CGProxySpecialOperation(CGPerSignatureCall):
return "" return ""
wrap = CGGeneric(wrapForType(self.returnType, self.descriptor, self.templateValues)) wrap = CGGeneric(wrapForType(self.returnType, self.descriptor, self.templateValues))
wrap = CGIfWrapper(wrap, "found") if self.checkFound:
wrap = CGIfWrapper(wrap, "found")
else:
wrap = CGList([CGGeneric("MOZ_ASSERT(found);"), wrap], "\n")
return "\n" + wrap.define() return "\n" + wrap.define()
class CGProxyIndexedOperation(CGProxySpecialOperation): class CGProxyIndexedOperation(CGProxySpecialOperation):
""" """
Class to generate a call to an indexed operation. Class to generate a call to an indexed operation.
If doUnwrap is False, the caller is responsible for making sure a variable
named 'self' holds the C++ object somewhere where the code we generate
will see it.
If checkFound is False, will just assert that the prop is found instead of
checking that it is before wrapping the value.
""" """
def __init__(self, descriptor, name): def __init__(self, descriptor, name, doUnwrap=True, checkFound=True):
CGProxySpecialOperation.__init__(self, descriptor, name) self.doUnwrap = doUnwrap
CGProxySpecialOperation.__init__(self, descriptor, name, checkFound)
def define(self): def define(self):
# Our first argument is the id we're getting. # Our first argument is the id we're getting.
argName = self.arguments[0].identifier.name argName = self.arguments[0].identifier.name
@ -7716,18 +7732,30 @@ class CGProxyIndexedOperation(CGProxySpecialOperation):
setIndex = "" setIndex = ""
else: else:
setIndex = "uint32_t %s = index;\n" % argName setIndex = "uint32_t %s = index;\n" % argName
return (setIndex + if self.doUnwrap:
"%s* self = UnwrapProxy(proxy);\n" + unwrap = "%s* self = UnwrapProxy(proxy);\n"
else:
unwrap = ""
return (setIndex + unwrap +
CGProxySpecialOperation.define(self)) CGProxySpecialOperation.define(self))
class CGProxyIndexedGetter(CGProxyIndexedOperation): class CGProxyIndexedGetter(CGProxyIndexedOperation):
""" """
Class to generate a call to an indexed getter. If templateValues is not None Class to generate a call to an indexed getter. If templateValues is not None
the returned value will be wrapped with wrapForType using templateValues. the returned value will be wrapped with wrapForType using templateValues.
If doUnwrap is False, the caller is responsible for making sure a variable
named 'self' holds the C++ object somewhere where the code we generate
will see it.
If checkFound is False, will just assert that the prop is found instead of
checking that it is before wrapping the value.
""" """
def __init__(self, descriptor, templateValues=None): def __init__(self, descriptor, templateValues=None, doUnwrap=True,
checkFound=True):
self.templateValues = templateValues self.templateValues = templateValues
CGProxyIndexedOperation.__init__(self, descriptor, 'IndexedGetter') CGProxyIndexedOperation.__init__(self, descriptor, 'IndexedGetter',
doUnwrap, checkFound)
class CGProxyIndexedPresenceChecker(CGProxyIndexedGetter): class CGProxyIndexedPresenceChecker(CGProxyIndexedGetter):
""" """
@ -8364,65 +8392,55 @@ class CGDOMJSProxyHandler_finalize(ClassMethod):
return ("%s self = UnwrapProxy(proxy);\n\n" % (self.descriptor.nativeType + "*") + return ("%s self = UnwrapProxy(proxy);\n\n" % (self.descriptor.nativeType + "*") +
finalizeHook(self.descriptor, FINALIZE_HOOK_NAME, self.args[0].name).define()) finalizeHook(self.descriptor, FINALIZE_HOOK_NAME, self.args[0].name).define())
class CGDOMJSProxyHandler_getElementIfPresent(ClassMethod): class CGDOMJSProxyHandler_slice(ClassMethod):
def __init__(self, descriptor): def __init__(self, descriptor):
assert descriptor.supportsIndexedProperties()
args = [Argument('JSContext*', 'cx'), args = [Argument('JSContext*', 'cx'),
Argument('JS::Handle<JSObject*>', 'proxy'), Argument('JS::Handle<JSObject*>', 'proxy'),
Argument('JS::Handle<JSObject*>', 'receiver'), Argument('uint32_t', 'begin'),
Argument('uint32_t', 'index'), Argument('uint32_t', 'end'),
Argument('JS::MutableHandle<JS::Value>', 'vp'), Argument('JS::Handle<JSObject*>', 'array')]
Argument('bool*', 'present')] ClassMethod.__init__(self, "slice", "bool", args)
ClassMethod.__init__(self, "getElementIfPresent", "bool", args)
self.descriptor = descriptor self.descriptor = descriptor
def getBody(self): def getBody(self):
successCode = ("*present = found;\n" # Just like getOwnPropertyNames we'll assume that we have no holes, so
"return true;") # we have all properties from 0 to length. If that ever changes
templateValues = {'jsvalRef': 'vp', 'jsvalHandle': 'vp', # (unlikely), we'll need to do something a bit more clever with how we
# forward on to our ancestor.
header = CGGeneric(
'JS::Rooted<JS::Value> temp(cx);\n'
'MOZ_ASSERT(!xpc::WrapperFactory::IsXrayWrapper(proxy),\n'
' "Should not have a XrayWrapper here");\n'
'\n'
'%s* self = UnwrapProxy(proxy);\n'
'uint32_t length = self->Length();\n'
"// Compute the end of the indices we'll get ourselves\n"
'uint32_t ourEnd = std::max(begin, std::min(end, length));' %
self.descriptor.nativeType)
successCode = ("js::UnsafeDefineElement(cx, array, index - begin, temp);\n"
"continue;")
templateValues = {'jsvalRef': 'temp', 'jsvalHandle': '&temp',
'obj': 'proxy', 'successCode': successCode} 'obj': 'proxy', 'successCode': successCode}
if self.descriptor.supportsIndexedProperties(): get = CGProxyIndexedGetter(self.descriptor, templateValues, False, False)
get = (CGProxyIndexedGetter(self.descriptor, templateValues).define() + "\n"
"// We skip the expando object and any named getters if\n"
"// there is an indexed getter.\n" +
"\n") % (self.descriptor.nativeType)
else:
if self.descriptor.supportsNamedProperties():
get = CGProxyNamedGetter(self.descriptor, templateValues,
"UINT_TO_JSVAL(index)").define()
get += """
JS::Rooted<JSObject*> expando(cx, GetExpandoObject(proxy)); getOurElements = CGWrapper(
if (expando) { CGIndenter(get),
bool isPresent; pre="for (uint32_t index = begin; index < ourEnd; ++index) {\n",
if (!JS_GetElementIfPresent(cx, expando, index, expando, vp, &isPresent)) { post="\n}")
return false;
}
if (isPresent) {
*present = true;
return true;
}
}
"""
return """MOZ_ASSERT(!xpc::WrapperFactory::IsXrayWrapper(proxy), getProtoElements = CGIfWrapper(
"Should not have a XrayWrapper here"); CGGeneric("JS::Rooted<JSObject*> proto(cx);\n"
"if (!js::GetObjectProto(cx, proxy, &proto)) {\n"
" return false;\n"
"}\n"
"return js::SliceSlowly(cx, proto, proxy, ourEnd, end, array);"),
"end > ourEnd")
""" + get + """ return CGList([header, getOurElements, getProtoElements,
JS::Rooted<JSObject*> proto(cx); CGGeneric("return true;")], "\n\n").define();
if (!js::GetObjectProto(cx, proxy, &proto)) {
return false;
}
if (proto) {
bool isPresent;
if (!JS_GetElementIfPresent(cx, proto, index, proxy, vp, &isPresent)) {
return false;
}
*present = isPresent;
return true;
}
*present = false;
// Can't Debug_SetValueRangeToCrashOnTouch because it's not public
return true;"""
class CGDOMJSProxyHandler_getInstance(ClassMethod): class CGDOMJSProxyHandler_getInstance(ClassMethod):
def __init__(self): def __init__(self):
@ -8446,9 +8464,11 @@ class CGDOMJSProxyHandler(CGClass):
CGDOMJSProxyHandler_className(descriptor), CGDOMJSProxyHandler_className(descriptor),
CGDOMJSProxyHandler_finalizeInBackground(descriptor), CGDOMJSProxyHandler_finalizeInBackground(descriptor),
CGDOMJSProxyHandler_finalize(descriptor), CGDOMJSProxyHandler_finalize(descriptor),
CGDOMJSProxyHandler_getElementIfPresent(descriptor),
CGDOMJSProxyHandler_getInstance(), CGDOMJSProxyHandler_getInstance(),
CGDOMJSProxyHandler_delete(descriptor)] CGDOMJSProxyHandler_delete(descriptor)]
if descriptor.supportsIndexedProperties():
methods.append(CGDOMJSProxyHandler_slice(descriptor))
CGClass.__init__(self, 'DOMProxyHandler', CGClass.__init__(self, 'DOMProxyHandler',
bases=[ClassBase('mozilla::dom::DOMProxyHandler')], bases=[ClassBase('mozilla::dom::DOMProxyHandler')],
constructors=constructors, constructors=constructors,

Просмотреть файл

@ -105,31 +105,6 @@ nsDOMCameraManager::CreateInstance(nsPIDOMWindow* aWindow)
return cameraManager.forget(); return cameraManager.forget();
} }
nsDOMCameraControl*
nsDOMCameraManager::GetCameraControl(uint32_t aDeviceNum,
nsICameraGetCameraCallback* onSuccess,
nsICameraErrorCallback* onError,
ErrorResult& aRv)
{
aRv = NS_OK;
// reuse the same camera thread to conserve resources
if (!mCameraThread) {
aRv = NS_NewThread(getter_AddRefs(mCameraThread));
if (aRv.Failed()) {
return nullptr;
}
}
// Creating this object will trigger the onSuccess handler
nsDOMCameraControl* cameraControl = new nsDOMCameraControl(aDeviceNum, mCameraThread,
onSuccess, onError, mWindow);
if (cameraControl) {
Register(cameraControl);
}
return cameraControl;
}
void void
nsDOMCameraManager::GetCamera(const CameraSelector& aOptions, nsDOMCameraManager::GetCamera(const CameraSelector& aOptions,
nsICameraGetCameraCallback* onSuccess, nsICameraGetCameraCallback* onSuccess,
@ -141,10 +116,22 @@ nsDOMCameraManager::GetCamera(const CameraSelector& aOptions,
cameraId = 1; cameraId = 1;
} }
// reuse the same camera thread to conserve resources
if (!mCameraThread) {
aRv = NS_NewThread(getter_AddRefs(mCameraThread));
if (aRv.Failed()) {
return;
}
}
DOM_CAMERA_LOGT("%s:%d\n", __func__, __LINE__); DOM_CAMERA_LOGT("%s:%d\n", __func__, __LINE__);
// Creating this object will trigger the onSuccess handler
nsRefPtr<nsDOMCameraControl> cameraControl = nsRefPtr<nsDOMCameraControl> cameraControl =
GetCameraControl(cameraId, onSuccess, onError.WasPassed() ? onError.Value() : nullptr, aRv); new nsDOMCameraControl(cameraId, mCameraThread,
onSuccess, onError.WasPassed() ? onError.Value() : nullptr, mWindow);
Register(cameraControl);
} }
void void

Просмотреть файл

@ -49,11 +49,6 @@ public:
CreateInstance(nsPIDOMWindow* aWindow); CreateInstance(nsPIDOMWindow* aWindow);
static bool IsWindowStillActive(uint64_t aWindowId); static bool IsWindowStillActive(uint64_t aWindowId);
// Build us an nsDOMCameraControl
mozilla::nsDOMCameraControl* GetCameraControl(uint32_t aDeviceNum,
nsICameraGetCameraCallback* onSuccess,
nsICameraErrorCallback* onError,
mozilla::ErrorResult& aRv);
void Register(mozilla::nsDOMCameraControl* aDOMCameraControl); void Register(mozilla::nsDOMCameraControl* aDOMCameraControl);
void OnNavigation(uint64_t aWindowId); void OnNavigation(uint64_t aWindowId);

Просмотреть файл

@ -49,7 +49,6 @@
#include "nsIStringBundle.h" #include "nsIStringBundle.h"
#include "nsIDocument.h" #include "nsIDocument.h"
#include <algorithm> #include <algorithm>
#include "nsContentPermissionHelper.h"
#include "mozilla/dom/DeviceStorageBinding.h" #include "mozilla/dom/DeviceStorageBinding.h"
@ -1734,14 +1733,17 @@ nsDOMDeviceStorageCursor::GetStorageType(nsAString & aType)
} }
NS_IMETHODIMP NS_IMETHODIMP
nsDOMDeviceStorageCursor::GetTypes(nsIArray** aTypes) nsDOMDeviceStorageCursor::GetType(nsACString & aType)
{ {
nsCString type; return DeviceStorageTypeChecker::GetPermissionForType(mFile->mStorageType,
nsresult rv = aType);
DeviceStorageTypeChecker::GetPermissionForType(mFile->mStorageType, type); }
NS_ENSURE_SUCCESS(rv, rv);
return CreatePermissionArray(type, NS_LITERAL_CSTRING("read"), aTypes); NS_IMETHODIMP
nsDOMDeviceStorageCursor::GetAccess(nsACString & aAccess)
{
aAccess = NS_LITERAL_CSTRING("read");
return NS_OK;
} }
NS_IMETHODIMP NS_IMETHODIMP
@ -2249,10 +2251,8 @@ public:
if (NS_FAILED(rv)) { if (NS_FAILED(rv)) {
return rv; return rv;
} }
nsTArray<PermissionRequest> permArray;
permArray.AppendElement(PermissionRequest(type, access));
child->SendPContentPermissionRequestConstructor( child->SendPContentPermissionRequestConstructor(
this, permArray, IPC::Principal(mPrincipal)); this, type, access, IPC::Principal(mPrincipal));
Sendprompt(); Sendprompt();
return NS_OK; return NS_OK;
@ -2266,23 +2266,26 @@ public:
return NS_OK; return NS_OK;
} }
NS_IMETHODIMP GetTypes(nsIArray** aTypes) NS_IMETHOD GetType(nsACString & aType)
{ {
nsCString type; nsCString type;
nsresult rv = nsresult rv
DeviceStorageTypeChecker::GetPermissionForType(mFile->mStorageType, type); = DeviceStorageTypeChecker::GetPermissionForType(mFile->mStorageType,
aType);
if (NS_FAILED(rv)) { if (NS_FAILED(rv)) {
return rv; return rv;
} }
return NS_OK;
}
nsCString access; NS_IMETHOD GetAccess(nsACString & aAccess)
rv = DeviceStorageTypeChecker::GetAccessForRequest( {
DeviceStorageRequestType(mRequestType), access); nsresult rv = DeviceStorageTypeChecker::GetAccessForRequest(
DeviceStorageRequestType(mRequestType), aAccess);
if (NS_FAILED(rv)) { if (NS_FAILED(rv)) {
return rv; return rv;
} }
return NS_OK;
return CreatePermissionArray(type, access, aTypes);
} }
NS_IMETHOD GetPrincipal(nsIPrincipal * *aRequestingPrincipal) NS_IMETHOD GetPrincipal(nsIPrincipal * *aRequestingPrincipal)
@ -3296,10 +3299,8 @@ nsDOMDeviceStorage::EnumerateInternal(const nsAString& aPath,
if (aRv.Failed()) { if (aRv.Failed()) {
return nullptr; return nullptr;
} }
nsTArray<PermissionRequest> permArray; child->SendPContentPermissionRequestConstructor(r, type,
permArray.AppendElement(PermissionRequest(type, NS_LITERAL_CSTRING("read"))); NS_LITERAL_CSTRING("read"),
child->SendPContentPermissionRequestConstructor(r,
permArray,
IPC::Principal(mPrincipal)); IPC::Principal(mPrincipal));
r->Sendprompt(); r->Sendprompt();

Просмотреть файл

@ -7,13 +7,15 @@
interface nsIPrincipal; interface nsIPrincipal;
interface nsIDOMWindow; interface nsIDOMWindow;
interface nsIDOMElement; interface nsIDOMElement;
interface nsIArray;
/** /**
* Interface provides the request type and its access. * Interface allows access to a content to request
* permission to perform a privileged operation such as
* geolocation.
*/ */
[scriptable, builtinclass, uuid(384b6cc4-a66b-4bea-98e0-eb10562a9ba4)] [scriptable, uuid(1de67000-2de8-11e2-81c1-0800200c9a66)]
interface nsIContentPermissionType : nsISupports { interface nsIContentPermissionRequest : nsISupports {
/** /**
* The type of the permission request, such as * The type of the permission request, such as
* "geolocation". * "geolocation".
@ -25,22 +27,8 @@ interface nsIContentPermissionType : nsISupports {
* "read". * "read".
*/ */
readonly attribute ACString access; readonly attribute ACString access;
};
/**
* Interface allows access to a content to request
* permission to perform a privileged operation such as
* geolocation.
*/
[scriptable, uuid(69a39d88-d1c4-4ba9-9b19-bafc7a1bb783)]
interface nsIContentPermissionRequest : nsISupports {
/** /**
* The array will include the request types. Elements of this array are
* nsIContentPermissionType object.
*/
readonly attribute nsIArray types;
/*
* The principal of the permission request. * The principal of the permission request.
*/ */
readonly attribute nsIPrincipal principal; readonly attribute nsIPrincipal principal;

Просмотреть файл

@ -497,19 +497,12 @@ ContentChild::RecvPMemoryReportRequestConstructor(
GetProcessName(process); GetProcessName(process);
AppendProcessId(process); AppendProcessId(process);
// Run each reporter. The callback will turn each measurement into a // Run the reporters. The callback will turn each measurement into a
// MemoryReport. // MemoryReport.
nsCOMPtr<nsISimpleEnumerator> e;
mgr->EnumerateReporters(getter_AddRefs(e));
nsRefPtr<MemoryReportsWrapper> wrappedReports = nsRefPtr<MemoryReportsWrapper> wrappedReports =
new MemoryReportsWrapper(&reports); new MemoryReportsWrapper(&reports);
nsRefPtr<MemoryReportCallback> cb = new MemoryReportCallback(process); nsRefPtr<MemoryReportCallback> cb = new MemoryReportCallback(process);
bool more; mgr->GetReportsForThisProcess(cb, wrappedReports);
while (NS_SUCCEEDED(e->HasMoreElements(&more)) && more) {
nsCOMPtr<nsIMemoryReporter> r;
e->GetNext(getter_AddRefs(r));
r->CollectReports(cb, wrappedReports);
}
child->Send__delete__(child, generation, reports); child->Send__delete__(child, generation, reports);
return true; return true;

Просмотреть файл

@ -193,15 +193,15 @@ MemoryReportRequestParent::~MemoryReportRequestParent()
} }
// A memory reporter for ContentParent objects themselves. // A memory reporter for ContentParent objects themselves.
class ContentParentsMemoryReporter MOZ_FINAL : public MemoryMultiReporter class ContentParentsMemoryReporter MOZ_FINAL : public nsIMemoryReporter
{ {
public: public:
ContentParentsMemoryReporter() {} NS_DECL_ISUPPORTS
NS_DECL_NSIMEMORYREPORTER
NS_IMETHOD CollectReports(nsIMemoryReporterCallback* cb,
nsISupports* aClosure);
}; };
NS_IMPL_ISUPPORTS1(ContentParentsMemoryReporter, nsIMemoryReporter)
NS_IMETHODIMP NS_IMETHODIMP
ContentParentsMemoryReporter::CollectReports(nsIMemoryReporterCallback* cb, ContentParentsMemoryReporter::CollectReports(nsIMemoryReporterCallback* cb,
nsISupports* aClosure) nsISupports* aClosure)

Просмотреть файл

@ -16,7 +16,6 @@ include protocol PIndexedDB;
include DOMTypes; include DOMTypes;
include JavaScriptTypes; include JavaScriptTypes;
include URIParams; include URIParams;
include PContentPermission;
using class IPC::Principal from "mozilla/dom/PermissionMessageUtils.h"; using class IPC::Principal from "mozilla/dom/PermissionMessageUtils.h";
@ -207,8 +206,10 @@ parent:
* Initiates an asynchronous request for permission for the * Initiates an asynchronous request for permission for the
* provided principal. * provided principal.
* *
* @param aRequests * @param aType
* The array of permissions to request. * The type of permission to request.
* @param aAccess
* Access type. "read" for example.
* @param aPrincipal * @param aPrincipal
* The principal of the request. * The principal of the request.
* *
@ -216,7 +217,7 @@ parent:
* principals that can live in the content process should * principals that can live in the content process should
* provided. * provided.
*/ */
PContentPermissionRequest(PermissionRequest[] aRequests, Principal aPrincipal); PContentPermissionRequest(nsCString aType, nsCString aAccess, Principal principal);
PContentDialog(uint32_t aType, nsCString aName, nsCString aFeatures, PContentDialog(uint32_t aType, nsCString aName, nsCString aFeatures,
int32_t[] aIntParams, nsString[] aStringParams); int32_t[] aIntParams, nsString[] aStringParams);

Просмотреть файл

@ -1,14 +0,0 @@
/* 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/. */
namespace mozilla {
namespace dom {
struct PermissionRequest {
nsCString type;
nsCString access;
};
} // namespace dom
} // namespace mozilla

Просмотреть файл

@ -1157,11 +1157,12 @@ TabChild::ArraysToParams(const InfallibleTArray<int>& aIntParams,
#ifdef DEBUG #ifdef DEBUG
PContentPermissionRequestChild* PContentPermissionRequestChild*
TabChild:: SendPContentPermissionRequestConstructor(PContentPermissionRequestChild* aActor, TabChild:: SendPContentPermissionRequestConstructor(PContentPermissionRequestChild* aActor,
const InfallibleTArray<PermissionRequest>& aRequests, const nsCString& aType,
const nsCString& aAccess,
const IPC::Principal& aPrincipal) const IPC::Principal& aPrincipal)
{ {
PCOMContentPermissionRequestChild* child = static_cast<PCOMContentPermissionRequestChild*>(aActor); PCOMContentPermissionRequestChild* child = static_cast<PCOMContentPermissionRequestChild*>(aActor);
PContentPermissionRequestChild* request = PBrowserChild::SendPContentPermissionRequestConstructor(aActor, aRequests, aPrincipal); PContentPermissionRequestChild* request = PBrowserChild::SendPContentPermissionRequestConstructor(aActor, aType, aAccess, aPrincipal);
child->mIPCOpen = true; child->mIPCOpen = true;
return request; return request;
} }
@ -2039,8 +2040,7 @@ TabChild::DeallocPContentDialogChild(PContentDialogChild* aDialog)
} }
PContentPermissionRequestChild* PContentPermissionRequestChild*
TabChild::AllocPContentPermissionRequestChild(const InfallibleTArray<PermissionRequest>& aRequests, TabChild::AllocPContentPermissionRequestChild(const nsCString& aType, const nsCString& aAccess, const IPC::Principal&)
const IPC::Principal& aPrincipal)
{ {
NS_RUNTIMEABORT("unused"); NS_RUNTIMEABORT("unused");
return nullptr; return nullptr;

Просмотреть файл

@ -280,11 +280,13 @@ public:
#ifdef DEBUG #ifdef DEBUG
virtual PContentPermissionRequestChild* virtual PContentPermissionRequestChild*
SendPContentPermissionRequestConstructor(PContentPermissionRequestChild* aActor, SendPContentPermissionRequestConstructor(PContentPermissionRequestChild* aActor,
const InfallibleTArray<PermissionRequest>& aRequests, const nsCString& aType,
const nsCString& aAccess,
const IPC::Principal& aPrincipal); const IPC::Principal& aPrincipal);
#endif /* DEBUG */ #endif /* DEBUG */
virtual PContentPermissionRequestChild* AllocPContentPermissionRequestChild(const InfallibleTArray<PermissionRequest>& aRequests, virtual PContentPermissionRequestChild* AllocPContentPermissionRequestChild(const nsCString& aType,
const nsCString& aAccess,
const IPC::Principal& aPrincipal); const IPC::Principal& aPrincipal);
virtual bool DeallocPContentPermissionRequestChild(PContentPermissionRequestChild* actor); virtual bool DeallocPContentPermissionRequestChild(PContentPermissionRequestChild* actor);

Просмотреть файл

@ -15,7 +15,6 @@
#include "mozilla/BrowserElementParent.h" #include "mozilla/BrowserElementParent.h"
#include "mozilla/docshell/OfflineCacheUpdateParent.h" #include "mozilla/docshell/OfflineCacheUpdateParent.h"
#include "mozilla/dom/ContentParent.h" #include "mozilla/dom/ContentParent.h"
#include "mozilla/dom/PContentPermissionRequestParent.h"
#include "mozilla/Hal.h" #include "mozilla/Hal.h"
#include "mozilla/ipc/DocumentRendererParent.h" #include "mozilla/ipc/DocumentRendererParent.h"
#include "mozilla/layers/CompositorParent.h" #include "mozilla/layers/CompositorParent.h"
@ -594,10 +593,9 @@ TabParent::DeallocPDocumentRendererParent(PDocumentRendererParent* actor)
} }
PContentPermissionRequestParent* PContentPermissionRequestParent*
TabParent::AllocPContentPermissionRequestParent(const InfallibleTArray<PermissionRequest>& aRequests, TabParent::AllocPContentPermissionRequestParent(const nsCString& type, const nsCString& access, const IPC::Principal& principal)
const IPC::Principal& aPrincipal)
{ {
return CreateContentPermissionRequestParent(aRequests, mFrameElement, aPrincipal); return new ContentPermissionRequestParent(type, access, mFrameElement, principal);
} }
bool bool

Просмотреть файл

@ -227,8 +227,7 @@ public:
virtual bool DeallocPDocumentRendererParent(PDocumentRendererParent* actor); virtual bool DeallocPDocumentRendererParent(PDocumentRendererParent* actor);
virtual PContentPermissionRequestParent* virtual PContentPermissionRequestParent*
AllocPContentPermissionRequestParent(const InfallibleTArray<PermissionRequest>& aRequests, AllocPContentPermissionRequestParent(const nsCString& aType, const nsCString& aAccess, const IPC::Principal& aPrincipal);
const IPC::Principal& aPrincipal);
virtual bool DeallocPContentPermissionRequestParent(PContentPermissionRequestParent* actor); virtual bool DeallocPContentPermissionRequestParent(PContentPermissionRequestParent* actor);
virtual POfflineCacheUpdateParent* AllocPOfflineCacheUpdateParent( virtual POfflineCacheUpdateParent* AllocPOfflineCacheUpdateParent(

Просмотреть файл

@ -68,7 +68,6 @@ IPDL_SOURCES += [
'PBrowser.ipdl', 'PBrowser.ipdl',
'PContent.ipdl', 'PContent.ipdl',
'PContentDialog.ipdl', 'PContentDialog.ipdl',
'PContentPermission.ipdlh',
'PContentPermissionRequest.ipdl', 'PContentPermissionRequest.ipdl',
'PCrashReporter.ipdl', 'PCrashReporter.ipdl',
'PDocumentRenderer.ipdl', 'PDocumentRenderer.ipdl',

Просмотреть файл

@ -41,7 +41,7 @@
#include "MediaEngineWebRTC.h" #include "MediaEngineWebRTC.h"
#endif #endif
#ifdef MOZ_B2G #ifdef MOZ_WIDGET_GONK
#include "MediaPermissionGonk.h" #include "MediaPermissionGonk.h"
#endif #endif
@ -756,7 +756,7 @@ public:
, mListener(aListener) , mListener(aListener)
, mPrefs(aPrefs) , mPrefs(aPrefs)
, mDeviceChosen(false) , mDeviceChosen(false)
, mBackend(nullptr) , mBackendChosen(false)
, mManager(MediaManager::GetInstance()) , mManager(MediaManager::GetInstance())
{} {}
@ -778,11 +778,15 @@ public:
, mListener(aListener) , mListener(aListener)
, mPrefs(aPrefs) , mPrefs(aPrefs)
, mDeviceChosen(false) , mDeviceChosen(false)
, mBackendChosen(true)
, mBackend(aBackend) , mBackend(aBackend)
, mManager(MediaManager::GetInstance()) , mManager(MediaManager::GetInstance())
{} {}
~GetUserMediaRunnable() { ~GetUserMediaRunnable() {
if (mBackendChosen) {
delete mBackend;
}
} }
NS_IMETHOD NS_IMETHOD
@ -790,15 +794,14 @@ public:
{ {
NS_ASSERTION(!NS_IsMainThread(), "Don't call on main thread"); NS_ASSERTION(!NS_IsMainThread(), "Don't call on main thread");
MediaEngine* backend = mBackend;
// Was a backend provided? // Was a backend provided?
if (!backend) { if (!mBackendChosen) {
backend = mManager->GetBackend(mWindowID); mBackend = mManager->GetBackend(mWindowID);
} }
// Was a device provided? // Was a device provided?
if (!mDeviceChosen) { if (!mDeviceChosen) {
nsresult rv = SelectDevice(backend); nsresult rv = SelectDevice();
if (rv != NS_OK) { if (rv != NS_OK) {
return rv; return rv;
} }
@ -870,10 +873,10 @@ public:
} }
nsresult nsresult
SelectDevice(MediaEngine* backend) SelectDevice()
{ {
if (mConstraints.mPicture || mConstraints.mVideo) { if (mConstraints.mPicture || mConstraints.mVideo) {
ScopedDeletePtr<SourceSet> sources (GetSources(backend, ScopedDeletePtr<SourceSet> sources (GetSources(mBackend,
mConstraints.mVideom, &MediaEngine::EnumerateVideoDevices)); mConstraints.mVideom, &MediaEngine::EnumerateVideoDevices));
if (!sources->Length()) { if (!sources->Length()) {
@ -887,7 +890,7 @@ public:
} }
if (mConstraints.mAudio) { if (mConstraints.mAudio) {
ScopedDeletePtr<SourceSet> sources (GetSources(backend, ScopedDeletePtr<SourceSet> sources (GetSources(mBackend,
mConstraints.mAudiom, &MediaEngine::EnumerateAudioDevices)); mConstraints.mAudiom, &MediaEngine::EnumerateAudioDevices));
if (!sources->Length()) { if (!sources->Length()) {
@ -981,8 +984,9 @@ private:
MediaEnginePrefs mPrefs; MediaEnginePrefs mPrefs;
bool mDeviceChosen; bool mDeviceChosen;
bool mBackendChosen;
RefPtr<MediaEngine> mBackend; MediaEngine* mBackend;
nsRefPtr<MediaManager> mManager; // get ref to this when creating the runnable nsRefPtr<MediaManager> mManager; // get ref to this when creating the runnable
}; };
@ -1262,10 +1266,10 @@ MediaManager::GetUserMedia(JSContext* aCx, bool aPrivileged,
// Force MediaManager to startup before we try to access it from other threads // Force MediaManager to startup before we try to access it from other threads
// Hack: should init singleton earlier unless it's expensive (mem or CPU) // Hack: should init singleton earlier unless it's expensive (mem or CPU)
(void) MediaManager::Get(); (void) MediaManager::Get();
#ifdef MOZ_B2G #ifdef MOZ_WIDGET_GONK
// Initialize MediaPermissionManager before send out any permission request. // Initialize MediaPermissionManager before send out any permission request.
(void) MediaPermissionManager::GetInstance(); (void) MediaPermissionManager::GetInstance();
#endif //MOZ_B2G #endif //MOZ_WIDGET_GONK
} }
// Store the WindowID in a hash table and mark as active. The entry is removed // Store the WindowID in a hash table and mark as active. The entry is removed
@ -1411,11 +1415,11 @@ MediaManager::GetBackend(uint64_t aWindowId)
MutexAutoLock lock(mMutex); MutexAutoLock lock(mMutex);
if (!mBackend) { if (!mBackend) {
#if defined(MOZ_WEBRTC) #if defined(MOZ_WEBRTC)
#ifndef MOZ_B2G_CAMERA #ifndef MOZ_B2G_CAMERA
mBackend = new MediaEngineWebRTC(mPrefs); mBackend = new MediaEngineWebRTC(mPrefs);
#else #else
mBackend = new MediaEngineWebRTC(mCameraManager); mBackend = new MediaEngineWebRTC(mCameraManager, aWindowId);
#endif #endif
#else #else
mBackend = new MediaEngineDefault(); mBackend = new MediaEngineDefault();
#endif #endif

Просмотреть файл

@ -513,7 +513,9 @@ private:
// Make private because we want only one instance of this class // Make private because we want only one instance of this class
MediaManager(); MediaManager();
~MediaManager() {} ~MediaManager() {
delete mBackend;
}
nsresult MediaCaptureWindowStateInternal(nsIDOMWindow* aWindow, bool* aVideo, nsresult MediaCaptureWindowStateInternal(nsIDOMWindow* aWindow, bool* aVideo,
bool* aAudio); bool* aAudio);
@ -528,11 +530,11 @@ private:
Mutex mMutex; Mutex mMutex;
// protected with mMutex: // protected with mMutex:
RefPtr<MediaEngine> mBackend; MediaEngine* mBackend;
static StaticRefPtr<MediaManager> sSingleton; static StaticRefPtr<MediaManager> sSingleton;
#ifdef MOZ_B2G_CAMERA #ifdef MOZ_WIDGET_GONK
nsRefPtr<nsDOMCameraManager> mCameraManager; nsRefPtr<nsDOMCameraManager> mCameraManager;
#endif #endif
}; };

Просмотреть файл

@ -20,36 +20,14 @@
#include "mozilla/dom/MediaStreamTrackBinding.h" #include "mozilla/dom/MediaStreamTrackBinding.h"
#include "nsISupportsPrimitives.h" #include "nsISupportsPrimitives.h"
#include "nsServiceManagerUtils.h" #include "nsServiceManagerUtils.h"
#include "nsArrayUtils.h"
#include "nsContentPermissionHelper.h"
#include "mozilla/dom/PermissionMessageUtils.h" #include "mozilla/dom/PermissionMessageUtils.h"
#define AUDIO_PERMISSION_NAME "audio-capture" #define AUDIO_PERMISSION_NAME "audio-capture"
#define VIDEO_PERMISSION_NAME "video-capture"
using namespace mozilla::dom;
namespace mozilla { namespace mozilla {
static MediaPermissionManager *gMediaPermMgr = nullptr; static MediaPermissionManager *gMediaPermMgr = nullptr;
static uint32_t
ConvertArrayToPermissionRequest(nsIArray* aSrcArray,
nsTArray<PermissionRequest>& aDesArray)
{
uint32_t len = 0;
aSrcArray->GetLength(&len);
for (uint32_t i = 0; i < len; i++) {
nsCOMPtr<nsIContentPermissionType> cpt = do_QueryElementAt(aSrcArray, i);
nsAutoCString type;
nsAutoCString access;
cpt->GetType(type);
cpt->GetAccess(access);
aDesArray.AppendElement(PermissionRequest(type, access));
}
return len;
}
// Helper function for notifying permission granted // Helper function for notifying permission granted
static nsresult static nsresult
NotifyPermissionAllow(const nsAString &aCallID, nsTArray<nsCOMPtr<nsIMediaDevice> > &aDevices) NotifyPermissionAllow(const nsAString &aCallID, nsTArray<nsCOMPtr<nsIMediaDevice> > &aDevices)
@ -115,7 +93,6 @@ public:
private: private:
bool mAudio; // Request for audio permission bool mAudio; // Request for audio permission
bool mVideo; // Request for video permission
nsRefPtr<dom::GetUserMediaRequest> mRequest; nsRefPtr<dom::GetUserMediaRequest> mRequest;
nsTArray<nsCOMPtr<nsIMediaDevice> > mDevices; // candiate device list nsTArray<nsCOMPtr<nsIMediaDevice> > mDevices; // candiate device list
}; };
@ -131,7 +108,6 @@ MediaPermissionRequest::MediaPermissionRequest(nsRefPtr<dom::GetUserMediaRequest
mRequest->GetConstraints(constraints); mRequest->GetConstraints(constraints);
mAudio = constraints.mAudio; mAudio = constraints.mAudio;
mVideo = constraints.mVideo;
for (uint32_t i = 0; i < aDevices.Length(); ++i) { for (uint32_t i = 0; i < aDevices.Length(); ++i) {
nsCOMPtr<nsIMediaDevice> device(aDevices[i]); nsCOMPtr<nsIMediaDevice> device(aDevices[i]);
@ -140,34 +116,10 @@ MediaPermissionRequest::MediaPermissionRequest(nsRefPtr<dom::GetUserMediaRequest
if (mAudio && deviceType.EqualsLiteral("audio")) { if (mAudio && deviceType.EqualsLiteral("audio")) {
mDevices.AppendElement(device); mDevices.AppendElement(device);
} }
if (mVideo && deviceType.EqualsLiteral("video")) {
mDevices.AppendElement(device);
}
} }
} }
// nsIContentPermissionRequest methods // nsIContentPermissionRequest methods
NS_IMETHODIMP
MediaPermissionRequest::GetTypes(nsIArray** aTypes)
{
nsCOMPtr<nsIMutableArray> types = do_CreateInstance(NS_ARRAY_CONTRACTID);
if (mAudio) {
nsCOMPtr<ContentPermissionType> AudioType =
new ContentPermissionType(NS_LITERAL_CSTRING(AUDIO_PERMISSION_NAME),
NS_LITERAL_CSTRING("unused"));
types->AppendElement(AudioType, false);
}
if (mVideo) {
nsCOMPtr<ContentPermissionType> VideoType =
new ContentPermissionType(NS_LITERAL_CSTRING(VIDEO_PERMISSION_NAME),
NS_LITERAL_CSTRING("unused"));
types->AppendElement(VideoType, false);
}
NS_IF_ADDREF(*aTypes = types);
return NS_OK;
}
NS_IMETHODIMP NS_IMETHODIMP
MediaPermissionRequest::GetPrincipal(nsIPrincipal **aRequestingPrincipal) MediaPermissionRequest::GetPrincipal(nsIPrincipal **aRequestingPrincipal)
{ {
@ -183,6 +135,24 @@ MediaPermissionRequest::GetPrincipal(nsIPrincipal **aRequestingPrincipal)
return NS_OK; return NS_OK;
} }
NS_IMETHODIMP
MediaPermissionRequest::GetType(nsACString &aType)
{
if (mAudio) {
aType = AUDIO_PERMISSION_NAME;
return NS_OK;
}
return NS_OK;
}
NS_IMETHODIMP
MediaPermissionRequest::GetAccess(nsACString &aAccess)
{
aAccess = "unused";
return NS_OK;
}
NS_IMETHODIMP NS_IMETHODIMP
MediaPermissionRequest::GetWindow(nsIDOMWindow** aRequestingWindow) MediaPermissionRequest::GetWindow(nsIDOMWindow** aRequestingWindow)
{ {
@ -308,12 +278,13 @@ MediaDeviceSuccessCallback::DoPrompt(nsRefPtr<MediaPermissionRequest> &req)
dom::TabChild* child = dom::TabChild::GetFrom(window->GetDocShell()); dom::TabChild* child = dom::TabChild::GetFrom(window->GetDocShell());
NS_ENSURE_TRUE(child, NS_ERROR_FAILURE); NS_ENSURE_TRUE(child, NS_ERROR_FAILURE);
nsCOMPtr<nsIArray> typeArray; nsAutoCString type;
rv = req->GetTypes(getter_AddRefs(typeArray)); rv = req->GetType(type);
NS_ENSURE_SUCCESS(rv, rv); NS_ENSURE_SUCCESS(rv, rv);
nsTArray<PermissionRequest> permArray; nsAutoCString access;
ConvertArrayToPermissionRequest(typeArray, permArray); rv = req->GetAccess(access);
NS_ENSURE_SUCCESS(rv, rv);
nsCOMPtr<nsIPrincipal> principal; nsCOMPtr<nsIPrincipal> principal;
rv = req->GetPrincipal(getter_AddRefs(principal)); rv = req->GetPrincipal(getter_AddRefs(principal));
@ -321,7 +292,8 @@ MediaDeviceSuccessCallback::DoPrompt(nsRefPtr<MediaPermissionRequest> &req)
req->AddRef(); req->AddRef();
child->SendPContentPermissionRequestConstructor(req, child->SendPContentPermissionRequestConstructor(req,
permArray, type,
access,
IPC::Principal(principal)); IPC::Principal(principal));
req->Sendprompt(); req->Sendprompt();

Просмотреть файл

@ -169,7 +169,11 @@ function expandPermissions(aPerms) {
aPerms.forEach(function(el) { aPerms.forEach(function(el) {
var access = permTable[el].access ? "readwrite" : null; var access = permTable[el].access ? "readwrite" : null;
var expanded = SpecialPowers.unwrap(expand(el, access)); var expanded = SpecialPowers.unwrap(expand(el, access));
perms = perms.concat(expanded.slice(0)); // COW arrays don't behave array-like enough, to allow
// using expanded.slice(0) here.
for (let i = 0; i < expanded.length; i++) {
perms.push(expanded[i]);
}
}); });
return perms; return perms;

Просмотреть файл

@ -386,11 +386,17 @@ nsGeolocationRequest::GetPrincipal(nsIPrincipal * *aRequestingPrincipal)
} }
NS_IMETHODIMP NS_IMETHODIMP
nsGeolocationRequest::GetTypes(nsIArray** aTypes) nsGeolocationRequest::GetType(nsACString & aType)
{ {
return CreatePermissionArray(NS_LITERAL_CSTRING("geolocation"), aType = "geolocation";
NS_LITERAL_CSTRING("unused"), return NS_OK;
aTypes); }
NS_IMETHODIMP
nsGeolocationRequest::GetAccess(nsACString & aAccess)
{
aAccess = "unused";
return NS_OK;
} }
NS_IMETHODIMP NS_IMETHODIMP
@ -1447,15 +1453,12 @@ Geolocation::RegisterRequestWithPrompt(nsGeolocationRequest* request)
return false; return false;
} }
nsTArray<PermissionRequest> permArray;
permArray.AppendElement(PermissionRequest(NS_LITERAL_CSTRING("geolocation"),
NS_LITERAL_CSTRING("unused")));
// Retain a reference so the object isn't deleted without IPDL's knowledge. // Retain a reference so the object isn't deleted without IPDL's knowledge.
// Corresponding release occurs in DeallocPContentPermissionRequest. // Corresponding release occurs in DeallocPContentPermissionRequest.
request->AddRef(); request->AddRef();
child->SendPContentPermissionRequestConstructor(request, child->SendPContentPermissionRequestConstructor(request,
permArray, NS_LITERAL_CSTRING("geolocation"),
NS_LITERAL_CSTRING("unused"),
IPC::Principal(mPrincipal)); IPC::Principal(mPrincipal));
request->Sendprompt(); request->Sendprompt();

Просмотреть файл

@ -15,7 +15,6 @@
#include "PCOMContentPermissionRequestChild.h" #include "PCOMContentPermissionRequestChild.h"
#include "nsIScriptSecurityManager.h" #include "nsIScriptSecurityManager.h"
#include "nsServiceManagerUtils.h" #include "nsServiceManagerUtils.h"
#include "PermissionMessageUtils.h"
namespace mozilla { namespace mozilla {
namespace dom { namespace dom {
@ -180,12 +179,9 @@ DesktopNotification::Init()
// Corresponding release occurs in DeallocPContentPermissionRequest. // Corresponding release occurs in DeallocPContentPermissionRequest.
nsRefPtr<DesktopNotificationRequest> copy = request; nsRefPtr<DesktopNotificationRequest> copy = request;
nsTArray<PermissionRequest> permArray;
permArray.AppendElement(PermissionRequest(
NS_LITERAL_CSTRING("desktop-notification"),
NS_LITERAL_CSTRING("unused")));
child->SendPContentPermissionRequestConstructor(copy.forget().get(), child->SendPContentPermissionRequestConstructor(copy.forget().get(),
permArray, NS_LITERAL_CSTRING("desktop-notification"),
NS_LITERAL_CSTRING("unused"),
IPC::Principal(mPrincipal)); IPC::Principal(mPrincipal));
request->Sendprompt(); request->Sendprompt();
@ -357,11 +353,17 @@ DesktopNotificationRequest::Allow()
} }
NS_IMETHODIMP NS_IMETHODIMP
DesktopNotificationRequest::GetTypes(nsIArray** aTypes) DesktopNotificationRequest::GetType(nsACString & aType)
{ {
return CreatePermissionArray(NS_LITERAL_CSTRING("desktop-notification"), aType = "desktop-notification";
NS_LITERAL_CSTRING("unused"), return NS_OK;
aTypes); }
NS_IMETHODIMP
DesktopNotificationRequest::GetAccess(nsACString & aAccess)
{
aAccess = "unused";
return NS_OK;
} }
} // namespace dom } // namespace dom

Просмотреть файл

@ -24,7 +24,6 @@
#include "nsDOMJSUtils.h" #include "nsDOMJSUtils.h"
#include "nsIScriptSecurityManager.h" #include "nsIScriptSecurityManager.h"
#include "mozilla/dom/PermissionMessageUtils.h" #include "mozilla/dom/PermissionMessageUtils.h"
#include "nsContentPermissionHelper.h"
#ifdef MOZ_B2G #ifdef MOZ_B2G
#include "nsIDOMDesktopNotification.h" #include "nsIDOMDesktopNotification.h"
#endif #endif
@ -268,11 +267,9 @@ NotificationPermissionRequest::Run()
// Corresponding release occurs in DeallocPContentPermissionRequest. // Corresponding release occurs in DeallocPContentPermissionRequest.
AddRef(); AddRef();
nsTArray<PermissionRequest> permArray; NS_NAMED_LITERAL_CSTRING(type, "desktop-notification");
permArray.AppendElement(PermissionRequest( NS_NAMED_LITERAL_CSTRING(access, "unused");
NS_LITERAL_CSTRING("desktop-notification"), child->SendPContentPermissionRequestConstructor(this, type, access,
NS_LITERAL_CSTRING("unused")));
child->SendPContentPermissionRequestConstructor(this, permArray,
IPC::Principal(mPrincipal)); IPC::Principal(mPrincipal));
Sendprompt(); Sendprompt();
@ -345,11 +342,17 @@ NotificationPermissionRequest::CallCallback()
} }
NS_IMETHODIMP NS_IMETHODIMP
NotificationPermissionRequest::GetTypes(nsIArray** aTypes) NotificationPermissionRequest::GetAccess(nsACString& aAccess)
{ {
return CreatePermissionArray(NS_LITERAL_CSTRING("desktop-notification"), aAccess.AssignLiteral("unused");
NS_LITERAL_CSTRING("unused"), return NS_OK;
aTypes); }
NS_IMETHODIMP
NotificationPermissionRequest::GetType(nsACString& aType)
{
aType.AssignLiteral("desktop-notification");
return NS_OK;
} }
bool bool

Просмотреть файл

@ -27,6 +27,7 @@
#include "jsfriendapi.h" #include "jsfriendapi.h"
#include "mozilla/ArrayUtils.h" #include "mozilla/ArrayUtils.h"
#include "mozilla/CycleCollectedJSRuntime.h" #include "mozilla/CycleCollectedJSRuntime.h"
#include "mozilla/dom/asmjscache/AsmJSCache.h"
#include "mozilla/dom/AtomList.h" #include "mozilla/dom/AtomList.h"
#include "mozilla/dom/BindingUtils.h" #include "mozilla/dom/BindingUtils.h"
#include "mozilla/dom/ErrorEventBinding.h" #include "mozilla/dom/ErrorEventBinding.h"
@ -766,6 +767,53 @@ CTypesActivityCallback(JSContext* aCx,
} }
} }
static nsIPrincipal*
GetPrincipalForAsmJSCacheOp()
{
WorkerPrivate* workerPrivate = GetCurrentThreadWorkerPrivate();
if (!workerPrivate) {
return nullptr;
}
// asmjscache::OpenEntryForX guarnatee to only access the given nsIPrincipal
// from the main thread.
return workerPrivate->GetPrincipalDontAssertMainThread();
}
static bool
AsmJSCacheOpenEntryForRead(JS::Handle<JSObject*> aGlobal,
const jschar* aBegin,
const jschar* aLimit,
size_t* aSize,
const uint8_t** aMemory,
intptr_t *aHandle)
{
nsIPrincipal* principal = GetPrincipalForAsmJSCacheOp();
if (!principal) {
return false;
}
return asmjscache::OpenEntryForRead(principal, aBegin, aLimit, aSize, aMemory,
aHandle);
}
static bool
AsmJSCacheOpenEntryForWrite(JS::Handle<JSObject*> aGlobal,
const jschar* aBegin,
const jschar* aEnd,
size_t aSize,
uint8_t** aMemory,
intptr_t* aHandle)
{
nsIPrincipal* principal = GetPrincipalForAsmJSCacheOp();
if (!principal) {
return false;
}
return asmjscache::OpenEntryForWrite(principal, aBegin, aEnd, aSize, aMemory,
aHandle);
}
struct WorkerThreadRuntimePrivate : public PerThreadAtomCache struct WorkerThreadRuntimePrivate : public PerThreadAtomCache
{ {
WorkerPrivate* mWorkerPrivate; WorkerPrivate* mWorkerPrivate;
@ -808,6 +856,16 @@ CreateJSContextForWorker(WorkerPrivate* aWorkerPrivate, JSRuntime* aRuntime)
}; };
SetDOMCallbacks(aRuntime, &DOMCallbacks); SetDOMCallbacks(aRuntime, &DOMCallbacks);
// Set up the asm.js cache callbacks
static JS::AsmJSCacheOps asmJSCacheOps = {
AsmJSCacheOpenEntryForRead,
asmjscache::CloseEntryForRead,
AsmJSCacheOpenEntryForWrite,
asmjscache::CloseEntryForWrite,
asmjscache::GetBuildId
};
JS::SetAsmJSCacheOps(aRuntime, &asmJSCacheOps);
JSContext* workerCx = JS_NewContext(aRuntime, 0); JSContext* workerCx = JS_NewContext(aRuntime, 0);
if (!workerCx) { if (!workerCx) {
NS_WARNING("Could not create new context!"); NS_WARNING("Could not create new context!");

Просмотреть файл

@ -94,7 +94,7 @@ using mozilla::AutoSafeJSContext;
USING_WORKERS_NAMESPACE USING_WORKERS_NAMESPACE
using namespace mozilla::dom; using namespace mozilla::dom;
NS_MEMORY_REPORTER_MALLOC_SIZEOF_FUN(JsWorkerMallocSizeOf) MOZ_DEFINE_MALLOC_SIZE_OF(JsWorkerMallocSizeOf)
namespace { namespace {
@ -2006,8 +2006,10 @@ struct WorkerPrivate::TimeoutInfo
bool mCanceled; bool mCanceled;
}; };
class WorkerPrivate::MemoryReporter MOZ_FINAL : public MemoryMultiReporter class WorkerPrivate::MemoryReporter MOZ_FINAL : public nsIMemoryReporter
{ {
NS_DECL_THREADSAFE_ISUPPORTS
friend class WorkerPrivate; friend class WorkerPrivate;
SharedMutex mMutex; SharedMutex mMutex;
@ -2119,6 +2121,8 @@ private:
} }
}; };
NS_IMPL_ISUPPORTS1(WorkerPrivate::MemoryReporter, nsIMemoryReporter)
template <class Derived> template <class Derived>
WorkerPrivateParent<Derived>::WorkerPrivateParent( WorkerPrivateParent<Derived>::WorkerPrivateParent(
JSContext* aCx, JSContext* aCx,

Просмотреть файл

@ -600,6 +600,15 @@ public:
return mLoadInfo.mPrincipal; return mLoadInfo.mPrincipal;
} }
// This method allows the principal to be retrieved off the main thread.
// Principals are main-thread objects so the caller must ensure that all
// access occurs on the main thread.
nsIPrincipal*
GetPrincipalDontAssertMainThread() const
{
return mLoadInfo.mPrincipal;
}
void void
SetPrincipal(nsIPrincipal* aPrincipal); SetPrincipal(nsIPrincipal* aPrincipal);

Просмотреть файл

@ -60,4 +60,6 @@ LOCAL_INCLUDES += [
'/xpcom/build', '/xpcom/build',
] ]
include('/ipc/chromium/chromium-config.mozbuild')
FINAL_LIBRARY = 'gklayout' FINAL_LIBRARY = 'gklayout'

Просмотреть файл

@ -431,7 +431,6 @@ public:
// XXX I expect we will want to move mWidget into this class and implement // XXX I expect we will want to move mWidget into this class and implement
// these methods properly. // these methods properly.
virtual nsIWidget* GetWidget() const { return nullptr; } virtual nsIWidget* GetWidget() const { return nullptr; }
virtual const nsIntSize& GetWidgetSize() = 0;
// Call before and after any rendering not done by this compositor but which // Call before and after any rendering not done by this compositor but which
// might affect the compositor's internal state or the state of any APIs it // might affect the compositor's internal state or the state of any APIs it

Просмотреть файл

@ -133,15 +133,6 @@ LayerManager::CreateDrawTarget(const IntSize &aSize,
CreateOffscreenCanvasDrawTarget(aSize, aFormat); CreateOffscreenCanvasDrawTarget(aSize, aFormat);
} }
TextureFactoryIdentifier
LayerManager::GetTextureFactoryIdentifier()
{
//TODO[nrc] make pure virtual when all layer managers use Compositor
NS_ERROR("Should have been overridden");
return TextureFactoryIdentifier();
}
#ifdef DEBUG #ifdef DEBUG
void void
LayerManager::Mutated(Layer* aLayer) LayerManager::Mutated(Layer* aLayer)

Просмотреть файл

@ -437,12 +437,6 @@ public:
virtual bool CanUseCanvasLayerForSize(const gfxIntSize &aSize) { return true; } virtual bool CanUseCanvasLayerForSize(const gfxIntSize &aSize) { return true; }
/**
* Returns a TextureFactoryIdentifier which describes properties of the backend
* used to decide what kind of texture and buffer clients to create
*/
virtual TextureFactoryIdentifier GetTextureFactoryIdentifier();
/** /**
* returns the maximum texture size on this layer backend, or INT32_MAX * returns the maximum texture size on this layer backend, or INT32_MAX
* if there is no maximum * if there is no maximum

Просмотреть файл

@ -220,7 +220,6 @@ CreateBasicDeprecatedTextureHost(SurfaceDescriptorType aDescriptorType,
BasicCompositor::BasicCompositor(nsIWidget *aWidget) BasicCompositor::BasicCompositor(nsIWidget *aWidget)
: mWidget(aWidget) : mWidget(aWidget)
, mWidgetSize(-1, -1)
{ {
MOZ_COUNT_CTOR(BasicCompositor); MOZ_COUNT_CTOR(BasicCompositor);
sBackend = LAYERS_BASIC; sBackend = LAYERS_BASIC;
@ -540,7 +539,6 @@ BasicCompositor::BeginFrame(const nsIntRegion& aInvalidRegion,
nsIntRect intRect; nsIntRect intRect;
mWidget->GetClientBounds(intRect); mWidget->GetClientBounds(intRect);
Rect rect = Rect(0, 0, intRect.width, intRect.height); Rect rect = Rect(0, 0, intRect.width, intRect.height);
mWidgetSize = intRect.Size();
nsIntRect invalidRect = aInvalidRegion.GetBounds(); nsIntRect invalidRect = aInvalidRegion.GetBounds();
mInvalidRect = IntRect(invalidRect.x, invalidRect.y, invalidRect.width, invalidRect.height); mInvalidRect = IntRect(invalidRect.x, invalidRect.y, invalidRect.width, invalidRect.height);

Просмотреть файл

@ -119,10 +119,6 @@ public:
virtual const char* Name() const { return "Basic"; } virtual const char* Name() const { return "Basic"; }
virtual nsIWidget* GetWidget() const MOZ_OVERRIDE { return mWidget; } virtual nsIWidget* GetWidget() const MOZ_OVERRIDE { return mWidget; }
virtual const nsIntSize& GetWidgetSize() MOZ_OVERRIDE
{
return mWidgetSize;
}
gfx::DrawTarget *GetDrawTarget() { return mDrawTarget; } gfx::DrawTarget *GetDrawTarget() { return mDrawTarget; }

Просмотреть файл

@ -73,7 +73,7 @@ public:
virtual already_AddRefed<ColorLayer> CreateColorLayer(); virtual already_AddRefed<ColorLayer> CreateColorLayer();
virtual already_AddRefed<RefLayer> CreateRefLayer(); virtual already_AddRefed<RefLayer> CreateRefLayer();
virtual TextureFactoryIdentifier GetTextureFactoryIdentifier() MOZ_OVERRIDE TextureFactoryIdentifier GetTextureFactoryIdentifier()
{ {
return mForwarder->GetTextureFactoryIdentifier(); return mForwarder->GetTextureFactoryIdentifier();
} }

Просмотреть файл

@ -203,6 +203,7 @@ LayerManagerComposite::EndTransaction(DrawThebesLayerCallback aCallback,
EndTransactionFlags aFlags) EndTransactionFlags aFlags)
{ {
NS_ASSERTION(mInTransaction, "Didn't call BeginTransaction?"); NS_ASSERTION(mInTransaction, "Didn't call BeginTransaction?");
NS_ASSERTION(!aCallback && !aCallbackData, "Not expecting callbacks here");
mInTransaction = false; mInTransaction = false;
if (!mIsCompositorReady) { if (!mIsCompositorReady) {
@ -240,13 +241,7 @@ LayerManagerComposite::EndTransaction(DrawThebesLayerCallback aCallback,
// so we don't need to pass any global transform here. // so we don't need to pass any global transform here.
mRoot->ComputeEffectiveTransforms(gfx3DMatrix()); mRoot->ComputeEffectiveTransforms(gfx3DMatrix());
mThebesLayerCallback = aCallback;
mThebesLayerCallbackData = aCallbackData;
Render(); Render();
mThebesLayerCallback = nullptr;
mThebesLayerCallbackData = nullptr;
} }
mCompositor->SetTargetContext(nullptr); mCompositor->SetTargetContext(nullptr);
@ -307,7 +302,7 @@ LayerManagerComposite::RootLayer() const
return nullptr; return nullptr;
} }
return static_cast<LayerComposite*>(mRoot->ImplData()); return ToLayerComposite(mRoot);
} }
static uint16_t sFrameCount = 0; static uint16_t sFrameCount = 0;
@ -723,7 +718,7 @@ LayerManagerComposite::AutoAddMaskEffect::AutoAddMaskEffect(Layer* aMaskLayer,
return; return;
} }
mCompositable = static_cast<LayerComposite*>(aMaskLayer->ImplData())->GetCompositableHost(); mCompositable = ToLayerComposite(aMaskLayer)->GetCompositableHost();
if (!mCompositable) { if (!mCompositable) {
NS_WARNING("Mask layer with no compositable host"); NS_WARNING("Mask layer with no compositable host");
return; return;
@ -786,25 +781,6 @@ LayerComposite::Destroy()
} }
} }
const nsIntSize&
LayerManagerComposite::GetWidgetSize()
{
return mCompositor->GetWidgetSize();
}
void
LayerManagerComposite::SetCompositorID(uint32_t aID)
{
NS_ASSERTION(mCompositor, "No compositor");
mCompositor->SetCompositorID(aID);
}
void
LayerManagerComposite::NotifyShadowTreeTransaction()
{
mCompositor->NotifyLayersTransaction();
}
bool bool
LayerManagerComposite::CanUseCanvasLayerForSize(const gfxIntSize &aSize) LayerManagerComposite::CanUseCanvasLayerForSize(const gfxIntSize &aSize)
{ {
@ -812,18 +788,6 @@ LayerManagerComposite::CanUseCanvasLayerForSize(const gfxIntSize &aSize)
aSize.height)); aSize.height));
} }
TextureFactoryIdentifier
LayerManagerComposite::GetTextureFactoryIdentifier()
{
return mCompositor->GetTextureFactoryIdentifier();
}
int32_t
LayerManagerComposite::GetMaxTextureSize() const
{
return mCompositor->GetMaxTextureSize();
}
#ifndef MOZ_HAVE_PLATFORM_SPECIFIC_LAYER_BUFFERS #ifndef MOZ_HAVE_PLATFORM_SPECIFIC_LAYER_BUFFERS
/*static*/ bool /*static*/ bool

Просмотреть файл

@ -110,8 +110,6 @@ public:
} }
void BeginTransactionWithDrawTarget(gfx::DrawTarget* aTarget); void BeginTransactionWithDrawTarget(gfx::DrawTarget* aTarget);
void NotifyShadowTreeTransaction();
virtual bool EndEmptyTransaction(EndTransactionFlags aFlags = END_DEFAULT) MOZ_OVERRIDE; virtual bool EndEmptyTransaction(EndTransactionFlags aFlags = END_DEFAULT) MOZ_OVERRIDE;
virtual void EndTransaction(DrawThebesLayerCallback aCallback, virtual void EndTransaction(DrawThebesLayerCallback aCallback,
void* aCallbackData, void* aCallbackData,
@ -119,11 +117,14 @@ public:
virtual void SetRoot(Layer* aLayer) MOZ_OVERRIDE { mRoot = aLayer; } virtual void SetRoot(Layer* aLayer) MOZ_OVERRIDE { mRoot = aLayer; }
// XXX[nrc]: never called, we should move this logic to ClientLayerManager
// (bug 946926).
virtual bool CanUseCanvasLayerForSize(const gfxIntSize &aSize) MOZ_OVERRIDE; virtual bool CanUseCanvasLayerForSize(const gfxIntSize &aSize) MOZ_OVERRIDE;
virtual TextureFactoryIdentifier GetTextureFactoryIdentifier() MOZ_OVERRIDE; virtual int32_t GetMaxTextureSize() const MOZ_OVERRIDE
{
virtual int32_t GetMaxTextureSize() const MOZ_OVERRIDE; MOZ_CRASH("Call on compositor, not LayerManagerComposite");
}
virtual void ClearCachedResources(Layer* aSubtree = nullptr) MOZ_OVERRIDE; virtual void ClearCachedResources(Layer* aSubtree = nullptr) MOZ_OVERRIDE;
@ -141,24 +142,16 @@ public:
virtual LayersBackend GetBackendType() MOZ_OVERRIDE virtual LayersBackend GetBackendType() MOZ_OVERRIDE
{ {
return LAYERS_NONE; MOZ_CRASH("Shouldn't be called for composited layer manager");
} }
virtual void GetBackendName(nsAString& name) MOZ_OVERRIDE virtual void GetBackendName(nsAString& name) MOZ_OVERRIDE
{ {
MOZ_ASSERT(false, "Shouldn't be called for composited layer manager"); MOZ_CRASH("Shouldn't be called for composited layer manager");
name.AssignLiteral("Composite");
} }
virtual already_AddRefed<gfxASurface> virtual already_AddRefed<gfxASurface>
CreateOptimalMaskSurface(const gfxIntSize &aSize) MOZ_OVERRIDE; CreateOptimalMaskSurface(const gfxIntSize &aSize) MOZ_OVERRIDE;
DrawThebesLayerCallback GetThebesLayerCallback() const
{ return mThebesLayerCallback; }
void* GetThebesLayerCallbackData() const
{ return mThebesLayerCallbackData; }
virtual const char* Name() const MOZ_OVERRIDE { return ""; } virtual const char* Name() const MOZ_OVERRIDE { return ""; }
enum WorldTransforPolicy { enum WorldTransforPolicy {
@ -195,11 +188,9 @@ public:
* layermanager. * layermanager.
*/ */
virtual TemporaryRef<mozilla::gfx::DrawTarget> virtual TemporaryRef<mozilla::gfx::DrawTarget>
CreateDrawTarget(const mozilla::gfx::IntSize &aSize, CreateDrawTarget(const mozilla::gfx::IntSize& aSize,
mozilla::gfx::SurfaceFormat aFormat) MOZ_OVERRIDE; mozilla::gfx::SurfaceFormat aFormat) MOZ_OVERRIDE;
const nsIntSize& GetWidgetSize();
/** /**
* Calculates the 'completeness' of the rendering that intersected with the * Calculates the 'completeness' of the rendering that intersected with the
* screen on the last render. This is only useful when progressive tile * screen on the last render. This is only useful when progressive tile
@ -217,8 +208,6 @@ public:
static void PlatformSyncBeforeReplyUpdate(); static void PlatformSyncBeforeReplyUpdate();
void SetCompositorID(uint32_t aID);
void AddInvalidRegion(const nsIntRegion& aRegion) void AddInvalidRegion(const nsIntRegion& aRegion)
{ {
mInvalidRegion.Or(mInvalidRegion, aRegion); mInvalidRegion.Or(mInvalidRegion, aRegion);
@ -245,7 +234,7 @@ private:
nsIntRect mRenderBounds; nsIntRect mRenderBounds;
/** Current root layer. */ /** Current root layer. */
LayerComposite *RootLayer() const; LayerComposite* RootLayer() const;
/** /**
* Recursive helper method for use by ComputeRenderIntegrity. Subtracts * Recursive helper method for use by ComputeRenderIntegrity. Subtracts
@ -275,10 +264,6 @@ private:
/** Our more efficient but less powerful alter ego, if one is available. */ /** Our more efficient but less powerful alter ego, if one is available. */
nsRefPtr<Composer2D> mComposer2D; nsRefPtr<Composer2D> mComposer2D;
/* Thebes layer callbacks; valid at the end of a transaciton,
* while rendering */
DrawThebesLayerCallback mThebesLayerCallback;
void *mThebesLayerCallbackData;
gfxMatrix mWorldMatrix; gfxMatrix mWorldMatrix;
bool mInTransaction; bool mInTransaction;

Просмотреть файл

@ -549,6 +549,8 @@ MemoryTextureHost::MemoryTextureHost(uint64_t aID,
MemoryTextureHost::~MemoryTextureHost() MemoryTextureHost::~MemoryTextureHost()
{ {
DeallocateDeviceData(); DeallocateDeviceData();
NS_ASSERTION(!mBuffer || (mFlags & TEXTURE_DEALLOCATE_CLIENT),
"Leaking our buffer");
MOZ_COUNT_DTOR(MemoryTextureHost); MOZ_COUNT_DTOR(MemoryTextureHost);
} }

Просмотреть файл

@ -139,14 +139,6 @@ public:
virtual void NotifyLayersTransaction() MOZ_OVERRIDE { } virtual void NotifyLayersTransaction() MOZ_OVERRIDE { }
virtual nsIWidget* GetWidget() const MOZ_OVERRIDE { return mWidget; } virtual nsIWidget* GetWidget() const MOZ_OVERRIDE { return mWidget; }
virtual const nsIntSize& GetWidgetSize() MOZ_OVERRIDE
{
NS_ASSERTION(false, "Getting the widget size on windows causes some kind of resizing of buffers. "
"You should not do that outside of BeginFrame, so the best we can do is return "
"the last size we got, that might not be up to date. So you probably shouldn't "
"use this method.");
return mSize;
}
ID3D11Device* GetDevice() { return mDevice; } ID3D11Device* GetDevice() { return mDevice; }

Просмотреть файл

@ -86,14 +86,6 @@ public:
virtual void NotifyLayersTransaction() MOZ_OVERRIDE {} virtual void NotifyLayersTransaction() MOZ_OVERRIDE {}
virtual nsIWidget* GetWidget() const MOZ_OVERRIDE { return mWidget; } virtual nsIWidget* GetWidget() const MOZ_OVERRIDE { return mWidget; }
virtual const nsIntSize& GetWidgetSize() MOZ_OVERRIDE
{
NS_ASSERTION(false, "Getting the widget size on windows causes some kind of resizing of buffers. "
"You should not do that outside of BeginFrame, so the best we can do is return "
"the last size we got, that might not be up to date. So you probably shouldn't "
"use this method.");
return mSize;
}
IDirect3DDevice9* device() const IDirect3DDevice9* device() const
{ {

Просмотреть файл

@ -1,24 +0,0 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set sw=2 ts=2 et tw=80 : */
/* 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/. */
#include "CompositorParent.h"
#include "CompositorCocoaWidgetHelper.h"
#include "nsDebug.h"
namespace mozilla {
namespace layers {
namespace compositor {
LayerManagerComposite*
GetLayerManager(CompositorParent* aParent)
{
return aParent->GetLayerManager();
}
}
}
}

Просмотреть файл

@ -1,29 +0,0 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/* vim: set sw=4 ts=8 et tw=80 : */
/* 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/. */
#ifndef mozilla_layers_CompositorCocoaWidgetHelper_h
#define mozilla_layers_CompositorCocoaWidgetHelper_h
// Note we can't include IPDL-generated headers here, since this file is being
// used as a workaround for Bug 719036.
namespace mozilla {
namespace layers {
class CompositorParent;
class LayerManagerComposite;
namespace compositor {
// Needed when we cannot directly include CompositorParent.h since it includes
// an IPDL-generated header (e.g. in widget/cocoa/nsChildView.mm; see Bug 719036).
LayerManagerComposite* GetLayerManager(CompositorParent* aParent);
}
}
}
#endif // mozilla_layers_CompositorCocoaWidgetHelper_h

Просмотреть файл

@ -62,6 +62,7 @@ namespace layers {
CompositorParent::LayerTreeState::LayerTreeState() CompositorParent::LayerTreeState::LayerTreeState()
: mParent(nullptr) : mParent(nullptr)
, mLayerManager(nullptr)
{ {
} }
@ -237,6 +238,7 @@ CompositorParent::Destroy()
// Ensure that the layer manager is destructed on the compositor thread. // Ensure that the layer manager is destructed on the compositor thread.
mLayerManager = nullptr; mLayerManager = nullptr;
mCompositor = nullptr;
mCompositionManager = nullptr; mCompositionManager = nullptr;
mApzcTreeManager->ClearTree(); mApzcTreeManager->ClearTree();
mApzcTreeManager = nullptr; mApzcTreeManager = nullptr;
@ -263,10 +265,12 @@ CompositorParent::RecvWillStop()
LayerTreeState* lts = &it->second; LayerTreeState* lts = &it->second;
if (lts->mParent == this) { if (lts->mParent == this) {
mLayerManager->ClearCachedResources(lts->mRoot); mLayerManager->ClearCachedResources(lts->mRoot);
lts->mLayerManager = nullptr;
} }
} }
mLayerManager->Destroy(); mLayerManager->Destroy();
mLayerManager = nullptr; mLayerManager = nullptr;
mCompositor = nullptr;
mCompositionManager = nullptr; mCompositionManager = nullptr;
} }
@ -371,7 +375,9 @@ CompositorParent::ActorDestroy(ActorDestroyReason why)
if (mLayerManager) { if (mLayerManager) {
mLayerManager->Destroy(); mLayerManager->Destroy();
mLayerManager = nullptr; mLayerManager = nullptr;
sIndirectLayerTrees[mRootLayerTreeID].mLayerManager = nullptr;
mCompositionManager = nullptr; mCompositionManager = nullptr;
mCompositor = nullptr;
} }
} }
@ -394,7 +400,7 @@ CompositorParent::PauseComposition()
if (!mPaused) { if (!mPaused) {
mPaused = true; mPaused = true;
mLayerManager->GetCompositor()->Pause(); mCompositor->Pause();
} }
// if anyone's waiting to make sure that composition really got paused, tell them // if anyone's waiting to make sure that composition really got paused, tell them
@ -409,7 +415,7 @@ CompositorParent::ResumeComposition()
MonitorAutoLock lock(mResumeCompositionMonitor); MonitorAutoLock lock(mResumeCompositionMonitor);
if (!mLayerManager->GetCompositor()->Resume()) { if (!mCompositor->Resume()) {
#ifdef MOZ_WIDGET_ANDROID #ifdef MOZ_WIDGET_ANDROID
// We can't get a surface. This could be because the activity changed between // We can't get a surface. This could be because the activity changed between
// the time resume was scheduled and now. // the time resume was scheduled and now.
@ -440,8 +446,8 @@ CompositorParent::SetEGLSurfaceSize(int width, int height)
{ {
NS_ASSERTION(mUseExternalSurfaceSize, "Compositor created without UseExternalSurfaceSize provided"); NS_ASSERTION(mUseExternalSurfaceSize, "Compositor created without UseExternalSurfaceSize provided");
mEGLSurfaceSize.SizeTo(width, height); mEGLSurfaceSize.SizeTo(width, height);
if (mLayerManager) { if (mCompositor) {
mLayerManager->GetCompositor()->SetDestinationSurfaceSize(gfx::IntSize(mEGLSurfaceSize.width, mEGLSurfaceSize.height)); mCompositor->SetDestinationSurfaceSize(gfx::IntSize(mEGLSurfaceSize.width, mEGLSurfaceSize.height));
} }
} }
@ -503,7 +509,7 @@ CompositorParent::NotifyShadowTreeTransaction(uint64_t aId, bool aIsFirstPaint)
AutoResolveRefLayers resolve(mCompositionManager); AutoResolveRefLayers resolve(mCompositionManager);
mApzcTreeManager->UpdatePanZoomControllerTree(this, mLayerManager->GetRoot(), aIsFirstPaint, aId); mApzcTreeManager->UpdatePanZoomControllerTree(this, mLayerManager->GetRoot(), aIsFirstPaint, aId);
mLayerManager->AsLayerManagerComposite()->NotifyShadowTreeTransaction(); mCompositor->NotifyLayersTransaction();
} }
ScheduleComposition(); ScheduleComposition();
} }
@ -697,7 +703,7 @@ CompositorParent::ShadowLayersUpdated(LayerTransactionParent* aLayerTree,
} }
} }
ScheduleComposition(); ScheduleComposition();
mLayerManager->NotifyShadowTreeTransaction(); mCompositor->NotifyLayersTransaction();
} }
void void
@ -706,34 +712,32 @@ CompositorParent::InitializeLayerManager(const nsTArray<LayersBackend>& aBackend
NS_ASSERTION(!mLayerManager, "Already initialised mLayerManager"); NS_ASSERTION(!mLayerManager, "Already initialised mLayerManager");
for (size_t i = 0; i < aBackendHints.Length(); ++i) { for (size_t i = 0; i < aBackendHints.Length(); ++i) {
RefPtr<LayerManagerComposite> layerManager; RefPtr<Compositor> compositor;
if (aBackendHints[i] == LAYERS_OPENGL) { if (aBackendHints[i] == LAYERS_OPENGL) {
layerManager = compositor = new CompositorOGL(mWidget,
new LayerManagerComposite(new CompositorOGL(mWidget, mEGLSurfaceSize.width,
mEGLSurfaceSize.width, mEGLSurfaceSize.height,
mEGLSurfaceSize.height, mUseExternalSurfaceSize);
mUseExternalSurfaceSize));
} else if (aBackendHints[i] == LAYERS_BASIC) { } else if (aBackendHints[i] == LAYERS_BASIC) {
layerManager = compositor = new BasicCompositor(mWidget);
new LayerManagerComposite(new BasicCompositor(mWidget));
#ifdef XP_WIN #ifdef XP_WIN
} else if (aBackendHints[i] == LAYERS_D3D11) { } else if (aBackendHints[i] == LAYERS_D3D11) {
layerManager = compositor = new CompositorD3D11(mWidget);
new LayerManagerComposite(new CompositorD3D11(mWidget));
} else if (aBackendHints[i] == LAYERS_D3D9) { } else if (aBackendHints[i] == LAYERS_D3D9) {
layerManager = compositor = new CompositorD3D9(this, mWidget);
new LayerManagerComposite(new CompositorD3D9(this, mWidget));
#endif #endif
} }
if (!layerManager) { MOZ_ASSERT(compositor, "Passed invalid backend hint");
continue;
}
layerManager->SetCompositorID(mCompositorID); compositor->SetCompositorID(mCompositorID);
RefPtr<LayerManagerComposite> layerManager = new LayerManagerComposite(compositor);
if (layerManager->Initialize()) { if (layerManager->Initialize()) {
mLayerManager = layerManager; mLayerManager = layerManager;
MOZ_ASSERT(compositor);
mCompositor = compositor;
sIndirectLayerTrees[mRootLayerTreeID].mLayerManager = layerManager;
return; return;
} }
} }
@ -765,7 +769,7 @@ CompositorParent::AllocPLayerTransactionParent(const nsTArray<LayersBackend>& aB
mCompositionManager = new AsyncCompositionManager(mLayerManager); mCompositionManager = new AsyncCompositionManager(mLayerManager);
*aSuccess = true; *aSuccess = true;
*aTextureFactoryIdentifier = mLayerManager->GetTextureFactoryIdentifier(); *aTextureFactoryIdentifier = mCompositor->GetTextureFactoryIdentifier();
LayerTransactionParent* p = new LayerTransactionParent(mLayerManager, this, 0); LayerTransactionParent* p = new LayerTransactionParent(mLayerManager, this, 0);
p->AddIPDLReference(); p->AddIPDLReference();
return p; return p;
@ -851,6 +855,7 @@ void
CompositorParent::NotifyChildCreated(uint64_t aChild) CompositorParent::NotifyChildCreated(uint64_t aChild)
{ {
sIndirectLayerTrees[aChild].mParent = this; sIndirectLayerTrees[aChild].mParent = this;
sIndirectLayerTrees[aChild].mLayerManager = mLayerManager;
} }
/*static*/ uint64_t /*static*/ uint64_t
@ -921,6 +926,17 @@ CompositorParent::GetAPZCTreeManager(uint64_t aLayersId)
return nullptr; return nullptr;
} }
float
CompositorParent::ComputeRenderIntegrity()
{
if (mLayerManager) {
return mLayerManager->ComputeRenderIntegrity();
}
return 1.0f;
}
/** /**
* This class handles layer updates pushed directly from child * This class handles layer updates pushed directly from child
* processes to the compositor thread. It's associated with a * processes to the compositor thread. It's associated with a
@ -1071,9 +1087,9 @@ CrossProcessCompositorParent::AllocPLayerTransactionParent(const nsTArray<Layers
{ {
MOZ_ASSERT(aId != 0); MOZ_ASSERT(aId != 0);
if (sIndirectLayerTrees[aId].mParent) { if (sIndirectLayerTrees[aId].mLayerManager) {
LayerManagerComposite* lm = sIndirectLayerTrees[aId].mParent->GetLayerManager(); LayerManagerComposite* lm = sIndirectLayerTrees[aId].mLayerManager;
*aTextureFactoryIdentifier = lm->GetTextureFactoryIdentifier(); *aTextureFactoryIdentifier = lm->GetCompositor()->GetTextureFactoryIdentifier();
*aSuccess = true; *aSuccess = true;
LayerTransactionParent* p = new LayerTransactionParent(lm, this, aId); LayerTransactionParent* p = new LayerTransactionParent(lm, this, aId);
p->AddIPDLReference(); p->AddIPDLReference();

Просмотреть файл

@ -47,6 +47,7 @@ namespace layers {
class APZCTreeManager; class APZCTreeManager;
class AsyncCompositionManager; class AsyncCompositionManager;
class Compositor;
class LayerManagerComposite; class LayerManagerComposite;
class LayerTransactionParent; class LayerTransactionParent;
@ -107,8 +108,6 @@ public:
void ForceIsFirstPaint(); void ForceIsFirstPaint();
void Destroy(); void Destroy();
LayerManagerComposite* GetLayerManager() { return mLayerManager; }
void NotifyChildCreated(uint64_t aChild); void NotifyChildCreated(uint64_t aChild);
void AsyncRender(); void AsyncRender();
@ -203,6 +202,7 @@ public:
nsRefPtr<Layer> mRoot; nsRefPtr<Layer> mRoot;
nsRefPtr<GeckoContentController> mController; nsRefPtr<GeckoContentController> mController;
CompositorParent* mParent; CompositorParent* mParent;
LayerManagerComposite* mLayerManager;
TargetConfig mTargetConfig; TargetConfig mTargetConfig;
}; };
@ -213,6 +213,8 @@ public:
*/ */
static const LayerTreeState* GetIndirectShadowTree(uint64_t aId); static const LayerTreeState* GetIndirectShadowTree(uint64_t aId);
float ComputeRenderIntegrity();
/** /**
* Tell all CompositorParents to update their last refresh to aTime and sample * Tell all CompositorParents to update their last refresh to aTime and sample
* animations at this time stamp. If aIsTesting is true, the * animations at this time stamp. If aIsTesting is true, the
@ -295,6 +297,7 @@ private:
bool CanComposite(); bool CanComposite();
nsRefPtr<LayerManagerComposite> mLayerManager; nsRefPtr<LayerManagerComposite> mLayerManager;
nsRefPtr<Compositor> mCompositor;
RefPtr<AsyncCompositionManager> mCompositionManager; RefPtr<AsyncCompositionManager> mCompositionManager;
nsIWidget* mWidget; nsIWidget* mWidget;
CancelableTask *mCurrentCompositeTask; CancelableTask *mCurrentCompositeTask;

Просмотреть файл

@ -128,7 +128,6 @@ EXPORTS.mozilla.layers += [
'ipc/CompositableForwarder.h', 'ipc/CompositableForwarder.h',
'ipc/CompositableTransactionParent.h', 'ipc/CompositableTransactionParent.h',
'ipc/CompositorChild.h', 'ipc/CompositorChild.h',
'ipc/CompositorCocoaWidgetHelper.h',
'ipc/CompositorParent.h', 'ipc/CompositorParent.h',
'ipc/GeckoContentController.h', 'ipc/GeckoContentController.h',
'ipc/GestureEventListener.h', 'ipc/GestureEventListener.h',
@ -240,7 +239,6 @@ UNIFIED_SOURCES += [
'ipc/Axis.cpp', 'ipc/Axis.cpp',
'ipc/CompositableTransactionParent.cpp', 'ipc/CompositableTransactionParent.cpp',
'ipc/CompositorChild.cpp', 'ipc/CompositorChild.cpp',
'ipc/CompositorCocoaWidgetHelper.cpp',
'ipc/CompositorParent.cpp', 'ipc/CompositorParent.cpp',
'ipc/GestureEventListener.cpp', 'ipc/GestureEventListener.cpp',
'ipc/ImageBridgeChild.cpp', 'ipc/ImageBridgeChild.cpp',

Просмотреть файл

@ -158,9 +158,6 @@ public:
virtual bool Resume() MOZ_OVERRIDE; virtual bool Resume() MOZ_OVERRIDE;
virtual nsIWidget* GetWidget() const MOZ_OVERRIDE { return mWidget; } virtual nsIWidget* GetWidget() const MOZ_OVERRIDE { return mWidget; }
virtual const nsIntSize& GetWidgetSize() MOZ_OVERRIDE {
return mWidgetSize;
}
GLContext* gl() const { return mGLContext; } GLContext* gl() const { return mGLContext; }
ShaderProgramType GetFBOLayerProgramType() const { ShaderProgramType GetFBOLayerProgramType() const {

Просмотреть файл

@ -6,7 +6,6 @@
#include "GLManager.h" #include "GLManager.h"
#include "CompositorOGL.h" // for CompositorOGL #include "CompositorOGL.h" // for CompositorOGL
#include "GLContext.h" // for GLContext #include "GLContext.h" // for GLContext
#include "Layers.h" // for LayerManager
#include "mozilla/Assertions.h" // for MOZ_CRASH #include "mozilla/Assertions.h" // for MOZ_CRASH
#include "mozilla/Attributes.h" // for MOZ_OVERRIDE #include "mozilla/Attributes.h" // for MOZ_OVERRIDE
#include "mozilla/RefPtr.h" // for RefPtr #include "mozilla/RefPtr.h" // for RefPtr
@ -15,7 +14,6 @@
#include "mozilla/layers/LayersTypes.h" #include "mozilla/layers/LayersTypes.h"
#include "mozilla/mozalloc.h" // for operator new, etc #include "mozilla/mozalloc.h" // for operator new, etc
#include "nsAutoPtr.h" // for nsRefPtr #include "nsAutoPtr.h" // for nsRefPtr
#include "nsISupportsImpl.h" // for LayerManager::AddRef, etc
using namespace mozilla::gl; using namespace mozilla::gl;
@ -49,21 +47,14 @@ private:
}; };
/* static */ GLManager* /* static */ GLManager*
GLManager::CreateGLManager(LayerManager* aManager) GLManager::CreateGLManager(LayerManagerComposite* aManager)
{ {
if (!aManager) { if (aManager &&
return nullptr; Compositor::GetBackend() == LAYERS_OPENGL) {
return new GLManagerCompositor(static_cast<CompositorOGL*>(
aManager->GetCompositor()));
} }
if (aManager->GetBackendType() == LAYERS_NONE) { return nullptr;
if (Compositor::GetBackend() == LAYERS_OPENGL) {
return new GLManagerCompositor(static_cast<CompositorOGL*>(
static_cast<LayerManagerComposite*>(aManager)->GetCompositor()));
} else {
return nullptr;
}
}
MOZ_CRASH("Cannot create GLManager for non-GL layer manager");
} }
} }

Просмотреть файл

@ -16,7 +16,7 @@ class GLContext;
namespace layers { namespace layers {
class LayerManager; class LayerManagerComposite;
/** /**
* Minimal interface to allow widgets to draw using OpenGL. Abstracts * Minimal interface to allow widgets to draw using OpenGL. Abstracts
@ -26,7 +26,7 @@ class LayerManager;
class GLManager class GLManager
{ {
public: public:
static GLManager* CreateGLManager(LayerManager* aManager); static GLManager* CreateGLManager(LayerManagerComposite* aManager);
virtual ~GLManager() {} virtual ~GLManager() {}

Просмотреть файл

@ -256,8 +256,17 @@ private:
nsRegion& Copy (const nsRect& aRect) nsRegion& Copy (const nsRect& aRect)
{ {
pixman_box32_t box = RectToBox(aRect); // pixman needs to distinguish between an empty region and a region
pixman_region32_reset(&mImpl, &box); // with one rect so that it can return a different number of rectangles.
// Empty rect: data = empty_box
// 1 rect: data = NULL
// >1 rect: data = rects
if (aRect.IsEmpty()) {
pixman_region32_clear(&mImpl);
} else {
pixman_box32_t box = RectToBox(aRect);
pixman_region32_reset(&mImpl, &box);
}
return *this; return *this;
} }

Просмотреть файл

@ -631,10 +631,10 @@ PR_STATIC_ASSERT(uint32_t(CAIRO_SURFACE_TYPE_SKIA) ==
static int64_t gSurfaceMemoryUsed[gfxSurfaceTypeMax] = { 0 }; static int64_t gSurfaceMemoryUsed[gfxSurfaceTypeMax] = { 0 };
class SurfaceMemoryReporter MOZ_FINAL : public MemoryMultiReporter class SurfaceMemoryReporter MOZ_FINAL : public nsIMemoryReporter
{ {
public: public:
SurfaceMemoryReporter() { } NS_DECL_ISUPPORTS
NS_IMETHOD CollectReports(nsIMemoryReporterCallback *aCb, NS_IMETHOD CollectReports(nsIMemoryReporterCallback *aCb,
nsISupports *aClosure) nsISupports *aClosure)
@ -651,8 +651,7 @@ public:
} }
nsresult rv = aCb->Callback(EmptyCString(), nsCString(path), nsresult rv = aCb->Callback(EmptyCString(), nsCString(path),
nsIMemoryReporter::KIND_OTHER, KIND_OTHER, UNITS_BYTES,
nsIMemoryReporter::UNITS_BYTES,
gSurfaceMemoryUsed[i], gSurfaceMemoryUsed[i],
nsCString(desc), aClosure); nsCString(desc), aClosure);
NS_ENSURE_SUCCESS(rv, rv); NS_ENSURE_SUCCESS(rv, rv);
@ -663,6 +662,8 @@ public:
} }
}; };
NS_IMPL_ISUPPORTS1(SurfaceMemoryReporter, nsIMemoryReporter)
void void
gfxASurface::RecordMemoryUsedForSurfaceType(gfxSurfaceType aType, gfxASurface::RecordMemoryUsedForSurfaceType(gfxSurfaceType aType,
int32_t aBytes) int32_t aBytes)

Просмотреть файл

@ -1360,7 +1360,9 @@ gfxFontFamily::AddSizeOfIncludingThis(MallocSizeOf aMallocSizeOf,
* shaped-word caches to free up memory. * shaped-word caches to free up memory.
*/ */
NS_MEMORY_REPORTER_MALLOC_SIZEOF_FUN(FontCacheMallocSizeOf) MOZ_DEFINE_MALLOC_SIZE_OF(FontCacheMallocSizeOf)
NS_IMPL_ISUPPORTS1(gfxFontCache::MemoryReporter, nsIMemoryReporter)
NS_IMETHODIMP NS_IMETHODIMP
gfxFontCache::MemoryReporter::CollectReports gfxFontCache::MemoryReporter::CollectReports

Просмотреть файл

@ -951,13 +951,11 @@ public:
FontCacheSizes* aSizes) const; FontCacheSizes* aSizes) const;
protected: protected:
class MemoryReporter MOZ_FINAL : public mozilla::MemoryMultiReporter class MemoryReporter MOZ_FINAL : public nsIMemoryReporter
{ {
public: public:
MemoryReporter() {} NS_DECL_ISUPPORTS
NS_DECL_NSIMEMORYREPORTER
NS_IMETHOD CollectReports(nsIMemoryReporterCallback* aCb,
nsISupports* aClosure);
}; };
// Observer for notifications that the font cache cares about // Observer for notifications that the font cache cares about

Просмотреть файл

@ -71,10 +71,9 @@ gfxFontListPrefObserver::Observe(nsISupports *aSubject,
return NS_OK; return NS_OK;
} }
NS_MEMORY_REPORTER_MALLOC_SIZEOF_FUN(FontListMallocSizeOf) MOZ_DEFINE_MALLOC_SIZE_OF(FontListMallocSizeOf)
gfxPlatformFontList::MemoryReporter::MemoryReporter() NS_IMPL_ISUPPORTS1(gfxPlatformFontList::MemoryReporter, nsIMemoryReporter)
{}
NS_IMETHODIMP NS_IMETHODIMP
gfxPlatformFontList::MemoryReporter::CollectReports gfxPlatformFontList::MemoryReporter::CollectReports
@ -91,23 +90,20 @@ gfxPlatformFontList::MemoryReporter::CollectReports
aCb->Callback(EmptyCString(), aCb->Callback(EmptyCString(),
NS_LITERAL_CSTRING("explicit/gfx/font-list"), NS_LITERAL_CSTRING("explicit/gfx/font-list"),
nsIMemoryReporter::KIND_HEAP, nsIMemoryReporter::UNITS_BYTES, KIND_HEAP, UNITS_BYTES, sizes.mFontListSize,
sizes.mFontListSize,
NS_LITERAL_CSTRING("Memory used to manage the list of font families and faces."), NS_LITERAL_CSTRING("Memory used to manage the list of font families and faces."),
aClosure); aClosure);
aCb->Callback(EmptyCString(), aCb->Callback(EmptyCString(),
NS_LITERAL_CSTRING("explicit/gfx/font-charmaps"), NS_LITERAL_CSTRING("explicit/gfx/font-charmaps"),
nsIMemoryReporter::KIND_HEAP, nsIMemoryReporter::UNITS_BYTES, KIND_HEAP, UNITS_BYTES, sizes.mCharMapsSize,
sizes.mCharMapsSize,
NS_LITERAL_CSTRING("Memory used to record the character coverage of individual fonts."), NS_LITERAL_CSTRING("Memory used to record the character coverage of individual fonts."),
aClosure); aClosure);
if (sizes.mFontTableCacheSize) { if (sizes.mFontTableCacheSize) {
aCb->Callback(EmptyCString(), aCb->Callback(EmptyCString(),
NS_LITERAL_CSTRING("explicit/gfx/font-tables"), NS_LITERAL_CSTRING("explicit/gfx/font-tables"),
nsIMemoryReporter::KIND_HEAP, nsIMemoryReporter::UNITS_BYTES, KIND_HEAP, UNITS_BYTES, sizes.mFontTableCacheSize,
sizes.mFontTableCacheSize,
NS_LITERAL_CSTRING("Memory used for cached font metrics and layout tables."), NS_LITERAL_CSTRING("Memory used for cached font metrics and layout tables."),
aClosure); aClosure);
} }

Просмотреть файл

@ -178,12 +178,11 @@ public:
void RemoveCmap(const gfxCharacterMap *aCharMap); void RemoveCmap(const gfxCharacterMap *aCharMap);
protected: protected:
class MemoryReporter MOZ_FINAL : public mozilla::MemoryMultiReporter class MemoryReporter MOZ_FINAL : public nsIMemoryReporter
{ {
public: public:
MemoryReporter(); NS_DECL_ISUPPORTS
NS_IMETHOD CollectReports(nsIMemoryReporterCallback *aCb, NS_DECL_NSIMEMORYREPORTER
nsISupports *aClosure);
}; };
gfxPlatformFontList(bool aNeedFullnamePostscriptNames = true); gfxPlatformFontList(bool aNeedFullnamePostscriptNames = true);

Просмотреть файл

@ -3,10 +3,8 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this * 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/. */ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifdef MOZ_PANGO
#define PANGO_ENABLE_BACKEND #define PANGO_ENABLE_BACKEND
#define PANGO_ENABLE_ENGINE #define PANGO_ENABLE_ENGINE
#endif
#include "gfxPlatformGtk.h" #include "gfxPlatformGtk.h"
#include "prenv.h" #include "prenv.h"
@ -14,16 +12,10 @@
#include "nsUnicharUtils.h" #include "nsUnicharUtils.h"
#include "nsUnicodeProperties.h" #include "nsUnicodeProperties.h"
#include "gfxFontconfigUtils.h" #include "gfxFontconfigUtils.h"
#ifdef MOZ_PANGO
#include "gfxPangoFonts.h" #include "gfxPangoFonts.h"
#include "gfxContext.h" #include "gfxContext.h"
#include "gfxUserFontSet.h" #include "gfxUserFontSet.h"
#include "gfxFT2FontBase.h" #include "gfxFT2FontBase.h"
#else
#include <ft2build.h>
#include FT_FREETYPE_H
#include "gfxFT2Fonts.h"
#endif
#include "mozilla/gfx/2D.h" #include "mozilla/gfx/2D.h"
@ -56,16 +48,6 @@ using namespace mozilla::unicode;
gfxFontconfigUtils *gfxPlatformGtk::sFontconfigUtils = nullptr; gfxFontconfigUtils *gfxPlatformGtk::sFontconfigUtils = nullptr;
#ifndef MOZ_PANGO
typedef nsDataHashtable<nsStringHashKey, nsRefPtr<FontFamily> > FontTable;
typedef nsDataHashtable<nsCStringHashKey, nsTArray<nsRefPtr<gfxFontEntry> > > PrefFontTable;
static FontTable *gPlatformFonts = nullptr;
static FontTable *gPlatformFontAliases = nullptr;
static PrefFontTable *gPrefFonts = nullptr;
static gfxSparseBitSet *gCodepointsWithNoFonts = nullptr;
static FT_Library gPlatformFTLibrary = nullptr;
#endif
static cairo_user_data_key_t cairo_gdk_drawable_key; static cairo_user_data_key_t cairo_gdk_drawable_key;
#ifdef MOZ_X11 #ifdef MOZ_X11
@ -80,17 +62,6 @@ gfxPlatformGtk::gfxPlatformGtk()
sUseXRender = mozilla::Preferences::GetBool("gfx.xrender.enabled"); sUseXRender = mozilla::Preferences::GetBool("gfx.xrender.enabled");
#endif #endif
#ifndef MOZ_PANGO
FT_Init_FreeType(&gPlatformFTLibrary);
gPlatformFonts = new FontTable();
gPlatformFonts->Init(100);
gPlatformFontAliases = new FontTable();
gPlatformFontAliases->Init(100);
gPrefFonts = new PrefFontTable();
gPrefFonts->Init(100);
gCodepointsWithNoFonts = new gfxSparseBitSet();
UpdateFontList();
#endif
uint32_t canvasMask = (1 << BACKEND_CAIRO) | (1 << BACKEND_SKIA); uint32_t canvasMask = (1 << BACKEND_CAIRO) | (1 << BACKEND_SKIA);
uint32_t contentMask = (1 << BACKEND_CAIRO) | (1 << BACKEND_SKIA); uint32_t contentMask = (1 << BACKEND_CAIRO) | (1 << BACKEND_SKIA);
InitBackendPrefs(canvasMask, BACKEND_CAIRO, InitBackendPrefs(canvasMask, BACKEND_CAIRO,
@ -102,28 +73,7 @@ gfxPlatformGtk::~gfxPlatformGtk()
gfxFontconfigUtils::Shutdown(); gfxFontconfigUtils::Shutdown();
sFontconfigUtils = nullptr; sFontconfigUtils = nullptr;
#ifdef MOZ_PANGO
gfxPangoFontGroup::Shutdown(); gfxPangoFontGroup::Shutdown();
#else
delete gPlatformFonts;
gPlatformFonts = nullptr;
delete gPlatformFontAliases;
gPlatformFontAliases = nullptr;
delete gPrefFonts;
gPrefFonts = nullptr;
delete gCodepointsWithNoFonts;
gCodepointsWithNoFonts = nullptr;
#ifdef NS_FREE_PERMANENT_DATA
// do cairo cleanup *before* closing down the FTLibrary,
// otherwise we'll crash when the gfxPlatform destructor
// calls it (bug 605009)
cairo_debug_reset_static_data();
FT_Done_FreeType(gPlatformFTLibrary);
gPlatformFTLibrary = nullptr;
#endif
#endif
#if 0 #if 0
// It would be nice to do this (although it might need to be after // It would be nice to do this (although it might need to be after
@ -187,8 +137,6 @@ gfxPlatformGtk::CreateOffscreenSurface(const gfxIntSize& size,
return newSurface.forget(); return newSurface.forget();
} }
#ifdef MOZ_PANGO
nsresult nsresult
gfxPlatformGtk::GetFontList(nsIAtom *aLangGroup, gfxPlatformGtk::GetFontList(nsIAtom *aLangGroup,
const nsACString& aGenericFamily, const nsACString& aGenericFamily,
@ -270,188 +218,6 @@ gfxPlatformGtk::IsFontFormatSupported(nsIURI *aFontURI, uint32_t aFormatFlags)
return true; return true;
} }
#else
nsresult
gfxPlatformGtk::GetFontList(nsIAtom *aLangGroup,
const nsACString& aGenericFamily,
nsTArray<nsString>& aListOfFonts)
{
return sFontconfigUtils->GetFontList(aLangGroup, aGenericFamily,
aListOfFonts);
}
nsresult
gfxPlatformGtk::UpdateFontList()
{
FcPattern *pat = nullptr;
FcObjectSet *os = nullptr;
FcFontSet *fs = nullptr;
int32_t result = -1;
pat = FcPatternCreate();
os = FcObjectSetBuild(FC_FAMILY, FC_FILE, FC_INDEX, FC_WEIGHT, FC_SLANT, FC_WIDTH, nullptr);
fs = FcFontList(nullptr, pat, os);
for (int i = 0; i < fs->nfont; i++) {
char *str;
if (FcPatternGetString(fs->fonts[i], FC_FAMILY, 0, (FcChar8 **) &str) != FcResultMatch)
continue;
//printf("Family: %s\n", str);
nsAutoString name(NS_ConvertUTF8toUTF16(nsDependentCString(str)).get());
nsAutoString key(name);
ToLowerCase(key);
nsRefPtr<FontFamily> ff;
if (!gPlatformFonts->Get(key, &ff)) {
ff = new FontFamily(name);
gPlatformFonts->Put(key, ff);
}
FontEntry *fe = new FontEntry(ff->Name());
ff->AddFontEntry(fe);
if (FcPatternGetString(fs->fonts[i], FC_FILE, 0, (FcChar8 **) &str) == FcResultMatch) {
fe->mFilename = nsDependentCString(str);
//printf(" - file: %s\n", str);
}
int x;
if (FcPatternGetInteger(fs->fonts[i], FC_INDEX, 0, &x) == FcResultMatch) {
//printf(" - index: %d\n", x);
fe->mFTFontIndex = x;
} else {
fe->mFTFontIndex = 0;
}
fe->mWeight = gfxFontconfigUtils::GetThebesWeight(fs->fonts[i]);
//printf(" - weight: %d\n", fe->mWeight);
fe->mItalic = false;
if (FcPatternGetInteger(fs->fonts[i], FC_SLANT, 0, &x) == FcResultMatch) {
switch (x) {
case FC_SLANT_ITALIC:
case FC_SLANT_OBLIQUE:
fe->mItalic = true;
}
//printf(" - slant: %d\n", x);
}
//if (FcPatternGetInteger(fs->fonts[i], FC_WIDTH, 0, &x) == FcResultMatch)
//printf(" - width: %d\n", x);
// XXX deal with font-stretch stuff later
}
if (pat)
FcPatternDestroy(pat);
if (os)
FcObjectSetDestroy(os);
if (fs)
FcFontSetDestroy(fs);
return sFontconfigUtils->UpdateFontList();
}
nsresult
gfxPlatformGtk::ResolveFontName(const nsAString& aFontName,
FontResolverCallback aCallback,
void *aClosure,
bool& aAborted)
{
nsAutoString name(aFontName);
ToLowerCase(name);
nsRefPtr<FontFamily> ff;
if (gPlatformFonts->Get(name, &ff) ||
gPlatformFontAliases->Get(name, &ff)) {
aAborted = !(*aCallback)(ff->Name(), aClosure);
return NS_OK;
}
nsAutoCString utf8Name = NS_ConvertUTF16toUTF8(aFontName);
FcPattern *npat = FcPatternCreate();
FcPatternAddString(npat, FC_FAMILY, (FcChar8*)utf8Name.get());
FcObjectSet *nos = FcObjectSetBuild(FC_FAMILY, nullptr);
FcFontSet *nfs = FcFontList(nullptr, npat, nos);
for (int k = 0; k < nfs->nfont; k++) {
FcChar8 *str;
if (FcPatternGetString(nfs->fonts[k], FC_FAMILY, 0, (FcChar8 **) &str) != FcResultMatch)
continue;
nsAutoString altName = NS_ConvertUTF8toUTF16(nsDependentCString(reinterpret_cast<char*>(str)));
ToLowerCase(altName);
if (gPlatformFonts->Get(altName, &ff)) {
//printf("Adding alias: %s -> %s\n", utf8Name.get(), str);
gPlatformFontAliases->Put(name, ff);
aAborted = !(*aCallback)(NS_ConvertUTF8toUTF16(nsDependentCString(reinterpret_cast<char*>(str))), aClosure);
goto DONE;
}
}
FcPatternDestroy(npat);
FcObjectSetDestroy(nos);
FcFontSetDestroy(nfs);
{
npat = FcPatternCreate();
FcPatternAddString(npat, FC_FAMILY, (FcChar8*)utf8Name.get());
FcPatternDel(npat, FC_LANG);
FcConfigSubstitute(nullptr, npat, FcMatchPattern);
FcDefaultSubstitute(npat);
nos = FcObjectSetBuild(FC_FAMILY, nullptr);
nfs = FcFontList(nullptr, npat, nos);
FcResult fresult;
FcPattern *match = FcFontMatch(nullptr, npat, &fresult);
if (match)
FcFontSetAdd(nfs, match);
for (int k = 0; k < nfs->nfont; k++) {
FcChar8 *str;
if (FcPatternGetString(nfs->fonts[k], FC_FAMILY, 0, (FcChar8 **) &str) != FcResultMatch)
continue;
nsAutoString altName = NS_ConvertUTF8toUTF16(nsDependentCString(reinterpret_cast<char*>(str)));
ToLowerCase(altName);
if (gPlatformFonts->Get(altName, &ff)) {
//printf("Adding alias: %s -> %s\n", utf8Name.get(), str);
gPlatformFontAliases->Put(name, ff);
aAborted = !(*aCallback)(NS_ConvertUTF8toUTF16(nsDependentCString(reinterpret_cast<char*>(str))), aClosure);
goto DONE;
}
}
}
DONE:
FcPatternDestroy(npat);
FcObjectSetDestroy(nos);
FcFontSetDestroy(nfs);
return NS_OK;
}
nsresult
gfxPlatformGtk::GetStandardFamilyName(const nsAString& aFontName, nsAString& aFamilyName)
{
return sFontconfigUtils->GetStandardFamilyName(aFontName, aFamilyName);
}
gfxFontGroup *
gfxPlatformGtk::CreateFontGroup(const nsAString &aFamilies,
const gfxFontStyle *aStyle,
gfxUserFontSet *aUserFontSet)
{
return new gfxFT2FontGroup(aFamilies, aStyle, aUserFontSet);
}
#endif
static int32_t sDPI = 0; static int32_t sDPI = 0;
int32_t int32_t
@ -637,90 +403,6 @@ gfxPlatformGtk::GetPlatformCMSOutputProfile()
} }
#ifndef MOZ_PANGO
FT_Library
gfxPlatformGtk::GetFTLibrary()
{
return gPlatformFTLibrary;
}
FontFamily *
gfxPlatformGtk::FindFontFamily(const nsAString& aName)
{
nsAutoString name(aName);
ToLowerCase(name);
nsRefPtr<FontFamily> ff;
if (!gPlatformFonts->Get(name, &ff)) {
return nullptr;
}
return ff.get();
}
FontEntry *
gfxPlatformGtk::FindFontEntry(const nsAString& aName, const gfxFontStyle& aFontStyle)
{
nsRefPtr<FontFamily> ff = FindFontFamily(aName);
if (!ff)
return nullptr;
return ff->FindFontEntry(aFontStyle);
}
static PLDHashOperator
FindFontForCharProc(nsStringHashKey::KeyType aKey,
nsRefPtr<FontFamily>& aFontFamily,
void* aUserArg)
{
GlobalFontMatch *data = (GlobalFontMatch*)aUserArg;
aFontFamily->FindFontForChar(data);
return PL_DHASH_NEXT;
}
already_AddRefed<gfxFont>
gfxPlatformGtk::FindFontForChar(uint32_t aCh, gfxFont *aFont)
{
if (!gPlatformFonts || !gCodepointsWithNoFonts)
return nullptr;
// is codepoint with no matching font? return null immediately
if (gCodepointsWithNoFonts->test(aCh)) {
return nullptr;
}
GlobalFontMatch data(aCh, GetScriptCode(aCh),
(aFont ? aFont->GetStyle() : nullptr));
// find fonts that support the character
gPlatformFonts->Enumerate(FindFontForCharProc, &data);
if (data.mBestMatch) {
nsRefPtr<gfxFT2Font> font =
gfxFT2Font::GetOrMakeFont(static_cast<FontEntry*>(data.mBestMatch.get()),
aFont->GetStyle());
gfxFont* ret = font.forget().get();
return already_AddRefed<gfxFont>(ret);
}
// no match? add to set of non-matching codepoints
gCodepointsWithNoFonts->set(aCh);
return nullptr;
}
bool
gfxPlatformGtk::GetPrefFontEntries(const nsCString& aKey, nsTArray<nsRefPtr<gfxFontEntry> > *aFontEntryList)
{
return gPrefFonts->Get(aKey, aFontEntryList);
}
void
gfxPlatformGtk::SetPrefFontEntries(const nsCString& aKey, nsTArray<nsRefPtr<gfxFontEntry> >& aFontEntryList)
{
gPrefFonts->Put(aKey, aFontEntryList);
}
#endif
#if (MOZ_WIDGET_GTK == 2) #if (MOZ_WIDGET_GTK == 2)
void void
gfxPlatformGtk::SetGdkDrawable(cairo_surface_t *target, gfxPlatformGtk::SetGdkDrawable(cairo_surface_t *target,

Просмотреть файл

@ -17,11 +17,6 @@ extern "C" {
#endif #endif
class gfxFontconfigUtils; class gfxFontconfigUtils;
#ifndef MOZ_PANGO
class FontFamily;
class FontEntry;
typedef struct FT_LibraryRec_ *FT_Library;
#endif
class gfxPlatformGtk : public gfxPlatform { class gfxPlatformGtk : public gfxPlatform {
public: public:
@ -54,7 +49,6 @@ public:
const gfxFontStyle *aStyle, const gfxFontStyle *aStyle,
gfxUserFontSet *aUserFontSet); gfxUserFontSet *aUserFontSet);
#ifdef MOZ_PANGO
/** /**
* Look up a local platform font using the full font face name (needed to * Look up a local platform font using the full font face name (needed to
* support @font-face src local() ) * support @font-face src local() )
@ -76,19 +70,6 @@ public:
*/ */
virtual bool IsFontFormatSupported(nsIURI *aFontURI, virtual bool IsFontFormatSupported(nsIURI *aFontURI,
uint32_t aFormatFlags); uint32_t aFormatFlags);
#endif
#ifndef MOZ_PANGO
FontFamily *FindFontFamily(const nsAString& aName);
FontEntry *FindFontEntry(const nsAString& aFamilyName, const gfxFontStyle& aFontStyle);
already_AddRefed<gfxFont> FindFontForChar(uint32_t aCh, gfxFont *aFont);
bool GetPrefFontEntries(const nsCString& aLangGroup, nsTArray<nsRefPtr<gfxFontEntry> > *aFontEntryList);
void SetPrefFontEntries(const nsCString& aLangGroup, nsTArray<nsRefPtr<gfxFontEntry> >& aFontEntryList);
#endif
#ifndef MOZ_PANGO
FT_Library GetFTLibrary();
#endif
#if (MOZ_WIDGET_GTK == 2) #if (MOZ_WIDGET_GTK == 2)
static void SetGdkDrawable(cairo_surface_t *target, static void SetGdkDrawable(cairo_surface_t *target,

Просмотреть файл

@ -27,13 +27,9 @@
#include "gfxQPainterSurface.h" #include "gfxQPainterSurface.h"
#include "nsUnicodeProperties.h" #include "nsUnicodeProperties.h"
#ifdef MOZ_PANGO
#include "gfxPangoFonts.h" #include "gfxPangoFonts.h"
#include "gfxContext.h" #include "gfxContext.h"
#include "gfxUserFontSet.h" #include "gfxUserFontSet.h"
#else
#include "gfxFT2Fonts.h"
#endif
#include "nsUnicharUtils.h" #include "nsUnicharUtils.h"
@ -47,11 +43,6 @@
#include "qcms.h" #include "qcms.h"
#ifndef MOZ_PANGO
#include <ft2build.h>
#include FT_FREETYPE_H
#endif
#include "mozilla/Preferences.h" #include "mozilla/Preferences.h"
using namespace mozilla; using namespace mozilla;
@ -75,16 +66,6 @@ static void do_qt_pixmap_unref (void *data)
static gfxImageFormat sOffscreenFormat = gfxImageFormatRGB24; static gfxImageFormat sOffscreenFormat = gfxImageFormatRGB24;
#ifndef MOZ_PANGO
typedef nsDataHashtable<nsStringHashKey, nsRefPtr<FontFamily> > FontTable;
typedef nsDataHashtable<nsCStringHashKey, nsTArray<nsRefPtr<FontEntry> > > PrefFontTable;
static FontTable *gPlatformFonts = nullptr;
static FontTable *gPlatformFontAliases = nullptr;
static PrefFontTable *gPrefFonts = nullptr;
static gfxSparseBitSet *gCodepointsWithNoFonts = nullptr;
static FT_Library gPlatformFTLibrary = nullptr;
#endif
gfxQtPlatform::gfxQtPlatform() gfxQtPlatform::gfxQtPlatform()
{ {
mPrefFonts.Init(50); mPrefFonts.Init(50);
@ -92,20 +73,7 @@ gfxQtPlatform::gfxQtPlatform()
if (!sFontconfigUtils) if (!sFontconfigUtils)
sFontconfigUtils = gfxFontconfigUtils::GetFontconfigUtils(); sFontconfigUtils = gfxFontconfigUtils::GetFontconfigUtils();
#ifdef MOZ_PANGO
g_type_init(); g_type_init();
#else
FT_Init_FreeType(&gPlatformFTLibrary);
gPlatformFonts = new FontTable();
gPlatformFonts->Init(100);
gPlatformFontAliases = new FontTable();
gPlatformFontAliases->Init(100);
gPrefFonts = new PrefFontTable();
gPrefFonts->Init(100);
gCodepointsWithNoFonts = new gfxSparseBitSet();
UpdateFontList();
#endif
nsresult rv; nsresult rv;
// 0 - default gfxQPainterSurface // 0 - default gfxQPainterSurface
@ -148,23 +116,7 @@ gfxQtPlatform::~gfxQtPlatform()
gfxFontconfigUtils::Shutdown(); gfxFontconfigUtils::Shutdown();
sFontconfigUtils = nullptr; sFontconfigUtils = nullptr;
#ifdef MOZ_PANGO
gfxPangoFontGroup::Shutdown(); gfxPangoFontGroup::Shutdown();
#else
delete gPlatformFonts;
gPlatformFonts = nullptr;
delete gPlatformFontAliases;
gPlatformFontAliases = nullptr;
delete gPrefFonts;
gPrefFonts = nullptr;
delete gCodepointsWithNoFonts;
gCodepointsWithNoFonts = nullptr;
cairo_debug_reset_static_data();
FT_Done_FreeType(gPlatformFTLibrary);
gPlatformFTLibrary = nullptr;
#endif
#if 0 #if 0
// It would be nice to do this (although it might need to be after // It would be nice to do this (although it might need to be after
@ -259,103 +211,6 @@ gfxQtPlatform::GetFontList(nsIAtom *aLangGroup,
nsresult nsresult
gfxQtPlatform::UpdateFontList() gfxQtPlatform::UpdateFontList()
{ {
#ifndef MOZ_PANGO
FcPattern *pat = nullptr;
FcObjectSet *os = nullptr;
FcFontSet *fs = nullptr;
pat = FcPatternCreate();
os = FcObjectSetBuild(FC_FAMILY, FC_FILE, FC_INDEX, FC_WEIGHT, FC_SLANT, FC_WIDTH, nullptr);
fs = FcFontList(nullptr, pat, os);
for (int i = 0; i < fs->nfont; i++) {
char *str;
if (FcPatternGetString(fs->fonts[i], FC_FAMILY, 0, (FcChar8 **) &str) != FcResultMatch)
continue;
nsAutoString name(NS_ConvertUTF8toUTF16(nsDependentCString(str)).get());
nsAutoString key(name);
ToLowerCase(key);
nsRefPtr<FontFamily> ff;
if (!gPlatformFonts->Get(key, &ff)) {
ff = new FontFamily(name);
gPlatformFonts->Put(key, ff);
}
FontEntry *fe = new FontEntry(ff->Name());
ff->AddFontEntry(fe);
if (FcPatternGetString(fs->fonts[i], FC_FILE, 0, (FcChar8 **) &str) == FcResultMatch) {
fe->mFilename = nsDependentCString(str);
}
int x;
if (FcPatternGetInteger(fs->fonts[i], FC_INDEX, 0, &x) == FcResultMatch) {
fe->mFTFontIndex = x;
} else {
fe->mFTFontIndex = 0;
}
if (FcPatternGetInteger(fs->fonts[i], FC_WEIGHT, 0, &x) == FcResultMatch) {
switch(x) {
case 0:
fe->mWeight = 100;
break;
case 40:
fe->mWeight = 200;
break;
case 50:
fe->mWeight = 300;
break;
case 75:
case 80:
fe->mWeight = 400;
break;
case 100:
fe->mWeight = 500;
break;
case 180:
fe->mWeight = 600;
break;
case 200:
fe->mWeight = 700;
break;
case 205:
fe->mWeight = 800;
break;
case 210:
fe->mWeight = 900;
break;
default:
// rough estimate
fe->mWeight = (((x * 4) + 100) / 100) * 100;
break;
}
}
fe->mItalic = false;
if (FcPatternGetInteger(fs->fonts[i], FC_SLANT, 0, &x) == FcResultMatch) {
switch (x) {
case FC_SLANT_ITALIC:
case FC_SLANT_OBLIQUE:
fe->mItalic = true;
}
}
// XXX deal with font-stretch (FC_WIDTH) stuff later
}
if (pat)
FcPatternDestroy(pat);
if (os)
FcObjectSetDestroy(os);
if (fs)
FcFontSetDestroy(fs);
#endif
return sFontconfigUtils->UpdateFontList(); return sFontconfigUtils->UpdateFontList();
} }
@ -365,80 +220,8 @@ gfxQtPlatform::ResolveFontName(const nsAString& aFontName,
void *aClosure, void *aClosure,
bool& aAborted) bool& aAborted)
{ {
#ifdef MOZ_PANGO
return sFontconfigUtils->ResolveFontName(aFontName, aCallback, return sFontconfigUtils->ResolveFontName(aFontName, aCallback,
aClosure, aAborted); aClosure, aAborted);
#else
nsAutoString name(aFontName);
ToLowerCase(name);
nsRefPtr<FontFamily> ff;
if (gPlatformFonts->Get(name, &ff) ||
gPlatformFontAliases->Get(name, &ff)) {
aAborted = !(*aCallback)(ff->Name(), aClosure);
return NS_OK;
}
nsAutoCString utf8Name = NS_ConvertUTF16toUTF8(aFontName);
FcPattern *npat = FcPatternCreate();
FcPatternAddString(npat, FC_FAMILY, (FcChar8*)utf8Name.get());
FcObjectSet *nos = FcObjectSetBuild(FC_FAMILY, nullptr);
FcFontSet *nfs = FcFontList(nullptr, npat, nos);
for (int k = 0; k < nfs->nfont; k++) {
FcChar8 *str;
if (FcPatternGetString(nfs->fonts[k], FC_FAMILY, 0, (FcChar8 **) &str) != FcResultMatch)
continue;
nsAutoString altName = NS_ConvertUTF8toUTF16(nsDependentCString(reinterpret_cast<char*>(str)));
ToLowerCase(altName);
if (gPlatformFonts->Get(altName, &ff)) {
gPlatformFontAliases->Put(name, ff);
aAborted = !(*aCallback)(NS_ConvertUTF8toUTF16(nsDependentCString(reinterpret_cast<char*>(str))), aClosure);
goto DONE;
}
}
FcPatternDestroy(npat);
FcObjectSetDestroy(nos);
FcFontSetDestroy(nfs);
{
npat = FcPatternCreate();
FcPatternAddString(npat, FC_FAMILY, (FcChar8*)utf8Name.get());
FcPatternDel(npat, FC_LANG);
FcConfigSubstitute(nullptr, npat, FcMatchPattern);
FcDefaultSubstitute(npat);
nos = FcObjectSetBuild(FC_FAMILY, nullptr);
nfs = FcFontList(nullptr, npat, nos);
FcResult fresult;
FcPattern *match = FcFontMatch(nullptr, npat, &fresult);
if (match)
FcFontSetAdd(nfs, match);
for (int k = 0; k < nfs->nfont; k++) {
FcChar8 *str;
if (FcPatternGetString(nfs->fonts[k], FC_FAMILY, 0, (FcChar8 **) &str) != FcResultMatch)
continue;
nsAutoString altName = NS_ConvertUTF8toUTF16(nsDependentCString(reinterpret_cast<char*>(str)));
ToLowerCase(altName);
if (gPlatformFonts->Get(altName, &ff)) {
gPlatformFontAliases->Put(name, ff);
aAborted = !(*aCallback)(NS_ConvertUTF8toUTF16(nsDependentCString(reinterpret_cast<char*>(str))), aClosure);
goto DONE;
}
}
}
DONE:
FcPatternDestroy(npat);
FcObjectSetDestroy(nos);
FcFontSetDestroy(nfs);
return NS_OK;
#endif
} }
nsresult nsresult
@ -452,14 +235,9 @@ gfxQtPlatform::CreateFontGroup(const nsAString &aFamilies,
const gfxFontStyle *aStyle, const gfxFontStyle *aStyle,
gfxUserFontSet* aUserFontSet) gfxUserFontSet* aUserFontSet)
{ {
#ifdef MOZ_PANGO
return new gfxPangoFontGroup(aFamilies, aStyle, aUserFontSet); return new gfxPangoFontGroup(aFamilies, aStyle, aUserFontSet);
#else
return new gfxFT2FontGroup(aFamilies, aStyle, aUserFontSet);
#endif
} }
#ifdef MOZ_PANGO
gfxFontEntry* gfxFontEntry*
gfxQtPlatform::LookupLocalFont(const gfxProxyFontEntry *aProxyEntry, gfxQtPlatform::LookupLocalFont(const gfxProxyFontEntry *aProxyEntry,
const nsAString& aFontName) const nsAString& aFontName)
@ -501,7 +279,6 @@ gfxQtPlatform::IsFontFormatSupported(nsIURI *aFontURI, uint32_t aFormatFlags)
// no format hint set, need to look at data // no format hint set, need to look at data
return true; return true;
} }
#endif
qcms_profile* qcms_profile*
gfxQtPlatform::GetPlatformCMSOutputProfile() gfxQtPlatform::GetPlatformCMSOutputProfile()
@ -509,91 +286,6 @@ gfxQtPlatform::GetPlatformCMSOutputProfile()
return nullptr; return nullptr;
} }
#ifndef MOZ_PANGO
FT_Library
gfxQtPlatform::GetFTLibrary()
{
return gPlatformFTLibrary;
}
FontFamily *
gfxQtPlatform::FindFontFamily(const nsAString& aName)
{
nsAutoString name(aName);
ToLowerCase(name);
nsRefPtr<FontFamily> ff;
if (!gPlatformFonts->Get(name, &ff)) {
return nullptr;
}
return ff.get();
}
FontEntry *
gfxQtPlatform::FindFontEntry(const nsAString& aName, const gfxFontStyle& aFontStyle)
{
nsRefPtr<FontFamily> ff = FindFontFamily(aName);
if (!ff)
return nullptr;
return ff->FindFontEntry(aFontStyle);
}
static PLDHashOperator
FindFontForCharProc(nsStringHashKey::KeyType aKey,
nsRefPtr<FontFamily>& aFontFamily,
void* aUserArg)
{
GlobalFontMatch *data = (GlobalFontMatch*)aUserArg;
aFontFamily->FindFontForChar(data);
return PL_DHASH_NEXT;
}
already_AddRefed<gfxFont>
gfxQtPlatform::FindFontForChar(uint32_t aCh, gfxFont *aFont)
{
if (!gPlatformFonts || !gCodepointsWithNoFonts)
return nullptr;
// is codepoint with no matching font? return null immediately
if (gCodepointsWithNoFonts->test(aCh)) {
return nullptr;
}
GlobalFontMatch data(aCh, GetScriptCode(aCh),
(aFont ? aFont->GetStyle() : nullptr));
// find fonts that support the character
gPlatformFonts->Enumerate(FindFontForCharProc, &data);
if (data.mBestMatch) {
nsRefPtr<gfxFT2Font> font =
gfxFT2Font::GetOrMakeFont(static_cast<FontEntry*>(data.mBestMatch.get()),
aFont->GetStyle());
gfxFont* ret = font.forget().get();
return already_AddRefed<gfxFont>(ret);
}
// no match? add to set of non-matching codepoints
gCodepointsWithNoFonts->set(aCh);
return nullptr;
}
bool
gfxQtPlatform::GetPrefFontEntries(const nsCString& aKey, nsTArray<nsRefPtr<gfxFontEntry> > *array)
{
return mPrefFonts.Get(aKey, array);
}
void
gfxQtPlatform::SetPrefFontEntries(const nsCString& aKey, nsTArray<nsRefPtr<gfxFontEntry> >& array)
{
mPrefFonts.Put(aKey, array);
}
#endif
int32_t int32_t
gfxQtPlatform::GetDPI() gfxQtPlatform::GetDPI()
{ {

Просмотреть файл

@ -16,12 +16,6 @@
class gfxFontconfigUtils; class gfxFontconfigUtils;
class QWidget; class QWidget;
#ifndef MOZ_PANGO
typedef struct FT_LibraryRec_ *FT_Library;
class FontFamily;
class FontEntry;
#endif
class gfxQtPlatform : public gfxPlatform { class gfxQtPlatform : public gfxPlatform {
public: public:
@ -63,7 +57,6 @@ public:
const gfxFontStyle *aStyle, const gfxFontStyle *aStyle,
gfxUserFontSet* aUserFontSet); gfxUserFontSet* aUserFontSet);
#ifdef MOZ_PANGO
/** /**
* Look up a local platform font using the full font face name (needed to * Look up a local platform font using the full font face name (needed to
* support @font-face src local() ) * support @font-face src local() )
@ -85,22 +78,9 @@ public:
*/ */
virtual bool IsFontFormatSupported(nsIURI *aFontURI, virtual bool IsFontFormatSupported(nsIURI *aFontURI,
uint32_t aFormatFlags); uint32_t aFormatFlags);
#endif
#ifndef MOZ_PANGO
FontFamily *FindFontFamily(const nsAString& aName);
FontEntry *FindFontEntry(const nsAString& aFamilyName, const gfxFontStyle& aFontStyle);
already_AddRefed<gfxFont> FindFontForChar(uint32_t aCh, gfxFont *aFont);
bool GetPrefFontEntries(const nsCString& aLangGroup, nsTArray<nsRefPtr<gfxFontEntry> > *aFontEntryList);
void SetPrefFontEntries(const nsCString& aLangGroup, nsTArray<nsRefPtr<gfxFontEntry> >& aFontEntryList);
#endif
void ClearPrefFonts() { mPrefFonts.Clear(); } void ClearPrefFonts() { mPrefFonts.Clear(); }
#ifndef MOZ_PANGO
FT_Library GetFTLibrary();
#endif
RenderMode GetRenderMode() { return mRenderMode; } RenderMode GetRenderMode() { return mRenderMode; }
void SetRenderMode(RenderMode rmode) { mRenderMode = rmode; } void SetRenderMode(RenderMode rmode) { mRenderMode = rmode; }

Просмотреть файл

@ -209,7 +209,7 @@ typedef HRESULT (WINAPI*D3D11CreateDeviceFunc)(
ID3D11DeviceContext *ppImmediateContext ID3D11DeviceContext *ppImmediateContext
); );
class GPUAdapterReporter : public MemoryMultiReporter class GPUAdapterReporter : public nsIMemoryReporter
{ {
// Callers must Release the DXGIAdapter after use or risk mem-leak // Callers must Release the DXGIAdapter after use or risk mem-leak
static bool GetDXGIAdapter(IDXGIAdapter **DXGIAdapter) static bool GetDXGIAdapter(IDXGIAdapter **DXGIAdapter)
@ -229,7 +229,7 @@ class GPUAdapterReporter : public MemoryMultiReporter
} }
public: public:
GPUAdapterReporter() {} NS_DECL_ISUPPORTS
NS_IMETHOD NS_IMETHOD
CollectReports(nsIMemoryReporterCallback* aCb, CollectReports(nsIMemoryReporterCallback* aCb,
@ -339,6 +339,8 @@ public:
} }
}; };
NS_IMPL_ISUPPORTS1(GPUAdapterReporter, nsIMemoryReporter)
static __inline void static __inline void
BuildKeyNameFromFontName(nsAString &aName) BuildKeyNameFromFontName(nsAString &aName)
{ {

Просмотреть файл

@ -103,6 +103,7 @@ elif CONFIG['MOZ_WIDGET_GTK']:
EXPORTS += [ EXPORTS += [
'gfxFT2FontBase.h', 'gfxFT2FontBase.h',
'gfxGdkNativeRenderer.h', 'gfxGdkNativeRenderer.h',
'gfxPangoFonts.h',
'gfxPDFSurface.h', 'gfxPDFSurface.h',
'gfxPlatformGtk.h', 'gfxPlatformGtk.h',
'gfxPSSurface.h', 'gfxPSSurface.h',
@ -113,6 +114,7 @@ elif CONFIG['MOZ_WIDGET_GTK']:
'gfxFT2FontBase.cpp', 'gfxFT2FontBase.cpp',
'gfxFT2Utils.cpp', 'gfxFT2Utils.cpp',
'gfxGdkNativeRenderer.cpp', 'gfxGdkNativeRenderer.cpp',
'gfxPangoFonts.cpp',
'gfxPDFSurface.cpp', 'gfxPDFSurface.cpp',
'gfxPlatformGtk.cpp', 'gfxPlatformGtk.cpp',
'gfxPSSurface.cpp', 'gfxPSSurface.cpp',
@ -129,16 +131,6 @@ elif CONFIG['MOZ_WIDGET_GTK']:
'gfxXlibSurface.cpp', 'gfxXlibSurface.cpp',
] ]
if CONFIG['MOZ_PANGO']:
EXPORTS += ['gfxPangoFonts.h']
SOURCES += [
'gfxPangoFonts.cpp',
]
else:
EXPORTS += ['gfxFT2Fonts.h']
SOURCES += [
'gfxPangoFonts.cpp',
]
elif CONFIG['MOZ_WIDGET_TOOLKIT'] == 'os2': elif CONFIG['MOZ_WIDGET_TOOLKIT'] == 'os2':
EXPORTS += [ EXPORTS += [
'gfxOS2Fonts.h', 'gfxOS2Fonts.h',
@ -157,6 +149,7 @@ elif CONFIG['MOZ_WIDGET_TOOLKIT'] == 'os2':
elif CONFIG['MOZ_WIDGET_TOOLKIT'] == 'qt': elif CONFIG['MOZ_WIDGET_TOOLKIT'] == 'qt':
EXPORTS += [ EXPORTS += [
'gfxFT2FontBase.h', 'gfxFT2FontBase.h',
'gfxPangoFonts.h',
'gfxPDFSurface.h', 'gfxPDFSurface.h',
'gfxQPainterSurface.h', 'gfxQPainterSurface.h',
'gfxQtNativeRenderer.h', 'gfxQtNativeRenderer.h',
@ -166,6 +159,7 @@ elif CONFIG['MOZ_WIDGET_TOOLKIT'] == 'qt':
'gfxFontconfigUtils.cpp', 'gfxFontconfigUtils.cpp',
'gfxFT2FontBase.cpp', 'gfxFT2FontBase.cpp',
'gfxFT2Utils.cpp', 'gfxFT2Utils.cpp',
'gfxPangoFonts.cpp',
'gfxPDFSurface.cpp', 'gfxPDFSurface.cpp',
'gfxQPainterSurface.cpp', 'gfxQPainterSurface.cpp',
'gfxQtPlatform.cpp', 'gfxQtPlatform.cpp',
@ -181,16 +175,6 @@ elif CONFIG['MOZ_WIDGET_TOOLKIT'] == 'qt':
'gfxXlibSurface.cpp', 'gfxXlibSurface.cpp',
] ]
if CONFIG['MOZ_PANGO']:
EXPORTS += ['gfxPangoFonts.h']
SOURCES += [
'gfxPangoFonts.cpp',
]
else:
EXPORTS += ['gfxFT2Fonts.h']
SOURCES += [
'gfxFT2Fonts.cpp',
]
elif CONFIG['MOZ_WIDGET_TOOLKIT'] == 'windows': elif CONFIG['MOZ_WIDGET_TOOLKIT'] == 'windows':
EXPORTS += [ EXPORTS += [
'gfxD2DSurface.h', 'gfxD2DSurface.h',

Просмотреть файл

@ -349,7 +349,7 @@ Decoder::PostFrameStop(FrameBlender::FrameAlpha aFrameAlpha /* = FrameBlender::k
} }
mCurrentFrame->SetFrameDisposalMethod(aDisposalMethod); mCurrentFrame->SetFrameDisposalMethod(aDisposalMethod);
mCurrentFrame->SetTimeout(aTimeout); mCurrentFrame->SetRawTimeout(aTimeout);
mCurrentFrame->SetBlendMethod(aBlendMethod); mCurrentFrame->SetBlendMethod(aBlendMethod);
mCurrentFrame->ImageUpdated(mCurrentFrame->GetRect()); mCurrentFrame->ImageUpdated(mCurrentFrame->GetRect());

Просмотреть файл

@ -13,36 +13,36 @@ using namespace mozilla;
FrameAnimator::FrameAnimator(FrameBlender& aFrameBlender) FrameAnimator::FrameAnimator(FrameBlender& aFrameBlender)
: mCurrentAnimationFrameIndex(0) : mCurrentAnimationFrameIndex(0)
, mLoopCount(-1) , mLoopCounter(-1)
, mFrameBlender(aFrameBlender) , mFrameBlender(aFrameBlender)
, mAnimationMode(imgIContainer::kNormalAnimMode) , mAnimationMode(imgIContainer::kNormalAnimMode)
, mDoneDecoding(false) , mDoneDecoding(false)
{ {
} }
uint32_t int32_t
FrameAnimator::GetSingleLoopTime() const FrameAnimator::GetSingleLoopTime() const
{ {
// If we aren't done decoding, we don't know the image's full play time. // If we aren't done decoding, we don't know the image's full play time.
if (!mDoneDecoding) { if (!mDoneDecoding) {
return 0; return -1;
} }
// If we're not looping, a single loop time has no meaning // If we're not looping, a single loop time has no meaning
if (mAnimationMode != imgIContainer::kNormalAnimMode) { if (mAnimationMode != imgIContainer::kNormalAnimMode) {
return 0; return -1;
} }
uint32_t looptime = 0; uint32_t looptime = 0;
for (uint32_t i = 0; i < mFrameBlender.GetNumFrames(); ++i) { for (uint32_t i = 0; i < mFrameBlender.GetNumFrames(); ++i) {
int32_t timeout = mFrameBlender.RawGetFrame(i)->GetTimeout(); int32_t timeout = mFrameBlender.GetTimeoutForFrame(i);
if (timeout > 0) { if (timeout >= 0) {
looptime += static_cast<uint32_t>(timeout); looptime += static_cast<uint32_t>(timeout);
} else { } else {
// If we have a frame that never times out, we're probably in an error // If we have a frame that never times out, we're probably in an error
// case, but let's handle it more gracefully. // case, but let's handle it more gracefully.
NS_WARNING("Negative frame timeout - how did this happen?"); NS_WARNING("Negative frame timeout - how did this happen?");
return 0; return -1;
} }
} }
@ -52,9 +52,8 @@ FrameAnimator::GetSingleLoopTime() const
TimeStamp TimeStamp
FrameAnimator::GetCurrentImgFrameEndTime() const FrameAnimator::GetCurrentImgFrameEndTime() const
{ {
imgFrame* currentFrame = mFrameBlender.RawGetFrame(mCurrentAnimationFrameIndex);
TimeStamp currentFrameTime = mCurrentAnimationFrameTime; TimeStamp currentFrameTime = mCurrentAnimationFrameTime;
int64_t timeout = currentFrame->GetTimeout(); int32_t timeout = mFrameBlender.GetTimeoutForFrame(mCurrentAnimationFrameIndex);
if (timeout < 0) { if (timeout < 0) {
// We need to return a sentinel value in this case, because our logic // We need to return a sentinel value in this case, because our logic
@ -82,7 +81,7 @@ FrameAnimator::AdvanceFrame(TimeStamp aTime)
uint32_t currentFrameIndex = mCurrentAnimationFrameIndex; uint32_t currentFrameIndex = mCurrentAnimationFrameIndex;
uint32_t nextFrameIndex = currentFrameIndex + 1; uint32_t nextFrameIndex = currentFrameIndex + 1;
uint32_t timeout = 0; int32_t timeout = 0;
RefreshResult ret; RefreshResult ret;
@ -101,17 +100,22 @@ FrameAnimator::AdvanceFrame(TimeStamp aTime)
// If we're done decoding the next frame, go ahead and display it now and // If we're done decoding the next frame, go ahead and display it now and
// reinit with the next frame's delay time. // reinit with the next frame's delay time.
if (mFrameBlender.GetNumFrames() == nextFrameIndex) { if (mFrameBlender.GetNumFrames() == nextFrameIndex) {
// End of Animation, unless we are looping forever // End of an animation loop...
// If animation mode is "loop once", it's time to stop animating // If we are not looping forever, initialize the loop counter
if (mAnimationMode == imgIContainer::kLoopOnceAnimMode || mLoopCount == 0) { if (mLoopCounter < 0 && mFrameBlender.GetLoopCount() >= 0) {
mLoopCounter = mFrameBlender.GetLoopCount();
}
// If animation mode is "loop once", or we're at end of loop counter, it's time to stop animating
if (mAnimationMode == imgIContainer::kLoopOnceAnimMode || mLoopCounter == 0) {
ret.animationFinished = true; ret.animationFinished = true;
} }
nextFrameIndex = 0; nextFrameIndex = 0;
if (mLoopCount > 0) { if (mLoopCounter > 0) {
mLoopCount--; mLoopCounter--;
} }
// If we're done, exit early. // If we're done, exit early.
@ -120,11 +124,11 @@ FrameAnimator::AdvanceFrame(TimeStamp aTime)
} }
} }
timeout = mFrameBlender.GetFrame(nextFrameIndex)->GetTimeout(); timeout = mFrameBlender.GetTimeoutForFrame(nextFrameIndex);
} }
// Bad data // Bad data
if (!(timeout > 0)) { if (timeout < 0) {
ret.animationFinished = true; ret.animationFinished = true;
ret.error = true; ret.error = true;
} }
@ -246,12 +250,6 @@ FrameAnimator::UnionFirstFrameRefreshArea(const nsIntRect& aRect)
mFirstFrameRefreshArea.UnionRect(mFirstFrameRefreshArea, aRect); mFirstFrameRefreshArea.UnionRect(mFirstFrameRefreshArea, aRect);
} }
void
FrameAnimator::SetLoopCount(int loopcount)
{
mLoopCount = loopcount;
}
uint32_t uint32_t
FrameAnimator::GetCurrentAnimationFrameIndex() const FrameAnimator::GetCurrentAnimationFrameIndex() const
{ {

Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше